| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 1 |  | 
|  | 2 | /* pngtrans.c - transforms the data in a row (used by both readers and writers) | 
|  | 3 | * | 
| Sireesh Tripurari | b478e66 | 2014-05-09 15:15:10 +0530 | [diff] [blame] | 4 | * Last changed in libpng 1.6.9 [February 6, 2014] | 
|  | 5 | * Copyright (c) 1998-2014 Glenn Randers-Pehrson | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 6 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) | 
|  | 7 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 8 | * | 
|  | 9 | * This code is released under the libpng license. | 
|  | 10 | * For conditions of distribution and use, see the disclaimer | 
|  | 11 | * and license in png.h | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 12 | */ | 
|  | 13 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 14 | #include "pngpriv.h" | 
|  | 15 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 16 | #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 17 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 18 | #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 19 | /* Turn on BGR-to-RGB mapping */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 20 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 21 | png_set_bgr(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 22 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 23 | png_debug(1, "in png_set_bgr"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 24 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 25 | if (png_ptr == NULL) | 
|  | 26 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 27 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 28 | png_ptr->transformations |= PNG_BGR; | 
|  | 29 | } | 
|  | 30 | #endif | 
|  | 31 |  | 
|  | 32 | #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 33 | /* Turn on 16 bit byte swapping */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 34 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 35 | png_set_swap(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 36 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 37 | png_debug(1, "in png_set_swap"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 38 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 39 | if (png_ptr == NULL) | 
|  | 40 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 41 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 42 | if (png_ptr->bit_depth == 16) | 
|  | 43 | png_ptr->transformations |= PNG_SWAP_BYTES; | 
|  | 44 | } | 
|  | 45 | #endif | 
|  | 46 |  | 
|  | 47 | #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 48 | /* Turn on pixel packing */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 49 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 50 | png_set_packing(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 51 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 52 | png_debug(1, "in png_set_packing"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 53 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 54 | if (png_ptr == NULL) | 
|  | 55 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 56 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 57 | if (png_ptr->bit_depth < 8) | 
|  | 58 | { | 
|  | 59 | png_ptr->transformations |= PNG_PACK; | 
| Sireesh Tripurari | b478e66 | 2014-05-09 15:15:10 +0530 | [diff] [blame] | 60 | #     ifdef PNG_WRITE_SUPPORTED | 
|  | 61 | png_ptr->usr_bit_depth = 8; | 
|  | 62 | #     endif | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 63 | } | 
|  | 64 | } | 
|  | 65 | #endif | 
|  | 66 |  | 
|  | 67 | #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 68 | /* Turn on packed pixel swapping */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 69 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 70 | png_set_packswap(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 71 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 72 | png_debug(1, "in png_set_packswap"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 73 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 74 | if (png_ptr == NULL) | 
|  | 75 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 76 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 77 | if (png_ptr->bit_depth < 8) | 
|  | 78 | png_ptr->transformations |= PNG_PACKSWAP; | 
|  | 79 | } | 
|  | 80 | #endif | 
|  | 81 |  | 
|  | 82 | #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) | 
|  | 83 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 84 | png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 85 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 86 | png_debug(1, "in png_set_shift"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 87 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 88 | if (png_ptr == NULL) | 
|  | 89 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 90 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 91 | png_ptr->transformations |= PNG_SHIFT; | 
|  | 92 | png_ptr->shift = *true_bits; | 
|  | 93 | } | 
|  | 94 | #endif | 
|  | 95 |  | 
|  | 96 | #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ | 
|  | 97 | defined(PNG_WRITE_INTERLACING_SUPPORTED) | 
|  | 98 | int PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 99 | png_set_interlace_handling(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 100 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 101 | png_debug(1, "in png_set_interlace handling"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 102 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 103 | if (png_ptr && png_ptr->interlaced) | 
|  | 104 | { | 
|  | 105 | png_ptr->transformations |= PNG_INTERLACE; | 
|  | 106 | return (7); | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | return (1); | 
|  | 110 | } | 
|  | 111 | #endif | 
|  | 112 |  | 
|  | 113 | #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) | 
|  | 114 | /* Add a filler byte on read, or remove a filler or alpha byte on write. | 
|  | 115 | * The filler type has changed in v0.95 to allow future 2-byte fillers | 
|  | 116 | * for 48-bit input data, as well as to avoid problems with some compilers | 
|  | 117 | * that don't like bytes as parameters. | 
|  | 118 | */ | 
|  | 119 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 120 | png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 121 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 122 | png_debug(1, "in png_set_filler"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 123 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 124 | if (png_ptr == NULL) | 
|  | 125 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 126 |  | 
|  | 127 | /* In libpng 1.6 it is possible to determine whether this is a read or write | 
|  | 128 | * operation and therefore to do more checking here for a valid call. | 
|  | 129 | */ | 
|  | 130 | if (png_ptr->mode & PNG_IS_READ_STRUCT) | 
|  | 131 | { | 
|  | 132 | #     ifdef PNG_READ_FILLER_SUPPORTED | 
|  | 133 | /* On read png_set_filler is always valid, regardless of the base PNG | 
|  | 134 | * format, because other transformations can give a format where the | 
|  | 135 | * filler code can execute (basically an 8 or 16-bit component RGB or G | 
|  | 136 | * format.) | 
|  | 137 | * | 
|  | 138 | * NOTE: usr_channels is not used by the read code!  (This has led to | 
|  | 139 | * confusion in the past.)  The filler is only used in the read code. | 
|  | 140 | */ | 
|  | 141 | png_ptr->filler = (png_uint_16)filler; | 
|  | 142 | #     else | 
|  | 143 | png_app_error(png_ptr, "png_set_filler not supported on read"); | 
|  | 144 | PNG_UNUSED(filler) /* not used in the write case */ | 
|  | 145 | return; | 
|  | 146 | #     endif | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | else /* write */ | 
|  | 150 | { | 
|  | 151 | #     ifdef PNG_WRITE_FILLER_SUPPORTED | 
|  | 152 | /* On write the usr_channels parameter must be set correctly at the | 
|  | 153 | * start to record the number of channels in the app-supplied data. | 
|  | 154 | */ | 
|  | 155 | switch (png_ptr->color_type) | 
|  | 156 | { | 
|  | 157 | case PNG_COLOR_TYPE_RGB: | 
|  | 158 | png_ptr->usr_channels = 4; | 
|  | 159 | break; | 
|  | 160 |  | 
|  | 161 | case PNG_COLOR_TYPE_GRAY: | 
|  | 162 | if (png_ptr->bit_depth >= 8) | 
|  | 163 | { | 
|  | 164 | png_ptr->usr_channels = 2; | 
|  | 165 | break; | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 | else | 
|  | 169 | { | 
|  | 170 | /* There simply isn't any code in libpng to strip out bits | 
|  | 171 | * from bytes when the components are less than a byte in | 
|  | 172 | * size! | 
|  | 173 | */ | 
|  | 174 | png_app_error(png_ptr, | 
|  | 175 | "png_set_filler is invalid for low bit depth gray output"); | 
|  | 176 | return; | 
|  | 177 | } | 
|  | 178 |  | 
|  | 179 | default: | 
|  | 180 | png_app_error(png_ptr, | 
|  | 181 | "png_set_filler: inappropriate color type"); | 
|  | 182 | return; | 
|  | 183 | } | 
|  | 184 | #     else | 
|  | 185 | png_app_error(png_ptr, "png_set_filler not supported on write"); | 
|  | 186 | return; | 
|  | 187 | #     endif | 
|  | 188 | } | 
|  | 189 |  | 
|  | 190 | /* Here on success - libpng supports the operation, set the transformation | 
|  | 191 | * and the flag to say where the filler channel is. | 
|  | 192 | */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 193 | png_ptr->transformations |= PNG_FILLER; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 194 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 195 | if (filler_loc == PNG_FILLER_AFTER) | 
|  | 196 | png_ptr->flags |= PNG_FLAG_FILLER_AFTER; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 197 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 198 | else | 
|  | 199 | png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 200 | } | 
|  | 201 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 202 | /* Added to libpng-1.2.7 */ | 
|  | 203 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 204 | png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 205 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 206 | png_debug(1, "in png_set_add_alpha"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 207 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 208 | if (png_ptr == NULL) | 
|  | 209 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 210 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 211 | png_set_filler(png_ptr, filler, filler_loc); | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 212 | /* The above may fail to do anything. */ | 
|  | 213 | if (png_ptr->transformations & PNG_FILLER) | 
|  | 214 | png_ptr->transformations |= PNG_ADD_ALPHA; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 215 | } | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 216 |  | 
|  | 217 | #endif | 
|  | 218 |  | 
|  | 219 | #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ | 
|  | 220 | defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) | 
|  | 221 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 222 | png_set_swap_alpha(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 223 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 224 | png_debug(1, "in png_set_swap_alpha"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 225 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 226 | if (png_ptr == NULL) | 
|  | 227 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 228 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 229 | png_ptr->transformations |= PNG_SWAP_ALPHA; | 
|  | 230 | } | 
|  | 231 | #endif | 
|  | 232 |  | 
|  | 233 | #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ | 
|  | 234 | defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) | 
|  | 235 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 236 | png_set_invert_alpha(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 237 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 238 | png_debug(1, "in png_set_invert_alpha"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 239 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 240 | if (png_ptr == NULL) | 
|  | 241 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 242 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 243 | png_ptr->transformations |= PNG_INVERT_ALPHA; | 
|  | 244 | } | 
|  | 245 | #endif | 
|  | 246 |  | 
|  | 247 | #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) | 
|  | 248 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 249 | png_set_invert_mono(png_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 250 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 251 | png_debug(1, "in png_set_invert_mono"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 252 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 253 | if (png_ptr == NULL) | 
|  | 254 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 255 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 256 | png_ptr->transformations |= PNG_INVERT_MONO; | 
|  | 257 | } | 
|  | 258 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 259 | /* Invert monochrome grayscale data */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 260 | void /* PRIVATE */ | 
|  | 261 | png_do_invert(png_row_infop row_info, png_bytep row) | 
|  | 262 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 263 | png_debug(1, "in png_do_invert"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 264 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 265 | /* This test removed from libpng version 1.0.13 and 1.2.0: | 
|  | 266 | *   if (row_info->bit_depth == 1 && | 
|  | 267 | */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 268 | if (row_info->color_type == PNG_COLOR_TYPE_GRAY) | 
|  | 269 | { | 
|  | 270 | png_bytep rp = row; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 271 | png_size_t i; | 
|  | 272 | png_size_t istop = row_info->rowbytes; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 273 |  | 
|  | 274 | for (i = 0; i < istop; i++) | 
|  | 275 | { | 
|  | 276 | *rp = (png_byte)(~(*rp)); | 
|  | 277 | rp++; | 
|  | 278 | } | 
|  | 279 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 280 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 281 | else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && | 
|  | 282 | row_info->bit_depth == 8) | 
|  | 283 | { | 
|  | 284 | png_bytep rp = row; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 285 | png_size_t i; | 
|  | 286 | png_size_t istop = row_info->rowbytes; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 287 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 288 | for (i = 0; i < istop; i += 2) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 289 | { | 
|  | 290 | *rp = (png_byte)(~(*rp)); | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 291 | rp += 2; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 292 | } | 
|  | 293 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 294 |  | 
|  | 295 | #ifdef PNG_16BIT_SUPPORTED | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 296 | else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && | 
|  | 297 | row_info->bit_depth == 16) | 
|  | 298 | { | 
|  | 299 | png_bytep rp = row; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 300 | png_size_t i; | 
|  | 301 | png_size_t istop = row_info->rowbytes; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 302 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 303 | for (i = 0; i < istop; i += 4) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 304 | { | 
|  | 305 | *rp = (png_byte)(~(*rp)); | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 306 | *(rp + 1) = (png_byte)(~(*(rp + 1))); | 
|  | 307 | rp += 4; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 308 | } | 
|  | 309 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 310 | #endif | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 311 | } | 
|  | 312 | #endif | 
|  | 313 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 314 | #ifdef PNG_16BIT_SUPPORTED | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 315 | #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 316 | /* Swaps byte order on 16 bit depth images */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 317 | void /* PRIVATE */ | 
|  | 318 | png_do_swap(png_row_infop row_info, png_bytep row) | 
|  | 319 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 320 | png_debug(1, "in png_do_swap"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 321 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 322 | if (row_info->bit_depth == 16) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 323 | { | 
|  | 324 | png_bytep rp = row; | 
|  | 325 | png_uint_32 i; | 
|  | 326 | png_uint_32 istop= row_info->width * row_info->channels; | 
|  | 327 |  | 
|  | 328 | for (i = 0; i < istop; i++, rp += 2) | 
|  | 329 | { | 
|  | 330 | png_byte t = *rp; | 
|  | 331 | *rp = *(rp + 1); | 
|  | 332 | *(rp + 1) = t; | 
|  | 333 | } | 
|  | 334 | } | 
|  | 335 | } | 
|  | 336 | #endif | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 337 | #endif | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 338 |  | 
|  | 339 | #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) | 
|  | 340 | static PNG_CONST png_byte onebppswaptable[256] = { | 
|  | 341 | 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, | 
|  | 342 | 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, | 
|  | 343 | 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, | 
|  | 344 | 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, | 
|  | 345 | 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, | 
|  | 346 | 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, | 
|  | 347 | 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, | 
|  | 348 | 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, | 
|  | 349 | 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, | 
|  | 350 | 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, | 
|  | 351 | 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, | 
|  | 352 | 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, | 
|  | 353 | 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, | 
|  | 354 | 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, | 
|  | 355 | 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, | 
|  | 356 | 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, | 
|  | 357 | 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, | 
|  | 358 | 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, | 
|  | 359 | 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, | 
|  | 360 | 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, | 
|  | 361 | 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, | 
|  | 362 | 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, | 
|  | 363 | 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, | 
|  | 364 | 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, | 
|  | 365 | 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, | 
|  | 366 | 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, | 
|  | 367 | 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, | 
|  | 368 | 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, | 
|  | 369 | 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, | 
|  | 370 | 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, | 
|  | 371 | 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, | 
|  | 372 | 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF | 
|  | 373 | }; | 
|  | 374 |  | 
|  | 375 | static PNG_CONST png_byte twobppswaptable[256] = { | 
|  | 376 | 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, | 
|  | 377 | 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, | 
|  | 378 | 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, | 
|  | 379 | 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, | 
|  | 380 | 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, | 
|  | 381 | 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, | 
|  | 382 | 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, | 
|  | 383 | 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, | 
|  | 384 | 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, | 
|  | 385 | 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, | 
|  | 386 | 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, | 
|  | 387 | 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, | 
|  | 388 | 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, | 
|  | 389 | 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, | 
|  | 390 | 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, | 
|  | 391 | 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, | 
|  | 392 | 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, | 
|  | 393 | 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, | 
|  | 394 | 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, | 
|  | 395 | 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, | 
|  | 396 | 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, | 
|  | 397 | 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, | 
|  | 398 | 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, | 
|  | 399 | 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, | 
|  | 400 | 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, | 
|  | 401 | 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, | 
|  | 402 | 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, | 
|  | 403 | 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, | 
|  | 404 | 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, | 
|  | 405 | 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, | 
|  | 406 | 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, | 
|  | 407 | 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF | 
|  | 408 | }; | 
|  | 409 |  | 
|  | 410 | static PNG_CONST png_byte fourbppswaptable[256] = { | 
|  | 411 | 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, | 
|  | 412 | 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, | 
|  | 413 | 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, | 
|  | 414 | 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, | 
|  | 415 | 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, | 
|  | 416 | 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, | 
|  | 417 | 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, | 
|  | 418 | 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, | 
|  | 419 | 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, | 
|  | 420 | 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, | 
|  | 421 | 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, | 
|  | 422 | 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, | 
|  | 423 | 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, | 
|  | 424 | 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, | 
|  | 425 | 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, | 
|  | 426 | 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, | 
|  | 427 | 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, | 
|  | 428 | 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, | 
|  | 429 | 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, | 
|  | 430 | 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, | 
|  | 431 | 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, | 
|  | 432 | 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, | 
|  | 433 | 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, | 
|  | 434 | 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, | 
|  | 435 | 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, | 
|  | 436 | 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, | 
|  | 437 | 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, | 
|  | 438 | 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, | 
|  | 439 | 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, | 
|  | 440 | 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, | 
|  | 441 | 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, | 
|  | 442 | 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF | 
|  | 443 | }; | 
|  | 444 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 445 | /* Swaps pixel packing order within bytes */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 446 | void /* PRIVATE */ | 
|  | 447 | png_do_packswap(png_row_infop row_info, png_bytep row) | 
|  | 448 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 449 | png_debug(1, "in png_do_packswap"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 450 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 451 | if (row_info->bit_depth < 8) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 452 | { | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 453 | png_bytep rp; | 
|  | 454 | png_const_bytep end, table; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 455 |  | 
|  | 456 | end = row + row_info->rowbytes; | 
|  | 457 |  | 
|  | 458 | if (row_info->bit_depth == 1) | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 459 | table = onebppswaptable; | 
|  | 460 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 461 | else if (row_info->bit_depth == 2) | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 462 | table = twobppswaptable; | 
|  | 463 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 464 | else if (row_info->bit_depth == 4) | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 465 | table = fourbppswaptable; | 
|  | 466 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 467 | else | 
|  | 468 | return; | 
|  | 469 |  | 
|  | 470 | for (rp = row; rp < end; rp++) | 
|  | 471 | *rp = table[*rp]; | 
|  | 472 | } | 
|  | 473 | } | 
|  | 474 | #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ | 
|  | 475 |  | 
|  | 476 | #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ | 
|  | 477 | defined(PNG_READ_STRIP_ALPHA_SUPPORTED) | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 478 | /* Remove a channel - this used to be 'png_do_strip_filler' but it used a | 
|  | 479 | * somewhat weird combination of flags to determine what to do.  All the calls | 
|  | 480 | * to png_do_strip_filler are changed in 1.5.2 to call this instead with the | 
|  | 481 | * correct arguments. | 
|  | 482 | * | 
|  | 483 | * The routine isn't general - the channel must be the channel at the start or | 
|  | 484 | * end (not in the middle) of each pixel. | 
|  | 485 | */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 486 | void /* PRIVATE */ | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 487 | png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 488 | { | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 489 | png_bytep sp = row; /* source pointer */ | 
|  | 490 | png_bytep dp = row; /* destination pointer */ | 
|  | 491 | png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 492 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 493 | /* At the start sp will point to the first byte to copy and dp to where | 
|  | 494 | * it is copied to.  ep always points just beyond the end of the row, so | 
|  | 495 | * the loop simply copies (channels-1) channels until sp reaches ep. | 
|  | 496 | * | 
|  | 497 | * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. | 
|  | 498 | *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. | 
|  | 499 | */ | 
|  | 500 |  | 
|  | 501 | /* GA, GX, XG cases */ | 
|  | 502 | if (row_info->channels == 2) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 503 | { | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 504 | if (row_info->bit_depth == 8) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 505 | { | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 506 | if (at_start) /* Skip initial filler */ | 
|  | 507 | ++sp; | 
|  | 508 | else          /* Skip initial channel and, for sp, the filler */ | 
|  | 509 | sp += 2, ++dp; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 510 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 511 | /* For a 1 pixel wide image there is nothing to do */ | 
|  | 512 | while (sp < ep) | 
|  | 513 | *dp++ = *sp, sp += 2; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 514 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 515 | row_info->pixel_depth = 8; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 516 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 517 |  | 
|  | 518 | else if (row_info->bit_depth == 16) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 519 | { | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 520 | if (at_start) /* Skip initial filler */ | 
|  | 521 | sp += 2; | 
|  | 522 | else          /* Skip initial channel and, for sp, the filler */ | 
|  | 523 | sp += 4, dp += 2; | 
|  | 524 |  | 
|  | 525 | while (sp < ep) | 
|  | 526 | *dp++ = *sp++, *dp++ = *sp, sp += 3; | 
|  | 527 |  | 
|  | 528 | row_info->pixel_depth = 16; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 529 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 530 |  | 
|  | 531 | else | 
|  | 532 | return; /* bad bit depth */ | 
|  | 533 |  | 
|  | 534 | row_info->channels = 1; | 
|  | 535 |  | 
|  | 536 | /* Finally fix the color type if it records an alpha channel */ | 
|  | 537 | if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 
|  | 538 | row_info->color_type = PNG_COLOR_TYPE_GRAY; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 539 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 540 |  | 
|  | 541 | /* RGBA, RGBX, XRGB cases */ | 
|  | 542 | else if (row_info->channels == 4) | 
|  | 543 | { | 
|  | 544 | if (row_info->bit_depth == 8) | 
|  | 545 | { | 
|  | 546 | if (at_start) /* Skip initial filler */ | 
|  | 547 | ++sp; | 
|  | 548 | else          /* Skip initial channels and, for sp, the filler */ | 
|  | 549 | sp += 4, dp += 3; | 
|  | 550 |  | 
|  | 551 | /* Note that the loop adds 3 to dp and 4 to sp each time. */ | 
|  | 552 | while (sp < ep) | 
|  | 553 | *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; | 
|  | 554 |  | 
|  | 555 | row_info->pixel_depth = 24; | 
|  | 556 | } | 
|  | 557 |  | 
|  | 558 | else if (row_info->bit_depth == 16) | 
|  | 559 | { | 
|  | 560 | if (at_start) /* Skip initial filler */ | 
|  | 561 | sp += 2; | 
|  | 562 | else          /* Skip initial channels and, for sp, the filler */ | 
|  | 563 | sp += 8, dp += 6; | 
|  | 564 |  | 
|  | 565 | while (sp < ep) | 
|  | 566 | { | 
|  | 567 | /* Copy 6 bytes, skip 2 */ | 
|  | 568 | *dp++ = *sp++, *dp++ = *sp++; | 
|  | 569 | *dp++ = *sp++, *dp++ = *sp++; | 
|  | 570 | *dp++ = *sp++, *dp++ = *sp, sp += 3; | 
|  | 571 | } | 
|  | 572 |  | 
|  | 573 | row_info->pixel_depth = 48; | 
|  | 574 | } | 
|  | 575 |  | 
|  | 576 | else | 
|  | 577 | return; /* bad bit depth */ | 
|  | 578 |  | 
|  | 579 | row_info->channels = 3; | 
|  | 580 |  | 
|  | 581 | /* Finally fix the color type if it records an alpha channel */ | 
|  | 582 | if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 
|  | 583 | row_info->color_type = PNG_COLOR_TYPE_RGB; | 
|  | 584 | } | 
|  | 585 |  | 
|  | 586 | else | 
|  | 587 | return; /* The filler channel has gone already */ | 
|  | 588 |  | 
|  | 589 | /* Fix the rowbytes value. */ | 
|  | 590 | row_info->rowbytes = dp-row; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 591 | } | 
|  | 592 | #endif | 
|  | 593 |  | 
|  | 594 | #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 595 | /* Swaps red and blue bytes within a pixel */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 596 | void /* PRIVATE */ | 
|  | 597 | png_do_bgr(png_row_infop row_info, png_bytep row) | 
|  | 598 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 599 | png_debug(1, "in png_do_bgr"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 600 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 601 | if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 602 | { | 
|  | 603 | png_uint_32 row_width = row_info->width; | 
|  | 604 | if (row_info->bit_depth == 8) | 
|  | 605 | { | 
|  | 606 | if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 
|  | 607 | { | 
|  | 608 | png_bytep rp; | 
|  | 609 | png_uint_32 i; | 
|  | 610 |  | 
|  | 611 | for (i = 0, rp = row; i < row_width; i++, rp += 3) | 
|  | 612 | { | 
|  | 613 | png_byte save = *rp; | 
|  | 614 | *rp = *(rp + 2); | 
|  | 615 | *(rp + 2) = save; | 
|  | 616 | } | 
|  | 617 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 618 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 619 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 
|  | 620 | { | 
|  | 621 | png_bytep rp; | 
|  | 622 | png_uint_32 i; | 
|  | 623 |  | 
|  | 624 | for (i = 0, rp = row; i < row_width; i++, rp += 4) | 
|  | 625 | { | 
|  | 626 | png_byte save = *rp; | 
|  | 627 | *rp = *(rp + 2); | 
|  | 628 | *(rp + 2) = save; | 
|  | 629 | } | 
|  | 630 | } | 
|  | 631 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 632 |  | 
|  | 633 | #ifdef PNG_16BIT_SUPPORTED | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 634 | else if (row_info->bit_depth == 16) | 
|  | 635 | { | 
|  | 636 | if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 
|  | 637 | { | 
|  | 638 | png_bytep rp; | 
|  | 639 | png_uint_32 i; | 
|  | 640 |  | 
|  | 641 | for (i = 0, rp = row; i < row_width; i++, rp += 6) | 
|  | 642 | { | 
|  | 643 | png_byte save = *rp; | 
|  | 644 | *rp = *(rp + 4); | 
|  | 645 | *(rp + 4) = save; | 
|  | 646 | save = *(rp + 1); | 
|  | 647 | *(rp + 1) = *(rp + 5); | 
|  | 648 | *(rp + 5) = save; | 
|  | 649 | } | 
|  | 650 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 651 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 652 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 
|  | 653 | { | 
|  | 654 | png_bytep rp; | 
|  | 655 | png_uint_32 i; | 
|  | 656 |  | 
|  | 657 | for (i = 0, rp = row; i < row_width; i++, rp += 8) | 
|  | 658 | { | 
|  | 659 | png_byte save = *rp; | 
|  | 660 | *rp = *(rp + 4); | 
|  | 661 | *(rp + 4) = save; | 
|  | 662 | save = *(rp + 1); | 
|  | 663 | *(rp + 1) = *(rp + 5); | 
|  | 664 | *(rp + 5) = save; | 
|  | 665 | } | 
|  | 666 | } | 
|  | 667 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 668 | #endif | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 669 | } | 
|  | 670 | } | 
|  | 671 | #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ | 
|  | 672 |  | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 673 | #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ | 
|  | 674 | defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) | 
|  | 675 | /* Added at libpng-1.5.10 */ | 
|  | 676 | void /* PRIVATE */ | 
|  | 677 | png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) | 
|  | 678 | { | 
|  | 679 | if (png_ptr->num_palette < (1 << row_info->bit_depth) && | 
|  | 680 | png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ | 
|  | 681 | { | 
|  | 682 | /* Calculations moved outside switch in an attempt to stop different | 
|  | 683 | * compiler warnings.  'padding' is in *bits* within the last byte, it is | 
|  | 684 | * an 'int' because pixel_depth becomes an 'int' in the expression below, | 
|  | 685 | * and this calculation is used because it avoids warnings that other | 
|  | 686 | * forms produced on either GCC or MSVC. | 
|  | 687 | */ | 
|  | 688 | int padding = (-row_info->pixel_depth * row_info->width) & 7; | 
|  | 689 | png_bytep rp = png_ptr->row_buf + row_info->rowbytes; | 
|  | 690 |  | 
|  | 691 | switch (row_info->bit_depth) | 
|  | 692 | { | 
|  | 693 | case 1: | 
|  | 694 | { | 
|  | 695 | /* in this case, all bytes must be 0 so we don't need | 
|  | 696 | * to unpack the pixels except for the rightmost one. | 
|  | 697 | */ | 
|  | 698 | for (; rp > png_ptr->row_buf; rp--) | 
|  | 699 | { | 
|  | 700 | if (*rp >> padding != 0) | 
|  | 701 | png_ptr->num_palette_max = 1; | 
|  | 702 | padding = 0; | 
|  | 703 | } | 
|  | 704 |  | 
|  | 705 | break; | 
|  | 706 | } | 
|  | 707 |  | 
|  | 708 | case 2: | 
|  | 709 | { | 
|  | 710 | for (; rp > png_ptr->row_buf; rp--) | 
|  | 711 | { | 
|  | 712 | int i = ((*rp >> padding) & 0x03); | 
|  | 713 |  | 
|  | 714 | if (i > png_ptr->num_palette_max) | 
|  | 715 | png_ptr->num_palette_max = i; | 
|  | 716 |  | 
|  | 717 | i = (((*rp >> padding) >> 2) & 0x03); | 
|  | 718 |  | 
|  | 719 | if (i > png_ptr->num_palette_max) | 
|  | 720 | png_ptr->num_palette_max = i; | 
|  | 721 |  | 
|  | 722 | i = (((*rp >> padding) >> 4) & 0x03); | 
|  | 723 |  | 
|  | 724 | if (i > png_ptr->num_palette_max) | 
|  | 725 | png_ptr->num_palette_max = i; | 
|  | 726 |  | 
|  | 727 | i = (((*rp >> padding) >> 6) & 0x03); | 
|  | 728 |  | 
|  | 729 | if (i > png_ptr->num_palette_max) | 
|  | 730 | png_ptr->num_palette_max = i; | 
|  | 731 |  | 
|  | 732 | padding = 0; | 
|  | 733 | } | 
|  | 734 |  | 
|  | 735 | break; | 
|  | 736 | } | 
|  | 737 |  | 
|  | 738 | case 4: | 
|  | 739 | { | 
|  | 740 | for (; rp > png_ptr->row_buf; rp--) | 
|  | 741 | { | 
|  | 742 | int i = ((*rp >> padding) & 0x0f); | 
|  | 743 |  | 
|  | 744 | if (i > png_ptr->num_palette_max) | 
|  | 745 | png_ptr->num_palette_max = i; | 
|  | 746 |  | 
|  | 747 | i = (((*rp >> padding) >> 4) & 0x0f); | 
|  | 748 |  | 
|  | 749 | if (i > png_ptr->num_palette_max) | 
|  | 750 | png_ptr->num_palette_max = i; | 
|  | 751 |  | 
|  | 752 | padding = 0; | 
|  | 753 | } | 
|  | 754 |  | 
|  | 755 | break; | 
|  | 756 | } | 
|  | 757 |  | 
|  | 758 | case 8: | 
|  | 759 | { | 
|  | 760 | for (; rp > png_ptr->row_buf; rp--) | 
|  | 761 | { | 
|  | 762 | if (*rp > png_ptr->num_palette_max) | 
|  | 763 | png_ptr->num_palette_max = (int) *rp; | 
|  | 764 | } | 
|  | 765 |  | 
|  | 766 | break; | 
|  | 767 | } | 
|  | 768 |  | 
|  | 769 | default: | 
|  | 770 | break; | 
|  | 771 | } | 
|  | 772 | } | 
|  | 773 | } | 
|  | 774 | #endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */ | 
|  | 775 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 776 | #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 777 | defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 778 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 779 | void PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 780 | png_set_user_transform_info(png_structrp png_ptr, png_voidp | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 781 | user_transform_ptr, int user_transform_depth, int user_transform_channels) | 
|  | 782 | { | 
| The Android Open Source Project | 4215dd1 | 2009-03-09 11:52:12 -0700 | [diff] [blame] | 783 | png_debug(1, "in png_set_user_transform_info"); | 
| Patrick Scott | 5f6bd84 | 2010-06-28 16:55:16 -0400 | [diff] [blame] | 784 |  | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 785 | if (png_ptr == NULL) | 
|  | 786 | return; | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 787 |  | 
|  | 788 | #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED | 
|  | 789 | if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && | 
|  | 790 | (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) | 
|  | 791 | { | 
|  | 792 | png_app_error(png_ptr, | 
|  | 793 | "info change after png_start_read_image or png_read_update_info"); | 
|  | 794 | return; | 
|  | 795 | } | 
|  | 796 | #endif | 
|  | 797 |  | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 798 | png_ptr->user_transform_ptr = user_transform_ptr; | 
|  | 799 | png_ptr->user_transform_depth = (png_byte)user_transform_depth; | 
|  | 800 | png_ptr->user_transform_channels = (png_byte)user_transform_channels; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 801 | } | 
|  | 802 | #endif | 
|  | 803 |  | 
|  | 804 | /* This function returns a pointer to the user_transform_ptr associated with | 
|  | 805 | * the user transform functions.  The application should free any memory | 
|  | 806 | * associated with this pointer before png_write_destroy and png_read_destroy | 
|  | 807 | * are called. | 
|  | 808 | */ | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 809 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 810 | png_voidp PNGAPI | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 811 | png_get_user_transform_ptr(png_const_structrp png_ptr) | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 812 | { | 
| Patrick Scott | a0bb96c | 2009-07-22 11:50:02 -0400 | [diff] [blame] | 813 | if (png_ptr == NULL) | 
|  | 814 | return (NULL); | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 815 |  | 
|  | 816 | return png_ptr->user_transform_ptr; | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 817 | } | 
| Chris Craik | b50c217 | 2013-07-29 15:28:30 -0700 | [diff] [blame] | 818 | #endif | 
|  | 819 |  | 
|  | 820 | #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED | 
|  | 821 | png_uint_32 PNGAPI | 
|  | 822 | png_get_current_row_number(png_const_structrp png_ptr) | 
|  | 823 | { | 
|  | 824 | /* See the comments in png.h - this is the sub-image row when reading and | 
|  | 825 | * interlaced image. | 
|  | 826 | */ | 
|  | 827 | if (png_ptr != NULL) | 
|  | 828 | return png_ptr->row_number; | 
|  | 829 |  | 
|  | 830 | return PNG_UINT_32_MAX; /* help the app not to fail silently */ | 
|  | 831 | } | 
|  | 832 |  | 
|  | 833 | png_byte PNGAPI | 
|  | 834 | png_get_current_pass_number(png_const_structrp png_ptr) | 
|  | 835 | { | 
|  | 836 | if (png_ptr != NULL) | 
|  | 837 | return png_ptr->pass; | 
|  | 838 | return 8; /* invalid */ | 
|  | 839 | } | 
|  | 840 | #endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ | 
|  | 841 | #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || | 
|  | 842 | PNG_WRITE_USER_TRANSFORM_SUPPORTED */ | 
| The Android Open Source Project | 893912b | 2009-03-03 19:30:05 -0800 | [diff] [blame] | 843 | #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ |