pngwtran.c revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* pngwtran.c - transforms the data in a row for PNG writers 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Last changed in libpng 1.2.43 [February 25, 2010] 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 1998-2010 Glenn Randers-Pehrson 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code is released under the libpng license. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For conditions of distribution and use, see the disclaimer 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and license in png.h 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_INTERNAL 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_NO_PEDANTIC_WARNINGS 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "png.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SUPPORTED 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Transform the data according to the user's wishes. The order of 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transformations is significant. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_write_transformations(png_structp png_ptr) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_write_transformations"); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_USER_TRANSFORM) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->write_user_transform_fn != NULL) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(png_ptr->write_user_transform_fn)) /* User write transform 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function */ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr, /* png_ptr */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->row_info), /* row_info: */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_uint_32 width; width of row */ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_uint_32 rowbytes; number of bytes in row */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte color_type; color type of pixels */ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte bit_depth; bit depth of samples */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte channels; number of channels (1-4) */ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte pixel_depth; bits per pixel (depth*channels) */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_buf + 1); /* start of pixel data for row */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILLER_SUPPORTED 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_FILLER) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_PACKSWAP_SUPPORTED 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACKSWAP) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_PACK_SUPPORTED 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACK) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_ptr->bit_depth); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SWAP_SUPPORTED 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SWAP_BYTES) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SHIFT_SUPPORTED 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SHIFT) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->shift)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SWAP_ALPHA) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_ALPHA) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_BGR_SUPPORTED 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BGR) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_SUPPORTED 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_MONO) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_PACK_SUPPORTED 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * row_info bit depth should be 8 (one pixel per byte). The channels 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should be 1 (this only happens on grayscale and paletted images). 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_pack"); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8 && 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels == 1) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch ((int)bit_depth) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mask, v; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = 0x80; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp != 0) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v |= mask; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask > 1) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask >>= 1; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = 0x80; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp++; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask != 0x80) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift, v; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte value; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (png_byte)(*sp & 0x03); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v |= (value << shift); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 0) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp++; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 2; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift != 6) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift, v; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte value; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (png_byte)(*sp & 0x0f); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v |= (value << shift); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 0) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp++; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = 0; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 4; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift != 4) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)v; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = (png_byte)bit_depth; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->width); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SHIFT_SUPPORTED 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Shift pixel values to take advantage of whole range. Pass the 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * true number of bits in bit_depth. The row should be packed 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * according to row_info->bit_depth. Thus, if you had a row of 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * bit depth 4, but the pixels only had values from 0 to 7, you 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * would pass 3 as bit_depth, and this routine would translate the 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data to 0 to 15. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_shift"); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL && 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type != PNG_COLOR_TYPE_PALETTE) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift_start[4], shift_dec[4]; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channels = 0; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type & PNG_COLOR_MASK_COLOR) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_start[channels] = row_info->bit_depth - bit_depth->red; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_dec[channels] = bit_depth->red; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels++; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_start[channels] = row_info->bit_depth - bit_depth->green; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_dec[channels] = bit_depth->green; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels++; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_start[channels] = row_info->bit_depth - bit_depth->blue; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_dec[channels] = bit_depth->blue; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels++; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_start[channels] = row_info->bit_depth - bit_depth->gray; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_dec[channels] = bit_depth->gray; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels++; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_start[channels] = row_info->bit_depth - bit_depth->alpha; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift_dec[channels] = bit_depth->alpha; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels++; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* With low row depths, could only be grayscale, so one channel */ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth < 8) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp = row; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte mask; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_bytes = row_info->rowbytes; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bit_depth->gray == 1 && row_info->bit_depth == 2) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = 0x55; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 4 && bit_depth->gray == 3) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = 0x11; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = 0xff; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_bytes; i++, bp++) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = *bp; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = 0; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j > 0) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp |= (png_byte)((v << j) & 0xff); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp |= (png_byte)((v >> (-j)) & mask); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 8) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp = row; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = channels * row_info->width; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++, bp++) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c = (int)(i%channels); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = *bp; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = 0; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j > 0) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp |= (png_byte)((v << j) & 0xff); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp |= (png_byte)((v >> (-j)) & 0xff); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = channels * row_info->width; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (bp = row, i = 0; i < istop; i++) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c = (int)(i%channels); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 value, v; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = 0; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j > 0) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ = (png_byte)(value >> 8); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ = (png_byte)(value & 0xff); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_write_swap_alpha"); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from ARGB to RGBA */ 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save = *(sp++); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from AARRGGBB to RRGGBBAA */ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save[2]; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[0] = *(sp++); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[1] = *(sp++); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save[0]; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save[1]; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from AG to GA */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save = *(sp++); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from AAGG to GGAA */ 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save[2]; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[0] = *(sp++); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[1] = *(sp++); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save[0]; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = save[1]; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_write_invert_alpha"); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in RGBA */ 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Does nothing 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp+=3; dp = sp; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in RRGGBBAA */ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Does nothing 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp+=6; dp = sp; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in GA */ 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in GGAA */ 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, sp = dp = row; i < row_width; i++) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Does nothing 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp+=2; dp = sp; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(255 - *(sp++)); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_MNG_FEATURES_SUPPORTED 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Undoes intrapixel differencing */ 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_write_intrapixel(png_row_infop row_info, png_bytep row) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_write_intrapixel"); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (row_info->color_type & PNG_COLOR_MASK_COLOR)) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_per_pixel; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep rp; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 3; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 4; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp) = (png_byte)((*rp - *(rp+1))&0xff); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep rp; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 6; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 8; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp ) = (png_byte)((red >> 8) & 0xff); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+1) = (png_byte)(red & 0xff); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+4) = (png_byte)((blue >> 8) & 0xff); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+5) = (png_byte)(blue & 0xff); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_MNG_FEATURES_SUPPORTED */ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_SUPPORTED */ 583