예제 #1
0
def tagblock(tag):
    """
    Serialize block of tags

    `tag` should be a list of (*signature*, *element*) pairs, where
    *signature* (the key) is a length 4 string, and *element* is the
    content of the tag element (another string).

    The entire tag block (consisting of first a table and then the
    element data) is constructed and returned as a string.
    """
    n = len(tag)
    tablelen = 12 * n

    # Build the tag table in two parts.  A list of 12-byte tags, and a
    # string of element data.  Offset is the offset from the start of
    # the profile to the start of the element data (so the offset for
    # the next element is this offset plus the length of the element
    # string so far).
    offset = 128 + tablelen + 4
    # The table.  As a string.
    table = png.strtobytes('')
    # The element data
    element = png.strtobytes('')
    for k, v in tag:
        table += struct.pack('>4s2L', png.strtobytes(k), offset + len(element),
                             len(v))
        element += v
    return struct.pack('>L', n) + table + element
예제 #2
0
파일: iccp.py 프로젝트: Scondo/purepng
def tagblock(tag):
    """
    Serialize block of tags

    `tag` should be a list of (*signature*, *element*) pairs, where
    *signature* (the key) is a length 4 string, and *element* is the
    content of the tag element (another string).

    The entire tag block (consisting of first a table and then the
    element data) is constructed and returned as a string.
    """
    n = len(tag)
    tablelen = 12 * n

    # Build the tag table in two parts.  A list of 12-byte tags, and a
    # string of element data.  Offset is the offset from the start of
    # the profile to the start of the element data (so the offset for
    # the next element is this offset plus the length of the element
    # string so far).
    offset = 128 + tablelen + 4
    # The table.  As a string.
    table = png.strtobytes('')
    # The element data
    element = png.strtobytes('')
    for k, v in tag:
        table += struct.pack('>4s2L', png.strtobytes(k), offset + len(element),
                             len(v))
        element += v
    return struct.pack('>L', n) + table + element
예제 #3
0
def img(inp):
    """
    Open the PDS IMG file `inp` and return (*pixels*, *info*).

    *pixels* is an iterator over the rows,
    *info* is the information dictionary.
    """
    consumed = 1024

    s = inp.read(consumed)
    record_type = pdskey(s, 'RECORD_TYPE')
    if record_type != png.strtobytes('FIXED_LENGTH'):
        raise png.FormatError(
          "Can only deal with FIXED_LENGTH record type (found %s)" %
          record_type)
    record_bytes = int(pdskey(s, 'RECORD_BYTES'))
    # file_records = int(pdskey(s, 'FILE_RECORDS'))
    label_records = int(pdskey(s, 'LABEL_RECORDS'))
    remaining = label_records * record_bytes - consumed
    s += inp.read(remaining)
    consumed += remaining

    image_pointer = int(pdskey(s, '^IMAGE'))
    # "^IMAGE" locates a record.  Records are numbered starting from 1.
    image_index = image_pointer - 1
    image_offset = image_index * record_bytes
    gap = image_offset - consumed
    assert gap >= 0
    if gap:
        inp.read(gap)
    # This assumes there is only one OBJECT in the file, and it is the
    # IMAGE.
    height = int(pdskey(s, '  LINES'))
    width = int(pdskey(s, '  LINE_SAMPLES'))
    sample_type = pdskey(s, '  SAMPLE_TYPE')
    sample_bits = int(pdskey(s, '  SAMPLE_BITS'))
    # TODO: For Messenger MDIS, SAMPLE_BITS is reported as 16, but only values
    # from 0 ot 4095 are used.
    bitdepth = sample_bits
    if bitdepth == 16 and\
            sample_type == png.strtobytes('MSB_UNSIGNED_INTEGER'):
        fmt = '>H'
    elif bitdepth == 8:
        fmt = '@B'
    else:
        raise png.FormatError('Unknown sample type: %s.' % sample_type)
    sample_bytes = (1, 2)[bitdepth > 8]
    row_bytes = sample_bytes * width
    fmt = fmt[:1] + str(width) + fmt[1:]

    def rowiter():
        for y in range(height):
            yield struct.unpack(fmt, inp.read(row_bytes))
    info = dict(greyscale=True, alpha=False, bitdepth=bitdepth,
      size=(width, height), gamma=1.0)
    return rowiter(), info
예제 #4
0
    def desc(ascii):
        """
        Return textDescription type [ICC 2001] 6.5.17.

        The ASCII part is filled in with the string `ascii`,
        the Unicode and ScriptCode parts are empty.
        """
        ascii = png.strtobytes(ascii) + png.zerobyte
        l = len(ascii)
        return struct.pack('>L%ds2LHB67s' % l, l, ascii, 0, 0, 0, 0,
                           png.strtobytes(''))
예제 #5
0
파일: iccp.py 프로젝트: Scondo/purepng
    def desc(ascii):
        """
        Return textDescription type [ICC 2001] 6.5.17.

        The ASCII part is filled in with the string `ascii`,
        the Unicode and ScriptCode parts are empty.
        """
        ascii = png.strtobytes(ascii) + png.zerobyte
        l = len(ascii)
        return struct.pack('>L%ds2LHB67s' % l,
                           l, ascii, 0, 0, 0, 0, png.strtobytes(''))
예제 #6
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testPNMsbit(self):
     """Test that PNM files can generates sBIT chunk."""
     s = BytesIO()
     s.write(strtobytes('P6 8 1 1\n'))
     for pixel in range(8):
         s.write(struct.pack('<I', (0x4081 * pixel) & 0x10101)[:3])
     s.flush()
     s.seek(0)
     o = BytesIO()
     _redirect_io(s, o, lambda: png.pnm2png.main(['testPNMsbit']))
     r = png.Reader(bytes=o.getvalue())
     sbit = r.chunk('sBIT')[1]
     self.assertEqual(sbit, strtobytes('\x01\x01\x01'))
예제 #7
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testPGMin(self):
     """Test that the command line tool can read PGM files."""
     s = BytesIO()
     s.write(strtobytes('P5 2 2 3\n'))
     s.write(strtobytes('\x00\x01\x02\x03'))
     s.flush()
     s.seek(0)
     o = BytesIO()
     _redirect_io(s, o, lambda: png.pnm2png.main(['testPGMin']))
     r = png.Reader(bytes=o.getvalue())
     r.read()
     self.assertEqual(r.greyscale, True)
     self.assertEqual(r.bitdepth, 2)
예제 #8
0
 def testPGMin(self):
     """Test that the command line tool can read PGM files."""
     def do():
         return png._main(['testPGMin'])
     s = BytesIO()
     s.write(strtobytes('P5 2 2 3\n'))
     s.write(strtobytes('\x00\x01\x02\x03'))
     s.flush()
     s.seek(0)
     o = BytesIO()
     _redirect_io(s, o, do)
     r = png.Reader(bytes=o.getvalue())
     x,y,pixels,meta = r.read()
     self.assertTrue(r.greyscale)
     self.assertEqual(r.bitdepth, 2)
예제 #9
0
 def testPGMin(self):
     """Test that the command line tool can read PGM files."""
     def do():
         return png._main(['testPGMin'])
     s = BytesIO()
     s.write(strtobytes('P5 2 2 3\n'))
     s.write(strtobytes('\x00\x01\x02\x03'))
     s.flush()
     s.seek(0)
     o = BytesIO()
     _redirect_io(s, o, do)
     r = png.Reader(bytes=o.getvalue())
     x,y,pixels,meta = r.read()
     self.assertTrue(r.greyscale)
     self.assertEqual(r.bitdepth, 2)
예제 #10
0
def RDvcgt(s):
    """Convert Apple CMVideoCardGammaType."""

    # See
    # http://developer.apple.com/documentation/GraphicsImaging/Reference/
    #         ColorSync_Manager/Reference/reference.html#//apple_ref/c/
    #         tdef/CMVideoCardGammaType
    assert s[0:4] == png.strtobytes('vcgt')
    tagtype, = struct.unpack('>L', s[8:12])
    if tagtype != 0:
        return s[8:]
    if tagtype == 0:
        # Table.
        _, count, size = struct.unpack('>3H', s[12:18])
        if size == 1:
            fmt = 'B'
        elif size == 2:
            fmt = 'H'
        else:
            return s[8:]
        l = len(s[18:]) // size
        t = struct.unpack('>%d%s' % (l, fmt), s[18:])
        t = group(t, count)
        return size, t
    return s[8:]
예제 #11
0
파일: test_png.py 프로젝트: Scondo/purepng
def seqtobytes(s):
    """
    Convert a sequence of integers to a *bytes* instance.

    Good for plastering over Python 2 / Python 3 cracks.
    """
    return strtobytes(''.join([chr(x) for x in s]))
예제 #12
0
파일: iccp.py 프로젝트: Scondo/purepng
def RDvcgt(s):
    """Convert Apple CMVideoCardGammaType."""

    # See
    # http://developer.apple.com/documentation/GraphicsImaging/Reference/
    #         ColorSync_Manager/Reference/reference.html#//apple_ref/c/
    #         tdef/CMVideoCardGammaType
    assert s[0:4] == png.strtobytes('vcgt')
    tagtype, = struct.unpack('>L', s[8:12])
    if tagtype != 0:
        return s[8:]
    if tagtype == 0:
        # Table.
        _, count, size = struct.unpack('>3H', s[12:18])
        if size == 1:
            fmt = 'B'
        elif size == 2:
            fmt = 'H'
        else:
            return s[8:]
        l = len(s[18:]) // size
        t = struct.unpack('>%d%s' % (l, fmt), s[18:])
        t = group(t, count)
        return size, t
    return s[8:]
예제 #13
0
 def eachchunk(chunk):
     if chunk[0] != 'IDAT':
         return chunk
     data = zlib.decompress(chunk[1])
     # Corrupt the first filter byte
     data = strtobytes('\x99') + data[1:]
     data = zlib.compress(data)
     return (chunk[0], data)
예제 #14
0
 def eachchunk(chunk):
     if chunk[0] != 'IDAT':
         return chunk
     data = zlib.decompress(chunk[1])
     data += strtobytes('\x00garbage')
     data = zlib.compress(data)
     chunk = (chunk[0], data)
     return chunk
예제 #15
0
def RDtext(s):
    """Convert ICC textType to Python string."""

    # Note: type not specified or used in [ICC 2004], only in older
    # [ICC 2001].
    # See [ICC 2001] 6.5.18
    assert s[0:4] == png.strtobytes('text')
    return s[8:-1]
예제 #16
0
파일: iccp.py 프로젝트: Scondo/purepng
def RDtext(s):
    """Convert ICC textType to Python string."""

    # Note: type not specified or used in [ICC 2004], only in older
    # [ICC 2001].
    # See [ICC 2001] 6.5.18
    assert s[0:4] == png.strtobytes('text')
    return s[8:-1]
예제 #17
0
def _dehex(s):
    """Liberally convert from hex string to binary string."""
    import re
    import binascii

    # Remove all non-hexadecimal digits
    s = re.sub(r'[^a-fA-F\d]', '', s)
    # binscii.unhexlify works in Python 2 and Python 3 (unlike
    # thing.decode('hex')).
    return BytesIO(binascii.unhexlify(strtobytes(s)))
예제 #18
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testICCPgrey(self):
     """Test constructing grey ICC Profile with iccp tool"""
     o = BytesIO()
     _redirect_io(None, o,
                  lambda: png.iccp.main(['iccpgrey', '-mmkgrey',
                                         '-o-']))
     o.seek(0)
     r = png.iccp.Profile()
     r.fromFile(o)
     self.assertEqual(r.d['colourspace'], png.strtobytes('GRAY'))
예제 #19
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testICCPread(self):
     """Test ICC Profile read from png and parsed with iccp tool"""
     pngsuite.png["ff99ff_iccp"].seek(0)
     o = BytesIO()
     _redirect_io(pngsuite.png["ff99ff_iccp"], o,
                  lambda: png.iccp.main(['iccpexp', '-mview', '-o-']))
     o.seek(0)
     s = o.read()
     res = (png.strtobytes("rTRC: ('curv', {'gamma': 1})") in s)
     self.assertEqual(res, True)
예제 #20
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testPPMASCIIin(self):
     """Test that the command line tool can read ASCII PPM files."""
     s = os.path.join(os.path.dirname(__file__),
                      'testfiles', 'feep.ascii.ppm')
     o = BytesIO()
     _redirect_io(None, o, lambda: png.pnm2png.main(['testPPMASCIIin', s]))
     r = png.Reader(bytes=o.getvalue())
     r.read()
     self.assertEqual(r.greyscale, False)
     # bitdepth 4 could be saved in RGB only as sBIT
     self.assertEqual(r.sbit, strtobytes('\x04\x04\x04'))
예제 #21
0
파일: iccp.py 프로젝트: Scondo/purepng
    def fromString(self, profile, name='<unknown>'):
        self.d = dict()
        d = self.d
        if len(profile) < 128:
            raise png.FormatError("ICC Profile is too short.")
        d.update(dict(
          zip(['size', 'preferredCMM', 'version',
               'profileclass', 'colourspace', 'pcs'],
              struct.unpack('>L4sL4s4s4s', profile[:24]))))
        if len(profile) < d['size']:
            warnings.warn(
              'Profile size declared to be %d, but only got %d bytes' %
              (d['size'], len(profile)))
        d['version'] = '%08x' % d['version']
        d['created'] = readICCdatetime(profile[24:36])
        d.update(dict(
          zip(['acsp', 'platform', 'flag', 'manufacturer', 'model'],
              struct.unpack('>4s4s3L', profile[36:56]))))
        if d['acsp'] != png.strtobytes('acsp'):
            warnings.warn('acsp field not present (not an ICC Profile?).')
        d['deviceattributes'] = profile[56:64]
        d['intent'], = struct.unpack('>L', profile[64:68])
        d['pcsilluminant'] = readICCXYZNumber(profile[68:80])
        d['creator'] = profile[80:84]
        d['id'] = profile[84:100]
        ntags, = struct.unpack('>L', profile[128:132])
        d['ntags'] = ntags
        fmt = '4s2L' * ntags
        # tag table
        tt = struct.unpack('>' + fmt, profile[132:132 + 12 * ntags])
        tt = group(tt, 3)

        # Could (should) detect 2 or more tags having the same sig.  But
        # we don't.  Two or more tags with the same sig is illegal per
        # the ICC spec.

        # Convert (sig,offset,size) triples into (sig,value) pairs.
        rawtag = list(map(lambda x: (x[0], profile[x[1]:x[1] + x[2]]), tt))
        self.rawtagtable = rawtag
        self.rawtagdict = dict(rawtag)
        tag = dict()
        # Interpret the tags whose types we know about
        for sig, v in rawtag:
            sig = png.bytestostr(sig)
            if sig in tag:
                warnings.warn("Duplicate tag %r found.  Ignoring." % sig)
                continue
            v = ICCdecode(v)
            if v is not None:
                tag[sig] = v
        self.tag = tag
        self.name = name
        return self
예제 #22
0
파일: iccp.py 프로젝트: Scondo/purepng
def RDcurv(s):
    """Convert ICC curveType."""

    # See [ICC 2001] 6.5.3
    assert s[0:4] == png.strtobytes('curv')
    count, = struct.unpack('>L', s[8:12])
    if count == 0:
        return dict(gamma=1)
    table = struct.unpack('>%dH' % count, s[12:])
    if count == 1:
        return dict(gamma=table[0] * 2 ** -8)
    return table
예제 #23
0
def RDcurv(s):
    """Convert ICC curveType."""

    # See [ICC 2001] 6.5.3
    assert s[0:4] == png.strtobytes('curv')
    count, = struct.unpack('>L', s[8:12])
    if count == 0:
        return dict(gamma=1)
    table = struct.unpack('>%dH' % count, s[12:])
    if count == 1:
        return dict(gamma=table[0] * 2**-8)
    return table
예제 #24
0
def pdskey(s, k):
    """
    Lookup key `k` in string `s`.

    Returns value (as a string), or raises exception if not found.
    """
    assert re.match(r' *\^?[:\w]+$', k)
    safere = png.strtobytes('^' + re.escape(k) + r' *= *(\w+)')
    m = re.search(safere, s, re.MULTILINE)
    if not m:
        raise png.FormatError("Can't find %s." % k)
    return m.group(1)
예제 #25
0
파일: pnm2png.py 프로젝트: Scondo/purepng
def read_pnm_header(infile, supported=('P5', 'P6')):
    """
    Read a PNM header, returning (format, width, height, depth, maxval).

    `width` and `height` are in pixels.  `depth` is the number of
    channels in the image; for PBM and PGM it is synthesized as 1, for
    PPM as 3; for PAM images it is read from the header.  `maxval` is
    synthesized (as 1) for PBM images.
    """
    # Generally, see http://netpbm.sourceforge.net/doc/ppm.html
    # and http://netpbm.sourceforge.net/doc/pam.html
    supported = [png.strtobytes(x) for x in supported]

    # Technically 'P7' must be followed by a newline, so by using
    # rstrip() we are being liberal in what we accept.  I think this
    # is acceptable.
    mode = infile.read(3).rstrip()
    if mode not in supported:
        raise NotImplementedError('file format %s not supported' % mode)
    if mode == png.strtobytes('P7'):
        # PAM header parsing is completely different.
        return read_pam_header(infile)
    # Expected number of tokens in header (3 for P4, 4 for P6)
    expected = 4
    if mode in (png.strtobytes('P1'), png.strtobytes('P4')):
        expected = 3
    header = [mode]
    header.extend(read_int_tokens(infile, expected - 1, False))
    if len(header) == 3:
        # synthesize a MAXVAL
        header.append(1)

    depth = (1, 3)[mode in (png.strtobytes('P3'), png.strtobytes('P6'))]
    return header[0], header[1], header[2], depth, header[3]
예제 #26
0
def convert(f, output=None):
    """
    Convert Plan 9 file to PNG format.

    Works with either uncompressed or compressed files.
    """
    if output is None:
        output = sys.stdout
    r = f.read(11)
    if r == png.strtobytes('compressed\n'):
        aspng(output, *decompress(f))
    else:
        aspng(output, *glue(f, r))
예제 #27
0
파일: pnm2png.py 프로젝트: Scondo/purepng
def read_pam_header(infile):
    """
    Read (the rest of a) PAM header.

    `infile` should be positioned
    immediately after the initial 'P7' line (at the beginning of the
    second line).  Returns are as for `read_pnm_header`.
    """
    # Unlike PBM, PGM, and PPM, we can read the header a line at a time.
    header = dict()
    while True:
        l = infile.readline().strip()
        if l == png.strtobytes('ENDHDR'):
            break
        if not l:
            raise EOFError('PAM ended prematurely')
        if l[0] == png.strtobytes('#'):
            continue
        l = l.split(None, 1)
        if l[0] not in header:
            header[l[0]] = l[1]
        else:
            header[l[0]] += png.strtobytes(' ') + l[1]

    required = ['WIDTH', 'HEIGHT', 'DEPTH', 'MAXVAL']
    required = [png.strtobytes(x) for x in required]
    WIDTH, HEIGHT, DEPTH, MAXVAL = required
    present = [x for x in required if x in header]
    if len(present) != len(required):
        raise png.Error('PAM file must specify '
                        'WIDTH, HEIGHT, DEPTH, and MAXVAL')
    width = int(header[WIDTH])
    height = int(header[HEIGHT])
    depth = int(header[DEPTH])
    maxval = int(header[MAXVAL])
    if (width <= 0 or height <= 0 or depth <= 0 or maxval <= 0):
        raise png.Error(
          'WIDTH, HEIGHT, DEPTH, MAXVAL must all be positive integers')
    return 'P7', width, height, depth, maxval
예제 #28
0
def encode(tsig, *l):
    """
    Encode a Python value as an ICC type.

    `tsig` is the type signature to (the first 4 bytes of
    the encoded value, see [ICC 2004] section 10.
    """
    if tsig not in encodefuncs:
        raise "No encoder for type %r." % tsig
    v = encodefuncs[tsig](*l)
    # Padd tsig out with spaces (and ensure it is bytes).
    tsig = (png.strtobytes(tsig + '   '))[:4]
    return tsig + png.zerobyte * 4 + v
예제 #29
0
파일: iccp.py 프로젝트: Scondo/purepng
def encode(tsig, *l):
    """
    Encode a Python value as an ICC type.

    `tsig` is the type signature to (the first 4 bytes of
    the encoded value, see [ICC 2004] section 10.
    """
    if tsig not in encodefuncs:
        raise "No encoder for type %r." % tsig
    v = encodefuncs[tsig](*l)
    # Padd tsig out with spaces (and ensure it is bytes).
    tsig = (png.strtobytes(tsig + '   '))[:4]
    return tsig + png.zerobyte * 4 + v
예제 #30
0
파일: pnm2png.py 프로젝트: Scondo/purepng
def read_int_tokens(infile, n, allow_eof=False):
    """
    Read ASCII integers separated with whitespaces as list of length `n`

    Skip comments started with '#' to the end of line
    If comment starts right after digit and newline starts with digit
    these digits form single number.
    """
    result = []
    EOF = [False]  # Hack to allow modification in nested function

    # We may consume less or more than one line, so characters read one by one
    def getc():
        c = infile.read(1)
        if not c:
            if not allow_eof or EOF[0]:
                raise png.Error('premature End of file')
            else:
                # small hack to simulate trailing whitespace at the end of file
                EOF[0] = True   # but only once
                return ' '
        return c
    token = bytes()
    while True:
        c = getc()
        if c.isspace():
            if token:
                # post-token whitespace, save token
                result.append(int(token))
                if len(result) == n:
                    # we get here on last whitespace
                    break
                # and clean for new token
                token = bytes()
            # Skip whitespace that precedes a token or between tokens.
        elif c == png.strtobytes('#'):
            # Skip comments to the end of line.
            infile.readline()
            # If there is no whitespaces after conventional newline
            # continue reading token
        elif c.isdigit():
            token += c
        else:
            raise png.Error('unexpected character %s found ' % c)
    return result
예제 #31
0
파일: pnm2png.py 프로젝트: Scondo/purepng
def write_pnm(fileobj, width, height, pixels, meta):
    """Write a Netpbm PNM/PAM file."""
    bitdepth = meta['bitdepth']
    maxval = 2**bitdepth - 1
    # Rudely, the number of image planes can be used to determine
    # whether we are L (PGM), LA (PAM), RGB (PPM), or RGBA (PAM).
    planes = meta['planes']
    # Can be an assert as long as we assume that pixels and meta came
    # from a PNG file.
    assert planes in (1, 2, 3, 4)
    if planes in (1, 3):
        if 1 == planes:
            # PGM
            # Could generate PBM if maxval is 1, but we don't (for one
            # thing, we'd have to convert the data, not just blat it
            # out).
            fmt = 'P5'
        else:
            # PPM
            fmt = 'P6'
        header = '%s %d %d %d\n' % (fmt, width, height, maxval)
    if planes in (2, 4):
        # PAM
        # See http://netpbm.sourceforge.net/doc/pam.html
        if 2 == planes:
            tupltype = 'GRAYSCALE_ALPHA'
        else:
            tupltype = 'RGB_ALPHA'
        header = ('P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\n'
                  'TUPLTYPE %s\nENDHDR\n' %
                  (width, height, planes, maxval, tupltype))
    fileobj.write(png.strtobytes(header))
    # Values per row
    vpr = planes * width
    # struct format
    fmt = '>%d' % vpr
    if maxval > 0xff:
        fmt = fmt + 'H'
    else:
        fmt = fmt + 'B'
    for row in pixels:
        fileobj.write(struct.pack(fmt, *row))
    fileobj.flush()
예제 #32
0
파일: test_png.py 프로젝트: Scondo/purepng
 def testPAMin(self):
     """Test that the command line tool can read PAM file."""
     s = BytesIO()
     s.write(strtobytes('P7\nWIDTH 3\nHEIGHT 1\nDEPTH 4\nMAXVAL 255\n'
             'TUPLTYPE RGB_ALPHA\nENDHDR\n'))
     # The pixels in flat row flat pixel format
     flat = [255, 0, 0, 255,
             0, 255, 0, 120,
             0, 0, 255, 30]
     asbytes = seqtobytes(flat)
     s.write(asbytes)
     s.flush()
     s.seek(0)
     o = BytesIO()
     _redirect_io(s, o, lambda: png.pnm2png.main(['testPAMin']))
     r = png.Reader(bytes=o.getvalue())
     pixels = r.read()[2]
     self.assertEqual(r.alpha, True)
     self.assertEqual(not r.greyscale, True)
     self.assertEqual(list(itertools.chain(*pixels)), flat)
예제 #33
0
def RDmluc(s):
    """
    Convert ICC multiLocalizedUnicodeType.

    This types encodes several strings together with a language/country
    code for each string.  A list of (*lc*, *string*) pairs is returned
    where *lc* is the 4 byte language/country code, and *string* is the
    string corresponding to that code.  It seems unlikely that the same
    language/country code will appear more than once with different
    strings, but the ICC standard does not prohibit it.
    """
    # See [ICC 2004] 10.13
    assert s[0:4] == png.strtobytes('mluc')
    n, sz = struct.unpack('>2L', s[8:16])
    assert sz == 12
    record = []
    for _ in range(n):
        lc, l, o = struct.unpack('4s2L', s[16 + 12 * n:28 + 12 * n])
        record.append(lc, s[o:o + l])
    # How are strings encoded?
    return record
예제 #34
0
파일: iccp.py 프로젝트: Scondo/purepng
def RDmluc(s):
    """
    Convert ICC multiLocalizedUnicodeType.

    This types encodes several strings together with a language/country
    code for each string.  A list of (*lc*, *string*) pairs is returned
    where *lc* is the 4 byte language/country code, and *string* is the
    string corresponding to that code.  It seems unlikely that the same
    language/country code will appear more than once with different
    strings, but the ICC standard does not prohibit it.
    """
    # See [ICC 2004] 10.13
    assert s[0:4] == png.strtobytes('mluc')
    n, sz = struct.unpack('>2L', s[8:16])
    assert sz == 12
    record = []
    for _ in range(n):
        lc, l, o = struct.unpack('4s2L', s[16 + 12 * n:28 + 12 * n])
        record.append(lc, s[o:o + l])
    # How are strings encoded?
    return record
예제 #35
0
파일: test_png.py 프로젝트: Scondo/purepng
    def testText(self):
        """Test text information saving and retrieving"""
        # Use image as core for text
        pngsuite.png['basn2c16'].seek(0)
        r = png.Reader(file=pngsuite.png['basn2c16'])
        x, y, pixels, info = r.read()

        text = {'Software': 'PurePNG library',
                'Source': 'PNGSuite',
                'Comment': 'Text information test'}
        # Simple unicode test
        try:
            unic = unichr
        except NameError:
            unic = chr
        # Unicode only by type should be saved to tEXt
        text['Author'] = strtobytes('Pavel Zlatovratskii').decode('latin-1')
        # Non-latin unicode should go to iTXt
        # 'Be careful with unicode!' in russian.
        text['Warning'] = reduce(lambda x, y: x + unic(y),
                                 (1054, 1089, 1090, 1086, 1088, 1086, 1078,
                                  1085, 1077, 1081, 32, 1089, 32, 1102, 1085,
                                  1080, 1082, 1086, 1076, 1086, 1084, 33),
                                 '')
        # Embedded keyword test
        info_e = dict(info)  # copy
        info_e.update(text)
        test_e = topngbytes('text_e.png', pixels, x, y, **info_e)
        x, y, pixels, info_r = png.Reader(bytes=test_e).read()
        self.assertEqual(text, info_r.get('text'))

        # Separate argument test
        info_a = dict(info)
        info_a['text'] = text
        # Here we can use any keyword, not only registered
        info_a['text']['Goddamn'] = 'I can do ANYTHING!'
        test_a = topngbytes('text_a.png', pixels, x, y, **info_a)
        x, y, pixels, info_r = png.Reader(bytes=test_a).read()
        self.assertEqual(text, info_r.get('text'))
예제 #36
0
파일: pnm2png.py 프로젝트: Scondo/purepng
def main(argv):
    """Run the PNG encoder with options from the command line."""
    (options, infilename, infile, outfile) = parse_options(argv[1:])

    if options.read_png:
        # Encode PNG to PPM
        pngObj = png.Reader(file=infile)
        width, height, pixels, meta = pngObj.asDirect()
        write_pnm(outfile, width, height, pixels, meta)
    else:
        # Encode PNM to PNG
        mode, width, height, depth, maxval = \
          read_pnm_header(infile, ('P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7'))
        # When it comes to the variety of input formats, we do something
        # rather rude.  Observe that L, LA, RGB, RGBA are the 4 colour
        # types supported by PNG and that they correspond to 1, 2, 3, 4
        # channels respectively.  So we use the number of channels in
        # the source image to determine which one we have.  We do not
        # care about TUPLTYPE.
        greyscale = depth <= 2
        pamalpha = depth in (2, 4)
        supported = [2 ** x - 1 for x in range(1, 17)]
        try:
            bitdepth = supported.index(maxval) + 1
        except ValueError:
            raise NotImplementedError(
              'your maxval (%s) not in supported list %s' %
              (maxval, str(supported)))
        writer = png.Writer(width, height,
                        greyscale=greyscale,
                        bitdepth=bitdepth,
                        interlace=options.interlace,
                        transparent=options.transparent,
                        background=options.background,
                        alpha=bool(pamalpha or options.alpha),
                        gamma=options.gamma,
                        compression=options.compression)
        if mode == png.strtobytes('P4'):
            rows = pbmb_scanlines(infile, width, height)
        elif mode in (png.strtobytes('P1'),
                      png.strtobytes('P2'),
                      png.strtobytes('P3')):
            rows = ascii_scanlines(infile, width, height, depth, bitdepth)
        else:
            rows = file_scanlines(infile, width, height, depth, bitdepth)
        if options.alpha:
            apgmfile = open(options.alpha, 'rb')
            _, awidth, aheight, adepth, amaxval = \
                read_pnm_header(apgmfile, ('P5', ))
            if amaxval != maxval:
                raise NotImplementedError(
                  'maxval %s of alpha channel mismatch %s maxval %s'
                  % (amaxval, infilename, maxval))
            if adepth != 1:
                raise ValueError("alpha image should have 1 channel")
            if (awidth, aheight) != (width, height):
                raise ValueError("alpha channel image size mismatch"
                                 " (%s has %sx%s but %s has %sx%s)"
                                 % (infilename, width, height,
                                    options.alpha, awidth, aheight))
            arows = file_scanlines(apgmfile, width, height, 1, bitdepth)
            merged = png.MergedPlanes(rows, depth, arows, 1, bitdepth)
            writer.write(outfile, merged)
            apgmfile.close()
        else:
            writer.write(outfile, rows)
    if infilename != '-':
        # if open - then close
        infile.close()
예제 #37
0
파일: test_png.py 프로젝트: Scondo/purepng
 def eachchunk(cname, data):
     """Corrupt the first filter byte"""
     data = zlib.decompress(data)
     data = strtobytes('\x99') + data[1:]
     data = zlib.compress(data)
     return (cname, data)
예제 #38
0
파일: test_png.py 프로젝트: Scondo/purepng
 def eachchunk(cname, data):
     """Adding garbage"""
     data = zlib.decompress(data)
     data += strtobytes('\x00garbage')
     data = zlib.compress(data)
     return (cname, data)