summaryrefslogtreecommitdiff
path: root/Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c')
-rw-r--r--Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c b/Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c
new file mode 100644
index 00000000000..d717b3e6a07
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-1.6.2/contrib/tools/fixitxt.c
@@ -0,0 +1,144 @@
+#include <stdio.h>
+
+/* 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 MAX_LENGTH 500000
+
+#define GETBREAK c=getchar(); if (c == EOF) break;
+#include <zlib.h>
+
+main()
+{
+ unsigned int i;
+ unsigned char buf[MAX_LENGTH];
+ 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 long length;
+ c=GETBREAK; buf[0] = c;
+ c=GETBREAK; buf[1] = c;
+ c=GETBREAK; buf[2] = c;
+ c=GETBREAK; buf[3] = c;
+
+ length=((((unsigned long) buf[0]<<8 + 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)
+ {
+ if (length >= MAX_LENGTH-12)
+ break; /* To do: handle this more gracefully */
+
+ /* 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++;
+
+ if (length >= MAX_LENGTH-12)
+ break;
+
+ 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<length+12; i++)
+ putchar(buf[i]);
+ }
+
+ else
+ {
+ /* Copy bytes that were already read (length and chunk name) */
+ for (i=0; i<8; i++)
+ putchar(buf[i]);
+
+ /* Copy data bytes and CRC */
+ for (i=8; i< length+12; i++)
+ {
+ c=GETBREAK;
+ putchar(c);
+ }
+
+ if (c == EOF)
+ {
+ break;
+ }
+
+ /* The IEND chunk type expressed as integers is (73, 69, 78, 68) */
+ if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
+ break;
+ }
+
+ if (c == EOF)
+ break;
+
+ if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
+ break;
+ }
+}