[Image-SIG] Embedded ICC profiles - patches for JPEG, PNG, PSD, TIFF (PIL 1.1.6)

Florian Höch lists+Image_SIG at hoech.org
Sat Apr 12 18:00:50 CEST 2008


Hello Frédéric,

here are the patches:

--- JpegImagePlugin.py.bak	Sat Feb 23 01:48:22 2008
+++ JpegImagePlugin.py	Sat Mar 08 07:39:58 2008
@@ -81,6 +81,28 @@
      elif marker == 0xFFE2 and s[:5] == "FPXR\0":
          # extract FlashPix information (incomplete)
          self.info["flashpix"] = s # FIXME: value will change
+    elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0":
+        # Since an ICC profile can be larger than the maximum size of
+        # a JPEG marker (64K), we need provisions to split it into
+        # multiple markers. The format defined by the ICC specifies
+        # one or more APP2 markers containing the following data:
+        #   Identifying string      ASCII "ICC_PROFILE\0"  (12 bytes)
+        #   Marker sequence number  1, 2, etc (1 byte)
+        #   Number of markers       Total of APP2's used (1 byte)
+        #   Profile data            (remainder of APP2 data)
+        # Decoders should use the marker sequence numbers to
+        # reassemble the profile, rather than assuming that the APP2
+        # markers appear in the correct sequence.
+        if not self.info.has_key("icc_profile"):
+            self.icc_profile_marker_prev = "\0"
+            self.info["icc_profile"] = ""
+        icc_profile_marker_curr = s[12]
+        if self.icc_profile_marker_prev < icc_profile_marker_curr:
+            self.info["icc_profile"] += s[14:]
+        else:
+            self.info["icc_profile"] = s[14:] + \
+            self.info["icc_profile"]
+        self.icc_profile_marker_prev = icc_profile_marker_curr
      elif marker == 0xFFEE and s[:5] == "Adobe":
          self.info["adobe"] = i16(s, 5)
          # extract Adobe custom properties



--- PngImagePlugin.py.bak	Sat Feb 23 01:10:49 2008
+++ PngImagePlugin.py	Sat Feb 23 02:18:38 2008
@@ -32,7 +32,7 @@
  import re, string

  import Image, ImageFile, ImagePalette
-
+import zlib

  def i16(c):
      return ord(c[1]) + (ord(c[0])<<8)
@@ -174,6 +174,19 @@
          self.im_mode = None
          self.im_tile = None
          self.im_palette = None
+
+    def chunk_iCCP(self, pos, len):
+
+        # ICC profile
+        s = ImageFile._safe_read(self.fp, len)
+        # according to PNG spec, the iCCP chunk contains:
+        # Profile name 	1-79 bytes (character string)
+        # Null separator 	1 byte (null character)
+        # Compression method 	1 byte (0)
+        # Compressed profile 	n bytes (zlib with deflate compression)
+        i = string.find(s, chr(0))
+        self.im_info["icc_profile"] = zlib.decompress(s[i+2:])
+        return s

      def chunk_IHDR(self, pos, len):



--- PsdImagePlugin.py.bak	Sat Jun 03 11:58:20 2006
+++ PsdImagePlugin.py	Sat Feb 23 21:10:48 2008
@@ -108,6 +108,8 @@
                  if (len(data) & 1):
                      read(1) # padding
                  self.resources.append((id, name, data))
+                if id == 1039: # ICC profile
+                    self.info["icc_profile"] = data

          #
          # layer and mask information



--- TiffImagePlugin.py.bak	Sat Apr 12 17:50:29 2008
+++ TiffImagePlugin.py	Sat Feb 23 02:06:57 2008
@@ -102,6 +102,7 @@
  COPYRIGHT = 33432
  IPTC_NAA_CHUNK = 33723 # newsphoto properties
  PHOTOSHOP_CHUNK = 34377 # photoshop properties
+ICCPROFILE = 34675

  COMPRESSION_INFO = {
      # Compression => pil compression name
@@ -515,6 +516,9 @@
              if self.tag.has_key(317):
                  # Section 14: Differencing Predictor
                  self.decoderconfig = (self.tag[PREDICTOR][0],)
+
+        if self.tag.has_key(ICCPROFILE):
+            self.info['icc_profile'] = self.tag[ICCPROFILE]

          return args



Regards,

Florian

Frédéric Mantegazza schrieb:
> Could you provide a complete patch against the current 1.1.6 version?



More information about the Image-SIG mailing list