JDK-6211480 : Bundled com.sun.image.codec.jpeg JPEG API has errors for a new type of JPEG image
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.2_04
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: other
  • CPU: x86
  • Submitted: 2004-12-21
  • Updated: 2011-01-19
  • Resolved: 2005-01-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
1.4.2_08Fixed 6 betaFixed
Description
We are trying to use JAI for a new type of JPEG images.
These are technically "valid" Jpeg images which use color-separated "layers".
when we create a planar image using these type of images we are getting
IllegalArgument Exception.

java.lang.IllegalArgumentException: Tables must be 0, 1, 2, or 3.
        at sun.awt.image.codec.JPEGParam.setDCHuffmanComponentMapping(Unknown So
urce)

More information about the JPEG format, Sample code and images is attached

We used jai-1_1_1_01,JDK1.4 (j2sdk1.4.2_04) we tried using the new
version of JAI too. It resulted in same exception.
These JPEG images are generated by a new scanner from IBM called Trac
II.
These images are rendered in IE, Microsoft image editor without any
issues

Attached zip file has the sample code, jar files, start.bat
Please take a look at processImage() method in WLIJAIRunTest.java
Iam also attaching a word document which has details about the JPEG
image which we are 
trying to process. 


Installation instructions:
1.Unzip the attached zip file
2.change start.bat to point to the jar files which are attached in this
zip.
3.execute start.bat

You will get an exception.

java.lang.IllegalArgumentException: Tables must be 0, 1, 2, or 3.
        at sun.awt.image.codec.JPEGParam.setDCHuffmanComponentMapping(Unknown So
urce)
        at sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream(Native Method
)
        at sun.awt.image.codec.JPEGImageDecoderImpl.decodeAsBufferedImage(Unknow
n Source)
        at com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:11
2)
        at com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JP
EGImageDecoder.java:51)
        at com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:89)
        at com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.media.jai.FactoryCache.invoke(FactoryCache.java:130)
        at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.jav
a:1669)
        at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeO
perationRegistry.java:481)
        at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:340)
        at com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:104)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.media.jai.FactoryCache.invoke(FactoryCache.java:130)
        at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.jav
a:1669)
        at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeO
perationRegistry.java:481)
        at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:340)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:805)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getColorModel(RenderedOp.java:2198)
        at WLIJAITest.processImage(WLIJAIRunTest.java:176)
        at WLIJAITest.run(WLIJAIRunTest.java:107)
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.media.jai.FactoryCache.invoke(FactoryCache.java:130)
        at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.jav
a:1669)
        at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeO
perationRegistry.java:481)
        at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:340)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:805)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getColorModel(RenderedOp.java:2198)
        at WLIJAITest.processImage(WLIJAIRunTest.java:176)
        at WLIJAITest.run(WLIJAIRunTest.java:107)
Caused by: java.lang.RuntimeException: Unable to process image stream, incorrect
 format.
        at com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:11
4)
        at com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JP
EGImageDecoder.java:51)
        at com.sun.media.jai.codec.ImageDecoderImpl.decodeAsRenderedImage(ImageD
ecoderImpl.java:148)
        at com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:135)
        ... 19 more
java.lang.RuntimeException: - Unable to render RenderedOp for this operation.
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:813)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getRendering(RenderedOp.java:874)
        at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:785)
        at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:853)
        at javax.media.jai.RenderedOp.getColorModel(RenderedOp.java:2198)
        at WLIJAITest.processImage(WLIJAIRunTest.java:176)
        at WLIJAITest.run(WLIJAIRunTest.java:107)
java.lang.NullPointerException
        at WLIJAITest.processImage(WLIJAIRunTest.java:194)
        at WLIJAITest.run(WLIJAIRunTest.java:107)
###@###.### 2004-12-21 22:44:28 GMT

The problem is in the bundled com.sun.image.codec.jpeg JPEG decoder, not in JAI per se. This may be verified by attempting to load the image SA-8507_00012.jpg contained in the attached Zip archive using the attached test class JPEGTest.
###@###.### 2004-12-22 00:19:27 GMT

Comments
EVALUATION According to the frame header (SOF) of images SA-8507_00004-willnotwork.jpg and SA-8507_00012.jpg these images contains 3 components (YCbCr). However, the scan header (SOS) contains Huffman table selector only for one component (Y) (number components in the scan is 1). The reported exception occurs when data from uninitialized color components are pushed to the JPEGParam instance. The solution is to ignore uninitialized color components (consider the given image as greyscaled, according to the SOS marker data). ###@###.### 2004-12-22 16:43:28 GMT It looks like that images in questions have multiple SOS markers (one per each component declared in the SOF marker). Formally such images are legal according to JPEG specification and imageio jpeg reader handles them correctly. Our decoder has a problem - we allocate memory for all components declared in the SOF marker but do not wipe it with zeros. In most of cases this works ok because we explicitly initialize all component related data when we meet the SOS marker. However, in the this particular case first SOS marker contains data only for one component. As a result two other components are not initialized and contain random data. Moreover, first occurrence of SOS marker makes us assume that header of jpeg images is already completely processed. So, we try to push the component related data to the java object (instance of the JPEGParam). And here we may encounter data validity assertion due to junk passed in. Proposed solution is to explicitly initialize all component structures (by wiping allocated memory). Note that two other components will be initialized later when we meet corresponding SOS markers during decoding of compressed data. But we need to add some code to copy these updates to java object. ###@###.### 2005-1-13 17:41:38 GMT This issue was occuring because of uninitialized component structure rolling over in further processing. Normally this will not happen because these ones eventually gets filled with valid values being read from JPEG image. Since here SOF indicates YCbCR but SOS delivers huffman tables only for Y, remanining never got initialized which untimately results as exception from Java code because of funny values in comp_info. Fixed the issue by initializing comp_info structure before putting it to use. ###@###.### Jan 31 19:02:10 IST 2005 ###@###.### 2005-1-31 13:36:02 GMT
22-12-2004

WORK AROUND Use the core Java Image I/O Framework or the JPEG plug-in in JAI-Image I/O Tools both of which can read the problematic images. A straightforward replacement of "FileLoad" with "ImageRead" from JAI-Image I/O Tools should suffice. ###@###.### 2004-12-22 00:19:28 GMT
22-12-2004