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

ImageIO JPEG encoder fails due to missing PYCC.pf in JRE

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      1.7.0 update 1 and 1.6.0_31

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7, Windows XP, probably affects every OS

      A DESCRIPTION OF THE PROBLEM :
      Writing a JPEG with ImageIO fails if the image's colorspace is not one of the standard colorspaces. The problem was originally reported in Bug #4668557, but the bug report makes it sound like the user was trying to use the PYCC colorspace. It turns out you can hit the bug if your image is any non-standard colorspace.

      The PYCC.pf color profile was removed from the JRE back in 2002. Unfortunately, when they removed that file they didn't do a thorough job of updating the JPEG encoder to tolerate missing this file.

      Specifically, the isNonStandardICC() method in com.sun.imageio.plugins.jpeg.JPEG needs to be updated to tolerate the missing PYCC color profile. The isNonStandardICC() method is called during JPEG encoding and during creation of JPEG metadata objects. As a result, saving images with non-standard color spaces causes exceptions in most deployed JREs.

      The PYCC.pf file is included in the JREs inside the JDK, so everything works fine on development computers, but not on production machines.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.IllegalArgumentException: Can't load standard profile: PYCC.pf
      at java.awt.color.ICC_Profile$2.run(ICC_Profile.java:894)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.awt.color.ICC_Profile.getStandardProfile(ICC_Profile.java:887)
      at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:848)
      at java.awt.color.ColorSpace.getInstance(ColorSpace.java:303)
      at com.sun.imageio.plugins.jpeg.JPEG.isNonStandardICC(JPEG.java:227)
      at com.sun.imageio.plugins.jpeg.JPEGMetadata.<init>(JPEGMetadata.java:570)
      at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:640)
      at javax.imageio.ImageWriter.write(ImageWriter.java:580)
      at com.lifetouch.lti.image.jai.ProfileChecker.main(ProfileChecker.java:41)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      import java.awt.Transparency;
      import java.awt.color.ICC_ColorSpace;
      import java.awt.color.ICC_Profile;
      import java.awt.image.BufferedImage;
      import java.awt.image.ColorModel;
      import java.awt.image.ComponentColorModel;
      import java.awt.image.DataBuffer;
      import java.awt.image.WritableRaster;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.util.Iterator;

      import javax.imageio.IIOImage;
      import javax.imageio.ImageIO;
      import javax.imageio.ImageWriter;
      import javax.imageio.stream.ImageOutputStream;

      public class ProfileChecker {

      public static void main(String[] args) throws IOException {
      // Use any color profile here
      String profileFileName = "/usr/lib/jdk1.6.0_12/jre/lib/cmm/sRGB.pf";

      ICC_Profile srgbProfile = ICC_Profile.getInstance(profileFileName);
      ICC_ColorSpace srgbSpace = new ICC_ColorSpace(srgbProfile);

      ColorModel colorModel = new ComponentColorModel(srgbSpace, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
      int imageSize = 10;
      WritableRaster raster = colorModel.createCompatibleWritableRaster(imageSize, imageSize);

      BufferedImage bimage = new BufferedImage(colorModel, raster, false, null);

      ImageWriter imageWriter = getImageWriter();

      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);

      imageWriter.setOutput(ios);
      imageWriter.write(new IIOImage(bimage, null, null));
      }

      private static ImageWriter getImageWriter() {
      String desiredWriter = "com.sun.imageio.plugins.jpeg.JPEGImageWriter";

      Iterator<ImageWriter> writerIter = ImageIO.getImageWritersByFormatName("jpeg");
      while (writerIter.hasNext()) {
      ImageWriter writer = writerIter.next();
      if (writer.getClass().getName().equals(desiredWriter)) {
      return writer;
      }
      }
      return null;
      }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      The image writer that comes with JAI ImageIO Tools does not appear to have this bug.

      Attachments

        Activity

          People

            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: