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

JPEGImageWriter corrupts color for non-JFIF images with differing sample factors

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4
    • 9
    • 5.0
    • client-libs
    • b52
    • x86
    • windows_xp

    Backports

      Description

        FULL PRODUCT VERSION :
        1.4 ; 1.5.0_01; 1.5.0_02

        ADDITIONAL OS VERSION INFORMATION :
        Windows XP (irrelevant)

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Jpeg image coming from some Canon digital SLR camera, prealably rotated by Windows XP explorer or auto-rotated by the Canon camera itself.

        A DESCRIPTION OF THE PROBLEM :
        Take an image that has been rotated - problem seen with the Windows XP rotating tool in the explorer (right-click on a thumbnail) and with photo directly rotated by the camera (auto-rotated mode) - , read it fully as a IIOImage then save it (with metadata). The image color appears all magenta, like if an offset has been applied to the original color.
        This happens only with some camera (don't know why, I'm not a JPeg guru). if you rotated it witha tool, like photoshop, that create a JFIF marker it works fine.

        After hours of debugging it seems (not sure though) that the problem comes from the following method found in the com.sun.imageio.plugins.jpeg.JPEGImageWriter class:
            private boolean isSubsampled(SOFMarkerSegment.ComponentSpec [] specs) {
                int hsamp0 = specs[0].HsamplingFactor;
                int vsamp0 = specs[0].VsamplingFactor;
                for (int i = 1; i < specs.length; i++) {
                    if ((specs[i].HsamplingFactor != hsamp0) ||
                        (specs[i].HsamplingFactor != hsamp0))
                        return true;
                }
                return false;
            }

        if you look closer to the if condition you'll see that same condition is repeated twice ! I think (quite sure) that the condition should be:
                     if ((specs[i].HsamplingFactor != hsamp0) ||
                        (specs[i].VsamplingFactor != vsamp0))
                        return true;

        It makes me wonder if there is any kind of code review or code inspection procedure at SUN, as a half-decent IDE or code inspector will notify that the variable vsamp0 is not used in this method.

        Could you please fix this bug in the next release.


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        See reproducing code below.
        it depends of the image. I found no way to upload in the bug database the image. I'll be happy to email or ftp a sample of an image causing the problem.
        Once you have the image you name it 'prop.jpg', then youn run the class TestJpegProb on the same directory and you look at the result 'prob-output.jpg'


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import javax.imageio.ImageIO;
        import javax.imageio.IIOImage;
        import javax.imageio.ImageReader;
        import javax.imageio.ImageWriter;
        import javax.imageio.metadata.IIOMetadata;
        import javax.imageio.stream.FileImageInputStream;
        import javax.imageio.stream.FileImageOutputStream;
        import javax.imageio.plugins.jpeg.JPEGImageReadParam;
        import java.io.File;
        import java.io.IOException;


        public class TestJpegProb {

          public static void main(String[] args) throws IOException {
            File src = new File("./prob.jpg");
            File des = new File("./prob-output.jpg");

            ImageReader reader = (ImageReader) ImageIO.getImageReadersByFormatName("JPEG").next();
            ImageWriter writer = (ImageWriter)ImageIO.getImageWritersByFormatName("JPEG").next();

            reader.setInput(new FileImageInputStream(src));

            IIOImage iimage = reader.readAll(0,new JPEGImageReadParam());
            reader.dispose();
        // iimage.setMetadata(null); //if you uncomment this line it works, even if the image doesn't contain metadata (APPn marker)

            writer.setOutput(new FileImageOutputStream(des));
            writer.write(iimage);

            writer.dispose();
          }
        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        1-you have to set the metadata of the IIOImage to null.
        But this has nothing to do with the metadata of the image has I can reproduce the error with an image purged of all APPn marker.
        This make impossible for me to use ImageIO to keep the Exif metadata stored in the image.

        2-you rotate the image by a software (like photoshop) that creates a JFIF marker.
        ###@###.### 2005-03-21 07:07:07 GMT

        Attachments

          Issue Links

            Activity

              People

                prr Philip Race
                jssunw Jitender S (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: