(Forwarded from:  http://bugs.python.org/issue13514  per Ezio Melotti)

The Python Imaging Library does not support handling of UTF-8 'iTXt'
key:value chunks in PNG files:

  http://www.w3.org/TR/PNG/#11iTXt

Such support is necessary for successful extraction of key:value pairs
of UTF-8 encoded data, stored in an PNG 'iTXt' comment chunk.

The following example file (from British GCHQ) demonstrates such a
record in a PNG file.  Based on this evidence, it is highly likely
that GCHQ hide all of their important secrets using this kind of
steganography, and likely necessary that spies from the rest of the
world are requiring similar access to GCHQ secrets.  Inclusion of a
working chunk_iTXt() PIL/PNG support function will enable more
harmonious and effective eavesdropping.  Example image:

  http://www.canyoucrackit.co.uk/images/cyber.png

(The attached .py file is not a directly apply-able patch, but
contains a working implementation for chunk_iTXt() and a demonstrative
test function for inserting it).

        -Paul

#!/usr/bin/env python
# Paul Sladen, 2011-12-01
from PIL import PngImagePlugin, Image, ImageFile
#Image.DEBUG = True

# Meh, why doesn't PIL support this already?
def chunk_iTXt(self, pos, len):
    s = ImageFile._safe_read(self.fp, len)
    # http://www.w3.org/TR/PNG/#11iTXt
    k, structure = s.split('\0', 1)
    compression_flag, compression_method = map(ord, structure[:2])
    language_tag, translated, t = structure[2:].split('\0', 2)
    if compression_flag == 0:
        v = t.decode('utf-8')
    elif compression_flag == 1 and compression_method == 0:
        import zlib
        v = zlib.decompress(t).decode('utf-8')
    else:
        raise SyntaxError("Unknown compression request %d in iTXt chunk" %
                          compression_method)
    self.im_info[k] = {'translated_keyword': translated.decode('utf-8'),
                       'language_tag': language_tag,
                       'text': v}
    self.im_text[k] = v
    return s

PngImagePlugin.PngStream.chunk_iTXt = chunk_iTXt

def test(f):
    i = PngImagePlugin.PngImageFile(f)
    print i.info, i.text
    steno = i.text['Comment'].decode('base64')

if __name__ == '__main__':
    test('cyber.png')
_______________________________________________
Image-SIG maillist  -  Image-SIG@python.org
http://mail.python.org/mailman/listinfo/image-sig

Reply via email to