home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pypil112.zip / PIL-1.1.2.zip / Lib / site-packages / PIL / TiffImagePlugin.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2001-12-25  |  21KB  |  534 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.2)
  3.  
  4. __version__ = '1.1'
  5. import Image
  6. import ImageFile
  7. import ImagePalette
  8. import string
  9.  
  10. def il16(c, o = 0):
  11.     return ord(c[o]) + (ord(c[o + 1]) << 8)
  12.  
  13.  
  14. def il32(c, o = 0):
  15.     return ord(c[o]) + (ord(c[o + 1]) << 8) + (ord(c[o + 2]) << 16) + (ord(c[o + 3]) << 24)
  16.  
  17.  
  18. def ol16(i):
  19.     return chr(i & 255) + chr(i >> 8 & 255)
  20.  
  21.  
  22. def ol32(i):
  23.     return chr(i & 255) + chr(i >> 8 & 255) + chr(i >> 16 & 255) + chr(i >> 24 & 255)
  24.  
  25.  
  26. def ib16(c, o = 0):
  27.     return ord(c[o + 1]) + (ord(c[o]) << 8)
  28.  
  29.  
  30. def ib32(c, o = 0):
  31.     return ord(c[o + 3]) + (ord(c[o + 2]) << 8) + (ord(c[o + 1]) << 16) + (ord(c[o]) << 24)
  32.  
  33. IMAGEWIDTH = 256
  34. IMAGELENGTH = 257
  35. BITSPERSAMPLE = 258
  36. COMPRESSION = 259
  37. PHOTOMETRIC_INTERPRETATION = 262
  38. IMAGEDESCRIPTION = 270
  39. STRIPOFFSETS = 273
  40. SAMPLESPERPIXEL = 277
  41. ROWSPERSTRIP = 278
  42. STRIPBYTECOUNTS = 279
  43. PLANAR_CONFIGURATION = 284
  44. PREDICTOR = 317
  45. COLORMAP = 320
  46. EXTRASAMPLES = 338
  47. SAMPLEFORMAT = 339
  48. JPEGTABLES = 347
  49. IPTC_NAA_CHUNK = 33723
  50. PHOTOSHOP_CHUNK = 34377
  51. COMPRESSION_INFO = {
  52.     1: 'raw',
  53.     2: 'tiff_ccitt',
  54.     3: 'group3',
  55.     4: 'group4',
  56.     5: 'tiff_lzw',
  57.     6: 'tiff_jpeg',
  58.     7: 'jpeg',
  59.     32771: 'tiff_raw_16',
  60.     32773: 'packbits' }
  61. OPEN_INFO = {
  62.     (0, 1, (1,), ()): ('1', '1;I'),
  63.     (0, 1, (8,), ()): ('L', 'L;I'),
  64.     (1, 1, (1,), ()): ('1', '1'),
  65.     (1, 1, (8,), ()): ('L', 'L'),
  66.     (1, 2, (16,), ()): ('I;16', 'I;16'),
  67.     (1, 2, (32,), ()): ('I', 'I;32S'),
  68.     (1, 3, (32,), ()): ('F', 'F;32F'),
  69.     (2, 1, (8, 8, 8), ()): ('RGB', 'RGB'),
  70.     (2, 1, (8, 8, 8, 8), (0,)): ('RGBX', 'RGBX'),
  71.     (2, 1, (8, 8, 8, 8), (2,)): ('RGBA', 'RGBA'),
  72.     (3, 1, (1,), ()): ('P', 'P;1'),
  73.     (3, 1, (2,), ()): ('P', 'P;2'),
  74.     (3, 1, (4,), ()): ('P', 'P;4'),
  75.     (3, 1, (8,), ()): ('P', 'P'),
  76.     (5, 1, (8, 8, 8, 8), ()): ('CMYK', 'CMYK'),
  77.     (6, 1, (8, 8, 8), ()): ('YCbCr', 'YCbCr'),
  78.     (8, 1, (8, 8, 8), ()): ('LAB', 'LAB') }
  79. PREFIXES = [
  80.     'MM\x00*',
  81.     'II*\x00']
  82.  
  83. def _accept(prefix):
  84.     return prefix[:4] in PREFIXES
  85.  
  86.  
  87. class ImageFileDirectory:
  88.     
  89.     def __init__(self, prefix = 'II'):
  90.         if not __debug__ and prefix in ('MM', 'II'):
  91.             raise AssertionError
  92.         self.prefix = prefix
  93.         if prefix == 'MM':
  94.             (self.i16, self.i32) = (ib16, ib32)
  95.         else:
  96.             (self.i16, self.i32) = (il16, il32)
  97.             (self.o16, self.o32) = (ol16, ol32)
  98.         self.reset()
  99.  
  100.     
  101.     def reset(self):
  102.         self.tags = { }
  103.         self.tagdata = { }
  104.         self.next = None
  105.  
  106.     
  107.     def __len__(self):
  108.         return max(len(self.tagdata), len(self.tags))
  109.  
  110.     
  111.     def __getitem__(self, tag):
  112.         
  113.         try:
  114.             return self.tags[tag]
  115.         except KeyError:
  116.             (type, data) = self.tagdata[tag]
  117.             (size, handler) = self.load_dispatch[type]
  118.             self.tags[tag] = data = handler(self, data)
  119.             del self.tagdata[tag]
  120.             return data
  121.  
  122.  
  123.     
  124.     def get(self, tag, default = None):
  125.         
  126.         try:
  127.             return self[tag]
  128.         except KeyError:
  129.             return default
  130.  
  131.  
  132.     
  133.     def getscalar(self, tag, default = None):
  134.         
  135.         try:
  136.             value = self[tag]
  137.             if len(value) != 1:
  138.                 raise ValueError, 'not a scalar'
  139.             
  140.             return value[0]
  141.         except KeyError:
  142.             if default is None:
  143.                 raise 
  144.             
  145.             return default
  146.  
  147.  
  148.     
  149.     def has_key(self, tag):
  150.         if not self.tags.has_key(tag):
  151.             pass
  152.         return self.tagdata.has_key(tag)
  153.  
  154.     
  155.     def __setitem__(self, tag, value):
  156.         if type(value) is not type(()):
  157.             value = (value,)
  158.         
  159.         self.tags[tag] = value
  160.  
  161.     load_dispatch = { }
  162.     
  163.     def load_byte(self, data):
  164.         l = []
  165.         for i in range(len(data)):
  166.             l.append(ord(data[i]))
  167.         
  168.         return tuple(l)
  169.  
  170.     load_dispatch[1] = (1, load_byte)
  171.     
  172.     def load_string(self, data):
  173.         if data[-1:] == '\x00':
  174.             data = data[:-1]
  175.         
  176.         return data
  177.  
  178.     load_dispatch[2] = (1, load_string)
  179.     
  180.     def load_short(self, data):
  181.         l = []
  182.         for i in range(0, len(data), 2):
  183.             l.append(self.i16(data, i))
  184.         
  185.         return tuple(l)
  186.  
  187.     load_dispatch[3] = (2, load_short)
  188.     
  189.     def load_long(self, data):
  190.         l = []
  191.         for i in range(0, len(data), 4):
  192.             l.append(self.i32(data, i))
  193.         
  194.         return tuple(l)
  195.  
  196.     load_dispatch[4] = (4, load_long)
  197.     
  198.     def load_rational(self, data):
  199.         l = []
  200.         for i in range(0, len(data), 8):
  201.             l.append((self.i32(data, i), self.i32(data, i + 4)))
  202.         
  203.         return tuple(l)
  204.  
  205.     load_dispatch[5] = (8, load_rational)
  206.     
  207.     def load_undefined(self, data):
  208.         return data
  209.  
  210.     load_dispatch[7] = (1, load_undefined)
  211.     
  212.     def load(self, fp):
  213.         self.reset()
  214.         i16 = self.i16
  215.         i32 = self.i32
  216.         for i in range(i16(fp.read(2))):
  217.             ifd = fp.read(12)
  218.             (tag, typ) = (i16(ifd), i16(ifd, 2))
  219.             if Image.DEBUG:
  220.                 import TiffTags
  221.                 tagname = TiffTags.TAGS.get(tag, 'unknown')
  222.                 typname = TiffTags.TYPES.get(typ, 'unknown')
  223.                 print 'tag: %s (%d)' % (tagname, tag), '- type: %s (%d)' % (typname, typ),
  224.             
  225.             
  226.             try:
  227.                 dispatch = self.load_dispatch[typ]
  228.             except KeyError:
  229.                 if Image.DEBUG:
  230.                     print '- unsupported type', typ
  231.                 
  232.                 continue
  233.  
  234.             (size, handler) = dispatch
  235.             size = size * i32(ifd, 4)
  236.             if size > 4:
  237.                 here = fp.tell()
  238.                 fp.seek(i32(ifd, 8))
  239.                 data = fp.read(size)
  240.                 fp.seek(here)
  241.             else:
  242.                 data = ifd[8:8 + size]
  243.             if len(data) != size:
  244.                 raise IOError, 'not enough data'
  245.             
  246.             self.tagdata[tag] = (typ, data)
  247.             if Image.DEBUG:
  248.                 if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK):
  249.                     print '- value: <table: %d bytes>' % size
  250.                 else:
  251.                     print '- value:', self[tag]
  252.             
  253.         
  254.         self.next = i32(fp.read(4))
  255.  
  256.     
  257.     def save(self, fp):
  258.         o16 = self.o16
  259.         o32 = self.o32
  260.         fp.write(o16(len(self.tags)))
  261.         tags = self.tags.items()
  262.         tags.sort()
  263.         directory = []
  264.         append = directory.append
  265.         offset = fp.tell() + len(self.tags) * 12 + 4
  266.         stripoffsets = None
  267.         for tag, value in tags:
  268.             if Image.DEBUG:
  269.                 import TiffTags
  270.                 tagname = TiffTags.TAGS.get(tag, 'unknown')
  271.                 print 'save: %s (%d)' % (tagname, tag), '- value:', value
  272.             
  273.             if type(value[0]) is type(''):
  274.                 typ = 2
  275.                 data = value = string.join(value, '\x00') + '\x00'
  276.             elif tag == STRIPOFFSETS:
  277.                 stripoffsets = len(directory)
  278.                 typ = 4
  279.             else:
  280.                 typ = 3
  281.                 for v in value:
  282.                     if v >= 65536:
  283.                         typ = 4
  284.                     
  285.                 
  286.             if typ == 3:
  287.                 data = string.join(map(o16, value), '')
  288.             else:
  289.                 data = string.join(map(o32, value), '')
  290.             if len(data) == 4:
  291.                 append((tag, typ, len(value), data, ''))
  292.             elif len(data) < 4:
  293.                 append((tag, typ, len(value), data + (4 - len(data)) * '\x00', ''))
  294.             else:
  295.                 append((tag, typ, len(value), o32(offset), data))
  296.                 offset = offset + len(data)
  297.                 if offset & 1:
  298.                     offset = offset + 1
  299.                 
  300.         
  301.         if stripoffsets is not None:
  302.             (tag, typ, count, value, data) = directory[stripoffsets]
  303.             if not __debug__ and not data:
  304.                 raise AssertionError, 'multistrip support not yet implemented'
  305.             value = o32(self.i32(value) + offset)
  306.             directory[stripoffsets] = (tag, typ, count, value, data)
  307.         
  308.         for tag, typ, count, value, data in directory:
  309.             if Image.DEBUG > 1:
  310.                 print tag, typ, count, repr(value), repr(data)
  311.             
  312.             fp.write(o16(tag) + o16(typ) + o32(count) + value)
  313.         
  314.         fp.write('\x00\x00\x00\x00')
  315.         for tag, typ, count, value, data in directory:
  316.             fp.write(data)
  317.             if len(data) & 1:
  318.                 fp.write('\x00')
  319.             
  320.         
  321.         return offset
  322.  
  323.  
  324.  
  325. class TiffImageFile(ImageFile.ImageFile):
  326.     format = 'TIFF'
  327.     format_description = 'Adobe TIFF'
  328.     
  329.     def _open(self):
  330.         '''Open the first image in a TIFF file'''
  331.         ifh = self.fp.read(8)
  332.         if ifh[:4] not in PREFIXES:
  333.             raise SyntaxError, 'not a TIFF file'
  334.         
  335.         self.tag = self.ifd = ImageFileDirectory(ifh[:2])
  336.         self._TiffImageFile__first = self._TiffImageFile__next = self.ifd.i32(ifh, 4)
  337.         self._TiffImageFile__frame = -1
  338.         self._TiffImageFile__fp = self.fp
  339.         self._seek(0)
  340.  
  341.     
  342.     def seek(self, frame):
  343.         '''Select a given frame as current image'''
  344.         self._seek(frame)
  345.  
  346.     
  347.     def tell(self):
  348.         '''Return the current frame number'''
  349.         return self._tell()
  350.  
  351.     
  352.     def _seek(self, frame):
  353.         self.fp = self._TiffImageFile__fp
  354.         if frame < self._TiffImageFile__frame:
  355.             self._TiffImageFile__frame = 0
  356.             self._TiffImageFile__next = self._TiffImageFile__first
  357.         
  358.         while self._TiffImageFile__frame < frame:
  359.             self.fp.seek(self._TiffImageFile__next)
  360.             self.tag.load(self.fp)
  361.             self._TiffImageFile__next = self.tag.next
  362.             self._TiffImageFile__frame = self._TiffImageFile__frame + 1
  363.         self._setup()
  364.  
  365.     
  366.     def _tell(self):
  367.         return self._TiffImageFile__frame
  368.  
  369.     
  370.     def _decoder(self, rawmode, layer):
  371.         '''Setup decoder contexts'''
  372.         args = None
  373.         if rawmode == 'RGB' and self._planar_configuration == 2:
  374.             rawmode = rawmode[layer]
  375.         
  376.         if self._compression == 'raw':
  377.             args = (rawmode, 0, 1)
  378.         
  379.         if self._compression in [
  380.             'packbits',
  381.             'tiff_lzw',
  382.             'jpeg']:
  383.             args = rawmode
  384.             if self._compression == 'jpeg' and self.tag.has_key(JPEGTABLES):
  385.                 self.tile_prefix = self.tag[JPEGTABLES]
  386.             elif self._compression == 'tiff_lzw' and self.tag.has_key(317):
  387.                 self.decoderconfig = (self.tag[PREDICTOR][0],)
  388.             
  389.         
  390.         return args
  391.  
  392.     
  393.     def _setup(self):
  394.         '''Setup this image object based on current tags'''
  395.         self._compression = COMPRESSION_INFO[self.tag.getscalar(COMPRESSION, 1)]
  396.         self._planar_configuration = self.tag.getscalar(PLANAR_CONFIGURATION, 1)
  397.         photo = self.tag.getscalar(PHOTOMETRIC_INTERPRETATION)
  398.         if Image.DEBUG:
  399.             print '*** Summary ***'
  400.             print '- compression:', self._compression
  401.             print '- photometric_interpretation:', photo
  402.             print '- planar_configuration:', self._planar_configuration
  403.         
  404.         xsize = self.tag.getscalar(IMAGEWIDTH)
  405.         ysize = self.tag.getscalar(IMAGELENGTH)
  406.         self.size = (xsize, ysize)
  407.         if Image.DEBUG:
  408.             print '- size:', self.size
  409.         
  410.         format = self.tag.getscalar(SAMPLEFORMAT, 1)
  411.         key = (photo, format, self.tag.get(BITSPERSAMPLE, (1,)), self.tag.get(EXTRASAMPLES, ()))
  412.         if Image.DEBUG:
  413.             print 'format key:', key
  414.         
  415.         
  416.         try:
  417.             (self.mode, rawmode) = OPEN_INFO[key]
  418.         except KeyError:
  419.             if Image.DEBUG:
  420.                 print '- unsupported format'
  421.             
  422.             raise SyntaxError, 'unknown pixel mode'
  423.  
  424.         if Image.DEBUG:
  425.             print '- raw mode:', rawmode
  426.             print '- pil mode:', self.mode
  427.         
  428.         self.info['compression'] = self._compression
  429.         x = y = l = 0
  430.         self.tile = []
  431.         if self.tag.has_key(STRIPOFFSETS):
  432.             h = self.tag.getscalar(ROWSPERSTRIP, ysize)
  433.             w = self.size[0]
  434.             a = None
  435.             for o in self.tag[STRIPOFFSETS]:
  436.                 if not a:
  437.                     a = self._decoder(rawmode, l)
  438.                 
  439.                 self.tile.append((self._compression, (0, min(y, ysize), w, min(y + h, ysize)), o, a))
  440.                 y = y + h
  441.                 if y >= self.size[1]:
  442.                     x = y = 0
  443.                     l = l + 1
  444.                     a = None
  445.                 
  446.             
  447.         elif self.tag.has_key(324):
  448.             w = self.tag.getscalar(322)
  449.             h = self.tag.getscalar(323)
  450.             a = None
  451.             for o in self.tag[324]:
  452.                 if not a:
  453.                     a = self._decoder(rawmode, l)
  454.                 
  455.                 self.tile.append((self._compression, (x, y, x + w, y + h), o, a))
  456.                 x = x + w
  457.                 if x >= self.size[0]:
  458.                     (x, y) = (0, y + h)
  459.                     if y >= self.size[1]:
  460.                         x = y = 0
  461.                         l = l + 1
  462.                         a = None
  463.                     
  464.                 
  465.             
  466.         elif Image.DEBUG:
  467.             print '- unsupported data organization'
  468.         
  469.         raise SyntaxError, 'unknown data organization'
  470.         if self.mode == 'P':
  471.             palette = map((lambda a: chr(a / 256)), self.tag[COLORMAP])
  472.             self.palette = ImagePalette.raw('RGB;L', string.join(palette, ''))
  473.         
  474.  
  475.  
  476. SAVE_INFO = {
  477.     '1': ('1', 1, 1, (1,), None),
  478.     'L': ('L', 1, 1, (8,), None),
  479.     'P': ('P', 3, 1, (8,), None),
  480.     'I': ('I;32S', 1, 2, (32,), None),
  481.     'I;16': ('I;16', 1, 2, (16,), None),
  482.     'F': ('F;32F', 1, 3, (32,), None),
  483.     'RGB': ('RGB', 2, 1, (8, 8, 8), None),
  484.     'RGBX': ('RGBX', 2, 1, (8, 8, 8, 8), 0),
  485.     'RGBA': ('RGBA', 2, 1, (8, 8, 8, 8), 2),
  486.     'CMYK': ('CMYK', 5, 1, (8, 8, 8, 8), None),
  487.     'YCbCr': ('YCbCr', 6, 1, (8, 8, 8), None),
  488.     'LAB': ('LAB', 8, 1, (8, 8, 8), None) }
  489.  
  490. def _save(im, fp, filename):
  491.     
  492.     try:
  493.         (rawmode, photo, format, bits, extra) = SAVE_INFO[im.mode]
  494.     except KeyError:
  495.         raise IOError, 'cannot write mode %s as TIFF' % im.mode
  496.  
  497.     ifd = ImageFileDirectory()
  498.     fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8))
  499.     ifd[IMAGEWIDTH] = im.size[0]
  500.     ifd[IMAGELENGTH] = im.size[1]
  501.     if im.encoderinfo.has_key('description'):
  502.         ifd[IMAGEDESCRIPTION] = im.encoderinfo['description']
  503.     
  504.     if bits != (1,):
  505.         ifd[BITSPERSAMPLE] = bits
  506.         if len(bits) != 1:
  507.             ifd[SAMPLESPERPIXEL] = len(bits)
  508.         
  509.     
  510.     if extra is not None:
  511.         ifd[EXTRASAMPLES] = extra
  512.     
  513.     if format != 1:
  514.         ifd[SAMPLEFORMAT] = format
  515.     
  516.     ifd[PHOTOMETRIC_INTERPRETATION] = photo
  517.     if im.mode == 'P':
  518.         lut = im.im.getpalette('RGB', 'RGB;L')
  519.         ifd[COLORMAP] = tuple(map((lambda v: ord(v) * 256), lut))
  520.     
  521.     stride = len(bits) * ((im.size[0] * bits[0] + 7) / 8)
  522.     ifd[ROWSPERSTRIP] = im.size[1]
  523.     ifd[STRIPBYTECOUNTS] = stride * im.size[1]
  524.     ifd[STRIPOFFSETS] = 0
  525.     offset = ifd.save(fp)
  526.     ImageFile._save(im, fp, [
  527.         ('raw', (0, 0) + im.size, offset, (rawmode, stride, 1))])
  528.  
  529. Image.register_open('TIFF', TiffImageFile, _accept)
  530. Image.register_save('TIFF', _save)
  531. Image.register_extension('TIFF', '.tif')
  532. Image.register_extension('TIFF', '.tiff')
  533. Image.register_mime('TIFF', 'image/tiff')
  534.