[OpenJDK 2D-Dev] Fwd: JPEG native lib / enum / colour space long-standing bug?

Martijn Verburg martijnverburg at gmail.com
Fri May 11 11:37:22 UTC 2012


I think this was supposed to go to list - M


---------- Forwarded message ----------
Date: 11 May 2012 11:28
Subject: Re: [OpenJDK 2D-Dev] JPEG native lib / enum / colour space
long-standing bug?

Hi,

ColorSpace constant/enum mismatch between native code to generate
JPEGs in OpenJDK6 and JAVA means that attempts to generate JPEG from
(say) RGBA BufferedImage result in a IIOException but were probably
doing bad things under JDK6.

Rgds

Damon



See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7044758
    * See: http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/5c61c31d2621
    * See: http://java.net/jira/browse/MACOSX_PORT-351
    * See: http://java.net/jira/browse/MACOSX_PORT-756

In jpeglib.h:

typedef enum {
   JCS_UNKNOWN,
   JCS_GRAYSCALE,
   JCS_RGB,
   JCS_YCbCr,
   JCS_CMYK,
   JCS_YCCK
} J_COLOR_SPACE;

    * So JCS_YCCK == 5...

* In com.sun.imageio.plugins.jpeg.JPEG.java (1.15 03/12/19):

// IJG Color codes.
 170:    public static final int JCS_UNKNOWN = 0;       // error/unspecified
 171:    public static final int JCS_GRAYSCALE = 1;     // monochrome
 172:    public static final int JCS_RGB = 2;           // red/green/blue
 173:    public static final int JCS_YCbCr = 3;         // Y/Cb/Cr
(also known as YUV)
 174:    public static final int JCS_CMYK = 4;          // C/M/Y/K
 175:    public static final int JCS_YCC = 5;           // PhotoYCC
 176:    public static final int JCS_RGBA = 6;          // RGB-Alpha
 177:    public static final int JCS_YCbCrA = 7;        // Y/Cb/Cr/Alpha
 178:    // 8 and 9 were old "Legacy" codes which the old code never identified
 179:    // on reading anyway.  Support for writing them is being dropped, too.
 180:    public static final int JCS_YCCA = 10;         // PhotoYCC-Alpha
 181:    public static final int JCS_YCCK = 11;         // Y/Cb/Cr/K
 182:
 183:    public static final int NUM_JCS_CODES = JCS_YCCK+1;


    * And in new code to check args and fix vulnerabilities:
http://hg.openjdk.java.net/jdk7/jdk7/jdk/annotate/df445f522425/src/share/native/sun/awt/image/jpeg/imageioJPEG.c

JNIEXPORT jboolean JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage
...
   if ((inCs < 0) || (inCs > JCS_YCCK) ||
       (outCs < 0) || (outCs > JCS_YCCK) ||
...
   {
       JNU_ThrowByName(env, "javax/imageio/IIOException",
                       "Invalid argument to native writeImage");
       return JNI_FALSE;

Means that no colour space from RGBA onwards is possible.


Practical upshot: I was having IIOExceptions thrown when trying to
generate a nominally RGBA JPEG image that worked fine under JDK6, but
I had been having problems for months/years trying to actually
generate sensible RGB images this way.

If I switch to RGB BufferedImage I have no problem, eg with this:

   /**Create a test RGB fully-opaque true-colour image in memory.
    * This image will be suitable to make thumbnails from, for example,
    * if large enough.
    * <p>
    * This is an RGB image with a mixture of slowly-varying
    * colours and noise.
    * <p>
    * Package-visible to be available to other tests.
    */
   static BufferedImage makeTestRGBTrueColourBufferedImage(final int width,
                                                           final int height)
       {
       if((width < 1) || (height < 1))
           { throw new IllegalArgumentException(); }

       // Create a blank RGB (buffered) image.
       final BufferedImage bi = new BufferedImage(width,
                                                  height,

ImageUtils.NO_RGBA_OR_LATER_CS ? BufferedImage.TYPE_INT_RGB :
BufferedImage.TYPE_INT_ARGB);
       // Set this image up to have a relatively smoothly-changing backdrop
       // with some noise imposed on it.
       // Efficiency is not a huge issue here...
       for(int y = height; --y >= 0; )
           {
           final int r = Math.round((y / (float) height) * 128)
               + rnd.nextInt(16);
           for(int x = width; --x >= 0; )
               {
               final int g = Math.round((x / (float) width) * 128)
                   + rnd.nextInt(16);
               final int b = ((x+y) & 0xff);
               final int rgb = 0xff000000 | (r << 16) | (g << 8) | b;
               bi.setRGB(x, y, rgb);
               }
           }

       return(bi);
       }

If ImageUtils.NO_RGBA_OR_LATER_CS is false I get an exception under
(Open)JDK7 when trying to generate a JPEG with the built-in encoder.


Rgds

Damon


On 11 May 2012, at 11:01, Martijn Verburg wrote:

> This is the right mailing list yes :-), I'm not sure about the rest!
>
> On 11 May 2012 09:02, Damon Hart-Davis <dhd at exnet.com> wrote:
>> Hi,
>>
>> In running my (JDK6-based) app unit test suite on JDK7 I ran across what looks to be an ugly latent color space bug between libjpeg and calls to it from Java which now results in an exception because of better argument validation at the interface between them. I suspect that the problem been there for years and seems to have been the reason that I had weird problems generating JPEGs from ARGB images for example. I even have a workround...
>>
>> I'm not sure which the right mailing list would be to bring this up: is this it?
>>
>> Rgds
>>
>> Damon
>



More information about the 2d-dev mailing list