JDK-4712797 : ImageIO fails to decode YCbCr JPEGs that do not have a JFIF marker
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt,windows_2000
  • CPU: x86
  • Submitted: 2002-07-10
  • Updated: 2002-10-16
  • Resolved: 2002-10-16
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
1.4.2 mantisFixed
Related Reports
Duplicate :  
Relates :  
Description

Name: gm110360			Date: 07/10/2002


FULL PRODUCT VERSION :
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

also

java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b14)
Java HotSpot(TM) Client VM (build 1.4.1-beta-b14, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
ImageIO fails to properly decode a YCbCr JPEG that is not
subsampled and that does not contain a JFIF marker - it
assumes the JPEG is RGB and so the decoded image has its
colors shifted and distorted.

Some popular digital cameras create YCbCr JPEGs with no
JFIF marker - all other applications I have tried are able
to properly decode these images (they assume YCbCr). The
Independent JPEG Group reference implementation is also
able to decode these images (it assumes YCbCr). Java is
able to decode these images when using the
java.awt.Toolkit.createImage().

Only Java ImageIO fails to decode this type of image. The
following piece of code in the JDK 1.4 source explains why:
j2se\src\share\native\sun\awt\image\jpeg\imageioJPEG.c

} else if (!cinfo->saw_JFIF_marker) {  // We saw neither
marker
	/*
	 * IJG assumes all unidentified 3-channels are YCbCr
	 * We assume that only if the second two channels
are
	 * subsampled.  If not, we assume RGB
	 */
	h_samp0 = cinfo->comp_info[0].h_samp_factor;
	h_samp1 = cinfo->comp_info[1].h_samp_factor;
	h_samp2 = cinfo->comp_info[2].h_samp_factor;
	// Nobody does vertical without horizontal, so just
check horiz
	if ((h_samp1 == h_samp0) && (h_samp2 == h_samp0))  {
		cinfo->jpeg_color_space = JCS_RGB;
		/* output is already RGB, so it stays the
same */
	}
}

If no JFIF marker was found, and the second 2 channels are
not subsampled, then ImageIO assumes RGB instead of YCbCr.

This isn't necessarily "wrong" since the spec does not
define what to assume, but doing this makes Java behave
differently than it used to, and differently from virtually
all other apps/toolkits (many of which are based on the IJG
implementation which assumes YCbCr). Why be gratuitously
incompatible?

I am listing this bug as a regression because JDK 1.3.1 was
able to decode this type of JPEG using java.awt.Toolkit
(1.4 can as well, but 1.4 fails to decode with ImageIO).

REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the attached program: java JpegView
http://www.photica.com/aw/flowers.jpg
2. flowers.jpg is a YCbCr JPEG with no JFIF marker and no
subsampling. JpegView displays a window, the image on the
left was decoded with ImageIO and is wrong, the image on
the right was decoded with java.awt.Toolkit.createImage()
and looks correct

EXPECTED VERSUS ACTUAL BEHAVIOR :
Both images should look like the image on the right.
ImageIO should not behave differently from the
java.awt.Toolkit JPEG decoder and from every other
application.

If you run JpegView with
http://www.photica.com/aw/flowers_jfif.jpg you can see
ImageIO properly decode the JPEG - the only difference
between flowers_jfif.jpg and flowers.jpg is that
flowers_jfif.jpg contains an APP0 JFIF marker.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.imageio.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;

public class JpegView {
	public static void main(String args[]) throws Exception {
		if (args.length < 1) {
			System.err.println("Usage: JpegView <jpeg-url>");
			System.exit(1);
		}
		ImageIcon iiImageIO = new ImageIcon(ImageIO.read(new URL(args
[0])));
		ImageIcon iiToolkit = new ImageIcon(Toolkit.getDefaultToolkit
().createImage(new URL(args[0])));

		JFrame f= new JFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JLabel lblImageIO = new JLabel(iiImageIO);
		JLabel lblToolkit = new JLabel(iiToolkit);
		f.getContentPane().add(lblImageIO, BorderLayout.WEST);
		f.getContentPane().add(lblToolkit, BorderLayout.EAST);
		f.pack();
		f.setVisible(true);
	}
}

---------- END SOURCE ----------
(Review ID: 158677) 
======================================================================

###@###.### 2002-08-07

CAP member reports the same problem which prevents them from using the 
imageio library. The problem is that sometimes, reading in jpeg images using imageio results in shifted colors.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b04
14-06-2004

EVALUATION Should be a simple fix (as specified in the description). We should make sure the ImageIO JPEG plugin behaves similar to the Toolkit decoder. Committing to mantis. ###@###.### 2002-08-07 We should remove the conditional block starting at line 1579 in imageioJPEG.c. This check incorrectly assumes that JPEG images without an APP0 JFIF marker and no subsampling have an RGB color space. As seen above, it is possible to have non-subsampled YCbCr JPEG images. The Image I/O JPEGImageReader will now be consistent with the Toolkit reader, the com.sun decoder, and many other popular JPEG decoding applications. ###@###.### 2002-09-18 There are some subtleties in the fix for this bug that caused a regression with certain other JPEG images. Please see 4776576 for a more complete description of the problem and a more general solution that fixes both bugs (4712797 and 4776576). ###@###.### 2002-11-12
12-11-2002

SUGGESTED FIX Remove conditional block starting at line 1579 in imageioJPEG.c. ###@###.### 2002-09-18
18-09-2002