changeset 51102:580159eeac07

8204187: Remove proprietary JPEG code from javax.imageio Reviewed-by: bpb, serb, kaddepalli
author prr
date Wed, 06 Jun 2018 13:04:25 -0700
parents 15a2ef1e418e
children cbae0e359538
files src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java src/java.desktop/share/native/libjavajpeg/imageioJPEG.c src/java.desktop/share/native/libjavajpeg/jpegdecoder.c test/jdk/javax/imageio/plugins/jpeg/TestWriteARGBJPEG.java test/jdk/javax/imageio/plugins/shared/BitDepth.java
diffstat 10 files changed, 137 insertions(+), 306 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java	Wed Jun 06 13:04:25 2018 -0700
@@ -187,13 +187,7 @@
     public static final int JCS_RGB = 2;           // red/green/blue
     public static final int JCS_YCbCr = 3;         // Y/Cb/Cr (also known as YUV)
     public static final int JCS_CMYK = 4;          // C/M/Y/K
-    public static final int JCS_YCC = 5;           // PhotoYCC
-    public static final int JCS_RGBA = 6;          // RGB-Alpha
-    public static final int JCS_YCbCrA = 7;        // Y/Cb/Cr/Alpha
-    // 8 and 9 were old "Legacy" codes which the old code never identified
-    // on reading anyway.  Support for writing them is being dropped, too.
-    public static final int JCS_YCCA = 10;         // PhotoYCC-Alpha
-    public static final int JCS_YCCK = 11;         // Y/Cb/Cr/K
+    public static final int JCS_YCCK = 5;         // Y/Cb/Cr/K
 
     public static final int NUM_JCS_CODES = JCS_YCCK+1;
 
@@ -212,22 +206,6 @@
     public static class JCS {
         public static final ColorSpace sRGB =
             ColorSpace.getInstance(ColorSpace.CS_sRGB);
-
-        private static ColorSpace YCC = null;
-        private static boolean yccInited = false;
-
-        public static ColorSpace getYCC() {
-            if (!yccInited) {
-                try {
-                    YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC);
-                } catch (IllegalArgumentException e) {
-                    // PYCC.pf may not always be installed
-                } finally {
-                    yccInited = true;
-                }
-            }
-            return YCC;
-        }
     }
 
     // Default value for ImageWriteParam
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Wed Jun 06 13:04:25 2018 -0700
@@ -933,21 +933,6 @@
         case JPEG.JCS_RGB:
             list.add(raw);
             list.add(getImageType(JPEG.JCS_GRAYSCALE));
-            list.add(getImageType(JPEG.JCS_YCC));
-            break;
-        case JPEG.JCS_RGBA:
-            list.add(raw);
-            break;
-        case JPEG.JCS_YCC:
-            if (raw != null) {  // Might be null if PYCC.pf not installed
-                list.add(raw);
-                list.add(getImageType(JPEG.JCS_RGB));
-            }
-            break;
-        case JPEG.JCS_YCCA:
-            if (raw != null) {  // Might be null if PYCC.pf not installed
-                list.add(raw);
-            }
             break;
         case JPEG.JCS_YCbCr:
             // As there is no YCbCr ColorSpace, we can't support
@@ -972,12 +957,6 @@
             }
 
             list.add(getImageType(JPEG.JCS_GRAYSCALE));
-            list.add(getImageType(JPEG.JCS_YCC));
-            break;
-        case JPEG.JCS_YCbCrA:  // Default is to convert to RGBA
-            // As there is no YCbCr ColorSpace, we can't support
-            // the raw type.
-            list.add(getImageType(JPEG.JCS_RGBA));
             break;
         }
 
@@ -1065,36 +1044,6 @@
                 throw new IIOException("Incompatible color conversion");
             }
             break;
-        case JPEG.JCS_RGBA:
-            // No conversions available; image must be RGBA
-            if ((csType != ColorSpace.TYPE_RGB) ||
-                (cm.getNumComponents() != numComponents)) {
-                throw new IIOException("Incompatible color conversion");
-            }
-            break;
-        case JPEG.JCS_YCC:
-            {
-                ColorSpace YCC = JPEG.JCS.getYCC();
-                if (YCC == null) { // We can't do YCC at all
-                    throw new IIOException("Incompatible color conversion");
-                }
-                if ((cs != YCC) &&
-                    (cm.getNumComponents() == numComponents)) {
-                    convert = new ColorConvertOp(YCC, cs, null);
-                }
-            }
-            break;
-        case JPEG.JCS_YCCA:
-            {
-                ColorSpace YCC = JPEG.JCS.getYCC();
-                // No conversions available; image must be YCCA
-                if ((YCC == null) || // We can't do YCC at all
-                    (cs != YCC) ||
-                    (cm.getNumComponents() != numComponents)) {
-                    throw new IIOException("Incompatible color conversion");
-                }
-            }
-            break;
         default:
             // Anything else we can't handle at all
             throw new IIOException("Incompatible color conversion");
@@ -1929,36 +1878,6 @@
                         DataBuffer.TYPE_BYTE,
                         false,
                         false);
-            case JPEG.JCS_RGBA:
-                return ImageTypeSpecifier.createPacked(JPEG.JCS.sRGB,
-                        0xff000000,
-                        0x00ff0000,
-                        0x0000ff00,
-                        0x000000ff,
-                        DataBuffer.TYPE_INT,
-                        false);
-            case JPEG.JCS_YCC:
-                if (JPEG.JCS.getYCC() != null) {
-                    return ImageTypeSpecifier.createInterleaved(
-                            JPEG.JCS.getYCC(),
-                        JPEG.bandOffsets[2],
-                        DataBuffer.TYPE_BYTE,
-                        false,
-                        false);
-                } else {
-                    return null;
-                }
-            case JPEG.JCS_YCCA:
-                if (JPEG.JCS.getYCC() != null) {
-                    return ImageTypeSpecifier.createInterleaved(
-                            JPEG.JCS.getYCC(),
-                        JPEG.bandOffsets[3],
-                        DataBuffer.TYPE_BYTE,
-                        true,
-                        false);
-                } else {
-                    return null;
-                }
             default:
                 return null;
         }
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Wed Jun 06 13:04:25 2018 -0700
@@ -754,115 +754,47 @@
                             }
                             break;
                         case ColorSpace.TYPE_RGB:
-                            if (!alpha) {
-                                if (jfif != null) {
+                            if (jfif != null) {
+                                outCsType = JPEG.JCS_YCbCr;
+                                if (JPEG.isNonStandardICC(cs)
+                                    || ((cs instanceof ICC_ColorSpace)
+                                        && (jfif.iccSegment != null))) {
+                                    iccProfile =
+                                        ((ICC_ColorSpace) cs).getProfile();
+                                }
+                            } else if (adobe != null) {
+                                switch (adobe.transform) {
+                                case JPEG.ADOBE_UNKNOWN:
+                                    outCsType = JPEG.JCS_RGB;
+                                    break;
+                                case JPEG.ADOBE_YCC:
                                     outCsType = JPEG.JCS_YCbCr;
-                                    if (JPEG.isNonStandardICC(cs)
-                                        || ((cs instanceof ICC_ColorSpace)
-                                            && (jfif.iccSegment != null))) {
-                                        iccProfile =
-                                            ((ICC_ColorSpace) cs).getProfile();
-                                    }
-                                } else if (adobe != null) {
-                                    switch (adobe.transform) {
-                                    case JPEG.ADOBE_UNKNOWN:
+                                    break;
+                                default:
+                                    warningOccurred
+                                    (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
+                                    newAdobeTransform = JPEG.ADOBE_UNKNOWN;
+                                    outCsType = JPEG.JCS_RGB;
+                                    break;
+                                }
+                            } else {
+                                // consult the ids
+                                int outCS = sof.getIDencodedCSType();
+                                // if they don't resolve it,
+                                // consult the sampling factors
+                                if (outCS != JPEG.JCS_UNKNOWN) {
+                                    outCsType = outCS;
+                                } else {
+                                    boolean subsampled =
+                                    isSubsampled(sof.componentSpecs);
+                                    if (subsampled) {
+                                        outCsType = JPEG.JCS_YCbCr;
+                                    } else {
                                         outCsType = JPEG.JCS_RGB;
-                                        break;
-                                    case JPEG.ADOBE_YCC:
-                                        outCsType = JPEG.JCS_YCbCr;
-                                        break;
-                                    default:
-                                        warningOccurred
-                                        (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
-                                        newAdobeTransform = JPEG.ADOBE_UNKNOWN;
-                                        outCsType = JPEG.JCS_RGB;
-                                        break;
-                                    }
-                                } else {
-                                    // consult the ids
-                                    int outCS = sof.getIDencodedCSType();
-                                    // if they don't resolve it,
-                                    // consult the sampling factors
-                                    if (outCS != JPEG.JCS_UNKNOWN) {
-                                        outCsType = outCS;
-                                    } else {
-                                        boolean subsampled =
-                                        isSubsampled(sof.componentSpecs);
-                                        if (subsampled) {
-                                            outCsType = JPEG.JCS_YCbCr;
-                                        } else {
-                                            outCsType = JPEG.JCS_RGB;
-                                        }
-                                    }
-                                }
-                            } else { // RGBA
-                                if (jfif != null) {
-                                    ignoreJFIF = true;
-                                    warningOccurred
-                                    (WARNING_IMAGE_METADATA_JFIF_MISMATCH);
-                                }
-                                if (adobe != null) {
-                                    if (adobe.transform
-                                        != JPEG.ADOBE_UNKNOWN) {
-                                        newAdobeTransform = JPEG.ADOBE_UNKNOWN;
-                                        warningOccurred
-                                        (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
-                                    }
-                                    outCsType = JPEG.JCS_RGBA;
-                                } else {
-                                    // consult the ids
-                                    int outCS = sof.getIDencodedCSType();
-                                    // if they don't resolve it,
-                                    // consult the sampling factors
-                                    if (outCS != JPEG.JCS_UNKNOWN) {
-                                        outCsType = outCS;
-                                    } else {
-                                        boolean subsampled =
-                                        isSubsampled(sof.componentSpecs);
-                                        outCsType = subsampled ?
-                                            JPEG.JCS_YCbCrA : JPEG.JCS_RGBA;
                                     }
                                 }
                             }
                             break;
-                        case ColorSpace.TYPE_3CLR:
-                            if (cs == JPEG.JCS.getYCC()) {
-                                if (!alpha) {
-                                    if (jfif != null) {
-                                        convertTosRGB = true;
-                                        convertOp =
-                                        new ColorConvertOp(cs,
-                                                           JPEG.JCS.sRGB,
-                                                           null);
-                                        outCsType = JPEG.JCS_YCbCr;
-                                    } else if (adobe != null) {
-                                        if (adobe.transform
-                                            != JPEG.ADOBE_YCC) {
-                                            newAdobeTransform = JPEG.ADOBE_YCC;
-                                            warningOccurred
-                                            (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
-                                        }
-                                        outCsType = JPEG.JCS_YCC;
-                                    } else {
-                                        outCsType = JPEG.JCS_YCC;
-                                    }
-                                } else { // PhotoYCCA
-                                    if (jfif != null) {
-                                        ignoreJFIF = true;
-                                        warningOccurred
-                                        (WARNING_IMAGE_METADATA_JFIF_MISMATCH);
-                                    } else if (adobe != null) {
-                                        if (adobe.transform
-                                            != JPEG.ADOBE_UNKNOWN) {
-                                            newAdobeTransform
-                                            = JPEG.ADOBE_UNKNOWN;
-                                            warningOccurred
-                                            (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
-                                        }
-                                    }
-                                    outCsType = JPEG.JCS_YCCA;
-                                }
-                            }
                         }
                     }
                 } // else no dest, metadata, not an image.  Defaults ok
@@ -1564,27 +1496,10 @@
                 retval = JPEG.JCS_GRAYSCALE;
                 break;
             case ColorSpace.TYPE_RGB:
-                if (alpha) {
-                    retval = JPEG.JCS_RGBA;
-                } else {
-                    retval = JPEG.JCS_RGB;
-                }
+                retval = JPEG.JCS_RGB;
                 break;
             case ColorSpace.TYPE_YCbCr:
-                if (alpha) {
-                    retval = JPEG.JCS_YCbCrA;
-                } else {
-                    retval = JPEG.JCS_YCbCr;
-                }
-                break;
-            case ColorSpace.TYPE_3CLR:
-                if (cs == JPEG.JCS.getYCC()) {
-                    if (alpha) {
-                        retval = JPEG.JCS_YCCA;
-                    } else {
-                        retval = JPEG.JCS_YCC;
-                    }
-                }
+                retval = JPEG.JCS_YCbCr;
                 break;
             case ColorSpace.TYPE_CMYK:
                 retval = JPEG.JCS_CMYK;
@@ -1604,27 +1519,10 @@
                 retval = JPEG.JCS_GRAYSCALE;
                 break;
             case ColorSpace.TYPE_RGB:
-                if (alpha) {
-                    retval = JPEG.JCS_RGBA;
-                } else {
-                    retval = JPEG.JCS_RGB;
-                }
+                retval = JPEG.JCS_RGB;
                 break;
             case ColorSpace.TYPE_YCbCr:
-                if (alpha) {
-                    retval = JPEG.JCS_YCbCrA;
-                } else {
-                    retval = JPEG.JCS_YCbCr;
-                }
-                break;
-            case ColorSpace.TYPE_3CLR:
-                if (cs == JPEG.JCS.getYCC()) {
-                    if (alpha) {
-                        retval = JPEG.JCS_YCCA;
-                    } else {
-                        retval = JPEG.JCS_YCC;
-                    }
-                }
+                retval = JPEG.JCS_YCbCr;
                 break;
             case ColorSpace.TYPE_CMYK:
                 retval = JPEG.JCS_CMYK;
@@ -1651,27 +1549,10 @@
                 retval = JPEG.JCS_GRAYSCALE;
                 break;
             case ColorSpace.TYPE_RGB:
-                if (alpha) {
-                    retval = JPEG.JCS_YCbCrA;
-                } else {
-                    retval = JPEG.JCS_YCbCr;
-                }
+                retval = JPEG.JCS_YCbCr;
                 break;
             case ColorSpace.TYPE_YCbCr:
-                if (alpha) {
-                    retval = JPEG.JCS_YCbCrA;
-                } else {
-                    retval = JPEG.JCS_YCbCr;
-                }
-                break;
-            case ColorSpace.TYPE_3CLR:
-                if (cs == JPEG.JCS.getYCC()) {
-                    if (alpha) {
-                        retval = JPEG.JCS_YCCA;
-                    } else {
-                        retval = JPEG.JCS_YCC;
-                    }
-                }
+                retval = JPEG.JCS_YCbCr;
                 break;
             case ColorSpace.TYPE_CMYK:
                 retval = JPEG.JCS_YCCK;
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java	Wed Jun 06 13:04:25 2018 -0700
@@ -73,7 +73,11 @@
 
     public boolean canEncodeImage(ImageTypeSpecifier type) {
         SampleModel sampleModel = type.getSampleModel();
+        ColorModel cm = type.getColorModel();
 
+        if (cm.hasAlpha()) {
+            return false;
+        }
         // Find the maximum bit depth across all channels
         int[] sampleSize = sampleModel.getSampleSize();
         int bitDepth = sampleSize[0];
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java	Wed Jun 06 13:04:25 2018 -0700
@@ -491,17 +491,6 @@
                     wantJFIF = false;
                 }
                 break;
-            case ColorSpace.TYPE_3CLR:
-                if (cs == JPEG.JCS.getYCC()) {
-                    wantJFIF = false;
-                    componentIDs[0] = (byte) 'Y';
-                    componentIDs[1] = (byte) 'C';
-                    componentIDs[2] = (byte) 'c';
-                    if (hasAlpha) {
-                        componentIDs[3] = (byte) 'A';
-                    }
-                }
-                break;
             case ColorSpace.TYPE_YCbCr:
                 if (hasExtraComponents) { // e.g. K or alpha
                     wantJFIF = false;
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java	Wed Jun 06 13:04:25 2018 -0700
@@ -182,29 +182,11 @@
         switch(componentSpecs.length) {
         case 3:
             if ((componentSpecs[0].componentId == 'R')
-                &&(componentSpecs[0].componentId == 'G')
-                &&(componentSpecs[0].componentId == 'B')) {
+                &&(componentSpecs[1].componentId == 'G')
+                &&(componentSpecs[2].componentId == 'B')) {
                 return JPEG.JCS_RGB;
             }
-            if ((componentSpecs[0].componentId == 'Y')
-                &&(componentSpecs[0].componentId == 'C')
-                &&(componentSpecs[0].componentId == 'c')) {
-                return JPEG.JCS_YCC;
-            }
             break;
-        case 4:
-            if ((componentSpecs[0].componentId == 'R')
-                &&(componentSpecs[0].componentId == 'G')
-                &&(componentSpecs[0].componentId == 'B')
-                &&(componentSpecs[0].componentId == 'A')) {
-                return JPEG.JCS_RGBA;
-            }
-            if ((componentSpecs[0].componentId == 'Y')
-                &&(componentSpecs[0].componentId == 'C')
-                &&(componentSpecs[0].componentId == 'c')
-                &&(componentSpecs[0].componentId == 'A')) {
-                return JPEG.JCS_YCCA;
-            }
         }
 
         return JPEG.JCS_UNKNOWN;
--- a/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	Wed Jun 06 13:04:25 2018 -0700
@@ -1762,11 +1762,6 @@
                 }
             }
             break;
-#ifdef YCCALPHA
-        case JCS_YCC:
-            cinfo->out_color_space = JCS_YCC;
-            break;
-#endif
         case JCS_YCCK:
             if ((cinfo->saw_Adobe_marker) && (cinfo->Adobe_transform != 2)) {
                 /*
--- a/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	Wed Jun 06 12:51:44 2018 -0700
+++ b/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	Wed Jun 06 13:04:25 2018 -0700
@@ -569,11 +569,7 @@
   /* select buffered-image mode if it is a progressive JPEG only */
   buffered_mode = cinfo.buffered_image = jpeg_has_multiple_scans(&cinfo);
   grayscale = (cinfo.out_color_space == JCS_GRAYSCALE);
-#ifdef YCCALPHA
-  hasalpha = (cinfo.out_color_space == JCS_RGBA);
-#else
   hasalpha = 0;
-#endif
   /* We can ignore the return value from jpeg_read_header since
    *   (a) suspension is not possible with the stdio data source, and
    *                                    (nor with the Java input source)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/jpeg/TestWriteARGBJPEG.java	Wed Jun 06 13:04:25 2018 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug     8204187
+ * @run     main TestWriteARGBJPEG
+ * @summary verify JPEG Alpha support is as reported.
+ */
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.io.ByteArrayOutputStream;
+import java.awt.image.BufferedImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class TestWriteARGBJPEG {
+    public static void main(String args[]) throws IOException {
+
+        BufferedImage bi =
+            new BufferedImage(10,10,BufferedImage.TYPE_INT_ARGB);
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+    // There should be no exception from the next line
+    // which internally should be relying on the canEncodeImage
+    // method which we'll also test directly.
+    boolean ret = ImageIO.write(bi, "jpeg", baos);
+    System.out.println("ImageIO.write(..) returned " + ret);
+
+    ImageTypeSpecifier its = new ImageTypeSpecifier(bi);
+    Iterator<ImageWriter> writers = ImageIO.getImageWriters(its, "jpeg");
+    boolean hasWriter = writers.hasNext();
+    // If this can't write it, an exception will be thrown.
+    if (writers.hasNext()) {
+        System.out.println("A writer was found.");
+        ImageWriter iw = writers.next();
+        MemoryCacheImageOutputStream mos =
+            new MemoryCacheImageOutputStream(baos);
+        iw.setOutput(mos);
+        iw.write(bi);
+    }
+
+    // Now Let's also ask the default JPEG writer's SPI if it
+    // can write an ARGB image.
+    ImageWriter iw = ImageIO.getImageWritersByFormatName("jpeg").next();
+    ImageWriterSpi iwSpi = iw.getOriginatingProvider();
+    boolean canEncode = iwSpi.canEncodeImage(bi);
+    System.out.println("SPI canEncodeImage returned " + canEncode);
+
+    // Now let's see if it is telling the truth.
+    try {
+        MemoryCacheImageOutputStream mos =
+            new MemoryCacheImageOutputStream(baos);
+        iw.setOutput(mos);
+        iw.write(bi);
+    } catch (IOException e) {
+         if (canEncode) {
+           throw e;
+         }
+    }
+  }
+}
--- a/test/jdk/javax/imageio/plugins/shared/BitDepth.java	Wed Jun 06 12:51:44 2018 -0700
+++ b/test/jdk/javax/imageio/plugins/shared/BitDepth.java	Wed Jun 06 13:04:25 2018 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug     4413109 4418221 6607198 8147448
+ * @bug     4413109 4418221 6607198 8147448 8204187
  * @run     main BitDepth
  * @summary Checks that ImageIO writers for standard formats can handle
  *          various BufferedImage RGB types. An optional list of arguments
@@ -197,6 +197,7 @@
         if (!writers.hasNext()) {
             System.out.println("\tNo writers available for type " + biTypeNames[type]
                                + " BufferedImage!");
+            return null;
         } else {
             ImageWriter writer = writers.next();
             try (ImageOutputStream out = ImageIO.createImageOutputStream(file)) {
@@ -205,7 +206,7 @@
             } catch (Exception e) {
                 System.out.println("\tCan't write a type " +  biTypeNames[type]
                            + " BufferedImage!");
-                return null;
+                throw new RuntimeException(e);
             }
         }