JDK-4893408 : JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 1.4.0,5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-07-21
  • Updated: 2009-03-07
  • Resolved: 2009-03-07
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.
6u14 b03Fixed 7Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
The specification for param.setDestination() claims that the destination specified must be one of the type specifiers returned by reader.getImageTypes(). JPEGImageReader returns 3 destination image types.
TYPE_3BYTE_BGR, TYPE_BYTE_GRAY and TYPE_CUSTOM. Out of these, when i set the destination to TYPE_BYTE_GRAY, i am getting an illegal argument exception saying the no. of source and destination bands differ. I created this destination buffered image through ImageTypeSpecifier.createBufferedImage() and I expect the type specifier to handle such incompatibilites. The specification gives an impression that setting a destination will work fine if it is one of the types returned by getImageTypes(). It does not say that the application has to handle the band incompatibilities between the source and destination images. This seem to work fine for all other readers and all other image types returned by getImageTypes().

This is reproducible on all platforms right from JDK1.4+.

I have attached a sample code. Execute the sample code as follows.
java SetDestinationTest <img file>
Choose the buffered image type from the drop-down. For JPEG, if you choose the TYPE_BYTE_GRAY buffered image, you will get an IllegalArgumentException. Try with other image types and compare the behavior.

EVALUATION This fix resolves problem with handling destination type for the case when number of color components differs form number of color components in the jpeg image. Particularly, it happens when we read YCbCr image (3 components) as a grayscale (1 component), and, the opposite case, when we read grayscaled jpeg as a RGB image. To resolve this problem we need to: - adjust java state of the reader after changing output color space (method JPEGImageReader.checkColorConversion(), lines 900 - 903 and 913 - 916) and set output color space code and number of color components according to requested output color space. - use output_component instead of num_components in the native readImage() for checks and buffer allocations, because this variable describes format of decoded data, whereas num_components refers to number of components declared in the jpeg header. The variable output_components is calculated during the decoder start, so we have to postpone verification of number of requested bands and allocation of scanline buffer until the decoder is started. The rest of changes made initialization of image type specifiers a bit more lazy: we do not create specifier until the explicit usage. In combination with postponed initialization of YCC color space, it gives a chance to avoid CMM initialization and profiles loading if user decoders only sRGB or grayscaled representation of jpeg image. Another change in this version is in ICC_Profile.java. Unfortunately, our deferring strategy cause failures in case of windows online installation, where PYCC profile is not present. So we have to check whether this profile is available before creation of deferred profile instance: - for case non-jkernel (or completed jkernel) installation we should check availability of the PYCC profile file and produce deferred instance only if this file exists. - for active jkernel case we can create deferred profile for PYCC because at the moment jkernel alway have the profiles bundle. Probably, this case should be re-visited if jkernel bundling strategy will be changed.