Created
May 3, 2015 10:39
-
-
Save f0k/57198de3cc2e9e2eebd6 to your computer and use it in GitHub Desktop.
Strip resolution information (pHYs chunk) from PNG file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
Strips the pHYs chunk (resolution information) of a .png file. | |
Handy if pdflatex fails with "dimension too large" due to the | |
PNG resolution being set to 1. | |
For usage information, call without any parameters. | |
Author: Jan Schlüter | |
""" | |
import sys | |
import os | |
import struct | |
KEEP_TIMESTAMP = True # whether to keep the timestamp on in-place operation | |
def print_usage(): | |
print 'png_strip_pHYs.py: Removes the pHYs chunk of a .png file if present.' | |
print 'Usage: %s INFILE [OUTFILE]' % sys.argv[0] | |
print ' INFILE: .png file to read' | |
print ' OUTFILE: .png file to write. Defaults to INFILE if omitted.' | |
def read_png_chunk(f): | |
""" | |
Yields all chunks from a PNG file. Make sure to have read the magic number | |
(first 8 bytes of the file) first. | |
See http://www.w3.org/TR/PNG/#5PNG-file-signature for documentation. | |
@return: A tuple of byte strings of a chunk: (length, type, data, crc). | |
""" | |
while True: | |
chunklen = f.read(4) | |
if len(chunklen) != 4: | |
break | |
chunktype = f.read(4) | |
chunkdata = f.read(struct.unpack('>L', chunklen)[0]) | |
chunkcrc = f.read(4) | |
yield chunklen, chunktype, chunkdata, chunkcrc | |
def main(): | |
if len(sys.argv) not in (2,3): | |
print_usage() | |
return | |
# 'parse' command line | |
infile = sys.argv[1] | |
if len(sys.argv) > 2: | |
outfile = sys.argv[2] | |
else: | |
outfile = infile | |
if KEEP_TIMESTAMP: | |
fileinfo = os.stat(infile) | |
# read input file | |
buff = [] | |
with open(infile, 'rb') as f: | |
# read magic number | |
magic = f.read(8) | |
if magic != '\x89PNG\r\n\x1a\n': | |
print "This is not a valid .png file. Aborting." | |
return | |
buff.append(magic) | |
# read input chunks | |
for clen, ctype, cdata, ccrc in read_png_chunk(f): | |
if ctype != 'pHYs': | |
buff.extend([clen, ctype, cdata, ccrc]) | |
# write output file | |
with open(outfile, 'wb') as f: | |
f.writelines(buff) | |
# keep timestamp if needed | |
if KEEP_TIMESTAMP and infile == outfile: | |
os.utime(outfile, (fileinfo.st_atime, fileinfo.st_mtime)) | |
if __name__=="__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment