1 2 /* pngtrans.c - transforms the data in a row (used by both readers and writers) 3 * 4 * Last changed in libpng 1.2.17 May 15, 2007 5 * For conditions of distribution and use, see copyright notice in png.h 6 * Copyright (c) 1998-2007 Glenn Randers-Pehrson 7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 9 */ 10 11 #define PNG_INTERNAL 12 #include "png.h" 13 14 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 15 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) 16 /* turn on BGR-to-RGB mapping */ 17 void PNGAPI 18 png_set_bgr(png_structp png_ptr) 19 { 20 png_debug(1, "in png_set_bgr\n"); 21 if(png_ptr == NULL) return; 22 png_ptr->transformations |= PNG_BGR; 23 } 24 #endif 25 26 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) 27 /* turn on 16 bit byte swapping */ 28 void PNGAPI 29 png_set_swap(png_structp png_ptr) 30 { 31 png_debug(1, "in png_set_swap\n"); 32 if(png_ptr == NULL) return; 33 if (png_ptr->bit_depth == 16) 34 png_ptr->transformations |= PNG_SWAP_BYTES; 35 } 36 #endif 37 38 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) 39 /* turn on pixel packing */ 40 void PNGAPI 41 png_set_packing(png_structp png_ptr) 42 { 43 png_debug(1, "in png_set_packing\n"); 44 if(png_ptr == NULL) return; 45 if (png_ptr->bit_depth < 8) 46 { 47 png_ptr->transformations |= PNG_PACK; 48 png_ptr->usr_bit_depth = 8; 49 } 50 } 51 #endif 52 53 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) 54 /* turn on packed pixel swapping */ 55 void PNGAPI 56 png_set_packswap(png_structp png_ptr) 57 { 58 png_debug(1, "in png_set_packswap\n"); 59 if(png_ptr == NULL) return; 60 if (png_ptr->bit_depth < 8) 61 png_ptr->transformations |= PNG_PACKSWAP; 62 } 63 #endif 64 65 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) 66 void PNGAPI 67 png_set_shift(png_structp png_ptr, png_color_8p true_bits) 68 { 69 png_debug(1, "in png_set_shift\n"); 70 if(png_ptr == NULL) return; 71 png_ptr->transformations |= PNG_SHIFT; 72 png_ptr->shift = *true_bits; 73 } 74 #endif 75 76 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ 77 defined(PNG_WRITE_INTERLACING_SUPPORTED) 78 int PNGAPI 79 png_set_interlace_handling(png_structp png_ptr) 80 { 81 png_debug(1, "in png_set_interlace handling\n"); 82 if (png_ptr && png_ptr->interlaced) 83 { 84 png_ptr->transformations |= PNG_INTERLACE; 85 return (7); 86 } 87 88 return (1); 89 } 90 #endif 91 92 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) 93 /* Add a filler byte on read, or remove a filler or alpha byte on write. 94 * The filler type has changed in v0.95 to allow future 2-byte fillers 95 * for 48-bit input data, as well as to avoid problems with some compilers 96 * that don't like bytes as parameters. 97 */ 98 void PNGAPI 99 png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) 100 { 101 png_debug(1, "in png_set_filler\n"); 102 if(png_ptr == NULL) return; 103 png_ptr->transformations |= PNG_FILLER; 104 png_ptr->filler = (png_byte)filler; 105 if (filler_loc == PNG_FILLER_AFTER) 106 png_ptr->flags |= PNG_FLAG_FILLER_AFTER; 107 else 108 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; 109 110 /* This should probably go in the "do_read_filler" routine. 111 * I attempted to do that in libpng-1.0.1a but that caused problems 112 * so I restored it in libpng-1.0.2a 113 */ 114 115 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 116 { 117 png_ptr->usr_channels = 4; 118 } 119 120 /* Also I added this in libpng-1.0.2a (what happens when we expand 121 * a less-than-8-bit grayscale to GA? */ 122 123 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) 124 { 125 png_ptr->usr_channels = 2; 126 } 127 } 128 129 #if !defined(PNG_1_0_X) 130 /* Added to libpng-1.2.7 */ 131 void PNGAPI 132 png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) 133 { 134 png_debug(1, "in png_set_add_alpha\n"); 135 if(png_ptr == NULL) return; 136 png_set_filler(png_ptr, filler, filler_loc); 137 png_ptr->transformations |= PNG_ADD_ALPHA; 138 } 139 #endif 140 141 #endif 142 143 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ 144 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) 145 void PNGAPI 146 png_set_swap_alpha(png_structp png_ptr) 147 { 148 png_debug(1, "in png_set_swap_alpha\n"); 149 if(png_ptr == NULL) return; 150 png_ptr->transformations |= PNG_SWAP_ALPHA; 151 } 152 #endif 153 154 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ 155 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) 156 void PNGAPI 157 png_set_invert_alpha(png_structp png_ptr) 158 { 159 png_debug(1, "in png_set_invert_alpha\n"); 160 if(png_ptr == NULL) return; 161 png_ptr->transformations |= PNG_INVERT_ALPHA; 162 } 163 #endif 164 165 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) 166 void PNGAPI 167 png_set_invert_mono(png_structp png_ptr) 168 { 169 png_debug(1, "in png_set_invert_mono\n"); 170 if(png_ptr == NULL) return; 171 png_ptr->transformations |= PNG_INVERT_MONO; 172 } 173 174 /* invert monochrome grayscale data */ 175 void /* PRIVATE */ 176 png_do_invert(png_row_infop row_info, png_bytep row) 177 { 178 png_debug(1, "in png_do_invert\n"); 179 /* This test removed from libpng version 1.0.13 and 1.2.0: 180 * if (row_info->bit_depth == 1 && 181 */ 182 #if defined(PNG_USELESS_TESTS_SUPPORTED) 183 if (row == NULL || row_info == NULL) 184 return; 185 #endif 186 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 187 { 188 png_bytep rp = row; 189 png_uint_32 i; 190 png_uint_32 istop = row_info->rowbytes; 191 192 for (i = 0; i < istop; i++) 193 { 194 *rp = (png_byte)(~(*rp)); 195 rp++; 196 } 197 } 198 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && 199 row_info->bit_depth == 8) 200 { 201 png_bytep rp = row; 202 png_uint_32 i; 203 png_uint_32 istop = row_info->rowbytes; 204 205 for (i = 0; i < istop; i+=2) 206 { 207 *rp = (png_byte)(~(*rp)); 208 rp+=2; 209 } 210 } 211 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && 212 row_info->bit_depth == 16) 213 { 214 png_bytep rp = row; 215 png_uint_32 i; 216 png_uint_32 istop = row_info->rowbytes; 217 218 for (i = 0; i < istop; i+=4) 219 { 220 *rp = (png_byte)(~(*rp)); 221 *(rp+1) = (png_byte)(~(*(rp+1))); 222 rp+=4; 223 } 224 } 225 } 226 #endif 227 228 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) 229 /* swaps byte order on 16 bit depth images */ 230 void /* PRIVATE */ 231 png_do_swap(png_row_infop row_info, png_bytep row) 232 { 233 png_debug(1, "in png_do_swap\n"); 234 if ( 235 #if defined(PNG_USELESS_TESTS_SUPPORTED) 236 row != NULL && row_info != NULL && 237 #endif 238 row_info->bit_depth == 16) 239 { 240 png_bytep rp = row; 241 png_uint_32 i; 242 png_uint_32 istop= row_info->width * row_info->channels; 243 244 for (i = 0; i < istop; i++, rp += 2) 245 { 246 png_byte t = *rp; 247 *rp = *(rp + 1); 248 *(rp + 1) = t; 249 } 250 } 251 } 252 #endif 253 254 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) 255 static PNG_CONST png_byte onebppswaptable[256] = { 256 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 257 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 258 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 259 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 260 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 261 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 262 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 263 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 264 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 265 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 266 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 267 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 268 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 269 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 270 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 271 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 272 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 273 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 274 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 275 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 276 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 277 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 278 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 279 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 280 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 281 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 282 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 283 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 284 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 285 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 286 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 287 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF 288 }; 289 290 static PNG_CONST png_byte twobppswaptable[256] = { 291 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 292 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 293 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, 294 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, 295 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, 296 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, 297 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, 298 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, 299 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, 300 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, 301 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, 302 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, 303 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, 304 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, 305 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, 306 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, 307 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, 308 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, 309 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, 310 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, 311 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, 312 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, 313 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, 314 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, 315 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, 316 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, 317 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, 318 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, 319 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, 320 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, 321 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, 322 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF 323 }; 324 325 static PNG_CONST png_byte fourbppswaptable[256] = { 326 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 327 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 328 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 329 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, 330 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 331 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, 332 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 333 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, 334 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 335 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, 336 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 337 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, 338 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 339 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, 340 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 341 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, 342 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 343 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, 344 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 345 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, 346 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 347 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, 348 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 349 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, 350 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 351 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, 352 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 353 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, 354 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 355 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, 356 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 357 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF 358 }; 359 360 /* swaps pixel packing order within bytes */ 361 void /* PRIVATE */ 362 png_do_packswap(png_row_infop row_info, png_bytep row) 363 { 364 png_debug(1, "in png_do_packswap\n"); 365 if ( 366 #if defined(PNG_USELESS_TESTS_SUPPORTED) 367 row != NULL && row_info != NULL && 368 #endif 369 row_info->bit_depth < 8) 370 { 371 png_bytep rp, end, table; 372 373 end = row + row_info->rowbytes; 374 375 if (row_info->bit_depth == 1) 376 table = (png_bytep)onebppswaptable; 377 else if (row_info->bit_depth == 2) 378 table = (png_bytep)twobppswaptable; 379 else if (row_info->bit_depth == 4) 380 table = (png_bytep)fourbppswaptable; 381 else 382 return; 383 384 for (rp = row; rp < end; rp++) 385 *rp = table[*rp]; 386 } 387 } 388 #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ 389 390 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ 391 defined(PNG_READ_STRIP_ALPHA_SUPPORTED) 392 /* remove filler or alpha byte(s) */ 393 void /* PRIVATE */ 394 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) 395 { 396 png_debug(1, "in png_do_strip_filler\n"); 397 #if defined(PNG_USELESS_TESTS_SUPPORTED) 398 if (row != NULL && row_info != NULL) 399 #endif 400 { 401 png_bytep sp=row; 402 png_bytep dp=row; 403 png_uint_32 row_width=row_info->width; 404 png_uint_32 i; 405 406 if ((row_info->color_type == PNG_COLOR_TYPE_RGB || 407 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 408 (flags & PNG_FLAG_STRIP_ALPHA))) && 409 row_info->channels == 4) 410 { 411 if (row_info->bit_depth == 8) 412 { 413 /* This converts from RGBX or RGBA to RGB */ 414 if (flags & PNG_FLAG_FILLER_AFTER) 415 { 416 dp+=3; sp+=4; 417 for (i = 1; i < row_width; i++) 418 { 419 *dp++ = *sp++; 420 *dp++ = *sp++; 421 *dp++ = *sp++; 422 sp++; 423 } 424 } 425 /* This converts from XRGB or ARGB to RGB */ 426 else 427 { 428 for (i = 0; i < row_width; i++) 429 { 430 sp++; 431 *dp++ = *sp++; 432 *dp++ = *sp++; 433 *dp++ = *sp++; 434 } 435 } 436 row_info->pixel_depth = 24; 437 row_info->rowbytes = row_width * 3; 438 } 439 else /* if (row_info->bit_depth == 16) */ 440 { 441 if (flags & PNG_FLAG_FILLER_AFTER) 442 { 443 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */ 444 sp += 8; dp += 6; 445 for (i = 1; i < row_width; i++) 446 { 447 /* This could be (although png_memcpy is probably slower): 448 png_memcpy(dp, sp, 6); 449 sp += 8; 450 dp += 6; 451 */ 452 453 *dp++ = *sp++; 454 *dp++ = *sp++; 455 *dp++ = *sp++; 456 *dp++ = *sp++; 457 *dp++ = *sp++; 458 *dp++ = *sp++; 459 sp += 2; 460 } 461 } 462 else 463 { 464 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ 465 for (i = 0; i < row_width; i++) 466 { 467 /* This could be (although png_memcpy is probably slower): 468 png_memcpy(dp, sp, 6); 469 sp += 8; 470 dp += 6; 471 */ 472 473 sp+=2; 474 *dp++ = *sp++; 475 *dp++ = *sp++; 476 *dp++ = *sp++; 477 *dp++ = *sp++; 478 *dp++ = *sp++; 479 *dp++ = *sp++; 480 } 481 } 482 row_info->pixel_depth = 48; 483 row_info->rowbytes = row_width * 6; 484 } 485 row_info->channels = 3; 486 } 487 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || 488 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && 489 (flags & PNG_FLAG_STRIP_ALPHA))) && 490 row_info->channels == 2) 491 { 492 if (row_info->bit_depth == 8) 493 { 494 /* This converts from GX or GA to G */ 495 if (flags & PNG_FLAG_FILLER_AFTER) 496 { 497 for (i = 0; i < row_width; i++) 498 { 499 *dp++ = *sp++; 500 sp++; 501 } 502 } 503 /* This converts from XG or AG to G */ 504 else 505 { 506 for (i = 0; i < row_width; i++) 507 { 508 sp++; 509 *dp++ = *sp++; 510 } 511 } 512 row_info->pixel_depth = 8; 513 row_info->rowbytes = row_width; 514 } 515 else /* if (row_info->bit_depth == 16) */ 516 { 517 if (flags & PNG_FLAG_FILLER_AFTER) 518 { 519 /* This converts from GGXX or GGAA to GG */ 520 sp += 4; dp += 2; 521 for (i = 1; i < row_width; i++) 522 { 523 *dp++ = *sp++; 524 *dp++ = *sp++; 525 sp += 2; 526 } 527 } 528 else 529 { 530 /* This converts from XXGG or AAGG to GG */ 531 for (i = 0; i < row_width; i++) 532 { 533 sp += 2; 534 *dp++ = *sp++; 535 *dp++ = *sp++; 536 } 537 } 538 row_info->pixel_depth = 16; 539 row_info->rowbytes = row_width * 2; 540 } 541 row_info->channels = 1; 542 } 543 if (flags & PNG_FLAG_STRIP_ALPHA) 544 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; 545 } 546 } 547 #endif 548 549 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) 550 /* swaps red and blue bytes within a pixel */ 551 void /* PRIVATE */ 552 png_do_bgr(png_row_infop row_info, png_bytep row) 553 { 554 png_debug(1, "in png_do_bgr\n"); 555 if ( 556 #if defined(PNG_USELESS_TESTS_SUPPORTED) 557 row != NULL && row_info != NULL && 558 #endif 559 (row_info->color_type & PNG_COLOR_MASK_COLOR)) 560 { 561 png_uint_32 row_width = row_info->width; 562 if (row_info->bit_depth == 8) 563 { 564 if (row_info->color_type == PNG_COLOR_TYPE_RGB) 565 { 566 png_bytep rp; 567 png_uint_32 i; 568 569 for (i = 0, rp = row; i < row_width; i++, rp += 3) 570 { 571 png_byte save = *rp; 572 *rp = *(rp + 2); 573 *(rp + 2) = save; 574 } 575 } 576 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 577 { 578 png_bytep rp; 579 png_uint_32 i; 580 581 for (i = 0, rp = row; i < row_width; i++, rp += 4) 582 { 583 png_byte save = *rp; 584 *rp = *(rp + 2); 585 *(rp + 2) = save; 586 } 587 } 588 } 589 else if (row_info->bit_depth == 16) 590 { 591 if (row_info->color_type == PNG_COLOR_TYPE_RGB) 592 { 593 png_bytep rp; 594 png_uint_32 i; 595 596 for (i = 0, rp = row; i < row_width; i++, rp += 6) 597 { 598 png_byte save = *rp; 599 *rp = *(rp + 4); 600 *(rp + 4) = save; 601 save = *(rp + 1); 602 *(rp + 1) = *(rp + 5); 603 *(rp + 5) = save; 604 } 605 } 606 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 607 { 608 png_bytep rp; 609 png_uint_32 i; 610 611 for (i = 0, rp = row; i < row_width; i++, rp += 8) 612 { 613 png_byte save = *rp; 614 *rp = *(rp + 4); 615 *(rp + 4) = save; 616 save = *(rp + 1); 617 *(rp + 1) = *(rp + 5); 618 *(rp + 5) = save; 619 } 620 } 621 } 622 } 623 } 624 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ 625 626 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 627 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ 628 defined(PNG_LEGACY_SUPPORTED) 629 void PNGAPI 630 png_set_user_transform_info(png_structp png_ptr, png_voidp 631 user_transform_ptr, int user_transform_depth, int user_transform_channels) 632 { 633 png_debug(1, "in png_set_user_transform_info\n"); 634 if(png_ptr == NULL) return; 635 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 636 png_ptr->user_transform_ptr = user_transform_ptr; 637 png_ptr->user_transform_depth = (png_byte)user_transform_depth; 638 png_ptr->user_transform_channels = (png_byte)user_transform_channels; 639 #else 640 if(user_transform_ptr || user_transform_depth || user_transform_channels) 641 png_warning(png_ptr, 642 "This version of libpng does not support user transform info"); 643 #endif 644 } 645 #endif 646 647 /* This function returns a pointer to the user_transform_ptr associated with 648 * the user transform functions. The application should free any memory 649 * associated with this pointer before png_write_destroy and png_read_destroy 650 * are called. 651 */ 652 png_voidp PNGAPI 653 png_get_user_transform_ptr(png_structp png_ptr) 654 { 655 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 656 if (png_ptr == NULL) return (NULL); 657 return ((png_voidp)png_ptr->user_transform_ptr); 658 #else 659 return (NULL); 660 #endif 661 } 662 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ 663