JDK-4845461 : ImageIO fails to read a corrupted JPEG image
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-04-09
  • Updated: 2010-07-09
  • Resolved: 2011-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.
JDK 7
7 b03Fixed
Related Reports
Relates :  
Description
I tried reading a corrupted JPEG image using ImageIO as well as Toolkit API. Toolkit API is able to read this image properly where as ImageIO returns an image where the colors are totally distorted. I also tried reading this image using JPEGImageDecoderImpl but the VM crashes. However, a separate bug has been filed against this VM crash. 

How to reproduce: 
I have attached a sample code and the corrupted image. Save them in the same directory and run the sample code. You would see 2 different images. The first image will be normal(Toolkit API) where as the colors will be inverted in the second image (ImageIO).
I am able to reproduce this with JDK1.4.0 as well as JDK 1.4.2 - b19, on Solaris and Win32 platforms.

Comments
EVALUATION The test image have two important peculiarities: - APP0 segment is erased - horizontal and vertical sampling factors are 1 for all component. Why ImageIO jpeg reader experiences problem with this image? Due to erased APP0 segment, decoder does not set saw_JFIF_marker flag. In this case we are use some heuristic rules to detect the color space used in the image. First used rule is based on the component ID values. According to this, the YCbCr used in this image (that seems to be correct for this image, but does not work in general: for example NoAPP0_RGB.jpg has component ID as for YCbCr case but actually uses RGB color space). However, because we did not saw JFIF marker, we are trying to verify the color case using the sampling factors (added as part of fix for 4776576). Unfortunately, this rule give us wrong results and we mistakenly chose RGB color space. It looks like that only way that allows us to handle such images correctly is to set saw_JFIF_marker flag to true. This flag trigger us to use YCbCr color space that solves the problem. Why this way of saw_JFIF_marker flag is safe? In general, this flag is used to indicate that we are working with JFIF image. However, this flag also trigges copying of information retrieved from APP0 marker (related to version and units density): 1. jdmarker.c:228 just initialization to default values. The info related to version and density is initialized by default values too. 2. jdmarker.c:610 We skip getting APPO0 related info because length and content of APP0 marker is invalid. All related fields contain default values due to initialization made on lines 228 - 233. However, we saw JFIF marker and this fact is important for making correct chose of jpeg color space later. The version and density info contain default values, so it seems to be safe switch on corresponding flag. 3. jctrans.c:147 Here we use this flag to trigger information copying. According to comment, this information is not critical for application, however we should avoid mess. However, if we switch saw_JFIF_marker flag on for erased/corrupted APP0 and leave default values in place, then it seems to be safe just copy default values here. 4. imageioJPEG.c:1621 Here we use saw_JFIF_marker flag to correct the jpeg color space. This place is source of problem: if we did not set this flag for erased APP0 marker, then we have no ways to distinguish cases of erased APP0 and RGB without APPO because both these formats uses same data layout.
03-10-2006