Skip to content

PNG: "Raw profile type exif" keyword is only recognized in zTXt, not tEXt #387

Description

@generalmimon

See src/bang/parsers/image/png/UnpackParser.py - currently, the keyword Raw profile type exif is only recognized in zTXt chunks:

elif i.type == 'zTXt':
# zTXt contains key/value pairs with metadata about the PNG file,
# zlib compressed. (section 11.3.4.4)
# Multiple zTXt chunks are allowed.
if i.body.keyword == 'Raw profile type exif':
# before eXIf ImageMagick used the zTXt field to
# store EXIF data in hex form. python-pillow allows reading
# raw exif data using an Exif() object.
# https://github.com/python-pillow/Pillow/issues/4460

I came across a test file in https://github.com/python-pillow/Pillow/tree/701d40433650269af4607824e07309243a20d354 with a Raw profile type exif keyword in a tEXt chunk, namely Tests/images/exif_imagemagick.png. Below is a pngcheck -vt report (using pngcheck 4.0.1):

File: ./Tests/images/exif_imagemagick.png (179399 bytes)
  chunk IHDR at offset 0x0000c, length 13
    512 x 512 image, 24-bit RGB, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk cHRM at offset 0x00035, length 32
    White x = 0.31270 y = 0.32900,  Red x = 0.64000 y = 0.33000
    Green x = 0.30000 y = 0.60000,  Blue x = 0.15000 y = 0.06000
  chunk bKGD at offset 0x00061, length 6
    red = 0x00ff, green = 0x00ff, blue = 0x00ff
  chunk pHYs at offset 0x00073, length 9: 2834x2834 pixels/meter (72 dpi)
  chunk tIME at offset 0x00088, length 7:  7 Jan 2019 10:13:34 UTC
  chunk tEXt at offset 0x0009b, length 102, keyword: Raw profile type exif
    
    exif
          32
    4578696600004d4d002a00000008000101120003000000010001000000000000

  chunk IDAT at offset 0x0010d, length 32768
    zlib: deflated, 32K window, maximum compression
  chunk IDAT at offset 0x08119, length 32768
  chunk IDAT at offset 0x10125, length 32768
  chunk IDAT at offset 0x18131, length 32768
  chunk IDAT at offset 0x2013d, length 32768
  chunk IDAT at offset 0x28149, length 14882
  chunk tEXt at offset 0x2bb77, length 37, keyword: date:create
    2020-03-13T10:43:59+00:00
  chunk tEXt at offset 0x2bba8, length 37, keyword: date:modify
    2020-03-13T10:43:59+00:00
  chunk tEXt at offset 0x2bbd9, length 56, keyword: icc:copyright
    Copyright (c) 1998 Hewlett-Packard Company
  chunk tEXt at offset 0x2bc1d, length 33, keyword: icc:description
    sRGB IEC61966-2.1
  chunk tEXt at offset 0x2bc4a, length 38, keyword: icc:manufacturer
    IEC http://www.iec.ch
  chunk tEXt at offset 0x2bc7c, length 55, keyword: icc:model
    IEC 61966-2.1 Default RGB colour space - sRGB
  chunk IEND at offset 0x2bcbf, length 0
No errors detected in ./Tests/images/exif_imagemagick.png (20 chunks, 77.2% compression).

The official PNG spec explicitly states this (https://www.w3.org/TR/2025/REC-png-3-20250624/#11zTXt):

The zTXt and tEXt chunks are semantically equivalent, but the zTXt chunk is recommended for storing large blocks of text.

... so BANG should ideally handle zTXt and tEXt the same. Probably iTXt as well, but I haven't seen a Raw profile type exif keyword in iTXt, so... 🤷‍♂️

Also, it recommends using "uncompressed text chunks" (which tEXt is) if the text is less than 1024 bytes in size (https://www.w3.org/TR/2025/REC-png-3-20250624/#12Text-chunk-processing):

It is recommended that text items less than 1024 bytes in size should be output using uncompressed text chunks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions