Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4712797

ImageIO fails to decode YCbCr JPEGs that do not have a JFIF marker

XMLWordPrintable

    • mantis
    • x86
    • windows_nt, windows_2000



      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.

            campbell Christopher Campbell (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: