15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* pngrtran.c - transforms the data in a row for PNG readers 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Last changed in libpng 1.2.45 [July 7, 2011] 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 1998-2011 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) * This file contains functions optionally called by an application 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in order to tell libpng how to handle data when reading a PNG. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Transformations that are used in both reading and writing are 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in pngtrans.c. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_INTERNAL 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_NO_PEDANTIC_WARNINGS 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "png.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SUPPORTED 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Set the action on getting a CRC error for an ancillary or critical chunk. */ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_crc_action"); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Tell libpng how we react to CRC errors in critical chunks */ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (crit_action) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_WARN_USE: /* Warn/use data */ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_QUIET_USE: /* Quiet/use data */ 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_FLAG_CRC_CRITICAL_IGNORE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Can't discard critical data on CRC error."); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_ERROR_QUIT: /* Error/quit */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_DEFAULT: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Tell libpng how we react to CRC errors in ancillary chunks */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ancil_action) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_WARN_USE: /* Warn/use data */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_QUIET_USE: /* Quiet/use data */ 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_FLAG_CRC_ANCILLARY_NOWARN; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_ERROR_QUIT: /* Error/quit */ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_CRC_DEFAULT: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_FLOATING_POINT_SUPPORTED) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Handle alpha and tRNS via a background color */ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_background(png_structp png_ptr, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color_16p background_color, int background_gamma_code, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int need_expand, double background_gamma) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_background"); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Application must supply a known background gamma"); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_BACKGROUND; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(&(png_ptr->background), background_color, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_sizeof(png_color_16)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_gamma = (float)background_gamma; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_gamma_type = (png_byte)(background_gamma_code); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_16_TO_8_SUPPORTED 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Strip 16 bit depth files to 8 bit depth */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_strip_16(png_structp png_ptr) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_strip_16"); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_16_TO_8; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_strip_alpha(png_structp png_ptr) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_strip_alpha"); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_DITHER_SUPPORTED 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Dither file to 8 bit. Supply a palette, the current number 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of elements in the palette, the maximum number of elements 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * allowed, and a histogram if possible. If the current number 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of colors is greater then the maximum number, the palette will be 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modified to fit in the maximum number. "full_dither" indicates 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whether we need a dithering cube set up for RGB images, or if we 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * simply are reducing the number of colors in a paletted image. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct png_dsort_struct 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct png_dsort_struct FAR * next; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte left; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte right; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} png_dsort; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef png_dsort FAR * png_dsortp; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef png_dsort FAR * FAR * png_dsortpp; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_dither(png_structp png_ptr, png_colorp palette, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_palette, int maximum_colors, png_uint_16p histogram, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int full_dither) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_dither"); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_DITHER; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_dither) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num_palette * png_sizeof(png_byte))); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[i] = (png_byte)i; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_palette > maximum_colors) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (histogram != NULL) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This is easy enough, just throw out the least used colors. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Perhaps not the best solution, but good enough. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize an array to sort colors */ 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num_palette * png_sizeof(png_byte))); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the dither_sort array */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_sort[i] = (png_byte)i; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find the least used palette entries by starting a 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * bubble sort, and running it until we have sorted 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * out enough colors. Note that we don't care about 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sorting all the colors, just finding which are 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * least used. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = num_palette - 1; i >= maximum_colors; i--) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int done; /* To stop early if the list is pre-sorted */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = 1; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < i; j++) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (histogram[png_ptr->dither_sort[j]] 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < histogram[png_ptr->dither_sort[j + 1]]) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte t; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = png_ptr->dither_sort[j]; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_sort[j + 1] = t; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = 0; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (done) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Swap the palette around, and set up a table, if necessary */ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (full_dither) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = num_palette; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Put all the useful colors within the max, but don't 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * move the others. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < maximum_colors; i++) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->dither_sort[i] >= maximum_colors) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j--; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((int)png_ptr->dither_sort[j] >= maximum_colors); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = palette[j]; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = num_palette; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Move all the used colors inside the max limit, and 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * develop a translation table. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < maximum_colors; i++) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Only move the colors we need to */ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->dither_sort[i] >= maximum_colors) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color tmp_color; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j--; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((int)png_ptr->dither_sort[j] >= maximum_colors); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_color = palette[j]; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[j] = palette[i]; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = tmp_color; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Indicate where the color went */ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[j] = (png_byte)i; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[i] = (png_byte)j; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find closest color for those colors we are not using */ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->dither_index[i] >= maximum_colors) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min_d, k, min_k, d_index; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find the closest color to one we threw out */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d_index = png_ptr->dither_index[i]; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (k = 1, min_k = 0; k < maximum_colors; k++) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = PNG_COLOR_DIST(palette[d_index], palette[k]); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d < min_d) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_d = d; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_k = k; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Point to closest color */ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[i] = (png_byte)min_k; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->dither_sort); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_sort = NULL; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This is much harder to do simply (and quickly). Perhaps 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we need to go through a median cut routine, but those 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * don't always behave themselves with only a few colors 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as input. So we will just find the closest two colors, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and throw out one of them (chosen somewhat randomly). 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [We don't understand this at all, so if someone wants to 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * work on improving it, be our guest - AED, GRP] 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_d; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_new_palette; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_dsortp t; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_dsortpp hash; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = NULL; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize palette index arrays */ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num_palette * png_sizeof(png_byte))); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num_palette * png_sizeof(png_byte))); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the sort array */ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[i] = (png_byte)i; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_to_index[i] = (png_byte)i; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_sizeof(png_dsortp))); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_new_palette = num_palette; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initial wild guess at how far apart the farthest pixel 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pair we will be eliminating will be. Larger 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * numbers mean more areas will be allocated, Smaller 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * numbers run the risk of not saving enough data, and 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * having to do this all over again. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * I have not done extensive checking on this number. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_d = 96; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (num_new_palette > maximum_colors) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_new_palette - 1; i++) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = i + 1; j < num_new_palette; j++) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) d = PNG_COLOR_DIST(palette[i], palette[j]); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d <= max_d) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = (png_dsortp)png_malloc_warn(png_ptr, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_dsort))); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t == NULL) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t->next = hash[d]; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t->left = (png_byte)i; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t->right = (png_byte)j; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash[d] = t; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t == NULL) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t != NULL) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i <= max_d; i++) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hash[i] != NULL) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_dsortp p; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (p = hash[i]; p; p = p->next) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->index_to_palette[p->left] 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < num_new_palette && 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int)png_ptr->index_to_palette[p->right] 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < num_new_palette) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j, next_j; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_new_palette & 0x01) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = p->left; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_j = p->right; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = p->right; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_j = p->left; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_new_palette--; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[png_ptr->index_to_palette[j]] 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = palette[num_new_palette]; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_dither) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (k = 0; k < num_palette; k++) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->dither_index[k] == 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[j]) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[k] = 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[next_j]; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->dither_index[k] == 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_new_palette) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->dither_index[k] = 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[j]; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[png_ptr->palette_to_index 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [num_new_palette]] = png_ptr->index_to_palette[j]; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_to_index[png_ptr->index_to_palette[j]] 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->palette_to_index[num_new_palette]; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette[j] = 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)num_new_palette; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_to_index[num_new_palette] = 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)j; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_new_palette <= maximum_colors) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_new_palette <= maximum_colors) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 769; i++) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hash[i] != NULL) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_dsortp p = hash[i]; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (p) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = p->next; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, p); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = t; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash[i] = 0; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_d += 96; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, hash); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->palette_to_index); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->index_to_palette); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_to_index = NULL; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->index_to_palette = NULL; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = maximum_colors; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->palette == NULL) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette = palette; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->num_palette = (png_uint_16)num_palette; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (full_dither) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep distance; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_DITHER_BLUE_BITS; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_red = (1 << PNG_DITHER_RED_BITS); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_green = (1 << PNG_DITHER_GREEN_BITS); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_blue = (1 << PNG_DITHER_BLUE_BITS); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_size_t num_entries = ((png_size_t)1 << total_bits); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num_entries * png_sizeof(png_byte))); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_sizeof(png_byte))); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ir, ig, ib; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ir = 0; ir < num_red; ir++) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* int dr = abs(ir - r); */ 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dr = ((ir > r) ? ir - r : r - ir); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index_r = (ir << (PNG_DITHER_BLUE_BITS + 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_DITHER_GREEN_BITS)); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ig = 0; ig < num_green; ig++) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* int dg = abs(ig - g); */ 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dg = ((ig > g) ? ig - g : g - ig); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dt = dr + dg; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dm = ((dr > dg) ? dr : dg); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ib = 0; ib < num_blue; ib++) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d_index = index_g | ib; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* int db = abs(ib - b); */ 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int db = ((ib > b) ? ib - b : b - ib); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dmax = ((dm > db) ? dm : db); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d = dmax + dt + db; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d < (int)distance[d_index]) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distance[d_index] = (png_byte)d; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_lookup[d_index] = (png_byte)i; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, distance); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Transform the image from the file_gamma to the screen_gamma. We 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * only do transformations on images where the file_gamma and screen_gamma 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are not close reciprocals, otherwise it slows things down slightly, and 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * also needlessly introduces small errors. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We will turn off gamma transformation later if no semitransparent entries 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are present in the tRNS array for palette images. We can't do it here 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * because we don't necessarily have the tRNS chunk yet. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_gamma"); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_GAMMA; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma = (float)file_gamma; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->screen_gamma = (float)scrn_gamma; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand paletted images to RGB, expand grayscale images of 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * less than 8-bit depth to 8-bit depth, and expand tRNS chunks 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to alpha channels. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_expand(png_structp png_ptr) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_expand"); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* GRR 19990627: the following three functions currently are identical 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to png_set_expand(). However, it is entirely reasonable that someone 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * might wish to expand an indexed image to RGB but *not* expand a single, 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * fully transparent palette entry to a full alpha channel--perhaps instead 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the transparent color with a particular RGB value, or drop tRNS entirely. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IOW, a future version of the library may make the transformations flag 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a bit more fine-grained, with separate bits for each of these three 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * functions. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * More to the point, these functions make it obvious what libpng will be 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * doing, whereas "expand" can (and does) mean any number of things. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to expand only the sample depth but not to expand the tRNS to alpha 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and its name was changed to png_set_expand_gray_1_2_4_to_8(). 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand paletted images to RGB. */ 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_palette_to_rgb(png_structp png_ptr) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_palette_to_rgb"); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PNG_1_0_X 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_EXPAND; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_1_0_X) || defined(PNG_1_2_X) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Deprecated as of libpng-1.2.9 */ 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_gray_1_2_4_to_8(png_structp png_ptr) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_gray_1_2_4_to_8"); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand tRNS chunks to alpha channels. */ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_tRNS_to_alpha(png_structp png_ptr) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_tRNS_to_alpha"); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_gray_to_rgb(png_structp png_ptr) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_gray_to_rgb"); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_GRAY_TO_RGB; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FLOATING_POINT_SUPPORTED 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Convert a RGB image to a grayscale of the same width. This allows us, 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double green) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int red_fixed, green_fixed; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red > 21474.83647 || red < -21474.83648 || 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green > 21474.83647 || green < -21474.83648) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red_fixed = -1; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green_fixed = -1; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red_fixed = (int)((float)red*100000.0 + 0.5); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green_fixed = (int)((float)green*100000.0 + 0.5); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_fixed_point red, png_fixed_point green) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_rgb_to_gray"); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(error_action) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_EXPAND; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_RGB_TO_GRAY; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red_int, green_int; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red < 0 || green < 0) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red_int = 6968; /* .212671 * 32768 + .5 */ 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green_int = 23434; /* .715160 * 32768 + .5 */ 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (red + green < 100000L) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red_int = 6968; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green_int = 23434; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->rgb_to_gray_red_coeff = red_int; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->rgb_to_gray_green_coeff = green_int; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->rgb_to_gray_blue_coeff = 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)(32768 - red_int - green_int); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_LEGACY_SUPPORTED) || \ 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_user_transform_fn) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_read_user_transform_fn"); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_USER_TRANSFORM; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->read_user_transform_fn = read_user_transform_fn; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_LEGACY_SUPPORTED 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_user_transform_fn) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "This version of libpng does not support user transforms"); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialize everything needed for the read. This includes modifying 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the palette. 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_init_read_transformations(png_structp png_ptr) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_init_read_transformations"); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr != NULL) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_SHIFT_SUPPORTED) || \ 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_GAMMA_SUPPORTED) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int color_type = png_ptr->color_type; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Detect gray background and attempt to enable optimization 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for gray --> RGB case 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RGB_ALPHA (in which case need_expand is superfluous anyway), the 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * background color might actually be gray yet not be flagged as such. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is not a problem for the current code, which uses 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PNG_BACKGROUND_IS_GRAY only to decide when to do the 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * png_do_gray_to_rgb() transformation. 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(color_type & PNG_COLOR_MASK_COLOR)) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((png_ptr->transformations & PNG_BACKGROUND) && 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->transformations & PNG_GRAY_TO_RGB) && 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red == png_ptr->background.green && 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red == png_ptr->background.blue) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.gray = png_ptr->background.red; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->transformations & PNG_EXPAND)) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Expand background and tRNS chunks */ 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (png_ptr->bit_depth) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.gray *= (png_uint_16)0xff; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = png_ptr->background.green 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background.blue = png_ptr->background.gray; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.gray *= (png_uint_16)0xff; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.red = png_ptr->trans_values.green 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->trans_values.blue = png_ptr->trans_values.gray; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.gray *= (png_uint_16)0x55; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = png_ptr->background.green 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background.blue = png_ptr->background.gray; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.gray *= (png_uint_16)0x55; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.red = png_ptr->trans_values.green 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->trans_values.blue = png_ptr->trans_values.gray; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.gray *= (png_uint_16)0x11; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = png_ptr->background.green 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background.blue = png_ptr->background.gray; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.gray *= (png_uint_16)0x11; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans_values.red = png_ptr->trans_values.green 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->trans_values.blue = png_ptr->trans_values.gray; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = png_ptr->background.green 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background.blue = png_ptr->background.gray; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (color_type == PNG_COLOR_TYPE_PALETTE) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[png_ptr->background.index].red; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.green = 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[png_ptr->background.index].green; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.blue = 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[png_ptr->background.index].blue; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_ALPHA) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Invert the alpha channel (in tRNS) unless the pixels are 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * going to be expanded, in which case leave it for later 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, istop; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) istop=(int)png_ptr->num_trans; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i=0; i<istop; i++) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1 = png_ptr->background; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) < PNG_GAMMA_THRESHOLD)) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, k; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k=0; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i=0; i<png_ptr->num_trans; i++) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k=1; /* Partial transparency is present */ 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (k == 0) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_GAMMA; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma != 0.0) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_build_gamma_table(png_ptr); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BACKGROUND) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (color_type == PNG_COLOR_TYPE_PALETTE) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Could skip if no transparency */ 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color back, back_1; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_colorp palette = png_ptr->palette; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_palette = png_ptr->num_palette; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = png_ptr->gamma_table[png_ptr->background.red]; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = png_ptr->gamma_table[png_ptr->background.green]; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = png_ptr->gamma_table[png_ptr->background.blue]; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double g, gs; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (png_ptr->background_gamma_type) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_SCREEN: 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = (png_ptr->screen_gamma); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_FILE: 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_UNIQUE: 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->background_gamma); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0 / (png_ptr->background_gamma * 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->screen_gamma); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0; /* back_1 */ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0; /* back */ 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = (png_byte)png_ptr->background.red; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = (png_byte)png_ptr->background.green; 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = (png_byte)png_ptr->background.blue; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = (png_byte)(pow( 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.red/255, gs) * 255.0 + .5); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = (png_byte)(pow( 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.green/255, gs) * 255.0 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + .5); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = (png_byte)(pow( 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.blue/255, gs) * 255.0 + .5); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.red = (png_byte)(pow( 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.red/255, g) * 255.0 + .5); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.green = (png_byte)(pow( 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.green/255, g) * 255.0 + .5); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.blue = (png_byte)(pow( 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.blue/255, g) * 255.0 + .5); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->trans[i] == 0) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = back; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (png_ptr->trans[i] != 0xff) */ 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte v, w; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[palette[i].red]; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.red); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_from_1[w]; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[palette[i].green]; 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.green); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_from_1[w]; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[palette[i].blue]; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.blue); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_from_1[w]; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_table[palette[i].red]; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_table[palette[i].green]; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Prevent the transformations being done again, and make sure 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that the now spurious alpha channel is stripped - the code 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * has just reduced background composition and gamma correction 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to a simple alpha channel strip. 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_BACKGROUND; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_GAMMA; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_STRIP_ALPHA; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* color_type != PNG_COLOR_TYPE_PALETTE */ 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double g = 1.0; 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double gs = 1.0; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (png_ptr->background_gamma_type) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_SCREEN: 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = (png_ptr->screen_gamma); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_FILE: 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_BACKGROUND_GAMMA_UNIQUE: 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->background_gamma); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gs = 1.0 / (png_ptr->background_gamma * 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->screen_gamma); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1.gray = (png_uint_16)(pow( 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.gray / m, g) * m + .5); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.gray = (png_uint_16)(pow( 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.gray / m, gs) * m + .5); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->background.red != png_ptr->background.green) || 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->background.red != png_ptr->background.blue) || 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->background.red != png_ptr->background.gray)) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* RGB or RGBA with color background */ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1.red = (png_uint_16)(pow( 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.red / m, g) * m + .5); 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1.green = (png_uint_16)(pow( 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.green / m, g) * m + .5); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1.blue = (png_uint_16)(pow( 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.blue / m, g) * m + .5); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = (png_uint_16)(pow( 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.red / m, gs) * m + .5); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.green = (png_uint_16)(pow( 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.green / m, gs) * m + .5); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.blue = (png_uint_16)(pow( 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (double)png_ptr->background.blue / m, gs) * m + .5); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background_1.red = png_ptr->background_1.green 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background_1.blue = png_ptr->background_1.gray; 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->background.red = png_ptr->background.green 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = png_ptr->background.blue = png_ptr->background.gray; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Transformation does not include PNG_BACKGROUND */ 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (color_type == PNG_COLOR_TYPE_PALETTE) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_colorp palette = png_ptr->palette; 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_palette = png_ptr->num_palette; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_table[palette[i].red]; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_table[palette[i].green]; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Done the gamma correction. */ 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_GAMMA; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No GAMMA transformation */ 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_BACKGROUND) && 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (color_type == PNG_COLOR_TYPE_PALETTE)) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int istop = (int)png_ptr->num_trans; 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color back; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_colorp palette = png_ptr->palette; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = (png_byte)png_ptr->background.red; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = (png_byte)png_ptr->background.green; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = (png_byte)png_ptr->background.blue; 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->trans[i] == 0) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = back; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (png_ptr->trans[i] != 0xff) 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The png_composite() macro is defined in png.h */ 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].red, palette[i].red, 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.red); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].green, palette[i].green, 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.green); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].blue, palette[i].blue, 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.blue); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handled alpha, still need to strip the channel. */ 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations &= ~PNG_BACKGROUND; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_STRIP_ALPHA; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SHIFT_SUPPORTED 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_SHIFT) && 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (color_type == PNG_COLOR_TYPE_PALETTE)) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 i; 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 istop = png_ptr->num_palette; 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sr = 8 - png_ptr->sig_bit.red; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sg = 8 - png_ptr->sig_bit.green; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sb = 8 - png_ptr->sig_bit.blue; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sr < 0 || sr > 8) 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sr = 0; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sg < 0 || sg > 8) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sg = 0; 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sb < 0 || sb > 8) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sb = 0; 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[i].red >>= sr; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[i].green >>= sg; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette[i].blue >>= sb; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_SHIFT_SUPPORTED */ 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && !defined(PNG_READ_BACKGROUND_SUPPORTED) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Modify the info structure to reflect the transformations. The 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * info should be updated so a PNG file could be written with it, 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * assuming the transformations result in valid PNG data. 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_read_transform_info(png_structp png_ptr, png_infop info_ptr) 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_read_transform_info"); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_EXPAND) 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->num_trans) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type = PNG_COLOR_TYPE_RGB; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth = 8; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->num_trans = 0; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->num_trans) 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_EXPAND_tRNS) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->bit_depth < 8) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth = 8; 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->num_trans = 0; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BACKGROUND) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->num_trans = 0; 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->background = png_ptr->background; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_GAMMA) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FLOATING_POINT_SUPPORTED 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->gamma = png_ptr->gamma; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FIXED_POINT_SUPPORTED 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->int_gamma = png_ptr->int_gamma; 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_16_TO_8_SUPPORTED 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth = 8; 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_GRAY_TO_RGB) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type |= PNG_COLOR_MASK_COLOR; 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_RGB_TO_GRAY) 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_DITHER_SUPPORTED 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_DITHER) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_lookup && info_ptr->bit_depth == 8) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_PACK_SUPPORTED 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth = 8; 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels = 1; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels = 3; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels = 1; 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels++; 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_FILLER_SUPPORTED 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_FILLER) && 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels++; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If adding a true alpha channel not just filler */ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PNG_1_0_X 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_ADD_ALPHA) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)defined(PNG_READ_USER_TRANSFORM_SUPPORTED) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_USER_TRANSFORM) 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->bit_depth < png_ptr->user_transform_depth) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth = png_ptr->user_transform_depth; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->channels < png_ptr->user_transform_channels) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->channels = png_ptr->user_transform_channels; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->pixel_depth = (png_byte)(info_ptr->channels * 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PNG_READ_EXPAND_SUPPORTED 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Transform the row. The order of transformations is significant, 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and is very touchy. If you add a transformation, take care to 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decide how it fits in with the other transformations here. 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_read_transformations(png_structp png_ptr) 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_read_transformations"); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_buf == NULL) 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char msg[50]; 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_snprintf2(msg, 50, 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->pass); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, msg); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "NULL row buffer"); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WARN_UNINITIALIZED_ROW 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Application has failed to call either png_read_start_image() 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * or png_read_update_info() after setting transforms that expand 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pixels. This check added to libpng-1.2.19 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (PNG_WARN_UNINITIALIZED_ROW==1) 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "Uninitialized row"); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Uninitialized row"); 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_EXPAND) 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette, png_ptr->trans, png_ptr->num_trans); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->num_trans && 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->transformations & PNG_EXPAND_tRNS)) 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->trans_values)); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_RGB_TO_GRAY) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rgb_error = 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_buf + 1); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rgb_error) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->rgb_to_gray_status=1; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_RGB_TO_GRAY_WARN) 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_RGB_TO_GRAY_ERR) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* From Andreas Dilger e-mail to png-implement, 26 March 1998: 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In most cases, the "simple transparency" should be done prior to doing 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * gray-to-RGB, or you will have to test 3x as many bytes to check if a 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pixel is transparent. You would also need to make sure that the 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transparency information is upgraded to RGB. 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * To summarize, the current flow is: 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with background "in place" if transparent, 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * convert to RGB if necessary 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Gray + alpha -> composite with gray background and remove alpha bytes, 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * convert to RGB if necessary 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * To support RGB backgrounds for gray images we need: 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Gray + simple transparency -> convert to RGB + simple transparency, 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compare 3 or 6 bytes and composite with 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * background "in place" if transparent 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (3x compare/pixel compared to doing 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * composite with gray bkgrnd) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Gray + alpha -> convert to RGB + alpha, composite with background and 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * remove alpha bytes (3x float 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * operations/pixel compared with composite 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on gray background) 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Greg's change will do this. The reason it wasn't done before is for 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * performance, as this increases the per-pixel operations. If we would check 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in advance if the background was gray or RGB, and position the gray-to-RGB 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transform appropriately, then it would save a lot of work/time. 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If gray -> RGB, do so now only if background is non-gray; else do later 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for performance reasons 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_BACKGROUND) && 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((png_ptr->num_trans != 0 ) || 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->trans_values), &(png_ptr->background) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) , &(png_ptr->background_1), 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_table, png_ptr->gamma_from_1, 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_to_1, png_ptr->gamma_16_table, 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_GAMMA) && 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !((png_ptr->transformations & PNG_BACKGROUND) && 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((png_ptr->num_trans != 0) || 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_table, png_ptr->gamma_16_table, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_16_TO_8_SUPPORTED 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_16_TO_8) 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_DITHER_SUPPORTED 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_DITHER) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->palette_lookup, png_ptr->dither_index); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_info.rowbytes == (png_uint_32)0) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "png_do_dither returned rowbytes=0"); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_INVERT_SUPPORTED 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_MONO) 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SHIFT_SUPPORTED 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SHIFT) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->shift)); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_PACK_SUPPORTED 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACK) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BGR_SUPPORTED 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BGR) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_PACKSWAP_SUPPORTED 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACKSWAP) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If gray -> RGB, do so now only if we did not do so above */ 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_FILLER_SUPPORTED 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_FILLER) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_ptr->filler, png_ptr->flags); 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_ALPHA) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SWAP_ALPHA) 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SWAP_SUPPORTED 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SWAP_BYTES) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_USER_TRANSFORM) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->read_user_transform_fn != NULL) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(png_ptr->read_user_transform_fn)) /* User read transform function */ 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr, /* png_ptr */ 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &(png_ptr->row_info), /* row_info: */ 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_uint_32 width; width of row */ 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_uint_32 rowbytes; number of bytes in row */ 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte color_type; color type of pixels */ 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte bit_depth; bit depth of samples */ 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte channels; number of channels (1-4) */ 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* png_byte pixel_depth; bits per pixel (depth*channels) */ 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_buf + 1); /* start of pixel data for row */ 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->user_transform_depth) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->user_transform_channels) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.channels = png_ptr->user_transform_channels; 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.channels); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.width); 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_PACK_SUPPORTED 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without changing the actual values. Thus, if you had a row with 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a bit depth of 1, you would end up with bytes that only contained 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the numbers 0 or 1. If you would rather they contain 0 and 255, use 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * png_do_shift() after this. 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_unpack(png_row_infop row_info, png_bytep row) 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_unpack"); 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL && row_info->bit_depth < 8) 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth < 8) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row + (png_size_t)row_width - 1; 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((*sp >> shift) & 0x01); 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 7) 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift++; 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row + (png_size_t)row_width - 1; 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((*sp >> shift) & 0x03); 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 6) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift += 2; 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row + (png_size_t)row_width - 1; 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((*sp >> shift) & 0x0f); 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 4) 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(8 * row_info->channels); 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * row_info->channels; 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SHIFT_SUPPORTED 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Reverse the effects of png_do_shift. This routine merely shifts the 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pixels back to their significant bits values. Thus, if you have 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a row of bit depth 8, but only 5 are significant, this will shift 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the values back to 0 through 31. 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_unshift"); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && sig_bits != NULL && 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type != PNG_COLOR_TYPE_PALETTE) 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift[4]; 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channels = 0; 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 value = 0; 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type & PNG_COLOR_MASK_COLOR) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[channels++] = row_info->bit_depth - sig_bits->red; 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[channels++] = row_info->bit_depth - sig_bits->green; 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[channels++] = row_info->bit_depth - sig_bits->blue; 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[channels++] = row_info->bit_depth - sig_bits->gray; 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[channels++] = row_info->bit_depth - sig_bits->alpha; 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (c = 0; c < channels; c++) 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift[c] <= 0) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift[c] = 0; 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = 1; 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value) 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp; 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = row_info->rowbytes; 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (bp = row, i = 0; i < istop; i++) 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp >>= 1; 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ &= 0x55; 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp = row; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = row_info->rowbytes; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)((int)0xf >> shift[0])); 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++) 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp >>= shift[0]; 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ &= mask; 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp = row; 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = row_width * channels; 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ >>= shift[i%channels]; 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep bp = row; 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = channels * row_width; 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < istop; i++) 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (png_uint_16)((*bp << 8) + *(bp + 1)); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value >>= shift[i%channels]; 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ = (png_byte)(value >> 8); 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp++ = (png_byte)(value & 0xff); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_16_TO_8_SUPPORTED 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Chop rows of bit depth 16 down to 8 */ 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_chop(png_row_infop row_info, png_bytep row) 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_chop"); 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL && row_info->bit_depth == 16) 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 16) 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 istop = row_info->width * row_info->channels; 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i<istop; i++, sp += 2, dp++) 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This does a more accurate scaling of the 16-bit color 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * value, rather than a simple low-byte truncation. 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * What the ideal calculation should be: 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * *dp = (((((png_uint_32)(*sp) << 8) | 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (png_uint_32)(*(sp + 1))) * 255 + 127) 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * / (png_uint_32)65535L; 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GRR: no, I think this is what it really should be: 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * *dp = (((((png_uint_32)(*sp) << 8) | 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (png_uint_32)(*(sp + 1))) + 128L) 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * / (png_uint_32)257L; 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GRR: here's the exact calculation with shifts: 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * temp = (((png_uint_32)(*sp) << 8) | 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (png_uint_32)(*(sp + 1))) + 128L; 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * *dp = (temp - (temp >> 8)) >> 8; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Approximate calculation with shift/add instead of multiply/divide: 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * *dp = ((((png_uint_32)(*sp) << 8) | 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * What we actually do to avoid extra shifting and conversion: 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Simply discard the low order byte */ 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = *sp; 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(8 * row_info->channels); 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_info->width * row_info->channels; 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_read_swap_alpha"); 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from RGBA to ARGB */ 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save = *(--sp); 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save; 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from RRGGBBAA to AARRGGBB */ 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save[2]; 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[0] = *(--sp); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[1] = *(--sp); 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save[0]; 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save[1]; 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from GA to AG */ 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save; 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save = *(--sp); 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save; 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This converts from GGAA to AAGG */ 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte save[2]; 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[0] = *(--sp); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save[1] = *(--sp); 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save[0]; 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = save[1]; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_read_invert_alpha"); 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in RGBA */ 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This does nothing: 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) We can replace it with: 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp-=3; 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp=sp; 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in RRGGBBAA */ 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This does nothing: 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) We can replace it with: 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp-=6; 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp=sp; 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in GA */ 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This inverts the alpha channel in GGAA */ 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + row_info->rowbytes; 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp; 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = (png_byte)(255 - *(--sp)); 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp-=2; 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp=sp; 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_FILLER_SUPPORTED 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add filler channel if we have RGB color */ 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_read_filler(png_row_infop row_info, png_bytep row, 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 filler, png_uint_32 flags) 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte hi_filler = (png_byte)((filler>>8) & 0xff); 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte lo_filler = (png_byte)(filler & 0xff); 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_read_filler"); 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type == PNG_COLOR_TYPE_GRAY) 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from G to GX */ 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & PNG_FLAG_FILLER_AFTER) 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width; 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width; 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1; i < row_width; i++) 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 2; 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 16; 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 2; 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from G to XG */ 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width; 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width; 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 2; 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 16; 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 2; 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from GG to GGXX */ 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & PNG_FLAG_FILLER_AFTER) 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 2; 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1; i < row_width; i++) 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 2; 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 32; 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 4; 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from GG to XXGG */ 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 2; 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 2; 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 32; 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 4; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } /* COLOR_TYPE == GRAY */ 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB) 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from RGB to RGBX */ 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & PNG_FLAG_FILLER_AFTER) 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 3; 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width; 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1; i < row_width; i++) 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 32; 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 4; 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from RGB to XRGB */ 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 3; 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width; 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 32; 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 4; 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from RRGGBB to RRGGBBXX */ 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & PNG_FLAG_FILLER_AFTER) 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 6; 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1; i < row_width; i++) 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 64; 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 8; 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This changes the data from RRGGBB to XXRRGGBB */ 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 6; 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = *(--sp); 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = hi_filler; 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--dp) = lo_filler; 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 64; 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 8; 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } /* COLOR_TYPE == RGB */ 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expand grayscale files to RGB, with or without alpha */ 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_gray_to_rgb"); 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth >= 8 && 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(row_info->color_type & PNG_COLOR_MASK_COLOR)) 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width - 1; 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 2 - 1; 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 4; 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp - 1); 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp - 1); 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 2 - 1; 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 2; 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row + (png_size_t)row_width * 4 - 1; 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = sp + (png_size_t)row_width * 4; 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp - 1); 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *sp; 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp - 1); 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp--) = *(sp--); 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels += (png_byte)2; 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type |= PNG_COLOR_MASK_COLOR; 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(row_info->channels * 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth); 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Reduce RGB files to grayscale, with or without alpha 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * using the equation given in Poynton's ColorFAQ at 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * New link: 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <http://www.poynton.com/notes/colour_and_gamma/> 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Charles Poynton poynton at poynton.com 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We approximate this with 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which can be expressed with integers as 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Y = (6969 * R + 23434 * G + 2365 * B)/32768 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The calculation is to be done in a linear colorspace. 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Other integer coefficents can be used via png_set_rgb_to_gray(). 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int /* PRIVATE */ 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rgb_error = 0; 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_rgb_to_gray"); 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (row_info->color_type & PNG_COLOR_MASK_COLOR)) 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB) 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red = png_ptr->gamma_to_1[*(sp++)]; 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green = png_ptr->gamma_to_1[*(sp++)]; 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue = png_ptr->gamma_to_1[*(sp++)]; 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = png_ptr->gamma_from_1[ 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (rc*red + gc*green + bc*blue)>>15]; 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp - 1); 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red = *(sp++); 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green = *(sp++); 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue = *(sp++); 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp - 1); 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* RGB bit_depth == 16 */ 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->gamma_16_to_1 != NULL && 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1 != NULL) 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red, green, blue, w; 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red == green && red == blue) 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = red; 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][red>>8]; 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 green_1 = 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_to_1[(green&0xff) >> 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][green>>8]; 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][blue>>8]; 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + bc*blue_1)>>15); 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = png_ptr->gamma_16_from_1[(gray16&0xff) >> 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][gray16 >> 8]; 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((w>>8) & 0xff); 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(w & 0xff); 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red, green, blue, gray16; 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((gray16>>8) & 0xff); 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(gray16 & 0xff); 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red = png_ptr->gamma_to_1[*(sp++)]; 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green = png_ptr->gamma_to_1[*(sp++)]; 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue = png_ptr->gamma_to_1[*(sp++)]; 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = png_ptr->gamma_from_1 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [(rc*red + gc*green + bc*blue)>>15]; 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); /* alpha */ 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red = *(sp++); 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green = *(sp++); 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue = *(sp++); 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); /* alpha */ 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* RGBA bit_depth == 16 */ 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->gamma_16_to_1 != NULL && 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1 != NULL) 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red, green, blue, w; 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red == green && red == blue) 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = red; 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][red>>8]; 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 green_1 = 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_to_1[(green&0xff) >> 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][green>>8]; 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][blue>>8]; 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 gray16 = (png_uint_16)((rc * red_1 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + gc * green_1 + bc * blue_1)>>15); 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = png_ptr->gamma_16_from_1[(gray16&0xff) >> 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift][gray16 >> 8]; 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((w>>8) & 0xff); 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(w & 0xff); 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); /* alpha */ 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp = row; 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep dp = row; 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 red, green, blue, gray16; 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (red != green || red != blue) 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_error |= 1; 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)((gray16>>8) & 0xff); 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = (png_byte)(gray16 & 0xff); 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); /* alpha */ 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp++) = *(sp++); 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels -= (png_byte)2; 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type &= ~PNG_COLOR_MASK_COLOR; 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(row_info->channels * 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth); 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rgb_error; 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * large of png_color. This lets grayscale images be treated as 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * paletted. Most useful for gamma correction and simplification 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of code. 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_build_grayscale_palette(int bit_depth, png_colorp palette) 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_palette; 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int color_inc; 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int v; 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_build_grayscale_palette"); 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (palette == NULL) 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (bit_depth) 25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = 2; 25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_inc = 0xff; 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = 4; 25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_inc = 0x55; 25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = 16; 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_inc = 0x11; 25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = 256; 26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_inc = 1; 26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_palette = 0; 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_inc = 0; 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, v = 0; i < num_palette; i++, v += color_inc) 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = (png_byte)v; 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = (png_byte)v; 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = (png_byte)v; 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function is currently unused. Do we really need it? */ 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_DITHER_SUPPORTED) && \ 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_CORRECT_PALETTE_SUPPORTED) 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_correct_palette(png_structp png_ptr, png_colorp palette, 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_palette) 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_correct_palette"); 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_GAMMA_SUPPORTED) && \ 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_FLOATING_POINT_SUPPORTED) 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color back, back_1; 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = png_ptr->gamma_table[png_ptr->background.red]; 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = png_ptr->gamma_table[png_ptr->background.green]; 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = png_ptr->gamma_table[png_ptr->background.blue]; 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double g; 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = png_ptr->background.red; 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = png_ptr->background.green; 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = png_ptr->background.blue; 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.red/255, g) * 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.green/255, g) * 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.blue/255, g) * 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / png_ptr->background_gamma; 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.red = 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.red/255, g) * 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.green = 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.green/255, g) * 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_1.blue = 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_byte)(pow((double)png_ptr->background.blue/255, g) * 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255.0 + 0.5); 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < (png_uint_32)num_palette; i++) 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = back; 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte v, w; 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.red); 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_from_1[w]; 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.green); 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_from_1[w]; 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, png_ptr->trans[i], back_1.blue); 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_from_1[w]; 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_table[palette[i].red]; 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_table[palette[i].green]; 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (palette[i].red == (png_byte)png_ptr->trans_values.gray) 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i] = back; 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_table[palette[i].red]; 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_table[palette[i].green]; 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_GAMMA) 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = png_ptr->gamma_table[palette[i].red]; 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = png_ptr->gamma_table[palette[i].green]; 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BACKGROUND) 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color back; 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.red = (png_byte)png_ptr->background.red; 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.green = (png_byte)png_ptr->background.green; 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.blue = (png_byte)png_ptr->background.blue; 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < (int)png_ptr->num_trans; i++) 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->trans[i] == 0) 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = back.red; 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = back.green; 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = back.blue; 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (png_ptr->trans[i] != 0xff) 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].red, png_ptr->palette[i].red, 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.red); 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].green, png_ptr->palette[i].green, 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.green); 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(palette[i].blue, png_ptr->palette[i].blue, 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->trans[i], back.blue); 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* Assume grayscale palette (what else could it be?) */ 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_palette; i++) 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == (png_byte)png_ptr->trans_values.gray) 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].red = (png_byte)png_ptr->background.red; 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].green = (png_byte)png_ptr->background.green; 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette[i].blue = (png_byte)png_ptr->background.blue; 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_BACKGROUND_SUPPORTED 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Replace any alpha or transparency with the supplied background color. 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "background" is already in the screen gamma, while "background_1" is 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at a gamma of 1.0. Paletted files have already been taken care of. 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_background(png_row_infop row_info, png_bytep row, 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color_16p trans_values, png_color_16p background 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) , png_color_16p background_1, 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16pp gamma_16_to_1, int gamma_shift 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift; 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_background"); 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (background != NULL && 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->color_type) 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_GRAY: 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 7; 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_uint_16)((*sp >> shift) & 0x01) 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) == trans_values->gray) 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(background->gray << shift); 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shift) 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 7; 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift--; 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_table != NULL) 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_uint_16)((*sp >> shift) & 0x03) 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) == trans_values->gray) 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(background->gray << shift); 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte p = (png_byte)((*sp >> shift) & 0x03); 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte g = (png_byte)((gamma_table [p | (p << 2) | 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (p << 4) | (p << 6)] >> 6) & 0x03); 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(g << shift); 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shift) 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 2; 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_uint_16)((*sp >> shift) & 0x03) 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) == trans_values->gray) 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(background->gray << shift); 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shift) 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 6; 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 2; 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_table != NULL) 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_uint_16)((*sp >> shift) & 0x0f) 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) == trans_values->gray) 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(background->gray << shift); 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte p = (png_byte)((*sp >> shift) & 0x0f); 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte g = (png_byte)((gamma_table[p | 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (p << 4)] >> 4) & 0x0f); 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(g << shift); 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shift) 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 4; 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_uint_16)((*sp >> shift) & 0x0f) 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) == trans_values->gray) 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp |= (png_byte)(background->gray << shift); 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shift) 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift -= 4; 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_table != NULL) 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp++) 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp == trans_values->gray) 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)background->gray; 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp++) 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp == trans_values->gray) 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)background->gray; 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_16 != NULL) 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 2) 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (v == trans_values->gray) 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((background->gray >> 8) & 0xff); 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(background->gray & 0xff); 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 2) 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (v == trans_values->gray) 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((background->gray >> 8) & 0xff); 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(background->gray & 0xff); 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_RGB: 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_table != NULL) 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 3) 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp == trans_values->red && 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) == trans_values->green && 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) == trans_values->blue) 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)background->red; 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)background->green; 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = (png_byte)background->blue; 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = gamma_table[*(sp + 1)]; 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = gamma_table[*(sp + 2)]; 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 3) 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp == trans_values->red && 30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) == trans_values->green && 30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) == trans_values->blue) 30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)background->red; 30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)background->green; 30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = (png_byte)background->blue; 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (row_info->bit_depth == 16) */ 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_16 != NULL) 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 6) 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r == trans_values->red && g == trans_values->green && 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b == trans_values->blue) 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((background->red >> 8) & 0xff); 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(background->red & 0xff); 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 3) = (png_byte)(background->green & 0xff); 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 5) = (png_byte)(background->blue & 0xff); 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = (png_byte)((v >> 8) & 0xff); 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 3) = (png_byte)(v & 0xff); 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 4) = (png_byte)((v >> 8) & 0xff); 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 5) = (png_byte)(v & 0xff); 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 6) 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r == trans_values->red && g == trans_values->green && 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b == trans_values->blue) 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((background->red >> 8) & 0xff); 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(background->red & 0xff); 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 3) = (png_byte)(background->green & 0xff); 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 5) = (png_byte)(background->blue & 0xff); 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_GRAY_ALPHA: 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_to_1 != NULL && gamma_from_1 != NULL && 31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gamma_table != NULL) 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 2, dp++) 31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 a = *(sp + 1); 31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == 0xff) 31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = gamma_table[*sp]; 31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)background->gray; 31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte v, w; 31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_to_1[*sp]; 31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, a, background_1->gray); 31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = gamma_from_1[w]; 31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 2, dp++) 31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte a = *(sp + 1); 32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == 0xff) 32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = *sp; 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)background->gray; 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(*dp, *sp, a, background_1->gray); 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)background->gray; 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (png_ptr->bit_depth == 16) */ 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_16 != NULL && gamma_16_from_1 != NULL && 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gamma_16_to_1 != NULL) 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 4, dp += 2) 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == (png_uint_16)0xffff) 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((v >> 8) & 0xff); 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(v & 0xff); 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((background->gray >> 8) & 0xff); 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(background->gray & 0xff); 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 g, v, w; 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(v, g, a, background_1->gray); 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((w >> 8) & 0xff); 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(w & 0xff); 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 4, dp += 2) 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == (png_uint_16)0xffff) 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(dp, sp, 2); 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((background->gray >> 8) & 0xff); 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(background->gray & 0xff); 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 g, v; 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(v, g, a, background_1->gray); 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((v >> 8) & 0xff); 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(v & 0xff); 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_RGB_ALPHA: 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_to_1 != NULL && gamma_from_1 != NULL && 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gamma_table != NULL) 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 4, dp += 3) 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte a = *(sp + 3); 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == 0xff) 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = gamma_table[*sp]; 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = gamma_table[*(sp + 1)]; 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = gamma_table[*(sp + 2)]; 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)background->red; 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)background->green; 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)background->blue; 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte v, w; 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_to_1[*sp]; 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, a, background_1->red); 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = gamma_from_1[w]; 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_to_1[*(sp + 1)]; 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, a, background_1->green); 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = gamma_from_1[w]; 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_to_1[*(sp + 2)]; 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(w, v, a, background_1->blue); 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = gamma_from_1[w]; 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 4, dp += 3) 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte a = *(sp + 3); 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == 0xff) 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = *sp; 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = *(sp + 1); 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = *(sp + 2); 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)background->red; 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)background->green; 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)background->blue; 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(*dp, *sp, a, background->red); 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(*(dp + 1), *(sp + 1), a, 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) background->green); 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite(*(dp + 2), *(sp + 2), a, 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) background->blue); 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (row_info->bit_depth == 16) */ 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gamma_16 != NULL && gamma_16_from_1 != NULL && 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gamma_16_to_1 != NULL) 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 8, dp += 6) 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << 8) + (png_uint_16)(*(sp + 7))); 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == (png_uint_16)0xffff) 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((v >> 8) & 0xff); 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(v & 0xff); 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)((v >> 8) & 0xff); 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 3) = (png_byte)(v & 0xff); 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 4) = (png_byte)((v >> 8) & 0xff); 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 5) = (png_byte)(v & 0xff); 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Background is already in screen gamma */ 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((background->red >> 8) & 0xff); 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(background->red & 0xff); 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 3) = (png_byte)(background->green & 0xff); 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 5) = (png_byte)(background->blue & 0xff); 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v, w, x; 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(w, v, a, background_1->red); 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((x >> 8) & 0xff); 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(x & 0xff); 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(w, v, a, background_1->green); 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)((x >> 8) & 0xff); 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 3) = (png_byte)(x & 0xff); 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(w, v, a, background_1->blue); 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 4) = (png_byte)((x >> 8) & 0xff); 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 5) = (png_byte)(x & 0xff); 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp += 8, dp += 6) 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << 8) + (png_uint_16)(*(sp + 7))); 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a == (png_uint_16)0xffff) 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(dp, sp, 6); 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (a == 0) 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((background->red >> 8) & 0xff); 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(background->red & 0xff); 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 3) = (png_byte)(background->green & 0xff); 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 5) = (png_byte)(background->blue & 0xff); 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + *(sp + 3)); 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + *(sp + 5)); 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(v, r, a, background->red); 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)((v >> 8) & 0xff); 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 1) = (png_byte)(v & 0xff); 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(v, g, a, background->green); 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 2) = (png_byte)((v >> 8) & 0xff); 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 3) = (png_byte)(v & 0xff); 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_composite_16(v, b, a, background->blue); 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 4) = (png_byte)((v >> 8) & 0xff); 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(dp + 5) = (png_byte)(v & 0xff); 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels--; 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(row_info->channels * 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth); 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Gamma correct the image, avoiding the alpha channel. Make sure 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you do this after you deal with the transparency issue on grayscale 35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * or RGB images. If your bit depth is 8, use gamma_table, if it 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is 16, use gamma_16_table and gamma_shift. Build these with 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * build_gamma_table(). 35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_gamma(png_row_infop row_info, png_bytep row, 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep gamma_table, png_uint_16pp gamma_16_table, 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int gamma_shift) 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp; 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_gamma"); 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((row_info->bit_depth <= 8 && gamma_table != NULL) || 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (row_info->bit_depth == 16 && gamma_16_table != NULL))) 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->color_type) 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_RGB: 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (row_info->bit_depth == 16) */ 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v; 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_RGB_ALPHA: 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (row_info->bit_depth == 16) */ 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 4; 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_GRAY_ALPHA: 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else /* if (row_info->bit_depth == 16) */ 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 4; 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_COLOR_TYPE_GRAY: 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 2) 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i += 4) 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int a = *sp & 0xc0; 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int b = *sp & 0x30; 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c = *sp & 0x0c; 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d = *sp & 0x03; 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)( 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 4) 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i += 2) 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int msb = *sp & 0xf0; 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lsb = *sp & 0x0f; 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 8) 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = gamma_table[*sp]; 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = (png_byte)((v >> 8) & 0xff); 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp + 1) = (png_byte)(v & 0xff); 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp += 2; 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_EXPAND_SUPPORTED 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Expands a palette row to an RGB or RGBA row depending 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * upon whether you supply trans and num_trans. 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_expand_palette(png_row_infop row_info, png_bytep row, 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_colorp palette, png_bytep trans, int num_trans) 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift, value; 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_expand_palette"); 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type == PNG_COLOR_TYPE_PALETTE) 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth < 8) 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 3); 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 7 - (int)((row_width + 7) & 0x07); 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*sp >> shift) & 0x01) 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = 1; 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = 0; 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 7) 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift++; 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 2); 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (*sp >> shift) & 0x03; 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)value; 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 6) 37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift += 2; 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 1); 37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = (int)((row_width & 0x01) << 2); 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (*sp >> shift) & 0x0f; 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)value; 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 4) 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift += 4; 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 8; 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width; 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans != NULL) 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)row_width - 1; 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)(row_width << 2) - 1; 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)(*sp) >= num_trans) 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = trans[*sp]; 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].blue; 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].green; 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].red; 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 32; 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 4; 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = 6; 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)row_width - 1; 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)(row_width * 3) - 1; 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].blue; 38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].green; 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = palette[*sp].red; 38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 24; 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width * 3; 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = 2; 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 3; 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* If the bit depth < 8, it is expanded to 8. Also, if the already 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * expanded transparency value is supplied, an alpha channel is built. 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_expand(png_row_infop row_info, png_bytep row, 38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_color_16p trans_value) 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift, value; 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_expand"); 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth < 8) 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (row_info->bit_depth) 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray = (png_uint_16)((gray&0x01)*0xff); 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 3); 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 7 - (int)((row_width + 7) & 0x07); 38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*sp >> shift) & 0x01) 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = 0xff; 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = 0; 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 7) 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift++; 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray = (png_uint_16)((gray&0x03)*0x55); 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 2); 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (*sp >> shift) & 0x03; 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)(value | (value << 2) | (value << 4) | 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (value << 6)); 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 6) 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift += 2; 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray = (png_uint_16)((gray&0x0f)*0x11); 39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)((row_width - 1) >> 1); 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)row_width - 1; 39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = (*sp >> shift) & 0x0f; 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp = (png_byte)(value | (value << 4)); 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift == 4) 39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp--; 39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 4; 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp--; 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->bit_depth = 8; 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = 8; 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = row_width; 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (trans_value != NULL) 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gray = gray & 0xff; 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)row_width - 1; 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)(row_width << 1) - 1; 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*sp == gray) 39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte gray_high = (gray >> 8) & 0xff; 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte gray_low = gray & 0xff; 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + row_info->rowbytes - 1; 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (row_info->rowbytes << 1) - 1; 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*(sp - 1) == gray_high && *(sp) == gray_low) 39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 2; 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_width); 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red = trans_value->red & 0xff; 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green = trans_value->green & 0xff; 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue = trans_value->blue & 0xff; 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + (png_size_t)row_info->rowbytes - 1; 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)(row_width << 2) - 1; 39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red_high = (trans_value->red >> 8) & 0xff; 40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green_high = (trans_value->green >> 8) & 0xff; 40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue_high = (trans_value->blue >> 8) & 0xff; 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte red_low = trans_value->red & 0xff; 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte green_low = trans_value->green & 0xff; 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_byte blue_low = trans_value->blue & 0xff; 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row + row_info->rowbytes - 1; 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row + (png_size_t)(row_width << 3) - 1; 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*(sp - 5) == red_high && 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp - 4) == red_low && 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp - 3) == green_high && 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp - 2) == green_low && 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp - 1) == blue_high && 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(sp ) == blue_low) 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0; 40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = 0xff; 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp-- = *sp--; 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 4; 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_DITHER_SUPPORTED 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_dither(png_row_infop row_info, png_bytep row, 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep palette_lookup, png_bytep dither_lookup) 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep sp, dp; 40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width=row_info->width; 40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_dither"); 40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row != NULL && row_info != NULL) 40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB && 40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette_lookup && row_info->bit_depth == 8) 40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r, g, b, p; 40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = *sp++; 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = *sp++; 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = *sp++; 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This looks real messy, but the compiler will reduce 40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it down to a reasonable formula. For example, with 40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5 bits per color, we get: 40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * p = (((r >> 3) & 0x1f) << 10) | 40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (((g >> 3) & 0x1f) << 5) | 40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ((b >> 3) & 0x1f); 40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = (((r >> (8 - PNG_DITHER_RED_BITS)) & 40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_RED_BITS) - 1)) << 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((g >> (8 - PNG_DITHER_GREEN_BITS)) & 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_GREEN_BITS) - 1)) << 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PNG_DITHER_BLUE_BITS)) | 40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((b >> (8 - PNG_DITHER_BLUE_BITS)) & 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_BLUE_BITS) - 1)); 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp++ = palette_lookup[p]; 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = PNG_COLOR_TYPE_PALETTE; 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 1; 40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = row_info->bit_depth; 41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) palette_lookup != NULL && row_info->bit_depth == 8) 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r, g, b, p; 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dp = row; 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++) 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = *sp++; 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = *sp++; 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = *sp++; 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp++; 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = (((r >> (8 - PNG_DITHER_RED_BITS)) & 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_RED_BITS) - 1)) << 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((g >> (8 - PNG_DITHER_GREEN_BITS)) & 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_GREEN_BITS) - 1)) << 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PNG_DITHER_BLUE_BITS)) | 41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((b >> (8 - PNG_DITHER_BLUE_BITS)) & 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((1 << PNG_DITHER_BLUE_BITS) - 1)); 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dp++ = palette_lookup[p]; 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->color_type = PNG_COLOR_TYPE_PALETTE; 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->channels = 1; 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->pixel_depth = row_info->bit_depth; 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dither_lookup && row_info->bit_depth == 8) 41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sp = row; 41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < row_width; i++, sp++) 41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = dither_lookup[*sp]; 41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FLOATING_POINT_SUPPORTED 41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_READ_GAMMA_SUPPORTED 41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PNG_CONST int png_gamma_shift[] = 41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; 41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit 41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables, we don't make a full table if we are reducing to 8-bit in 41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the future. Note also how the gamma_16 tables are segmented so that 41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we don't need to allocate > 64K chunks for a full 16-bit table. 41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the PNG extensions document for an integer algorithm for creating 41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the gamma tables. Maybe we will implement that here someday. 41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We should only reach this point if 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * or the application has provided a file_gamma) 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * AND 41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * { 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the screen_gamma is known 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RGB_to_gray transformation is being performed 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * } 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * AND 41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * { 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the screen_gamma is different from the reciprocal of the 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * file_gamma by more than the specified threshold 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR 41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a background color has been specified and the file_gamma 41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and screen_gamma are not 1.0, within the specified threshold. 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * } 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_build_gamma_table(png_structp png_ptr) 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_build_gamma_table"); 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->bit_depth <= 8) 41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double g; 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->screen_gamma > .000001) 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0; 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, 41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)256); 42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 256; i++) 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, 42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g) * 255.0 + .5); 42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma); 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)256); 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 256; i++) 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g) * 255.0 + .5); 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)256); 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->screen_gamma > 0.000001) 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / png_ptr->screen_gamma; 42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = png_ptr->gamma; /* Probably doing rgb_to_gray */ 42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 256; i++) 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, 42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g) * 255.0 + .5); 42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ 42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double g; 42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j, shift, num; 42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sig_bit; 42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 ig; 42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_bit = (int)png_ptr->sig_bit.red; 42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->sig_bit.green > sig_bit) 42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_bit = png_ptr->sig_bit.green; 42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((int)png_ptr->sig_bit.blue > sig_bit) 42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_bit = png_ptr->sig_bit.blue; 42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_bit = (int)png_ptr->sig_bit.gray; 42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sig_bit > 0) 42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 16 - sig_bit; 42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_16_TO_8) 42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift < (16 - PNG_MAX_GAMMA_8)) 42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = (16 - PNG_MAX_GAMMA_8); 42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift > 8) 42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 8; 42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shift < 0) 42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift = 0; 42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_shift = (png_byte)shift; 42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num = (1 << (8 - shift)); 42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->screen_gamma > .000001) 42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); 42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0; 42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, 42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num * png_sizeof(png_uint_16p))); 42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) 42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double fin, fout; 42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 last, max; 42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num; i++) 43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, 43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(256 * png_sizeof(png_uint_16))); 43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / g; 43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = 0; 43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 256; i++) 43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fout = ((double)i + 0.5) / 256.0; 43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin = pow(fout, g); 43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); 43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (last <= max) 43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] 43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [(int)(last >> (8 - shift))] = (png_uint_16)( 43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)i | ((png_uint_16)i << 8)); 43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (last < ((png_uint_32)num << 8)) 43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] 43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [(int)(last >> (8 - shift))] = (png_uint_16)65535L; 43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num; i++) 43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, 43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(256 * png_sizeof(png_uint_16))); 43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); 43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < 256; j++) 43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_table[i][j] = 43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65535.0, g) * 65535.0 + .5); 43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) 43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / (png_ptr->gamma); 43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, 43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num * png_sizeof(png_uint_16p ))); 43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num; i++) 43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, 43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(256 * png_sizeof(png_uint_16))); 43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ig = (((png_uint_32)i * 43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_gamma_shift[shift]) >> 4); 43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < 256; j++) 43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_to_1[i][j] = 43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65535.0, g) * 65535.0 + .5); 43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->screen_gamma > 0.000001) 43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = 1.0 / png_ptr->screen_gamma; 43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g = png_ptr->gamma; /* Probably doing rgb_to_gray */ 43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(num * png_sizeof(png_uint_16p))); 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num; i++) 43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(256 * png_sizeof(png_uint_16))); 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ig = (((png_uint_32)i * 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_gamma_shift[shift]) >> 4); 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j < 256; j++) 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->gamma_16_from_1[i][j] = 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65535.0, g) * 65535.0 + .5); 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* To do: install integer version of png_build_gamma_table here */ 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_MNG_FEATURES_SUPPORTED 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Undoes intrapixel differencing */ 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_do_read_intrapixel(png_row_infop row_info, png_bytep row) 44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_do_read_intrapixel"); 44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USELESS_TESTS_SUPPORTED 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row != NULL && row_info != NULL && 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (row_info->color_type & PNG_COLOR_MASK_COLOR)) 44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_per_pixel; 44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 row_width = row_info->width; 44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->bit_depth == 8) 44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep rp; 44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB) 44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 3; 44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 4; 44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); 44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); 44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->bit_depth == 16) 44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytep rp; 44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; 44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row_info->color_type == PNG_COLOR_TYPE_RGB) 44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 6; 44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_pixel = 8; 44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); 44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); 44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); 44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); 44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); 44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp ) = (png_byte)((red >> 8) & 0xff); 44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+1) = (png_byte)(red & 0xff); 44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+4) = (png_byte)((blue >> 8) & 0xff); 44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(rp+5) = (png_byte)(blue & 0xff); 44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_MNG_FEATURES_SUPPORTED */ 44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_READ_SUPPORTED */ 4468