vrshoot

annotate libs/libpng/pngwtran.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1
nuclear@0 2 /* pngwtran.c - transforms the data in a row for PNG writers
nuclear@0 3 *
nuclear@0 4 * Last changed in libpng 1.2.9 April 14, 2006
nuclear@0 5 * For conditions of distribution and use, see copyright notice in png.h
nuclear@0 6 * Copyright (c) 1998-2006 Glenn Randers-Pehrson
nuclear@0 7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
nuclear@0 8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
nuclear@0 9 */
nuclear@0 10
nuclear@0 11 #define PNG_INTERNAL
nuclear@0 12 #include "png.h"
nuclear@0 13 #ifdef PNG_WRITE_SUPPORTED
nuclear@0 14
nuclear@0 15 /* Transform the data according to the user's wishes. The order of
nuclear@0 16 * transformations is significant.
nuclear@0 17 */
nuclear@0 18 void /* PRIVATE */
nuclear@0 19 png_do_write_transformations(png_structp png_ptr)
nuclear@0 20 {
nuclear@0 21 png_debug(1, "in png_do_write_transformations\n");
nuclear@0 22
nuclear@0 23 if (png_ptr == NULL)
nuclear@0 24 return;
nuclear@0 25
nuclear@0 26 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
nuclear@0 27 if (png_ptr->transformations & PNG_USER_TRANSFORM)
nuclear@0 28 if (png_ptr->write_user_transform_fn != NULL)
nuclear@0 29 (*(png_ptr->write_user_transform_fn)) /* user write transform function */
nuclear@0 30 (png_ptr, /* png_ptr */
nuclear@0 31 &(png_ptr->row_info), /* row_info: */
nuclear@0 32 /* png_uint_32 width; width of row */
nuclear@0 33 /* png_uint_32 rowbytes; number of bytes in row */
nuclear@0 34 /* png_byte color_type; color type of pixels */
nuclear@0 35 /* png_byte bit_depth; bit depth of samples */
nuclear@0 36 /* png_byte channels; number of channels (1-4) */
nuclear@0 37 /* png_byte pixel_depth; bits per pixel (depth*channels) */
nuclear@0 38 png_ptr->row_buf + 1); /* start of pixel data for row */
nuclear@0 39 #endif
nuclear@0 40 #if defined(PNG_WRITE_FILLER_SUPPORTED)
nuclear@0 41 if (png_ptr->transformations & PNG_FILLER)
nuclear@0 42 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
nuclear@0 43 png_ptr->flags);
nuclear@0 44 #endif
nuclear@0 45 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
nuclear@0 46 if (png_ptr->transformations & PNG_PACKSWAP)
nuclear@0 47 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 48 #endif
nuclear@0 49 #if defined(PNG_WRITE_PACK_SUPPORTED)
nuclear@0 50 if (png_ptr->transformations & PNG_PACK)
nuclear@0 51 png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
nuclear@0 52 (png_uint_32)png_ptr->bit_depth);
nuclear@0 53 #endif
nuclear@0 54 #if defined(PNG_WRITE_SWAP_SUPPORTED)
nuclear@0 55 if (png_ptr->transformations & PNG_SWAP_BYTES)
nuclear@0 56 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 57 #endif
nuclear@0 58 #if defined(PNG_WRITE_SHIFT_SUPPORTED)
nuclear@0 59 if (png_ptr->transformations & PNG_SHIFT)
nuclear@0 60 png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
nuclear@0 61 &(png_ptr->shift));
nuclear@0 62 #endif
nuclear@0 63 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
nuclear@0 64 if (png_ptr->transformations & PNG_SWAP_ALPHA)
nuclear@0 65 png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 66 #endif
nuclear@0 67 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
nuclear@0 68 if (png_ptr->transformations & PNG_INVERT_ALPHA)
nuclear@0 69 png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 70 #endif
nuclear@0 71 #if defined(PNG_WRITE_BGR_SUPPORTED)
nuclear@0 72 if (png_ptr->transformations & PNG_BGR)
nuclear@0 73 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 74 #endif
nuclear@0 75 #if defined(PNG_WRITE_INVERT_SUPPORTED)
nuclear@0 76 if (png_ptr->transformations & PNG_INVERT_MONO)
nuclear@0 77 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
nuclear@0 78 #endif
nuclear@0 79 }
nuclear@0 80
nuclear@0 81 #if defined(PNG_WRITE_PACK_SUPPORTED)
nuclear@0 82 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
nuclear@0 83 * row_info bit depth should be 8 (one pixel per byte). The channels
nuclear@0 84 * should be 1 (this only happens on grayscale and paletted images).
nuclear@0 85 */
nuclear@0 86 void /* PRIVATE */
nuclear@0 87 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
nuclear@0 88 {
nuclear@0 89 png_debug(1, "in png_do_pack\n");
nuclear@0 90 if (row_info->bit_depth == 8 &&
nuclear@0 91 #if defined(PNG_USELESS_TESTS_SUPPORTED)
nuclear@0 92 row != NULL && row_info != NULL &&
nuclear@0 93 #endif
nuclear@0 94 row_info->channels == 1)
nuclear@0 95 {
nuclear@0 96 switch ((int)bit_depth)
nuclear@0 97 {
nuclear@0 98 case 1:
nuclear@0 99 {
nuclear@0 100 png_bytep sp, dp;
nuclear@0 101 int mask, v;
nuclear@0 102 png_uint_32 i;
nuclear@0 103 png_uint_32 row_width = row_info->width;
nuclear@0 104
nuclear@0 105 sp = row;
nuclear@0 106 dp = row;
nuclear@0 107 mask = 0x80;
nuclear@0 108 v = 0;
nuclear@0 109
nuclear@0 110 for (i = 0; i < row_width; i++)
nuclear@0 111 {
nuclear@0 112 if (*sp != 0)
nuclear@0 113 v |= mask;
nuclear@0 114 sp++;
nuclear@0 115 if (mask > 1)
nuclear@0 116 mask >>= 1;
nuclear@0 117 else
nuclear@0 118 {
nuclear@0 119 mask = 0x80;
nuclear@0 120 *dp = (png_byte)v;
nuclear@0 121 dp++;
nuclear@0 122 v = 0;
nuclear@0 123 }
nuclear@0 124 }
nuclear@0 125 if (mask != 0x80)
nuclear@0 126 *dp = (png_byte)v;
nuclear@0 127 break;
nuclear@0 128 }
nuclear@0 129 case 2:
nuclear@0 130 {
nuclear@0 131 png_bytep sp, dp;
nuclear@0 132 int shift, v;
nuclear@0 133 png_uint_32 i;
nuclear@0 134 png_uint_32 row_width = row_info->width;
nuclear@0 135
nuclear@0 136 sp = row;
nuclear@0 137 dp = row;
nuclear@0 138 shift = 6;
nuclear@0 139 v = 0;
nuclear@0 140 for (i = 0; i < row_width; i++)
nuclear@0 141 {
nuclear@0 142 png_byte value;
nuclear@0 143
nuclear@0 144 value = (png_byte)(*sp & 0x03);
nuclear@0 145 v |= (value << shift);
nuclear@0 146 if (shift == 0)
nuclear@0 147 {
nuclear@0 148 shift = 6;
nuclear@0 149 *dp = (png_byte)v;
nuclear@0 150 dp++;
nuclear@0 151 v = 0;
nuclear@0 152 }
nuclear@0 153 else
nuclear@0 154 shift -= 2;
nuclear@0 155 sp++;
nuclear@0 156 }
nuclear@0 157 if (shift != 6)
nuclear@0 158 *dp = (png_byte)v;
nuclear@0 159 break;
nuclear@0 160 }
nuclear@0 161 case 4:
nuclear@0 162 {
nuclear@0 163 png_bytep sp, dp;
nuclear@0 164 int shift, v;
nuclear@0 165 png_uint_32 i;
nuclear@0 166 png_uint_32 row_width = row_info->width;
nuclear@0 167
nuclear@0 168 sp = row;
nuclear@0 169 dp = row;
nuclear@0 170 shift = 4;
nuclear@0 171 v = 0;
nuclear@0 172 for (i = 0; i < row_width; i++)
nuclear@0 173 {
nuclear@0 174 png_byte value;
nuclear@0 175
nuclear@0 176 value = (png_byte)(*sp & 0x0f);
nuclear@0 177 v |= (value << shift);
nuclear@0 178
nuclear@0 179 if (shift == 0)
nuclear@0 180 {
nuclear@0 181 shift = 4;
nuclear@0 182 *dp = (png_byte)v;
nuclear@0 183 dp++;
nuclear@0 184 v = 0;
nuclear@0 185 }
nuclear@0 186 else
nuclear@0 187 shift -= 4;
nuclear@0 188
nuclear@0 189 sp++;
nuclear@0 190 }
nuclear@0 191 if (shift != 4)
nuclear@0 192 *dp = (png_byte)v;
nuclear@0 193 break;
nuclear@0 194 }
nuclear@0 195 }
nuclear@0 196 row_info->bit_depth = (png_byte)bit_depth;
nuclear@0 197 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
nuclear@0 198 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
nuclear@0 199 row_info->width);
nuclear@0 200 }
nuclear@0 201 }
nuclear@0 202 #endif
nuclear@0 203
nuclear@0 204 #if defined(PNG_WRITE_SHIFT_SUPPORTED)
nuclear@0 205 /* Shift pixel values to take advantage of whole range. Pass the
nuclear@0 206 * true number of bits in bit_depth. The row should be packed
nuclear@0 207 * according to row_info->bit_depth. Thus, if you had a row of
nuclear@0 208 * bit depth 4, but the pixels only had values from 0 to 7, you
nuclear@0 209 * would pass 3 as bit_depth, and this routine would translate the
nuclear@0 210 * data to 0 to 15.
nuclear@0 211 */
nuclear@0 212 void /* PRIVATE */
nuclear@0 213 png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
nuclear@0 214 {
nuclear@0 215 png_debug(1, "in png_do_shift\n");
nuclear@0 216 #if defined(PNG_USELESS_TESTS_SUPPORTED)
nuclear@0 217 if (row != NULL && row_info != NULL &&
nuclear@0 218 #else
nuclear@0 219 if (
nuclear@0 220 #endif
nuclear@0 221 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
nuclear@0 222 {
nuclear@0 223 int shift_start[4], shift_dec[4];
nuclear@0 224 int channels = 0;
nuclear@0 225
nuclear@0 226 if (row_info->color_type & PNG_COLOR_MASK_COLOR)
nuclear@0 227 {
nuclear@0 228 shift_start[channels] = row_info->bit_depth - bit_depth->red;
nuclear@0 229 shift_dec[channels] = bit_depth->red;
nuclear@0 230 channels++;
nuclear@0 231 shift_start[channels] = row_info->bit_depth - bit_depth->green;
nuclear@0 232 shift_dec[channels] = bit_depth->green;
nuclear@0 233 channels++;
nuclear@0 234 shift_start[channels] = row_info->bit_depth - bit_depth->blue;
nuclear@0 235 shift_dec[channels] = bit_depth->blue;
nuclear@0 236 channels++;
nuclear@0 237 }
nuclear@0 238 else
nuclear@0 239 {
nuclear@0 240 shift_start[channels] = row_info->bit_depth - bit_depth->gray;
nuclear@0 241 shift_dec[channels] = bit_depth->gray;
nuclear@0 242 channels++;
nuclear@0 243 }
nuclear@0 244 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
nuclear@0 245 {
nuclear@0 246 shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
nuclear@0 247 shift_dec[channels] = bit_depth->alpha;
nuclear@0 248 channels++;
nuclear@0 249 }
nuclear@0 250
nuclear@0 251 /* with low row depths, could only be grayscale, so one channel */
nuclear@0 252 if (row_info->bit_depth < 8)
nuclear@0 253 {
nuclear@0 254 png_bytep bp = row;
nuclear@0 255 png_uint_32 i;
nuclear@0 256 png_byte mask;
nuclear@0 257 png_uint_32 row_bytes = row_info->rowbytes;
nuclear@0 258
nuclear@0 259 if (bit_depth->gray == 1 && row_info->bit_depth == 2)
nuclear@0 260 mask = 0x55;
nuclear@0 261 else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
nuclear@0 262 mask = 0x11;
nuclear@0 263 else
nuclear@0 264 mask = 0xff;
nuclear@0 265
nuclear@0 266 for (i = 0; i < row_bytes; i++, bp++)
nuclear@0 267 {
nuclear@0 268 png_uint_16 v;
nuclear@0 269 int j;
nuclear@0 270
nuclear@0 271 v = *bp;
nuclear@0 272 *bp = 0;
nuclear@0 273 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
nuclear@0 274 {
nuclear@0 275 if (j > 0)
nuclear@0 276 *bp |= (png_byte)((v << j) & 0xff);
nuclear@0 277 else
nuclear@0 278 *bp |= (png_byte)((v >> (-j)) & mask);
nuclear@0 279 }
nuclear@0 280 }
nuclear@0 281 }
nuclear@0 282 else if (row_info->bit_depth == 8)
nuclear@0 283 {
nuclear@0 284 png_bytep bp = row;
nuclear@0 285 png_uint_32 i;
nuclear@0 286 png_uint_32 istop = channels * row_info->width;
nuclear@0 287
nuclear@0 288 for (i = 0; i < istop; i++, bp++)
nuclear@0 289 {
nuclear@0 290
nuclear@0 291 png_uint_16 v;
nuclear@0 292 int j;
nuclear@0 293 int c = (int)(i%channels);
nuclear@0 294
nuclear@0 295 v = *bp;
nuclear@0 296 *bp = 0;
nuclear@0 297 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
nuclear@0 298 {
nuclear@0 299 if (j > 0)
nuclear@0 300 *bp |= (png_byte)((v << j) & 0xff);
nuclear@0 301 else
nuclear@0 302 *bp |= (png_byte)((v >> (-j)) & 0xff);
nuclear@0 303 }
nuclear@0 304 }
nuclear@0 305 }
nuclear@0 306 else
nuclear@0 307 {
nuclear@0 308 png_bytep bp;
nuclear@0 309 png_uint_32 i;
nuclear@0 310 png_uint_32 istop = channels * row_info->width;
nuclear@0 311
nuclear@0 312 for (bp = row, i = 0; i < istop; i++)
nuclear@0 313 {
nuclear@0 314 int c = (int)(i%channels);
nuclear@0 315 png_uint_16 value, v;
nuclear@0 316 int j;
nuclear@0 317
nuclear@0 318 v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
nuclear@0 319 value = 0;
nuclear@0 320 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
nuclear@0 321 {
nuclear@0 322 if (j > 0)
nuclear@0 323 value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
nuclear@0 324 else
nuclear@0 325 value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
nuclear@0 326 }
nuclear@0 327 *bp++ = (png_byte)(value >> 8);
nuclear@0 328 *bp++ = (png_byte)(value & 0xff);
nuclear@0 329 }
nuclear@0 330 }
nuclear@0 331 }
nuclear@0 332 }
nuclear@0 333 #endif
nuclear@0 334
nuclear@0 335 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
nuclear@0 336 void /* PRIVATE */
nuclear@0 337 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
nuclear@0 338 {
nuclear@0 339 png_debug(1, "in png_do_write_swap_alpha\n");
nuclear@0 340 #if defined(PNG_USELESS_TESTS_SUPPORTED)
nuclear@0 341 if (row != NULL && row_info != NULL)
nuclear@0 342 #endif
nuclear@0 343 {
nuclear@0 344 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
nuclear@0 345 {
nuclear@0 346 /* This converts from ARGB to RGBA */
nuclear@0 347 if (row_info->bit_depth == 8)
nuclear@0 348 {
nuclear@0 349 png_bytep sp, dp;
nuclear@0 350 png_uint_32 i;
nuclear@0 351 png_uint_32 row_width = row_info->width;
nuclear@0 352 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 353 {
nuclear@0 354 png_byte save = *(sp++);
nuclear@0 355 *(dp++) = *(sp++);
nuclear@0 356 *(dp++) = *(sp++);
nuclear@0 357 *(dp++) = *(sp++);
nuclear@0 358 *(dp++) = save;
nuclear@0 359 }
nuclear@0 360 }
nuclear@0 361 /* This converts from AARRGGBB to RRGGBBAA */
nuclear@0 362 else
nuclear@0 363 {
nuclear@0 364 png_bytep sp, dp;
nuclear@0 365 png_uint_32 i;
nuclear@0 366 png_uint_32 row_width = row_info->width;
nuclear@0 367
nuclear@0 368 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 369 {
nuclear@0 370 png_byte save[2];
nuclear@0 371 save[0] = *(sp++);
nuclear@0 372 save[1] = *(sp++);
nuclear@0 373 *(dp++) = *(sp++);
nuclear@0 374 *(dp++) = *(sp++);
nuclear@0 375 *(dp++) = *(sp++);
nuclear@0 376 *(dp++) = *(sp++);
nuclear@0 377 *(dp++) = *(sp++);
nuclear@0 378 *(dp++) = *(sp++);
nuclear@0 379 *(dp++) = save[0];
nuclear@0 380 *(dp++) = save[1];
nuclear@0 381 }
nuclear@0 382 }
nuclear@0 383 }
nuclear@0 384 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
nuclear@0 385 {
nuclear@0 386 /* This converts from AG to GA */
nuclear@0 387 if (row_info->bit_depth == 8)
nuclear@0 388 {
nuclear@0 389 png_bytep sp, dp;
nuclear@0 390 png_uint_32 i;
nuclear@0 391 png_uint_32 row_width = row_info->width;
nuclear@0 392
nuclear@0 393 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 394 {
nuclear@0 395 png_byte save = *(sp++);
nuclear@0 396 *(dp++) = *(sp++);
nuclear@0 397 *(dp++) = save;
nuclear@0 398 }
nuclear@0 399 }
nuclear@0 400 /* This converts from AAGG to GGAA */
nuclear@0 401 else
nuclear@0 402 {
nuclear@0 403 png_bytep sp, dp;
nuclear@0 404 png_uint_32 i;
nuclear@0 405 png_uint_32 row_width = row_info->width;
nuclear@0 406
nuclear@0 407 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 408 {
nuclear@0 409 png_byte save[2];
nuclear@0 410 save[0] = *(sp++);
nuclear@0 411 save[1] = *(sp++);
nuclear@0 412 *(dp++) = *(sp++);
nuclear@0 413 *(dp++) = *(sp++);
nuclear@0 414 *(dp++) = save[0];
nuclear@0 415 *(dp++) = save[1];
nuclear@0 416 }
nuclear@0 417 }
nuclear@0 418 }
nuclear@0 419 }
nuclear@0 420 }
nuclear@0 421 #endif
nuclear@0 422
nuclear@0 423 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
nuclear@0 424 void /* PRIVATE */
nuclear@0 425 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
nuclear@0 426 {
nuclear@0 427 png_debug(1, "in png_do_write_invert_alpha\n");
nuclear@0 428 #if defined(PNG_USELESS_TESTS_SUPPORTED)
nuclear@0 429 if (row != NULL && row_info != NULL)
nuclear@0 430 #endif
nuclear@0 431 {
nuclear@0 432 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
nuclear@0 433 {
nuclear@0 434 /* This inverts the alpha channel in RGBA */
nuclear@0 435 if (row_info->bit_depth == 8)
nuclear@0 436 {
nuclear@0 437 png_bytep sp, dp;
nuclear@0 438 png_uint_32 i;
nuclear@0 439 png_uint_32 row_width = row_info->width;
nuclear@0 440 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 441 {
nuclear@0 442 /* does nothing
nuclear@0 443 *(dp++) = *(sp++);
nuclear@0 444 *(dp++) = *(sp++);
nuclear@0 445 *(dp++) = *(sp++);
nuclear@0 446 */
nuclear@0 447 sp+=3; dp = sp;
nuclear@0 448 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 449 }
nuclear@0 450 }
nuclear@0 451 /* This inverts the alpha channel in RRGGBBAA */
nuclear@0 452 else
nuclear@0 453 {
nuclear@0 454 png_bytep sp, dp;
nuclear@0 455 png_uint_32 i;
nuclear@0 456 png_uint_32 row_width = row_info->width;
nuclear@0 457
nuclear@0 458 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 459 {
nuclear@0 460 /* does nothing
nuclear@0 461 *(dp++) = *(sp++);
nuclear@0 462 *(dp++) = *(sp++);
nuclear@0 463 *(dp++) = *(sp++);
nuclear@0 464 *(dp++) = *(sp++);
nuclear@0 465 *(dp++) = *(sp++);
nuclear@0 466 *(dp++) = *(sp++);
nuclear@0 467 */
nuclear@0 468 sp+=6; dp = sp;
nuclear@0 469 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 470 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 471 }
nuclear@0 472 }
nuclear@0 473 }
nuclear@0 474 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
nuclear@0 475 {
nuclear@0 476 /* This inverts the alpha channel in GA */
nuclear@0 477 if (row_info->bit_depth == 8)
nuclear@0 478 {
nuclear@0 479 png_bytep sp, dp;
nuclear@0 480 png_uint_32 i;
nuclear@0 481 png_uint_32 row_width = row_info->width;
nuclear@0 482
nuclear@0 483 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 484 {
nuclear@0 485 *(dp++) = *(sp++);
nuclear@0 486 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 487 }
nuclear@0 488 }
nuclear@0 489 /* This inverts the alpha channel in GGAA */
nuclear@0 490 else
nuclear@0 491 {
nuclear@0 492 png_bytep sp, dp;
nuclear@0 493 png_uint_32 i;
nuclear@0 494 png_uint_32 row_width = row_info->width;
nuclear@0 495
nuclear@0 496 for (i = 0, sp = dp = row; i < row_width; i++)
nuclear@0 497 {
nuclear@0 498 /* does nothing
nuclear@0 499 *(dp++) = *(sp++);
nuclear@0 500 *(dp++) = *(sp++);
nuclear@0 501 */
nuclear@0 502 sp+=2; dp = sp;
nuclear@0 503 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 504 *(dp++) = (png_byte)(255 - *(sp++));
nuclear@0 505 }
nuclear@0 506 }
nuclear@0 507 }
nuclear@0 508 }
nuclear@0 509 }
nuclear@0 510 #endif
nuclear@0 511
nuclear@0 512 #if defined(PNG_MNG_FEATURES_SUPPORTED)
nuclear@0 513 /* undoes intrapixel differencing */
nuclear@0 514 void /* PRIVATE */
nuclear@0 515 png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
nuclear@0 516 {
nuclear@0 517 png_debug(1, "in png_do_write_intrapixel\n");
nuclear@0 518 if (
nuclear@0 519 #if defined(PNG_USELESS_TESTS_SUPPORTED)
nuclear@0 520 row != NULL && row_info != NULL &&
nuclear@0 521 #endif
nuclear@0 522 (row_info->color_type & PNG_COLOR_MASK_COLOR))
nuclear@0 523 {
nuclear@0 524 int bytes_per_pixel;
nuclear@0 525 png_uint_32 row_width = row_info->width;
nuclear@0 526 if (row_info->bit_depth == 8)
nuclear@0 527 {
nuclear@0 528 png_bytep rp;
nuclear@0 529 png_uint_32 i;
nuclear@0 530
nuclear@0 531 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
nuclear@0 532 bytes_per_pixel = 3;
nuclear@0 533 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
nuclear@0 534 bytes_per_pixel = 4;
nuclear@0 535 else
nuclear@0 536 return;
nuclear@0 537
nuclear@0 538 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
nuclear@0 539 {
nuclear@0 540 *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
nuclear@0 541 *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
nuclear@0 542 }
nuclear@0 543 }
nuclear@0 544 else if (row_info->bit_depth == 16)
nuclear@0 545 {
nuclear@0 546 png_bytep rp;
nuclear@0 547 png_uint_32 i;
nuclear@0 548
nuclear@0 549 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
nuclear@0 550 bytes_per_pixel = 6;
nuclear@0 551 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
nuclear@0 552 bytes_per_pixel = 8;
nuclear@0 553 else
nuclear@0 554 return;
nuclear@0 555
nuclear@0 556 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
nuclear@0 557 {
nuclear@0 558 png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
nuclear@0 559 png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
nuclear@0 560 png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
nuclear@0 561 png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
nuclear@0 562 png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
nuclear@0 563 *(rp ) = (png_byte)((red >> 8) & 0xff);
nuclear@0 564 *(rp+1) = (png_byte)(red & 0xff);
nuclear@0 565 *(rp+4) = (png_byte)((blue >> 8) & 0xff);
nuclear@0 566 *(rp+5) = (png_byte)(blue & 0xff);
nuclear@0 567 }
nuclear@0 568 }
nuclear@0 569 }
nuclear@0 570 }
nuclear@0 571 #endif /* PNG_MNG_FEATURES_SUPPORTED */
nuclear@0 572 #endif /* PNG_WRITE_SUPPORTED */