# -*- coding: utf-8 -*- """ sphinx.util.png ~~~~~~~~~~~~~~~ PNG image manipulation helpers. :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import struct import binascii from sphinx.util.pycompat import b LEN_IEND = 12 LEN_DEPTH = 22 DEPTH_CHUNK_LEN = struct.pack('!i', 10) DEPTH_CHUNK_START = b('tEXtDepth\x00') IEND_CHUNK = b('\x00\x00\x00\x00IEND\xAE\x42\x60\x82') def read_png_depth(filename): """Read the special tEXt chunk indicating the depth from a PNG file.""" result = None f = open(filename, 'rb') try: f.seek(- (LEN_IEND + LEN_DEPTH), 2) depthchunk = f.read(LEN_DEPTH) if not depthchunk.startswith(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START): # either not a PNG file or not containing the depth chunk return None result = struct.unpack('!i', depthchunk[14:18])[0] finally: f.close() return result def write_png_depth(filename, depth): """Write the special tEXt chunk indicating the depth to a PNG file. The chunk is placed immediately before the special IEND chunk. """ data = struct.pack('!i', depth) f = open(filename, 'r+b') try: # seek to the beginning of the IEND chunk f.seek(-LEN_IEND, 2) # overwrite it with the depth chunk f.write(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START + data) # calculate the checksum over chunk name and data f.write(struct.pack('!i', binascii.crc32(DEPTH_CHUNK_START + data))) # replace the IEND chunk f.write(IEND_CHUNK) finally: f.close()