home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / PIL / PngImagePlugin.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  15.9 KB  |  454 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = '0.8.2'
  5. import re
  6. import string
  7. import Image
  8. import ImageFile
  9. import ImagePalette
  10.  
  11. def i16(c):
  12.     return ord(c[1]) + (ord(c[0]) << 8)
  13.  
  14.  
  15. def i32(c):
  16.     return ord(c[3]) + (ord(c[2]) << 8) + (ord(c[1]) << 16) + (ord(c[0]) << 24)
  17.  
  18. is_cid = re.compile('\\w\\w\\w\\w').match
  19. _MAGIC = '\x89PNG\r\n\x1a\n'
  20. _MODES = {
  21.     (1, 0): ('1', '1'),
  22.     (2, 0): ('L', 'L;2'),
  23.     (4, 0): ('L', 'L;4'),
  24.     (8, 0): ('L', 'L'),
  25.     (16, 0): ('I', 'I;16B'),
  26.     (8, 2): ('RGB', 'RGB'),
  27.     (16, 2): ('RGB', 'RGB;16B'),
  28.     (1, 3): ('P', 'P;1'),
  29.     (2, 3): ('P', 'P;2'),
  30.     (4, 3): ('P', 'P;4'),
  31.     (8, 3): ('P', 'P'),
  32.     (8, 4): ('LA', 'LA'),
  33.     (16, 4): ('RGBA', 'LA;16B'),
  34.     (8, 6): ('RGBA', 'RGBA'),
  35.     (16, 6): ('RGBA', 'RGBA;16B') }
  36.  
  37. class ChunkStream:
  38.     
  39.     def __init__(self, fp):
  40.         self.fp = fp
  41.         self.queue = []
  42.         if not hasattr(Image.core, 'crc32'):
  43.             self.crc = self.crc_skip
  44.         
  45.  
  46.     
  47.     def read(self):
  48.         '''Fetch a new chunk. Returns header information.'''
  49.         if self.queue:
  50.             (cid, pos, len) = self.queue[-1]
  51.             del self.queue[-1]
  52.             self.fp.seek(pos)
  53.         else:
  54.             s = self.fp.read(8)
  55.             cid = s[4:]
  56.             pos = self.fp.tell()
  57.             len = i32(s)
  58.         if not is_cid(cid):
  59.             raise SyntaxError, 'broken PNG file (chunk %s)' % repr(cid)
  60.         is_cid(cid)
  61.         return (cid, pos, len)
  62.  
  63.     
  64.     def close(self):
  65.         self.queue = None
  66.         self.crc = None
  67.         self.fp = None
  68.  
  69.     
  70.     def push(self, cid, pos, len):
  71.         self.queue.append((cid, pos, len))
  72.  
  73.     
  74.     def call(self, cid, pos, len):
  75.         '''Call the appropriate chunk handler'''
  76.         if Image.DEBUG:
  77.             print 'STREAM', cid, pos, len
  78.         
  79.         return getattr(self, 'chunk_' + cid)(pos, len)
  80.  
  81.     
  82.     def crc(self, cid, data):
  83.         '''Read and verify checksum'''
  84.         crc1 = Image.core.crc32(data, Image.core.crc32(cid))
  85.         crc2 = (i16(self.fp.read(2)), i16(self.fp.read(2)))
  86.         if crc1 != crc2:
  87.             raise SyntaxError, 'broken PNG file(bad header checksum in %s)' % cid
  88.         crc1 != crc2
  89.  
  90.     
  91.     def crc_skip(self, cid, data):
  92.         '''Read checksum.  Used if the C module is not present'''
  93.         self.fp.read(4)
  94.  
  95.     
  96.     def verify(self, endchunk = 'IEND'):
  97.         cids = []
  98.         while None:
  99.             (cid, pos, len) = self.read()
  100.             if cid == endchunk:
  101.                 break
  102.             
  103.             cids.append(cid)
  104.             continue
  105.             return cids
  106.  
  107.  
  108.  
  109. class PngInfo:
  110.     
  111.     def __init__(self):
  112.         self.chunks = []
  113.  
  114.     
  115.     def add(self, cid, data):
  116.         self.chunks.append((cid, data))
  117.  
  118.     
  119.     def add_text(self, key, value, zip = 0):
  120.         if zip:
  121.             import zlib
  122.             self.add('zTXt', key + '\x00\x00' + zlib.compress(value))
  123.         else:
  124.             self.add('tEXt', key + '\x00' + value)
  125.  
  126.  
  127.  
  128. class PngStream(ChunkStream):
  129.     
  130.     def __init__(self, fp):
  131.         ChunkStream.__init__(self, fp)
  132.         self.im_info = { }
  133.         self.im_size = (0, 0)
  134.         self.im_mode = None
  135.         self.im_tile = None
  136.         self.im_palette = None
  137.  
  138.     
  139.     def chunk_IHDR(self, pos, len):
  140.         s = ImageFile._safe_read(self.fp, len)
  141.         self.im_size = (i32(s), i32(s[4:]))
  142.         
  143.         try:
  144.             (self.im_mode, self.im_rawmode) = _MODES[(ord(s[8]), ord(s[9]))]
  145.         except:
  146.             pass
  147.  
  148.         if ord(s[12]):
  149.             self.im_info['interlace'] = 1
  150.         
  151.         if ord(s[11]):
  152.             raise SyntaxError, 'unknown filter category'
  153.         ord(s[11])
  154.         return s
  155.  
  156.     
  157.     def chunk_IDAT(self, pos, len):
  158.         self.im_tile = [
  159.             ('zip', (0, 0) + self.im_size, pos, self.im_rawmode)]
  160.         self.im_idat = len
  161.         raise EOFError
  162.  
  163.     
  164.     def chunk_IEND(self, pos, len):
  165.         raise EOFError
  166.  
  167.     
  168.     def chunk_PLTE(self, pos, len):
  169.         s = ImageFile._safe_read(self.fp, len)
  170.         if self.im_mode == 'P':
  171.             self.im_palette = ('RGB', s)
  172.         
  173.         return s
  174.  
  175.     
  176.     def chunk_tRNS(self, pos, len):
  177.         s = ImageFile._safe_read(self.fp, len)
  178.         if self.im_mode == 'P':
  179.             i = string.find(s, chr(0))
  180.             if i >= 0:
  181.                 self.im_info['transparency'] = i
  182.             
  183.         elif self.im_mode == 'L':
  184.             self.im_info['transparency'] = i16(s)
  185.         
  186.         return s
  187.  
  188.     
  189.     def chunk_gAMA(self, pos, len):
  190.         s = ImageFile._safe_read(self.fp, len)
  191.         self.im_info['gamma'] = i32(s) / 100000
  192.         return s
  193.  
  194.     
  195.     def chunk_pHYs(self, pos, len):
  196.         s = ImageFile._safe_read(self.fp, len)
  197.         px = i32(s)
  198.         py = i32(s[4:])
  199.         unit = ord(s[8])
  200.         if unit == 1:
  201.             dpi = (int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5))
  202.             self.im_info['dpi'] = dpi
  203.         elif unit == 0:
  204.             self.im_info['aspect'] = (px, py)
  205.         
  206.         return s
  207.  
  208.     
  209.     def chunk_tEXt(self, pos, len):
  210.         s = ImageFile._safe_read(self.fp, len)
  211.         
  212.         try:
  213.             (k, v) = string.split(s, '\x00', 1)
  214.         except ValueError:
  215.             k = s
  216.             v = ''
  217.  
  218.         if k:
  219.             self.im_info[k] = v
  220.         
  221.         return s
  222.  
  223.  
  224.  
  225. def _accept(prefix):
  226.     return prefix[:8] == _MAGIC
  227.  
  228.  
  229. class PngImageFile(ImageFile.ImageFile):
  230.     format = 'PNG'
  231.     format_description = 'Portable network graphics'
  232.     
  233.     def _open(self):
  234.         if self.fp.read(8) != _MAGIC:
  235.             raise SyntaxError, 'not a PNG file'
  236.         self.fp.read(8) != _MAGIC
  237.         self.png = PngStream(self.fp)
  238.         while None:
  239.             (cid, pos, len) = self.png.read()
  240.             
  241.             try:
  242.                 s = self.png.call(cid, pos, len)
  243.             except EOFError:
  244.                 break
  245.             except AttributeError:
  246.                 if Image.DEBUG:
  247.                     print cid, pos, len, '(unknown)'
  248.                 
  249.                 s = ImageFile._safe_read(self.fp, len)
  250.  
  251.             continue
  252.             self.mode = self.png.im_mode
  253.             self.size = self.png.im_size
  254.             self.info = self.png.im_info
  255.             self.tile = self.png.im_tile
  256.             if self.png.im_palette:
  257.                 (rawmode, data) = self.png.im_palette
  258.                 self.palette = ImagePalette.raw(rawmode, data)
  259.             
  260.         self._PngImageFile__idat = len
  261.  
  262.     
  263.     def verify(self):
  264.         '''Verify PNG file'''
  265.         if self.fp is None:
  266.             raise RuntimeError('verify must be called directly after open')
  267.         self.fp is None
  268.         self.fp.seek(self.tile[0][2] - 8)
  269.         self.png.verify()
  270.         self.png.close()
  271.         self.fp = None
  272.  
  273.     
  274.     def load_prepare(self):
  275.         '''internal: prepare to read PNG file'''
  276.         if self.info.get('interlace'):
  277.             raise IOError('cannot read interlaced PNG files')
  278.         self.info.get('interlace')
  279.         ImageFile.ImageFile.load_prepare(self)
  280.  
  281.     
  282.     def load_read(self, bytes):
  283.         '''internal: read more image data'''
  284.         while self._PngImageFile__idat == 0:
  285.             self.fp.read(4)
  286.             (cid, pos, len) = self.png.read()
  287.             if cid not in ('IDAT', 'DDAT'):
  288.                 self.png.push(cid, pos, len)
  289.                 return ''
  290.             self._PngImageFile__idat = len
  291.             continue
  292.             cid not in ('IDAT', 'DDAT')
  293.         if bytes <= 0:
  294.             bytes = self._PngImageFile__idat
  295.         else:
  296.             bytes = min(bytes, self._PngImageFile__idat)
  297.         self._PngImageFile__idat = self._PngImageFile__idat - bytes
  298.         return self.fp.read(bytes)
  299.  
  300.     
  301.     def load_end(self):
  302.         '''internal: finished reading image data'''
  303.         self.png.close()
  304.         self.png = None
  305.  
  306.  
  307.  
  308. def o16(i):
  309.     return chr(i >> 8 & 255) + chr(i & 255)
  310.  
  311.  
  312. def o32(i):
  313.     return chr(i >> 24 & 255) + chr(i >> 16 & 255) + chr(i >> 8 & 255) + chr(i & 255)
  314.  
  315. _OUTMODES = {
  316.     '1': ('1', chr(1) + chr(0)),
  317.     'L;1': ('L;1', chr(1) + chr(0)),
  318.     'L;2': ('L;2', chr(2) + chr(0)),
  319.     'L;4': ('L;4', chr(4) + chr(0)),
  320.     'L': ('L', chr(8) + chr(0)),
  321.     'LA': ('LA', chr(8) + chr(4)),
  322.     'I': ('I;16B', chr(16) + chr(0)),
  323.     'P;1': ('P;1', chr(1) + chr(3)),
  324.     'P;2': ('P;2', chr(2) + chr(3)),
  325.     'P;4': ('P;4', chr(4) + chr(3)),
  326.     'P': ('P', chr(8) + chr(3)),
  327.     'RGB': ('RGB', chr(8) + chr(2)),
  328.     'RGBA': ('RGBA', chr(8) + chr(6)) }
  329.  
  330. def putchunk(fp, cid, *data):
  331.     '''Write a PNG chunk (including CRC field)'''
  332.     data = string.join(data, '')
  333.     fp.write(o32(len(data)) + cid)
  334.     fp.write(data)
  335.     (hi, lo) = Image.core.crc32(data, Image.core.crc32(cid))
  336.     fp.write(o16(hi) + o16(lo))
  337.  
  338.  
  339. class _idat:
  340.     
  341.     def __init__(self, fp, chunk):
  342.         self.fp = fp
  343.         self.chunk = chunk
  344.  
  345.     
  346.     def write(self, data):
  347.         self.chunk(self.fp, 'IDAT', data)
  348.  
  349.  
  350.  
  351. def _save(im, fp, filename, chunk = putchunk, check = 0):
  352.     mode = im.mode
  353.     if mode == 'P':
  354.         if im.encoderinfo.has_key('bits'):
  355.             n = 1 << im.encoderinfo['bits']
  356.         else:
  357.             n = 256
  358.         if n <= 2:
  359.             bits = 1
  360.         elif n <= 4:
  361.             bits = 2
  362.         elif n <= 16:
  363.             bits = 4
  364.         else:
  365.             bits = 8
  366.         if bits != 8:
  367.             mode = '%s;%d' % (mode, bits)
  368.         
  369.     
  370.     if im.encoderinfo.has_key('dictionary'):
  371.         dictionary = im.encoderinfo['dictionary']
  372.     else:
  373.         dictionary = ''
  374.     im.encoderconfig = (im.encoderinfo.has_key('optimize'), dictionary)
  375.     
  376.     try:
  377.         (rawmode, mode) = _OUTMODES[mode]
  378.     except KeyError:
  379.         raise IOError, 'cannot write mode %s as PNG' % mode
  380.  
  381.     if check:
  382.         return check
  383.     fp.write(_MAGIC)
  384.     chunk(fp, 'IHDR', o32(im.size[0]), o32(im.size[1]), mode, chr(0), chr(0), chr(0))
  385.     if im.mode == 'P':
  386.         chunk(fp, 'PLTE', im.im.getpalette('RGB'))
  387.     
  388.     if im.encoderinfo.has_key('transparency'):
  389.         if im.mode == 'P':
  390.             transparency = max(0, min(255, im.encoderinfo['transparency']))
  391.             chunk(fp, 'tRNS', chr(255) * transparency + chr(0))
  392.         elif im.mode == 'L':
  393.             transparency = max(0, min(65535, im.encoderinfo['transparency']))
  394.             chunk(fp, 'tRNS', o16(transparency))
  395.         else:
  396.             raise IOError, 'cannot use transparency for this mode'
  397.     im.mode == 'P'
  398.     dpi = im.encoderinfo.get('dpi')
  399.     if dpi:
  400.         chunk(fp, 'pHYs', o32(int(dpi[0] / 0.0254 + 0.5)), o32(int(dpi[1] / 0.0254 + 0.5)), chr(1))
  401.     
  402.     info = im.encoderinfo.get('pnginfo')
  403.     if info:
  404.         for cid, data in info.chunks:
  405.             chunk(fp, cid, data)
  406.         
  407.     
  408.     ImageFile._save(im, _idat(fp, chunk), [
  409.         ('zip', (0, 0) + im.size, 0, rawmode)])
  410.     chunk(fp, 'IEND', '')
  411.     
  412.     try:
  413.         fp.flush()
  414.     except:
  415.         pass
  416.  
  417.  
  418.  
  419. def getchunks(im, **params):
  420.     '''Return a list of PNG chunks representing this image.'''
  421.     
  422.     class collector:
  423.         data = []
  424.         
  425.         def write(self, data):
  426.             pass
  427.  
  428.         
  429.         def append(self, chunk):
  430.             self.data.append(chunk)
  431.  
  432.  
  433.     
  434.     def append(fp, cid, *data):
  435.         data = string.join(data, '')
  436.         (hi, lo) = Image.core.crc32(data, Image.core.crc32(cid))
  437.         crc = o16(hi) + o16(lo)
  438.         fp.append((cid, data, crc))
  439.  
  440.     fp = collector()
  441.     
  442.     try:
  443.         im.encoderinfo = params
  444.         _save(im, fp, None, append)
  445.     finally:
  446.         del im.encoderinfo
  447.  
  448.     return fp.data
  449.  
  450. Image.register_open('PNG', PngImageFile, _accept)
  451. Image.register_save('PNG', _save)
  452. Image.register_extension('PNG', '.png')
  453. Image.register_mime('PNG', 'image/png')
  454.