VirtualBox

source: vbox/trunk/src/libs/libpng-1.6.45/contrib/tools/png-fix-itxt.c@ 108378

最後變更 在這個檔案從108378是 103316,由 vboxsync 提交於 13 月 前

libpng-1.6.42: Applied and adjusted our libpng changes to 1.6.42. bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 4.0 KB
 
1/* png-fix-itxt
2 *
3 * Copyright 2015 Glenn Randers-Pehrson
4 *
5 * This code is released under the libpng license.
6 * For conditions of distribution and use, see the disclaimer
7 * and license in png.h
8 *
9 * Usage:
10 *
11 * png-fix-itxt < bad.png > good.png
12 *
13 * Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more
14 * uncompressed iTXt chunks. Assumes that the actual length is greater
15 * than or equal to the value in the length byte, and that the CRC is
16 * correct for the actual length. This program hunts for the CRC and
17 * adjusts the length byte accordingly. It is not an error to process a
18 * PNG file that has no iTXt chunks or one that has valid iTXt chunks;
19 * such files will simply be copied.
20 *
21 * Requires zlib (for crc32 and Z_NULL); build with
22 *
23 * gcc -O -o png-fix-itxt png-fix-itxt.c -lz
24 *
25 * If you need to handle iTXt chunks larger than 500000 kbytes you must
26 * rebuild png-fix-itxt with a larger values of MAX_LENGTH (or a smaller value
27 * if you know you will never encounter such huge iTXt chunks).
28 */
29
30#include <stdio.h>
31#include <zlib.h>
32
33#define MAX_LENGTH 500000
34
35/* Read one character (inchar), also return octet (c), break if EOF */
36#define GETBREAK inchar=getchar(); \
37 c=(inchar & 0xffU);\
38 if (inchar != c) break
39int
40main(void)
41{
42 unsigned int i;
43 unsigned char buf[MAX_LENGTH];
44 unsigned long crc;
45 unsigned char c;
46 int inchar;
47
48/* Skip 8-byte signature */
49 for (i=8; i; i--)
50 {
51 GETBREAK;
52 putchar(c);
53 }
54
55if (inchar == c) /* !EOF */
56for (;;)
57 {
58 /* Read the length */
59 unsigned long length; /* must be 32 bits! */
60 GETBREAK; buf[0] = c; length = c; length <<= 8;
61 GETBREAK; buf[1] = c; length += c; length <<= 8;
62 GETBREAK; buf[2] = c; length += c; length <<= 8;
63 GETBREAK; buf[3] = c; length += c;
64
65 /* Read the chunkname */
66 GETBREAK; buf[4] = c;
67 GETBREAK; buf[5] = c;
68 GETBREAK; buf[6] = c;
69 GETBREAK; buf[7] = c;
70
71
72 /* The iTXt chunk type expressed as integers is (105, 84, 88, 116) */
73 if (buf[4] == 105 && buf[5] == 84 && buf[6] == 88 && buf[7] == 116)
74 {
75 if (length >= MAX_LENGTH-12)
76 break; /* To do: handle this more gracefully */
77
78 /* Initialize the CRC */
79 crc = crc32(0, Z_NULL, 0);
80
81 /* Copy the data bytes */
82 for (i=8; i < length + 12; i++)
83 {
84 GETBREAK; buf[i] = c;
85 }
86
87 if (inchar != c) /* EOF */
88 break;
89
90 /* Calculate the CRC */
91 crc = crc32(crc, buf+4, (uInt)length+4);
92
93 for (;;)
94 {
95 /* Check the CRC */
96 if (((crc >> 24) & 0xffU) == buf[length+8] &&
97 ((crc >> 16) & 0xffU) == buf[length+9] &&
98 ((crc >> 8) & 0xffU) == buf[length+10] &&
99 ((crc ) & 0xffU) == buf[length+11])
100 break;
101
102 length++;
103
104 if (length >= MAX_LENGTH-12)
105 break;
106
107 GETBREAK;
108 buf[length+11] = c;
109
110 /* Update the CRC */
111 crc = crc32(crc, buf+7+length, 1);
112 }
113
114 if (inchar != c) /* EOF */
115 break;
116
117 /* Update length bytes */
118 buf[0] = (unsigned char)((length >> 24) & 0xffU);
119 buf[1] = (unsigned char)((length >> 16) & 0xffU);
120 buf[2] = (unsigned char)((length >> 8) & 0xffU);
121 buf[3] = (unsigned char)((length ) & 0xffU);
122
123 /* Write the fixed iTXt chunk (length, name, data, crc) */
124 for (i=0; i<length+12; i++)
125 putchar(buf[i]);
126 }
127
128 else
129 {
130 if (inchar != c) /* EOF */
131 break;
132
133 /* Copy bytes that were already read (length and chunk name) */
134 for (i=0; i<8; i++)
135 putchar(buf[i]);
136
137 /* Copy data bytes and CRC */
138 for (i=8; i< length+12; i++)
139 {
140 GETBREAK;
141 putchar(c);
142 }
143
144 if (inchar != c) /* EOF */
145 {
146 break;
147 }
148
149 /* The IEND chunk type expressed as integers is (73, 69, 78, 68) */
150 if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
151 break;
152 }
153
154 if (inchar != c) /* EOF */
155 break;
156
157 if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
158 break;
159 }
160
161 return 0;
162}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette