From f1736a636bb813a08a780eef8f2f87987c6cc622 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Tue, 16 Apr 2013 23:12:09 -0500 Subject: [PATCH] [libpng16] Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length written by libpng-1.6.0 and 1.6.1. --- ANNOUNCE | 6 +- CHANGES | 4 +- contrib/tools/fixitxt.c | 140 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 contrib/tools/fixitxt.c diff --git a/ANNOUNCE b/ANNOUNCE index ae81f644c..065a28c0d 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.6.2beta02 - April 14, 2013 +Libpng 1.6.2beta02 - April 17, 2013 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -38,7 +38,9 @@ Version 1.6.2beta01 [April 14, 2013] (Flavio Medeiros). Corrected length written to uncompressed iTXt chunks (Samuli Suominen). -Version 1.6.2beta02 [April 14, 2013] +Version 1.6.2beta02 [April 17, 2013] + Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length + written by libpng-1.6.0 and 1.6.1. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 4bc5d9dbd..c3484516b 100644 --- a/CHANGES +++ b/CHANGES @@ -4486,7 +4486,9 @@ Version 1.6.2beta01 [April 14, 2013] (Flavio Medeiros). Corrected length written to uncompressed iTXt chunks (Samuli Suominen). -Version 1.6.2beta02 [April 14, 2013] +Version 1.6.2beta02 [April 17, 2013] + Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length + written by libpng-1.6.0 and 1.6.1. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/contrib/tools/fixitxt.c b/contrib/tools/fixitxt.c new file mode 100644 index 000000000..b979a7a30 --- /dev/null +++ b/contrib/tools/fixitxt.c @@ -0,0 +1,140 @@ +#include + +/* fixitxt version 1.0.0 + * + * Copyright 2013 Glenn Randers-Pehrson + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * Usage: + * + * fixitxt.exe < bad.png > good.png + * + * Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more + * uncompressed iTXt chunks. Assumes that the actual length is greater + * than or equal to the value in the length byte, and that the CRC is + * correct for the actual length. This program hunts for the CRC and + * adjusts the length byte accordingly. It is not an error to process a + * PNG file that has no iTXt chunks or one that has valid iTXt chunks; + * such files will simply be copied. + * + * Requires zlib (for crc32 and Z_NULL); build with + * + * gcc -O -o fixitxt fixitxt.c -lz + */ + +#define GETBREAK c=getchar(); if (c == EOF) break; +#include + +main() +{ + unsigned int i; + unsigned char buf[100000]; + unsigned long crc; + unsigned int c; + +/* Skip 8-byte signature */ + for (i=8; i; i--) + { + c=GETBREAK; + putchar(c); + } + +if (c != EOF) +for (;;) + { + /* Read the length */ + unsigned int length; + c=GETBREAK; buf[0] = c; + c=GETBREAK; buf[1] = c; + c=GETBREAK; buf[2] = c; + c=GETBREAK; buf[3] = c; + + length=buf[0]<<24 | buf[1]<<16 | buf[2] << 8 | buf[3]; + /* Read the chunkname */ + c=GETBREAK; buf[4] = c; + c=GETBREAK; buf[5] = c; + c=GETBREAK; buf[6] = c; + c=GETBREAK; buf[7] = c; + + + /* The iTXt chunk type expressed as integers is (105, 84, 88, 116) */ + if (buf[4] == 105 && buf[5] == 84 && buf[6] == 88 && buf[7] == 116) + { + /* Initialize the CRC */ + crc = crc32(0, Z_NULL, 0); + + /* Copy the data bytes */ + for (i=8; i < length + 12; i++) + { + c=GETBREAK; buf[i] = c; + } + + /* Calculate the CRC */ + crc = crc32(crc, buf+4, (uInt)length+4); + + for (;;) + { + /* Check the CRC */ + if (((crc >> 24) & 0xff) == buf[length+8] && + ((crc >> 16) & 0xff) == buf[length+9] && + ((crc >> 8) & 0xff) == buf[length+10] && + ((crc ) & 0xff) == buf[length+11]) + break; + + length++; + + c=GETBREAK; + buf[length+11]=c; + + /* Update the CRC */ + crc = crc32(crc, buf+7+length, 1); + } + + /* Update length bytes */ + buf[0] = (length << 24) & 0xff; + buf[1] = (length << 16) & 0xff; + buf[2] = (length << 8) & 0xff; + buf[3] = (length ) & 0xff; + + /* Write the fixed iTXt chunk (length, name, data, crc) */ + for (i=0; i