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 * 4b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Last changed in libpng 1.6.10 [March 6, 2014] 5b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Copyright (c) 1998-2014 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, 51b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "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 94b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to have been read in all cases, the parameter allows for this check too. 95b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 96b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic int 97b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_rtran_ok(png_structrp png_ptr, int need_IHDR) 98b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr != NULL) 100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->flags & PNG_FLAG_ROW_INIT) 102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_error(png_ptr, 103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "invalid after png_start_read_image or png_read_update_info"); 104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) 106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_error(png_ptr, "invalid before the PNG header has been read"); 107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Turn on failure to initialize correctly for all transforms. */ 111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; 112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return 1; /* Ok */ 114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return 0; /* no png_error possible! */ 118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_BACKGROUND_SUPPORTED 122a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Handle alpha and tRNS via a background color */ 123b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 124b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_background_fixed(png_structrp png_ptr, 125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p background_color, int background_gamma_code, 126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int need_expand, png_fixed_point background_gamma) 127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_background_fixed"); 129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0) || background_color == NULL) 131a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Application must supply a known background gamma"); 136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; 140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background = *background_color; 144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma = background_gamma; 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background_gamma_type = (png_byte)(background_gamma_code); 146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (need_expand) 147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_BACKGROUND_EXPAND; 148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 153b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 154b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_background(png_structrp png_ptr, 155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p background_color, int background_gamma_code, 156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int need_expand, double background_gamma) 157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_background_fixed(png_ptr, background_color, background_gamma_code, 159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); 160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif /* FLOATING_POINT */ 162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_BACKGROUND */ 163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the 165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * one that pngrtran does first (scale) happens. This is necessary to allow the 166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. 167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 169b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 170b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_scale_16(png_structrp png_ptr) 171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_scale_16"); 173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_SCALE_16_TO_8; 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Chop 16-bit depth files to 8-bit depth */ 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 184b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_strip_16(png_structrp png_ptr) 185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_strip_16"); 1875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 189a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_16_TO_8; 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 197b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_strip_alpha(png_structrp png_ptr) 198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_strip_alpha"); 2005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 202b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 203b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_STRIP_ALPHA; 205b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) 209b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic png_fixed_point 210b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktranslate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, 211b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int is_screen) 212b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Check for flag values. The main reason for having the old Mac value as a 214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * flag is that it is pretty near impossible to work out what the correct 215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * value is from Apple documentation - a working Mac system is needed to 216b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * discover the value! 217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma == PNG_DEFAULT_sRGB || 219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) 220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If there is no sRGB support this just sets the gamma to the standard 222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * sRGB value. (This is a side effect of using this function!) 223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_sRGB_SUPPORTED 225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; 226b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_UNUSED(png_ptr) 228b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (is_screen) 230b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_sRGB; 231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_sRGB_INVERSE; 233b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 234b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (output_gamma == PNG_GAMMA_MAC_18 || 236b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) 237b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (is_screen) 239b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_MAC_OLD; 240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_GAMMA_MAC_INVERSE; 242b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 243b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 244b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return output_gamma; 245b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 246b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 248b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic png_fixed_point 249b50c217251b086440efcdb273c22f86a06c80cbaChris Craikconvert_gamma_value(png_structrp png_ptr, double output_gamma) 250b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 251b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following silently ignores cases where fixed point (times 100,000) 252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma values are passed to the floating point API. This is safe and it 253b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * means the fixed point constants work just fine with the floating point 254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * API. The alternative would just lead to undetected errors and spurious 255b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * bug reports. Negative values fail inside the _fixed API unless they 256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correspond to the flag values. 257b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma > 0 && output_gamma < 128) 259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma *= PNG_FP_1; 260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This preserves -1 and -2 exactly: */ 262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = floor(output_gamma + .5); 263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) 265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_error(png_ptr, "gamma value"); 266b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return (png_fixed_point)output_gamma; 268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 269b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_ALPHA_MODE || READ_GAMMA */ 271b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 273b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 274b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_alpha_mode_fixed(png_structrp png_ptr, int mode, 275b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point output_gamma) 276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int compose = 0; 278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point file_gamma; 279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_alpha_mode"); 281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 283a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); 286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Validate the value to ensure it is in a reasonable range. The value 288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is expected to be 1 or greater, but this range test allows for some 289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * viewing correction values. The intent is to weed out users of this API 290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * who use the inverse of the gamma value accidentally! Since some of these 291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values are reasonable this may have to be changed. 292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (output_gamma < 70000 || output_gamma > 300000) 294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "output gamma out of expected range"); 295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The default file gamma is the inverse of the output gamma; the output 297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma may be changed below so get the file value first: 298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik file_gamma = png_reciprocal(output_gamma); 300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* There are really 8 possibilities here, composed of any combination 302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of: 303b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiply the color channels 305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * do not encode non-opaque pixels 306b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * encode the alpha as well as the color channels 307b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The differences disappear if the input/output ('screen') gamma is 1.0, 309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because then the encoding is a no-op and there is only the choice of 310b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiplying the color channels or not. 311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode and png_set_background interact because both use 313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_compose to do the work. Calling both is only useful when 314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along 315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * with a default gamma value. Otherwise PNG_COMPOSE must not be set. 316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (mode) 318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_PNG: /* default: png standard */ 320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* No compose, but it may be set by png_set_background! */ 321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ 326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The output is linear: */ 330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma = PNG_FP_1; 331b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ 334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; 337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* output_gamma records the encoding of opaque pixels! */ 338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ 341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik compose = 1; 342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_ENCODE_ALPHA; 343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 346b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 347b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid alpha mode"); 348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 349b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Only set the default gamma if the file gamma has not been set (this has 351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the side effect that the gamma in a second call to png_set_alpha_mode will 352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * be ignored.) 353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->colorspace.gamma == 0) 355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = file_gamma; 357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* But always set the output gamma: */ 361b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = output_gamma; 362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Finally, if pre-multiplying, set the background fields to achieve the 364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * desired result. 365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (compose) 367b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 368b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* And obtain alpha pre-multiplication by composing on black: */ 369b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memset(&png_ptr->background, 0, (sizeof png_ptr->background)); 370b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ 371b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; 372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 374b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_COMPOSE) 375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, 376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "conflicting calls to set alpha mode and background"); 377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_COMPOSE; 379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 380b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 383b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 384b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) 385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, 387b50c217251b086440efcdb273c22f86a06c80cbaChris Craik output_gamma)); 388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_QUANTIZE_SUPPORTED 393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Dither file to 8-bit. Supply a palette, the current number 394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of elements in the palette, the maximum number of elements 395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * allowed, and a histogram if possible. If the current number 396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of colors is greater then the maximum number, the palette will be 397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * modified to fit in the maximum number. "full_quantize" indicates 398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * whether we need a quantizing cube set up for RGB images, or if we 399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * simply are reducing the number of colors in a paletted image. 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef struct png_dsort_struct 403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik struct png_dsort_struct * next; 405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte left; 406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte right; 407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} png_dsort; 408b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktypedef png_dsort * png_dsortp; 409b50c217251b086440efcdb273c22f86a06c80cbaChris Craiktypedef png_dsort * * png_dsortpp; 410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 412b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_quantize(png_structrp png_ptr, png_colorp palette, 413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_palette, int maximum_colors, png_const_uint_16p histogram, 414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int full_quantize) 415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_quantize"); 4175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 419a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 421b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_QUANTIZE; 422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 423b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!full_quantize) 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 427b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, 428b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_palette * (sizeof (png_byte)))); 429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)i; 431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_palette > maximum_colors) 434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (histogram != NULL) 436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This is easy enough, just throw out the least used colors. 438a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * Perhaps not the best solution, but good enough. 439a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 443a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize an array to sort colors */ 444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, 445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_palette * (sizeof (png_byte)))); 446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Initialize the quantize_sort array */ 448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 449b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[i] = (png_byte)i; 450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Find the least used palette entries by starting a 452a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * bubble sort, and running it until we have sorted 453a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * out enough colors. Note that we don't care about 454a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * sorting all the colors, just finding which are 455a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * least used. 456a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = num_palette - 1; i >= maximum_colors; i--) 459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 460a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott int done; /* To stop early if the list is pre-sorted */ 461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project done = 1; 464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < i; j++) 465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 466b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (histogram[png_ptr->quantize_sort[j]] 467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < histogram[png_ptr->quantize_sort[j + 1]]) 468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte t; 470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik t = png_ptr->quantize_sort[j]; 472b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; 473b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort[j + 1] = t; 474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project done = 0; 475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (done) 479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 482a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Swap the palette around, and set up a table, if necessary */ 483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (full_quantize) 484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j = num_palette; 486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 487a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Put all the useful colors within the max, but don't 488a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * move the others. 489a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < maximum_colors; i++) 491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j--; 496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 497b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = palette[j]; 499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j = num_palette; 505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 506a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Move all the used colors inside the max limit, and 507a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * develop a translation table. 508a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < maximum_colors; i++) 510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 511a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Only move the colors we need to */ 512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color tmp_color; 515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j--; 518b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project tmp_color = palette[j]; 521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[j] = palette[i]; 522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = tmp_color; 523a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Indicate where the color went */ 524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[j] = (png_byte)i; 525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)j; 526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 529a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Find closest color for those colors we are not using */ 530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 532b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_index[i] >= maximum_colors) 533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int min_d, k, min_k, d_index; 535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 536a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Find the closest color to one we threw out */ 537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik d_index = png_ptr->quantize_index[i]; 538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); 539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (k = 1, min_k = 0; k < maximum_colors; k++) 540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d; 542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project d = PNG_COLOR_DIST(palette[d_index], palette[k]); 544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d < min_d) 546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_d = d; 548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project min_k = k; 549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 551a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Point to closest color */ 552b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[i] = (png_byte)min_k; 553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_free(png_ptr, png_ptr->quantize_sort); 557b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_sort = NULL; 558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This is much harder to do simply (and quickly). Perhaps 562a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * we need to go through a median cut routine, but those 563a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * don't always behave themselves with only a few colors 564a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * as input. So we will just find the closest two colors, 565a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and throw out one of them (chosen somewhat randomly). 566a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * [We don't understand this at all, so if someone wants to 567a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * work on improving it, be our guest - AED, GRP] 568a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int max_d; 571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_new_palette; 572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp t; 573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortpp hash; 574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project t = NULL; 576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 577a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize palette index arrays */ 578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, 579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_palette * (sizeof (png_byte)))); 580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, 581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_palette * (sizeof (png_byte)))); 582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 583a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initialize the sort array */ 584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette[i] = (png_byte)i; 587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index[i] = (png_byte)i; 588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * 591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (sizeof (png_dsortp)))); 592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_new_palette = num_palette; 594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 595a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Initial wild guess at how far apart the farthest pixel 596a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * pair we will be eliminating will be. Larger 597a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * numbers mean more areas will be allocated, Smaller 598a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * numbers run the risk of not saving enough data, and 599a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * having to do this all over again. 600a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 601a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * I have not done extensive checking on this number. 602a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_d = 96; 604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (num_new_palette > maximum_colors) 606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_new_palette - 1; i++) 608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = i + 1; j < num_new_palette; j++) 612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d; 614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project d = PNG_COLOR_DIST(palette[i], palette[j]); 616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d <= max_d) 618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t = (png_dsortp)png_malloc_warn(png_ptr, 621b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(sizeof (png_dsort))); 622b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t == NULL) 624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->next = hash[d]; 627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->left = (png_byte)i; 628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t->right = (png_byte)j; 629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project hash[d] = t; 630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t == NULL) 633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (t != NULL) 637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i <= max_d; i++) 638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (hash[i] != NULL) 640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp p; 642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (p = hash[i]; p; p = p->next) 644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((int)png_ptr->index_to_palette[p->left] 646b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < num_new_palette && 647b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (int)png_ptr->index_to_palette[p->right] 648b50c217251b086440efcdb273c22f86a06c80cbaChris Craik < num_new_palette) 649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j, next_j; 651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette & 0x01) 653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j = p->left; 655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project next_j = p->right; 656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project j = p->right; 660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project next_j = p->left; 661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_new_palette--; 664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[png_ptr->index_to_palette[j]] 665b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = palette[num_new_palette]; 666b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!full_quantize) 667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int k; 669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (k = 0; k < num_palette; k++) 671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 672b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->quantize_index[k] == 673b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[j]) 674b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[k] = 675b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[next_j]; 676b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 677b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((int)png_ptr->quantize_index[k] == 678b50c217251b086440efcdb273c22f86a06c80cbaChris Craik num_new_palette) 679b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->quantize_index[k] = 680b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->index_to_palette[j]; 681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->index_to_palette[png_ptr->palette_to_index 685b50c217251b086440efcdb273c22f86a06c80cbaChris Craik [num_new_palette]] = png_ptr->index_to_palette[j]; 686b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_to_index[png_ptr->index_to_palette[j]] 688b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->palette_to_index[num_new_palette]; 689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 6905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->index_to_palette[j] = 6915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_byte)num_new_palette; 692b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 6935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->palette_to_index[num_new_palette] = 6945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_byte)j; 695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette <= maximum_colors) 697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_new_palette <= maximum_colors) 700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 769; i++) 705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (hash[i] != NULL) 707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_dsortp p = hash[i]; 709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (p) 710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project t = p->next; 712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, p); 713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = t; 714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project hash[i] = 0; 717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_d += 96; 719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, hash); 721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, png_ptr->palette_to_index); 722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, png_ptr->index_to_palette); 7234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->palette_to_index = NULL; 7244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->index_to_palette = NULL; 725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_palette = maximum_colors; 727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->palette == NULL) 729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette = palette; 731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_palette = (png_uint_16)num_palette; 733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 734b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (full_quantize) 735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep distance; 738b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + 739b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_QUANTIZE_BLUE_BITS; 740b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_red = (1 << PNG_QUANTIZE_RED_BITS); 741b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); 742b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); 743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t num_entries = ((png_size_t)1 << total_bits); 7445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, 746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_32)(num_entries * (sizeof (png_byte)))); 747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * 749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (sizeof (png_byte)))); 750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 751b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memset(distance, 0xff, num_entries * (sizeof (png_byte))); 752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ir, ig, ib; 756b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); 757b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); 758b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); 759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ir = 0; ir < num_red; ir++) 761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int dr = abs(ir - r); */ 763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dr = ((ir > r) ? ir - r : r - ir); 764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + 765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_QUANTIZE_GREEN_BITS)); 766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ig = 0; ig < num_green; ig++) 768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int dg = abs(ig - g); */ 770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dg = ((ig > g) ? ig - g : g - ig); 771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dt = dr + dg; 772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dm = ((dr > dg) ? dr : dg); 773b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); 774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (ib = 0; ib < num_blue; ib++) 776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d_index = index_g | ib; 778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* int db = abs(ib - b); */ 779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int db = ((ib > b) ? ib - b : b - ib); 780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int dmax = ((dm > db) ? dm : db); 781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d = dmax + dt + db; 782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (d < (int)distance[d_index]) 784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project distance[d_index] = (png_byte)d; 786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->palette_lookup[d_index] = (png_byte)i; 787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, distance); 794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 798b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 799b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 800b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, 801b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point file_gamma) 802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 803b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_gamma_fixed"); 8045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 805b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 806a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* New in libpng-1.5.4 - reserve particular negative values as flags. */ 809b50c217251b086440efcdb273c22f86a06c80cbaChris Craik scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); 810b50c217251b086440efcdb273c22f86a06c80cbaChris Craik file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); 811b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 812b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Checking the gamma values for being >0 was added in 1.5.4 along with the 813b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * premultiplied alpha support; this actually hides an undocumented feature 814b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of the previous implementation which allowed gamma processing to be 815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * disabled in background handling. There is no evidence (so far) that this 816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * was being used; however, png_set_background itself accepted and must still 817b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * accept '0' for the gamma value it takes, because it isn't always used. 818b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 819b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Since this is an API change (albeit a very minor one that removes an 820b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * undocumented API feature) the following checks were only enabled in 821b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng-1.6.0. 822b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 823b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (file_gamma <= 0) 824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid file gamma in png_set_gamma"); 825b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 826b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (scrn_gamma <= 0) 827b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid screen gamma in png_set_gamma"); 828b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 829b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Set the gamma values unconditionally - this overrides the value in the PNG 830b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * file if a gAMA chunk was present. png_set_alpha_mode provides a 831b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * different, easier, way to default the file gamma. 832b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 833b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = file_gamma; 834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = scrn_gamma; 836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 837b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 838b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_FLOATING_POINT_SUPPORTED 839b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 840b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) 841b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 842b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), 843b50c217251b086440efcdb273c22f86a06c80cbaChris Craik convert_gamma_value(png_ptr, file_gamma)); 844b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 845b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif /* FLOATING_POINT_SUPPORTED */ 846b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* READ_GAMMA */ 847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB, expand grayscale images of 850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * less than 8-bit depth to 8-bit depth, and expand tRNS chunks 851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to alpha channels. 852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 854b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand(png_structrp png_ptr) 855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_expand"); 8575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 858b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 859a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR 19990627: the following three functions currently are identical 865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to png_set_expand(). However, it is entirely reasonable that someone 866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * might wish to expand an indexed image to RGB but *not* expand a single, 867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * fully transparent palette entry to a full alpha channel--perhaps instead 868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace 869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the transparent color with a particular RGB value, or drop tRNS entirely. 870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * IOW, a future version of the library may make the transformations flag 871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a bit more fine-grained, with separate bits for each of these three 872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * functions. 873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * More to the point, these functions make it obvious what libpng will be 875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * doing, whereas "expand" can (and does) mean any number of things. 876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 8775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified 8785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * to expand only the sample depth but not to expand the tRNS to alpha 8795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * and its name was changed to png_set_expand_gray_1_2_4_to_8(). 880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB. */ 883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 884b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_palette_to_rgb(png_structrp png_ptr) 885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_palette_to_rgb"); 8875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 888b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 889a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 8905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 896b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) 897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); 8995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 901a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_EXPAND; 904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 906b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Expand tRNS chunks to alpha channels. */ 907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 908b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_tRNS_to_alpha(png_structrp png_ptr) 909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 910b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_tRNS_to_alpha"); 9115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 912b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 913a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 917b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ 918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 919b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 920b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise 921b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it may not work correctly.) 922b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 924b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_expand_16(png_structrp png_ptr) 925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 926b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_set_expand_16"); 9275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 928b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 929b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 930b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 931b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); 932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 933b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 937b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gray_to_rgb(png_structrp png_ptr) 938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 9394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_gray_to_rgb"); 9405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 941b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 0)) 942b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 943b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 944b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Because rgb must be 8 bits or more: */ 945b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_expand_gray_1_2_4_to_8(png_ptr); 946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_GRAY_TO_RGB; 947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 951b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI 952b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, 953b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point red, png_fixed_point green) 954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 9554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_rgb_to_gray"); 9565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 957b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Need the IHDR here because of the check on color_type below. */ 958b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: fix this */ 959b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_rtran_ok(png_ptr, 1)) 960a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 9615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch(error_action) 963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 964b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_NONE: 965b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY; 966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 967a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_WARN: 969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; 970b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 971b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_ERROR_ACTION_ERROR: 973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; 974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 975a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid error action to rgb_to_gray"); 978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 980b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 9825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_EXPAND; 984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 986b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Make this an error in 1.6 because otherwise the application may assume 987b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that it just worked and get a memory overwrite. 988b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, 990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); 991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 992b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ 993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 996b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) 997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red_int, green_int; 999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1000b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: this calculation does not round, but this behavior is retained 1001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * for consistency, the inaccuracy is very small. The code here always 1002b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * overwrites the coefficients, regardless of whether they have been 1003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * defaulted or set already. 1004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); 1006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); 1007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_red_coeff = red_int; 1009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_green_coeff = green_int; 1010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_coefficients_set = 1; 1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1012b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red >= 0 && green >= 0) 1016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_app_warning(png_ptr, 1017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "ignoring out of range rgb_to_gray coefficients"); 1018b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Use the defaults, from the cHRM chunk if set, else the historical 1020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See 1021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_rgb_to_gray for more discussion of the values. In this case 1022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the coefficients are not marked as 'set' and are not overwritten if 1023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * something has already provided a default. 1024b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1025b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->rgb_to_gray_red_coeff == 0 && 1026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_green_coeff == 0) 1027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1028b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_red_coeff = 6968; 1029b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->rgb_to_gray_green_coeff = 23434; 1030b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ 1031b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1035b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1036b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_FLOATING_POINT_SUPPORTED 1037b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Convert a RGB image to a grayscale of the same width. This allows us, 1038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. 1039b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1041b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI 1042b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, 1043b50c217251b086440efcdb273c22f86a06c80cbaChris Craik double green) 1044b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1045b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_set_rgb_to_gray_fixed(png_ptr, error_action, 1046b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed(png_ptr, red, "rgb to gray red coefficient"), 1047b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed(png_ptr, green, "rgb to gray green coefficient")); 1048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1049b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* FLOATING POINT */ 1050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* RGB_TO_GRAY */ 1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 1054a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) 1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 1056b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr 1057b50c217251b086440efcdb273c22f86a06c80cbaChris Craik read_user_transform_fn) 1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 10594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_set_read_user_transform_fn"); 10605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 10615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->transformations |= PNG_USER_TRANSFORM; 1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->read_user_transform_fn = read_user_transform_fn; 1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1068b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1069b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1070b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* In the case of gamma transformations only do transformations on images where 1071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the [file] gamma and screen_gamma are not close reciprocals, otherwise it 1072b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * slows things down slightly, and also needlessly introduces small errors. 1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1074b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic int /* PRIVATE */ 1075b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) 1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1077b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma 1078b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correction as a difference of the overall transform from 1.0 1079b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1080b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * We want to compare the threshold with s*f - 1, if we get 1081b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * overflow here it is because of wacky gamma values so we 1082b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * turn on processing anyway. 1083b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1084b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point gtest; 1085b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || 1086b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_gamma_significant(gtest); 1087b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1090b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Initialize everything needed for the read. This includes modifying 1091b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the palette. 1092b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1094b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/*For the moment 'png_init_palette_transformations' and 1095b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 'png_init_rgb_transformations' only do some flag canceling optimizations. 1096b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The intent is that these two routines should have palette or rgb operations 1097b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * extracted from 'png_init_read_transformations'. 1098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1099b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic void /* PRIVATE */ 1100b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_palette_transformations(png_structrp png_ptr) 1101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Called to handle the (input) palette case. In png_do_read_transformations 1103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the first step is to expand the palette if requested, so this code must 1104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * take care to only make changes that are invariant with respect to the 1105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * palette expansion, or only do them if there is no expansion. 1106a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 1107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * STRIP_ALPHA has already been handled in the caller (by setting num_trans 1108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to 0.) 1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_alpha = 0; 1111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_transparency = 0; 1112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->num_trans > 0) 1114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i; 1116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Ignore if all the entries are opaque (unlikely!) */ 1118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i=0; i<png_ptr->num_trans; ++i) 1119b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 255) 1121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik continue; 1122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->trans_alpha[i] == 0) 1123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik input_has_transparency = 1; 1124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1125b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1126b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari input_has_transparency = 1; 1127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik input_has_alpha = 1; 1128b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 1129b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1130b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If no alpha we can optimize. */ 1134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!input_has_alpha) 1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Any alpha means background and associative alpha processing is 1137b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA 1138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and ENCODE_ALPHA are irrelevant. 1139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!input_has_transparency) 1144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_set_background handling - deals with the complexity of whether the 1149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color is in the file format or the screen format in the case 1150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * where an 'expand' will happen. 1151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following code cannot be entered in the alpha pre-multiplication case 1154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because PNG_BACKGROUND_EXPAND is cancelled below. 1155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->transformations & PNG_EXPAND)) 1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = 1161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].red; 1162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = 1163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].green; 1164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = 1165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->palette[png_ptr->background.index].blue; 1166a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 1168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_INVERT_ALPHA) 1169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Invert the alpha channel (in tRNS) unless the pixels are 1173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * going to be expanded, in which case leave it for later 1174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i, istop = png_ptr->num_trans; 1176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i=0; i<istop; i++) 1178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i] = (png_byte)(255 - 1179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i]); 1180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ 1183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* background expand and (therefore) no alpha association. */ 1185b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1188b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic void /* PRIVATE */ 1189b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_rgb_transformations(png_structrp png_ptr) 1190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Added to libpng-1.5.4: check the color type to determine whether there 1192b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is any alpha or transparency in the image and simply cancel the 1193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background and alpha mode stuff if there isn't. 1194b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; 1196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int input_has_transparency = png_ptr->num_trans > 0; 1197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If no alpha we can optimize. */ 1199b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!input_has_alpha) 1200b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Any alpha means background and associative alpha processing is 1202b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA 1203b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and ENCODE_ALPHA are irrelevant. 1204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1205b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1209b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1210b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!input_has_transparency) 1211b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1212b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* png_set_background handling - deals with the complexity of whether the 1216b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color is in the file format or the screen format in the case 1217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * where an 'expand' will happen. 1218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following code cannot be entered in the alpha pre-multiplication case 1221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * because PNG_BACKGROUND_EXPAND is cancelled below. 1222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->transformations & PNG_EXPAND) && 1225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1226b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* i.e., GRAY or GRAY_ALPHA */ 1227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1228b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Expand background and tRNS chunks */ 1230b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gray = png_ptr->background.gray; 1231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int trans_gray = png_ptr->trans_color.gray; 1232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1233b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (png_ptr->bit_depth) 1234b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case 1: 1236b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0xff; 1237b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0xff; 1238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 1239b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case 2: 1241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0x55; 1242b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0x55; 1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1244a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 1246b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray *= 0x11; 1247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik trans_gray *= 0x11; 1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1249a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1250b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 1251b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 1253b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* FALL THROUGH (Already 8 bits) */ 1254a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 1256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Already a full 16 bits */ 1257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = png_ptr->background.green = 1261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = (png_uint_16)gray; 1262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_color.red = png_ptr->trans_color.green = 1266b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_color.blue = (png_uint_16)trans_gray; 1267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1269b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* background expand and (therefore) no alpha association. */ 1270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1271b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 1272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1273b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid /* PRIVATE */ 1274b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_read_transformations(png_structrp png_ptr) 1275b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 1276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_init_read_transformations"); 1277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This internal function is called from png_read_start_row in pngrutil.c 1279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and it is called before the 'rowbytes' calculation is done, so the code 1280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in here can change or update the transformations flags. 1281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * First do updates that do not depend on the details of the PNG image data 1283b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * being processed. 1284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds 1288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode and this is another source for a default file gamma so 1289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the test needs to be performed later - here. In addition prior to 1.5.4 1290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the tests were repeated for the PALETTE color type here - this is no 1291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * longer necessary (and doesn't seem to have been necessary before.) 1292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following temporary indicates if overall gamma correction is 1295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * required. 1296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_correction = 0; 1298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->colorspace.gamma != 0) /* has been set */ 1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->screen_gamma != 0) /* screen set too */ 1302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, 1303b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1306b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Assume the output matches the input; a long time default behavior 1307b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of libpng, although the standard has nothing to say about this. 1308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); 1310b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->screen_gamma != 0) 1313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The converse - assume the file matches the screen, note that this 1314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * perhaps undesireable default can (from 1.5.4) be changed by calling 1315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_alpha_mode (even if the alpha handling mode isn't required 1316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * or isn't changed from the default.) 1317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); 1319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* neither are set */ 1321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Just in case the following prevents any processing - file and screen 1322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * are both assumed to be linear and there is no way to introduce a 1323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * third gamma value other than png_set_background with 'UNIQUE', and, 1324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * prior to 1.5.4 1325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; 1327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We have a gamma value now. */ 1329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 1330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1331b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Now turn the gamma transformation on or off as appropriate. Notice 1332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that PNG_GAMMA just refers to the file->screen correction. Alpha 1333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * composition may independently cause gamma correction because it needs 1334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * linear data (e.g. if the file has a gAMA chunk but the screen gamma 1335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * hasn't been specified.) In any case this flag may get turned off in 1336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the code immediately below if the transform can be handled outside the 1337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * row loop. 1338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (gamma_correction) 1340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_GAMMA; 1341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_GAMMA; 1344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1347b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Certain transformations have the effect of preventing other 1348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * transformations that happen afterward in png_do_read_transformations, 1349b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * resolve the interdependencies here. From the code of 1350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_read_transformations the order is: 1351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) 1353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2) PNG_STRIP_ALPHA (if no compose) 1354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 3) PNG_RGB_TO_GRAY 1355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY 1356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 5) PNG_COMPOSE 1357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 6) PNG_GAMMA 1358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 7) PNG_STRIP_ALPHA (if compose) 1359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 8) PNG_ENCODE_ALPHA 1360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 9) PNG_SCALE_16_TO_8 1361b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 10) PNG_16_TO_8 1362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 11) PNG_QUANTIZE (converts to palette) 1363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 12) PNG_EXPAND_16 1364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY 1365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 14) PNG_INVERT_MONO 1366b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 15) PNG_INVERT_ALPHA 1367b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 16) PNG_SHIFT 1368b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 17) PNG_PACK 1369b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 18) PNG_BGR 1370b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 19) PNG_PACKSWAP 1371b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 20) PNG_FILLER (includes PNG_ADD_ALPHA) 1372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 21) PNG_SWAP_ALPHA 1373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 22) PNG_SWAP_BYTES 1374b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 23) PNG_USER_TRANSFORM [must be last] 1375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 1377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 1378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->transformations & PNG_COMPOSE)) 1379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1380b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Stripping the alpha channel happens immediately after the 'expand' 1381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * transformations, before all other transformation, so it cancels out 1382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the alpha handling. It has the side effect negating the effect of 1383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_EXPAND_tRNS too: 1384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | 1386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_EXPAND_tRNS); 1387b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen 1390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so transparency information would remain just so long as it wasn't 1391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * expanded. This produces unexpected API changes if the set of things 1392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that do PNG_EXPAND_tRNS changes (perfectly possible given the 1393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * documentation - which says ask for what you want, accept what you 1394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * get.) This makes the behavior consistent from 1.5.4: 1395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->num_trans = 0; 1397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* STRIP_ALPHA supported, no COMPOSE */ 1399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1400b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA 1402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * settings will have no effect. 1403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!png_gamma_significant(png_ptr->screen_gamma)) 1405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1411b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1412b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Make sure the coefficients for the rgb to gray conversion are set 1413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * appropriately. 1414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_RGB_TO_GRAY) 1416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_colorspace_set_rgb_coefficients(png_ptr); 1417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1421b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Detect gray background and attempt to enable optimization for 1422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gray --> RGB case. 1423b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or 1425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * RGB_ALPHA (in which case need_expand is superfluous anyway), the 1426b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background color might actually be gray yet not be flagged as such. 1427b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This is not a problem for the current code, which uses 1428b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_BACKGROUND_IS_GRAY only to decide when to do the 1429b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_gray_to_rgb() transformation. 1430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: this code needs to be revised to avoid the complexity and 1432b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * interdependencies. The color type of the background should be recorded in 1433b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_set_background, along with the bit depth, then the code has a record 1434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * of exactly what color space the background is currently in. 1435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1436b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) 1437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if 1439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the file was grayscale the background value is gray. 1440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1442b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->transformations & PNG_COMPOSE) 1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* PNG_COMPOSE: png_set_background was called with need_expand false, 1448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so the color is in the color space of the output or png_set_alpha_mode 1449b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * was called and the color is black. Ignore RGB_TO_GRAY because that 1450b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * happens before GRAY_TO_RGB. 1451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1452b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_GRAY_TO_RGB) 1453b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1454b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->background.red == png_ptr->background.green && 1455b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red == png_ptr->background.blue) 1456b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1457b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1458b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = png_ptr->background.red; 1459b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1460b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1461b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1462b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ 1464b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1465b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations 1466b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * can be performed directly on the palette, and some (such as rgb to gray) 1467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * can be optimized inside the palette. This is particularly true of the 1468b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * composite (background and alpha) stuff, which can be pretty much all done 1469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in the palette even if the result is expanded to RGB or gray afterward. 1470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and 1472b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * earlier and the palette stuff is actually handled on the first row. This 1473b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * leads to the reported bug that the palette returned by png_get_PLTE is not 1474b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * updated. 1475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1476b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_init_palette_transformations(png_ptr); 1478b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1479b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1480b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_init_rgb_transformations(png_ptr); 1481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1482b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_EXPAND_16_SUPPORTED) 1484b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & PNG_EXPAND_16) && 1485b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->transformations & PNG_COMPOSE) && 1486b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->bit_depth != 16) 1488b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1489b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: fix this. Because the expand_16 operation is after the compose 1490b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * handling the background color must be 8, not 16, bits deep, but the 1491b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * application will supply a 16-bit value so reduce it here. 1492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1493b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at 1494b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * present, so that case is ok (until do_expand_16 is moved.) 1495b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this discards the low 16 bits of the user supplied background 1497b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * color, but until expand_16 works properly there is no choice! 1498b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1499b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) 1500b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.red); 1501b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.green); 1502b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.blue); 1503b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CHOP(png_ptr->background.gray); 1504b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# undef CHOP 1505b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ 1507b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1508b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1509b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ 1510b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) 1511b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && 1512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->transformations & PNG_COMPOSE) && 1513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1514b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->bit_depth == 16) 1515b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1516b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* On the other hand, if a 16-bit file is to be reduced to 8-bits per 1517b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * component this will also happen after PNG_COMPOSE and so the background 1518b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * color must be pre-expanded here. 1519b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1520b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: fix this too. 1521b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); 1523b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = 1524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_uint_16)(png_ptr->background.green * 257); 1525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); 1526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); 1527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 1529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the 1531b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * background support (see the comments in scripts/pnglibconf.dfa), this 1532b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * allows pre-multiplication of the alpha channel to be implemented as 1533b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * compositing on black. This is probably sub-optimal and has been done in 1534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1.5.4 betas simply to enable external critique and testing (i.e. to 1535b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * implement the new API quickly, without lots of internal changes.) 1536b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 1539b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_BACKGROUND_SUPPORTED 1540b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Includes ALPHA_MODE */ 1541b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1 = png_ptr->background; 1542b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1543b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1544b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This needs to change - in the palette image case a whole set of tables are 1545b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * built when it would be quicker to just calculate the correct value for 1546b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * each palette entry directly. Also, the test is too tricky - why check 1547b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that 1548b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the 1549b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction 1550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the gamma tables will not be built even if composition is required on a 1551b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma encoded value. 1552b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1553b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * In 1.5.4 this is addressed below by an additional check on the individual 1554b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the 1555b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * tables. 1556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1557b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & PNG_GAMMA) 1558b50c217251b086440efcdb273c22f86a06c80cbaChris Craik || ((png_ptr->transformations & PNG_RGB_TO_GRAY) 1559b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && (png_gamma_significant(png_ptr->colorspace.gamma) || 1560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_gamma_significant(png_ptr->screen_gamma))) 1561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik || ((png_ptr->transformations & PNG_COMPOSE) 1562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && (png_gamma_significant(png_ptr->colorspace.gamma) 1563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik || png_gamma_significant(png_ptr->screen_gamma) 1564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_BACKGROUND_SUPPORTED 1565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE 1566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && png_gamma_significant(png_ptr->background_gamma)) 1567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) 1569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && png_gamma_significant(png_ptr->screen_gamma)) 1570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ) 1571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1572b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_build_gamma_table(png_ptr, png_ptr->bit_depth); 15735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 15745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 1575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_COMPOSE) 1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Issue a warning about this combination: because RGB_TO_GRAY is 1578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * optimized to do the gamma transform if present yet do_background has 1579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to do the same thing if both options are set a 1580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * double-gamma-correction happens. This is true in all versions of 1581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng to date. 1582b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_RGB_TO_GRAY) 1584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, 1585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "libpng does not support gamma+background+rgb_to_gray"); 1586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We don't get to here unless there is a tRNS chunk with non-opaque 1590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * entries - see the checking code at the start of this function. 1591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color back, back_1; 1593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_palette = png_ptr->num_palette; 1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) 1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = png_ptr->gamma_table[png_ptr->background.red]; 1600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = png_ptr->gamma_table[png_ptr->background.green]; 1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = png_ptr->gamma_table[png_ptr->background.blue]; 1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; 1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; 1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; 1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1609b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point g, gs; 1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->background_gamma_type) 1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_SCREEN: 1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = (png_ptr->screen_gamma); 1615b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = PNG_FP_1; 1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1617a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_FILE: 1619b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->colorspace.gamma); 1620b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->colorspace.gamma, 1621b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1623a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_UNIQUE: 1625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->background_gamma); 1626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->background_gamma, 1627b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 1630b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = PNG_FP_1; /* back_1 */ 1631b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = PNG_FP_1; /* back */ 1632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1635b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_gamma_significant(gs)) 1636b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1637b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.red = png_gamma_8bit_correct(png_ptr->background.red, 1638b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1639b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.green = png_gamma_8bit_correct(png_ptr->background.green, 1640b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1641b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back.blue = png_gamma_8bit_correct(png_ptr->background.blue, 1642b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs); 1643b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1644b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = (png_byte)png_ptr->background.red; 1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = (png_byte)png_ptr->background.green; 1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = (png_byte)png_ptr->background.blue; 1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1651b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1652b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_gamma_significant(g)) 1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1654b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.red = png_gamma_8bit_correct(png_ptr->background.red, 1655b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g); 1656b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.green = png_gamma_8bit_correct( 1657b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green, g); 1658b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, 1659b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g); 1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1662b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 1663b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.red = (png_byte)png_ptr->background.red; 1665b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.green = (png_byte)png_ptr->background.green; 1666b50c217251b086440efcdb273c22f86a06c80cbaChris Craik back_1.blue = (png_byte)png_ptr->background.blue; 1667b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1669b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 1671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1672b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (i < (int)png_ptr->num_trans && 1673b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i] != 0xff) 1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1675b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 0) 1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = back; 1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1679b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* if (png_ptr->trans_alpha[i] != 0xff) */ 1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].red]; 1684b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); 1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_from_1[w]; 1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].green]; 1688b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); 1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_from_1[w]; 1690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = png_ptr->gamma_to_1[palette[i].blue]; 1692b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); 1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_from_1[w]; 1694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_table[palette[i].red]; 1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_table[palette[i].green]; 1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1703b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1704b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Prevent the transformations being done again. 1705b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1706b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * NOTE: this is highly dubious; it removes the transformations in 1707b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * place. This seems inconsistent with the general treatment of the 1708b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * transformations elsewhere. 17095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 1710b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); 1711b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type == PNG_COLOR_TYPE_PALETTE */ 1712b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ 1714b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* color_type != PNG_COLOR_TYPE_PALETTE */ 1715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1716b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gs_sig, g_sig; 1717b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point g = PNG_FP_1; /* Correction to linear */ 1718b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_fixed_point gs = PNG_FP_1; /* Correction to screen */ 1719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->background_gamma_type) 1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_SCREEN: 1723b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_ptr->screen_gamma; 1724b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* gs = PNG_FP_1; */ 1725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1726a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_FILE: 1728b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->colorspace.gamma); 1729b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->colorspace.gamma, 1730b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1732a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_BACKGROUND_GAMMA_UNIQUE: 1734b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g = png_reciprocal(png_ptr->background_gamma); 1735b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs = png_reciprocal2(png_ptr->background_gamma, 1736b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->screen_gamma); 1737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1738b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1739b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 1740b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "invalid background gamma type"); 1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1743b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g_sig = png_gamma_significant(g); 1744b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gs_sig = png_gamma_significant(gs); 1745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (g_sig) 1747b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.gray = png_gamma_correct(png_ptr, 1748b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray, g); 1749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (gs_sig) 1751b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray = png_gamma_correct(png_ptr, 1752b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.gray, gs); 1753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->background.red != png_ptr->background.green) || 1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->background.red != png_ptr->background.blue) || 1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->background.red != png_ptr->background.gray)) 1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* RGB or RGBA with color background */ 1759b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (g_sig) 1760b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1761b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.red = png_gamma_correct(png_ptr, 1762b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red, g); 1763b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.green = png_gamma_correct(png_ptr, 1765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green, g); 1766b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1767b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_1.blue = png_gamma_correct(png_ptr, 1768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue, g); 1769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1770b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (gs_sig) 1772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1773b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red = png_gamma_correct(png_ptr, 1774b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.red, gs); 1775b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1776b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green = png_gamma_correct(png_ptr, 1777b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green, gs); 1778b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1779b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue = png_gamma_correct(png_ptr, 1780b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue, gs); 1781b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1783b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ 1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background_1.red = png_ptr->background_1.green 1788b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->background_1.blue = png_ptr->background_1.gray; 1789b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.red = png_ptr->background.green 1791b50c217251b086440efcdb273c22f86a06c80cbaChris Craik = png_ptr->background.blue = png_ptr->background.gray; 1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1793b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1794b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The background is now in screen gamma: */ 1795b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; 1796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type != PNG_COLOR_TYPE_PALETTE */ 1797b50c217251b086440efcdb273c22f86a06c80cbaChris Craik }/* png_ptr->transformations & PNG_BACKGROUND */ 1798b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1800a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Transformation does not include PNG_BACKGROUND */ 1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 1802b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE 1803b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1804b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ 1805b50c217251b086440efcdb273c22f86a06c80cbaChris Craik && ((png_ptr->transformations & PNG_EXPAND) == 0 || 1806b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) 1807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 1808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ) 1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_palette = png_ptr->num_palette; 1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1814b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: there are other transformations that should probably be in 1815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * here too. 1816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num_palette; i++) 1818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = png_ptr->gamma_table[palette[i].red]; 1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = png_ptr->gamma_table[palette[i].green]; 1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Done the gamma correction. */ 18255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->transformations &= ~PNG_GAMMA; 1826b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ 1827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 18285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1831b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_GAMMA_SUPPORTED */ 1832b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 18335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED 1834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* No GAMMA transformation (see the hanging else 4 lines above) */ 1835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if ((png_ptr->transformations & PNG_COMPOSE) && 1836b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int istop = (int)png_ptr->num_trans; 1840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color back; 1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp palette = png_ptr->palette; 1842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.red = (png_byte)png_ptr->background.red; 1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.green = (png_byte)png_ptr->background.green; 1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project back.blue = (png_byte)png_ptr->background.blue; 1846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < istop; i++) 1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1849b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->trans_alpha[i] == 0) 1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i] = back; 1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1853b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1854b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->trans_alpha[i] != 0xff) 1855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* The png_composite() macro is defined in png.h */ 1857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].red, palette[i].red, 1858b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.red); 1859b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].green, palette[i].green, 1861b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.green); 1862b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_composite(palette[i].blue, palette[i].blue, 1864b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->trans_alpha[i], back.blue); 1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1868b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_COMPOSE; 1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 1871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SHIFT_SUPPORTED 1873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->transformations & PNG_SHIFT) && 1874b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->transformations & PNG_EXPAND) && 1875b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1877b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int i; 1878b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int istop = png_ptr->num_palette; 1879b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int shift = 8 - png_ptr->sig_bit.red; 1880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1881b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations &= ~PNG_SHIFT; 1882b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1883b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* significant bits can be in the range 1 to 7 for a meaninful result, if 1884b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the number of significant bits is 0 then no shift is done (this is an 1885b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error condition which is silently ignored.) 1886b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1887b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1888b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1889b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1890b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].red; 1891b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1892b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1893b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].red = (png_byte)component; 1894b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1895b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1896b50c217251b086440efcdb273c22f86a06c80cbaChris Craik shift = 8 - png_ptr->sig_bit.green; 1897b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1898b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1899b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1900b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].green; 1901b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1902b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1903b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].green = (png_byte)component; 1904b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1905b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1906b50c217251b086440efcdb273c22f86a06c80cbaChris Craik shift = 8 - png_ptr->sig_bit.blue; 1907b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift > 0 && shift < 8) 1908b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i=0; i<istop; ++i) 1909b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 1910b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int component = png_ptr->palette[i].blue; 1911b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1912b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari component >>= shift; 1913b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette[i].blue = (png_byte)component; 1914b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 1915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SHIFT_SUPPORTED */ 1917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Modify the info structure to reflect the transformations. The 1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * info should be updated so a PNG file could be written with it, 1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * assuming the transformations result in valid PNG data. 1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1924b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) 1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 19264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_read_transform_info"); 19275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 19285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 1929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_EXPAND) 1930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1933b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This check must match what actually happens in 1934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_do_expand_palette; if it ever checks the tRNS chunk to see if 1935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it is all opaque we must do the same (at present it does not.) 1936b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1937b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->num_trans > 0) 1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 1939b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_RGB; 1942b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 1944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->num_trans = 0; 1945b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 1946b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->palette == NULL) 1947b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error (png_ptr, "Palette is NULL in indexed image"); 1948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->num_trans) 1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_EXPAND_tRNS) 1954b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->bit_depth < 8) 1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 1958b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->num_trans = 0; 1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1964b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 1965b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_ALPHA_MODE_SUPPORTED) 1966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following is almost certainly wrong unless the background value is in 1967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the screen space! 1968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_COMPOSE) 1970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->background = png_ptr->background; 1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 1974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), 1975b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * however it seems that the code in png_init_read_transformations, which has 1976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * been called before this from png_read_update_info->png_read_start_row 1977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * sometimes does the gamma transform and cancels the flag. 1978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1979b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * TODO: this looks wrong; the info_ptr should end up with a gamma equal to 1980b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the screen_gamma value. The following probably results in weirdness if 1981b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the info_ptr is used by the app after the rows have been read. 1982b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1983b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; 1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1986b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (info_ptr->bit_depth == 16) 1987b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 1988b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_16BIT_SUPPORTED 1989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 1990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_SCALE_16_TO_8) 1991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 1992b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1993b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 1995b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_16_TO_8) 1996b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 1997b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 1998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 2000b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* No 16 bit support: force chopping 16-bit input down to 8, in this case 2001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the app program can chose if both APIs are available by setting the 2002b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * correct scaling to use. 2003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* For compatibility with previous versions use the strip method by 2006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * default. This code works because if PNG_SCALE_16_TO_8 is already 2007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * set the code below will do that in preference to the chop. 2008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_16_TO_8; 2010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 2011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 2012b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2014b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations |= PNG_SCALE_16_TO_8; 2015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 8; 2016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# else 2017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2018b50c217251b086440efcdb273c22f86a06c80cbaChris Craik CONFIGURATION ERROR: you must enable at least one 16 to 8 method 2019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 2020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# endif 2021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* !READ_16BIT_SUPPORTED */ 2022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_GRAY_TO_RGB) 2026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type | 2027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_COLOR_MASK_COLOR); 2028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_RGB_TO_GRAY) 2032b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type & 2033b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_COLOR); 2034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2036b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_QUANTIZE_SUPPORTED 2037b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_QUANTIZE) 2038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 2040a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && 2041a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->palette_lookup && info_ptr->bit_depth == 8) 2042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; 2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 2049b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && 2050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 2051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2052b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth = 16; 2053b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2055b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 20565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED 2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) 2058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = 8; 2059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 1; 2063b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 3; 2066b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = 1; 2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 2071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations & PNG_STRIP_ALPHA) 2072b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2073b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type = (png_byte)(info_ptr->color_type & 2074b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_ALPHA); 2075b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->num_trans = 0; 2076b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels++; 2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ 2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->transformations & PNG_FILLER) && 2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) 2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels++; 2089a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* If adding a true alpha channel not just filler */ 2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_ADD_ALPHA) 2091b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 2092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ 2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_READ_USER_TRANSFORM_SUPPORTED) 20974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->transformations & PNG_USER_TRANSFORM) 2098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2099b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (info_ptr->bit_depth < png_ptr->user_transform_depth) 2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->bit_depth = png_ptr->user_transform_depth; 2101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (info_ptr->channels < png_ptr->user_transform_channels) 2103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->channels = png_ptr->user_transform_channels; 2104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->pixel_depth = (png_byte)(info_ptr->channels * 2108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik info_ptr->bit_depth); 2109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); 2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Adding in 1.5.4: cache the above value in png_struct so that we can later 2113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * check in png_rowbytes that the user buffer won't get overwritten. Note 2114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * that the field is not always set - if png_read_update_info isn't called 2115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the application has to either not do any transforms or get the calculation 2116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * right itself. 2117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->info_rowbytes = info_ptr->rowbytes; 2119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 21205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_EXPAND_SUPPORTED 21214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr) 2122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2126b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACK_SUPPORTED 2127b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, 2128b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * without changing the actual values. Thus, if you had a row with 2129b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * a bit depth of 1, you would end up with bytes that only contained 2130b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * the numbers 0 or 1. If you would rather they contain 0 and 255, use 2131b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_do_shift() after this. 2132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 2133b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2134b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_unpack(png_row_infop row_info, png_bytep row) 2135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2136b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_unpack"); 2137b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2138b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->bit_depth < 8) 2139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2140b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 i; 2141b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 row_width=row_info->width; 2142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2143b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari switch (row_info->bit_depth) 2144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2145b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 1: 2146b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2147b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); 2148b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2149b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); 2150b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2151b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2152b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x01); 2153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2154b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 7) 2155b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2156b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2157b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2158b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2160b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2161b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift++; 2162b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2163b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2164b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2165b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2166b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2167b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2168b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 2: 2169b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2170b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2171b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); 2172b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2173b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 2174b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2175b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2176b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x03); 2177b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2178b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 6) 2179b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2180b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2181b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2182b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2183b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2184b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2185b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift += 2; 2186b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2187b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2188b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2189b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2190b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2191b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2192b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case 4: 2193b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2194b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); 2195b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep dp = row + (png_size_t)row_width - 1; 2196b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 2197b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 2198b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2199b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp = (png_byte)((*sp >> shift) & 0x0f); 2200b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2201b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift == 4) 2202b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2203b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 0; 2204b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp--; 2205b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2206b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2207b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2208b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift = 4; 2209b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2210b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp--; 2211b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2212b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2213b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2214b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2215b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari default: 2216b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 2217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2218b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->bit_depth = 8; 2219b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2220b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = row_width * row_info->channels; 2221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2222b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari} 2223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2225b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SHIFT_SUPPORTED 2226b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Reverse the effects of png_do_shift. This routine merely shifts the 2227b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * pixels back to their significant bits values. Thus, if you have 2228b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * a row of bit depth 8, but only 5 are significant, this will shift 2229b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * the values back to 0 through 31. 2230b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 2231b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2232b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_unshift(png_row_infop row_info, png_bytep row, 2233b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_const_color_8p sig_bits) 2234b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 2235b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int color_type; 2236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2237b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_unshift"); 2238b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2239b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* The palette case has already been handled in the _init routine. */ 2240b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari color_type = row_info->color_type; 2241b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 2242b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (color_type != PNG_COLOR_TYPE_PALETTE) 2243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2244b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int shift[4]; 2245b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int channels = 0; 2246b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int bit_depth = row_info->bit_depth; 2247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2248b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (color_type & PNG_COLOR_MASK_COLOR) 2249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2250b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->red; 2251b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->green; 2252b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->blue; 2253b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2255b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 2256b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2257b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->gray; 2258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2260b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (color_type & PNG_COLOR_MASK_ALPHA) 2261b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2262b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[channels++] = bit_depth - sig_bits->alpha; 2263b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 2264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2265b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2266b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int c, have_shift; 2267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2268b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (c = have_shift = 0; c < channels; ++c) 2269b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 2270b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* A shift of more than the bit depth is an error condition but it 2271b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * gets ignored here. 2272b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 2273b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (shift[c] <= 0 || shift[c] >= bit_depth) 2274b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari shift[c] = 0; 2275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik have_shift = 1; 2278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!have_shift) 2281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 2282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2283b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch (bit_depth) 2285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 2287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 1bpp gray: should not be here! */ 2288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTREACHED */ 2289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 2290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 2292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 2bpp gray */ 2293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* assert(channels == 1 && shift[0] == 1) */ 2294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp = row; 2296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (*bp >> 1) & 0x55; 2301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2305a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 2307b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Must be 4bpp gray */ 2308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* assert(channels == 1) */ 2309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gray_shift = shift[0]; 2313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int mask = 0xf >> gray_shift; 2314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik mask |= mask << 4; 2316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = (*bp >> gray_shift) & mask; 2320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2324a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 2326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Single byte components, G, GA, RGB, RGBA */ 2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int channel = 0; 2331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int b = *bp >> shift[channel]; 2335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (++channel >= channels) 2336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik channel = 0; 2337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *bp++ = (png_byte)b; 2338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2341a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 2342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 2344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Double byte components, G, GA, RGB, RGBA */ 2345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep bp = row; 2347b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep bp_end = bp + row_info->rowbytes; 2348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int channel = 0; 2349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (bp < bp_end) 2351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int value = (bp[0] << 8) + bp[1]; 2353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik value >>= shift[channel]; 2355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (++channel >= channels) 2356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik channel = 0; 2357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *bp++ = (png_byte)(value >> 8); 2358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *bp++ = (png_byte)(value & 0xff); 2359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2368b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2369b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Scale rows of bit depth 16 down to 8 accurately */ 2370b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2371b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_scale_16_to_8(png_row_infop row_info, png_bytep row) 2372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_scale_16_to_8"); 23745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 16) 2376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; /* source */ 2378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; /* destination */ 2379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (sp < ep) 2382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The input is an array of 16 bit components, these must be scaled to 2384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 8 bits each. For a 16 bit value V the required value (from the PNG 2385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * specification) is: 2386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2387b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (V * 255) / 65535 2388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This reduces to round(V / 257), or floor((V + 128.5)/257) 2390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Represent V as the two byte value vhi.vlo. Make a guess that the 2392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * result is the top byte of V, vhi, then the correction to this value 2393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is: 2394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = floor(((V-vhi.vhi) + 128.5) / 257) 2396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * = floor(((vlo-vhi) + 128.5) / 257) 2397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This can be approximated using integer arithmetic (and a signed 2399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * shift): 2400b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = (vlo-vhi+128) >> 8; 2402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * The approximate differs from the exact answer only when (vlo-vhi) is 2404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 128; it then gives a correction of +1 when the exact correction is 2405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 0. This gives 128 errors. The exact answer (correct for all 16 bit 2406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * input values) is: 2407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * error = (vlo-vhi+128)*65535 >> 24; 2409b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2410b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * An alternative arithmetic calculation which also gives no errors is: 2411b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2412b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (V * 255 + 32895) >> 16 2413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_int_32 tmp = *sp++; /* must be signed! */ 2416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; 2417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp++ = (png_byte)tmp; 2418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth = 8; 2421b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2422b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->rowbytes = row_info->width * row_info->channels; 2423b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 2425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2426b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2427b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2428b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2429b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Simply discard the low byte. This was the default behavior prior 2430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to libpng-1.5.4. 2431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 2432b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_chop(png_row_infop row_info, png_bytep row) 2433b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 2434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_chop"); 2435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2436b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 16) 2437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; /* source */ 2439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; /* destination */ 2440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2442b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (sp < ep) 2443b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp++ = *sp; 2445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp += 2; /* skip low byte */ 2446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 2449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_info->width * row_info->channels; 2451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 24555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 2456b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row) 2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 24594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_swap_alpha"); 24605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from RGBA to ARGB */ 2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save; 2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save = *(--sp); 2476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save; 2480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2482b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from RRGGBBAA to AARRGGBB */ 2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save[2]; 2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[0] = *(--sp); 2495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[1] = *(--sp); 2496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[0]; 2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[1]; 2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2508b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from GA to AG */ 2512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save; 2517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save = *(--sp); 2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save; 2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This converts from GGAA to AAGG */ 2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + row_info->rowbytes; 2532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp; 2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte save[2]; 2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[0] = *(--sp); 2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save[1] = *(--sp); 2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[0]; 2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = save[1]; 2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2546b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 25525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 2553b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row) 2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width; 25574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_invert_alpha"); 25585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2559b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_width = row_info->width; 2560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 2563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in RGBA */ 2565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2573b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This does nothing: 2574b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2576b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik We can replace it with: 2578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=3; 2580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2582b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This inverts the alpha channel in RRGGBBAA */ 2586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2596b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2597b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This does nothing: 2598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2599b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2602b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2603b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2604b50c217251b086440efcdb273c22f86a06c80cbaChris Craik We can replace it with: 2605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2606b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=6; 2607b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2610b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2611b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2612b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2613b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2614b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 2615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in GA */ 2617b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2618b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2619b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2621b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2622b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2623b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2624b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 2627b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2628b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2629b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 2630b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This inverts the alpha channel in GGAA */ 2632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row + row_info->rowbytes; 2633b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = sp; 2634b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2636b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 2637b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 2638b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2639b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = (png_byte)(255 - *(--sp)); 2640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* 2641b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2642b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(--dp) = *(--sp); 2643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/ 2644b50c217251b086440efcdb273c22f86a06c80cbaChris Craik sp-=2; 2645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp=sp; 2646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2648b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Add filler channel if we have RGB color */ 2655b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_filler(png_row_infop row_info, png_bytep row, 2657b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 filler, png_uint_32 flags) 2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2662b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte hi_filler = (png_byte)((filler>>8) & 0xff); 2664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte lo_filler = (png_byte)(filler & 0xff); 2666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_filler"); 26685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ( 2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type == PNG_COLOR_TYPE_GRAY) 2671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 26724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (row_info->bit_depth == 8) 2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (flags & PNG_FLAG_FILLER_AFTER) 2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2676b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from G to GX */ 2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width; 2678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 16; 2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 2; 2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2689b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2692b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from G to XG */ 2693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width; 2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 16; 2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 2; 2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2705b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2706b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 27074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project else if (row_info->bit_depth == 16) 2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (flags & PNG_FLAG_FILLER_AFTER) 2710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2711b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from GG to GGXX */ 2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2; 2713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2727b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2730b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from GG to XXGG */ 2731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2; 2732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } /* COLOR_TYPE == GRAY */ 2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_RGB) 2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 27494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (row_info->bit_depth == 8) 2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (flags & PNG_FLAG_FILLER_AFTER) 2752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2753b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RGB to RGBX */ 2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 3; 2755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RGB to XRGB */ 2772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 3; 2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width; 2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 2783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2786b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2787b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_16BIT_SUPPORTED 27884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project else if (row_info->bit_depth == 16) 2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (flags & PNG_FLAG_FILLER_AFTER) 2791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2792b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RRGGBB to RRGGBBXX */ 2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 6; 2794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 1; i < row_width; i++) 2796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 64; 2810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 8; 2811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2812b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes the data from RRGGBB to XXRRGGBB */ 2816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 6; 2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = *(--sp); 2826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = hi_filler; 2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(--dp) = lo_filler; 2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2829b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 2831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 64; 2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 8; 2833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } /* COLOR_TYPE == RGB */ 2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2841a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Expand grayscale files to RGB, with or without alpha */ 2842b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row) 2844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = row_info->width; 2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_gray_to_rgb"); 28495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth >= 8 && 2851b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(row_info->color_type & PNG_COLOR_MASK_COLOR)) 2852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2857b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes G to RGB */ 2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width - 1; 2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2867b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2870b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GG to RRGGBB */ 2871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2 - 1; 2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 4; 2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2884b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 2888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2889b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GA to RGBA */ 2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 2 - 1; 2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 2; 2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2903b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This changes GGAA to RRGGBBAA */ 2904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)row_width * 4 - 1; 2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = sp + (png_size_t)row_width * 4; 2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *sp; 2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp - 1); 2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp--) = *(sp--); 2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2919b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->channels = (png_byte)(row_info->channels + 2); 2920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type |= PNG_COLOR_MASK_COLOR; 2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->channels * 2922b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth); 29234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 2924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 29285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2929a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Reduce RGB files to grayscale, with or without alpha 2930b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * using the equation given in Poynton's ColorFAQ of 1998-01-04 at 2931b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but 2932b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * versions dated 1998 through November 2002 have been archived at 2933b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ 2934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) 29354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Charles Poynton poynton at poynton.com 2936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B 2938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2939b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * which can be expressed with integers as 2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2941b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6969 * R + 23434 * G + 2365 * B)/32768 2942b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2943b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Poynton's current link (as of January 2003 through July 2011): 2944b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * <http://www.poynton.com/notes/colour_and_gamma/> 2945b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * has changed the numbers slightly: 2946b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2947b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = 0.2126*R + 0.7152*G + 0.0722*B 2948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * which can be expressed with integers as 2950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2951b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6966 * R + 23436 * G + 2366 * B)/32768 2952b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2953b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 2954b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * end point chromaticities and the D65 white point. Depending on the 2955b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * precision used for the D65 white point this produces a variety of different 2956b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * numbers, however if the four decimal place value used in ITU-R Rec 709 is 2957b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * used (0.3127,0.3290) the Y calculation would be: 2958b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2959b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6968 * R + 23435 * G + 2366 * B)/32768 2960b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2961b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * While this is correct the rounding results in an overflow for white, because 2962b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the sum of the rounded coefficients is 32769, not 32768. Consequently 2963b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * libpng uses, instead, the closest non-overflowing approximation: 2964b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2965b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Y = (6968 * R + 23434 * G + 2366 * B)/32768 2966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 2967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk 2968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (including an sRGB chunk) then the chromaticities are used to calculate the 2969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * coefficients. See the chunk handling in pngrutil.c for more information. 2970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2971b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * In all cases the calculation is to be done in a linear colorspace. If no 2972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * gamma information is available to correct the encoding of the original RGB 2973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values this results in an implicit assumption that the original PNG RGB 2974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * values were linear. 2975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 2976b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Other integer coefficents can be used via png_set_rgb_to_gray(). Because 2977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the API takes just red and green coefficients the blue coefficient is 2978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * calculated to make the sum 32768. This will result in different rounding 2979b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to that used above. 2980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 2981b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic int 2982b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) 2983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int rgb_error = 0; 2986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 29874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_rgb_to_gray"); 29885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && 2990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_COLOR)) 2991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2992b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; 2993b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; 2994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 bc = 32768 - rc - gc; 2995b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_32 row_width = row_info->width; 2996b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int have_alpha = 2997b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; 2998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2999b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 3000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 3002b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Notice that gamma to/from 1 are not necessarily inverses (if 3003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * there is an overall gamma correction). Prior to 1.5.5 this code 3004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * checked the linearized values for equality; this doesn't match 3005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the documentation, the original values must be checked. 3006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3007b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 3008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3009b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = *(sp++); 3016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = *(sp++); 3017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = *(sp++); 3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3019b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = png_ptr->gamma_to_1[red]; 3022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green = png_ptr->gamma_to_1[green]; 3023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik blue = png_ptr->gamma_to_1[blue]; 3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3025b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = png_ptr->gamma_from_1[ 3027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (rc*red + gc*green + bc*blue + 16384)>>15]; 3028b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3030b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3031b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3032b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If there is no overall correction the table will not be 3033b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * set. 3034b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3035b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_table != NULL) 3036b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = png_ptr->gamma_table[red]; 3037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = red; 3039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3041b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (have_alpha) 3042b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3044b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3045b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3047b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3049b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3052b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = *(sp++); 3055b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = *(sp++); 3056b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = *(sp++); 3057b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3058b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3060b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3061b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* NOTE: this is the historical approach which simply 3062b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * truncates the results. 3063b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3064b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 3065b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3067b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3068b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = red; 3069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3070b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (have_alpha) 3071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3075b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3076b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else /* RGB bit_depth == 16 */ 3077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3078b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_GAMMA_SUPPORTED 3079b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) 3080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3081b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3082b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3083b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3084b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3085b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3087b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red, green, blue, w; 3088b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3089b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3090b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3091b50c217251b086440efcdb273c22f86a06c80cbaChris Craik blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3092b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3093b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red == green && red == blue) 3094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3095b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->gamma_16_table != NULL) 3096b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = png_ptr->gamma_16_table[(red&0xff) 3097b50c217251b086440efcdb273c22f86a06c80cbaChris Craik >> png_ptr->gamma_shift][red>>8]; 3098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3099b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = red; 3101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) 3106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik >> png_ptr->gamma_shift][red>>8]; 3107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 green_1 = 3108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->gamma_16_to_1[(green&0xff) >> 3109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->gamma_shift][green>>8]; 3110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) 3111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik >> png_ptr->gamma_shift][blue>>8]; 3112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 3113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + bc*blue_1 + 16384)>>15); 3114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = png_ptr->gamma_16_from_1[(gray16&0xff) >> 3115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->gamma_shift][gray16 >> 8]; 3116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)((w>>8) & 0xff); 3120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)(w & 0xff); 3121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (have_alpha) 3123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp++) = *(sp++); 3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 3129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 3132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp = row; 3133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep dp = row; 3134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 i; 3135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++) 3137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 red, green, blue, gray16; 3139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (red != green || red != blue) 3145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik rgb_error |= 1; 3146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* From 1.5.5 in the 16 bit case do the accurate conversion even 3148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * in the 'fast' case - this is because this is where the code 3149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * ends up when handling linear 16 bit data. 3150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 3151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 3152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 15); 3153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)((gray16>>8) & 0xff); 3154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = (png_byte)(gray16 & 0xff); 3155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (have_alpha) 3157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(dp++) = *(sp++); 3159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(dp++) = *(sp++); 3160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->channels = (png_byte)(row_info->channels - 2); 3166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->color_type = (png_byte)(row_info->color_type & 3167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik ~PNG_COLOR_MASK_COLOR); 3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->channels * 3169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth); 31704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 3171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return rgb_error; 3173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 3174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 3177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik defined(PNG_READ_ALPHA_MODE_SUPPORTED) 3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Replace any alpha or transparency with the supplied background color. 3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "background" is already in the screen gamma, while "background_1" is 3180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * at a gamma of 1.0. Paletted files have already been taken care of. 3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 3182b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 3183b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 31855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_table = png_ptr->gamma_table; 3187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; 3188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; 3189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; 3190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; 3191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; 3192b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_shift = png_ptr->gamma_shift; 3193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; 3194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep sp; 3197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 3198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width = row_info->width; 3199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift; 3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_compose"); 32025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->color_type) 3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 3207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7; 3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x01) 3217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); 3220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= png_ptr->background.gray << shift; 3221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!shift) 3225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7; 3227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift--; 3232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3235a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 32385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x03) 3246b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3248b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3249b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= png_ptr->background.gray << shift; 3250b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3255b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int p = (*sp >> shift) & 0x03; 3256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int g = (gamma_table [p | (p << 2) | 3257b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (p << 4) | (p << 6)] >> 6) & 0x03; 3258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= g << shift; 3260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!shift) 3264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 2; 3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3273b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x03) 3282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= png_ptr->background.gray << shift; 3286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!shift) 3290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 6; 3292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 2; 3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3301a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x0f) 3312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= png_ptr->background.gray << shift; 3316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int p = (*sp >> shift) & 0x0f; 3322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 3323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 0x0f; 3324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= g << shift; 3326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!shift) 3330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 4; 3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_uint_16)((*sp >> shift) & 0x0f) 3348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik == png_ptr->trans_color.gray) 3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik tmp |= png_ptr->background.gray << shift; 3352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)(tmp & 0xff); 3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!shift) 3356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 3358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift -= 4; 3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3367a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 8: 3369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp++) 3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.gray) 3377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp++) 3388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.gray) 3390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3395a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 16: 3397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL) 3400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 2) 3403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (v == png_ptr->trans_color.gray) 3409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3410a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3411b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3412b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray 3414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 2) 3430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (v == png_ptr->trans_color.gray) 3436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray 3440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3446b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 3448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 3449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3452a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB: 3454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 34575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_table != NULL) 3459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 3) 3462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.red && 3464b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) == png_ptr->trans_color.green && 3465b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) == png_ptr->trans_color.blue) 3466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3468b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = gamma_table[*(sp + 1)]; 3476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 2) = gamma_table[*(sp + 2)]; 3477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 3) 3485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3486b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (*sp == png_ptr->trans_color.red && 3487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) == png_ptr->trans_color.green && 3488b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) == png_ptr->trans_color.blue) 3489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3490b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3491b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 34995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL) 3501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 6) 3504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3507b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3508b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3509b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3510b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3511b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 5)); 3512b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (r == png_ptr->trans_color.red && 3514b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g == png_ptr->trans_color.green && 3515b50c217251b086440efcdb273c22f86a06c80cbaChris Craik b == png_ptr->trans_color.blue) 3516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3517a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3518b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3519b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3520b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3521b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3523b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 3) = (png_byte)(v & 0xff); 3538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 5) = (png_byte)(v & 0xff); 3542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3545b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++, sp += 6) 3551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3552b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3554b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3555b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3556b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3557b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3558b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 5)); 3559b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (r == png_ptr->trans_color.red && 3561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik g == png_ptr->trans_color.green && 3562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik b == png_ptr->trans_color.blue) 3563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3572b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3579a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 3581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 35845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_table != NULL) 3587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 2) 3590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = *(sp + 1); 3592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == 0xff) 3594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = gamma_table[*sp]; 3595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3598a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3599b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 3605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*sp]; 3607b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.gray); 3608b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) 3609b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_from_1[w]; 3610b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = w; 3611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3618b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 2) 3619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 1); 3621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3622b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3623b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.gray; 3624b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xff) 3626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*sp, *sp, a, png_ptr->background.gray); 3627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (png_ptr->bit_depth == 16) */ 3631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 36325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_16_to_1 != NULL) 3635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3637b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3639b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3640b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == (png_uint_16)0xffff) 3643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3647b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3648b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3650b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3653a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3654b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3655b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3656b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3658b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g, v, w; 3662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background_1.gray); 3665b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (optimize) 3666b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = v; 3667b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 3668b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; 3669b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((w >> 8) & 0xff); 3670b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(w & 0xff); 3671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3678b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3680b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3681b50c217251b086440efcdb273c22f86a06c80cbaChris Craik + *(sp + 3)); 3682b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3683b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3685b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.gray >> 8) 3686b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3687b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3689b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3690b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xffff) 3691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g, v; 3693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3695b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background.gray); 3696b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3697b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3704a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 3706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 37095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_table != NULL) 3712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3714b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 3); 3717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == 0xff) 3719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3720b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = gamma_table[*sp]; 3721b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = gamma_table[*(sp + 1)]; 3722b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = gamma_table[*(sp + 2)]; 3723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3724b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3727a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3728b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3729b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3730b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3732b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v, w; 3736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*sp]; 3738b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.red); 3739b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) w = gamma_from_1[w]; 3740b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = w; 3741b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*(sp + 1)]; 3743b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.green); 3744b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) w = gamma_from_1[w]; 3745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = w; 3746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_to_1[*(sp + 2)]; 3748b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(w, v, a, png_ptr->background_1.blue); 3749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) w = gamma_from_1[w]; 3750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = w; 3751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3758b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 4) 3759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte a = *(sp + 3); 3761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3762b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)png_ptr->background.red; 3765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)png_ptr->background.green; 3766b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)png_ptr->background.blue; 3767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xff) 3770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*sp, *sp, a, png_ptr->background.red); 3772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3773b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*(sp + 1), *(sp + 1), a, 3774b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.green); 3775b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3776b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite(*(sp + 2), *(sp + 2), a, 3777b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->background.blue); 3778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 37845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gamma_16_to_1 != NULL) 3787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3789b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 8) 3790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project << 8) + (png_uint_16)(*(sp + 7))); 3793b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == (png_uint_16)0xffff) 3795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3799b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3800b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3801b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3803b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3804b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(v & 0xff); 3805b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(v & 0xff); 3809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3810b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (a == 0) 3812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3813a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Background is already in screen gamma */ 3814b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3815b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3816b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3817b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3818b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3819b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3820b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3821b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3822b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3827b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 v, w; 3828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3830b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.red); 3831b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) 3832b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 3833b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((w >> 8) & 0xff); 3835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(w & 0xff); 3836b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3838b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.green); 3839b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) 3840b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 3841b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3842b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3843b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((w >> 8) & 0xff); 3844b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(w & 0xff); 3845b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3847b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(w, v, a, png_ptr->background_1.blue); 3848b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!optimize) 3849b50c217251b086440efcdb273c22f86a06c80cbaChris Craik w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 3850b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8]; 3851b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3852b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((w >> 8) & 0xff); 3853b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(w & 0xff); 3854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3857b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3862b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (i = 0; i < row_width; i++, sp += 8) 3863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3865b50c217251b086440efcdb273c22f86a06c80cbaChris Craik << 8) + (png_uint_16)(*(sp + 7))); 3866b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3867b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (a == 0) 3868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3869b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3870b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3871b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3872b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3873b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(png_ptr->background.green 3874b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3875b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3876b50c217251b086440efcdb273c22f86a06c80cbaChris Craik & 0xff); 3877b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3879b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (a < 0xffff) 3881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project + *(sp + 3)); 3887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project + *(sp + 5)); 3889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3890b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, r, a, png_ptr->background.red); 3891b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *sp = (png_byte)((v >> 8) & 0xff); 3892b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 1) = (png_byte)(v & 0xff); 3893b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3894b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, g, a, png_ptr->background.green); 3895b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3896b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 3) = (png_byte)(v & 0xff); 3897b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3898b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_composite_16(v, b, a, png_ptr->background.blue); 3899b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp + 5) = (png_byte)(v & 0xff); 3901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3908b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 3909b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 3910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 3913b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ 3914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 39155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED 3916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Gamma correct the image, avoiding the alpha channel. Make sure 3917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * you do this after you deal with the transparency issue on grayscale 3918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * or RGB images. If your bit depth is 8, use gamma_table, if it 3919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * is 16, use gamma_16_table and gamma_shift. Build these with 3920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * build_gamma_table(). 3921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 3922b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 3923b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 3925b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep gamma_table = png_ptr->gamma_table; 3926b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; 3927b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int gamma_shift = png_ptr->gamma_shift; 3928b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp; 3930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 3931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 3932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 39334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_gamma"); 39345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (((row_info->bit_depth <= 8 && gamma_table != NULL) || 3936b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->bit_depth == 16 && gamma_16_table != NULL))) 3937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->color_type) 3939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB: 3941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3955b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 3957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v; 3962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 3974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 3975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 3976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 3977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3981a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 3983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 3985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 3987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 3988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 3996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3997b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 3998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 3999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4001b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 4003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4011b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 4; 4021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4025a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 4027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4037b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (row_info->bit_depth == 16) */ 4039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 4; 4047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4051a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 4053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 2) 4055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i += 4) 4058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int a = *sp & 0xc0; 4060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int b = *sp & 0x30; 4061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int c = *sp & 0x0c; 4062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int d = *sp & 0x03; 4063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)( 40655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| 40665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| 40675f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| 40685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); 4069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4072a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 4) 4074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i += 2) 4077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int msb = *sp & 0xf0; 4079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int lsb = *sp & 0x0f; 4080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) 40825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); 4083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4086a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 8) 4088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = gamma_table[*sp]; 4093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 4094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4096a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row; 4100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *sp = (png_byte)((v >> 8) & 0xff); 4104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *(sp + 1) = (png_byte)(v & 0xff); 4105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += 2; 4106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 4116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 4117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Encode the alpha channel to the output gamma (the input channel is always 4120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * linear.) Called only with color types that have an alpha channel. Needs the 4121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * from_1 tables. 4122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4123b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4124b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 4125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 4126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 row_width = row_info->width; 4127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_debug(1, "in png_do_encode_alpha"); 4129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 4131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 4133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_bytep table = png_ptr->gamma_from_1; 4135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (table != NULL) 4137b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int step = 4139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; 4140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The alpha channel is the last component: */ 4142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row += step - 1; 4143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (; row_width > 0; --row_width, row += step) 4145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *row = table[*row]; 4146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 4148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (row_info->bit_depth == 16) 4152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; 4154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int gamma_shift = png_ptr->gamma_shift; 4155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (table != NULL) 4157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_CONST int step = 4159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; 4160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The alpha channel is the last component: */ 4162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row += step - 2; 4163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik for (; row_width > 0; --row_width, row += step) 4165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_16 v; 4167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik v = table[*(row + 1) >> gamma_shift][*row]; 4169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *row = (png_byte)((v >> 8) & 0xff); 4170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(row + 1) = (png_byte)(v & 0xff); 4171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 4174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Only get to here if called with a weird row_info; no harm has been done, 4179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * so just issue a warning. 4180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); 4182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 41855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 4186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expands a palette row to an RGB or RGBA row depending 4187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * upon whether you supply trans and num_trans. 4188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 4189b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand_palette(png_row_infop row_info, png_bytep row, 4191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) 4192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 4193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift, value; 4194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp, dp; 4195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 4196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 4197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 41984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_expand_palette"); 41995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4200b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth < 8) 4203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 4205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 4207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 3); 4209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7 - (int)((row_width + 7) & 0x07); 4211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((*sp >> shift) & 0x01) 4214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 1; 4215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0; 4218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 7) 4220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift++; 4227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4232a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 4234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 2); 4236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x03; 4241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)value; 4242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 6) 4243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 2; 4250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4255a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 4257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 1); 4259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((row_width & 0x01) << 2); 4261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x0f; 4264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)value; 4265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 4) 4266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 4; 4273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 8; 4284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width; 4285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8) 4288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (num_trans > 0) 4291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 2) - 1; 4294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((int)(*sp) >= num_trans) 4298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *dp-- = trans_alpha[*sp]; 4302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].blue; 4304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].green; 4305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].red; 4306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 32; 4310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 4; 4311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = 6; 4312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 4313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width * 3) - 1; 4319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].blue; 4323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].green; 4324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = palette[*sp].red; 4325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4327a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 24; 4330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width * 3; 4331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = 2; 4332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 3; 4333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* If the bit depth < 8, it is expanded to 8. Also, if the already 4340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * expanded transparency value is supplied, an alpha channel is built. 4341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 4342b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand(png_row_infop row_info, png_bytep row, 4344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_color_16p trans_color) 4345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 4346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift, value; 4347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp, dp; 4348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 4349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width=row_info->width; 4350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 43514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_expand"); 43525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 4355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int gray = trans_color ? trans_color->gray : 0; 4357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth < 8) 4359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->bit_depth) 4361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 4363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x01) * 0xff; 4365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 3); 4366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 7 - (int)((row_width + 7) & 0x07); 4368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((*sp >> shift) & 0x01) 4371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0xff; 4372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = 0; 4375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 7) 4377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift++; 4384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4389a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 4391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x03) * 0x55; 4393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 2); 4394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x03; 4399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)(value | (value << 2) | (value << 4) | 4400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (value << 6)); 4401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 6) 4402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += 2; 4409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4414a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 4416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik gray = (gray & 0x0f) * 0x11; 4418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)((row_width - 1) >> 1); 4419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)row_width - 1; 4420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 4421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x0f; 4424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = (png_byte)(value | (value << 4)); 4425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == 4) 4426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 0; 4428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 4429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = 4; 4433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 4435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 4437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 4440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 4441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4442a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->bit_depth = 8; 4444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = 8; 4445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = row_width; 4446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (trans_color != NULL) 4449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project gray = gray & 0xff; 4453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_width - 1; 4454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 1) - 1; 4455b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*sp == gray) 4459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4460b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4467a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int gray_high = (gray >> 8) & 0xff; 4471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik unsigned int gray_low = gray & 0xff; 4472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + row_info->rowbytes - 1; 4473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (row_info->rowbytes << 1) - 1; 4474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 44764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (*(sp - 1) == gray_high && *(sp) == gray_low) 4477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4492a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 4494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 2; 4495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); 4496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 4497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_width); 4498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4500b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) 4501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_info->bit_depth == 8) 4503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4504b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red = (png_byte)(trans_color->red & 0xff); 4505b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green = (png_byte)(trans_color->green & 0xff); 4506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue = (png_byte)(trans_color->blue & 0xff); 4507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + (png_size_t)row_info->rowbytes - 1; 4508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 2) - 1; 4509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) 4512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4516b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (row_info->bit_depth == 16) 4523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); 4525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); 4526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); 4527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte red_low = (png_byte)(trans_color->red & 0xff); 4528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte green_low = (png_byte)(trans_color->green & 0xff); 4529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte blue_low = (png_byte)(trans_color->blue & 0xff); 4530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp = row + row_info->rowbytes - 1; 4531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp = row + (png_size_t)(row_width << 3) - 1; 4532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 4533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*(sp - 5) == red_high && 4535b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 4) == red_low && 4536b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 3) == green_high && 4537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 2) == green_low && 4538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp - 1) == blue_high && 4539b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *(sp ) == blue_low) 4540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0; 4543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4544b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 4546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = 0xff; 4549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp-- = *sp--; 4557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 4560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->channels = 4; 4561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); 45624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_EXPAND_16_SUPPORTED 4569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* If the bit depth is 8 and the color type is not a palette type expand the 4570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * whole row to 16 bits. Has no effect otherwise. 4571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4572b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4573b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_do_expand_16(png_row_infop row_info, png_bytep row) 4574b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 4575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info->bit_depth == 8 && 4576b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->color_type != PNG_COLOR_TYPE_PALETTE) 4577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 4578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The row have a sequence of bytes containing [0..255] and we need 4579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * to turn it into another row containing [0..65535], to do this we 4580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * calculate: 4581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4582b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * (input / 255) * 65535 4583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 4584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Which happens to be exactly input * 257 and this can be achieved 4585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * simply by byte replication in place (copying backwards). 4586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 4587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ 4588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ 4589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik while (dp > sp) 4590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik dp[-2] = dp[-1] = *--sp, dp -= 2; 4591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->rowbytes *= 2; 4593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->bit_depth = 16; 4594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info->pixel_depth = (png_byte)(row_info->channels * 16); 4595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 4596b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 4597b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 4598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4599b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_QUANTIZE_SUPPORTED 4600b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic void 4601b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_quantize(png_row_infop row_info, png_bytep row, 4602b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_const_bytep palette_lookup, png_const_bytep quantize_lookup) 4603b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 4604b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_bytep sp, dp; 4605b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 i; 4606b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_uint_32 row_width=row_info->width; 4607b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4608b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_quantize"); 4609b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4610b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->bit_depth == 8) 4611b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4612b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) 4613b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4614b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int r, g, b, p; 4615b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4616b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp = row; 4617b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 4618b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4619b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari r = *sp++; 4620b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari g = *sp++; 4621b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari b = *sp++; 4622b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4623b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* This looks real messy, but the compiler will reduce 4624b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * it down to a reasonable formula. For example, with 4625b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 5 bits per color, we get: 4626b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * p = (((r >> 3) & 0x1f) << 10) | 4627b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * (((g >> 3) & 0x1f) << 5) | 4628b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * ((b >> 3) & 0x1f); 4629b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4630b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4631b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4632b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4633b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4634b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4635b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_BLUE_BITS)) | 4636b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4637b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4638b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4639b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp++ = palette_lookup[p]; 4640b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4641b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4642b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4643b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = 1; 4644b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = row_info->bit_depth; 4645b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4646b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4647b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4648b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 4649b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari palette_lookup != NULL) 4650b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4651b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int r, g, b, p; 4652b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4653b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari dp = row; 4654b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++) 4655b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4656b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari r = *sp++; 4657b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari g = *sp++; 4658b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari b = *sp++; 4659b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp++; 4660b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4661b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4662b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4663b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4664b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4665b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4666b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (PNG_QUANTIZE_BLUE_BITS)) | 4667b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4668b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4669b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4670b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *dp++ = palette_lookup[p]; 4671b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4672b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4673b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4674b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = 1; 4675b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = row_info->bit_depth; 4676b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4677b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4678b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4679b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4680b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari quantize_lookup) 4681b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4682b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari sp = row; 4683b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4684b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (i = 0; i < row_width; i++, sp++) 4685b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4686b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari *sp = quantize_lookup[*sp]; 4687b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4688b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4689b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4690b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari} 4691b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 4692b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4693b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* Transform the row. The order of transformations is significant, 4694b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * and is very touchy. If you add a transformation, take care to 4695b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * decide how it fits in with the other transformations here. 4696b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4697b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurarivoid /* PRIVATE */ 4698b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) 4699b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 4700b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_debug(1, "in png_do_read_transformations"); 4701b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4702b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->row_buf == NULL) 4703b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4704b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this 4705b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * error is incredibly rare and incredibly easy to debug without this 4706b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * information. 4707b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4708b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "NULL row buffer"); 4709b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4710b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4711b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* The following is debugging; prior to 1.5.4 the code was never compiled in; 4712b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro 4713b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for 4714b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * all transformations, however in practice the ROW_INIT always gets done on 4715b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * demand, if necessary. 4716b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4717b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && 4718b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari !(png_ptr->flags & PNG_FLAG_ROW_INIT)) 4719b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4720b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Application has failed to call either png_read_start_image() or 4721b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_read_update_info() after setting transforms that expand pixels. 4722b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * This check added to libpng-1.2.19 (but not enabled until 1.5.4). 4723b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4724b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "Uninitialized row"); 4725b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4726b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4727b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_EXPAND_SUPPORTED 4728b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_EXPAND) 4729b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4730b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4731b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4732b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand_palette(row_info, png_ptr->row_buf + 1, 4733b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); 4734b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4735b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4736b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 4737b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4738b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->num_trans && 4739b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->transformations & PNG_EXPAND_tRNS)) 4740b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand(row_info, png_ptr->row_buf + 1, 4741b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari &(png_ptr->trans_color)); 4742b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4743b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 4744b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand(row_info, png_ptr->row_buf + 1, 4745b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari NULL); 4746b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4747b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4748b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4749b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4750b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 4751b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 4752b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari !(png_ptr->transformations & PNG_COMPOSE) && 4753b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 4754b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4755b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_strip_channel(row_info, png_ptr->row_buf + 1, 4756b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 0 /* at_start == false, because SWAP_ALPHA happens later */); 4757b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4758b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4759b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 4760b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_RGB_TO_GRAY) 4761b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4762b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int rgb_error = 4763b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_rgb_to_gray(png_ptr, row_info, 4764b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->row_buf + 1); 4765b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4766b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (rgb_error) 4767b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4768b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->rgb_to_gray_status=1; 4769b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4770b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari PNG_RGB_TO_GRAY_WARN) 4771b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4772b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4773b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4774b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari PNG_RGB_TO_GRAY_ERR) 4775b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4776b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4777b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4778b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4779b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4780b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* From Andreas Dilger e-mail to png-implement, 26 March 1998: 4781b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4782b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * In most cases, the "simple transparency" should be done prior to doing 4783b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * gray-to-RGB, or you will have to test 3x as many bytes to check if a 4784b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * pixel is transparent. You would also need to make sure that the 4785b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * transparency information is upgraded to RGB. 4786b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4787b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * To summarize, the current flow is: 4788b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite 4789b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * with background "in place" if transparent, 4790b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * convert to RGB if necessary 4791b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + alpha -> composite with gray background and remove alpha bytes, 4792b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * convert to RGB if necessary 4793b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4794b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * To support RGB backgrounds for gray images we need: 4795b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + simple transparency -> convert to RGB + simple transparency, 4796b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * compare 3 or 6 bytes and composite with 4797b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * background "in place" if transparent 4798b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * (3x compare/pixel compared to doing 4799b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * composite with gray bkgrnd) 4800b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * - Gray + alpha -> convert to RGB + alpha, composite with background and 4801b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * remove alpha bytes (3x float 4802b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * operations/pixel compared with composite 4803b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * on gray background) 4804b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 4805b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Greg's change will do this. The reason it wasn't done before is for 4806b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * performance, as this increases the per-pixel operations. If we would check 4807b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * in advance if the background was gray or RGB, and position the gray-to-RGB 4808b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * transform appropriately, then it would save a lot of work/time. 4809b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4810b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4811b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4812b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* If gray -> RGB, do so now only if background is non-gray; else do later 4813b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * for performance reasons 4814b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4815b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 4816b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 4817b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4818b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4819b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4820b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4821b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari defined(PNG_READ_ALPHA_MODE_SUPPORTED) 4822b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_COMPOSE) 4823b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); 4824b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4826b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GAMMA_SUPPORTED 4827b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_GAMMA) && 4828b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 4829b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because RGB_TO_GRAY does the gamma transform. */ 4830b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari !(png_ptr->transformations & PNG_RGB_TO_GRAY) && 4831b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4832b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4833b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari defined(PNG_READ_ALPHA_MODE_SUPPORTED) 4834b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because PNG_COMPOSE does the gamma transform if there is something to 4835b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * do (if there is an alpha channel or transparency.) 4836b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4837b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari !((png_ptr->transformations & PNG_COMPOSE) && 4838b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari ((png_ptr->num_trans != 0) || 4839b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && 4840b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4841b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Because png_init_read_transformations transforms the palette, unless 4842b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * RGB_TO_GRAY will do the transform. 4843b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4844b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) 4845b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); 4846b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 48475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4848b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 4849b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 4850b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->transformations & PNG_COMPOSE) && 4851b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 4852b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4853b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_strip_channel(row_info, png_ptr->row_buf + 1, 4854b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 0 /* at_start == false, because SWAP_ALPHA happens later */); 4855b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4857b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4858b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && 4859b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (row_info->color_type & PNG_COLOR_MASK_ALPHA)) 4860b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); 4861b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4863b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 4864b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_SCALE_16_TO_8) 4865b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); 4866b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4867b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4868b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 4869b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* There is no harm in doing both of these because only one has any effect, 4870b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * by putting the 'scale' option first if the app asks for scale (either by 4871b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * calling the API or in a TRANSFORM flag) this is what happens. 4872b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4873b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_16_TO_8) 4874b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_chop(row_info, png_ptr->row_buf + 1); 4875b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4876b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4877b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_QUANTIZE_SUPPORTED 4878b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_QUANTIZE) 4879b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4880b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_quantize(row_info, png_ptr->row_buf + 1, 4881b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->palette_lookup, png_ptr->quantize_index); 4882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4883b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->rowbytes == 0) 4884b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "png_do_quantize returned rowbytes=0"); 4885b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 4886b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 4887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4888b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_EXPAND_16_SUPPORTED 4889b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Do the expansion now, after all the arithmetic has been done. Notice 4890b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * that previous transformations can handle the PNG_EXPAND_16 flag if this 4891b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * is efficient (particularly true in the case of gamma correction, where 4892b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * better accuracy results faster!) 4893b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 4894b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_EXPAND_16) 4895b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_expand_16(row_info, png_ptr->row_buf + 1); 4896b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4897b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4898b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4899b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* NOTE: moved here in 1.5.4 (from much later in this list.) */ 4900b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 4901b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 4902b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4903b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4904b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4905b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_INVERT_SUPPORTED 4906b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_INVERT_MONO) 4907b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_invert(row_info, png_ptr->row_buf + 1); 4908b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4909b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4910b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 4911b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_INVERT_ALPHA) 4912b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); 4913b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4915b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SHIFT_SUPPORTED 4916b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_SHIFT) 4917b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_unshift(row_info, png_ptr->row_buf + 1, 4918b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari &(png_ptr->shift)); 4919b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 49205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4921b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACK_SUPPORTED 4922b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_PACK) 4923b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_unpack(row_info, png_ptr->row_buf + 1); 4924b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4925b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 4926b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 4927b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Added at libpng-1.5.10 */ 4928b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4929b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->num_palette_max >= 0) 4930b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_check_palette_indexes(png_ptr, row_info); 4931b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4933b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_BGR_SUPPORTED 4934b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_BGR) 4935b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_bgr(row_info, png_ptr->row_buf + 1); 4936b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4937a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4938b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_PACKSWAP_SUPPORTED 4939b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_PACKSWAP) 4940b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_packswap(row_info, png_ptr->row_buf + 1); 4941b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4942a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4943b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_FILLER_SUPPORTED 4944b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_FILLER) 4945b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_filler(row_info, png_ptr->row_buf + 1, 4946b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_uint_32)png_ptr->filler, png_ptr->flags); 4947b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4949b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 4950b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_SWAP_ALPHA) 4951b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); 4952b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4954b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_16BIT_SUPPORTED 4955b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_SWAP_SUPPORTED 4956b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_SWAP_BYTES) 4957b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_do_swap(row_info, png_ptr->row_buf + 1); 4958b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4959b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4960a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4961b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 4962b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->transformations & PNG_USER_TRANSFORM) 4963b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 4964b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->read_user_transform_fn != NULL) 4965b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (*(png_ptr->read_user_transform_fn)) /* User read transform function */ 4966b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari (png_ptr, /* png_ptr */ 4967b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info, /* row_info: */ 4968b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_uint_32 width; width of row */ 4969b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_size_t rowbytes; number of bytes in row */ 4970b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte color_type; color type of pixels */ 4971b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte bit_depth; bit depth of samples */ 4972b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte channels; number of channels (1-4) */ 4973b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* png_byte pixel_depth; bits per pixel (depth*channels) */ 4974b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->row_buf + 1); /* start of pixel data for row */ 4975b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED 4976b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->user_transform_depth) 4977b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->bit_depth = png_ptr->user_transform_depth; 4978a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4979b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (png_ptr->user_transform_channels) 4980b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels = png_ptr->user_transform_channels; 4981b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4982b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->pixel_depth = (png_byte)(row_info->bit_depth * 4983b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->channels); 4984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4985b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); 4986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4987b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 4988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 4989b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 4990b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 4991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED */ 4992