You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2008/04/21 10:25:32 UTC

svn commit: r650048 - in /xmlgraphics/commons/trunk: src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java status.xml

Author: jeremias
Date: Mon Apr 21 01:25:22 2008
New Revision: 650048

URL: http://svn.apache.org/viewvc?rev=650048&view=rev
Log:
Bugfix: Field alignment in ICC color profiles are by 4 bytes, not 8.
Bugfix: ICC chunks were cut short by two bytes which could lead to parse errors or yellow-tinted images.

Modified:
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java
    xmlgraphics/commons/trunk/status.xml

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java?rev=650048&r1=650047&r2=650048&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/image/loader/impl/ImageLoaderRawJPEG.java Mon Apr 21 01:25:22 2008
@@ -21,6 +21,8 @@
 
 import java.awt.color.ColorSpace;
 import java.awt.color.ICC_Profile;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
 import java.io.IOException;
 import java.util.Map;
 
@@ -82,15 +84,15 @@
             while (true) {
                 int reclen;
                 int segID = jpeg.readMarkerSegment();
-                if (log.isDebugEnabled()) {
-                    log.debug("Seg Marker: " + Integer.toHexString(segID));
+                if (log.isTraceEnabled()) {
+                    log.trace("Seg Marker: " + Integer.toHexString(segID));
                 }
                 switch (segID) {
                 case EOI:
-                    log.debug("EOI found. Stopping.");
+                    log.trace("EOI found. Stopping.");
                     break outer;
                 case SOS:
-                    log.debug("SOS found. Stopping early."); //TODO Not sure if this is safe
+                    log.trace("SOS found. Stopping early."); //TODO Not sure if this is safe
                     break outer;
                 case SOI:
                 case NULL:
@@ -99,8 +101,8 @@
                 case SOF2: //progressive (since PDF 1.3)
                 case SOFA: //progressive (since PDF 1.3)
                     sofType = segID;
-                    if (log.isDebugEnabled()) {
-                        log.debug("SOF: " + Integer.toHexString(sofType));
+                    if (log.isTraceEnabled()) {
+                        log.trace("SOF: " + Integer.toHexString(sofType));
                     }
                     in.mark();
                     try {
@@ -137,18 +139,24 @@
                         in.skipBytes(1); //string terminator (null byte)
 
                         if ("ICC_PROFILE".equals(new String(iccString, "US-ASCII"))) {
-                            log.debug("JPEG has an ICC profile");
                             in.skipBytes(2); //chunk sequence number and total number of chunks
+                            int payloadSize = reclen - 2 - 12 - 2;
                             if (ignoreColorProfile(hints)) {
-                                in.skipBytes(reclen - 18);
+                                log.debug("Ignoring ICC profile data in JPEG");
+                                in.skipBytes(payloadSize);
                             } else {
+                                byte[] buf = new byte[payloadSize];
+                                in.readFully(buf);
                                 if (iccStream == null) {
+                                    if (log.isDebugEnabled()) {
+                                        log.debug("JPEG has an ICC profile");
+                                        DataInputStream din = new DataInputStream(new ByteArrayInputStream(buf));
+                                        log.debug("Declared ICC profile size: " + din.readInt());
+                                    }
                                     //ICC profiles can be split into several chunks
                                     //so collect in a byte array output stream
                                     iccStream = new ByteArrayOutputStream();
                                 }
-                                byte[] buf = new byte[reclen - 18];
-                                in.readFully(buf);
                                 iccStream.write(buf);
                             }
                         }
@@ -209,7 +217,11 @@
     private ICC_Profile buildICCProfile(ImageInfo info, ColorSpace colorSpace,
             ByteArrayOutputStream iccStream) throws IOException, ImageException {
         if (iccStream != null && iccStream.size() > 0) {
-            int padding = (8 - (iccStream.size() % 8)) % 8;
+            if (log.isDebugEnabled()) {
+                log.debug("Effective ICC profile size: " + iccStream.size());
+            }
+            final int alignment = 4;
+            int padding = (alignment - (iccStream.size() % alignment)) % alignment;
             if (padding != 0) {
                 try {
                     iccStream.write(new byte[padding]);
@@ -217,12 +229,15 @@
                     throw new IOException("Error while aligning ICC stream: " + ioe.getMessage());
                 }
             }
+            
             ICC_Profile iccProfile = null;
             try {
                 iccProfile = ICC_Profile.getInstance(iccStream.toByteArray());
-                log.debug("JPEG has an ICC profile: " + iccProfile.toString());
+                if (log.isDebugEnabled()) {
+                    log.debug("JPEG has an ICC profile: " + iccProfile.toString());
+                }
             } catch (IllegalArgumentException iae) {
-                log.warn("An ICC profile is present but it is invalid (" 
+                log.warn("An ICC profile is present in the JPEG file but it is invalid (" 
                         + iae.getMessage() + "). The color profile will be ignored. (" 
                         + info.getOriginalURI() + ")");
                 return null;

Modified: xmlgraphics/commons/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/status.xml?rev=650048&r1=650047&r2=650048&view=diff
==============================================================================
--- xmlgraphics/commons/trunk/status.xml (original)
+++ xmlgraphics/commons/trunk/status.xml Mon Apr 21 01:25:22 2008
@@ -41,6 +41,9 @@
   <changes>
     <release version="Trunk" date="n/a">
       <action context="Code" dev="JM" type="add">
+        Bugfix for extracting ICC color profiles from JPEG images.
+      </action>
+      <action context="Code" dev="JM" type="add">
         Added an image loader for XML Graphics Commons' internal TIFF codec.
       </action>
       <action context="Code" dev="JM" type="fix">



---------------------------------------------------------------------
Apache XML Graphics Project URL: http://xmlgraphics.apache.org/
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org