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 <[email protected]> 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
> 

Reply via email to