ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pngwtran.c
Go to the documentation of this file.
00001 
00002 /* pngwtran.c - transforms the data in a row for PNG writers
00003  *
00004  * Last changed in libpng 1.5.6 [November 3, 2011]
00005  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
00006  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00007  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00008  *
00009  * This code is released under the libpng license.
00010  * For conditions of distribution and use, see the disclaimer
00011  * and license in png.h
00012  */
00013 
00014 #include "pngpriv.h"
00015 
00016 #ifdef PNG_WRITE_SUPPORTED
00017 
00018 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
00019 /* Transform the data according to the user's wishes.  The order of
00020  * transformations is significant.
00021  */
00022 void /* PRIVATE */
00023 png_do_write_transformations(png_structp png_ptr, png_row_infop row_info)
00024 {
00025    png_debug(1, "in png_do_write_transformations");
00026 
00027    if (png_ptr == NULL)
00028       return;
00029 
00030 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
00031    if (png_ptr->transformations & PNG_USER_TRANSFORM)
00032       if (png_ptr->write_user_transform_fn != NULL)
00033          (*(png_ptr->write_user_transform_fn)) /* User write transform
00034                                                  function */
00035              (png_ptr,  /* png_ptr */
00036              row_info,  /* row_info: */
00037                 /*  png_uint_32 width;       width of row */
00038                 /*  png_size_t rowbytes;     number of bytes in row */
00039                 /*  png_byte color_type;     color type of pixels */
00040                 /*  png_byte bit_depth;      bit depth of samples */
00041                 /*  png_byte channels;       number of channels (1-4) */
00042                 /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
00043              png_ptr->row_buf + 1);      /* start of pixel data for row */
00044 #endif
00045 
00046 #ifdef PNG_WRITE_FILLER_SUPPORTED
00047    if (png_ptr->transformations & PNG_FILLER)
00048       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
00049          !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
00050 #endif
00051 
00052 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
00053    if (png_ptr->transformations & PNG_PACKSWAP)
00054       png_do_packswap(row_info, png_ptr->row_buf + 1);
00055 #endif
00056 
00057 #ifdef PNG_WRITE_PACK_SUPPORTED
00058    if (png_ptr->transformations & PNG_PACK)
00059       png_do_pack(row_info, png_ptr->row_buf + 1,
00060           (png_uint_32)png_ptr->bit_depth);
00061 #endif
00062 
00063 #ifdef PNG_WRITE_SWAP_SUPPORTED
00064    if (png_ptr->transformations & PNG_SWAP_BYTES)
00065       png_do_swap(row_info, png_ptr->row_buf + 1);
00066 #endif
00067 
00068 #ifdef PNG_WRITE_SHIFT_SUPPORTED
00069    if (png_ptr->transformations & PNG_SHIFT)
00070       png_do_shift(row_info, png_ptr->row_buf + 1,
00071           &(png_ptr->shift));
00072 #endif
00073 
00074 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
00075    if (png_ptr->transformations & PNG_SWAP_ALPHA)
00076       png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
00077 #endif
00078 
00079 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
00080    if (png_ptr->transformations & PNG_INVERT_ALPHA)
00081       png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
00082 #endif
00083 
00084 #ifdef PNG_WRITE_BGR_SUPPORTED
00085    if (png_ptr->transformations & PNG_BGR)
00086       png_do_bgr(row_info, png_ptr->row_buf + 1);
00087 #endif
00088 
00089 #ifdef PNG_WRITE_INVERT_SUPPORTED
00090    if (png_ptr->transformations & PNG_INVERT_MONO)
00091       png_do_invert(row_info, png_ptr->row_buf + 1);
00092 #endif
00093 }
00094 
00095 #ifdef PNG_WRITE_PACK_SUPPORTED
00096 /* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
00097  * row_info bit depth should be 8 (one pixel per byte).  The channels
00098  * should be 1 (this only happens on grayscale and paletted images).
00099  */
00100 void /* PRIVATE */
00101 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
00102 {
00103    png_debug(1, "in png_do_pack");
00104 
00105    if (row_info->bit_depth == 8 &&
00106       row_info->channels == 1)
00107    {
00108       switch ((int)bit_depth)
00109       {
00110          case 1:
00111          {
00112             png_bytep sp, dp;
00113             int mask, v;
00114             png_uint_32 i;
00115             png_uint_32 row_width = row_info->width;
00116 
00117             sp = row;
00118             dp = row;
00119             mask = 0x80;
00120             v = 0;
00121 
00122             for (i = 0; i < row_width; i++)
00123             {
00124                if (*sp != 0)
00125                   v |= mask;
00126 
00127                sp++;
00128 
00129                if (mask > 1)
00130                   mask >>= 1;
00131 
00132                else
00133                {
00134                   mask = 0x80;
00135                   *dp = (png_byte)v;
00136                   dp++;
00137                   v = 0;
00138                }
00139             }
00140 
00141             if (mask != 0x80)
00142                *dp = (png_byte)v;
00143 
00144             break;
00145          }
00146 
00147          case 2:
00148          {
00149             png_bytep sp, dp;
00150             int shift, v;
00151             png_uint_32 i;
00152             png_uint_32 row_width = row_info->width;
00153 
00154             sp = row;
00155             dp = row;
00156             shift = 6;
00157             v = 0;
00158 
00159             for (i = 0; i < row_width; i++)
00160             {
00161                png_byte value;
00162 
00163                value = (png_byte)(*sp & 0x03);
00164                v |= (value << shift);
00165 
00166                if (shift == 0)
00167                {
00168                   shift = 6;
00169                   *dp = (png_byte)v;
00170                   dp++;
00171                   v = 0;
00172                }
00173 
00174                else
00175                   shift -= 2;
00176 
00177                sp++;
00178             }
00179 
00180             if (shift != 6)
00181                *dp = (png_byte)v;
00182 
00183             break;
00184          }
00185 
00186          case 4:
00187          {
00188             png_bytep sp, dp;
00189             int shift, v;
00190             png_uint_32 i;
00191             png_uint_32 row_width = row_info->width;
00192 
00193             sp = row;
00194             dp = row;
00195             shift = 4;
00196             v = 0;
00197 
00198             for (i = 0; i < row_width; i++)
00199             {
00200                png_byte value;
00201 
00202                value = (png_byte)(*sp & 0x0f);
00203                v |= (value << shift);
00204 
00205                if (shift == 0)
00206                {
00207                   shift = 4;
00208                   *dp = (png_byte)v;
00209                   dp++;
00210                   v = 0;
00211                }
00212 
00213                else
00214                   shift -= 4;
00215 
00216                sp++;
00217             }
00218 
00219             if (shift != 4)
00220                *dp = (png_byte)v;
00221 
00222             break;
00223          }
00224 
00225          default:
00226             break;
00227       }
00228 
00229       row_info->bit_depth = (png_byte)bit_depth;
00230       row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
00231       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
00232           row_info->width);
00233    }
00234 }
00235 #endif
00236 
00237 #ifdef PNG_WRITE_SHIFT_SUPPORTED
00238 /* Shift pixel values to take advantage of whole range.  Pass the
00239  * true number of bits in bit_depth.  The row should be packed
00240  * according to row_info->bit_depth.  Thus, if you had a row of
00241  * bit depth 4, but the pixels only had values from 0 to 7, you
00242  * would pass 3 as bit_depth, and this routine would translate the
00243  * data to 0 to 15.
00244  */
00245 void /* PRIVATE */
00246 png_do_shift(png_row_infop row_info, png_bytep row,
00247     png_const_color_8p bit_depth)
00248 {
00249    png_debug(1, "in png_do_shift");
00250 
00251    if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
00252    {
00253       int shift_start[4], shift_dec[4];
00254       int channels = 0;
00255 
00256       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
00257       {
00258          shift_start[channels] = row_info->bit_depth - bit_depth->red;
00259          shift_dec[channels] = bit_depth->red;
00260          channels++;
00261 
00262          shift_start[channels] = row_info->bit_depth - bit_depth->green;
00263          shift_dec[channels] = bit_depth->green;
00264          channels++;
00265 
00266          shift_start[channels] = row_info->bit_depth - bit_depth->blue;
00267          shift_dec[channels] = bit_depth->blue;
00268          channels++;
00269       }
00270 
00271       else
00272       {
00273          shift_start[channels] = row_info->bit_depth - bit_depth->gray;
00274          shift_dec[channels] = bit_depth->gray;
00275          channels++;
00276       }
00277 
00278       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
00279       {
00280          shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
00281          shift_dec[channels] = bit_depth->alpha;
00282          channels++;
00283       }
00284 
00285       /* With low row depths, could only be grayscale, so one channel */
00286       if (row_info->bit_depth < 8)
00287       {
00288          png_bytep bp = row;
00289          png_size_t i;
00290          png_byte mask;
00291          png_size_t row_bytes = row_info->rowbytes;
00292 
00293          if (bit_depth->gray == 1 && row_info->bit_depth == 2)
00294             mask = 0x55;
00295 
00296          else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
00297             mask = 0x11;
00298 
00299          else
00300             mask = 0xff;
00301 
00302          for (i = 0; i < row_bytes; i++, bp++)
00303          {
00304             png_uint_16 v;
00305             int j;
00306 
00307             v = *bp;
00308             *bp = 0;
00309 
00310             for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
00311             {
00312                if (j > 0)
00313                   *bp |= (png_byte)((v << j) & 0xff);
00314 
00315                else
00316                   *bp |= (png_byte)((v >> (-j)) & mask);
00317             }
00318          }
00319       }
00320 
00321       else if (row_info->bit_depth == 8)
00322       {
00323          png_bytep bp = row;
00324          png_uint_32 i;
00325          png_uint_32 istop = channels * row_info->width;
00326 
00327          for (i = 0; i < istop; i++, bp++)
00328          {
00329 
00330             png_uint_16 v;
00331             int j;
00332             int c = (int)(i%channels);
00333 
00334             v = *bp;
00335             *bp = 0;
00336 
00337             for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
00338             {
00339                if (j > 0)
00340                   *bp |= (png_byte)((v << j) & 0xff);
00341 
00342                else
00343                   *bp |= (png_byte)((v >> (-j)) & 0xff);
00344             }
00345          }
00346       }
00347 
00348       else
00349       {
00350          png_bytep bp;
00351          png_uint_32 i;
00352          png_uint_32 istop = channels * row_info->width;
00353 
00354          for (bp = row, i = 0; i < istop; i++)
00355          {
00356             int c = (int)(i%channels);
00357             png_uint_16 value, v;
00358             int j;
00359 
00360             v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
00361             value = 0;
00362 
00363             for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
00364             {
00365                if (j > 0)
00366                   value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
00367 
00368                else
00369                   value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
00370             }
00371             *bp++ = (png_byte)(value >> 8);
00372             *bp++ = (png_byte)(value & 0xff);
00373          }
00374       }
00375    }
00376 }
00377 #endif
00378 
00379 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
00380 void /* PRIVATE */
00381 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
00382 {
00383    png_debug(1, "in png_do_write_swap_alpha");
00384 
00385    {
00386       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00387       {
00388          if (row_info->bit_depth == 8)
00389          {
00390             /* This converts from ARGB to RGBA */
00391             png_bytep sp, dp;
00392             png_uint_32 i;
00393             png_uint_32 row_width = row_info->width;
00394 
00395             for (i = 0, sp = dp = row; i < row_width; i++)
00396             {
00397                png_byte save = *(sp++);
00398                *(dp++) = *(sp++);
00399                *(dp++) = *(sp++);
00400                *(dp++) = *(sp++);
00401                *(dp++) = save;
00402             }
00403          }
00404 
00405 #ifdef PNG_WRITE_16BIT_SUPPORTED
00406          else
00407          {
00408             /* This converts from AARRGGBB to RRGGBBAA */
00409             png_bytep sp, dp;
00410             png_uint_32 i;
00411             png_uint_32 row_width = row_info->width;
00412 
00413             for (i = 0, sp = dp = row; i < row_width; i++)
00414             {
00415                png_byte save[2];
00416                save[0] = *(sp++);
00417                save[1] = *(sp++);
00418                *(dp++) = *(sp++);
00419                *(dp++) = *(sp++);
00420                *(dp++) = *(sp++);
00421                *(dp++) = *(sp++);
00422                *(dp++) = *(sp++);
00423                *(dp++) = *(sp++);
00424                *(dp++) = save[0];
00425                *(dp++) = save[1];
00426             }
00427          }
00428 #endif /* PNG_WRITE_16BIT_SUPPORTED */
00429       }
00430 
00431       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00432       {
00433          if (row_info->bit_depth == 8)
00434          {
00435             /* This converts from AG to GA */
00436             png_bytep sp, dp;
00437             png_uint_32 i;
00438             png_uint_32 row_width = row_info->width;
00439 
00440             for (i = 0, sp = dp = row; i < row_width; i++)
00441             {
00442                png_byte save = *(sp++);
00443                *(dp++) = *(sp++);
00444                *(dp++) = save;
00445             }
00446          }
00447 
00448 #ifdef PNG_WRITE_16BIT_SUPPORTED
00449          else
00450          {
00451             /* This converts from AAGG to GGAA */
00452             png_bytep sp, dp;
00453             png_uint_32 i;
00454             png_uint_32 row_width = row_info->width;
00455 
00456             for (i = 0, sp = dp = row; i < row_width; i++)
00457             {
00458                png_byte save[2];
00459                save[0] = *(sp++);
00460                save[1] = *(sp++);
00461                *(dp++) = *(sp++);
00462                *(dp++) = *(sp++);
00463                *(dp++) = save[0];
00464                *(dp++) = save[1];
00465             }
00466          }
00467 #endif /* PNG_WRITE_16BIT_SUPPORTED */
00468       }
00469    }
00470 }
00471 #endif
00472 
00473 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
00474 void /* PRIVATE */
00475 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
00476 {
00477    png_debug(1, "in png_do_write_invert_alpha");
00478 
00479    {
00480       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00481       {
00482          if (row_info->bit_depth == 8)
00483          {
00484             /* This inverts the alpha channel in RGBA */
00485             png_bytep sp, dp;
00486             png_uint_32 i;
00487             png_uint_32 row_width = row_info->width;
00488 
00489             for (i = 0, sp = dp = row; i < row_width; i++)
00490             {
00491                /* Does nothing
00492                *(dp++) = *(sp++);
00493                *(dp++) = *(sp++);
00494                *(dp++) = *(sp++);
00495                */
00496                sp+=3; dp = sp;
00497                *(dp++) = (png_byte)(255 - *(sp++));
00498             }
00499          }
00500 
00501 #ifdef PNG_WRITE_16BIT_SUPPORTED
00502          else
00503          {
00504             /* This inverts the alpha channel in RRGGBBAA */
00505             png_bytep sp, dp;
00506             png_uint_32 i;
00507             png_uint_32 row_width = row_info->width;
00508 
00509             for (i = 0, sp = dp = row; i < row_width; i++)
00510             {
00511                /* Does nothing
00512                *(dp++) = *(sp++);
00513                *(dp++) = *(sp++);
00514                *(dp++) = *(sp++);
00515                *(dp++) = *(sp++);
00516                *(dp++) = *(sp++);
00517                *(dp++) = *(sp++);
00518                */
00519                sp+=6; dp = sp;
00520                *(dp++) = (png_byte)(255 - *(sp++));
00521                *(dp++) = (png_byte)(255 - *(sp++));
00522             }
00523          }
00524 #endif /* PNG_WRITE_16BIT_SUPPORTED */
00525       }
00526 
00527       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00528       {
00529          if (row_info->bit_depth == 8)
00530          {
00531             /* This inverts the alpha channel in GA */
00532             png_bytep sp, dp;
00533             png_uint_32 i;
00534             png_uint_32 row_width = row_info->width;
00535 
00536             for (i = 0, sp = dp = row; i < row_width; i++)
00537             {
00538                *(dp++) = *(sp++);
00539                *(dp++) = (png_byte)(255 - *(sp++));
00540             }
00541          }
00542 
00543 #ifdef PNG_WRITE_16BIT_SUPPORTED
00544          else
00545          {
00546             /* This inverts the alpha channel in GGAA */
00547             png_bytep sp, dp;
00548             png_uint_32 i;
00549             png_uint_32 row_width = row_info->width;
00550 
00551             for (i = 0, sp = dp = row; i < row_width; i++)
00552             {
00553                /* Does nothing
00554                *(dp++) = *(sp++);
00555                *(dp++) = *(sp++);
00556                */
00557                sp+=2; dp = sp;
00558                *(dp++) = (png_byte)(255 - *(sp++));
00559                *(dp++) = (png_byte)(255 - *(sp++));
00560             }
00561          }
00562 #endif /* PNG_WRITE_16BIT_SUPPORTED */
00563       }
00564    }
00565 }
00566 #endif
00567 #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
00568 
00569 #ifdef PNG_MNG_FEATURES_SUPPORTED
00570 /* Undoes intrapixel differencing  */
00571 void /* PRIVATE */
00572 png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
00573 {
00574    png_debug(1, "in png_do_write_intrapixel");
00575 
00576    if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
00577    {
00578       int bytes_per_pixel;
00579       png_uint_32 row_width = row_info->width;
00580       if (row_info->bit_depth == 8)
00581       {
00582          png_bytep rp;
00583          png_uint_32 i;
00584 
00585          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00586             bytes_per_pixel = 3;
00587 
00588          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00589             bytes_per_pixel = 4;
00590 
00591          else
00592             return;
00593 
00594          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
00595          {
00596             *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
00597             *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
00598          }
00599       }
00600 
00601 #ifdef PNG_WRITE_16BIT_SUPPORTED
00602       else if (row_info->bit_depth == 16)
00603       {
00604          png_bytep rp;
00605          png_uint_32 i;
00606 
00607          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
00608             bytes_per_pixel = 6;
00609 
00610          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
00611             bytes_per_pixel = 8;
00612 
00613          else
00614             return;
00615 
00616          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
00617          {
00618             png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
00619             png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
00620             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
00621             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
00622             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
00623             *(rp    ) = (png_byte)((red >> 8) & 0xff);
00624             *(rp + 1) = (png_byte)(red & 0xff);
00625             *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
00626             *(rp + 5) = (png_byte)(blue & 0xff);
00627          }
00628       }
00629 #endif /* PNG_WRITE_16BIT_SUPPORTED */
00630    }
00631 }
00632 #endif /* PNG_MNG_FEATURES_SUPPORTED */
00633 #endif /* PNG_WRITE_SUPPORTED */

Generated on Sun May 27 2012 04:19:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.