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 / PngImagePlugin.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2001-12-25  |  16KB  |  386 lines

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