home *** CD-ROM | disk | FTP | other *** search
/ Freelog 116 / FreelogNo116-JuilletSeptembre2013.iso / Bureautique / gImageReader / gimagereader_0.9-1_win32.exe / bin / PngImagePlugin.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2011-03-24  |  16KB  |  481 lines

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