New comit of SDL2
[supertux.git] / src / SDL2 / external / libpng-1.6.2 / contrib / tools / fixitxt.c
1 #include <stdio.h>
2
3 /* fixitxt version 1.0.0
4  *
5  * Copyright 2013 Glenn Randers-Pehrson
6  *
7  * This code is released under the libpng license.
8  * For conditions of distribution and use, see the disclaimer
9  * and license in png.h
10  *
11  * Usage:            
12  *
13  *     fixitxt.exe < bad.png > good.png
14  *
15  * Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more
16  * uncompressed iTXt chunks.  Assumes that the actual length is greater
17  * than or equal to the value in the length byte, and that the CRC is
18  * correct for the actual length.  This program hunts for the CRC and
19  * adjusts the length byte accordingly.  It is not an error to process a
20  * PNG file that has no iTXt chunks or one that has valid iTXt chunks;
21  * such files will simply be copied.
22  *
23  * Requires zlib (for crc32 and Z_NULL); build with
24  *
25  *     gcc -O -o fixitxt fixitxt.c -lz
26  */
27
28 #define MAX_LENGTH 500000
29
30 #define GETBREAK c=getchar(); if (c == EOF) break;
31 #include <zlib.h>
32
33 main()
34 {
35    unsigned int i;
36    unsigned char buf[MAX_LENGTH];
37    unsigned long crc;
38    unsigned int c;
39
40 /* Skip 8-byte signature */
41    for (i=8; i; i--)
42    {
43       c=GETBREAK;
44       putchar(c);
45    }
46
47 if (c != EOF)
48 for (;;)
49  {
50    /* Read the length */
51    unsigned long length;
52    c=GETBREAK; buf[0] = c;
53    c=GETBREAK; buf[1] = c;
54    c=GETBREAK; buf[2] = c;
55    c=GETBREAK; buf[3] = c;
56
57    length=((((unsigned long) buf[0]<<8 + buf[1]<<16) + buf[2] << 8) + buf[3]);
58    /* Read the chunkname */
59    c=GETBREAK; buf[4] = c;
60    c=GETBREAK; buf[5] = c;
61    c=GETBREAK; buf[6] = c;
62    c=GETBREAK; buf[7] = c;
63
64
65    /* The iTXt chunk type expressed as integers is (105, 84, 88, 116) */
66    if (buf[4] == 105 && buf[5] == 84 && buf[6] == 88 && buf[7] == 116)
67    {
68       if (length >= MAX_LENGTH-12)
69          break;  /* To do: handle this more gracefully */
70
71       /* Initialize the CRC */
72       crc = crc32(0, Z_NULL, 0);
73
74       /* Copy the data bytes */
75       for (i=8; i < length + 12; i++)
76       {
77          c=GETBREAK; buf[i] = c;
78       }
79
80       /* Calculate the CRC */
81       crc = crc32(crc, buf+4, (uInt)length+4);
82
83       for (;;)
84       {
85         /* Check the CRC */
86         if (((crc >> 24) & 0xff) == buf[length+8] &&
87             ((crc >> 16) & 0xff) == buf[length+9] &&
88             ((crc >>  8) & 0xff) == buf[length+10] &&
89             ((crc      ) & 0xff) == buf[length+11])
90            break;
91
92         length++;
93
94         if (length >= MAX_LENGTH-12)
95            break;
96
97         c=GETBREAK;
98         buf[length+11]=c;
99
100         /* Update the CRC */
101         crc = crc32(crc, buf+7+length, 1);
102       }
103
104       /* Update length bytes */
105         buf[0] = (length << 24) & 0xff;
106         buf[1] = (length << 16) & 0xff;
107         buf[2] = (length <<  8) & 0xff;
108         buf[3] = (length      ) & 0xff;
109
110       /* Write the fixed iTXt chunk (length, name, data, crc) */
111       for (i=0; i<length+12; i++)
112          putchar(buf[i]);
113    }
114
115    else
116    {
117       /* Copy bytes that were already read (length and chunk name) */
118       for (i=0; i<8; i++)
119          putchar(buf[i]);
120
121       /* Copy data bytes and CRC */
122       for (i=8; i< length+12; i++)
123       {
124          c=GETBREAK;
125          putchar(c);
126       }
127
128       if (c == EOF)
129       {
130          break;
131       }
132
133    /* The IEND chunk type expressed as integers is (73, 69, 78, 68) */
134       if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
135          break;
136    }
137
138    if (c == EOF)
139       break;
140
141    if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
142      break;
143  }
144 }