00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #define PNG_INTERNAL
00012 #include "png.h"
00013 #ifdef PNG_WRITE_SUPPORTED
00014
00015
00016
00017
00018 void
00019 png_do_write_transformations(png_structp png_ptr)
00020 {
00021 png_debug(1, "in png_do_write_transformations\n");
00022
00023 if (png_ptr == NULL)
00024 return;
00025
00026 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
00027 if (png_ptr->transformations & PNG_USER_TRANSFORM)
00028 if (png_ptr->write_user_transform_fn != NULL)
00029 (*(png_ptr->write_user_transform_fn))
00030 (png_ptr,
00031 &(png_ptr->row_info),
00032
00033
00034
00035
00036
00037
00038 png_ptr->row_buf + 1);
00039 #endif
00040 #if defined(PNG_WRITE_FILLER_SUPPORTED)
00041 if (png_ptr->transformations & PNG_FILLER)
00042 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
00043 png_ptr->flags);
00044 #endif
00045 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00046 if (png_ptr->transformations & PNG_PACKSWAP)
00047 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
00048 #endif
00049 #if defined(PNG_WRITE_PACK_SUPPORTED)
00050 if (png_ptr->transformations & PNG_PACK)
00051 png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
00052 (png_uint_32)png_ptr->bit_depth);
00053 #endif
00054 #if defined(PNG_WRITE_SWAP_SUPPORTED)
00055 if (png_ptr->transformations & PNG_SWAP_BYTES)
00056 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
00057 #endif
00058 #if defined(PNG_WRITE_SHIFT_SUPPORTED)
00059 if (png_ptr->transformations & PNG_SHIFT)
00060 png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
00061 &(png_ptr->shift));
00062 #endif
00063 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00064 if (png_ptr->transformations & PNG_SWAP_ALPHA)
00065 png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
00066 #endif
00067 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00068 if (png_ptr->transformations & PNG_INVERT_ALPHA)
00069 png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
00070 #endif
00071 #if defined(PNG_WRITE_BGR_SUPPORTED)
00072 if (png_ptr->transformations & PNG_BGR)
00073 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
00074 #endif
00075 #if defined(PNG_WRITE_INVERT_SUPPORTED)
00076 if (png_ptr->transformations & PNG_INVERT_MONO)
00077 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
00078 #endif
00079 }
00080
00081 #if defined(PNG_WRITE_PACK_SUPPORTED)
00082
00083
00084
00085
00086 void
00087 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
00088 {
00089 png_debug(1, "in png_do_pack\n");
00090 if (row_info->bit_depth == 8 &&
00091 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00092 row != NULL && row_info != NULL &&
00093 #endif
00094 row_info->channels == 1)
00095 {
00096 switch ((int)bit_depth)
00097 {
00098 case 1:
00099 {
00100 png_bytep sp, dp;
00101 int mask, v;
00102 png_uint_32 i;
00103 png_uint_32 row_width = row_info->width;
00104
00105 sp = row;
00106 dp = row;
00107 mask = 0x80;
00108 v = 0;
00109
00110 for (i = 0; i < row_width; i++)
00111 {
00112 if (*sp != 0)
00113 v |= mask;
00114 sp++;
00115 if (mask > 1)
00116 mask >>= 1;
00117 else
00118 {
00119 mask = 0x80;
00120 *dp = (png_byte)v;
00121 dp++;
00122 v = 0;
00123 }
00124 }
00125 if (mask != 0x80)
00126 *dp = (png_byte)v;
00127 break;
00128 }
00129 case 2:
00130 {
00131 png_bytep sp, dp;
00132 int shift, v;
00133 png_uint_32 i;
00134 png_uint_32 row_width = row_info->width;
00135
00136 sp = row;
00137 dp = row;
00138 shift = 6;
00139 v = 0;
00140 for (i = 0; i < row_width; i++)
00141 {
00142 png_byte value;
00143
00144 value = (png_byte)(*sp & 0x03);
00145 v |= (value << shift);
00146 if (shift == 0)
00147 {
00148 shift = 6;
00149 *dp = (png_byte)v;
00150 dp++;
00151 v = 0;
00152 }
00153 else
00154 shift -= 2;
00155 sp++;
00156 }
00157 if (shift != 6)
00158 *dp = (png_byte)v;
00159 break;
00160 }
00161 case 4:
00162 {
00163 png_bytep sp, dp;
00164 int shift, v;
00165 png_uint_32 i;
00166 png_uint_32 row_width = row_info->width;
00167
00168 sp = row;
00169 dp = row;
00170 shift = 4;
00171 v = 0;
00172 for (i = 0; i < row_width; i++)
00173 {
00174 png_byte value;
00175
00176 value = (png_byte)(*sp & 0x0f);
00177 v |= (value << shift);
00178
00179 if (shift == 0)
00180 {
00181 shift = 4;
00182 *dp = (png_byte)v;
00183 dp++;
00184 v = 0;
00185 }
00186 else
00187 shift -= 4;
00188
00189 sp++;
00190 }
00191 if (shift != 4)
00192 *dp = (png_byte)v;
00193 break;
00194 }
00195 }
00196 row_info->bit_depth = (png_byte)bit_depth;
00197 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
00198 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
00199 row_info->width);
00200 }
00201 }
00202 #endif
00203
00204 #if defined(PNG_WRITE_SHIFT_SUPPORTED)
00205
00206
00207
00208
00209
00210
00211
00212 void
00213 png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
00214 {
00215 png_debug(1, "in png_do_shift\n");
00216 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00217 if (row != NULL && row_info != NULL &&
00218 #else
00219 if (
00220 #endif
00221 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
00222 {
00223 int shift_start[4], shift_dec[4];
00224 int channels = 0;
00225
00226 if (row_info->color_type & PNG_COLOR_MASK_COLOR)
00227 {
00228 shift_start[channels] = row_info->bit_depth - bit_depth->red;
00229 shift_dec[channels] = bit_depth->red;
00230 channels++;
00231 shift_start[channels] = row_info->bit_depth - bit_depth->green;
00232 shift_dec[channels] = bit_depth->green;
00233 channels++;
00234 shift_start[channels] = row_info->bit_depth - bit_depth->blue;
00235 shift_dec[channels] = bit_depth->blue;
00236 channels++;
00237 }
00238 else
00239 {
00240 shift_start[channels] = row_info->bit_depth - bit_depth->gray;
00241 shift_dec[channels] = bit_depth->gray;
00242 channels++;
00243 }
00244 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
00245 {
00246 shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
00247 shift_dec[channels] = bit_depth->alpha;
00248 channels++;
00249 }
00250
00251
00252 if (row_info->bit_depth < 8)
00253 {
00254 png_bytep bp = row;
00255 png_uint_32 i;
00256 png_byte mask;
00257 png_uint_32 row_bytes = row_info->rowbytes;
00258
00259 if (bit_depth->gray == 1 && row_info->bit_depth == 2)
00260 mask = 0x55;
00261 else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
00262 mask = 0x11;
00263 else
00264 mask = 0xff;
00265
00266 for (i = 0; i < row_bytes; i++, bp++)
00267 {
00268 png_uint_16 v;
00269 int j;
00270
00271 v = *bp;
00272 *bp = 0;
00273 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
00274 {
00275 if (j > 0)
00276 *bp |= (png_byte)((v << j) & 0xff);
00277 else
00278 *bp |= (png_byte)((v >> (-j)) & mask);
00279 }
00280 }
00281 }
00282 else if (row_info->bit_depth == 8)
00283 {
00284 png_bytep bp = row;
00285 png_uint_32 i;
00286 png_uint_32 istop = channels * row_info->width;
00287
00288 for (i = 0; i < istop; i++, bp++)
00289 {
00290
00291 png_uint_16 v;
00292 int j;
00293 int c = (int)(i%channels);
00294
00295 v = *bp;
00296 *bp = 0;
00297 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
00298 {
00299 if (j > 0)
00300 *bp |= (png_byte)((v << j) & 0xff);
00301 else
00302 *bp |= (png_byte)((v >> (-j)) & 0xff);
00303 }
00304 }
00305 }
00306 else
00307 {
00308 png_bytep bp;
00309 png_uint_32 i;
00310 png_uint_32 istop = channels * row_info->width;
00311
00312 for (bp = row, i = 0; i < istop; i++)
00313 {
00314 int c = (int)(i%channels);
00315 png_uint_16 value, v;
00316 int j;
00317
00318 v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
00319 value = 0;
00320 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
00321 {
00322 if (j > 0)
00323 value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
00324 else
00325 value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
00326 }
00327 *bp++ = (png_byte)(value >> 8);
00328 *bp++ = (png_byte)(value & 0xff);
00329 }
00330 }
00331 }
00332 }
00333 #endif
00334
00335 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00336 void
00337 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
00338 {
00339 png_debug(1, "in png_do_write_swap_alpha\n");
00340 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00341 if (row != NULL && row_info != NULL)
00342 #endif
00343 {
00344 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00345 {
00346
00347 if (row_info->bit_depth == 8)
00348 {
00349 png_bytep sp, dp;
00350 png_uint_32 i;
00351 png_uint_32 row_width = row_info->width;
00352 for (i = 0, sp = dp = row; i < row_width; i++)
00353 {
00354 png_byte save = *(sp++);
00355 *(dp++) = *(sp++);
00356 *(dp++) = *(sp++);
00357 *(dp++) = *(sp++);
00358 *(dp++) = save;
00359 }
00360 }
00361
00362 else
00363 {
00364 png_bytep sp, dp;
00365 png_uint_32 i;
00366 png_uint_32 row_width = row_info->width;
00367
00368 for (i = 0, sp = dp = row; i < row_width; i++)
00369 {
00370 png_byte save[2];
00371 save[0] = *(sp++);
00372 save[1] = *(sp++);
00373 *(dp++) = *(sp++);
00374 *(dp++) = *(sp++);
00375 *(dp++) = *(sp++);
00376 *(dp++) = *(sp++);
00377 *(dp++) = *(sp++);
00378 *(dp++) = *(sp++);
00379 *(dp++) = save[0];
00380 *(dp++) = save[1];
00381 }
00382 }
00383 }
00384 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00385 {
00386
00387 if (row_info->bit_depth == 8)
00388 {
00389 png_bytep sp, dp;
00390 png_uint_32 i;
00391 png_uint_32 row_width = row_info->width;
00392
00393 for (i = 0, sp = dp = row; i < row_width; i++)
00394 {
00395 png_byte save = *(sp++);
00396 *(dp++) = *(sp++);
00397 *(dp++) = save;
00398 }
00399 }
00400
00401 else
00402 {
00403 png_bytep sp, dp;
00404 png_uint_32 i;
00405 png_uint_32 row_width = row_info->width;
00406
00407 for (i = 0, sp = dp = row; i < row_width; i++)
00408 {
00409 png_byte save[2];
00410 save[0] = *(sp++);
00411 save[1] = *(sp++);
00412 *(dp++) = *(sp++);
00413 *(dp++) = *(sp++);
00414 *(dp++) = save[0];
00415 *(dp++) = save[1];
00416 }
00417 }
00418 }
00419 }
00420 }
00421 #endif
00422
00423 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00424 void
00425 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
00426 {
00427 png_debug(1, "in png_do_write_invert_alpha\n");
00428 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00429 if (row != NULL && row_info != NULL)
00430 #endif
00431 {
00432 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00433 {
00434
00435 if (row_info->bit_depth == 8)
00436 {
00437 png_bytep sp, dp;
00438 png_uint_32 i;
00439 png_uint_32 row_width = row_info->width;
00440 for (i = 0, sp = dp = row; i < row_width; i++)
00441 {
00442
00443
00444
00445
00446
00447 sp+=3; dp = sp;
00448 *(dp++) = (png_byte)(255 - *(sp++));
00449 }
00450 }
00451
00452 else
00453 {
00454 png_bytep sp, dp;
00455 png_uint_32 i;
00456 png_uint_32 row_width = row_info->width;
00457
00458 for (i = 0, sp = dp = row; i < row_width; i++)
00459 {
00460
00461
00462
00463
00464
00465
00466
00467
00468 sp+=6; dp = sp;
00469 *(dp++) = (png_byte)(255 - *(sp++));
00470 *(dp++) = (png_byte)(255 - *(sp++));
00471 }
00472 }
00473 }
00474 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00475 {
00476
00477 if (row_info->bit_depth == 8)
00478 {
00479 png_bytep sp, dp;
00480 png_uint_32 i;
00481 png_uint_32 row_width = row_info->width;
00482
00483 for (i = 0, sp = dp = row; i < row_width; i++)
00484 {
00485 *(dp++) = *(sp++);
00486 *(dp++) = (png_byte)(255 - *(sp++));
00487 }
00488 }
00489
00490 else
00491 {
00492 png_bytep sp, dp;
00493 png_uint_32 i;
00494 png_uint_32 row_width = row_info->width;
00495
00496 for (i = 0, sp = dp = row; i < row_width; i++)
00497 {
00498
00499
00500
00501
00502 sp+=2; dp = sp;
00503 *(dp++) = (png_byte)(255 - *(sp++));
00504 *(dp++) = (png_byte)(255 - *(sp++));
00505 }
00506 }
00507 }
00508 }
00509 }
00510 #endif
00511
00512 #if defined(PNG_MNG_FEATURES_SUPPORTED)
00513
00514 void
00515 png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
00516 {
00517 png_debug(1, "in png_do_write_intrapixel\n");
00518 if (
00519 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00520 row != NULL && row_info != NULL &&
00521 #endif
00522 (row_info->color_type & PNG_COLOR_MASK_COLOR))
00523 {
00524 int bytes_per_pixel;
00525 png_uint_32 row_width = row_info->width;
00526 if (row_info->bit_depth == 8)
00527 {
00528 png_bytep rp;
00529 png_uint_32 i;
00530
00531 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00532 bytes_per_pixel = 3;
00533 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00534 bytes_per_pixel = 4;
00535 else
00536 return;
00537
00538 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
00539 {
00540 *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
00541 *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
00542 }
00543 }
00544 else if (row_info->bit_depth == 16)
00545 {
00546 png_bytep rp;
00547 png_uint_32 i;
00548
00549 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00550 bytes_per_pixel = 6;
00551 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00552 bytes_per_pixel = 8;
00553 else
00554 return;
00555
00556 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
00557 {
00558 png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
00559 png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
00560 png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
00561 png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
00562 png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
00563 *(rp ) = (png_byte)((red >> 8) & 0xff);
00564 *(rp+1) = (png_byte)(red & 0xff);
00565 *(rp+4) = (png_byte)((blue >> 8) & 0xff);
00566 *(rp+5) = (png_byte)(blue & 0xff);
00567 }
00568 }
00569 }
00570 }
00571 #endif
00572 #endif