15#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
17#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
20png_set_bgr(png_structrp png_ptr)
22 png_debug(1,
"in png_set_bgr");
27 png_ptr->transformations |= PNG_BGR;
31#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
34png_set_swap(png_structrp png_ptr)
36 png_debug(1,
"in png_set_swap");
41 if (png_ptr->bit_depth == 16)
42 png_ptr->transformations |= PNG_SWAP_BYTES;
46#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
49png_set_packing(png_structrp png_ptr)
51 png_debug(1,
"in png_set_packing");
56 if (png_ptr->bit_depth < 8)
58 png_ptr->transformations |= PNG_PACK;
59# ifdef PNG_WRITE_SUPPORTED
60 png_ptr->usr_bit_depth = 8;
66#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
69png_set_packswap(png_structrp png_ptr)
71 png_debug(1,
"in png_set_packswap");
76 if (png_ptr->bit_depth < 8)
77 png_ptr->transformations |= PNG_PACKSWAP;
81#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
83png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
85 png_debug(1,
"in png_set_shift");
90 png_ptr->transformations |= PNG_SHIFT;
91 png_ptr->shift = *true_bits;
95#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
96 defined(PNG_WRITE_INTERLACING_SUPPORTED)
98png_set_interlace_handling(png_structrp png_ptr)
100 png_debug(1,
"in png_set_interlace handling");
102 if (png_ptr != 0 && png_ptr->interlaced != 0)
104 png_ptr->transformations |= PNG_INTERLACE;
112#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
119png_set_filler(png_structrp png_ptr, png_uint_32 filler,
int filler_loc)
121 png_debug(1,
"in png_set_filler");
129 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
131# ifdef PNG_READ_FILLER_SUPPORTED
140 png_ptr->filler = (png_uint_16)filler;
142 png_app_error(png_ptr,
"png_set_filler not supported on read");
150# ifdef PNG_WRITE_FILLER_SUPPORTED
154 switch (png_ptr->color_type)
156 case PNG_COLOR_TYPE_RGB:
157 png_ptr->usr_channels = 4;
160 case PNG_COLOR_TYPE_GRAY:
161 if (png_ptr->bit_depth >= 8)
163 png_ptr->usr_channels = 2;
173 png_app_error(png_ptr,
174 "png_set_filler is invalid for"
175 " low bit depth gray output");
180 png_app_error(png_ptr,
181 "png_set_filler: inappropriate color type");
185 png_app_error(png_ptr,
"png_set_filler not supported on write");
193 png_ptr->transformations |= PNG_FILLER;
195 if (filler_loc == PNG_FILLER_AFTER)
196 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
199 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
204png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler,
int filler_loc)
206 png_debug(1,
"in png_set_add_alpha");
211 png_set_filler(png_ptr, filler, filler_loc);
213 if ((png_ptr->transformations & PNG_FILLER) != 0)
214 png_ptr->transformations |= PNG_ADD_ALPHA;
219#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
220 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
222png_set_swap_alpha(png_structrp png_ptr)
224 png_debug(1,
"in png_set_swap_alpha");
229 png_ptr->transformations |= PNG_SWAP_ALPHA;
233#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
234 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
236png_set_invert_alpha(png_structrp png_ptr)
238 png_debug(1,
"in png_set_invert_alpha");
243 png_ptr->transformations |= PNG_INVERT_ALPHA;
247#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
249png_set_invert_mono(png_structrp png_ptr)
251 png_debug(1,
"in png_set_invert_mono");
256 png_ptr->transformations |= PNG_INVERT_MONO;
261png_do_invert(png_row_infop row_info, png_bytep row)
263 png_debug(1,
"in png_do_invert");
268 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
272 size_t istop = row_info->rowbytes;
274 for (i = 0; i < istop; i++)
276 *rp = (png_byte)(~(*rp));
281 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
282 row_info->bit_depth == 8)
286 size_t istop = row_info->rowbytes;
288 for (i = 0; i < istop; i += 2)
290 *rp = (png_byte)(~(*rp));
295#ifdef PNG_16BIT_SUPPORTED
296 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
297 row_info->bit_depth == 16)
301 size_t istop = row_info->rowbytes;
303 for (i = 0; i < istop; i += 4)
305 *rp = (png_byte)(~(*rp));
306 *(rp + 1) = (png_byte)(~(*(rp + 1)));
314#ifdef PNG_16BIT_SUPPORTED
315#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
318png_do_swap(png_row_infop row_info, png_bytep row)
320 png_debug(1,
"in png_do_swap");
322 if (row_info->bit_depth == 16)
326 png_uint_32 istop= row_info->width * row_info->channels;
328 for (i = 0; i < istop; i++, rp += 2)
330#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
334 *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
346#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
347static const png_byte onebppswaptable[256] = {
348 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
349 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
350 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
351 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
352 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
353 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
354 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
355 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
356 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
357 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
358 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
359 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
360 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
361 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
362 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
363 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
364 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
365 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
366 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
367 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
368 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
369 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
370 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
371 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
372 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
373 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
374 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
375 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
376 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
377 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
378 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
379 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
382static const png_byte twobppswaptable[256] = {
383 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
384 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
385 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
386 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
387 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
388 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
389 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
390 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
391 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
392 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
393 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
394 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
395 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
396 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
397 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
398 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
399 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
400 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
401 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
402 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
403 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
404 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
405 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
406 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
407 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
408 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
409 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
410 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
411 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
412 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
413 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
414 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
417static const png_byte fourbppswaptable[256] = {
418 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
419 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
420 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
421 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
422 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
423 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
424 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
425 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
426 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
427 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
428 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
429 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
430 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
431 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
432 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
433 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
434 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
435 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
436 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
437 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
438 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
439 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
440 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
441 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
442 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
443 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
444 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
445 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
446 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
447 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
448 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
449 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
454png_do_packswap(png_row_infop row_info, png_bytep row)
456 png_debug(1,
"in png_do_packswap");
458 if (row_info->bit_depth < 8)
461 png_const_bytep end, table;
463 end = row + row_info->rowbytes;
465 if (row_info->bit_depth == 1)
466 table = onebppswaptable;
468 else if (row_info->bit_depth == 2)
469 table = twobppswaptable;
471 else if (row_info->bit_depth == 4)
472 table = fourbppswaptable;
477 for (rp = row; rp < end; rp++)
483#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
484 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
494png_do_strip_channel(png_row_infop row_info, png_bytep row,
int at_start)
498 png_bytep ep = row + row_info->rowbytes;
500 png_debug(1,
"in png_do_strip_channel");
511 if (row_info->channels == 2)
513 if (row_info->bit_depth == 8)
525 *dp++ = *sp; sp += 2;
528 row_info->pixel_depth = 8;
531 else if (row_info->bit_depth == 16)
542 *dp++ = *sp++; *dp++ = *sp; sp += 3;
545 row_info->pixel_depth = 16;
551 row_info->channels = 1;
554 if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
555 row_info->color_type = PNG_COLOR_TYPE_GRAY;
559 else if (row_info->channels == 4)
561 if (row_info->bit_depth == 8)
573 *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
576 row_info->pixel_depth = 24;
579 else if (row_info->bit_depth == 16)
591 *dp++ = *sp++; *dp++ = *sp++;
592 *dp++ = *sp++; *dp++ = *sp++;
593 *dp++ = *sp++; *dp++ = *sp; sp += 3;
596 row_info->pixel_depth = 48;
602 row_info->channels = 3;
605 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
606 row_info->color_type = PNG_COLOR_TYPE_RGB;
613 row_info->rowbytes = (size_t)(dp-row);
617#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
620png_do_bgr(png_row_infop row_info, png_bytep row)
622 png_debug(1,
"in png_do_bgr");
624 if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
626 png_uint_32 row_width = row_info->width;
627 if (row_info->bit_depth == 8)
629 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
634 for (i = 0, rp = row; i < row_width; i++, rp += 3)
642 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
647 for (i = 0, rp = row; i < row_width; i++, rp += 4)
656#ifdef PNG_16BIT_SUPPORTED
657 else if (row_info->bit_depth == 16)
659 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
664 for (i = 0, rp = row; i < row_width; i++, rp += 6)
670 *(rp + 1) = *(rp + 5);
675 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
680 for (i = 0, rp = row; i < row_width; i++, rp += 8)
686 *(rp + 1) = *(rp + 5);
696#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
697 defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
700png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
702 png_debug(1,
"in png_do_check_palette_indexes");
704 if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
705 png_ptr->num_palette > 0)
713 int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
714 png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
716 switch (row_info->bit_depth)
723 for (; rp > png_ptr->row_buf; rp--)
725 if ((*rp >> padding) != 0)
726 png_ptr->num_palette_max = 1;
735 for (; rp > png_ptr->row_buf; rp--)
737 int i = ((*rp >> padding) & 0x03);
739 if (i > png_ptr->num_palette_max)
740 png_ptr->num_palette_max = i;
742 i = (((*rp >> padding) >> 2) & 0x03);
744 if (i > png_ptr->num_palette_max)
745 png_ptr->num_palette_max = i;
747 i = (((*rp >> padding) >> 4) & 0x03);
749 if (i > png_ptr->num_palette_max)
750 png_ptr->num_palette_max = i;
752 i = (((*rp >> padding) >> 6) & 0x03);
754 if (i > png_ptr->num_palette_max)
755 png_ptr->num_palette_max = i;
765 for (; rp > png_ptr->row_buf; rp--)
767 int i = ((*rp >> padding) & 0x0f);
769 if (i > png_ptr->num_palette_max)
770 png_ptr->num_palette_max = i;
772 i = (((*rp >> padding) >> 4) & 0x0f);
774 if (i > png_ptr->num_palette_max)
775 png_ptr->num_palette_max = i;
785 for (; rp > png_ptr->row_buf; rp--)
787 if (*rp > png_ptr->num_palette_max)
788 png_ptr->num_palette_max = (int) *rp;
801#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
802 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
803#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
805png_set_user_transform_info(png_structrp png_ptr, png_voidp
806 user_transform_ptr,
int user_transform_depth,
int user_transform_channels)
808 png_debug(1,
"in png_set_user_transform_info");
813#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
814 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
815 (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
817 png_app_error(png_ptr,
818 "info change after png_start_read_image or png_read_update_info");
823 png_ptr->user_transform_ptr = user_transform_ptr;
824 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
825 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
834#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
836png_get_user_transform_ptr(png_const_structrp png_ptr)
841 return png_ptr->user_transform_ptr;
845#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
847png_get_current_row_number(png_const_structrp png_ptr)
853 return png_ptr->row_number;
855 return PNG_UINT_32_MAX;
859png_get_current_pass_number(png_const_structrp png_ptr)
862 return png_ptr->pass;