2296
|
1
|
|
2 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
|
|
3 *
|
|
4 * Last changed in libpng 1.6.9 [February 6, 2014]
|
|
5 * Copyright (c) 1998-2014 Glenn Randers-Pehrson
|
|
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
|
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
|
8 *
|
|
9 * This code is released under the libpng license.
|
|
10 * For conditions of distribution and use, see the disclaimer
|
|
11 * and license in png.h
|
|
12 */
|
|
13
|
|
14 #include "pngpriv.h"
|
|
15
|
|
16 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
|
17
|
|
18 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
|
19 /* Turn on BGR-to-RGB mapping */
|
|
20 void PNGAPI
|
|
21 png_set_bgr(png_structrp png_ptr)
|
|
22 {
|
|
23 png_debug(1, "in png_set_bgr");
|
|
24
|
|
25 if (png_ptr == NULL)
|
|
26 return;
|
|
27
|
|
28 png_ptr->transformations |= PNG_BGR;
|
|
29 }
|
|
30 #endif
|
|
31
|
|
32 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
|
33 /* Turn on 16 bit byte swapping */
|
|
34 void PNGAPI
|
|
35 png_set_swap(png_structrp png_ptr)
|
|
36 {
|
|
37 png_debug(1, "in png_set_swap");
|
|
38
|
|
39 if (png_ptr == NULL)
|
|
40 return;
|
|
41
|
|
42 if (png_ptr->bit_depth == 16)
|
|
43 png_ptr->transformations |= PNG_SWAP_BYTES;
|
|
44 }
|
|
45 #endif
|
|
46
|
|
47 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
|
48 /* Turn on pixel packing */
|
|
49 void PNGAPI
|
|
50 png_set_packing(png_structrp png_ptr)
|
|
51 {
|
|
52 png_debug(1, "in png_set_packing");
|
|
53
|
|
54 if (png_ptr == NULL)
|
|
55 return;
|
|
56
|
|
57 if (png_ptr->bit_depth < 8)
|
|
58 {
|
|
59 png_ptr->transformations |= PNG_PACK;
|
|
60 # ifdef PNG_WRITE_SUPPORTED
|
|
61 png_ptr->usr_bit_depth = 8;
|
|
62 # endif
|
|
63 }
|
|
64 }
|
|
65 #endif
|
|
66
|
|
67 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
|
68 /* Turn on packed pixel swapping */
|
|
69 void PNGAPI
|
|
70 png_set_packswap(png_structrp png_ptr)
|
|
71 {
|
|
72 png_debug(1, "in png_set_packswap");
|
|
73
|
|
74 if (png_ptr == NULL)
|
|
75 return;
|
|
76
|
|
77 if (png_ptr->bit_depth < 8)
|
|
78 png_ptr->transformations |= PNG_PACKSWAP;
|
|
79 }
|
|
80 #endif
|
|
81
|
|
82 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
|
83 void PNGAPI
|
|
84 png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
|
|
85 {
|
|
86 png_debug(1, "in png_set_shift");
|
|
87
|
|
88 if (png_ptr == NULL)
|
|
89 return;
|
|
90
|
|
91 png_ptr->transformations |= PNG_SHIFT;
|
|
92 png_ptr->shift = *true_bits;
|
|
93 }
|
|
94 #endif
|
|
95
|
|
96 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
|
|
97 defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
|
98 int PNGAPI
|
|
99 png_set_interlace_handling(png_structrp png_ptr)
|
|
100 {
|
|
101 png_debug(1, "in png_set_interlace handling");
|
|
102
|
|
103 if (png_ptr && png_ptr->interlaced)
|
|
104 {
|
|
105 png_ptr->transformations |= PNG_INTERLACE;
|
|
106 return (7);
|
|
107 }
|
|
108
|
|
109 return (1);
|
|
110 }
|
|
111 #endif
|
|
112
|
|
113 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
|
114 /* Add a filler byte on read, or remove a filler or alpha byte on write.
|
|
115 * The filler type has changed in v0.95 to allow future 2-byte fillers
|
|
116 * for 48-bit input data, as well as to avoid problems with some compilers
|
|
117 * that don't like bytes as parameters.
|
|
118 */
|
|
119 void PNGAPI
|
|
120 png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
|
|
121 {
|
|
122 png_debug(1, "in png_set_filler");
|
|
123
|
|
124 if (png_ptr == NULL)
|
|
125 return;
|
|
126
|
|
127 /* In libpng 1.6 it is possible to determine whether this is a read or write
|
|
128 * operation and therefore to do more checking here for a valid call.
|
|
129 */
|
|
130 if (png_ptr->mode & PNG_IS_READ_STRUCT)
|
|
131 {
|
|
132 # ifdef PNG_READ_FILLER_SUPPORTED
|
|
133 /* On read png_set_filler is always valid, regardless of the base PNG
|
|
134 * format, because other transformations can give a format where the
|
|
135 * filler code can execute (basically an 8 or 16-bit component RGB or G
|
|
136 * format.)
|
|
137 *
|
|
138 * NOTE: usr_channels is not used by the read code! (This has led to
|
|
139 * confusion in the past.) The filler is only used in the read code.
|
|
140 */
|
|
141 png_ptr->filler = (png_uint_16)filler;
|
|
142 # else
|
|
143 png_app_error(png_ptr, "png_set_filler not supported on read");
|
|
144 PNG_UNUSED(filler) /* not used in the write case */
|
|
145 return;
|
|
146 # endif
|
|
147 }
|
|
148
|
|
149 else /* write */
|
|
150 {
|
|
151 # ifdef PNG_WRITE_FILLER_SUPPORTED
|
|
152 /* On write the usr_channels parameter must be set correctly at the
|
|
153 * start to record the number of channels in the app-supplied data.
|
|
154 */
|
|
155 switch (png_ptr->color_type)
|
|
156 {
|
|
157 case PNG_COLOR_TYPE_RGB:
|
|
158 png_ptr->usr_channels = 4;
|
|
159 break;
|
|
160
|
|
161 case PNG_COLOR_TYPE_GRAY:
|
|
162 if (png_ptr->bit_depth >= 8)
|
|
163 {
|
|
164 png_ptr->usr_channels = 2;
|
|
165 break;
|
|
166 }
|
|
167
|
|
168 else
|
|
169 {
|
|
170 /* There simply isn't any code in libpng to strip out bits
|
|
171 * from bytes when the components are less than a byte in
|
|
172 * size!
|
|
173 */
|
|
174 png_app_error(png_ptr,
|
|
175 "png_set_filler is invalid for low bit depth gray output");
|
|
176 return;
|
|
177 }
|
|
178
|
|
179 default:
|
|
180 png_app_error(png_ptr,
|
|
181 "png_set_filler: inappropriate color type");
|
|
182 return;
|
|
183 }
|
|
184 # else
|
|
185 png_app_error(png_ptr, "png_set_filler not supported on write");
|
|
186 return;
|
|
187 # endif
|
|
188 }
|
|
189
|
|
190 /* Here on success - libpng supports the operation, set the transformation
|
|
191 * and the flag to say where the filler channel is.
|
|
192 */
|
|
193 png_ptr->transformations |= PNG_FILLER;
|
|
194
|
|
195 if (filler_loc == PNG_FILLER_AFTER)
|
|
196 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
|
|
197
|
|
198 else
|
|
199 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
|
|
200 }
|
|
201
|
|
202 /* Added to libpng-1.2.7 */
|
|
203 void PNGAPI
|
|
204 png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
|
|
205 {
|
|
206 png_debug(1, "in png_set_add_alpha");
|
|
207
|
|
208 if (png_ptr == NULL)
|
|
209 return;
|
|
210
|
|
211 png_set_filler(png_ptr, filler, filler_loc);
|
|
212 /* The above may fail to do anything. */
|
|
213 if (png_ptr->transformations & PNG_FILLER)
|
|
214 png_ptr->transformations |= PNG_ADD_ALPHA;
|
|
215 }
|
|
216
|
|
217 #endif
|
|
218
|
|
219 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
|
220 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
|
221 void PNGAPI
|
|
222 png_set_swap_alpha(png_structrp png_ptr)
|
|
223 {
|
|
224 png_debug(1, "in png_set_swap_alpha");
|
|
225
|
|
226 if (png_ptr == NULL)
|
|
227 return;
|
|
228
|
|
229 png_ptr->transformations |= PNG_SWAP_ALPHA;
|
|
230 }
|
|
231 #endif
|
|
232
|
|
233 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
|
|
234 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
|
235 void PNGAPI
|
|
236 png_set_invert_alpha(png_structrp png_ptr)
|
|
237 {
|
|
238 png_debug(1, "in png_set_invert_alpha");
|
|
239
|
|
240 if (png_ptr == NULL)
|
|
241 return;
|
|
242
|
|
243 png_ptr->transformations |= PNG_INVERT_ALPHA;
|
|
244 }
|
|
245 #endif
|
|
246
|
|
247 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
|
248 void PNGAPI
|
|
249 png_set_invert_mono(png_structrp png_ptr)
|
|
250 {
|
|
251 png_debug(1, "in png_set_invert_mono");
|
|
252
|
|
253 if (png_ptr == NULL)
|
|
254 return;
|
|
255
|
|
256 png_ptr->transformations |= PNG_INVERT_MONO;
|
|
257 }
|
|
258
|
|
259 /* Invert monochrome grayscale data */
|
|
260 void /* PRIVATE */
|
|
261 png_do_invert(png_row_infop row_info, png_bytep row)
|
|
262 {
|
|
263 png_debug(1, "in png_do_invert");
|
|
264
|
|
265 /* This test removed from libpng version 1.0.13 and 1.2.0:
|
|
266 * if (row_info->bit_depth == 1 &&
|
|
267 */
|
|
268 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
|
269 {
|
|
270 png_bytep rp = row;
|
|
271 png_size_t i;
|
|
272 png_size_t istop = row_info->rowbytes;
|
|
273
|
|
274 for (i = 0; i < istop; i++)
|
|
275 {
|
|
276 *rp = (png_byte)(~(*rp));
|
|
277 rp++;
|
|
278 }
|
|
279 }
|
|
280
|
|
281 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
|
282 row_info->bit_depth == 8)
|
|
283 {
|
|
284 png_bytep rp = row;
|
|
285 png_size_t i;
|
|
286 png_size_t istop = row_info->rowbytes;
|
|
287
|
|
288 for (i = 0; i < istop; i += 2)
|
|
289 {
|
|
290 *rp = (png_byte)(~(*rp));
|
|
291 rp += 2;
|
|
292 }
|
|
293 }
|
|
294
|
|
295 #ifdef PNG_16BIT_SUPPORTED
|
|
296 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
|
297 row_info->bit_depth == 16)
|
|
298 {
|
|
299 png_bytep rp = row;
|
|
300 png_size_t i;
|
|
301 png_size_t istop = row_info->rowbytes;
|
|
302
|
|
303 for (i = 0; i < istop; i += 4)
|
|
304 {
|
|
305 *rp = (png_byte)(~(*rp));
|
|
306 *(rp + 1) = (png_byte)(~(*(rp + 1)));
|
|
307 rp += 4;
|
|
308 }
|
|
309 }
|
|
310 #endif
|
|
311 }
|
|
312 #endif
|
|
313
|
|
314 #ifdef PNG_16BIT_SUPPORTED
|
|
315 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
|
316 /* Swaps byte order on 16 bit depth images */
|
|
317 void /* PRIVATE */
|
|
318 png_do_swap(png_row_infop row_info, png_bytep row)
|
|
319 {
|
|
320 png_debug(1, "in png_do_swap");
|
|
321
|
|
322 if (row_info->bit_depth == 16)
|
|
323 {
|
|
324 png_bytep rp = row;
|
|
325 png_uint_32 i;
|
|
326 png_uint_32 istop= row_info->width * row_info->channels;
|
|
327
|
|
328 for (i = 0; i < istop; i++, rp += 2)
|
|
329 {
|
|
330 png_byte t = *rp;
|
|
331 *rp = *(rp + 1);
|
|
332 *(rp + 1) = t;
|
|
333 }
|
|
334 }
|
|
335 }
|
|
336 #endif
|
|
337 #endif
|
|
338
|
|
339 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
|
340 static PNG_CONST png_byte onebppswaptable[256] = {
|
|
341 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
|
342 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
|
343 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
|
344 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
|
345 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
|
346 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
|
347 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
|
348 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
|
349 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
|
350 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
|
351 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
|
352 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
|
353 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
|
354 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
|
355 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
|
356 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
|
357 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
|
358 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
|
359 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
|
360 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
|
361 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
|
362 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
|
363 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
|
364 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
|
365 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
|
366 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
|
367 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
|
368 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
|
369 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
|
370 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
|
371 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
|
372 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
|
373 };
|
|
374
|
|
375 static PNG_CONST png_byte twobppswaptable[256] = {
|
|
376 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
|
|
377 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
|
|
378 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
|
|
379 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
|
|
380 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
|
|
381 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
|
|
382 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
|
|
383 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
|
|
384 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
|
|
385 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
|
|
386 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
|
|
387 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
|
|
388 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
|
|
389 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
|
|
390 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
|
|
391 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
|
|
392 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
|
|
393 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
|
|
394 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
|
|
395 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
|
|
396 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
|
|
397 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
|
|
398 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
|
|
399 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
|
|
400 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
|
|
401 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
|
|
402 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
|
|
403 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
|
|
404 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
|
|
405 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
|
|
406 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
|
|
407 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
|
|
408 };
|
|
409
|
|
410 static PNG_CONST png_byte fourbppswaptable[256] = {
|
|
411 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
|
|
412 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
|
|
413 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
|
|
414 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
|
|
415 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
|
|
416 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
|
|
417 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
|
|
418 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
|
|
419 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
|
|
420 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
|
|
421 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
|
|
422 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
|
|
423 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
|
|
424 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
|
|
425 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
|
|
426 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
|
|
427 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
|
|
428 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
|
|
429 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
|
|
430 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
|
|
431 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
|
|
432 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
|
|
433 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
|
|
434 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
|
|
435 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
|
|
436 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
|
|
437 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
|
|
438 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
|
|
439 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
|
|
440 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
|
|
441 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
|
|
442 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
|
|
443 };
|
|
444
|
|
445 /* Swaps pixel packing order within bytes */
|
|
446 void /* PRIVATE */
|
|
447 png_do_packswap(png_row_infop row_info, png_bytep row)
|
|
448 {
|
|
449 png_debug(1, "in png_do_packswap");
|
|
450
|
|
451 if (row_info->bit_depth < 8)
|
|
452 {
|
|
453 png_bytep rp;
|
|
454 png_const_bytep end, table;
|
|
455
|
|
456 end = row + row_info->rowbytes;
|
|
457
|
|
458 if (row_info->bit_depth == 1)
|
|
459 table = onebppswaptable;
|
|
460
|
|
461 else if (row_info->bit_depth == 2)
|
|
462 table = twobppswaptable;
|
|
463
|
|
464 else if (row_info->bit_depth == 4)
|
|
465 table = fourbppswaptable;
|
|
466
|
|
467 else
|
|
468 return;
|
|
469
|
|
470 for (rp = row; rp < end; rp++)
|
|
471 *rp = table[*rp];
|
|
472 }
|
|
473 }
|
|
474 #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
|
|
475
|
|
476 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
|
477 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
|
478 /* Remove a channel - this used to be 'png_do_strip_filler' but it used a
|
|
479 * somewhat weird combination of flags to determine what to do. All the calls
|
|
480 * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
|
|
481 * correct arguments.
|
|
482 *
|
|
483 * The routine isn't general - the channel must be the channel at the start or
|
|
484 * end (not in the middle) of each pixel.
|
|
485 */
|
|
486 void /* PRIVATE */
|
|
487 png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
|
|
488 {
|
|
489 png_bytep sp = row; /* source pointer */
|
|
490 png_bytep dp = row; /* destination pointer */
|
|
491 png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
|
|
492
|
|
493 /* At the start sp will point to the first byte to copy and dp to where
|
|
494 * it is copied to. ep always points just beyond the end of the row, so
|
|
495 * the loop simply copies (channels-1) channels until sp reaches ep.
|
|
496 *
|
|
497 * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
|
|
498 * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
|
|
499 */
|
|
500
|
|
501 /* GA, GX, XG cases */
|
|
502 if (row_info->channels == 2)
|
|
503 {
|
|
504 if (row_info->bit_depth == 8)
|
|
505 {
|
|
506 if (at_start) /* Skip initial filler */
|
|
507 ++sp;
|
|
508 else /* Skip initial channel and, for sp, the filler */
|
|
509 sp += 2, ++dp;
|
|
510
|
|
511 /* For a 1 pixel wide image there is nothing to do */
|
|
512 while (sp < ep)
|
|
513 *dp++ = *sp, sp += 2;
|
|
514
|
|
515 row_info->pixel_depth = 8;
|
|
516 }
|
|
517
|
|
518 else if (row_info->bit_depth == 16)
|
|
519 {
|
|
520 if (at_start) /* Skip initial filler */
|
|
521 sp += 2;
|
|
522 else /* Skip initial channel and, for sp, the filler */
|
|
523 sp += 4, dp += 2;
|
|
524
|
|
525 while (sp < ep)
|
|
526 *dp++ = *sp++, *dp++ = *sp, sp += 3;
|
|
527
|
|
528 row_info->pixel_depth = 16;
|
|
529 }
|
|
530
|
|
531 else
|
|
532 return; /* bad bit depth */
|
|
533
|
|
534 row_info->channels = 1;
|
|
535
|
|
536 /* Finally fix the color type if it records an alpha channel */
|
|
537 if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
538 row_info->color_type = PNG_COLOR_TYPE_GRAY;
|
|
539 }
|
|
540
|
|
541 /* RGBA, RGBX, XRGB cases */
|
|
542 else if (row_info->channels == 4)
|
|
543 {
|
|
544 if (row_info->bit_depth == 8)
|
|
545 {
|
|
546 if (at_start) /* Skip initial filler */
|
|
547 ++sp;
|
|
548 else /* Skip initial channels and, for sp, the filler */
|
|
549 sp += 4, dp += 3;
|
|
550
|
|
551 /* Note that the loop adds 3 to dp and 4 to sp each time. */
|
|
552 while (sp < ep)
|
|
553 *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
|
|
554
|
|
555 row_info->pixel_depth = 24;
|
|
556 }
|
|
557
|
|
558 else if (row_info->bit_depth == 16)
|
|
559 {
|
|
560 if (at_start) /* Skip initial filler */
|
|
561 sp += 2;
|
|
562 else /* Skip initial channels and, for sp, the filler */
|
|
563 sp += 8, dp += 6;
|
|
564
|
|
565 while (sp < ep)
|
|
566 {
|
|
567 /* Copy 6 bytes, skip 2 */
|
|
568 *dp++ = *sp++, *dp++ = *sp++;
|
|
569 *dp++ = *sp++, *dp++ = *sp++;
|
|
570 *dp++ = *sp++, *dp++ = *sp, sp += 3;
|
|
571 }
|
|
572
|
|
573 row_info->pixel_depth = 48;
|
|
574 }
|
|
575
|
|
576 else
|
|
577 return; /* bad bit depth */
|
|
578
|
|
579 row_info->channels = 3;
|
|
580
|
|
581 /* Finally fix the color type if it records an alpha channel */
|
|
582 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
583 row_info->color_type = PNG_COLOR_TYPE_RGB;
|
|
584 }
|
|
585
|
|
586 else
|
|
587 return; /* The filler channel has gone already */
|
|
588
|
|
589 /* Fix the rowbytes value. */
|
|
590 row_info->rowbytes = dp-row;
|
|
591 }
|
|
592 #endif
|
|
593
|
|
594 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
|
595 /* Swaps red and blue bytes within a pixel */
|
|
596 void /* PRIVATE */
|
|
597 png_do_bgr(png_row_infop row_info, png_bytep row)
|
|
598 {
|
|
599 png_debug(1, "in png_do_bgr");
|
|
600
|
|
601 if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
|
|
602 {
|
|
603 png_uint_32 row_width = row_info->width;
|
|
604 if (row_info->bit_depth == 8)
|
|
605 {
|
|
606 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
|
607 {
|
|
608 png_bytep rp;
|
|
609 png_uint_32 i;
|
|
610
|
|
611 for (i = 0, rp = row; i < row_width; i++, rp += 3)
|
|
612 {
|
|
613 png_byte save = *rp;
|
|
614 *rp = *(rp + 2);
|
|
615 *(rp + 2) = save;
|
|
616 }
|
|
617 }
|
|
618
|
|
619 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
620 {
|
|
621 png_bytep rp;
|
|
622 png_uint_32 i;
|
|
623
|
|
624 for (i = 0, rp = row; i < row_width; i++, rp += 4)
|
|
625 {
|
|
626 png_byte save = *rp;
|
|
627 *rp = *(rp + 2);
|
|
628 *(rp + 2) = save;
|
|
629 }
|
|
630 }
|
|
631 }
|
|
632
|
|
633 #ifdef PNG_16BIT_SUPPORTED
|
|
634 else if (row_info->bit_depth == 16)
|
|
635 {
|
|
636 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
|
637 {
|
|
638 png_bytep rp;
|
|
639 png_uint_32 i;
|
|
640
|
|
641 for (i = 0, rp = row; i < row_width; i++, rp += 6)
|
|
642 {
|
|
643 png_byte save = *rp;
|
|
644 *rp = *(rp + 4);
|
|
645 *(rp + 4) = save;
|
|
646 save = *(rp + 1);
|
|
647 *(rp + 1) = *(rp + 5);
|
|
648 *(rp + 5) = save;
|
|
649 }
|
|
650 }
|
|
651
|
|
652 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
653 {
|
|
654 png_bytep rp;
|
|
655 png_uint_32 i;
|
|
656
|
|
657 for (i = 0, rp = row; i < row_width; i++, rp += 8)
|
|
658 {
|
|
659 png_byte save = *rp;
|
|
660 *rp = *(rp + 4);
|
|
661 *(rp + 4) = save;
|
|
662 save = *(rp + 1);
|
|
663 *(rp + 1) = *(rp + 5);
|
|
664 *(rp + 5) = save;
|
|
665 }
|
|
666 }
|
|
667 }
|
|
668 #endif
|
|
669 }
|
|
670 }
|
|
671 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
|
|
672
|
|
673 #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
|
|
674 defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
|
|
675 /* Added at libpng-1.5.10 */
|
|
676 void /* PRIVATE */
|
|
677 png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
|
|
678 {
|
|
679 if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
|
|
680 png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
|
|
681 {
|
|
682 /* Calculations moved outside switch in an attempt to stop different
|
|
683 * compiler warnings. 'padding' is in *bits* within the last byte, it is
|
|
684 * an 'int' because pixel_depth becomes an 'int' in the expression below,
|
|
685 * and this calculation is used because it avoids warnings that other
|
|
686 * forms produced on either GCC or MSVC.
|
|
687 */
|
|
688 int padding = (-row_info->pixel_depth * row_info->width) & 7;
|
|
689 png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
|
|
690
|
|
691 switch (row_info->bit_depth)
|
|
692 {
|
|
693 case 1:
|
|
694 {
|
|
695 /* in this case, all bytes must be 0 so we don't need
|
|
696 * to unpack the pixels except for the rightmost one.
|
|
697 */
|
|
698 for (; rp > png_ptr->row_buf; rp--)
|
|
699 {
|
|
700 if (*rp >> padding != 0)
|
|
701 png_ptr->num_palette_max = 1;
|
|
702 padding = 0;
|
|
703 }
|
|
704
|
|
705 break;
|
|
706 }
|
|
707
|
|
708 case 2:
|
|
709 {
|
|
710 for (; rp > png_ptr->row_buf; rp--)
|
|
711 {
|
|
712 int i = ((*rp >> padding) & 0x03);
|
|
713
|
|
714 if (i > png_ptr->num_palette_max)
|
|
715 png_ptr->num_palette_max = i;
|
|
716
|
|
717 i = (((*rp >> padding) >> 2) & 0x03);
|
|
718
|
|
719 if (i > png_ptr->num_palette_max)
|
|
720 png_ptr->num_palette_max = i;
|
|
721
|
|
722 i = (((*rp >> padding) >> 4) & 0x03);
|
|
723
|
|
724 if (i > png_ptr->num_palette_max)
|
|
725 png_ptr->num_palette_max = i;
|
|
726
|
|
727 i = (((*rp >> padding) >> 6) & 0x03);
|
|
728
|
|
729 if (i > png_ptr->num_palette_max)
|
|
730 png_ptr->num_palette_max = i;
|
|
731
|
|
732 padding = 0;
|
|
733 }
|
|
734
|
|
735 break;
|
|
736 }
|
|
737
|
|
738 case 4:
|
|
739 {
|
|
740 for (; rp > png_ptr->row_buf; rp--)
|
|
741 {
|
|
742 int i = ((*rp >> padding) & 0x0f);
|
|
743
|
|
744 if (i > png_ptr->num_palette_max)
|
|
745 png_ptr->num_palette_max = i;
|
|
746
|
|
747 i = (((*rp >> padding) >> 4) & 0x0f);
|
|
748
|
|
749 if (i > png_ptr->num_palette_max)
|
|
750 png_ptr->num_palette_max = i;
|
|
751
|
|
752 padding = 0;
|
|
753 }
|
|
754
|
|
755 break;
|
|
756 }
|
|
757
|
|
758 case 8:
|
|
759 {
|
|
760 for (; rp > png_ptr->row_buf; rp--)
|
|
761 {
|
|
762 if (*rp > png_ptr->num_palette_max)
|
|
763 png_ptr->num_palette_max = (int) *rp;
|
|
764 }
|
|
765
|
|
766 break;
|
|
767 }
|
|
768
|
|
769 default:
|
|
770 break;
|
|
771 }
|
|
772 }
|
|
773 }
|
|
774 #endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
|
|
775
|
|
776 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
|
777 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
|
778 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
779 void PNGAPI
|
|
780 png_set_user_transform_info(png_structrp png_ptr, png_voidp
|
|
781 user_transform_ptr, int user_transform_depth, int user_transform_channels)
|
|
782 {
|
|
783 png_debug(1, "in png_set_user_transform_info");
|
|
784
|
|
785 if (png_ptr == NULL)
|
|
786 return;
|
|
787
|
|
788 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
|
|
789 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
|
790 (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
|
|
791 {
|
|
792 png_app_error(png_ptr,
|
|
793 "info change after png_start_read_image or png_read_update_info");
|
|
794 return;
|
|
795 }
|
|
796 #endif
|
|
797
|
|
798 png_ptr->user_transform_ptr = user_transform_ptr;
|
|
799 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
|
|
800 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
|
|
801 }
|
|
802 #endif
|
|
803
|
|
804 /* This function returns a pointer to the user_transform_ptr associated with
|
|
805 * the user transform functions. The application should free any memory
|
|
806 * associated with this pointer before png_write_destroy and png_read_destroy
|
|
807 * are called.
|
|
808 */
|
|
809 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
810 png_voidp PNGAPI
|
|
811 png_get_user_transform_ptr(png_const_structrp png_ptr)
|
|
812 {
|
|
813 if (png_ptr == NULL)
|
|
814 return (NULL);
|
|
815
|
|
816 return png_ptr->user_transform_ptr;
|
|
817 }
|
|
818 #endif
|
|
819
|
|
820 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
|
|
821 png_uint_32 PNGAPI
|
|
822 png_get_current_row_number(png_const_structrp png_ptr)
|
|
823 {
|
|
824 /* See the comments in png.h - this is the sub-image row when reading and
|
|
825 * interlaced image.
|
|
826 */
|
|
827 if (png_ptr != NULL)
|
|
828 return png_ptr->row_number;
|
|
829
|
|
830 return PNG_UINT_32_MAX; /* help the app not to fail silently */
|
|
831 }
|
|
832
|
|
833 png_byte PNGAPI
|
|
834 png_get_current_pass_number(png_const_structrp png_ptr)
|
|
835 {
|
|
836 if (png_ptr != NULL)
|
|
837 return png_ptr->pass;
|
|
838 return 8; /* invalid */
|
|
839 }
|
|
840 #endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
|
|
841 #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
|
|
842 PNG_WRITE_USER_TRANSFORM_SUPPORTED */
|
|
843 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
|