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