[Image-SIG] patch for more TIFF tags when saving TIFF images

Greg Couch gregc@cgl.ucsf.EDU
Fri, 11 May 2001 17:42:30 -0700 (PDT)


Then enclosed patch adds support for more TIFF tags, namely the
Artist, Copyright, DateTime, ResolutionUnit, Software, XResolution
and YResolution tags.  The trickiest part was adding support for
TIFF rational numbers.  Hope this makes it into the next release,

	Greg Couch
	UCSF Computer Graphics Lab
	gregc@cgl.ucsf.edu

===================================================================
RCS file: RCS/TiffImagePlugin.py,v
retrieving revision 1.1
diff -c -r1.1 TiffImagePlugin.py
*** TiffImagePlugin.py	2001/05/11 23:37:24	1.1
--- TiffImagePlugin.py	2001/05/12 00:26:56
***************
*** 66,77 ****
--- 66,84 ----
  SAMPLESPERPIXEL = 277
  ROWSPERSTRIP = 278
  STRIPBYTECOUNTS = 279
+ X_RESOLUTION = 282
+ Y_RESOLUTION = 283
  PLANAR_CONFIGURATION = 284
+ RESOLUTION_UNIT = 296
+ SOFTWARE = 305
+ DATE_TIME = 306
+ ARTIST = 315
  PREDICTOR = 317
  COLORMAP = 320
  EXTRASAMPLES = 338
  SAMPLEFORMAT = 339
  JPEGTABLES = 347
+ COPYRIGHT = 33432
  IPTC_NAA_CHUNK = 33723 # newsphoto properties
  PHOTOSHOP_CHUNK = 34377 # photoshop properties
  
***************
*** 313,318 ****
--- 320,328 ----
                  if tag == STRIPOFFSETS:
                      stripoffsets = len(directory)
                      typ = 4 # to avoid catch-22
+                 elif tag in (X_RESOLUTION, Y_RESOLUTION):
+                     # identify rational data fields
+                     typ = 5
                  else:
                      typ = 3
                      for v in value:
***************
*** 329,335 ****
              elif len(data) < 4:
                  append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
              else:
!                 append((tag, typ, len(value), o32(offset), data))
                  offset = offset + len(data)
                  if offset & 1:
                      offset = offset + 1 # word padding
--- 339,348 ----
              elif len(data) < 4:
                  append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
              else:
!                 count = len(value)
!                 if typ == 5:
!                     count = count / 2        # adjust for rational data field
!                 append((tag, typ, count, o32(offset), data))
                  offset = offset + len(data)
                  if offset & 1:
                      offset = offset + 1 # word padding
***************
*** 551,556 ****
--- 564,579 ----
      "LAB": ("LAB", 8, 1, (8,8,8), None),
  }
  
+ def _cvt_res(value):
+     # convert value to TIFF rational number -- (numerator, denominator)
+     if type(value) in (type([]), type(())):
+         assert(len(value) % 2 == 0)
+         return value
+     if type(value) == type(1):
+         return (value, 1)
+     value = float(value)
+     return (int(value * 65536), 65536)
+ 
  def _save(im, fp, filename):
  
      try:
***************
*** 566,573 ****
--- 589,626 ----
      ifd[IMAGEWIDTH] = im.size[0]
      ifd[IMAGELENGTH] = im.size[1]
  
+     # additions written by Greg Couch, gregc@cgl.ucsf.edu
+     # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
+     if hasattr(im, 'tag'):
+         # preserve tags from original TIFF image file
+         for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
+             if im.tag.tagdata.has_key(key):
+                 ifd[key] = im.tag.tagdata.get(key)
      if im.encoderinfo.has_key("description"):
          ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"]
+     if im.encoderinfo.has_key("resolution"):
+         ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \
+                                 = _cvt_res(im.encoderinfo["resolution"])
+     if im.encoderinfo.has_key("x resolution"):
+         ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"])
+     if im.encoderinfo.has_key("y resolution"):
+         ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"])
+     if im.encoderinfo.has_key("resolution unit"):
+         unit = im.encoderinfo["resolution unit"]
+         if unit == "inch":
+             ifd[RESOLUTION_UNIT] = 2
+         elif unit == "cm" or unit == "centimeter":
+             ifd[RESOLUTION_UNIT] = 3
+         else:
+             ifd[RESOLUTION_UNIT] = 1
+     if im.encoderinfo.has_key("software"):
+         ifd[SOFTWARE] = im.encoderinfo["software"]
+     if im.encoderinfo.has_key("date time"):
+         ifd[DATE_TIME] = im.encoderinfo["date time"]
+     if im.encoderinfo.has_key("artist"):
+         ifd[ARTIST] = im.encoderinfo["artist"]
+     if im.encoderinfo.has_key("copyright"):
+         ifd[COPYRIGHT] = im.encoderinfo["copyright"]
  
      if bits != (1,):
          ifd[BITSPERSAMPLE] = bits