2
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
4
* libpng 1.2.7 - September 12, 2004
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
7
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
14
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
15
/* turn on BGR-to-RGB mapping */
17
png_set_bgr(png_structp png_ptr)
19
png_debug(1, "in png_set_bgr\n");
20
png_ptr->transformations |= PNG_BGR;
24
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
25
/* turn on 16 bit byte swapping */
27
png_set_swap(png_structp png_ptr)
29
png_debug(1, "in png_set_swap\n");
30
if (png_ptr->bit_depth == 16)
31
png_ptr->transformations |= PNG_SWAP_BYTES;
35
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
36
/* turn on pixel packing */
38
png_set_packing(png_structp png_ptr)
40
png_debug(1, "in png_set_packing\n");
41
if (png_ptr->bit_depth < 8)
43
png_ptr->transformations |= PNG_PACK;
44
png_ptr->usr_bit_depth = 8;
49
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
50
/* turn on packed pixel swapping */
52
png_set_packswap(png_structp png_ptr)
54
png_debug(1, "in png_set_packswap\n");
55
if (png_ptr->bit_depth < 8)
56
png_ptr->transformations |= PNG_PACKSWAP;
60
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
62
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
64
png_debug(1, "in png_set_shift\n");
65
png_ptr->transformations |= PNG_SHIFT;
66
png_ptr->shift = *true_bits;
70
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
71
defined(PNG_WRITE_INTERLACING_SUPPORTED)
73
png_set_interlace_handling(png_structp png_ptr)
75
png_debug(1, "in png_set_interlace handling\n");
76
if (png_ptr->interlaced)
78
png_ptr->transformations |= PNG_INTERLACE;
86
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
87
/* Add a filler byte on read, or remove a filler or alpha byte on write.
88
* The filler type has changed in v0.95 to allow future 2-byte fillers
89
* for 48-bit input data, as well as to avoid problems with some compilers
90
* that don't like bytes as parameters.
93
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
95
png_debug(1, "in png_set_filler\n");
96
png_ptr->transformations |= PNG_FILLER;
97
png_ptr->filler = (png_byte)filler;
98
if (filler_loc == PNG_FILLER_AFTER)
99
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
101
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
103
/* This should probably go in the "do_read_filler" routine.
104
* I attempted to do that in libpng-1.0.1a but that caused problems
105
* so I restored it in libpng-1.0.2a
108
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
110
png_ptr->usr_channels = 4;
113
/* Also I added this in libpng-1.0.2a (what happens when we expand
114
* a less-than-8-bit grayscale to GA? */
116
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
118
png_ptr->usr_channels = 2;
122
#if !defined(PNG_1_0_X)
123
/* Added to libpng-1.2.7 */
125
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
127
png_debug(1, "in png_set_add_alpha\n");
128
png_set_filler(png_ptr, filler, filler_loc);
129
png_ptr->transformations |= PNG_ADD_ALPHA;
135
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
136
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
138
png_set_swap_alpha(png_structp png_ptr)
140
png_debug(1, "in png_set_swap_alpha\n");
141
png_ptr->transformations |= PNG_SWAP_ALPHA;
145
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
146
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
148
png_set_invert_alpha(png_structp png_ptr)
150
png_debug(1, "in png_set_invert_alpha\n");
151
png_ptr->transformations |= PNG_INVERT_ALPHA;
155
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
157
png_set_invert_mono(png_structp png_ptr)
159
png_debug(1, "in png_set_invert_mono\n");
160
png_ptr->transformations |= PNG_INVERT_MONO;
163
/* invert monochrome grayscale data */
165
png_do_invert(png_row_infop row_info, png_bytep row)
167
png_debug(1, "in png_do_invert\n");
168
/* This test removed from libpng version 1.0.13 and 1.2.0:
169
* if (row_info->bit_depth == 1 &&
171
#if defined(PNG_USELESS_TESTS_SUPPORTED)
172
if (row == NULL || row_info == NULL)
175
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
179
png_uint_32 istop = row_info->rowbytes;
181
for (i = 0; i < istop; i++)
183
*rp = (png_byte)(~(*rp));
187
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
188
row_info->bit_depth == 8)
192
png_uint_32 istop = row_info->rowbytes;
194
for (i = 0; i < istop; i+=2)
196
*rp = (png_byte)(~(*rp));
200
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
201
row_info->bit_depth == 16)
205
png_uint_32 istop = row_info->rowbytes;
207
for (i = 0; i < istop; i+=4)
209
*rp = (png_byte)(~(*rp));
210
*(rp+1) = (png_byte)(~(*(rp+1)));
217
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
218
/* swaps byte order on 16 bit depth images */
220
png_do_swap(png_row_infop row_info, png_bytep row)
222
png_debug(1, "in png_do_swap\n");
224
#if defined(PNG_USELESS_TESTS_SUPPORTED)
225
row != NULL && row_info != NULL &&
227
row_info->bit_depth == 16)
231
png_uint_32 istop= row_info->width * row_info->channels;
233
for (i = 0; i < istop; i++, rp += 2)
243
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
244
static png_byte onebppswaptable[256] = {
245
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
246
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
247
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
248
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
249
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
250
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
251
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
252
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
253
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
254
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
255
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
256
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
257
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
258
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
259
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
260
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
261
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
262
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
263
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
264
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
265
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
266
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
267
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
268
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
269
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
270
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
271
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
272
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
273
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
274
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
275
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
276
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
279
static png_byte twobppswaptable[256] = {
280
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
281
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
282
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
283
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
284
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
285
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
286
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
287
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
288
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
289
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
290
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
291
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
292
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
293
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
294
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
295
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
296
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
297
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
298
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
299
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
300
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
301
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
302
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
303
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
304
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
305
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
306
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
307
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
308
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
309
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
310
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
311
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
314
static png_byte fourbppswaptable[256] = {
315
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
316
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
317
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
318
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
319
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
320
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
321
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
322
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
323
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
324
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
325
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
326
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
327
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
328
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
329
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
330
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
331
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
332
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
333
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
334
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
335
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
336
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
337
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
338
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
339
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
340
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
341
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
342
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
343
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
344
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
345
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
346
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
349
/* swaps pixel packing order within bytes */
351
png_do_packswap(png_row_infop row_info, png_bytep row)
353
png_debug(1, "in png_do_packswap\n");
355
#if defined(PNG_USELESS_TESTS_SUPPORTED)
356
row != NULL && row_info != NULL &&
358
row_info->bit_depth < 8)
360
png_bytep rp, end, table;
362
end = row + row_info->rowbytes;
364
if (row_info->bit_depth == 1)
365
table = onebppswaptable;
366
else if (row_info->bit_depth == 2)
367
table = twobppswaptable;
368
else if (row_info->bit_depth == 4)
369
table = fourbppswaptable;
373
for (rp = row; rp < end; rp++)
377
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
379
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
380
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
381
/* remove filler or alpha byte(s) */
383
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
385
png_debug(1, "in png_do_strip_filler\n");
386
#if defined(PNG_USELESS_TESTS_SUPPORTED)
387
if (row != NULL && row_info != NULL)
392
png_uint_32 row_width=row_info->width;
395
if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
396
row_info->channels == 4)
398
if (row_info->bit_depth == 8)
400
/* This converts from RGBX or RGBA to RGB */
401
if (flags & PNG_FLAG_FILLER_AFTER)
404
for (i = 1; i < row_width; i++)
412
/* This converts from XRGB or ARGB to RGB */
415
for (i = 0; i < row_width; i++)
423
row_info->pixel_depth = 24;
424
row_info->rowbytes = row_width * 3;
426
else /* if (row_info->bit_depth == 16) */
428
if (flags & PNG_FLAG_FILLER_AFTER)
430
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
432
for (i = 1; i < row_width; i++)
434
/* This could be (although png_memcpy is probably slower):
435
png_memcpy(dp, sp, 6);
451
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
452
for (i = 0; i < row_width; i++)
454
/* This could be (although png_memcpy is probably slower):
455
png_memcpy(dp, sp, 6);
469
row_info->pixel_depth = 48;
470
row_info->rowbytes = row_width * 6;
472
row_info->channels = 3;
474
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
475
row_info->channels == 2)
477
if (row_info->bit_depth == 8)
479
/* This converts from GX or GA to G */
480
if (flags & PNG_FLAG_FILLER_AFTER)
482
for (i = 0; i < row_width; i++)
488
/* This converts from XG or AG to G */
491
for (i = 0; i < row_width; i++)
497
row_info->pixel_depth = 8;
498
row_info->rowbytes = row_width;
500
else /* if (row_info->bit_depth == 16) */
502
if (flags & PNG_FLAG_FILLER_AFTER)
504
/* This converts from GGXX or GGAA to GG */
506
for (i = 1; i < row_width; i++)
515
/* This converts from XXGG or AAGG to GG */
516
for (i = 0; i < row_width; i++)
523
row_info->pixel_depth = 16;
524
row_info->rowbytes = row_width * 2;
526
row_info->channels = 1;
532
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
533
/* swaps red and blue bytes within a pixel */
535
png_do_bgr(png_row_infop row_info, png_bytep row)
537
png_debug(1, "in png_do_bgr\n");
539
#if defined(PNG_USELESS_TESTS_SUPPORTED)
540
row != NULL && row_info != NULL &&
542
(row_info->color_type & PNG_COLOR_MASK_COLOR))
544
png_uint_32 row_width = row_info->width;
545
if (row_info->bit_depth == 8)
547
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
552
for (i = 0, rp = row; i < row_width; i++, rp += 3)
559
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
564
for (i = 0, rp = row; i < row_width; i++, rp += 4)
572
else if (row_info->bit_depth == 16)
574
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
579
for (i = 0, rp = row; i < row_width; i++, rp += 6)
585
*(rp + 1) = *(rp + 5);
589
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
594
for (i = 0, rp = row; i < row_width; i++, rp += 8)
600
*(rp + 1) = *(rp + 5);
607
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
609
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
610
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
611
defined(PNG_LEGACY_SUPPORTED)
613
png_set_user_transform_info(png_structp png_ptr, png_voidp
614
user_transform_ptr, int user_transform_depth, int user_transform_channels)
616
png_debug(1, "in png_set_user_transform_info\n");
617
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
618
png_ptr->user_transform_ptr = user_transform_ptr;
619
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
620
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
622
if(user_transform_ptr || user_transform_depth || user_transform_channels)
624
"This version of libpng does not support user transform info");
629
/* This function returns a pointer to the user_transform_ptr associated with
630
* the user transform functions. The application should free any memory
631
* associated with this pointer before png_write_destroy and png_read_destroy
635
png_get_user_transform_ptr(png_structp png_ptr)
637
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
638
return ((png_voidp)png_ptr->user_transform_ptr);