1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngrtran.c - transforms the data in a row for PNG readers 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 47a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * Last changed in libpng 1.6.24 [August 4, 2016] 5114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson 6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 9a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * This code is released under the libpng license. 10a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * For conditions of distribution and use, see the disclaimer 11a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and license in png.h 12a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * This file contains functions optionally called by an application 14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in order to tell libpng how to handle data when reading a PNG. 15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Transformations that are used in both reading and writing are 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in pngtrans.c. 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#include "pngpriv.h" 20b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SUPPORTED 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Set the action on getting a CRC error for an ancillary or critical chunk. */ 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 25b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_crc_action"); 28b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 29a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 30a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Tell libpng how we react to CRC errors in critical chunks */ 33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (crit_action) 34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 35a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 37a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 38a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_WARN_USE: /* Warn/use data */ 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 42a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 43a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_QUIET_USE: /* Quiet/use data */ 44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | 46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_FLAG_CRC_CRITICAL_IGNORE; 47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 48a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 49a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ 504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, 517a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "Can't discard critical data on CRC error"); 52a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_ERROR_QUIT: /* Error/quit */ 53a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_CRC_DEFAULT: 55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Tell libpng how we react to CRC errors in ancillary chunks */ 61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (ancil_action) 62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 63a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 65a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 66a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_WARN_USE: /* Warn/use data */ 67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; 69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 70a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 71a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_QUIET_USE: /* Quiet/use data */ 72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | 74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_FLAG_CRC_ANCILLARY_NOWARN; 75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 76a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 77a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_ERROR_QUIT: /* Error/quit */ 78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; 80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 81a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 82a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ 83a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_CRC_DEFAULT: 85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 91b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_TRANSFORMS_SUPPORTED 92b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Is it OK to set a transformation now? Only if png_start_read_image or 93b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_read_update_info have not been called. It is not necessary for the IHDR 949b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * to have been read in all cases; the need_IHDR parameter allows for this 959b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * check too. 96b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 97b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic int 98b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_rtran_ok(png_structrp png_ptr, int need_IHDR) 99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr != NULL) 101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) 103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_error(png_ptr, 1047a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "invalid after png_start_read_image or png_read_update_info"); 105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) 107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_error(png_ptr, "invalid before the PNG header has been read"); 108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Turn on failure to initialize correctly for all transforms. */ 112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; 113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return 1; /* Ok */ 115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return 0; /* no png_error possible! */ 119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_BACKGROUND_SUPPORTED 123a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Handle alpha and tRNS via a background color */ 124b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 125b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_background_fixed(png_structrp png_ptr, 126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p background_color, int background_gamma_code, 127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int need_expand, png_fixed_point background_gamma) 128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_background_fixed"); 130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1319b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) 132a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Application must supply a known background gamma"); 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; 141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background = *background_color; 145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma = background_gamma; 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background_gamma_type = (png_byte)(background_gamma_code); 1479b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (need_expand != 0) 148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_BACKGROUND_EXPAND; 149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 154b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 155b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_background(png_structrp png_ptr, 156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p background_color, int background_gamma_code, 157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int need_expand, double background_gamma) 158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_background_fixed(png_ptr, background_color, background_gamma_code, 160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); 161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1627a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis# endif /* FLOATING_POINT */ 163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_BACKGROUND */ 164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the 166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * one that pngrtran does first (scale) happens. This is necessary to allow the 167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. 168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 170b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 171b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_scale_16(png_structrp png_ptr) 172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_scale_16"); 174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1759b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_SCALE_16_TO_8; 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Chop 16-bit depth files to 8-bit depth */ 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 185b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_strip_16(png_structrp png_ptr) 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_strip_16"); 1885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 1899b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 190a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_16_TO_8; 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 198b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_strip_alpha(png_structrp png_ptr) 199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_strip_alpha"); 2015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 203b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 205b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_STRIP_ALPHA; 206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 209b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) 210b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic png_fixed_point 211b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktranslate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, 2127a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis int is_screen) 213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Check for flag values. The main reason for having the old Mac value as a 215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * flag is that it is pretty near impossible to work out what the correct 216b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * value is from Apple documentation - a working Mac system is needed to 217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * discover the value! 218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma == PNG_DEFAULT_sRGB || 220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) 221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If there is no sRGB support this just sets the gamma to the standard 223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * sRGB value. (This is a side effect of using this function!) 224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_sRGB_SUPPORTED 226b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; 227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 228b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_UNUSED(png_ptr) 229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 2309b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (is_screen != 0) 231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_sRGB; 232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 233b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_sRGB_INVERSE; 234b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 236b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (output_gamma == PNG_GAMMA_MAC_18 || 237b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) 238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2399b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (is_screen != 0) 240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_MAC_OLD; 241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 242b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_MAC_INVERSE; 243b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 244b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 245b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return output_gamma; 246b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 248b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 249b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic png_fixed_point 250b50c217251b086440efcdb273c22f86a06c80cbaChris Craikconvert_gamma_value(png_structrp png_ptr, double output_gamma) 251b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following silently ignores cases where fixed point (times 100,000) 253b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma values are passed to the floating point API. This is safe and it 254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * means the fixed point constants work just fine with the floating point 255b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * API. The alternative would just lead to undetected errors and spurious 256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * bug reports. Negative values fail inside the _fixed API unless they 257b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correspond to the flag values. 258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma > 0 && output_gamma < 128) 260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma *= PNG_FP_1; 261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This preserves -1 and -2 exactly: */ 263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = floor(output_gamma + .5); 264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) 266b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_error(png_ptr, "gamma value"); 267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return (png_fixed_point)output_gamma; 269b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 271b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_ALPHA_MODE || READ_GAMMA */ 272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 273b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 274b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 275b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_alpha_mode_fixed(png_structrp png_ptr, int mode, 2767a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_fixed_point output_gamma) 277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int compose = 0; 279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point file_gamma; 280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_alpha_mode"); 282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2839b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 284a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); 287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Validate the value to ensure it is in a reasonable range. The value 289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is expected to be 1 or greater, but this range test allows for some 290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * viewing correction values. The intent is to weed out users of this API 291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * who use the inverse of the gamma value accidentally! Since some of these 292114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett * values are reasonable this may have to be changed: 293114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett * 294114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit 295114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett * gamma of 36, and its reciprocal.) 296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 297114668651129dc978b9710d0f0ad107ee5ee3281Matt Sarett if (output_gamma < 1000 || output_gamma > 10000000) 298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "output gamma out of expected range"); 299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The default file gamma is the inverse of the output gamma; the output 301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma may be changed below so get the file value first: 302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 303b50c217251b086440efcdb273c22f86a06c80cbaChris Craik file_gamma = png_reciprocal(output_gamma); 304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* There are really 8 possibilities here, composed of any combination 306b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of: 307b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiply the color channels 309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * do not encode non-opaque pixels 310b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * encode the alpha as well as the color channels 311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The differences disappear if the input/output ('screen') gamma is 1.0, 313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because then the encoding is a no-op and there is only the choice of 314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiplying the color channels or not. 315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode and png_set_background interact because both use 317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_compose to do the work. Calling both is only useful when 318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along 319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * with a default gamma value. Otherwise PNG_COMPOSE must not be set. 320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (mode) 322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_PNG: /* default: png standard */ 324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* No compose, but it may be set by png_set_background! */ 325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ 330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 331b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The output is linear: */ 334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_FP_1; 335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ 338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; 341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* output_gamma records the encoding of opaque pixels! */ 342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ 345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 346b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_ENCODE_ALPHA; 347b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 349b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid alpha mode"); 352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Only set the default gamma if the file gamma has not been set (this has 355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the side effect that the gamma in a second call to png_set_alpha_mode will 356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * be ignored.) 357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->colorspace.gamma == 0) 359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = file_gamma; 361b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* But always set the output gamma: */ 365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = output_gamma; 366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 367b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Finally, if pre-multiplying, set the background fields to achieve the 368b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * desired result. 369b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3709b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (compose != 0) 371b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* And obtain alpha pre-multiplication by composing on black: */ 373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memset(&png_ptr->background, 0, (sizeof png_ptr->background)); 374b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ 375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; 376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3789b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_COMPOSE) != 0) 379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, 3807a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "conflicting calls to set alpha mode and background"); 381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_COMPOSE; 383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 387b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 388b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) 389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, 3917a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis output_gamma)); 392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_QUANTIZE_SUPPORTED 397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Dither file to 8-bit. Supply a palette, the current number 398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of elements in the palette, the maximum number of elements 399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * allowed, and a histogram if possible. If the current number 4009b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * of colors is greater than the maximum number, the palette will be 401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * modified to fit in the maximum number. "full_quantize" indicates 402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * whether we need a quantizing cube set up for RGB images, or if we 403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * simply are reducing the number of colors in a paletted image. 404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef struct png_dsort_struct 407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik struct png_dsort_struct * next; 409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte left; 410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte right; 411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} png_dsort; 412b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktypedef png_dsort * png_dsortp; 413b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktypedef png_dsort * * png_dsortpp; 414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 416b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_quantize(png_structrp png_ptr, png_colorp palette, 417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_palette, int maximum_colors, png_const_uint_16p histogram, 418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int full_quantize) 419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_quantize"); 4215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4229b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 423a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_QUANTIZE; 426b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4279b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (full_quantize == 0) 428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, 432851c67770f9cebece9c79e914a54c348f539a512Matt Sarett (png_uint_32)(num_palette * (sizeof (png_byte)))); 433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)i; 435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_palette > maximum_colors) 438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (histogram != NULL) 440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This is easy enough, just throw out the least used colors. 442a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * Perhaps not the best solution, but good enough. 443a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 447a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize an array to sort colors */ 448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, 449851c67770f9cebece9c79e914a54c348f539a512Matt Sarett (png_uint_32)(num_palette * (sizeof (png_byte)))); 450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Initialize the quantize_sort array */ 452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 453b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[i] = (png_byte)i; 454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Find the least used palette entries by starting a 456a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * bubble sort, and running it until we have sorted 457a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * out enough colors. Note that we don't care about 458a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * sorting all the colors, just finding which are 459a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * least used. 460a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = num_palette - 1; i >= maximum_colors; i--) 463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 464a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott int done; /* To stop early if the list is pre-sorted */ 465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project done = 1; 468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < i; j++) 469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (histogram[png_ptr->quantize_sort[j]] 471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < histogram[png_ptr->quantize_sort[j + 1]]) 472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte t; 474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik t = png_ptr->quantize_sort[j]; 476b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; 477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[j + 1] = t; 478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project done = 0; 479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4829b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (done != 0) 483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 486a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Swap the palette around, and set up a table, if necessary */ 4879b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (full_quantize != 0) 488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j = num_palette; 490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 491a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Put all the useful colors within the max, but don't 492a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * move the others. 493a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < maximum_colors; i++) 495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j--; 500b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 501b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = palette[j]; 503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j = num_palette; 509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 510a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Move all the used colors inside the max limit, and 511a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * develop a translation table. 512a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < maximum_colors; i++) 514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 515a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Only move the colors we need to */ 516b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color tmp_color; 519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j--; 522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project tmp_color = palette[j]; 525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[j] = palette[i]; 526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = tmp_color; 527a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Indicate where the color went */ 528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[j] = (png_byte)i; 529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)j; 530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 533a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Find closest color for those colors we are not using */ 534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 536b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_index[i] >= maximum_colors) 537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int min_d, k, min_k, d_index; 539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 540a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Find the closest color to one we threw out */ 541b50c217251b086440efcdb273c22f86a06c80cbaChris Craik d_index = png_ptr->quantize_index[i]; 542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); 543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (k = 1, min_k = 0; k < maximum_colors; k++) 544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d; 546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project d = PNG_COLOR_DIST(palette[d_index], palette[k]); 548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d < min_d) 550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_d = d; 552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_k = k; 553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 555a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Point to closest color */ 556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)min_k; 557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_free(png_ptr, png_ptr->quantize_sort); 561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort = NULL; 562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This is much harder to do simply (and quickly). Perhaps 566a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * we need to go through a median cut routine, but those 567a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * don't always behave themselves with only a few colors 568a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * as input. So we will just find the closest two colors, 569a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and throw out one of them (chosen somewhat randomly). 570a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * [We don't understand this at all, so if someone wants to 571a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * work on improving it, be our guest - AED, GRP] 572a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int max_d; 575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_new_palette; 576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp t; 577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortpp hash; 578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project t = NULL; 580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 581a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize palette index arrays */ 582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, 583851c67770f9cebece9c79e914a54c348f539a512Matt Sarett (png_uint_32)(num_palette * (sizeof (png_byte)))); 584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, 585851c67770f9cebece9c79e914a54c348f539a512Matt Sarett (png_uint_32)(num_palette * (sizeof (png_byte)))); 586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 587a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize the sort array */ 588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette[i] = (png_byte)i; 591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index[i] = (png_byte)i; 592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * 595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (sizeof (png_dsortp)))); 596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_new_palette = num_palette; 598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 599a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initial wild guess at how far apart the farthest pixel 600a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * pair we will be eliminating will be. Larger 601a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * numbers mean more areas will be allocated, Smaller 602a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * numbers run the risk of not saving enough data, and 603a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * having to do this all over again. 604a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 605a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * I have not done extensive checking on this number. 606a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_d = 96; 608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (num_new_palette > maximum_colors) 610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_new_palette - 1; i++) 612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = i + 1; j < num_new_palette; j++) 616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d; 618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project d = PNG_COLOR_DIST(palette[i], palette[j]); 620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d <= max_d) 622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t = (png_dsortp)png_malloc_warn(png_ptr, 625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(sizeof (png_dsort))); 626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t == NULL) 628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 629b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->next = hash[d]; 631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->left = (png_byte)i; 632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->right = (png_byte)j; 633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project hash[d] = t; 634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t == NULL) 637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t != NULL) 641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i <= max_d; i++) 642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (hash[i] != NULL) 644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp p; 646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (p = hash[i]; p; p = p->next) 648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((int)png_ptr->index_to_palette[p->left] 650b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < num_new_palette && 651b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (int)png_ptr->index_to_palette[p->right] 652b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < num_new_palette) 653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j, next_j; 655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette & 0x01) 657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j = p->left; 659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project next_j = p->right; 660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j = p->right; 664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project next_j = p->left; 665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_new_palette--; 668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[png_ptr->index_to_palette[j]] 669b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = palette[num_new_palette]; 6709b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (full_quantize == 0) 671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int k; 673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (k = 0; k < num_palette; k++) 675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 676b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->quantize_index[k] == 677b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[j]) 678b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[k] = 679b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[next_j]; 680b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 681b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_index[k] == 682b50c217251b086440efcdb273c22f86a06c80cbaChris Craik num_new_palette) 683b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[k] = 684b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[j]; 685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette[png_ptr->palette_to_index 689b50c217251b086440efcdb273c22f86a06c80cbaChris Craik [num_new_palette]] = png_ptr->index_to_palette[j]; 690b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index[png_ptr->index_to_palette[j]] 692b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->palette_to_index[num_new_palette]; 693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 6945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->index_to_palette[j] = 6955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_byte)num_new_palette; 696b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 6975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->palette_to_index[num_new_palette] = 6985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_byte)j; 699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette <= maximum_colors) 701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette <= maximum_colors) 704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 769; i++) 709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (hash[i] != NULL) 711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp p = hash[i]; 713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (p) 714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t = p->next; 716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, p); 717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = t; 718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project hash[i] = 0; 721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_d += 96; 723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, hash); 725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, png_ptr->palette_to_index); 726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, png_ptr->index_to_palette); 7274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->palette_to_index = NULL; 7284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->index_to_palette = NULL; 729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_palette = maximum_colors; 731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->palette == NULL) 733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette = palette; 735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_palette = (png_uint_16)num_palette; 737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 7389b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (full_quantize != 0) 739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep distance; 742b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + 743b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_QUANTIZE_BLUE_BITS; 744b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_red = (1 << PNG_QUANTIZE_RED_BITS); 745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); 746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); 747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t num_entries = ((png_size_t)1 << total_bits); 7485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, 750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_entries * (sizeof (png_byte)))); 751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * 753b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (sizeof (png_byte)))); 754b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 755b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memset(distance, 0xff, num_entries * (sizeof (png_byte))); 756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ir, ig, ib; 760b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); 761b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); 762b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); 763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ir = 0; ir < num_red; ir++) 765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int dr = abs(ir - r); */ 767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dr = ((ir > r) ? ir - r : r - ir); 768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + 769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_QUANTIZE_GREEN_BITS)); 770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ig = 0; ig < num_green; ig++) 772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int dg = abs(ig - g); */ 774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dg = ((ig > g) ? ig - g : g - ig); 775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dt = dr + dg; 776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dm = ((dr > dg) ? dr : dg); 777b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); 778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ib = 0; ib < num_blue; ib++) 780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d_index = index_g | ib; 782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int db = abs(ib - b); */ 783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int db = ((ib > b) ? ib - b : b - ib); 784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dmax = ((dm > db) ? dm : db); 785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d = dmax + dt + db; 786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d < (int)distance[d_index]) 788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project distance[d_index] = (png_byte)d; 790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_lookup[d_index] = (png_byte)i; 791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, distance); 798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 8009b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_QUANTIZE */ 801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 802b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 803b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 804b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, 8057a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_fixed_point file_gamma) 806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_gamma_fixed"); 8085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8099b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 810a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 812b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* New in libpng-1.5.4 - reserve particular negative values as flags. */ 813b50c217251b086440efcdb273c22f86a06c80cbaChris Craik scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); 814b50c217251b086440efcdb273c22f86a06c80cbaChris Craik file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); 815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Checking the gamma values for being >0 was added in 1.5.4 along with the 817b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiplied alpha support; this actually hides an undocumented feature 818b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of the previous implementation which allowed gamma processing to be 819b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * disabled in background handling. There is no evidence (so far) that this 820b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * was being used; however, png_set_background itself accepted and must still 821b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * accept '0' for the gamma value it takes, because it isn't always used. 822b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 823b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Since this is an API change (albeit a very minor one that removes an 824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * undocumented API feature) the following checks were only enabled in 825b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng-1.6.0. 826b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 827b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (file_gamma <= 0) 828b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid file gamma in png_set_gamma"); 829b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 830b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (scrn_gamma <= 0) 831b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid screen gamma in png_set_gamma"); 832b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 833b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Set the gamma values unconditionally - this overrides the value in the PNG 834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * file if a gAMA chunk was present. png_set_alpha_mode provides a 835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * different, easier, way to default the file gamma. 836b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 837b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = file_gamma; 838b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 839b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = scrn_gamma; 840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 841b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 842b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 843b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 844b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) 845b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 846b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), 8477a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis convert_gamma_value(png_ptr, file_gamma)); 848b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 8499b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett# endif /* FLOATING_POINT */ 850b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_GAMMA */ 851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB, expand grayscale images of 854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * less than 8-bit depth to 8-bit depth, and expand tRNS chunks 855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to alpha channels. 856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 858b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand(png_structrp png_ptr) 859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_expand"); 8615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8629b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 863a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR 19990627: the following three functions currently are identical 869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to png_set_expand(). However, it is entirely reasonable that someone 870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * might wish to expand an indexed image to RGB but *not* expand a single, 871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * fully transparent palette entry to a full alpha channel--perhaps instead 872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace 873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the transparent color with a particular RGB value, or drop tRNS entirely. 874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * IOW, a future version of the library may make the transformations flag 875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a bit more fine-grained, with separate bits for each of these three 876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * functions. 877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * More to the point, these functions make it obvious what libpng will be 879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * doing, whereas "expand" can (and does) mean any number of things. 880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 8815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified 8825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * to expand only the sample depth but not to expand the tRNS to alpha 8835f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * and its name was changed to png_set_expand_gray_1_2_4_to_8(). 884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB. */ 887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 888b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_palette_to_rgb(png_structrp png_ptr) 889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_palette_to_rgb"); 8915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8929b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 893a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 900b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) 901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 9024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); 9035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9049b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 905a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_EXPAND; 908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 910b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Expand tRNS chunks to alpha channels. */ 911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 912b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_tRNS_to_alpha(png_structrp png_ptr) 913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 914b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_tRNS_to_alpha"); 9155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9169b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 917a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 9219b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_EXPAND */ 922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 923b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 924b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise 925b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it may not work correctly.) 926b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 928b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand_16(png_structrp png_ptr) 929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 930b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_expand_16"); 9315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9329b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 933b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); 936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 937b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 941b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gray_to_rgb(png_structrp png_ptr) 942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 9434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_gray_to_rgb"); 9445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9459b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 0) == 0) 946b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 947b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 948b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Because rgb must be 8 bits or more: */ 949b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_expand_gray_1_2_4_to_8(png_ptr); 950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_GRAY_TO_RGB; 951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 955b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 956b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, 957b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point red, png_fixed_point green) 958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 9594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_rgb_to_gray"); 9605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 961b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Need the IHDR here because of the check on color_type below. */ 962b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: fix this */ 9639b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_rtran_ok(png_ptr, 1) == 0) 964a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9669b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett switch (error_action) 967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_NONE: 969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY; 970b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 971a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_WARN: 973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; 974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 975b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_ERROR: 977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; 978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 979a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 980b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 981b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid error action to rgb_to_gray"); 982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 983b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 9855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_EXPAND; 987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Make this an error in 1.6 because otherwise the application may assume 990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that it just worked and get a memory overwrite. 991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 992b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, 9937a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); 994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 995b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ 996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) 1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red_int, green_int; 1002b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: this calculation does not round, but this behavior is retained 10049b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * for consistency; the inaccuracy is very small. The code here always 1005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * overwrites the coefficients, regardless of whether they have been 1006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * defaulted or set already. 1007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); 1009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); 1010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_red_coeff = red_int; 1012b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_green_coeff = green_int; 1013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_coefficients_set = 1; 1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1018b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red >= 0 && green >= 0) 1019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_warning(png_ptr, 10207a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "ignoring out of range rgb_to_gray coefficients"); 1021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Use the defaults, from the cHRM chunk if set, else the historical 1023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See 1024b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_rgb_to_gray for more discussion of the values. In this case 1025b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the coefficients are not marked as 'set' and are not overwritten if 1026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * something has already provided a default. 1027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1028b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->rgb_to_gray_red_coeff == 0 && 10297a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->rgb_to_gray_green_coeff == 0) 1030b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1031b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_red_coeff = 6968; 1032b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_green_coeff = 23434; 1033b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ 1034b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1039b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_FLOATING_POINT_SUPPORTED 1040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Convert a RGB image to a grayscale of the same width. This allows us, 1041b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. 1042b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1043b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1044b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 1045b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, 10467a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis double green) 1047b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_rgb_to_gray_fixed(png_ptr, error_action, 10497a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_fixed(png_ptr, red, "rgb to gray red coefficient"), 1050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed(png_ptr, green, "rgb to gray green coefficient")); 1051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1052b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* FLOATING POINT */ 1053b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* RGB_TO_GRAY */ 1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 1057a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) 1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 1059b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr 1060b50c217251b086440efcdb273c22f86a06c80cbaChris Craik read_user_transform_fn) 1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 10624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_read_user_transform_fn"); 10635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 10645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_USER_TRANSFORM; 1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->read_user_transform_fn = read_user_transform_fn; 1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1072b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1073b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* In the case of gamma transformations only do transformations on images where 1074b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the [file] gamma and screen_gamma are not close reciprocals, otherwise it 1075b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * slows things down slightly, and also needlessly introduces small errors. 1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1077b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic int /* PRIVATE */ 1078b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) 1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1080b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma 1081b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correction as a difference of the overall transform from 1.0 1082b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1083b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * We want to compare the threshold with s*f - 1, if we get 1084b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * overflow here it is because of wacky gamma values so we 1085b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * turn on processing anyway. 1086b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1087b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point gtest; 1088b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || 1089b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_gamma_significant(gtest); 1090b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1093b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Initialize everything needed for the read. This includes modifying 1094b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the palette. 1095b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 10979b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett/* For the moment 'png_init_palette_transformations' and 1098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 'png_init_rgb_transformations' only do some flag canceling optimizations. 1099b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The intent is that these two routines should have palette or rgb operations 1100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * extracted from 'png_init_read_transformations'. 1101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1102b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic void /* PRIVATE */ 1103b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_palette_transformations(png_structrp png_ptr) 1104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Called to handle the (input) palette case. In png_do_read_transformations 1106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the first step is to expand the palette if requested, so this code must 1107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * take care to only make changes that are invariant with respect to the 1108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * palette expansion, or only do them if there is no expansion. 1109a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 1110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * STRIP_ALPHA has already been handled in the caller (by setting num_trans 1111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to 0.) 1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_alpha = 0; 1114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_transparency = 0; 1115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->num_trans > 0) 1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i; 1119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Ignore if all the entries are opaque (unlikely!) */ 1121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i=0; i<png_ptr->num_trans; ++i) 1122b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 255) 1124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik continue; 1125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->trans_alpha[i] == 0) 1126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik input_has_transparency = 1; 1127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1128b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1129b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari input_has_transparency = 1; 1130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik input_has_alpha = 1; 1131b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 1132b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1133b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If no alpha we can optimize. */ 11379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (input_has_alpha == 0) 1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Any alpha means background and associative alpha processing is 1140b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA 1141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and ENCODE_ALPHA are irrelevant. 1142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 11469b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (input_has_transparency == 0) 1147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_set_background handling - deals with the complexity of whether the 1152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color is in the file format or the screen format in the case 1153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * where an 'expand' will happen. 1154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following code cannot be entered in the alpha pre-multiplication case 1157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because PNG_BACKGROUND_EXPAND is cancelled below. 1158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 11599b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && 11609b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_EXPAND) != 0) 1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = 1164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].red; 1165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = 1166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].green; 1167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = 1168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].blue; 1169a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 11719b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) 1172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 11739b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) 1174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Invert the alpha channel (in tRNS) unless the pixels are 1176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * going to be expanded, in which case leave it for later 1177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i, istop = png_ptr->num_trans; 1179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i=0; i<istop; i++) 1181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i] = (png_byte)(255 - 1182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i]); 1183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 11859b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_INVERT_ALPHA */ 1186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* background expand and (therefore) no alpha association. */ 11889b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_EXPAND && READ_BACKGROUND */ 1189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1191b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic void /* PRIVATE */ 1192b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_rgb_transformations(png_structrp png_ptr) 1193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1194b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Added to libpng-1.5.4: check the color type to determine whether there 1195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is any alpha or transparency in the image and simply cancel the 1196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background and alpha mode stuff if there isn't. 1197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; 1199b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_transparency = png_ptr->num_trans > 0; 1200b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If no alpha we can optimize. */ 12029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (input_has_alpha == 0) 1203b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Any alpha means background and associative alpha processing is 1205b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA 1206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and ENCODE_ALPHA are irrelevant. 1207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1209b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1210b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1211b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1212b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 12139b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (input_has_transparency == 0) 1214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1216b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_set_background handling - deals with the complexity of whether the 1219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color is in the file format or the screen format in the case 1220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * where an 'expand' will happen. 1221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following code cannot be entered in the alpha pre-multiplication case 1224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because PNG_BACKGROUND_EXPAND is cancelled below. 1225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 12269b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && 12279b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_EXPAND) != 0 && 12289b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) 1229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* i.e., GRAY or GRAY_ALPHA */ 1230b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Expand background and tRNS chunks */ 1233b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gray = png_ptr->background.gray; 1234b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int trans_gray = png_ptr->trans_color.gray; 1235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1236b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (png_ptr->bit_depth) 1237b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case 1: 1239b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0xff; 1240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0xff; 1241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 1242b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1243b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case 2: 1244b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0x55; 1245b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0x55; 1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1247a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 1249b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0x11; 1250b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0x11; 1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1252a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1253b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 1254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 1256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* FALL THROUGH (Already 8 bits) */ 1257a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 1259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Already a full 16 bits */ 1260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = png_ptr->background.green = 1264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = (png_uint_16)gray; 1265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 12669b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) 1267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_color.red = png_ptr->trans_color.green = 1269b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_color.blue = (png_uint_16)trans_gray; 1270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* background expand and (therefore) no alpha association. */ 12739b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_EXPAND && READ_BACKGROUND */ 1274b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1275b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1276b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid /* PRIVATE */ 1277b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_read_transformations(png_structrp png_ptr) 1278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_init_read_transformations"); 1280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This internal function is called from png_read_start_row in pngrutil.c 1282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and it is called before the 'rowbytes' calculation is done, so the code 1283b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in here can change or update the transformations flags. 1284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * First do updates that do not depend on the details of the PNG image data 1286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * being processed. 1287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds 1291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode and this is another source for a default file gamma so 1292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the test needs to be performed later - here. In addition prior to 1.5.4 1293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the tests were repeated for the PALETTE color type here - this is no 1294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * longer necessary (and doesn't seem to have been necessary before.) 1295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following temporary indicates if overall gamma correction is 1298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * required. 1299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_correction = 0; 1301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->colorspace.gamma != 0) /* has been set */ 1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->screen_gamma != 0) /* screen set too */ 1305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, 13067a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->screen_gamma); 1307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Assume the output matches the input; a long time default behavior 1310b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of libpng, although the standard has nothing to say about this. 1311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); 1313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->screen_gamma != 0) 1316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The converse - assume the file matches the screen, note that this 1317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * perhaps undesireable default can (from 1.5.4) be changed by calling 1318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode (even if the alpha handling mode isn't required 1319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * or isn't changed from the default.) 1320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); 1322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* neither are set */ 1324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Just in case the following prevents any processing - file and screen 1325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * are both assumed to be linear and there is no way to introduce a 1326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * third gamma value other than png_set_background with 'UNIQUE', and, 1327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * prior to 1.5.4 1328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; 1330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1331b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We have a gamma value now. */ 1332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 1333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Now turn the gamma transformation on or off as appropriate. Notice 1335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that PNG_GAMMA just refers to the file->screen correction. Alpha 1336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * composition may independently cause gamma correction because it needs 1337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * linear data (e.g. if the file has a gAMA chunk but the screen gamma 1338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * hasn't been specified.) In any case this flag may get turned off in 1339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the code immediately below if the transform can be handled outside the 1340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * row loop. 1341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 13429b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (gamma_correction != 0) 1343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_GAMMA; 1344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1346b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_GAMMA; 1347b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Certain transformations have the effect of preventing other 13519b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * transformations that happen afterward in png_do_read_transformations; 1352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * resolve the interdependencies here. From the code of 1353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_read_transformations the order is: 1354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) 1356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2) PNG_STRIP_ALPHA (if no compose) 1357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 3) PNG_RGB_TO_GRAY 1358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY 1359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 5) PNG_COMPOSE 1360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 6) PNG_GAMMA 1361b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 7) PNG_STRIP_ALPHA (if compose) 1362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 8) PNG_ENCODE_ALPHA 1363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 9) PNG_SCALE_16_TO_8 1364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 10) PNG_16_TO_8 1365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 11) PNG_QUANTIZE (converts to palette) 1366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 12) PNG_EXPAND_16 1367b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY 1368b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 14) PNG_INVERT_MONO 1369b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 15) PNG_INVERT_ALPHA 1370b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 16) PNG_SHIFT 1371b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 17) PNG_PACK 1372b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 18) PNG_BGR 1373b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 19) PNG_PACKSWAP 1374b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 20) PNG_FILLER (includes PNG_ADD_ALPHA) 1375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 21) PNG_SWAP_ALPHA 1376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 22) PNG_SWAP_BYTES 1377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 23) PNG_USER_TRANSFORM [must be last] 1378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 13809b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && 13819b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_COMPOSE) == 0) 1382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Stripping the alpha channel happens immediately after the 'expand' 1384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * transformations, before all other transformation, so it cancels out 1385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the alpha handling. It has the side effect negating the effect of 1386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_EXPAND_tRNS too: 1387b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | 1389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_EXPAND_tRNS); 1390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen 1393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so transparency information would remain just so long as it wasn't 1394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * expanded. This produces unexpected API changes if the set of things 1395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that do PNG_EXPAND_tRNS changes (perfectly possible given the 1396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * documentation - which says ask for what you want, accept what you 1397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * get.) This makes the behavior consistent from 1.5.4: 1398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->num_trans = 0; 1400b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* STRIP_ALPHA supported, no COMPOSE */ 1402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA 1405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * settings will have no effect. 1406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 14079b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_gamma_significant(png_ptr->screen_gamma) == 0) 1408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1409b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1410b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Make sure the coefficients for the rgb to gray conversion are set 1416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * appropriately. 1417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 14189b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) 1419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_colorspace_set_rgb_coefficients(png_ptr); 1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1423b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Detect gray background and attempt to enable optimization for 1425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gray --> RGB case. 1426b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1427b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or 1428b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * RGB_ALPHA (in which case need_expand is superfluous anyway), the 1429b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color might actually be gray yet not be flagged as such. 1430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This is not a problem for the current code, which uses 1431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_BACKGROUND_IS_GRAY only to decide when to do the 1432b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_gray_to_rgb() transformation. 1433b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: this code needs to be revised to avoid the complexity and 1435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * interdependencies. The color type of the background should be recorded in 1436b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_background, along with the bit depth, then the code has a record 1437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of exactly what color space the background is currently in. 1438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 14399b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) 1440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if 1442b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the file was grayscale the background value is gray. 1443b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 14449b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) 1445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 14489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett else if ((png_ptr->transformations & PNG_COMPOSE) != 0) 1449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1450b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_COMPOSE: png_set_background was called with need_expand false, 1451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so the color is in the color space of the output or png_set_alpha_mode 1452b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * was called and the color is black. Ignore RGB_TO_GRAY because that 1453b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * happens before GRAY_TO_RGB. 1454b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 14559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) 1456b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1457b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->background.red == png_ptr->background.green && 1458b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red == png_ptr->background.blue) 1459b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1460b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1461b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = png_ptr->background.red; 1462b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1464b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 14659b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_EXPAND && READ_BACKGROUND */ 14669b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_GRAY_TO_RGB */ 1467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1468b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations 1469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * can be performed directly on the palette, and some (such as rgb to gray) 1470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * can be optimized inside the palette. This is particularly true of the 1471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * composite (background and alpha) stuff, which can be pretty much all done 1472b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in the palette even if the result is expanded to RGB or gray afterward. 1473b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1474b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and 1475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * earlier and the palette stuff is actually handled on the first row. This 1476b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * leads to the reported bug that the palette returned by png_get_PLTE is not 1477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * updated. 1478b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1479b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1480b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_init_palette_transformations(png_ptr); 1481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1482b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_init_rgb_transformations(png_ptr); 1484b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1485b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1486b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_EXPAND_16_SUPPORTED) 14879b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && 14889b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_COMPOSE) != 0 && 14899b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && 14909b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_ptr->bit_depth != 16) 1491b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: fix this. Because the expand_16 operation is after the compose 1493b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * handling the background color must be 8, not 16, bits deep, but the 1494b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * application will supply a 16-bit value so reduce it here. 1495b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at 1497b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * present, so that case is ok (until do_expand_16 is moved.) 1498b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1499b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this discards the low 16 bits of the user supplied background 1500b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * color, but until expand_16 works properly there is no choice! 1501b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1502b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) 1503b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.red); 1504b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.green); 1505b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.blue); 1506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.gray); 1507b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# undef CHOP 1508b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 15099b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_BACKGROUND && READ_EXPAND_16 */ 1510b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1511b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ 1513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) 15149b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && 15159b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_COMPOSE) != 0 && 15169b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && 15179b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_ptr->bit_depth == 16) 1518b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1519b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* On the other hand, if a 16-bit file is to be reduced to 8-bits per 1520b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * component this will also happen after PNG_COMPOSE and so the background 1521b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * color must be pre-expanded here. 1522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1523b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: fix this too. 1524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); 1526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = 1527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_16)(png_ptr->background.green * 257); 1528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); 1529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); 1530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1531b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 1532b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1533b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the 1534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background support (see the comments in scripts/pnglibconf.dfa), this 1535b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * allows pre-multiplication of the alpha channel to be implemented as 1536b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * compositing on black. This is probably sub-optimal and has been done in 1537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1.5.4 betas simply to enable external critique and testing (i.e. to 1538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * implement the new API quickly, without lots of internal changes.) 1539b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1540b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1541b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1542b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_BACKGROUND_SUPPORTED 1543b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Includes ALPHA_MODE */ 1544b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1 = png_ptr->background; 1545b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1546b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1547b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This needs to change - in the palette image case a whole set of tables are 1548b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * built when it would be quicker to just calculate the correct value for 1549b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * each palette entry directly. Also, the test is too tricky - why check 1550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that 1551b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the 1552b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction 1553b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the gamma tables will not be built even if composition is required on a 1554b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma encoded value. 1555b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * In 1.5.4 this is addressed below by an additional check on the individual 1557b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the 1558b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * tables. 1559b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 15609b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GAMMA) != 0 || 15619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && 15629b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || 15639b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_gamma_significant(png_ptr->screen_gamma) != 0)) || 15649b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett ((png_ptr->transformations & PNG_COMPOSE) != 0 && 15659b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || 15669b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_gamma_significant(png_ptr->screen_gamma) != 0 1567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_BACKGROUND_SUPPORTED 15689b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && 15699b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_gamma_significant(png_ptr->background_gamma) != 0) 1570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 15719b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && 15729b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_gamma_significant(png_ptr->screen_gamma) != 0)) 1573b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1574b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_build_gamma_table(png_ptr, png_ptr->bit_depth); 15755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 15765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 15779b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_COMPOSE) != 0) 1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Issue a warning about this combination: because RGB_TO_GRAY is 1580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * optimized to do the gamma transform if present yet do_background has 1581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to do the same thing if both options are set a 1582b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * double-gamma-correction happens. This is true in all versions of 1583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng to date. 1584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 15859b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) 1586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, 15877a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis "libpng does not support gamma+background+rgb_to_gray"); 1588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 15899b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) 1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We don't get to here unless there is a tRNS chunk with non-opaque 1592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * entries - see the checking code at the start of this function. 1593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color back, back_1; 1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_palette = png_ptr->num_palette; 1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) 1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = png_ptr->gamma_table[png_ptr->background.red]; 1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = png_ptr->gamma_table[png_ptr->background.green]; 1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = png_ptr->gamma_table[png_ptr->background.blue]; 1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; 1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; 1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; 1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1611b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point g, gs; 1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->background_gamma_type) 1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_SCREEN: 1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = (png_ptr->screen_gamma); 1617b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = PNG_FP_1; 1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1619a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_FILE: 1621b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->colorspace.gamma); 1622b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->colorspace.gamma, 16237a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->screen_gamma); 1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1625a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_UNIQUE: 1627b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->background_gamma); 1628b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->background_gamma, 16297a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->screen_gamma); 1630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 1632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = PNG_FP_1; /* back_1 */ 1633b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = PNG_FP_1; /* back */ 1634b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_gamma_significant(gs) != 0) 1638b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1639b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.red = png_gamma_8bit_correct(png_ptr->background.red, 1640b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1641b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.green = png_gamma_8bit_correct(png_ptr->background.green, 1642b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1643b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.blue = png_gamma_8bit_correct(png_ptr->background.blue, 1644b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1646b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1647b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = (png_byte)png_ptr->background.red; 1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = (png_byte)png_ptr->background.green; 1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = (png_byte)png_ptr->background.blue; 1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1653b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 16549b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_gamma_significant(g) != 0) 1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1656b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.red = png_gamma_8bit_correct(png_ptr->background.red, 16577a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis g); 1658b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.green = png_gamma_8bit_correct( 16597a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->background.green, g); 1660b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, 16617a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis g); 1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1665b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1666b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.red = (png_byte)png_ptr->background.red; 1667b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.green = (png_byte)png_ptr->background.green; 1668b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.blue = (png_byte)png_ptr->background.blue; 1669b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1671b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1674b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (i < (int)png_ptr->num_trans && 1675b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i] != 0xff) 1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1677b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 0) 1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = back; 1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1681b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* if (png_ptr->trans_alpha[i] != 0xff) */ 1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].red]; 1686b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); 1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_from_1[w]; 1688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].green]; 1690b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); 1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_from_1[w]; 1692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].blue]; 1694b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); 1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_from_1[w]; 1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_table[palette[i].red]; 1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_table[palette[i].green]; 1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1705b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1706b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Prevent the transformations being done again. 1707b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1708b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this is highly dubious; it removes the transformations in 1709b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * place. This seems inconsistent with the general treatment of the 1710b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * transformations elsewhere. 17115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 1712b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); 1713b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type == PNG_COLOR_TYPE_PALETTE */ 1714b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ 1716b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* color_type != PNG_COLOR_TYPE_PALETTE */ 1717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1718b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gs_sig, g_sig; 1719b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point g = PNG_FP_1; /* Correction to linear */ 1720b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point gs = PNG_FP_1; /* Correction to screen */ 1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->background_gamma_type) 1723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_SCREEN: 1725b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_ptr->screen_gamma; 1726b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* gs = PNG_FP_1; */ 1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1728a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_FILE: 1730b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->colorspace.gamma); 1731b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->colorspace.gamma, 17327a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_ptr->screen_gamma); 1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1734a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_UNIQUE: 1736b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->background_gamma); 1737b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->background_gamma, 1738b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1740b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1741b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 1742b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid background gamma type"); 1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g_sig = png_gamma_significant(g); 1746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs_sig = png_gamma_significant(gs); 1747b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 17489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (g_sig != 0) 1749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.gray = png_gamma_correct(png_ptr, 1750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray, g); 1751b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 17529b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (gs_sig != 0) 1753b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = png_gamma_correct(png_ptr, 1754b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray, gs); 1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->background.red != png_ptr->background.green) || 1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->background.red != png_ptr->background.blue) || 1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->background.red != png_ptr->background.gray)) 1759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* RGB or RGBA with color background */ 17619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (g_sig != 0) 1762b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1763b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.red = png_gamma_correct(png_ptr, 1764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red, g); 1765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1766b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.green = png_gamma_correct(png_ptr, 1767b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green, g); 1768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.blue = png_gamma_correct(png_ptr, 1770b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue, g); 1771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 17739b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (gs_sig != 0) 1774b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1775b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = png_gamma_correct(png_ptr, 1776b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red, gs); 1777b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1778b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = png_gamma_correct(png_ptr, 1779b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green, gs); 1780b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1781b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = png_gamma_correct(png_ptr, 1782b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue, gs); 1783b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1785b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ 1789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background_1.red = png_ptr->background_1.green 1790b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->background_1.blue = png_ptr->background_1.gray; 1791b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.red = png_ptr->background.green 1793b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->background.blue = png_ptr->background.gray; 1794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1795b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The background is now in screen gamma: */ 1797b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; 1798b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type != PNG_COLOR_TYPE_PALETTE */ 1799b50c217251b086440efcdb273c22f86a06c80cbaChris Craik }/* png_ptr->transformations & PNG_BACKGROUND */ 1800b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1802a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Transformation does not include PNG_BACKGROUND */ 18039b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_BACKGROUND */ 1804b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE 1805b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1806b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ 1807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && ((png_ptr->transformations & PNG_EXPAND) == 0 || 1808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) 1809b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 1810b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ) 1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_palette = png_ptr->num_palette; 1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: there are other transformations that should probably be in 1817b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * here too. 1818b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_table[palette[i].red]; 1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_table[palette[i].green]; 1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Done the gamma correction. */ 18275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->transformations &= ~PNG_GAMMA; 1828b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ 1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 18305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 1831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 18339b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_GAMMA */ 1834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 18355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 1836b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* No GAMMA transformation (see the hanging else 4 lines above) */ 18379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_COMPOSE) != 0 && 1838b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int istop = (int)png_ptr->num_trans; 1842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color back; 1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = (png_byte)png_ptr->background.red; 1846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = (png_byte)png_ptr->background.green; 1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = (png_byte)png_ptr->background.blue; 1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < istop; i++) 1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1851b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 0) 1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = back; 1854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1855b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1856b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->trans_alpha[i] != 0xff) 1857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* The png_composite() macro is defined in png.h */ 1859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].red, palette[i].red, 1860b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.red); 1861b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].green, palette[i].green, 1863b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.green); 1864b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].blue, palette[i].blue, 1866b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.blue); 1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1870b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_COMPOSE; 1871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 18729b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_BACKGROUND */ 1873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SHIFT_SUPPORTED 18759b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SHIFT) != 0 && 18769b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_EXPAND) == 0 && 1877b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1879b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i; 1880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int istop = png_ptr->num_palette; 1881b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int shift = 8 - png_ptr->sig_bit.red; 1882b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1883b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_SHIFT; 1884b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1885b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* significant bits can be in the range 1 to 7 for a meaninful result, if 1886b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the number of significant bits is 0 then no shift is done (this is an 1887b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error condition which is silently ignored.) 1888b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1889b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1890b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1891b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1892b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].red; 1893b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1894b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1895b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].red = (png_byte)component; 1896b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1897b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1898b50c217251b086440efcdb273c22f86a06c80cbaChris Craik shift = 8 - png_ptr->sig_bit.green; 1899b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1900b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1901b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1902b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].green; 1903b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1904b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1905b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].green = (png_byte)component; 1906b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1907b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1908b50c217251b086440efcdb273c22f86a06c80cbaChris Craik shift = 8 - png_ptr->sig_bit.blue; 1909b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1910b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1911b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1912b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].blue; 1913b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1914b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1915b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].blue = (png_byte)component; 1916b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 19187a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* READ_SHIFT */ 1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Modify the info structure to reflect the transformations. The 1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * info should be updated so a PNG file could be written with it, 1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * assuming the transformations result in valid PNG data. 1924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1926b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) 1927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 19284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_read_transform_info"); 19295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 19305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 19319b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND) != 0) 1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This check must match what actually happens in 1936b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_expand_palette; if it ever checks the tRNS chunk to see if 1937b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it is all opaque we must do the same (at present it does not.) 1938b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1939b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->num_trans > 0) 1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 1941b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_RGB; 1944b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->num_trans = 0; 1947b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 1948b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->palette == NULL) 1949b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error (png_ptr, "Palette is NULL in indexed image"); 1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 19539b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->num_trans != 0) 1954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 19559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) 1956b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->bit_depth < 8) 1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 1960b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->num_trans = 0; 1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 1967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_ALPHA_MODE_SUPPORTED) 1968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following is almost certainly wrong unless the background value is in 1969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the screen space! 1970b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 19719b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_COMPOSE) != 0) 1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->background = png_ptr->background; 1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 1976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), 1977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * however it seems that the code in png_init_read_transformations, which has 1978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * been called before this from png_read_update_info->png_read_start_row 1979b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * sometimes does the gamma transform and cancels the flag. 1980b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1981b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: this looks wrong; the info_ptr should end up with a gamma equal to 1982b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the screen_gamma value. The following probably results in weirdness if 1983b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the info_ptr is used by the app after the rows have been read. 1984b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1985b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; 1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1988b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (info_ptr->bit_depth == 16) 1989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_16BIT_SUPPORTED 1991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 19929b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) 1993b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 1994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1995b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1996b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 19979b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_16_TO_8) != 0) 1998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 1999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 2000b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 20029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett /* No 16-bit support: force chopping 16-bit input down to 8, in this case 2003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the app program can chose if both APIs are available by setting the 2004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correct scaling to use. 2005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* For compatibility with previous versions use the strip method by 2008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * default. This code works because if PNG_SCALE_16_TO_8 is already 2009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * set the code below will do that in preference to the chop. 2010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_16_TO_8; 2012b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 2013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 2014b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_SCALE_16_TO_8; 2017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 2018b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 2019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CONFIGURATION ERROR: you must enable at least one 16 to 8 method 2021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 2022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 20239b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* !READ_16BIT */ 2024b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 20279b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) 2028b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type | 2029b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_COLOR_MASK_COLOR); 2030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 20339b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) 2034b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type & 2035b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_COLOR); 2036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_QUANTIZE_SUPPORTED 20399b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_QUANTIZE) != 0) 2040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 2042a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && 20439b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) 2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; 2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 20519b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && 20529b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett info_ptr->bit_depth == 8 && 20539b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 2054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2055b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 16; 2056b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2057b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2058b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 20595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED 20609b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_PACK) != 0 && 20619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (info_ptr->bit_depth < 8)) 2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 2063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 1; 2067b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 20689b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) 2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 3; 2070b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 1; 2073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 20759b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) 2076b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2077b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type & 2078b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_ALPHA); 2079b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->num_trans = 0; 2080b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20839b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) 2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels++; 2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ 20889b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_FILLER) != 0 && 20899b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (info_ptr->color_type == PNG_COLOR_TYPE_RGB || 20909b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) 2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels++; 2093a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* If adding a true alpha channel not just filler */ 20949b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) 2095b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ 2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_READ_USER_TRANSFORM_SUPPORTED) 21019b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) 2102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 21039b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->user_transform_depth != 0) 2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = png_ptr->user_transform_depth; 2105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 21069b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->user_transform_channels != 0) 2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = png_ptr->user_transform_channels; 2108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->pixel_depth = (png_byte)(info_ptr->channels * 2112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth); 2113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); 2115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Adding in 1.5.4: cache the above value in png_struct so that we can later 2117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * check in png_rowbytes that the user buffer won't get overwritten. Note 2118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that the field is not always set - if png_read_update_info isn't called 2119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the application has to either not do any transforms or get the calculation 2120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * right itself. 2121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->info_rowbytes = info_ptr->rowbytes; 2123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 21245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_EXPAND_SUPPORTED 21259b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr != NULL) 2126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2130b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACK_SUPPORTED 2131b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, 2132b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * without changing the actual values. Thus, if you had a row with 2133b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * a bit depth of 1, you would end up with bytes that only contained 2134b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * the numbers 0 or 1. If you would rather they contain 0 and 255, use 2135b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_do_shift() after this. 2136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 2137b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2138b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_unpack(png_row_infop row_info, png_bytep row) 2139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2140b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_unpack"); 2141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2142b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->bit_depth < 8) 2143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2144b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 i; 2145b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 row_width=row_info->width; 2146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2147b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari switch (row_info->bit_depth) 2148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2149b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 1: 2150b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2151b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); 2152b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2153851c67770f9cebece9c79e914a54c348f539a512Matt Sarett png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); 2154b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2155b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2156b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x01); 2157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2158b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 7) 2159b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2160b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2161b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2162b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2164b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2165b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift++; 2166b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2167b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2168b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2169b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2170b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2171b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2172b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 2: 2173b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2174b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2175b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); 2176b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2177851c67770f9cebece9c79e914a54c348f539a512Matt Sarett png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 2178b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2179b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2180b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x03); 2181b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2182b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 6) 2183b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2184b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2185b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2186b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2187b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2188b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2189b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift += 2; 2190b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2191b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2192b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2193b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2194b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2195b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2196b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 4: 2197b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2198b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); 2199b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2200851c67770f9cebece9c79e914a54c348f539a512Matt Sarett png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 2201b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2202b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2203b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x0f); 2204b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2205b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 4) 2206b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2207b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2208b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2209b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2210b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2211b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2212b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 4; 2213b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2214b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2215b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2216b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2217b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2218b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2219b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari default: 2220b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2222b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->bit_depth = 8; 2223b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2224b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = row_width * row_info->channels; 2225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2226b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari} 2227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2229b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SHIFT_SUPPORTED 2230b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Reverse the effects of png_do_shift. This routine merely shifts the 2231b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * pixels back to their significant bits values. Thus, if you have 2232b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * a row of bit depth 8, but only 5 are significant, this will shift 2233b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * the values back to 0 through 31. 2234b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 2235b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2236b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_unshift(png_row_infop row_info, png_bytep row, 2237b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_const_color_8p sig_bits) 2238b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 2239b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int color_type; 2240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2241b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_unshift"); 2242b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2243b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* The palette case has already been handled in the _init routine. */ 2244b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari color_type = row_info->color_type; 2245b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2246b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (color_type != PNG_COLOR_TYPE_PALETTE) 2247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2248b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int shift[4]; 2249b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int channels = 0; 2250b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int bit_depth = row_info->bit_depth; 2251b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 22529b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((color_type & PNG_COLOR_MASK_COLOR) != 0) 2253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2254b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->red; 2255b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->green; 2256b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->blue; 2257b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2259b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2260b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2261b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->gray; 2262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22649b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) 2265b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2266b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->alpha; 2267b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2269b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2270b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int c, have_shift; 2271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2272b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (c = have_shift = 0; c < channels; ++c) 2273b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2274b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* A shift of more than the bit depth is an error condition but it 2275b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * gets ignored here. 2276b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 2277b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift[c] <= 0 || shift[c] >= bit_depth) 2278b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[c] = 0; 2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik have_shift = 1; 2282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22849b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (have_shift == 0) 2285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 2286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (bit_depth) 2289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 2291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 1bpp gray: should not be here! */ 2292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTREACHED */ 2293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 2294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 2296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 2bpp gray */ 2297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* assert(channels == 1 && shift[0] == 1) */ 2298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp = row; 2300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (*bp >> 1) & 0x55; 2305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2309a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 2311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 4bpp gray */ 2312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* assert(channels == 1) */ 2313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gray_shift = shift[0]; 2317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int mask = 0xf >> gray_shift; 2318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik mask |= mask << 4; 2320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (*bp >> gray_shift) & mask; 2324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2328a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 2330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Single byte components, G, GA, RGB, RGBA */ 2331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int channel = 0; 2335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = *bp >> shift[channel]; 2339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (++channel >= channels) 2340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik channel = 0; 2341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2345a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2346b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 2348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Double byte components, G, GA, RGB, RGBA */ 2349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int channel = 0; 2353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int value = (bp[0] << 8) + bp[1]; 2357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik value >>= shift[channel]; 2359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (++channel >= channels) 2360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik channel = 0; 2361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *bp++ = (png_byte)(value >> 8); 23629b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *bp++ = (png_byte)value; 2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Scale rows of bit depth 16 down to 8 accurately */ 2374b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2375b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_scale_16_to_8(png_row_infop row_info, png_bytep row) 2376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_scale_16_to_8"); 23785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 16) 2380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; /* source */ 2382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; /* destination */ 2383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (sp < ep) 2386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 23879b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett /* The input is an array of 16-bit components, these must be scaled to 23889b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * 8 bits each. For a 16-bit value V the required value (from the PNG 2389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * specification) is: 2390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (V * 255) / 65535 2392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This reduces to round(V / 257), or floor((V + 128.5)/257) 2394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Represent V as the two byte value vhi.vlo. Make a guess that the 2396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * result is the top byte of V, vhi, then the correction to this value 2397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is: 2398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = floor(((V-vhi.vhi) + 128.5) / 257) 2400b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * = floor(((vlo-vhi) + 128.5) / 257) 2401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This can be approximated using integer arithmetic (and a signed 2403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * shift): 2404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = (vlo-vhi+128) >> 8; 2406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The approximate differs from the exact answer only when (vlo-vhi) is 2408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 128; it then gives a correction of +1 when the exact correction is 24099b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * 0. This gives 128 errors. The exact answer (correct for all 16-bit 2410b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * input values) is: 2411b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2412b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = (vlo-vhi+128)*65535 >> 24; 2413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * An alternative arithmetic calculation which also gives no errors is: 2415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (V * 255 + 32895) >> 16 2417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_int_32 tmp = *sp++; /* must be signed! */ 2420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; 2421b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp++ = (png_byte)tmp; 2422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2423b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth = 8; 2425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2426b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->rowbytes = row_info->width * row_info->channels; 2427b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2428b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 2429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2432b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2433b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Simply discard the low byte. This was the default behavior prior 2434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to libpng-1.5.4. 2435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2436b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_chop(png_row_infop row_info, png_bytep row) 2437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 2438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_chop"); 2439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 16) 2441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2442b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; /* source */ 2443b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; /* destination */ 2444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2446b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (sp < ep) 2447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp++ = *sp; 2449b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp += 2; /* skip low byte */ 2450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_info->width * row_info->channels; 2455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 24595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 2460b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row) 2462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 24634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_swap_alpha"); 24645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from RGBA to ARGB */ 2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save; 2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save = *(--sp); 2480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save; 2484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2486b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from RRGGBBAA to AARRGGBB */ 2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save[2]; 2494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[0] = *(--sp); 2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[1] = *(--sp); 2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[0]; 2507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[1]; 2508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2510b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from GA to AG */ 2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save; 2521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save = *(--sp); 2526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save; 2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2531b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from GGAA to AAGG */ 2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save[2]; 2538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[0] = *(--sp); 2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[1] = *(--sp); 2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[0]; 2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[1]; 2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 25565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 2557b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row) 2559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width; 25614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_invert_alpha"); 25625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_width = row_info->width; 2564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 2567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in RGBA */ 2569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2573b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2574b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This does nothing: 2578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik We can replace it with: 2582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=3; 2584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This inverts the alpha channel in RRGGBBAA */ 2590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2596b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2597b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2599b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This does nothing: 2602b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2603b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2604b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2605b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2606b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2607b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2608b50c217251b086440efcdb273c22f86a06c80cbaChris Craik We can replace it with: 2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2610b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=6; 2611b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2614b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2615b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2616b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2617b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2618b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 2619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in GA */ 2621b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2622b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2623b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2627b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2628b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2630b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2631b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2633b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2634b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in GGAA */ 2636b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2637b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2638b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2640b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2641b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2642b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2643b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* 2645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2646b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2648b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=2; 2649b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2652b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Add filler channel if we have RGB color */ 2659b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_filler(png_row_infop row_info, png_bytep row, 2661b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 filler, png_uint_32 flags) 2662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2666b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 26679b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_byte hi_filler = (png_byte)(filler>>8); 2668b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 26699b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_byte lo_filler = (png_byte)filler; 2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_filler"); 26725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ( 2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type == PNG_COLOR_TYPE_GRAY) 2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 26764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (row_info->bit_depth == 8) 2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 26789b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2680b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from G to GX */ 2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width; 2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 16; 2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 2; 2692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2693b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2696b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from G to XG */ 2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width; 2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 16; 2706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 2; 2707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2709b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2710b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 27114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project else if (row_info->bit_depth == 16) 2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 27139b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2715b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from GG to GGXX */ 2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2; 2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 27219b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 27269b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2731b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2734b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from GG to XXGG */ 2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2; 2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 27429b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } /* COLOR_TYPE == GRAY */ 2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_RGB) 2752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 27534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (row_info->bit_depth == 8) 2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 27559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2757b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RGB to RGBX */ 2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 3; 2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2775b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RGB to XRGB */ 2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 3; 2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2790b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2791b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 27924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project else if (row_info->bit_depth == 16) 2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 27949b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RRGGBB to RRGGBBXX */ 2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 6; 2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 28029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 28119b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 64; 2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 8; 2815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2819b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RRGGBB to XXRRGGBB */ 2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 6; 2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 28319b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(--dp) = hi_filler; 2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2833b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 64; 2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 8; 2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2839b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } /* COLOR_TYPE == RGB */ 2841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2845a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Expand grayscale files to RGB, with or without alpha */ 2846b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row) 2848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_gray_to_rgb"); 28535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth >= 8 && 28559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) 2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2861b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes G to RGB */ 2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width - 1; 2863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2871b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2874b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GG to RRGGBB */ 2875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2 - 1; 2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 4; 2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2888b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2893b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GA to RGBA */ 2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2 - 1; 2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2904b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2907b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GGAA to RRGGBBAA */ 2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 4 - 1; 2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 4; 2910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2923b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->channels = (png_byte)(row_info->channels + 2); 2924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type |= PNG_COLOR_MASK_COLOR; 2925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->channels * 2926b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth); 29274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 2928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 29325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2933a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Reduce RGB files to grayscale, with or without alpha 2934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * using the equation given in Poynton's ColorFAQ of 1998-01-04 at 2935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but 2936b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * versions dated 1998 through November 2002 have been archived at 2937b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ 2938b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) 29394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Charles Poynton poynton at poynton.com 2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B 2942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2943b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * which can be expressed with integers as 2944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2945b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6969 * R + 23434 * G + 2365 * B)/32768 2946b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2947b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Poynton's current link (as of January 2003 through July 2011): 2948b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * <http://www.poynton.com/notes/colour_and_gamma/> 2949b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * has changed the numbers slightly: 2950b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2951b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = 0.2126*R + 0.7152*G + 0.0722*B 2952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * which can be expressed with integers as 2954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2955b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6966 * R + 23436 * G + 2366 * B)/32768 2956b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2957b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 2958b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * end point chromaticities and the D65 white point. Depending on the 2959b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * precision used for the D65 white point this produces a variety of different 2960b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * numbers, however if the four decimal place value used in ITU-R Rec 709 is 2961b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * used (0.3127,0.3290) the Y calculation would be: 2962b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2963b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6968 * R + 23435 * G + 2366 * B)/32768 2964b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2965b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * While this is correct the rounding results in an overflow for white, because 2966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the sum of the rounded coefficients is 32769, not 32768. Consequently 2967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng uses, instead, the closest non-overflowing approximation: 2968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6968 * R + 23434 * G + 2366 * B)/32768 2970b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2971b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk 2972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (including an sRGB chunk) then the chromaticities are used to calculate the 2973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * coefficients. See the chunk handling in pngrutil.c for more information. 2974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2975b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * In all cases the calculation is to be done in a linear colorspace. If no 2976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma information is available to correct the encoding of the original RGB 2977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values this results in an implicit assumption that the original PNG RGB 2978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values were linear. 2979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2980b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Other integer coefficents can be used via png_set_rgb_to_gray(). Because 2981b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the API takes just red and green coefficients the blue coefficient is 2982b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * calculated to make the sum 32768. This will result in different rounding 2983b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to that used above. 2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 2985b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic int 2986b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) 2987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int rgb_error = 0; 2990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 29914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_rgb_to_gray"); 29925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 29939b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && 29949b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) 2995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2996b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; 2997b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; 2998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 bc = 32768 - rc - gc; 2999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 row_width = row_info->width; 3000b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int have_alpha = 3001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; 3002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 3004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 3006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Notice that gamma to/from 1 are not necessarily inverses (if 3007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * there is an overall gamma correction). Prior to 1.5.5 this code 3008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * checked the linearized values for equality; this doesn't match 3009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the documentation, the original values must be checked. 3010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3014b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = *(sp++); 3020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = *(sp++); 3021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = *(sp++); 3022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3025b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = png_ptr->gamma_to_1[red]; 3026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green = png_ptr->gamma_to_1[green]; 3027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik blue = png_ptr->gamma_to_1[blue]; 3028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3029b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3030b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = png_ptr->gamma_from_1[ 3031b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (rc*red + gc*green + bc*blue + 16384)>>15]; 3032b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3034b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3035b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3036b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If there is no overall correction the table will not be 3037b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * set. 3038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3039b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_table != NULL) 3040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = png_ptr->gamma_table[red]; 3041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3042b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = red; 3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3044b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 30459b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (have_alpha != 0) 3046b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3049b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3052b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3053b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3055b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3056b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3058b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = *(sp++); 3059b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = *(sp++); 3060b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = *(sp++); 3061b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3062b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3064b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3065b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: this is the historical approach which simply 3066b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * truncates the results. 3067b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3068b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 3069b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3072b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = red; 3073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 30749b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (have_alpha != 0) 3075b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3079b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3080b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* RGB bit_depth == 16 */ 3081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3082b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 3083b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) 3084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3085b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3086b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3087b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3088b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3089b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3091b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red, green, blue, w; 30929b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_byte hi,lo; 3093b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 30949b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); 30959b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); 30969b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); 3097b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red == green && red == blue) 3099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_16_table != NULL) 31019b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = png_ptr->gamma_16_table[(red & 0xff) 31029b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett >> png_ptr->gamma_shift][red >> 8]; 3103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = red; 3106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 31109b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) 3111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik >> png_ptr->gamma_shift][red>>8]; 3112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 green_1 = 31139b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_ptr->gamma_16_to_1[(green & 0xff) >> 3114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->gamma_shift][green>>8]; 31159b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) 3116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik >> png_ptr->gamma_shift][blue>>8]; 3117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 3118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + bc*blue_1 + 16384)>>15); 31199b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> 3120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->gamma_shift][gray16 >> 8]; 3121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)((w>>8) & 0xff); 3125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)(w & 0xff); 3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 31279b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (have_alpha != 0) 3128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp++) = *(sp++); 3131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3137b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red, green, blue, gray16; 31449b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_byte hi,lo; 3145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 31469b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); 31479b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); 31489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); 3149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 31539b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett /* From 1.5.5 in the 16-bit case do the accurate conversion even 3154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in the 'fast' case - this is because this is where the code 31559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * ends up when handling linear 16-bit data. 3156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 3158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 15); 31599b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett *(dp++) = (png_byte)((gray16 >> 8) & 0xff); 3160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)(gray16 & 0xff); 3161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 31629b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (have_alpha != 0) 3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp++) = *(sp++); 3166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->channels = (png_byte)(row_info->channels - 2); 3172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->color_type = (png_byte)(row_info->color_type & 3173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_COLOR); 3174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->channels * 3175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth); 31764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 3177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return rgb_error; 3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 3180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 3183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_ALPHA_MODE_SUPPORTED) 3184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Replace any alpha or transparency with the supplied background color. 3185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "background" is already in the screen gamma, while "background_1" is 3186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * at a gamma of 1.0. Paletted files have already been taken care of. 3187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 3188b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 3189b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 31915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3192b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_table = png_ptr->gamma_table; 3193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; 3194b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; 3195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; 3196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; 3197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; 3198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_shift = png_ptr->gamma_shift; 3199b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; 3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3202b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp; 3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 3204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width = row_info->width; 3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift; 3206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_compose"); 32085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->color_type) 3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 3217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7; 3220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x01) 3223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); 3226851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= png_ptr->background.gray << shift; 3227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 32309b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (shift == 0) 3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7; 3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift--; 3238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3241a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 3243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 32445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x03) 3252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3255851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= png_ptr->background.gray << shift; 3256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int p = (*sp >> shift) & 0x03; 3262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int g = (gamma_table [p | (p << 2) | 3263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (p << 4) | (p << 6)] >> 6) & 0x03; 3264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3265851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= g << shift; 3266b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 32699b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (shift == 0) 3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3274b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 2; 3277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x03) 3288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3291851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= png_ptr->background.gray << shift; 3292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 32959b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (shift == 0) 3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 2; 3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3307a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x0f) 3318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33209b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3321851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= png_ptr->background.gray << shift; 3322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int p = (*sp >> shift) & 0x0f; 3328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 3329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 0x0f; 33309b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3331851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= g << shift; 3332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 33359b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (shift == 0) 3336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 4; 3343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x0f) 3354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33569b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3357851c67770f9cebece9c79e914a54c348f539a512Matt Sarett tmp |= png_ptr->background.gray << shift; 3358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 33619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (shift == 0) 3362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 4; 3369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3373a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp++) 3381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.gray) 3383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp++) 3394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.gray) 3396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3401a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 3403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 34045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL) 3406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 2) 3409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (v == png_ptr->trans_color.gray) 3415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3416a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray 3420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 2) 3436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (v == png_ptr->trans_color.gray) 3442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3443b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray 3446b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3452b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3453b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 3454b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 3455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3458a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB: 3460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 34635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 3) 3468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.red && 3470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) == png_ptr->trans_color.green && 3471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) == png_ptr->trans_color.blue) 3472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3473b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3474b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = gamma_table[*(sp + 1)]; 3482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 2) = gamma_table[*(sp + 2)]; 3483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 3) 3491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.red && 3493b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) == png_ptr->trans_color.green && 3494b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) == png_ptr->trans_color.blue) 3495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3497b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3498b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 35055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL) 3507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 6) 3510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3514b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3515b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3516b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3517b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 5)); 3518b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3519b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (r == png_ptr->trans_color.red && 3520b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g == png_ptr->trans_color.green && 3521b50c217251b086440efcdb273c22f86a06c80cbaChris Craik b == png_ptr->trans_color.blue) 3522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3523a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3531b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3532b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3540b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 3) = (png_byte)(v & 0xff); 3544b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 5) = (png_byte)(v & 0xff); 3548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3551b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 6) 3557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3558b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 5)); 3565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (r == png_ptr->trans_color.red && 3567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g == png_ptr->trans_color.green && 3568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik b == png_ptr->trans_color.blue) 3569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3572b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3573b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3574b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3576b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3585a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 3587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 35905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_table != NULL) 3593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 2) 3596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = *(sp + 1); 3598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == 0xff) 3600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = gamma_table[*sp]; 3601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3604a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3605b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3607b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 3611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*sp]; 3613b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.gray); 36149b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) 3615b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_from_1[w]; 3616b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = w; 3617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3624b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 2) 3625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 1); 3627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3628b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3629b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3630b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3631b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xff) 3632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*sp, *sp, a, png_ptr->background.gray); 3633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (png_ptr->bit_depth == 16) */ 3637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 36385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_16_to_1 != NULL) 3641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3643b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3646b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == (png_uint_16)0xffff) 3649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3653b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3654b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3656b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3659a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3660b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3661b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3662b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g, v, w; 3668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3670b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background_1.gray); 36719b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize != 0) 3672b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = v; 3673b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 36749b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = gamma_16_from_1[(v & 0xff) >> 36759b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett gamma_shift][v >> 8]; 3676b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((w >> 8) & 0xff); 3677b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(w & 0xff); 3678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3685b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3687b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3688b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3689b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3690b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3692b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3693b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3694b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3696b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3697b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xffff) 3698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g, v; 3700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3702b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background.gray); 3703b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3704b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3711a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 3713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 37165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_table != NULL) 3719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3721b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 3); 3724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == 0xff) 3726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3727b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = gamma_table[*sp]; 3728b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = gamma_table[*(sp + 1)]; 3729b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = gamma_table[*(sp + 2)]; 3730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3731b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3734a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3735b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3736b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3737b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3739b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 3743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*sp]; 3745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.red); 37469b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) w = gamma_from_1[w]; 3747b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = w; 3748b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*(sp + 1)]; 3750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.green); 37519b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) w = gamma_from_1[w]; 3752b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = w; 3753b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*(sp + 2)]; 3755b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.blue); 37569b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) w = gamma_from_1[w]; 3757b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = w; 3758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 3); 3768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3773b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3775b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3776b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xff) 3777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3778b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*sp, *sp, a, png_ptr->background.red); 3779b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3780b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*(sp + 1), *(sp + 1), a, 3781b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green); 3782b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3783b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*(sp + 2), *(sp + 2), a, 3784b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue); 3785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 37915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_16_to_1 != NULL) 3794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 8) 3797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project << 8) + (png_uint_16)(*(sp + 7))); 3800b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == (png_uint_16)0xffff) 3802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3806b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3810b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3811b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(v & 0xff); 3812b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3814b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(v & 0xff); 3816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3817b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3820a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3821b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3822b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3823b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3825b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3826b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3827b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3828b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3829b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3831b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 v, w; 3835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3837b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.red); 38389b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) 38399b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3840b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3841b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((w >> 8) & 0xff); 3842b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(w & 0xff); 3843b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3845b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.green); 38469b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) 38479b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3848b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3849b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3850b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((w >> 8) & 0xff); 3851b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(w & 0xff); 3852b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3854b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.blue); 38559b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (optimize == 0) 38569b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3857b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3858b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3859b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((w >> 8) & 0xff); 3860b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(w & 0xff); 3861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3864b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3869b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 8) 3870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3872b50c217251b086440efcdb273c22f86a06c80cbaChris Craik << 8) + (png_uint_16)(*(sp + 7))); 3873b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3874b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3876b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3877b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3878b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3879b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3881b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3882b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3883b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3884b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3886b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3887b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xffff) 3888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project + *(sp + 3)); 3894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project + *(sp + 5)); 3896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3897b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, r, a, png_ptr->background.red); 3898b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3899b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3901b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background.green); 3902b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3903b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(v & 0xff); 3904b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3905b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, b, a, png_ptr->background.blue); 3906b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3907b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(v & 0xff); 3908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3915b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 3916b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 3917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 39209b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ 3921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 39225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Gamma correct the image, avoiding the alpha channel. Make sure 3924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * you do this after you deal with the transparency issue on grayscale 3925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * or RGB images. If your bit depth is 8, use gamma_table, if it 3926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * is 16, use gamma_16_table and gamma_shift. Build these with 3927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * build_gamma_table(). 3928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 3929b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 3930b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 3932b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_table = png_ptr->gamma_table; 3933b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; 3934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_shift = png_ptr->gamma_shift; 3935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp; 3937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 3938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 3939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 39404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_gamma"); 39415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3942b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (((row_info->bit_depth <= 8 && gamma_table != NULL) || 3943b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->bit_depth == 16 && gamma_16_table != NULL))) 3944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->color_type) 3946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB: 3948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3962b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3979b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3988a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 3990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 4010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4018b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 4; 4028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4032a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 4034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4044b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 4046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 4; 4054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4058a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 4060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 2) 4062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i += 4) 4065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int a = *sp & 0xc0; 4067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int b = *sp & 0x30; 4068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int c = *sp & 0x0c; 4069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d = *sp & 0x03; 4070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)( 40725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| 40735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| 40745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| 40755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); 4076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4079a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 4) 4081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i += 2) 4084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int msb = *sp & 0xf0; 4086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int lsb = *sp & 0x0f; 4087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) 40895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); 4090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4093a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 8) 4095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4103a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 4123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 4124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Encode the alpha channel to the output gamma (the input channel is always 4127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * linear.) Called only with color types that have an alpha channel. Needs the 4128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * from_1 tables. 4129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4130b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4131b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 4132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 4133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width = row_info->width; 4134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_encode_alpha"); 4136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 41379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) 4138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 4140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_bytep table = png_ptr->gamma_from_1; 4142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (table != NULL) 4144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int step = 4146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; 4147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The alpha channel is the last component: */ 4149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row += step - 1; 4150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (; row_width > 0; --row_width, row += step) 4152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *row = table[*row]; 4153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 4155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (row_info->bit_depth == 16) 4159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; 4161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int gamma_shift = png_ptr->gamma_shift; 4162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (table != NULL) 4164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int step = 4166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; 4167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The alpha channel is the last component: */ 4169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row += step - 2; 4170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (; row_width > 0; --row_width, row += step) 4172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 v; 4174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik v = table[*(row + 1) >> gamma_shift][*row]; 4176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *row = (png_byte)((v >> 8) & 0xff); 4177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(row + 1) = (png_byte)(v & 0xff); 4178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 4181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4185b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Only get to here if called with a weird row_info; no harm has been done, 4186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so just issue a warning. 4187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); 4189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 41925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 4193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expands a palette row to an RGB or RGBA row depending 4194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * upon whether you supply trans and num_trans. 4195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 4196b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand_palette(png_row_infop row_info, png_bytep row, 41987a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) 4199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 4200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift, value; 4201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp, dp; 4202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 4203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 4204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 42054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_expand_palette"); 42065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth < 8) 4210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 4212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 4214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 3); 4216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7 - (int)((row_width + 7) & 0x07); 4218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((*sp >> shift) & 0x01) 4221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 1; 4222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0; 4225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 7) 4227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift++; 4234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4239a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 4241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 2); 4243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x03; 4248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)value; 4249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 6) 4250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 2; 4257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4262a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 4264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 1); 4266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((row_width & 0x01) << 2); 4268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x0f; 4271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)value; 4272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 4) 4273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 4; 4280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 8; 4291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width; 4292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 4295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (num_trans > 0) 4298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 2) - 1; 4301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((int)(*sp) >= num_trans) 4305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4306b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp-- = trans_alpha[*sp]; 4309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].blue; 4311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].green; 4312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].red; 4313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 4317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 4318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = 6; 4319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 4320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width * 3) - 1; 4326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].blue; 4330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].green; 4331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].red; 4332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4334a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 24; 4337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 3; 4338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = 2; 4339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 3; 4340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* If the bit depth < 8, it is expanded to 8. Also, if the already 4347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * expanded transparency value is supplied, an alpha channel is built. 4348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 4349b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand(png_row_infop row_info, png_bytep row, 4351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p trans_color) 4352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 4353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift, value; 4354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp, dp; 4355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 4356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 4357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 43584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_expand"); 43595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 4362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 43639b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett unsigned int gray = trans_color != NULL ? trans_color->gray : 0; 4364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth < 8) 4366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 4368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 4370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4371b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x01) * 0xff; 4372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 3); 4373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7 - (int)((row_width + 7) & 0x07); 4375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((*sp >> shift) & 0x01) 4378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0xff; 4379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0; 4382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 7) 4384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift++; 4391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4396a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 4398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x03) * 0x55; 4400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 2); 4401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x03; 4406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)(value | (value << 2) | (value << 4) | 4407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (value << 6)); 4408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 6) 4409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 2; 4416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4421a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 4423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x0f) * 0x11; 4425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 1); 4426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 4428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x0f; 4431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)(value | (value << 4)); 4432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 4) 4433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 4440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4446b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4449a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 8; 4452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width; 4453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4455b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (trans_color != NULL) 4456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gray = gray & 0xff; 4460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 1) - 1; 4462b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 44659b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((*sp & 0xffU) == gray) 4466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4474a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int gray_high = (gray >> 8) & 0xff; 4478b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int gray_low = gray & 0xff; 4479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + row_info->rowbytes - 1; 4480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (row_info->rowbytes << 1) - 1; 4481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 44839b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((*(sp - 1) & 0xffU) == gray_high && 44849b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (*(sp) & 0xffU) == gray_low) 4485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4489b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4495b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4500a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 4502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 4503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); 4504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 45057a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis row_width); 4506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 45089b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett else if (row_info->color_type == PNG_COLOR_TYPE_RGB && 45099b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett trans_color != NULL) 4510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = (png_byte)(trans_color->red & 0xff); 4514b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = (png_byte)(trans_color->green & 0xff); 4515b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = (png_byte)(trans_color->blue & 0xff); 4516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_info->rowbytes - 1; 4517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 2) - 1; 4518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) 4521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4533b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); 4534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); 4535b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); 4536b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red_low = (png_byte)(trans_color->red & 0xff); 4537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green_low = (png_byte)(trans_color->green & 0xff); 4538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue_low = (png_byte)(trans_color->blue & 0xff); 4539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + row_info->rowbytes - 1; 4540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 3) - 1; 4541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*(sp - 5) == red_high && 4544b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 4) == red_low && 4545b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 3) == green_high && 4546b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 2) == green_low && 4547b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 1) == blue_high && 4548b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp ) == blue_low) 4549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4553b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4559b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 4569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 4570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); 45714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 4578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* If the bit depth is 8 and the color type is not a palette type expand the 4579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * whole row to 16 bits. Has no effect otherwise. 4580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4581b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4582b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_expand_16(png_row_infop row_info, png_bytep row) 4583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 4584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8 && 4585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->color_type != PNG_COLOR_TYPE_PALETTE) 4586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The row have a sequence of bytes containing [0..255] and we need 4588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to turn it into another row containing [0..65535], to do this we 4589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * calculate: 4590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (input / 255) * 65535 4592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Which happens to be exactly input * 257 and this can be achieved 4594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * simply by byte replication in place (copying backwards). 4595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4596b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ 4597b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ 4598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (dp > sp) 4599b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp[-2] = dp[-1] = *--sp, dp -= 2; 4600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->rowbytes *= 2; 4602b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth = 16; 4603b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->pixel_depth = (png_byte)(row_info->channels * 16); 4604b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4605b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 4606b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 4607b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4608b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_QUANTIZE_SUPPORTED 4609b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4610b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_quantize(png_row_infop row_info, png_bytep row, 4611b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_const_bytep palette_lookup, png_const_bytep quantize_lookup) 4612b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 4613b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp, dp; 4614b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 i; 4615b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 row_width=row_info->width; 4616b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4617b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_quantize"); 4618b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4619b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->bit_depth == 8) 4620b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4621b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) 4622b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4623b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int r, g, b, p; 4624b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4625b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp = row; 4626b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 4627b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4628b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari r = *sp++; 4629b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari g = *sp++; 4630b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari b = *sp++; 4631b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4632b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* This looks real messy, but the compiler will reduce 4633b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * it down to a reasonable formula. For example, with 4634b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 5 bits per color, we get: 4635b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * p = (((r >> 3) & 0x1f) << 10) | 4636b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * (((g >> 3) & 0x1f) << 5) | 4637b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * ((b >> 3) & 0x1f); 4638b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4639b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4640b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4641b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4642b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4643b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4644b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_BLUE_BITS)) | 4645b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4646b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4647b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4648b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp++ = palette_lookup[p]; 4649b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4650b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4651b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4652b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = 1; 4653b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = row_info->bit_depth; 4654b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4655b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4656b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4657b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 4658b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari palette_lookup != NULL) 4659b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4660b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int r, g, b, p; 4661b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4662b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp = row; 4663b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 4664b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4665b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari r = *sp++; 4666b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari g = *sp++; 4667b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari b = *sp++; 4668b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp++; 4669b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4670b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4671b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4672b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4673b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4674b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4675b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_BLUE_BITS)) | 4676b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4677b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4678b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4679b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp++ = palette_lookup[p]; 4680b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4681b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4682b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4683b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = 1; 4684b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = row_info->bit_depth; 4685b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4686b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4687b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4688b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4689b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari quantize_lookup) 4690b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4691b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4692b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4693b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++, sp++) 4694b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4695b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *sp = quantize_lookup[*sp]; 4696b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4697b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4698b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4699b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari} 47009b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_QUANTIZE */ 4701b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4702b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Transform the row. The order of transformations is significant, 4703b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * and is very touchy. If you add a transformation, take care to 4704b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * decide how it fits in with the other transformations here. 4705b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4706b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurarivoid /* PRIVATE */ 4707b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) 4708b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 4709b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_read_transformations"); 4710b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4711b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->row_buf == NULL) 4712b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4713b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this 4714b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * error is incredibly rare and incredibly easy to debug without this 4715b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * information. 4716b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4717b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "NULL row buffer"); 4718b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4719b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4720b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* The following is debugging; prior to 1.5.4 the code was never compiled in; 4721b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro 4722b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for 4723b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * all transformations, however in practice the ROW_INIT always gets done on 4724b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * demand, if necessary. 4725b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4726b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && 47279b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 4728b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4729b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Application has failed to call either png_read_start_image() or 4730b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_read_update_info() after setting transforms that expand pixels. 4731b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * This check added to libpng-1.2.19 (but not enabled until 1.5.4). 4732b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4733b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "Uninitialized row"); 4734b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4735b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4736b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_EXPAND_SUPPORTED 47379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND) != 0) 4738b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4739b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4740b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4741b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand_palette(row_info, png_ptr->row_buf + 1, 4742b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); 4743b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4744b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4745b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 4746b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 47479b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->num_trans != 0 && 47489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) 4749b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand(row_info, png_ptr->row_buf + 1, 4750b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari &(png_ptr->trans_color)); 4751b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4752b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 4753b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand(row_info, png_ptr->row_buf + 1, 4754b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari NULL); 4755b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4756b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4757b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4758b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4759b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 47609b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && 47619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_COMPOSE) == 0 && 47629b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 47639b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4764b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_strip_channel(row_info, png_ptr->row_buf + 1, 47657a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis 0 /* at_start == false, because SWAP_ALPHA happens later */); 4766b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4767b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4768b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 47699b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) 4770b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4771b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int rgb_error = 4772b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_rgb_to_gray(png_ptr, row_info, 4773b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->row_buf + 1); 4774b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 47759b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (rgb_error != 0) 4776b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4777b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->rgb_to_gray_status=1; 4778b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4779b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari PNG_RGB_TO_GRAY_WARN) 4780b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4781b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4782b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4783b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari PNG_RGB_TO_GRAY_ERR) 4784b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4785b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4786b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4787b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4788b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4789b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* From Andreas Dilger e-mail to png-implement, 26 March 1998: 4790b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4791b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * In most cases, the "simple transparency" should be done prior to doing 4792b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * gray-to-RGB, or you will have to test 3x as many bytes to check if a 4793b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * pixel is transparent. You would also need to make sure that the 4794b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * transparency information is upgraded to RGB. 4795b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4796b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * To summarize, the current flow is: 4797b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite 4798b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * with background "in place" if transparent, 4799b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * convert to RGB if necessary 4800b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + alpha -> composite with gray background and remove alpha bytes, 4801b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * convert to RGB if necessary 4802b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4803b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * To support RGB backgrounds for gray images we need: 4804b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + simple transparency -> convert to RGB + simple transparency, 4805b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * compare 3 or 6 bytes and composite with 4806b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * background "in place" if transparent 4807b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * (3x compare/pixel compared to doing 4808b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * composite with gray bkgrnd) 4809b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + alpha -> convert to RGB + alpha, composite with background and 4810b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * remove alpha bytes (3x float 4811b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * operations/pixel compared with composite 4812b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * on gray background) 4813b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4814b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Greg's change will do this. The reason it wasn't done before is for 4815b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * performance, as this increases the per-pixel operations. If we would check 4816b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * in advance if the background was gray or RGB, and position the gray-to-RGB 4817b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * transform appropriately, then it would save a lot of work/time. 4818b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4819b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4820b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4821b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* If gray -> RGB, do so now only if background is non-gray; else do later 4822b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * for performance reasons 4823b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 48249b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && 48259b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) 4826b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4827b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4828b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4829b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4830b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari defined(PNG_READ_ALPHA_MODE_SUPPORTED) 48319b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_COMPOSE) != 0) 4832b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); 4833b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4835b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GAMMA_SUPPORTED 48369b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GAMMA) != 0 && 4837b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 4838b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because RGB_TO_GRAY does the gamma transform. */ 48399b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && 4840b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4841b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4842b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari defined(PNG_READ_ALPHA_MODE_SUPPORTED) 4843b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because PNG_COMPOSE does the gamma transform if there is something to 4844b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * do (if there is an alpha channel or transparency.) 4845b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 48469b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett !((png_ptr->transformations & PNG_COMPOSE) != 0 && 4847b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((png_ptr->num_trans != 0) || 48489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && 4849b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4850b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because png_init_read_transformations transforms the palette, unless 4851b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * RGB_TO_GRAY will do the transform. 4852b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4853b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) 4854b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); 4855b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 48565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4857b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 48589b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && 48599b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->transformations & PNG_COMPOSE) != 0 && 48609b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 48619b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4862b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_strip_channel(row_info, png_ptr->row_buf + 1, 48639b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett 0 /* at_start == false, because SWAP_ALPHA happens later */); 4864b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4866b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 48679b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && 48689b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) 4869b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); 4870b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4872b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 48739b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) 4874b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); 4875b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4876b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4877b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 4878b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* There is no harm in doing both of these because only one has any effect, 4879b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * by putting the 'scale' option first if the app asks for scale (either by 4880b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * calling the API or in a TRANSFORM flag) this is what happens. 4881b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 48829b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_16_TO_8) != 0) 4883b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_chop(row_info, png_ptr->row_buf + 1); 4884b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4885b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4886b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_QUANTIZE_SUPPORTED 48879b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_QUANTIZE) != 0) 4888b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4889b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_quantize(row_info, png_ptr->row_buf + 1, 4890b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette_lookup, png_ptr->quantize_index); 4891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4892b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->rowbytes == 0) 4893b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "png_do_quantize returned rowbytes=0"); 4894b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 48959b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_QUANTIZE */ 4896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4897b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_EXPAND_16_SUPPORTED 4898b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Do the expansion now, after all the arithmetic has been done. Notice 4899b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * that previous transformations can handle the PNG_EXPAND_16 flag if this 4900b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * is efficient (particularly true in the case of gamma correction, where 4901b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * better accuracy results faster!) 4902b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 49039b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_EXPAND_16) != 0) 4904b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand_16(row_info, png_ptr->row_buf + 1); 4905b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4906b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4907b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4908b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* NOTE: moved here in 1.5.4 (from much later in this list.) */ 49099b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && 49109b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) 4911b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4912b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4913b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4914b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_INVERT_SUPPORTED 49159b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) 4916b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_invert(row_info, png_ptr->row_buf + 1); 4917b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4918b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4919b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 49209b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) 4921b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); 4922b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4924b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SHIFT_SUPPORTED 49259b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SHIFT) != 0) 4926b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_unshift(row_info, png_ptr->row_buf + 1, 4927b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari &(png_ptr->shift)); 4928b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 49295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4930b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACK_SUPPORTED 49319b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_PACK) != 0) 4932b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_unpack(row_info, png_ptr->row_buf + 1); 4933b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4935b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 4936b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Added at libpng-1.5.10 */ 4937b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4938b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->num_palette_max >= 0) 4939b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_check_palette_indexes(png_ptr, row_info); 4940b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4942b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_BGR_SUPPORTED 49439b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_BGR) != 0) 4944b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_bgr(row_info, png_ptr->row_buf + 1); 4945b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4946a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4947b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACKSWAP_SUPPORTED 49489b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_PACKSWAP) != 0) 4949b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_packswap(row_info, png_ptr->row_buf + 1); 4950b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4951a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4952b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_FILLER_SUPPORTED 49539b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_FILLER) != 0) 4954b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_filler(row_info, png_ptr->row_buf + 1, 4955b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_uint_32)png_ptr->filler, png_ptr->flags); 4956b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4958b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 49599b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) 4960b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); 4961b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4963b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_16BIT_SUPPORTED 4964b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SWAP_SUPPORTED 49659b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) 4966b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_swap(row_info, png_ptr->row_buf + 1); 4967b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4968b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4969a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4970b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 49719b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) 49729b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett { 4973b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->read_user_transform_fn != NULL) 4974b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (*(png_ptr->read_user_transform_fn)) /* User read transform function */ 4975b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr, /* png_ptr */ 4976b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info, /* row_info: */ 4977b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_uint_32 width; width of row */ 4978b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_size_t rowbytes; number of bytes in row */ 4979b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte color_type; color type of pixels */ 4980b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte bit_depth; bit depth of samples */ 4981b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte channels; number of channels (1-4) */ 4982b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte pixel_depth; bits per pixel (depth*channels) */ 4983b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->row_buf + 1); /* start of pixel data for row */ 4984b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED 49859b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->user_transform_depth != 0) 4986b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->bit_depth = png_ptr->user_transform_depth; 4987a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 49889b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett if (png_ptr->user_transform_channels != 0) 4989b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = png_ptr->user_transform_channels; 4990b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4991b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = (png_byte)(row_info->bit_depth * 4992b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels); 4993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4994b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); 4995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4996b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4998b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 49999b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ_TRANSFORMS */ 50009b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ */ 5001