1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libpng/pngwtran.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,572 @@ 1.4 + 1.5 +/* pngwtran.c - transforms the data in a row for PNG writers 1.6 + * 1.7 + * Last changed in libpng 1.6.9 [February 6, 2014] 1.8 + * Copyright (c) 1998-2014 Glenn Randers-Pehrson 1.9 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 1.10 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 1.11 + * 1.12 + * This code is released under the libpng license. 1.13 + * For conditions of distribution and use, see the disclaimer 1.14 + * and license in png.h 1.15 + */ 1.16 + 1.17 +#include "pngpriv.h" 1.18 + 1.19 +#ifdef PNG_WRITE_SUPPORTED 1.20 +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED 1.21 + 1.22 +#ifdef PNG_WRITE_PACK_SUPPORTED 1.23 +/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The 1.24 + * row_info bit depth should be 8 (one pixel per byte). The channels 1.25 + * should be 1 (this only happens on grayscale and paletted images). 1.26 + */ 1.27 +static void 1.28 +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) 1.29 +{ 1.30 + png_debug(1, "in png_do_pack"); 1.31 + 1.32 + if (row_info->bit_depth == 8 && 1.33 + row_info->channels == 1) 1.34 + { 1.35 + switch ((int)bit_depth) 1.36 + { 1.37 + case 1: 1.38 + { 1.39 + png_bytep sp, dp; 1.40 + int mask, v; 1.41 + png_uint_32 i; 1.42 + png_uint_32 row_width = row_info->width; 1.43 + 1.44 + sp = row; 1.45 + dp = row; 1.46 + mask = 0x80; 1.47 + v = 0; 1.48 + 1.49 + for (i = 0; i < row_width; i++) 1.50 + { 1.51 + if (*sp != 0) 1.52 + v |= mask; 1.53 + 1.54 + sp++; 1.55 + 1.56 + if (mask > 1) 1.57 + mask >>= 1; 1.58 + 1.59 + else 1.60 + { 1.61 + mask = 0x80; 1.62 + *dp = (png_byte)v; 1.63 + dp++; 1.64 + v = 0; 1.65 + } 1.66 + } 1.67 + 1.68 + if (mask != 0x80) 1.69 + *dp = (png_byte)v; 1.70 + 1.71 + break; 1.72 + } 1.73 + 1.74 + case 2: 1.75 + { 1.76 + png_bytep sp, dp; 1.77 + int shift, v; 1.78 + png_uint_32 i; 1.79 + png_uint_32 row_width = row_info->width; 1.80 + 1.81 + sp = row; 1.82 + dp = row; 1.83 + shift = 6; 1.84 + v = 0; 1.85 + 1.86 + for (i = 0; i < row_width; i++) 1.87 + { 1.88 + png_byte value; 1.89 + 1.90 + value = (png_byte)(*sp & 0x03); 1.91 + v |= (value << shift); 1.92 + 1.93 + if (shift == 0) 1.94 + { 1.95 + shift = 6; 1.96 + *dp = (png_byte)v; 1.97 + dp++; 1.98 + v = 0; 1.99 + } 1.100 + 1.101 + else 1.102 + shift -= 2; 1.103 + 1.104 + sp++; 1.105 + } 1.106 + 1.107 + if (shift != 6) 1.108 + *dp = (png_byte)v; 1.109 + 1.110 + break; 1.111 + } 1.112 + 1.113 + case 4: 1.114 + { 1.115 + png_bytep sp, dp; 1.116 + int shift, v; 1.117 + png_uint_32 i; 1.118 + png_uint_32 row_width = row_info->width; 1.119 + 1.120 + sp = row; 1.121 + dp = row; 1.122 + shift = 4; 1.123 + v = 0; 1.124 + 1.125 + for (i = 0; i < row_width; i++) 1.126 + { 1.127 + png_byte value; 1.128 + 1.129 + value = (png_byte)(*sp & 0x0f); 1.130 + v |= (value << shift); 1.131 + 1.132 + if (shift == 0) 1.133 + { 1.134 + shift = 4; 1.135 + *dp = (png_byte)v; 1.136 + dp++; 1.137 + v = 0; 1.138 + } 1.139 + 1.140 + else 1.141 + shift -= 4; 1.142 + 1.143 + sp++; 1.144 + } 1.145 + 1.146 + if (shift != 4) 1.147 + *dp = (png_byte)v; 1.148 + 1.149 + break; 1.150 + } 1.151 + 1.152 + default: 1.153 + break; 1.154 + } 1.155 + 1.156 + row_info->bit_depth = (png_byte)bit_depth; 1.157 + row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); 1.158 + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 1.159 + row_info->width); 1.160 + } 1.161 +} 1.162 +#endif 1.163 + 1.164 +#ifdef PNG_WRITE_SHIFT_SUPPORTED 1.165 +/* Shift pixel values to take advantage of whole range. Pass the 1.166 + * true number of bits in bit_depth. The row should be packed 1.167 + * according to row_info->bit_depth. Thus, if you had a row of 1.168 + * bit depth 4, but the pixels only had values from 0 to 7, you 1.169 + * would pass 3 as bit_depth, and this routine would translate the 1.170 + * data to 0 to 15. 1.171 + */ 1.172 +static void 1.173 +png_do_shift(png_row_infop row_info, png_bytep row, 1.174 + png_const_color_8p bit_depth) 1.175 +{ 1.176 + png_debug(1, "in png_do_shift"); 1.177 + 1.178 + if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) 1.179 + { 1.180 + int shift_start[4], shift_dec[4]; 1.181 + int channels = 0; 1.182 + 1.183 + if (row_info->color_type & PNG_COLOR_MASK_COLOR) 1.184 + { 1.185 + shift_start[channels] = row_info->bit_depth - bit_depth->red; 1.186 + shift_dec[channels] = bit_depth->red; 1.187 + channels++; 1.188 + 1.189 + shift_start[channels] = row_info->bit_depth - bit_depth->green; 1.190 + shift_dec[channels] = bit_depth->green; 1.191 + channels++; 1.192 + 1.193 + shift_start[channels] = row_info->bit_depth - bit_depth->blue; 1.194 + shift_dec[channels] = bit_depth->blue; 1.195 + channels++; 1.196 + } 1.197 + 1.198 + else 1.199 + { 1.200 + shift_start[channels] = row_info->bit_depth - bit_depth->gray; 1.201 + shift_dec[channels] = bit_depth->gray; 1.202 + channels++; 1.203 + } 1.204 + 1.205 + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 1.206 + { 1.207 + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; 1.208 + shift_dec[channels] = bit_depth->alpha; 1.209 + channels++; 1.210 + } 1.211 + 1.212 + /* With low row depths, could only be grayscale, so one channel */ 1.213 + if (row_info->bit_depth < 8) 1.214 + { 1.215 + png_bytep bp = row; 1.216 + png_size_t i; 1.217 + unsigned int mask; 1.218 + png_size_t row_bytes = row_info->rowbytes; 1.219 + 1.220 + if (bit_depth->gray == 1 && row_info->bit_depth == 2) 1.221 + mask = 0x55; 1.222 + 1.223 + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) 1.224 + mask = 0x11; 1.225 + 1.226 + else 1.227 + mask = 0xff; 1.228 + 1.229 + for (i = 0; i < row_bytes; i++, bp++) 1.230 + { 1.231 + int j; 1.232 + unsigned int v, out; 1.233 + 1.234 + v = *bp; 1.235 + out = 0; 1.236 + 1.237 + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) 1.238 + { 1.239 + if (j > 0) 1.240 + out |= v << j; 1.241 + 1.242 + else 1.243 + out |= (v >> (-j)) & mask; 1.244 + } 1.245 + 1.246 + *bp = (png_byte)(out & 0xff); 1.247 + } 1.248 + } 1.249 + 1.250 + else if (row_info->bit_depth == 8) 1.251 + { 1.252 + png_bytep bp = row; 1.253 + png_uint_32 i; 1.254 + png_uint_32 istop = channels * row_info->width; 1.255 + 1.256 + for (i = 0; i < istop; i++, bp++) 1.257 + { 1.258 + 1.259 + const unsigned int c = i%channels; 1.260 + int j; 1.261 + unsigned int v, out; 1.262 + 1.263 + v = *bp; 1.264 + out = 0; 1.265 + 1.266 + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) 1.267 + { 1.268 + if (j > 0) 1.269 + out |= v << j; 1.270 + 1.271 + else 1.272 + out |= v >> (-j); 1.273 + } 1.274 + 1.275 + *bp = (png_byte)(out & 0xff); 1.276 + } 1.277 + } 1.278 + 1.279 + else 1.280 + { 1.281 + png_bytep bp; 1.282 + png_uint_32 i; 1.283 + png_uint_32 istop = channels * row_info->width; 1.284 + 1.285 + for (bp = row, i = 0; i < istop; i++) 1.286 + { 1.287 + const unsigned int c = i%channels; 1.288 + int j; 1.289 + unsigned int value, v; 1.290 + 1.291 + v = png_get_uint_16(bp); 1.292 + value = 0; 1.293 + 1.294 + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) 1.295 + { 1.296 + if (j > 0) 1.297 + value |= v << j; 1.298 + 1.299 + else 1.300 + value |= v >> (-j); 1.301 + } 1.302 + *bp++ = (png_byte)((value >> 8) & 0xff); 1.303 + *bp++ = (png_byte)(value & 0xff); 1.304 + } 1.305 + } 1.306 + } 1.307 +} 1.308 +#endif 1.309 + 1.310 +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED 1.311 +static void 1.312 +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) 1.313 +{ 1.314 + png_debug(1, "in png_do_write_swap_alpha"); 1.315 + 1.316 + { 1.317 + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.318 + { 1.319 + if (row_info->bit_depth == 8) 1.320 + { 1.321 + /* This converts from ARGB to RGBA */ 1.322 + png_bytep sp, dp; 1.323 + png_uint_32 i; 1.324 + png_uint_32 row_width = row_info->width; 1.325 + 1.326 + for (i = 0, sp = dp = row; i < row_width; i++) 1.327 + { 1.328 + png_byte save = *(sp++); 1.329 + *(dp++) = *(sp++); 1.330 + *(dp++) = *(sp++); 1.331 + *(dp++) = *(sp++); 1.332 + *(dp++) = save; 1.333 + } 1.334 + } 1.335 + 1.336 +#ifdef PNG_WRITE_16BIT_SUPPORTED 1.337 + else 1.338 + { 1.339 + /* This converts from AARRGGBB to RRGGBBAA */ 1.340 + png_bytep sp, dp; 1.341 + png_uint_32 i; 1.342 + png_uint_32 row_width = row_info->width; 1.343 + 1.344 + for (i = 0, sp = dp = row; i < row_width; i++) 1.345 + { 1.346 + png_byte save[2]; 1.347 + save[0] = *(sp++); 1.348 + save[1] = *(sp++); 1.349 + *(dp++) = *(sp++); 1.350 + *(dp++) = *(sp++); 1.351 + *(dp++) = *(sp++); 1.352 + *(dp++) = *(sp++); 1.353 + *(dp++) = *(sp++); 1.354 + *(dp++) = *(sp++); 1.355 + *(dp++) = save[0]; 1.356 + *(dp++) = save[1]; 1.357 + } 1.358 + } 1.359 +#endif /* PNG_WRITE_16BIT_SUPPORTED */ 1.360 + } 1.361 + 1.362 + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 1.363 + { 1.364 + if (row_info->bit_depth == 8) 1.365 + { 1.366 + /* This converts from AG to GA */ 1.367 + png_bytep sp, dp; 1.368 + png_uint_32 i; 1.369 + png_uint_32 row_width = row_info->width; 1.370 + 1.371 + for (i = 0, sp = dp = row; i < row_width; i++) 1.372 + { 1.373 + png_byte save = *(sp++); 1.374 + *(dp++) = *(sp++); 1.375 + *(dp++) = save; 1.376 + } 1.377 + } 1.378 + 1.379 +#ifdef PNG_WRITE_16BIT_SUPPORTED 1.380 + else 1.381 + { 1.382 + /* This converts from AAGG to GGAA */ 1.383 + png_bytep sp, dp; 1.384 + png_uint_32 i; 1.385 + png_uint_32 row_width = row_info->width; 1.386 + 1.387 + for (i = 0, sp = dp = row; i < row_width; i++) 1.388 + { 1.389 + png_byte save[2]; 1.390 + save[0] = *(sp++); 1.391 + save[1] = *(sp++); 1.392 + *(dp++) = *(sp++); 1.393 + *(dp++) = *(sp++); 1.394 + *(dp++) = save[0]; 1.395 + *(dp++) = save[1]; 1.396 + } 1.397 + } 1.398 +#endif /* PNG_WRITE_16BIT_SUPPORTED */ 1.399 + } 1.400 + } 1.401 +} 1.402 +#endif 1.403 + 1.404 +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 1.405 +static void 1.406 +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) 1.407 +{ 1.408 + png_debug(1, "in png_do_write_invert_alpha"); 1.409 + 1.410 + { 1.411 + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.412 + { 1.413 + if (row_info->bit_depth == 8) 1.414 + { 1.415 + /* This inverts the alpha channel in RGBA */ 1.416 + png_bytep sp, dp; 1.417 + png_uint_32 i; 1.418 + png_uint_32 row_width = row_info->width; 1.419 + 1.420 + for (i = 0, sp = dp = row; i < row_width; i++) 1.421 + { 1.422 + /* Does nothing 1.423 + *(dp++) = *(sp++); 1.424 + *(dp++) = *(sp++); 1.425 + *(dp++) = *(sp++); 1.426 + */ 1.427 + sp+=3; dp = sp; 1.428 + *(dp++) = (png_byte)(255 - *(sp++)); 1.429 + } 1.430 + } 1.431 + 1.432 +#ifdef PNG_WRITE_16BIT_SUPPORTED 1.433 + else 1.434 + { 1.435 + /* This inverts the alpha channel in RRGGBBAA */ 1.436 + png_bytep sp, dp; 1.437 + png_uint_32 i; 1.438 + png_uint_32 row_width = row_info->width; 1.439 + 1.440 + for (i = 0, sp = dp = row; i < row_width; i++) 1.441 + { 1.442 + /* Does nothing 1.443 + *(dp++) = *(sp++); 1.444 + *(dp++) = *(sp++); 1.445 + *(dp++) = *(sp++); 1.446 + *(dp++) = *(sp++); 1.447 + *(dp++) = *(sp++); 1.448 + *(dp++) = *(sp++); 1.449 + */ 1.450 + sp+=6; dp = sp; 1.451 + *(dp++) = (png_byte)(255 - *(sp++)); 1.452 + *(dp++) = (png_byte)(255 - *(sp++)); 1.453 + } 1.454 + } 1.455 +#endif /* PNG_WRITE_16BIT_SUPPORTED */ 1.456 + } 1.457 + 1.458 + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 1.459 + { 1.460 + if (row_info->bit_depth == 8) 1.461 + { 1.462 + /* This inverts the alpha channel in GA */ 1.463 + png_bytep sp, dp; 1.464 + png_uint_32 i; 1.465 + png_uint_32 row_width = row_info->width; 1.466 + 1.467 + for (i = 0, sp = dp = row; i < row_width; i++) 1.468 + { 1.469 + *(dp++) = *(sp++); 1.470 + *(dp++) = (png_byte)(255 - *(sp++)); 1.471 + } 1.472 + } 1.473 + 1.474 +#ifdef PNG_WRITE_16BIT_SUPPORTED 1.475 + else 1.476 + { 1.477 + /* This inverts the alpha channel in GGAA */ 1.478 + png_bytep sp, dp; 1.479 + png_uint_32 i; 1.480 + png_uint_32 row_width = row_info->width; 1.481 + 1.482 + for (i = 0, sp = dp = row; i < row_width; i++) 1.483 + { 1.484 + /* Does nothing 1.485 + *(dp++) = *(sp++); 1.486 + *(dp++) = *(sp++); 1.487 + */ 1.488 + sp+=2; dp = sp; 1.489 + *(dp++) = (png_byte)(255 - *(sp++)); 1.490 + *(dp++) = (png_byte)(255 - *(sp++)); 1.491 + } 1.492 + } 1.493 +#endif /* PNG_WRITE_16BIT_SUPPORTED */ 1.494 + } 1.495 + } 1.496 +} 1.497 +#endif 1.498 + 1.499 +/* Transform the data according to the user's wishes. The order of 1.500 + * transformations is significant. 1.501 + */ 1.502 +void /* PRIVATE */ 1.503 +png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) 1.504 +{ 1.505 + png_debug(1, "in png_do_write_transformations"); 1.506 + 1.507 + if (png_ptr == NULL) 1.508 + return; 1.509 + 1.510 +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 1.511 + if (png_ptr->transformations & PNG_USER_TRANSFORM) 1.512 + if (png_ptr->write_user_transform_fn != NULL) 1.513 + (*(png_ptr->write_user_transform_fn)) /* User write transform 1.514 + function */ 1.515 + (png_ptr, /* png_ptr */ 1.516 + row_info, /* row_info: */ 1.517 + /* png_uint_32 width; width of row */ 1.518 + /* png_size_t rowbytes; number of bytes in row */ 1.519 + /* png_byte color_type; color type of pixels */ 1.520 + /* png_byte bit_depth; bit depth of samples */ 1.521 + /* png_byte channels; number of channels (1-4) */ 1.522 + /* png_byte pixel_depth; bits per pixel (depth*channels) */ 1.523 + png_ptr->row_buf + 1); /* start of pixel data for row */ 1.524 +#endif 1.525 + 1.526 +#ifdef PNG_WRITE_FILLER_SUPPORTED 1.527 + if (png_ptr->transformations & PNG_FILLER) 1.528 + png_do_strip_channel(row_info, png_ptr->row_buf + 1, 1.529 + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); 1.530 +#endif 1.531 + 1.532 +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED 1.533 + if (png_ptr->transformations & PNG_PACKSWAP) 1.534 + png_do_packswap(row_info, png_ptr->row_buf + 1); 1.535 +#endif 1.536 + 1.537 +#ifdef PNG_WRITE_PACK_SUPPORTED 1.538 + if (png_ptr->transformations & PNG_PACK) 1.539 + png_do_pack(row_info, png_ptr->row_buf + 1, 1.540 + (png_uint_32)png_ptr->bit_depth); 1.541 +#endif 1.542 + 1.543 +#ifdef PNG_WRITE_SWAP_SUPPORTED 1.544 + if (png_ptr->transformations & PNG_SWAP_BYTES) 1.545 + png_do_swap(row_info, png_ptr->row_buf + 1); 1.546 +#endif 1.547 + 1.548 +#ifdef PNG_WRITE_SHIFT_SUPPORTED 1.549 + if (png_ptr->transformations & PNG_SHIFT) 1.550 + png_do_shift(row_info, png_ptr->row_buf + 1, 1.551 + &(png_ptr->shift)); 1.552 +#endif 1.553 + 1.554 +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED 1.555 + if (png_ptr->transformations & PNG_SWAP_ALPHA) 1.556 + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); 1.557 +#endif 1.558 + 1.559 +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 1.560 + if (png_ptr->transformations & PNG_INVERT_ALPHA) 1.561 + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); 1.562 +#endif 1.563 + 1.564 +#ifdef PNG_WRITE_BGR_SUPPORTED 1.565 + if (png_ptr->transformations & PNG_BGR) 1.566 + png_do_bgr(row_info, png_ptr->row_buf + 1); 1.567 +#endif 1.568 + 1.569 +#ifdef PNG_WRITE_INVERT_SUPPORTED 1.570 + if (png_ptr->transformations & PNG_INVERT_MONO) 1.571 + png_do_invert(row_info, png_ptr->row_buf + 1); 1.572 +#endif 1.573 +} 1.574 +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ 1.575 +#endif /* PNG_WRITE_SUPPORTED */