Home | History | Annotate | Download | only in libpng-1.2.19
      1 
      2 /* pngrtran.c - transforms the data in a row for PNG readers
      3  *
      4  * Last changed in libpng 1.2.19 August 18, 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  * This file contains functions optionally called by an application
     11  * in order to tell libpng how to handle data when reading a PNG.
     12  * Transformations that are used in both reading and writing are
     13  * in pngtrans.c.
     14  */
     15 
     16 #define PNG_INTERNAL
     17 #include "png.h"
     18 
     19 #if defined(PNG_READ_SUPPORTED)
     20 
     21 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
     22 void PNGAPI
     23 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
     24 {
     25    png_debug(1, "in png_set_crc_action\n");
     26    /* Tell libpng how we react to CRC errors in critical chunks */
     27    if(png_ptr == NULL) return;
     28    switch (crit_action)
     29    {
     30       case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
     31          break;
     32       case PNG_CRC_WARN_USE:                               /* warn/use data */
     33          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     34          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
     35          break;
     36       case PNG_CRC_QUIET_USE:                             /* quiet/use data */
     37          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     38          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
     39                            PNG_FLAG_CRC_CRITICAL_IGNORE;
     40          break;
     41       case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
     42          png_warning(png_ptr, "Can't discard critical data on CRC error.");
     43       case PNG_CRC_ERROR_QUIT:                                /* error/quit */
     44       case PNG_CRC_DEFAULT:
     45       default:
     46          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     47          break;
     48    }
     49 
     50    switch (ancil_action)
     51    {
     52       case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
     53          break;
     54       case PNG_CRC_WARN_USE:                              /* warn/use data */
     55          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     56          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
     57          break;
     58       case PNG_CRC_QUIET_USE:                            /* quiet/use data */
     59          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     60          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
     61                            PNG_FLAG_CRC_ANCILLARY_NOWARN;
     62          break;
     63       case PNG_CRC_ERROR_QUIT:                               /* error/quit */
     64          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     65          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
     66          break;
     67       case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
     68       case PNG_CRC_DEFAULT:
     69       default:
     70          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     71          break;
     72    }
     73 }
     74 
     75 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
     76     defined(PNG_FLOATING_POINT_SUPPORTED)
     77 /* handle alpha and tRNS via a background color */
     78 void PNGAPI
     79 png_set_background(png_structp png_ptr,
     80    png_color_16p background_color, int background_gamma_code,
     81    int need_expand, double background_gamma)
     82 {
     83    png_debug(1, "in png_set_background\n");
     84    if(png_ptr == NULL) return;
     85    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
     86    {
     87       png_warning(png_ptr, "Application must supply a known background gamma");
     88       return;
     89    }
     90 
     91    png_ptr->transformations |= PNG_BACKGROUND;
     92    png_memcpy(&(png_ptr->background), background_color,
     93       png_sizeof(png_color_16));
     94    png_ptr->background_gamma = (float)background_gamma;
     95    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
     96    png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
     97 }
     98 #endif
     99 
    100 #if defined(PNG_READ_16_TO_8_SUPPORTED)
    101 /* strip 16 bit depth files to 8 bit depth */
    102 void PNGAPI
    103 png_set_strip_16(png_structp png_ptr)
    104 {
    105    png_debug(1, "in png_set_strip_16\n");
    106    if(png_ptr == NULL) return;
    107    png_ptr->transformations |= PNG_16_TO_8;
    108 }
    109 #endif
    110 
    111 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
    112 void PNGAPI
    113 png_set_strip_alpha(png_structp png_ptr)
    114 {
    115    png_debug(1, "in png_set_strip_alpha\n");
    116    if(png_ptr == NULL) return;
    117    png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
    118 }
    119 #endif
    120 
    121 #if defined(PNG_READ_DITHER_SUPPORTED)
    122 /* Dither file to 8 bit.  Supply a palette, the current number
    123  * of elements in the palette, the maximum number of elements
    124  * allowed, and a histogram if possible.  If the current number
    125  * of colors is greater then the maximum number, the palette will be
    126  * modified to fit in the maximum number.  "full_dither" indicates
    127  * whether we need a dithering cube set up for RGB images, or if we
    128  * simply are reducing the number of colors in a paletted image.
    129  */
    130 
    131 typedef struct png_dsort_struct
    132 {
    133    struct png_dsort_struct FAR * next;
    134    png_byte left;
    135    png_byte right;
    136 } png_dsort;
    137 typedef png_dsort FAR *       png_dsortp;
    138 typedef png_dsort FAR * FAR * png_dsortpp;
    139 
    140 void PNGAPI
    141 png_set_dither(png_structp png_ptr, png_colorp palette,
    142    int num_palette, int maximum_colors, png_uint_16p histogram,
    143    int full_dither)
    144 {
    145    png_debug(1, "in png_set_dither\n");
    146    if(png_ptr == NULL) return;
    147    png_ptr->transformations |= PNG_DITHER;
    148 
    149    if (!full_dither)
    150    {
    151       int i;
    152 
    153       png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
    154          (png_uint_32)(num_palette * png_sizeof (png_byte)));
    155       for (i = 0; i < num_palette; i++)
    156          png_ptr->dither_index[i] = (png_byte)i;
    157    }
    158 
    159    if (num_palette > maximum_colors)
    160    {
    161       if (histogram != NULL)
    162       {
    163          /* This is easy enough, just throw out the least used colors.
    164             Perhaps not the best solution, but good enough. */
    165 
    166          int i;
    167 
    168          /* initialize an array to sort colors */
    169          png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
    170             (png_uint_32)(num_palette * png_sizeof (png_byte)));
    171 
    172          /* initialize the dither_sort array */
    173          for (i = 0; i < num_palette; i++)
    174             png_ptr->dither_sort[i] = (png_byte)i;
    175 
    176          /* Find the least used palette entries by starting a
    177             bubble sort, and running it until we have sorted
    178             out enough colors.  Note that we don't care about
    179             sorting all the colors, just finding which are
    180             least used. */
    181 
    182          for (i = num_palette - 1; i >= maximum_colors; i--)
    183          {
    184             int done; /* to stop early if the list is pre-sorted */
    185             int j;
    186 
    187             done = 1;
    188             for (j = 0; j < i; j++)
    189             {
    190                if (histogram[png_ptr->dither_sort[j]]
    191                    < histogram[png_ptr->dither_sort[j + 1]])
    192                {
    193                   png_byte t;
    194 
    195                   t = png_ptr->dither_sort[j];
    196                   png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
    197                   png_ptr->dither_sort[j + 1] = t;
    198                   done = 0;
    199                }
    200             }
    201             if (done)
    202                break;
    203          }
    204 
    205          /* swap the palette around, and set up a table, if necessary */
    206          if (full_dither)
    207          {
    208             int j = num_palette;
    209 
    210             /* put all the useful colors within the max, but don't
    211                move the others */
    212             for (i = 0; i < maximum_colors; i++)
    213             {
    214                if ((int)png_ptr->dither_sort[i] >= maximum_colors)
    215                {
    216                   do
    217                      j--;
    218                   while ((int)png_ptr->dither_sort[j] >= maximum_colors);
    219                   palette[i] = palette[j];
    220                }
    221             }
    222          }
    223          else
    224          {
    225             int j = num_palette;
    226 
    227             /* move all the used colors inside the max limit, and
    228                develop a translation table */
    229             for (i = 0; i < maximum_colors; i++)
    230             {
    231                /* only move the colors we need to */
    232                if ((int)png_ptr->dither_sort[i] >= maximum_colors)
    233                {
    234                   png_color tmp_color;
    235 
    236                   do
    237                      j--;
    238                   while ((int)png_ptr->dither_sort[j] >= maximum_colors);
    239 
    240                   tmp_color = palette[j];
    241                   palette[j] = palette[i];
    242                   palette[i] = tmp_color;
    243                   /* indicate where the color went */
    244                   png_ptr->dither_index[j] = (png_byte)i;
    245                   png_ptr->dither_index[i] = (png_byte)j;
    246                }
    247             }
    248 
    249             /* find closest color for those colors we are not using */
    250             for (i = 0; i < num_palette; i++)
    251             {
    252                if ((int)png_ptr->dither_index[i] >= maximum_colors)
    253                {
    254                   int min_d, k, min_k, d_index;
    255 
    256                   /* find the closest color to one we threw out */
    257                   d_index = png_ptr->dither_index[i];
    258                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
    259                   for (k = 1, min_k = 0; k < maximum_colors; k++)
    260                   {
    261                      int d;
    262 
    263                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);
    264 
    265                      if (d < min_d)
    266                      {
    267                         min_d = d;
    268                         min_k = k;
    269                      }
    270                   }
    271                   /* point to closest color */
    272                   png_ptr->dither_index[i] = (png_byte)min_k;
    273                }
    274             }
    275          }
    276          png_free(png_ptr, png_ptr->dither_sort);
    277          png_ptr->dither_sort=NULL;
    278       }
    279       else
    280       {
    281          /* This is much harder to do simply (and quickly).  Perhaps
    282             we need to go through a median cut routine, but those
    283             don't always behave themselves with only a few colors
    284             as input.  So we will just find the closest two colors,
    285             and throw out one of them (chosen somewhat randomly).
    286             [We don't understand this at all, so if someone wants to
    287              work on improving it, be our guest - AED, GRP]
    288             */
    289          int i;
    290          int max_d;
    291          int num_new_palette;
    292          png_dsortp t;
    293          png_dsortpp hash;
    294 
    295          t=NULL;
    296 
    297          /* initialize palette index arrays */
    298          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
    299             (png_uint_32)(num_palette * png_sizeof (png_byte)));
    300          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
    301             (png_uint_32)(num_palette * png_sizeof (png_byte)));
    302 
    303          /* initialize the sort array */
    304          for (i = 0; i < num_palette; i++)
    305          {
    306             png_ptr->index_to_palette[i] = (png_byte)i;
    307             png_ptr->palette_to_index[i] = (png_byte)i;
    308          }
    309 
    310          hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
    311             png_sizeof (png_dsortp)));
    312          for (i = 0; i < 769; i++)
    313             hash[i] = NULL;
    314 /*         png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
    315 
    316          num_new_palette = num_palette;
    317 
    318          /* initial wild guess at how far apart the farthest pixel
    319             pair we will be eliminating will be.  Larger
    320             numbers mean more areas will be allocated, Smaller
    321             numbers run the risk of not saving enough data, and
    322             having to do this all over again.
    323 
    324             I have not done extensive checking on this number.
    325             */
    326          max_d = 96;
    327 
    328          while (num_new_palette > maximum_colors)
    329          {
    330             for (i = 0; i < num_new_palette - 1; i++)
    331             {
    332                int j;
    333 
    334                for (j = i + 1; j < num_new_palette; j++)
    335                {
    336                   int d;
    337 
    338                   d = PNG_COLOR_DIST(palette[i], palette[j]);
    339 
    340                   if (d <= max_d)
    341                   {
    342 
    343                      t = (png_dsortp)png_malloc_warn(png_ptr,
    344                          (png_uint_32)(png_sizeof(png_dsort)));
    345                      if (t == NULL)
    346                          break;
    347                      t->next = hash[d];
    348                      t->left = (png_byte)i;
    349                      t->right = (png_byte)j;
    350                      hash[d] = t;
    351                   }
    352                }
    353                if (t == NULL)
    354                   break;
    355             }
    356 
    357             if (t != NULL)
    358             for (i = 0; i <= max_d; i++)
    359             {
    360                if (hash[i] != NULL)
    361                {
    362                   png_dsortp p;
    363 
    364                   for (p = hash[i]; p; p = p->next)
    365                   {
    366                      if ((int)png_ptr->index_to_palette[p->left]
    367                         < num_new_palette &&
    368                         (int)png_ptr->index_to_palette[p->right]
    369                         < num_new_palette)
    370                      {
    371                         int j, next_j;
    372 
    373                         if (num_new_palette & 0x01)
    374                         {
    375                            j = p->left;
    376                            next_j = p->right;
    377                         }
    378                         else
    379                         {
    380                            j = p->right;
    381                            next_j = p->left;
    382                         }
    383 
    384                         num_new_palette--;
    385                         palette[png_ptr->index_to_palette[j]]
    386                           = palette[num_new_palette];
    387                         if (!full_dither)
    388                         {
    389                            int k;
    390 
    391                            for (k = 0; k < num_palette; k++)
    392                            {
    393                               if (png_ptr->dither_index[k] ==
    394                                  png_ptr->index_to_palette[j])
    395                                  png_ptr->dither_index[k] =
    396                                     png_ptr->index_to_palette[next_j];
    397                               if ((int)png_ptr->dither_index[k] ==
    398                                  num_new_palette)
    399                                  png_ptr->dither_index[k] =
    400                                     png_ptr->index_to_palette[j];
    401                            }
    402                         }
    403 
    404                         png_ptr->index_to_palette[png_ptr->palette_to_index
    405                            [num_new_palette]] = png_ptr->index_to_palette[j];
    406                         png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
    407                            = png_ptr->palette_to_index[num_new_palette];
    408 
    409                         png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
    410                         png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
    411                      }
    412                      if (num_new_palette <= maximum_colors)
    413                         break;
    414                   }
    415                   if (num_new_palette <= maximum_colors)
    416                      break;
    417                }
    418             }
    419 
    420             for (i = 0; i < 769; i++)
    421             {
    422                if (hash[i] != NULL)
    423                {
    424                   png_dsortp p = hash[i];
    425                   while (p)
    426                   {
    427                      t = p->next;
    428                      png_free(png_ptr, p);
    429                      p = t;
    430                   }
    431                }
    432                hash[i] = 0;
    433             }
    434             max_d += 96;
    435          }
    436          png_free(png_ptr, hash);
    437          png_free(png_ptr, png_ptr->palette_to_index);
    438          png_free(png_ptr, png_ptr->index_to_palette);
    439          png_ptr->palette_to_index=NULL;
    440          png_ptr->index_to_palette=NULL;
    441       }
    442       num_palette = maximum_colors;
    443    }
    444    if (png_ptr->palette == NULL)
    445    {
    446       png_ptr->palette = palette;
    447    }
    448    png_ptr->num_palette = (png_uint_16)num_palette;
    449 
    450    if (full_dither)
    451    {
    452       int i;
    453       png_bytep distance;
    454       int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
    455          PNG_DITHER_BLUE_BITS;
    456       int num_red = (1 << PNG_DITHER_RED_BITS);
    457       int num_green = (1 << PNG_DITHER_GREEN_BITS);
    458       int num_blue = (1 << PNG_DITHER_BLUE_BITS);
    459       png_size_t num_entries = ((png_size_t)1 << total_bits);
    460 
    461       png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
    462          (png_uint_32)(num_entries * png_sizeof (png_byte)));
    463 
    464       png_memset(png_ptr->palette_lookup, 0, num_entries *
    465          png_sizeof (png_byte));
    466 
    467       distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
    468          png_sizeof(png_byte)));
    469 
    470       png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
    471 
    472       for (i = 0; i < num_palette; i++)
    473       {
    474          int ir, ig, ib;
    475          int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
    476          int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
    477          int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
    478 
    479          for (ir = 0; ir < num_red; ir++)
    480          {
    481             /* int dr = abs(ir - r); */
    482             int dr = ((ir > r) ? ir - r : r - ir);
    483             int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
    484 
    485             for (ig = 0; ig < num_green; ig++)
    486             {
    487                /* int dg = abs(ig - g); */
    488                int dg = ((ig > g) ? ig - g : g - ig);
    489                int dt = dr + dg;
    490                int dm = ((dr > dg) ? dr : dg);
    491                int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
    492 
    493                for (ib = 0; ib < num_blue; ib++)
    494                {
    495                   int d_index = index_g | ib;
    496                   /* int db = abs(ib - b); */
    497                   int db = ((ib > b) ? ib - b : b - ib);
    498                   int dmax = ((dm > db) ? dm : db);
    499                   int d = dmax + dt + db;
    500 
    501                   if (d < (int)distance[d_index])
    502                   {
    503                      distance[d_index] = (png_byte)d;
    504                      png_ptr->palette_lookup[d_index] = (png_byte)i;
    505                   }
    506                }
    507             }
    508          }
    509       }
    510 
    511       png_free(png_ptr, distance);
    512    }
    513 }
    514 #endif
    515 
    516 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
    517 /* Transform the image from the file_gamma to the screen_gamma.  We
    518  * only do transformations on images where the file_gamma and screen_gamma
    519  * are not close reciprocals, otherwise it slows things down slightly, and
    520  * also needlessly introduces small errors.
    521  *
    522  * We will turn off gamma transformation later if no semitransparent entries
    523  * are present in the tRNS array for palette images.  We can't do it here
    524  * because we don't necessarily have the tRNS chunk yet.
    525  */
    526 void PNGAPI
    527 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
    528 {
    529    png_debug(1, "in png_set_gamma\n");
    530    if(png_ptr == NULL) return;
    531    if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
    532        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
    533        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
    534      png_ptr->transformations |= PNG_GAMMA;
    535    png_ptr->gamma = (float)file_gamma;
    536    png_ptr->screen_gamma = (float)scrn_gamma;
    537 }
    538 #endif
    539 
    540 #if defined(PNG_READ_EXPAND_SUPPORTED)
    541 /* Expand paletted images to RGB, expand grayscale images of
    542  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
    543  * to alpha channels.
    544  */
    545 void PNGAPI
    546 png_set_expand(png_structp png_ptr)
    547 {
    548    png_debug(1, "in png_set_expand\n");
    549    if(png_ptr == NULL) return;
    550    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    551 #ifdef PNG_WARN_UNINITIALIZED_ROW
    552    png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
    553 #endif
    554 }
    555 
    556 /* GRR 19990627:  the following three functions currently are identical
    557  *  to png_set_expand().  However, it is entirely reasonable that someone
    558  *  might wish to expand an indexed image to RGB but *not* expand a single,
    559  *  fully transparent palette entry to a full alpha channel--perhaps instead
    560  *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
    561  *  the transparent color with a particular RGB value, or drop tRNS entirely.
    562  *  IOW, a future version of the library may make the transformations flag
    563  *  a bit more fine-grained, with separate bits for each of these three
    564  *  functions.
    565  *
    566  *  More to the point, these functions make it obvious what libpng will be
    567  *  doing, whereas "expand" can (and does) mean any number of things.
    568  *
    569  *  GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
    570  *  to expand only the sample depth but not to expand the tRNS to alpha.
    571  */
    572 
    573 /* Expand paletted images to RGB. */
    574 void PNGAPI
    575 png_set_palette_to_rgb(png_structp png_ptr)
    576 {
    577    png_debug(1, "in png_set_palette_to_rgb\n");
    578    if(png_ptr == NULL) return;
    579    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    580 #ifdef PNG_WARN_UNINITIALIZED_ROW
    581    png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
    582 #endif
    583 }
    584 
    585 #if !defined(PNG_1_0_X)
    586 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
    587 void PNGAPI
    588 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
    589 {
    590    png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
    591    if(png_ptr == NULL) return;
    592    png_ptr->transformations |= PNG_EXPAND;
    593 #ifdef PNG_WARN_UNINITIALIZED_ROW
    594    png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
    595 #endif
    596 }
    597 #endif
    598 
    599 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
    600 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
    601 /* Deprecated as of libpng-1.2.9 */
    602 void PNGAPI
    603 png_set_gray_1_2_4_to_8(png_structp png_ptr)
    604 {
    605    png_debug(1, "in png_set_gray_1_2_4_to_8\n");
    606    if(png_ptr == NULL) return;
    607    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    608 }
    609 #endif
    610 
    611 
    612 /* Expand tRNS chunks to alpha channels. */
    613 void PNGAPI
    614 png_set_tRNS_to_alpha(png_structp png_ptr)
    615 {
    616    png_debug(1, "in png_set_tRNS_to_alpha\n");
    617    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    618 #ifdef PNG_WARN_UNINITIALIZED_ROW
    619    png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
    620 #endif
    621 }
    622 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
    623 
    624 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
    625 void PNGAPI
    626 png_set_gray_to_rgb(png_structp png_ptr)
    627 {
    628    png_debug(1, "in png_set_gray_to_rgb\n");
    629    png_ptr->transformations |= PNG_GRAY_TO_RGB;
    630 #ifdef PNG_WARN_UNINITIALIZED_ROW
    631    png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
    632 #endif
    633 }
    634 #endif
    635 
    636 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    637 #if defined(PNG_FLOATING_POINT_SUPPORTED)
    638 /* Convert a RGB image to a grayscale of the same width.  This allows us,
    639  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
    640  */
    641 
    642 void PNGAPI
    643 png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
    644    double green)
    645 {
    646       int red_fixed = (int)((float)red*100000.0 + 0.5);
    647       int green_fixed = (int)((float)green*100000.0 + 0.5);
    648       if(png_ptr == NULL) return;
    649       png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
    650 }
    651 #endif
    652 
    653 void PNGAPI
    654 png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
    655    png_fixed_point red, png_fixed_point green)
    656 {
    657    png_debug(1, "in png_set_rgb_to_gray\n");
    658    if(png_ptr == NULL) return;
    659    switch(error_action)
    660    {
    661       case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
    662               break;
    663       case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
    664               break;
    665       case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
    666    }
    667    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    668 #if defined(PNG_READ_EXPAND_SUPPORTED)
    669       png_ptr->transformations |= PNG_EXPAND;
    670 #else
    671    {
    672       png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
    673       png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
    674    }
    675 #endif
    676    {
    677       png_uint_16 red_int, green_int;
    678       if(red < 0 || green < 0)
    679       {
    680          red_int   =  6968; /* .212671 * 32768 + .5 */
    681          green_int = 23434; /* .715160 * 32768 + .5 */
    682       }
    683       else if(red + green < 100000L)
    684       {
    685         red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
    686         green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
    687       }
    688       else
    689       {
    690          png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
    691          red_int   =  6968;
    692          green_int = 23434;
    693       }
    694       png_ptr->rgb_to_gray_red_coeff   = red_int;
    695       png_ptr->rgb_to_gray_green_coeff = green_int;
    696       png_ptr->rgb_to_gray_blue_coeff  = (png_uint_16)(32768-red_int-green_int);
    697    }
    698 }
    699 #endif
    700 
    701 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
    702     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
    703     defined(PNG_LEGACY_SUPPORTED)
    704 void PNGAPI
    705 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
    706    read_user_transform_fn)
    707 {
    708    png_debug(1, "in png_set_read_user_transform_fn\n");
    709    if(png_ptr == NULL) return;
    710 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    711    png_ptr->transformations |= PNG_USER_TRANSFORM;
    712    png_ptr->read_user_transform_fn = read_user_transform_fn;
    713 #endif
    714 #ifdef PNG_LEGACY_SUPPORTED
    715    if(read_user_transform_fn)
    716       png_warning(png_ptr,
    717         "This version of libpng does not support user transforms");
    718 #endif
    719 }
    720 #endif
    721 
    722 /* Initialize everything needed for the read.  This includes modifying
    723  * the palette.
    724  */
    725 void /* PRIVATE */
    726 png_init_read_transformations(png_structp png_ptr)
    727 {
    728    png_debug(1, "in png_init_read_transformations\n");
    729 #if defined(PNG_USELESS_TESTS_SUPPORTED)
    730    if(png_ptr != NULL)
    731 #endif
    732   {
    733 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
    734  || defined(PNG_READ_GAMMA_SUPPORTED)
    735    int color_type = png_ptr->color_type;
    736 #endif
    737 
    738 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
    739 
    740 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
    741    /* Detect gray background and attempt to enable optimization
    742     * for gray --> RGB case */
    743    /* Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
    744     * RGB_ALPHA (in which case need_expand is superfluous anyway), the
    745     * background color might actually be gray yet not be flagged as such.
    746     * This is not a problem for the current code, which uses
    747     * PNG_BACKGROUND_IS_GRAY only to decide when to do the
    748     * png_do_gray_to_rgb() transformation.
    749     */
    750    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
    751        !(color_type & PNG_COLOR_MASK_COLOR))
    752    {
    753           png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
    754    } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
    755               !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
    756               (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
    757               png_ptr->background.red == png_ptr->background.green &&
    758               png_ptr->background.red == png_ptr->background.blue)
    759    {
    760           png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
    761           png_ptr->background.gray = png_ptr->background.red;
    762    }
    763 #endif
    764 
    765    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
    766        (png_ptr->transformations & PNG_EXPAND))
    767    {
    768       if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
    769       {
    770          /* expand background and tRNS chunks */
    771          switch (png_ptr->bit_depth)
    772          {
    773             case 1:
    774                png_ptr->background.gray *= (png_uint_16)0xff;
    775                png_ptr->background.red = png_ptr->background.green
    776                  =  png_ptr->background.blue = png_ptr->background.gray;
    777                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
    778                {
    779                  png_ptr->trans_values.gray *= (png_uint_16)0xff;
    780                  png_ptr->trans_values.red = png_ptr->trans_values.green
    781                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
    782                }
    783                break;
    784             case 2:
    785                png_ptr->background.gray *= (png_uint_16)0x55;
    786                png_ptr->background.red = png_ptr->background.green
    787                  = png_ptr->background.blue = png_ptr->background.gray;
    788                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
    789                {
    790                  png_ptr->trans_values.gray *= (png_uint_16)0x55;
    791                  png_ptr->trans_values.red = png_ptr->trans_values.green
    792                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
    793                }
    794                break;
    795             case 4:
    796                png_ptr->background.gray *= (png_uint_16)0x11;
    797                png_ptr->background.red = png_ptr->background.green
    798                  = png_ptr->background.blue = png_ptr->background.gray;
    799                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
    800                {
    801                  png_ptr->trans_values.gray *= (png_uint_16)0x11;
    802                  png_ptr->trans_values.red = png_ptr->trans_values.green
    803                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
    804                }
    805                break;
    806             case 8:
    807             case 16:
    808                png_ptr->background.red = png_ptr->background.green
    809                  = png_ptr->background.blue = png_ptr->background.gray;
    810                break;
    811          }
    812       }
    813       else if (color_type == PNG_COLOR_TYPE_PALETTE)
    814       {
    815          png_ptr->background.red   =
    816             png_ptr->palette[png_ptr->background.index].red;
    817          png_ptr->background.green =
    818             png_ptr->palette[png_ptr->background.index].green;
    819          png_ptr->background.blue  =
    820             png_ptr->palette[png_ptr->background.index].blue;
    821 
    822 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
    823         if (png_ptr->transformations & PNG_INVERT_ALPHA)
    824         {
    825 #if defined(PNG_READ_EXPAND_SUPPORTED)
    826            if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
    827 #endif
    828            {
    829            /* invert the alpha channel (in tRNS) unless the pixels are
    830               going to be expanded, in which case leave it for later */
    831               int i,istop;
    832               istop=(int)png_ptr->num_trans;
    833               for (i=0; i<istop; i++)
    834                  png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
    835            }
    836         }
    837 #endif
    838 
    839       }
    840    }
    841 #endif
    842 
    843 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
    844    png_ptr->background_1 = png_ptr->background;
    845 #endif
    846 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
    847 
    848    if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
    849        && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
    850          < PNG_GAMMA_THRESHOLD))
    851    {
    852     int i,k;
    853     k=0;
    854     for (i=0; i<png_ptr->num_trans; i++)
    855     {
    856       if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
    857         k=1; /* partial transparency is present */
    858     }
    859     if (k == 0)
    860       png_ptr->transformations &= (~PNG_GAMMA);
    861    }
    862 
    863    if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
    864         png_ptr->gamma != 0.0)
    865    {
    866       png_build_gamma_table(png_ptr);
    867 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
    868       if (png_ptr->transformations & PNG_BACKGROUND)
    869       {
    870          if (color_type == PNG_COLOR_TYPE_PALETTE)
    871          {
    872            /* could skip if no transparency and
    873            */
    874             png_color back, back_1;
    875             png_colorp palette = png_ptr->palette;
    876             int num_palette = png_ptr->num_palette;
    877             int i;
    878             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
    879             {
    880                back.red = png_ptr->gamma_table[png_ptr->background.red];
    881                back.green = png_ptr->gamma_table[png_ptr->background.green];
    882                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
    883 
    884                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
    885                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
    886                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
    887             }
    888             else
    889             {
    890                double g, gs;
    891 
    892                switch (png_ptr->background_gamma_type)
    893                {
    894                   case PNG_BACKGROUND_GAMMA_SCREEN:
    895                      g = (png_ptr->screen_gamma);
    896                      gs = 1.0;
    897                      break;
    898                   case PNG_BACKGROUND_GAMMA_FILE:
    899                      g = 1.0 / (png_ptr->gamma);
    900                      gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
    901                      break;
    902                   case PNG_BACKGROUND_GAMMA_UNIQUE:
    903                      g = 1.0 / (png_ptr->background_gamma);
    904                      gs = 1.0 / (png_ptr->background_gamma *
    905                                  png_ptr->screen_gamma);
    906                      break;
    907                   default:
    908                      g = 1.0;    /* back_1 */
    909                      gs = 1.0;   /* back */
    910                }
    911 
    912                if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
    913                {
    914                   back.red   = (png_byte)png_ptr->background.red;
    915                   back.green = (png_byte)png_ptr->background.green;
    916                   back.blue  = (png_byte)png_ptr->background.blue;
    917                }
    918                else
    919                {
    920                   back.red = (png_byte)(pow(
    921                      (double)png_ptr->background.red/255, gs) * 255.0 + .5);
    922                   back.green = (png_byte)(pow(
    923                      (double)png_ptr->background.green/255, gs) * 255.0 + .5);
    924                   back.blue = (png_byte)(pow(
    925                      (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
    926                }
    927 
    928                back_1.red = (png_byte)(pow(
    929                   (double)png_ptr->background.red/255, g) * 255.0 + .5);
    930                back_1.green = (png_byte)(pow(
    931                   (double)png_ptr->background.green/255, g) * 255.0 + .5);
    932                back_1.blue = (png_byte)(pow(
    933                   (double)png_ptr->background.blue/255, g) * 255.0 + .5);
    934             }
    935             for (i = 0; i < num_palette; i++)
    936             {
    937                if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
    938                {
    939                   if (png_ptr->trans[i] == 0)
    940                   {
    941                      palette[i] = back;
    942                   }
    943                   else /* if (png_ptr->trans[i] != 0xff) */
    944                   {
    945                      png_byte v, w;
    946 
    947                      v = png_ptr->gamma_to_1[palette[i].red];
    948                      png_composite(w, v, png_ptr->trans[i], back_1.red);
    949                      palette[i].red = png_ptr->gamma_from_1[w];
    950 
    951                      v = png_ptr->gamma_to_1[palette[i].green];
    952                      png_composite(w, v, png_ptr->trans[i], back_1.green);
    953                      palette[i].green = png_ptr->gamma_from_1[w];
    954 
    955                      v = png_ptr->gamma_to_1[palette[i].blue];
    956                      png_composite(w, v, png_ptr->trans[i], back_1.blue);
    957                      palette[i].blue = png_ptr->gamma_from_1[w];
    958                   }
    959                }
    960                else
    961                {
    962                   palette[i].red = png_ptr->gamma_table[palette[i].red];
    963                   palette[i].green = png_ptr->gamma_table[palette[i].green];
    964                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
    965                }
    966             }
    967          }
    968          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
    969          else
    970          /* color_type != PNG_COLOR_TYPE_PALETTE */
    971          {
    972             double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
    973             double g = 1.0;
    974             double gs = 1.0;
    975 
    976             switch (png_ptr->background_gamma_type)
    977             {
    978                case PNG_BACKGROUND_GAMMA_SCREEN:
    979                   g = (png_ptr->screen_gamma);
    980                   gs = 1.0;
    981                   break;
    982                case PNG_BACKGROUND_GAMMA_FILE:
    983                   g = 1.0 / (png_ptr->gamma);
    984                   gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
    985                   break;
    986                case PNG_BACKGROUND_GAMMA_UNIQUE:
    987                   g = 1.0 / (png_ptr->background_gamma);
    988                   gs = 1.0 / (png_ptr->background_gamma *
    989                      png_ptr->screen_gamma);
    990                   break;
    991             }
    992 
    993             png_ptr->background_1.gray = (png_uint_16)(pow(
    994                (double)png_ptr->background.gray / m, g) * m + .5);
    995             png_ptr->background.gray = (png_uint_16)(pow(
    996                (double)png_ptr->background.gray / m, gs) * m + .5);
    997 
    998             if ((png_ptr->background.red != png_ptr->background.green) ||
    999                 (png_ptr->background.red != png_ptr->background.blue) ||
   1000                 (png_ptr->background.red != png_ptr->background.gray))
   1001             {
   1002                /* RGB or RGBA with color background */
   1003                png_ptr->background_1.red = (png_uint_16)(pow(
   1004                   (double)png_ptr->background.red / m, g) * m + .5);
   1005                png_ptr->background_1.green = (png_uint_16)(pow(
   1006                   (double)png_ptr->background.green / m, g) * m + .5);
   1007                png_ptr->background_1.blue = (png_uint_16)(pow(
   1008                   (double)png_ptr->background.blue / m, g) * m + .5);
   1009                png_ptr->background.red = (png_uint_16)(pow(
   1010                   (double)png_ptr->background.red / m, gs) * m + .5);
   1011                png_ptr->background.green = (png_uint_16)(pow(
   1012                   (double)png_ptr->background.green / m, gs) * m + .5);
   1013                png_ptr->background.blue = (png_uint_16)(pow(
   1014                   (double)png_ptr->background.blue / m, gs) * m + .5);
   1015             }
   1016             else
   1017             {
   1018                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
   1019                png_ptr->background_1.red = png_ptr->background_1.green
   1020                  = png_ptr->background_1.blue = png_ptr->background_1.gray;
   1021                png_ptr->background.red = png_ptr->background.green
   1022                  = png_ptr->background.blue = png_ptr->background.gray;
   1023             }
   1024          }
   1025       }
   1026       else
   1027       /* transformation does not include PNG_BACKGROUND */
   1028 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
   1029       if (color_type == PNG_COLOR_TYPE_PALETTE)
   1030       {
   1031          png_colorp palette = png_ptr->palette;
   1032          int num_palette = png_ptr->num_palette;
   1033          int i;
   1034 
   1035          for (i = 0; i < num_palette; i++)
   1036          {
   1037             palette[i].red = png_ptr->gamma_table[palette[i].red];
   1038             palette[i].green = png_ptr->gamma_table[palette[i].green];
   1039             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   1040          }
   1041       }
   1042    }
   1043 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   1044    else
   1045 #endif
   1046 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
   1047 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   1048    /* No GAMMA transformation */
   1049    if ((png_ptr->transformations & PNG_BACKGROUND) &&
   1050        (color_type == PNG_COLOR_TYPE_PALETTE))
   1051    {
   1052       int i;
   1053       int istop = (int)png_ptr->num_trans;
   1054       png_color back;
   1055       png_colorp palette = png_ptr->palette;
   1056 
   1057       back.red   = (png_byte)png_ptr->background.red;
   1058       back.green = (png_byte)png_ptr->background.green;
   1059       back.blue  = (png_byte)png_ptr->background.blue;
   1060 
   1061       for (i = 0; i < istop; i++)
   1062       {
   1063          if (png_ptr->trans[i] == 0)
   1064          {
   1065             palette[i] = back;
   1066          }
   1067          else if (png_ptr->trans[i] != 0xff)
   1068          {
   1069             /* The png_composite() macro is defined in png.h */
   1070             png_composite(palette[i].red, palette[i].red,
   1071                png_ptr->trans[i], back.red);
   1072             png_composite(palette[i].green, palette[i].green,
   1073                png_ptr->trans[i], back.green);
   1074             png_composite(palette[i].blue, palette[i].blue,
   1075                png_ptr->trans[i], back.blue);
   1076          }
   1077       }
   1078    }
   1079 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
   1080 
   1081 #if defined(PNG_READ_SHIFT_SUPPORTED)
   1082    if ((png_ptr->transformations & PNG_SHIFT) &&
   1083       (color_type == PNG_COLOR_TYPE_PALETTE))
   1084    {
   1085       png_uint_16 i;
   1086       png_uint_16 istop = png_ptr->num_palette;
   1087       int sr = 8 - png_ptr->sig_bit.red;
   1088       int sg = 8 - png_ptr->sig_bit.green;
   1089       int sb = 8 - png_ptr->sig_bit.blue;
   1090 
   1091       if (sr < 0 || sr > 8)
   1092          sr = 0;
   1093       if (sg < 0 || sg > 8)
   1094          sg = 0;
   1095       if (sb < 0 || sb > 8)
   1096          sb = 0;
   1097       for (i = 0; i < istop; i++)
   1098       {
   1099          png_ptr->palette[i].red >>= sr;
   1100          png_ptr->palette[i].green >>= sg;
   1101          png_ptr->palette[i].blue >>= sb;
   1102       }
   1103    }
   1104 #endif  /* PNG_READ_SHIFT_SUPPORTED */
   1105  }
   1106 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
   1107  && !defined(PNG_READ_BACKGROUND_SUPPORTED)
   1108    if(png_ptr)
   1109       return;
   1110 #endif
   1111 }
   1112 
   1113 /* Modify the info structure to reflect the transformations.  The
   1114  * info should be updated so a PNG file could be written with it,
   1115  * assuming the transformations result in valid PNG data.
   1116  */
   1117 void /* PRIVATE */
   1118 png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
   1119 {
   1120    png_debug(1, "in png_read_transform_info\n");
   1121 #if defined(PNG_READ_EXPAND_SUPPORTED)
   1122    if (png_ptr->transformations & PNG_EXPAND)
   1123    {
   1124       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1125       {
   1126          if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
   1127             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   1128          else
   1129             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
   1130          info_ptr->bit_depth = 8;
   1131          info_ptr->num_trans = 0;
   1132       }
   1133       else
   1134       {
   1135          if (png_ptr->num_trans)
   1136          {
   1137             if (png_ptr->transformations & PNG_EXPAND_tRNS)
   1138               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   1139             else
   1140               info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
   1141          }
   1142          if (info_ptr->bit_depth < 8)
   1143             info_ptr->bit_depth = 8;
   1144          info_ptr->num_trans = 0;
   1145       }
   1146    }
   1147 #endif
   1148 
   1149 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   1150    if (png_ptr->transformations & PNG_BACKGROUND)
   1151    {
   1152       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
   1153       info_ptr->num_trans = 0;
   1154       info_ptr->background = png_ptr->background;
   1155    }
   1156 #endif
   1157 
   1158 #if defined(PNG_READ_GAMMA_SUPPORTED)
   1159    if (png_ptr->transformations & PNG_GAMMA)
   1160    {
   1161 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1162       info_ptr->gamma = png_ptr->gamma;
   1163 #endif
   1164 #ifdef PNG_FIXED_POINT_SUPPORTED
   1165       info_ptr->int_gamma = png_ptr->int_gamma;
   1166 #endif
   1167    }
   1168 #endif
   1169 
   1170 #if defined(PNG_READ_16_TO_8_SUPPORTED)
   1171    if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
   1172       info_ptr->bit_depth = 8;
   1173 #endif
   1174 
   1175 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   1176    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   1177       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
   1178 #endif
   1179 
   1180 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   1181    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
   1182       info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
   1183 #endif
   1184 
   1185 #if defined(PNG_READ_DITHER_SUPPORTED)
   1186    if (png_ptr->transformations & PNG_DITHER)
   1187    {
   1188       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
   1189          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
   1190          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
   1191       {
   1192          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
   1193       }
   1194    }
   1195 #endif
   1196 
   1197 #if defined(PNG_READ_PACK_SUPPORTED)
   1198    if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
   1199       info_ptr->bit_depth = 8;
   1200 #endif
   1201 
   1202    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1203       info_ptr->channels = 1;
   1204    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
   1205       info_ptr->channels = 3;
   1206    else
   1207       info_ptr->channels = 1;
   1208 
   1209 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
   1210    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
   1211       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
   1212 #endif
   1213 
   1214    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
   1215       info_ptr->channels++;
   1216 
   1217 #if defined(PNG_READ_FILLER_SUPPORTED)
   1218    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
   1219    if ((png_ptr->transformations & PNG_FILLER) &&
   1220        ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
   1221        (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
   1222    {
   1223       info_ptr->channels++;
   1224       /* if adding a true alpha channel not just filler */
   1225 #if !defined(PNG_1_0_X)
   1226       if (png_ptr->transformations & PNG_ADD_ALPHA)
   1227         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   1228 #endif
   1229    }
   1230 #endif
   1231 
   1232 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
   1233 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   1234    if(png_ptr->transformations & PNG_USER_TRANSFORM)
   1235      {
   1236        if(info_ptr->bit_depth < png_ptr->user_transform_depth)
   1237          info_ptr->bit_depth = png_ptr->user_transform_depth;
   1238        if(info_ptr->channels < png_ptr->user_transform_channels)
   1239          info_ptr->channels = png_ptr->user_transform_channels;
   1240      }
   1241 #endif
   1242 
   1243    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
   1244       info_ptr->bit_depth);
   1245 
   1246    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
   1247 
   1248 #if !defined(PNG_READ_EXPAND_SUPPORTED)
   1249    if(png_ptr)
   1250       return;
   1251 #endif
   1252 }
   1253 
   1254 /* Transform the row.  The order of transformations is significant,
   1255  * and is very touchy.  If you add a transformation, take care to
   1256  * decide how it fits in with the other transformations here.
   1257  */
   1258 void /* PRIVATE */
   1259 png_do_read_transformations(png_structp png_ptr)
   1260 {
   1261    png_debug(1, "in png_do_read_transformations\n");
   1262    if (png_ptr->row_buf == NULL)
   1263    {
   1264 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
   1265       char msg[50];
   1266 
   1267       png_snprintf2(msg, 50,
   1268          "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
   1269          png_ptr->pass);
   1270       png_error(png_ptr, msg);
   1271 #else
   1272       png_error(png_ptr, "NULL row buffer");
   1273 #endif
   1274    }
   1275 #ifdef PNG_WARN_UNINITIALIZED_ROW
   1276    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
   1277       /* Application has failed to call either png_read_start_image()
   1278        * or png_read_update_info() after setting transforms that expand
   1279        * pixels.  This check added to libpng-1.2.19 */
   1280 #if (PNG_WARN_UNINITIALIZED_ROW==1)
   1281       png_error(png_ptr, "Uninitialized row");
   1282 #else
   1283       png_warning(png_ptr, "Uninitialized row");
   1284 #endif
   1285 #endif
   1286 
   1287 #if defined(PNG_READ_EXPAND_SUPPORTED)
   1288    if (png_ptr->transformations & PNG_EXPAND)
   1289    {
   1290       if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
   1291       {
   1292          png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1293             png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
   1294       }
   1295       else
   1296       {
   1297          if (png_ptr->num_trans &&
   1298              (png_ptr->transformations & PNG_EXPAND_tRNS))
   1299             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1300                &(png_ptr->trans_values));
   1301          else
   1302             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1303                NULL);
   1304       }
   1305    }
   1306 #endif
   1307 
   1308 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
   1309    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
   1310       png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1311          PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
   1312 #endif
   1313 
   1314 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   1315    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
   1316    {
   1317       int rgb_error =
   1318          png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
   1319       if(rgb_error)
   1320       {
   1321          png_ptr->rgb_to_gray_status=1;
   1322          if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   1323              PNG_RGB_TO_GRAY_WARN)
   1324             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   1325          if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   1326              PNG_RGB_TO_GRAY_ERR)
   1327             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   1328       }
   1329    }
   1330 #endif
   1331 
   1332 /*
   1333 From Andreas Dilger e-mail to png-implement, 26 March 1998:
   1334 
   1335   In most cases, the "simple transparency" should be done prior to doing
   1336   gray-to-RGB, or you will have to test 3x as many bytes to check if a
   1337   pixel is transparent.  You would also need to make sure that the
   1338   transparency information is upgraded to RGB.
   1339 
   1340   To summarize, the current flow is:
   1341   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
   1342                                   with background "in place" if transparent,
   1343                                   convert to RGB if necessary
   1344   - Gray + alpha -> composite with gray background and remove alpha bytes,
   1345                                   convert to RGB if necessary
   1346 
   1347   To support RGB backgrounds for gray images we need:
   1348   - Gray + simple transparency -> convert to RGB + simple transparency, compare
   1349                                   3 or 6 bytes and composite with background
   1350                                   "in place" if transparent (3x compare/pixel
   1351                                   compared to doing composite with gray bkgrnd)
   1352   - Gray + alpha -> convert to RGB + alpha, composite with background and
   1353                                   remove alpha bytes (3x float operations/pixel
   1354                                   compared with composite on gray background)
   1355 
   1356   Greg's change will do this.  The reason it wasn't done before is for
   1357   performance, as this increases the per-pixel operations.  If we would check
   1358   in advance if the background was gray or RGB, and position the gray-to-RGB
   1359   transform appropriately, then it would save a lot of work/time.
   1360  */
   1361 
   1362 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   1363    /* if gray -> RGB, do so now only if background is non-gray; else do later
   1364     * for performance reasons */
   1365    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
   1366        !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
   1367       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1368 #endif
   1369 
   1370 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   1371    if ((png_ptr->transformations & PNG_BACKGROUND) &&
   1372       ((png_ptr->num_trans != 0 ) ||
   1373       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
   1374       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1375          &(png_ptr->trans_values), &(png_ptr->background)
   1376 #if defined(PNG_READ_GAMMA_SUPPORTED)
   1377          , &(png_ptr->background_1),
   1378          png_ptr->gamma_table, png_ptr->gamma_from_1,
   1379          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
   1380          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
   1381          png_ptr->gamma_shift
   1382 #endif
   1383 );
   1384 #endif
   1385 
   1386 #if defined(PNG_READ_GAMMA_SUPPORTED)
   1387    if ((png_ptr->transformations & PNG_GAMMA) &&
   1388 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   1389       !((png_ptr->transformations & PNG_BACKGROUND) &&
   1390       ((png_ptr->num_trans != 0) ||
   1391       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
   1392 #endif
   1393       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
   1394       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1395          png_ptr->gamma_table, png_ptr->gamma_16_table,
   1396          png_ptr->gamma_shift);
   1397 #endif
   1398 
   1399 #if defined(PNG_READ_16_TO_8_SUPPORTED)
   1400    if (png_ptr->transformations & PNG_16_TO_8)
   1401       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1402 #endif
   1403 
   1404 #if defined(PNG_READ_DITHER_SUPPORTED)
   1405    if (png_ptr->transformations & PNG_DITHER)
   1406    {
   1407       png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
   1408          png_ptr->palette_lookup, png_ptr->dither_index);
   1409       if(png_ptr->row_info.rowbytes == (png_uint_32)0)
   1410          png_error(png_ptr, "png_do_dither returned rowbytes=0");
   1411    }
   1412 #endif
   1413 
   1414 #if defined(PNG_READ_INVERT_SUPPORTED)
   1415    if (png_ptr->transformations & PNG_INVERT_MONO)
   1416       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1417 #endif
   1418 
   1419 #if defined(PNG_READ_SHIFT_SUPPORTED)
   1420    if (png_ptr->transformations & PNG_SHIFT)
   1421       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1422          &(png_ptr->shift));
   1423 #endif
   1424 
   1425 #if defined(PNG_READ_PACK_SUPPORTED)
   1426    if (png_ptr->transformations & PNG_PACK)
   1427       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1428 #endif
   1429 
   1430 #if defined(PNG_READ_BGR_SUPPORTED)
   1431    if (png_ptr->transformations & PNG_BGR)
   1432       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1433 #endif
   1434 
   1435 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
   1436    if (png_ptr->transformations & PNG_PACKSWAP)
   1437       png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1438 #endif
   1439 
   1440 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   1441    /* if gray -> RGB, do so now only if we did not do so above */
   1442    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
   1443        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
   1444       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1445 #endif
   1446 
   1447 #if defined(PNG_READ_FILLER_SUPPORTED)
   1448    if (png_ptr->transformations & PNG_FILLER)
   1449       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1450          (png_uint_32)png_ptr->filler, png_ptr->flags);
   1451 #endif
   1452 
   1453 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
   1454    if (png_ptr->transformations & PNG_INVERT_ALPHA)
   1455       png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1456 #endif
   1457 
   1458 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
   1459    if (png_ptr->transformations & PNG_SWAP_ALPHA)
   1460       png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1461 #endif
   1462 
   1463 #if defined(PNG_READ_SWAP_SUPPORTED)
   1464    if (png_ptr->transformations & PNG_SWAP_BYTES)
   1465       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1466 #endif
   1467 
   1468 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   1469    if (png_ptr->transformations & PNG_USER_TRANSFORM)
   1470     {
   1471       if(png_ptr->read_user_transform_fn != NULL)
   1472         (*(png_ptr->read_user_transform_fn)) /* user read transform function */
   1473           (png_ptr,                    /* png_ptr */
   1474            &(png_ptr->row_info),       /* row_info:     */
   1475              /*  png_uint_32 width;          width of row */
   1476              /*  png_uint_32 rowbytes;       number of bytes in row */
   1477              /*  png_byte color_type;        color type of pixels */
   1478              /*  png_byte bit_depth;         bit depth of samples */
   1479              /*  png_byte channels;          number of channels (1-4) */
   1480              /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
   1481            png_ptr->row_buf + 1);      /* start of pixel data for row */
   1482 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
   1483       if(png_ptr->user_transform_depth)
   1484          png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
   1485       if(png_ptr->user_transform_channels)
   1486          png_ptr->row_info.channels = png_ptr->user_transform_channels;
   1487 #endif
   1488       png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
   1489          png_ptr->row_info.channels);
   1490       png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
   1491          png_ptr->row_info.width);
   1492    }
   1493 #endif
   1494 
   1495 }
   1496 
   1497 #if defined(PNG_READ_PACK_SUPPORTED)
   1498 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
   1499  * without changing the actual values.  Thus, if you had a row with
   1500  * a bit depth of 1, you would end up with bytes that only contained
   1501  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
   1502  * png_do_shift() after this.
   1503  */
   1504 void /* PRIVATE */
   1505 png_do_unpack(png_row_infop row_info, png_bytep row)
   1506 {
   1507    png_debug(1, "in png_do_unpack\n");
   1508 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1509    if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
   1510 #else
   1511    if (row_info->bit_depth < 8)
   1512 #endif
   1513    {
   1514       png_uint_32 i;
   1515       png_uint_32 row_width=row_info->width;
   1516 
   1517       switch (row_info->bit_depth)
   1518       {
   1519          case 1:
   1520          {
   1521             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
   1522             png_bytep dp = row + (png_size_t)row_width - 1;
   1523             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
   1524             for (i = 0; i < row_width; i++)
   1525             {
   1526                *dp = (png_byte)((*sp >> shift) & 0x01);
   1527                if (shift == 7)
   1528                {
   1529                   shift = 0;
   1530                   sp--;
   1531                }
   1532                else
   1533                   shift++;
   1534 
   1535                dp--;
   1536             }
   1537             break;
   1538          }
   1539          case 2:
   1540          {
   1541 
   1542             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
   1543             png_bytep dp = row + (png_size_t)row_width - 1;
   1544             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   1545             for (i = 0; i < row_width; i++)
   1546             {
   1547                *dp = (png_byte)((*sp >> shift) & 0x03);
   1548                if (shift == 6)
   1549                {
   1550                   shift = 0;
   1551                   sp--;
   1552                }
   1553                else
   1554                   shift += 2;
   1555 
   1556                dp--;
   1557             }
   1558             break;
   1559          }
   1560          case 4:
   1561          {
   1562             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
   1563             png_bytep dp = row + (png_size_t)row_width - 1;
   1564             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   1565             for (i = 0; i < row_width; i++)
   1566             {
   1567                *dp = (png_byte)((*sp >> shift) & 0x0f);
   1568                if (shift == 4)
   1569                {
   1570                   shift = 0;
   1571                   sp--;
   1572                }
   1573                else
   1574                   shift = 4;
   1575 
   1576                dp--;
   1577             }
   1578             break;
   1579          }
   1580       }
   1581       row_info->bit_depth = 8;
   1582       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   1583       row_info->rowbytes = row_width * row_info->channels;
   1584    }
   1585 }
   1586 #endif
   1587 
   1588 #if defined(PNG_READ_SHIFT_SUPPORTED)
   1589 /* Reverse the effects of png_do_shift.  This routine merely shifts the
   1590  * pixels back to their significant bits values.  Thus, if you have
   1591  * a row of bit depth 8, but only 5 are significant, this will shift
   1592  * the values back to 0 through 31.
   1593  */
   1594 void /* PRIVATE */
   1595 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
   1596 {
   1597    png_debug(1, "in png_do_unshift\n");
   1598    if (
   1599 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1600        row != NULL && row_info != NULL && sig_bits != NULL &&
   1601 #endif
   1602        row_info->color_type != PNG_COLOR_TYPE_PALETTE)
   1603    {
   1604       int shift[4];
   1605       int channels = 0;
   1606       int c;
   1607       png_uint_16 value = 0;
   1608       png_uint_32 row_width = row_info->width;
   1609 
   1610       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
   1611       {
   1612          shift[channels++] = row_info->bit_depth - sig_bits->red;
   1613          shift[channels++] = row_info->bit_depth - sig_bits->green;
   1614          shift[channels++] = row_info->bit_depth - sig_bits->blue;
   1615       }
   1616       else
   1617       {
   1618          shift[channels++] = row_info->bit_depth - sig_bits->gray;
   1619       }
   1620       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
   1621       {
   1622          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
   1623       }
   1624 
   1625       for (c = 0; c < channels; c++)
   1626       {
   1627          if (shift[c] <= 0)
   1628             shift[c] = 0;
   1629          else
   1630             value = 1;
   1631       }
   1632 
   1633       if (!value)
   1634          return;
   1635 
   1636       switch (row_info->bit_depth)
   1637       {
   1638          case 2:
   1639          {
   1640             png_bytep bp;
   1641             png_uint_32 i;
   1642             png_uint_32 istop = row_info->rowbytes;
   1643 
   1644             for (bp = row, i = 0; i < istop; i++)
   1645             {
   1646                *bp >>= 1;
   1647                *bp++ &= 0x55;
   1648             }
   1649             break;
   1650          }
   1651          case 4:
   1652          {
   1653             png_bytep bp = row;
   1654             png_uint_32 i;
   1655             png_uint_32 istop = row_info->rowbytes;
   1656             png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
   1657                (png_byte)((int)0xf >> shift[0]));
   1658 
   1659             for (i = 0; i < istop; i++)
   1660             {
   1661                *bp >>= shift[0];
   1662                *bp++ &= mask;
   1663             }
   1664             break;
   1665          }
   1666          case 8:
   1667          {
   1668             png_bytep bp = row;
   1669             png_uint_32 i;
   1670             png_uint_32 istop = row_width * channels;
   1671 
   1672             for (i = 0; i < istop; i++)
   1673             {
   1674                *bp++ >>= shift[i%channels];
   1675             }
   1676             break;
   1677          }
   1678          case 16:
   1679          {
   1680             png_bytep bp = row;
   1681             png_uint_32 i;
   1682             png_uint_32 istop = channels * row_width;
   1683 
   1684             for (i = 0; i < istop; i++)
   1685             {
   1686                value = (png_uint_16)((*bp << 8) + *(bp + 1));
   1687                value >>= shift[i%channels];
   1688                *bp++ = (png_byte)(value >> 8);
   1689                *bp++ = (png_byte)(value & 0xff);
   1690             }
   1691             break;
   1692          }
   1693       }
   1694    }
   1695 }
   1696 #endif
   1697 
   1698 #if defined(PNG_READ_16_TO_8_SUPPORTED)
   1699 /* chop rows of bit depth 16 down to 8 */
   1700 void /* PRIVATE */
   1701 png_do_chop(png_row_infop row_info, png_bytep row)
   1702 {
   1703    png_debug(1, "in png_do_chop\n");
   1704 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1705    if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
   1706 #else
   1707    if (row_info->bit_depth == 16)
   1708 #endif
   1709    {
   1710       png_bytep sp = row;
   1711       png_bytep dp = row;
   1712       png_uint_32 i;
   1713       png_uint_32 istop = row_info->width * row_info->channels;
   1714 
   1715       for (i = 0; i<istop; i++, sp += 2, dp++)
   1716       {
   1717 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
   1718       /* This does a more accurate scaling of the 16-bit color
   1719        * value, rather than a simple low-byte truncation.
   1720        *
   1721        * What the ideal calculation should be:
   1722        *   *dp = (((((png_uint_32)(*sp) << 8) |
   1723        *          (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
   1724        *
   1725        * GRR: no, I think this is what it really should be:
   1726        *   *dp = (((((png_uint_32)(*sp) << 8) |
   1727        *           (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
   1728        *
   1729        * GRR: here's the exact calculation with shifts:
   1730        *   temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
   1731        *   *dp = (temp - (temp >> 8)) >> 8;
   1732        *
   1733        * Approximate calculation with shift/add instead of multiply/divide:
   1734        *   *dp = ((((png_uint_32)(*sp) << 8) |
   1735        *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
   1736        *
   1737        * What we actually do to avoid extra shifting and conversion:
   1738        */
   1739 
   1740          *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
   1741 #else
   1742        /* Simply discard the low order byte */
   1743          *dp = *sp;
   1744 #endif
   1745       }
   1746       row_info->bit_depth = 8;
   1747       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   1748       row_info->rowbytes = row_info->width * row_info->channels;
   1749    }
   1750 }
   1751 #endif
   1752 
   1753 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
   1754 void /* PRIVATE */
   1755 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
   1756 {
   1757    png_debug(1, "in png_do_read_swap_alpha\n");
   1758 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1759    if (row != NULL && row_info != NULL)
   1760 #endif
   1761    {
   1762       png_uint_32 row_width = row_info->width;
   1763       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   1764       {
   1765          /* This converts from RGBA to ARGB */
   1766          if (row_info->bit_depth == 8)
   1767          {
   1768             png_bytep sp = row + row_info->rowbytes;
   1769             png_bytep dp = sp;
   1770             png_byte save;
   1771             png_uint_32 i;
   1772 
   1773             for (i = 0; i < row_width; i++)
   1774             {
   1775                save = *(--sp);
   1776                *(--dp) = *(--sp);
   1777                *(--dp) = *(--sp);
   1778                *(--dp) = *(--sp);
   1779                *(--dp) = save;
   1780             }
   1781          }
   1782          /* This converts from RRGGBBAA to AARRGGBB */
   1783          else
   1784          {
   1785             png_bytep sp = row + row_info->rowbytes;
   1786             png_bytep dp = sp;
   1787             png_byte save[2];
   1788             png_uint_32 i;
   1789 
   1790             for (i = 0; i < row_width; i++)
   1791             {
   1792                save[0] = *(--sp);
   1793                save[1] = *(--sp);
   1794                *(--dp) = *(--sp);
   1795                *(--dp) = *(--sp);
   1796                *(--dp) = *(--sp);
   1797                *(--dp) = *(--sp);
   1798                *(--dp) = *(--sp);
   1799                *(--dp) = *(--sp);
   1800                *(--dp) = save[0];
   1801                *(--dp) = save[1];
   1802             }
   1803          }
   1804       }
   1805       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   1806       {
   1807          /* This converts from GA to AG */
   1808          if (row_info->bit_depth == 8)
   1809          {
   1810             png_bytep sp = row + row_info->rowbytes;
   1811             png_bytep dp = sp;
   1812             png_byte save;
   1813             png_uint_32 i;
   1814 
   1815             for (i = 0; i < row_width; i++)
   1816             {
   1817                save = *(--sp);
   1818                *(--dp) = *(--sp);
   1819                *(--dp) = save;
   1820             }
   1821          }
   1822          /* This converts from GGAA to AAGG */
   1823          else
   1824          {
   1825             png_bytep sp = row + row_info->rowbytes;
   1826             png_bytep dp = sp;
   1827             png_byte save[2];
   1828             png_uint_32 i;
   1829 
   1830             for (i = 0; i < row_width; i++)
   1831             {
   1832                save[0] = *(--sp);
   1833                save[1] = *(--sp);
   1834                *(--dp) = *(--sp);
   1835                *(--dp) = *(--sp);
   1836                *(--dp) = save[0];
   1837                *(--dp) = save[1];
   1838             }
   1839          }
   1840       }
   1841    }
   1842 }
   1843 #endif
   1844 
   1845 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
   1846 void /* PRIVATE */
   1847 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
   1848 {
   1849    png_debug(1, "in png_do_read_invert_alpha\n");
   1850 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1851    if (row != NULL && row_info != NULL)
   1852 #endif
   1853    {
   1854       png_uint_32 row_width = row_info->width;
   1855       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   1856       {
   1857          /* This inverts the alpha channel in RGBA */
   1858          if (row_info->bit_depth == 8)
   1859          {
   1860             png_bytep sp = row + row_info->rowbytes;
   1861             png_bytep dp = sp;
   1862             png_uint_32 i;
   1863 
   1864             for (i = 0; i < row_width; i++)
   1865             {
   1866                *(--dp) = (png_byte)(255 - *(--sp));
   1867 
   1868 /*             This does nothing:
   1869                *(--dp) = *(--sp);
   1870                *(--dp) = *(--sp);
   1871                *(--dp) = *(--sp);
   1872                We can replace it with:
   1873 */
   1874                sp-=3;
   1875                dp=sp;
   1876             }
   1877          }
   1878          /* This inverts the alpha channel in RRGGBBAA */
   1879          else
   1880          {
   1881             png_bytep sp = row + row_info->rowbytes;
   1882             png_bytep dp = sp;
   1883             png_uint_32 i;
   1884 
   1885             for (i = 0; i < row_width; i++)
   1886             {
   1887                *(--dp) = (png_byte)(255 - *(--sp));
   1888                *(--dp) = (png_byte)(255 - *(--sp));
   1889 
   1890 /*             This does nothing:
   1891                *(--dp) = *(--sp);
   1892                *(--dp) = *(--sp);
   1893                *(--dp) = *(--sp);
   1894                *(--dp) = *(--sp);
   1895                *(--dp) = *(--sp);
   1896                *(--dp) = *(--sp);
   1897                We can replace it with:
   1898 */
   1899                sp-=6;
   1900                dp=sp;
   1901             }
   1902          }
   1903       }
   1904       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   1905       {
   1906          /* This inverts the alpha channel in GA */
   1907          if (row_info->bit_depth == 8)
   1908          {
   1909             png_bytep sp = row + row_info->rowbytes;
   1910             png_bytep dp = sp;
   1911             png_uint_32 i;
   1912 
   1913             for (i = 0; i < row_width; i++)
   1914             {
   1915                *(--dp) = (png_byte)(255 - *(--sp));
   1916                *(--dp) = *(--sp);
   1917             }
   1918          }
   1919          /* This inverts the alpha channel in GGAA */
   1920          else
   1921          {
   1922             png_bytep sp  = row + row_info->rowbytes;
   1923             png_bytep dp = sp;
   1924             png_uint_32 i;
   1925 
   1926             for (i = 0; i < row_width; i++)
   1927             {
   1928                *(--dp) = (png_byte)(255 - *(--sp));
   1929                *(--dp) = (png_byte)(255 - *(--sp));
   1930 /*
   1931                *(--dp) = *(--sp);
   1932                *(--dp) = *(--sp);
   1933 */
   1934                sp-=2;
   1935                dp=sp;
   1936             }
   1937          }
   1938       }
   1939    }
   1940 }
   1941 #endif
   1942 
   1943 #if defined(PNG_READ_FILLER_SUPPORTED)
   1944 /* Add filler channel if we have RGB color */
   1945 void /* PRIVATE */
   1946 png_do_read_filler(png_row_infop row_info, png_bytep row,
   1947    png_uint_32 filler, png_uint_32 flags)
   1948 {
   1949    png_uint_32 i;
   1950    png_uint_32 row_width = row_info->width;
   1951 
   1952    png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
   1953    png_byte lo_filler = (png_byte)(filler & 0xff);
   1954 
   1955    png_debug(1, "in png_do_read_filler\n");
   1956    if (
   1957 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   1958        row != NULL  && row_info != NULL &&
   1959 #endif
   1960        row_info->color_type == PNG_COLOR_TYPE_GRAY)
   1961    {
   1962       if(row_info->bit_depth == 8)
   1963       {
   1964          /* This changes the data from G to GX */
   1965          if (flags & PNG_FLAG_FILLER_AFTER)
   1966          {
   1967             png_bytep sp = row + (png_size_t)row_width;
   1968             png_bytep dp =  sp + (png_size_t)row_width;
   1969             for (i = 1; i < row_width; i++)
   1970             {
   1971                *(--dp) = lo_filler;
   1972                *(--dp) = *(--sp);
   1973             }
   1974             *(--dp) = lo_filler;
   1975             row_info->channels = 2;
   1976             row_info->pixel_depth = 16;
   1977             row_info->rowbytes = row_width * 2;
   1978          }
   1979       /* This changes the data from G to XG */
   1980          else
   1981          {
   1982             png_bytep sp = row + (png_size_t)row_width;
   1983             png_bytep dp = sp  + (png_size_t)row_width;
   1984             for (i = 0; i < row_width; i++)
   1985             {
   1986                *(--dp) = *(--sp);
   1987                *(--dp) = lo_filler;
   1988             }
   1989             row_info->channels = 2;
   1990             row_info->pixel_depth = 16;
   1991             row_info->rowbytes = row_width * 2;
   1992          }
   1993       }
   1994       else if(row_info->bit_depth == 16)
   1995       {
   1996          /* This changes the data from GG to GGXX */
   1997          if (flags & PNG_FLAG_FILLER_AFTER)
   1998          {
   1999             png_bytep sp = row + (png_size_t)row_width * 2;
   2000             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2001             for (i = 1; i < row_width; i++)
   2002             {
   2003                *(--dp) = hi_filler;
   2004                *(--dp) = lo_filler;
   2005                *(--dp) = *(--sp);
   2006                *(--dp) = *(--sp);
   2007             }
   2008             *(--dp) = hi_filler;
   2009             *(--dp) = lo_filler;
   2010             row_info->channels = 2;
   2011             row_info->pixel_depth = 32;
   2012             row_info->rowbytes = row_width * 4;
   2013          }
   2014          /* This changes the data from GG to XXGG */
   2015          else
   2016          {
   2017             png_bytep sp = row + (png_size_t)row_width * 2;
   2018             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2019             for (i = 0; i < row_width; i++)
   2020             {
   2021                *(--dp) = *(--sp);
   2022                *(--dp) = *(--sp);
   2023                *(--dp) = hi_filler;
   2024                *(--dp) = lo_filler;
   2025             }
   2026             row_info->channels = 2;
   2027             row_info->pixel_depth = 32;
   2028             row_info->rowbytes = row_width * 4;
   2029          }
   2030       }
   2031    } /* COLOR_TYPE == GRAY */
   2032    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   2033    {
   2034       if(row_info->bit_depth == 8)
   2035       {
   2036          /* This changes the data from RGB to RGBX */
   2037          if (flags & PNG_FLAG_FILLER_AFTER)
   2038          {
   2039             png_bytep sp = row + (png_size_t)row_width * 3;
   2040             png_bytep dp = sp  + (png_size_t)row_width;
   2041             for (i = 1; i < row_width; i++)
   2042             {
   2043                *(--dp) = lo_filler;
   2044                *(--dp) = *(--sp);
   2045                *(--dp) = *(--sp);
   2046                *(--dp) = *(--sp);
   2047             }
   2048             *(--dp) = lo_filler;
   2049             row_info->channels = 4;
   2050             row_info->pixel_depth = 32;
   2051             row_info->rowbytes = row_width * 4;
   2052          }
   2053       /* This changes the data from RGB to XRGB */
   2054          else
   2055          {
   2056             png_bytep sp = row + (png_size_t)row_width * 3;
   2057             png_bytep dp = sp + (png_size_t)row_width;
   2058             for (i = 0; i < row_width; i++)
   2059             {
   2060                *(--dp) = *(--sp);
   2061                *(--dp) = *(--sp);
   2062                *(--dp) = *(--sp);
   2063                *(--dp) = lo_filler;
   2064             }
   2065             row_info->channels = 4;
   2066             row_info->pixel_depth = 32;
   2067             row_info->rowbytes = row_width * 4;
   2068          }
   2069       }
   2070       else if(row_info->bit_depth == 16)
   2071       {
   2072          /* This changes the data from RRGGBB to RRGGBBXX */
   2073          if (flags & PNG_FLAG_FILLER_AFTER)
   2074          {
   2075             png_bytep sp = row + (png_size_t)row_width * 6;
   2076             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2077             for (i = 1; i < row_width; i++)
   2078             {
   2079                *(--dp) = hi_filler;
   2080                *(--dp) = lo_filler;
   2081                *(--dp) = *(--sp);
   2082                *(--dp) = *(--sp);
   2083                *(--dp) = *(--sp);
   2084                *(--dp) = *(--sp);
   2085                *(--dp) = *(--sp);
   2086                *(--dp) = *(--sp);
   2087             }
   2088             *(--dp) = hi_filler;
   2089             *(--dp) = lo_filler;
   2090             row_info->channels = 4;
   2091             row_info->pixel_depth = 64;
   2092             row_info->rowbytes = row_width * 8;
   2093          }
   2094          /* This changes the data from RRGGBB to XXRRGGBB */
   2095          else
   2096          {
   2097             png_bytep sp = row + (png_size_t)row_width * 6;
   2098             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2099             for (i = 0; i < row_width; i++)
   2100             {
   2101                *(--dp) = *(--sp);
   2102                *(--dp) = *(--sp);
   2103                *(--dp) = *(--sp);
   2104                *(--dp) = *(--sp);
   2105                *(--dp) = *(--sp);
   2106                *(--dp) = *(--sp);
   2107                *(--dp) = hi_filler;
   2108                *(--dp) = lo_filler;
   2109             }
   2110             row_info->channels = 4;
   2111             row_info->pixel_depth = 64;
   2112             row_info->rowbytes = row_width * 8;
   2113          }
   2114       }
   2115    } /* COLOR_TYPE == RGB */
   2116 }
   2117 #endif
   2118 
   2119 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
   2120 /* expand grayscale files to RGB, with or without alpha */
   2121 void /* PRIVATE */
   2122 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
   2123 {
   2124    png_uint_32 i;
   2125    png_uint_32 row_width = row_info->width;
   2126 
   2127    png_debug(1, "in png_do_gray_to_rgb\n");
   2128    if (row_info->bit_depth >= 8 &&
   2129 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   2130        row != NULL && row_info != NULL &&
   2131 #endif
   2132       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
   2133    {
   2134       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   2135       {
   2136          if (row_info->bit_depth == 8)
   2137          {
   2138             png_bytep sp = row + (png_size_t)row_width - 1;
   2139             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2140             for (i = 0; i < row_width; i++)
   2141             {
   2142                *(dp--) = *sp;
   2143                *(dp--) = *sp;
   2144                *(dp--) = *(sp--);
   2145             }
   2146          }
   2147          else
   2148          {
   2149             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2150             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2151             for (i = 0; i < row_width; i++)
   2152             {
   2153                *(dp--) = *sp;
   2154                *(dp--) = *(sp - 1);
   2155                *(dp--) = *sp;
   2156                *(dp--) = *(sp - 1);
   2157                *(dp--) = *(sp--);
   2158                *(dp--) = *(sp--);
   2159             }
   2160          }
   2161       }
   2162       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2163       {
   2164          if (row_info->bit_depth == 8)
   2165          {
   2166             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2167             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2168             for (i = 0; i < row_width; i++)
   2169             {
   2170                *(dp--) = *(sp--);
   2171                *(dp--) = *sp;
   2172                *(dp--) = *sp;
   2173                *(dp--) = *(sp--);
   2174             }
   2175          }
   2176          else
   2177          {
   2178             png_bytep sp = row + (png_size_t)row_width * 4 - 1;
   2179             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2180             for (i = 0; i < row_width; i++)
   2181             {
   2182                *(dp--) = *(sp--);
   2183                *(dp--) = *(sp--);
   2184                *(dp--) = *sp;
   2185                *(dp--) = *(sp - 1);
   2186                *(dp--) = *sp;
   2187                *(dp--) = *(sp - 1);
   2188                *(dp--) = *(sp--);
   2189                *(dp--) = *(sp--);
   2190             }
   2191          }
   2192       }
   2193       row_info->channels += (png_byte)2;
   2194       row_info->color_type |= PNG_COLOR_MASK_COLOR;
   2195       row_info->pixel_depth = (png_byte)(row_info->channels *
   2196          row_info->bit_depth);
   2197       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   2198    }
   2199 }
   2200 #endif
   2201 
   2202 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   2203 /* reduce RGB files to grayscale, with or without alpha
   2204  * using the equation given in Poynton's ColorFAQ at
   2205  * <http://www.inforamp.net/~poynton/>
   2206  * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
   2207  *
   2208  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
   2209  *
   2210  *  We approximate this with
   2211  *
   2212  *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
   2213  *
   2214  *  which can be expressed with integers as
   2215  *
   2216  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
   2217  *
   2218  *  The calculation is to be done in a linear colorspace.
   2219  *
   2220  *  Other integer coefficents can be used via png_set_rgb_to_gray().
   2221  */
   2222 int /* PRIVATE */
   2223 png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
   2224 
   2225 {
   2226    png_uint_32 i;
   2227 
   2228    png_uint_32 row_width = row_info->width;
   2229    int rgb_error = 0;
   2230 
   2231    png_debug(1, "in png_do_rgb_to_gray\n");
   2232    if (
   2233 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   2234        row != NULL && row_info != NULL &&
   2235 #endif
   2236       (row_info->color_type & PNG_COLOR_MASK_COLOR))
   2237    {
   2238       png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
   2239       png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
   2240       png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
   2241 
   2242       if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   2243       {
   2244          if (row_info->bit_depth == 8)
   2245          {
   2246 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2247             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
   2248             {
   2249                png_bytep sp = row;
   2250                png_bytep dp = row;
   2251 
   2252                for (i = 0; i < row_width; i++)
   2253                {
   2254                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
   2255                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
   2256                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
   2257                   if(red != green || red != blue)
   2258                   {
   2259                      rgb_error |= 1;
   2260                      *(dp++) = png_ptr->gamma_from_1[
   2261                        (rc*red+gc*green+bc*blue)>>15];
   2262                   }
   2263                   else
   2264                      *(dp++) = *(sp-1);
   2265                }
   2266             }
   2267             else
   2268 #endif
   2269             {
   2270                png_bytep sp = row;
   2271                png_bytep dp = row;
   2272                for (i = 0; i < row_width; i++)
   2273                {
   2274                   png_byte red   = *(sp++);
   2275                   png_byte green = *(sp++);
   2276                   png_byte blue  = *(sp++);
   2277                   if(red != green || red != blue)
   2278                   {
   2279                      rgb_error |= 1;
   2280                      *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
   2281                   }
   2282                   else
   2283                      *(dp++) = *(sp-1);
   2284                }
   2285             }
   2286          }
   2287 
   2288          else /* RGB bit_depth == 16 */
   2289          {
   2290 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2291             if (png_ptr->gamma_16_to_1 != NULL &&
   2292                 png_ptr->gamma_16_from_1 != NULL)
   2293             {
   2294                png_bytep sp = row;
   2295                png_bytep dp = row;
   2296                for (i = 0; i < row_width; i++)
   2297                {
   2298                   png_uint_16 red, green, blue, w;
   2299 
   2300                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2301                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2302                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2303 
   2304                   if(red == green && red == blue)
   2305                      w = red;
   2306                   else
   2307                   {
   2308                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
   2309                                   png_ptr->gamma_shift][red>>8];
   2310                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
   2311                                   png_ptr->gamma_shift][green>>8];
   2312                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
   2313                                   png_ptr->gamma_shift][blue>>8];
   2314                      png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
   2315                                   + bc*blue_1)>>15);
   2316                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
   2317                          png_ptr->gamma_shift][gray16 >> 8];
   2318                      rgb_error |= 1;
   2319                   }
   2320 
   2321                   *(dp++) = (png_byte)((w>>8) & 0xff);
   2322                   *(dp++) = (png_byte)(w & 0xff);
   2323                }
   2324             }
   2325             else
   2326 #endif
   2327             {
   2328                png_bytep sp = row;
   2329                png_bytep dp = row;
   2330                for (i = 0; i < row_width; i++)
   2331                {
   2332                   png_uint_16 red, green, blue, gray16;
   2333 
   2334                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2335                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2336                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2337 
   2338                   if(red != green || red != blue)
   2339                      rgb_error |= 1;
   2340                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
   2341                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
   2342                   *(dp++) = (png_byte)(gray16 & 0xff);
   2343                }
   2344             }
   2345          }
   2346       }
   2347       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   2348       {
   2349          if (row_info->bit_depth == 8)
   2350          {
   2351 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2352             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
   2353             {
   2354                png_bytep sp = row;
   2355                png_bytep dp = row;
   2356                for (i = 0; i < row_width; i++)
   2357                {
   2358                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
   2359                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
   2360                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
   2361                   if(red != green || red != blue)
   2362                      rgb_error |= 1;
   2363                   *(dp++) =  png_ptr->gamma_from_1
   2364                              [(rc*red + gc*green + bc*blue)>>15];
   2365                   *(dp++) = *(sp++);  /* alpha */
   2366                }
   2367             }
   2368             else
   2369 #endif
   2370             {
   2371                png_bytep sp = row;
   2372                png_bytep dp = row;
   2373                for (i = 0; i < row_width; i++)
   2374                {
   2375                   png_byte red   = *(sp++);
   2376                   png_byte green = *(sp++);
   2377                   png_byte blue  = *(sp++);
   2378                   if(red != green || red != blue)
   2379                      rgb_error |= 1;
   2380                   *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
   2381                   *(dp++) = *(sp++);  /* alpha */
   2382                }
   2383             }
   2384          }
   2385          else /* RGBA bit_depth == 16 */
   2386          {
   2387 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2388             if (png_ptr->gamma_16_to_1 != NULL &&
   2389                 png_ptr->gamma_16_from_1 != NULL)
   2390             {
   2391                png_bytep sp = row;
   2392                png_bytep dp = row;
   2393                for (i = 0; i < row_width; i++)
   2394                {
   2395                   png_uint_16 red, green, blue, w;
   2396 
   2397                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2398                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2399                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2400 
   2401                   if(red == green && red == blue)
   2402                      w = red;
   2403                   else
   2404                   {
   2405                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
   2406                                   png_ptr->gamma_shift][red>>8];
   2407                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
   2408                                   png_ptr->gamma_shift][green>>8];
   2409                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
   2410                                   png_ptr->gamma_shift][blue>>8];
   2411                      png_uint_16 gray16  = (png_uint_16)((rc * red_1
   2412                                   + gc * green_1 + bc * blue_1)>>15);
   2413                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
   2414                          png_ptr->gamma_shift][gray16 >> 8];
   2415                      rgb_error |= 1;
   2416                   }
   2417 
   2418                   *(dp++) = (png_byte)((w>>8) & 0xff);
   2419                   *(dp++) = (png_byte)(w & 0xff);
   2420                   *(dp++) = *(sp++);  /* alpha */
   2421                   *(dp++) = *(sp++);
   2422                }
   2423             }
   2424             else
   2425 #endif
   2426             {
   2427                png_bytep sp = row;
   2428                png_bytep dp = row;
   2429                for (i = 0; i < row_width; i++)
   2430                {
   2431                   png_uint_16 red, green, blue, gray16;
   2432                   red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2433                   green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2434                   blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2435                   if(red != green || red != blue)
   2436                      rgb_error |= 1;
   2437                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
   2438                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
   2439                   *(dp++) = (png_byte)(gray16 & 0xff);
   2440                   *(dp++) = *(sp++);  /* alpha */
   2441                   *(dp++) = *(sp++);
   2442                }
   2443             }
   2444          }
   2445       }
   2446    row_info->channels -= (png_byte)2;
   2447       row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
   2448       row_info->pixel_depth = (png_byte)(row_info->channels *
   2449          row_info->bit_depth);
   2450       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   2451    }
   2452    return rgb_error;
   2453 }
   2454 #endif
   2455 
   2456 /* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
   2457  * large of png_color.  This lets grayscale images be treated as
   2458  * paletted.  Most useful for gamma correction and simplification
   2459  * of code.
   2460  */
   2461 void PNGAPI
   2462 png_build_grayscale_palette(int bit_depth, png_colorp palette)
   2463 {
   2464    int num_palette;
   2465    int color_inc;
   2466    int i;
   2467    int v;
   2468 
   2469    png_debug(1, "in png_do_build_grayscale_palette\n");
   2470    if (palette == NULL)
   2471       return;
   2472 
   2473    switch (bit_depth)
   2474    {
   2475       case 1:
   2476          num_palette = 2;
   2477          color_inc = 0xff;
   2478          break;
   2479       case 2:
   2480          num_palette = 4;
   2481          color_inc = 0x55;
   2482          break;
   2483       case 4:
   2484          num_palette = 16;
   2485          color_inc = 0x11;
   2486          break;
   2487       case 8:
   2488          num_palette = 256;
   2489          color_inc = 1;
   2490          break;
   2491       default:
   2492          num_palette = 0;
   2493          color_inc = 0;
   2494          break;
   2495    }
   2496 
   2497    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
   2498    {
   2499       palette[i].red = (png_byte)v;
   2500       palette[i].green = (png_byte)v;
   2501       palette[i].blue = (png_byte)v;
   2502    }
   2503 }
   2504 
   2505 /* This function is currently unused.  Do we really need it? */
   2506 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
   2507 void /* PRIVATE */
   2508 png_correct_palette(png_structp png_ptr, png_colorp palette,
   2509    int num_palette)
   2510 {
   2511    png_debug(1, "in png_correct_palette\n");
   2512 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
   2513     defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
   2514    if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
   2515    {
   2516       png_color back, back_1;
   2517 
   2518       if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
   2519       {
   2520          back.red = png_ptr->gamma_table[png_ptr->background.red];
   2521          back.green = png_ptr->gamma_table[png_ptr->background.green];
   2522          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
   2523 
   2524          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
   2525          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
   2526          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
   2527       }
   2528       else
   2529       {
   2530          double g;
   2531 
   2532          g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
   2533 
   2534          if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
   2535              fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
   2536          {
   2537             back.red = png_ptr->background.red;
   2538             back.green = png_ptr->background.green;
   2539             back.blue = png_ptr->background.blue;
   2540          }
   2541          else
   2542          {
   2543             back.red =
   2544                (png_byte)(pow((double)png_ptr->background.red/255, g) *
   2545                 255.0 + 0.5);
   2546             back.green =
   2547                (png_byte)(pow((double)png_ptr->background.green/255, g) *
   2548                 255.0 + 0.5);
   2549             back.blue =
   2550                (png_byte)(pow((double)png_ptr->background.blue/255, g) *
   2551                 255.0 + 0.5);
   2552          }
   2553 
   2554          g = 1.0 / png_ptr->background_gamma;
   2555 
   2556          back_1.red =
   2557             (png_byte)(pow((double)png_ptr->background.red/255, g) *
   2558              255.0 + 0.5);
   2559          back_1.green =
   2560             (png_byte)(pow((double)png_ptr->background.green/255, g) *
   2561              255.0 + 0.5);
   2562          back_1.blue =
   2563             (png_byte)(pow((double)png_ptr->background.blue/255, g) *
   2564              255.0 + 0.5);
   2565       }
   2566 
   2567       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   2568       {
   2569          png_uint_32 i;
   2570 
   2571          for (i = 0; i < (png_uint_32)num_palette; i++)
   2572          {
   2573             if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
   2574             {
   2575                palette[i] = back;
   2576             }
   2577             else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
   2578             {
   2579                png_byte v, w;
   2580 
   2581                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
   2582                png_composite(w, v, png_ptr->trans[i], back_1.red);
   2583                palette[i].red = png_ptr->gamma_from_1[w];
   2584 
   2585                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
   2586                png_composite(w, v, png_ptr->trans[i], back_1.green);
   2587                palette[i].green = png_ptr->gamma_from_1[w];
   2588 
   2589                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
   2590                png_composite(w, v, png_ptr->trans[i], back_1.blue);
   2591                palette[i].blue = png_ptr->gamma_from_1[w];
   2592             }
   2593             else
   2594             {
   2595                palette[i].red = png_ptr->gamma_table[palette[i].red];
   2596                palette[i].green = png_ptr->gamma_table[palette[i].green];
   2597                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2598             }
   2599          }
   2600       }
   2601       else
   2602       {
   2603          int i;
   2604 
   2605          for (i = 0; i < num_palette; i++)
   2606          {
   2607             if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
   2608             {
   2609                palette[i] = back;
   2610             }
   2611             else
   2612             {
   2613                palette[i].red = png_ptr->gamma_table[palette[i].red];
   2614                palette[i].green = png_ptr->gamma_table[palette[i].green];
   2615                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2616             }
   2617          }
   2618       }
   2619    }
   2620    else
   2621 #endif
   2622 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2623    if (png_ptr->transformations & PNG_GAMMA)
   2624    {
   2625       int i;
   2626 
   2627       for (i = 0; i < num_palette; i++)
   2628       {
   2629          palette[i].red = png_ptr->gamma_table[palette[i].red];
   2630          palette[i].green = png_ptr->gamma_table[palette[i].green];
   2631          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2632       }
   2633    }
   2634 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   2635    else
   2636 #endif
   2637 #endif
   2638 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   2639    if (png_ptr->transformations & PNG_BACKGROUND)
   2640    {
   2641       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   2642       {
   2643          png_color back;
   2644 
   2645          back.red   = (png_byte)png_ptr->background.red;
   2646          back.green = (png_byte)png_ptr->background.green;
   2647          back.blue  = (png_byte)png_ptr->background.blue;
   2648 
   2649          for (i = 0; i < (int)png_ptr->num_trans; i++)
   2650          {
   2651             if (png_ptr->trans[i] == 0)
   2652             {
   2653                palette[i].red = back.red;
   2654                palette[i].green = back.green;
   2655                palette[i].blue = back.blue;
   2656             }
   2657             else if (png_ptr->trans[i] != 0xff)
   2658             {
   2659                png_composite(palette[i].red, png_ptr->palette[i].red,
   2660                   png_ptr->trans[i], back.red);
   2661                png_composite(palette[i].green, png_ptr->palette[i].green,
   2662                   png_ptr->trans[i], back.green);
   2663                png_composite(palette[i].blue, png_ptr->palette[i].blue,
   2664                   png_ptr->trans[i], back.blue);
   2665             }
   2666          }
   2667       }
   2668       else /* assume grayscale palette (what else could it be?) */
   2669       {
   2670          int i;
   2671 
   2672          for (i = 0; i < num_palette; i++)
   2673          {
   2674             if (i == (png_byte)png_ptr->trans_values.gray)
   2675             {
   2676                palette[i].red = (png_byte)png_ptr->background.red;
   2677                palette[i].green = (png_byte)png_ptr->background.green;
   2678                palette[i].blue = (png_byte)png_ptr->background.blue;
   2679             }
   2680          }
   2681       }
   2682    }
   2683 #endif
   2684 }
   2685 #endif
   2686 
   2687 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
   2688 /* Replace any alpha or transparency with the supplied background color.
   2689  * "background" is already in the screen gamma, while "background_1" is
   2690  * at a gamma of 1.0.  Paletted files have already been taken care of.
   2691  */
   2692 void /* PRIVATE */
   2693 png_do_background(png_row_infop row_info, png_bytep row,
   2694    png_color_16p trans_values, png_color_16p background
   2695 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2696    , png_color_16p background_1,
   2697    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
   2698    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
   2699    png_uint_16pp gamma_16_to_1, int gamma_shift
   2700 #endif
   2701    )
   2702 {
   2703    png_bytep sp, dp;
   2704    png_uint_32 i;
   2705    png_uint_32 row_width=row_info->width;
   2706    int shift;
   2707 
   2708    png_debug(1, "in png_do_background\n");
   2709    if (background != NULL &&
   2710 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   2711        row != NULL && row_info != NULL &&
   2712 #endif
   2713       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
   2714       (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
   2715    {
   2716       switch (row_info->color_type)
   2717       {
   2718          case PNG_COLOR_TYPE_GRAY:
   2719          {
   2720             switch (row_info->bit_depth)
   2721             {
   2722                case 1:
   2723                {
   2724                   sp = row;
   2725                   shift = 7;
   2726                   for (i = 0; i < row_width; i++)
   2727                   {
   2728                      if ((png_uint_16)((*sp >> shift) & 0x01)
   2729                         == trans_values->gray)
   2730                      {
   2731                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
   2732                         *sp |= (png_byte)(background->gray << shift);
   2733                      }
   2734                      if (!shift)
   2735                      {
   2736                         shift = 7;
   2737                         sp++;
   2738                      }
   2739                      else
   2740                         shift--;
   2741                   }
   2742                   break;
   2743                }
   2744                case 2:
   2745                {
   2746 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2747                   if (gamma_table != NULL)
   2748                   {
   2749                      sp = row;
   2750                      shift = 6;
   2751                      for (i = 0; i < row_width; i++)
   2752                      {
   2753                         if ((png_uint_16)((*sp >> shift) & 0x03)
   2754                             == trans_values->gray)
   2755                         {
   2756                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2757                            *sp |= (png_byte)(background->gray << shift);
   2758                         }
   2759                         else
   2760                         {
   2761                            png_byte p = (png_byte)((*sp >> shift) & 0x03);
   2762                            png_byte g = (png_byte)((gamma_table [p | (p << 2) |
   2763                                (p << 4) | (p << 6)] >> 6) & 0x03);
   2764                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2765                            *sp |= (png_byte)(g << shift);
   2766                         }
   2767                         if (!shift)
   2768                         {
   2769                            shift = 6;
   2770                            sp++;
   2771                         }
   2772                         else
   2773                            shift -= 2;
   2774                      }
   2775                   }
   2776                   else
   2777 #endif
   2778                   {
   2779                      sp = row;
   2780                      shift = 6;
   2781                      for (i = 0; i < row_width; i++)
   2782                      {
   2783                         if ((png_uint_16)((*sp >> shift) & 0x03)
   2784                             == trans_values->gray)
   2785                         {
   2786                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2787                            *sp |= (png_byte)(background->gray << shift);
   2788                         }
   2789                         if (!shift)
   2790                         {
   2791                            shift = 6;
   2792                            sp++;
   2793                         }
   2794                         else
   2795                            shift -= 2;
   2796                      }
   2797                   }
   2798                   break;
   2799                }
   2800                case 4:
   2801                {
   2802 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2803                   if (gamma_table != NULL)
   2804                   {
   2805                      sp = row;
   2806                      shift = 4;
   2807                      for (i = 0; i < row_width; i++)
   2808                      {
   2809                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   2810                             == trans_values->gray)
   2811                         {
   2812                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2813                            *sp |= (png_byte)(background->gray << shift);
   2814                         }
   2815                         else
   2816                         {
   2817                            png_byte p = (png_byte)((*sp >> shift) & 0x0f);
   2818                            png_byte g = (png_byte)((gamma_table[p |
   2819                              (p << 4)] >> 4) & 0x0f);
   2820                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2821                            *sp |= (png_byte)(g << shift);
   2822                         }
   2823                         if (!shift)
   2824                         {
   2825                            shift = 4;
   2826                            sp++;
   2827                         }
   2828                         else
   2829                            shift -= 4;
   2830                      }
   2831                   }
   2832                   else
   2833 #endif
   2834                   {
   2835                      sp = row;
   2836                      shift = 4;
   2837                      for (i = 0; i < row_width; i++)
   2838                      {
   2839                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   2840                             == trans_values->gray)
   2841                         {
   2842                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2843                            *sp |= (png_byte)(background->gray << shift);
   2844                         }
   2845                         if (!shift)
   2846                         {
   2847                            shift = 4;
   2848                            sp++;
   2849                         }
   2850                         else
   2851                            shift -= 4;
   2852                      }
   2853                   }
   2854                   break;
   2855                }
   2856                case 8:
   2857                {
   2858 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2859                   if (gamma_table != NULL)
   2860                   {
   2861                      sp = row;
   2862                      for (i = 0; i < row_width; i++, sp++)
   2863                      {
   2864                         if (*sp == trans_values->gray)
   2865                         {
   2866                            *sp = (png_byte)background->gray;
   2867                         }
   2868                         else
   2869                         {
   2870                            *sp = gamma_table[*sp];
   2871                         }
   2872                      }
   2873                   }
   2874                   else
   2875 #endif
   2876                   {
   2877                      sp = row;
   2878                      for (i = 0; i < row_width; i++, sp++)
   2879                      {
   2880                         if (*sp == trans_values->gray)
   2881                         {
   2882                            *sp = (png_byte)background->gray;
   2883                         }
   2884                      }
   2885                   }
   2886                   break;
   2887                }
   2888                case 16:
   2889                {
   2890 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2891                   if (gamma_16 != NULL)
   2892                   {
   2893                      sp = row;
   2894                      for (i = 0; i < row_width; i++, sp += 2)
   2895                      {
   2896                         png_uint_16 v;
   2897 
   2898                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   2899                         if (v == trans_values->gray)
   2900                         {
   2901                            /* background is already in screen gamma */
   2902                            *sp = (png_byte)((background->gray >> 8) & 0xff);
   2903                            *(sp + 1) = (png_byte)(background->gray & 0xff);
   2904                         }
   2905                         else
   2906                         {
   2907                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   2908                            *sp = (png_byte)((v >> 8) & 0xff);
   2909                            *(sp + 1) = (png_byte)(v & 0xff);
   2910                         }
   2911                      }
   2912                   }
   2913                   else
   2914 #endif
   2915                   {
   2916                      sp = row;
   2917                      for (i = 0; i < row_width; i++, sp += 2)
   2918                      {
   2919                         png_uint_16 v;
   2920 
   2921                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   2922                         if (v == trans_values->gray)
   2923                         {
   2924                            *sp = (png_byte)((background->gray >> 8) & 0xff);
   2925                            *(sp + 1) = (png_byte)(background->gray & 0xff);
   2926                         }
   2927                      }
   2928                   }
   2929                   break;
   2930                }
   2931             }
   2932             break;
   2933          }
   2934          case PNG_COLOR_TYPE_RGB:
   2935          {
   2936             if (row_info->bit_depth == 8)
   2937             {
   2938 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2939                if (gamma_table != NULL)
   2940                {
   2941                   sp = row;
   2942                   for (i = 0; i < row_width; i++, sp += 3)
   2943                   {
   2944                      if (*sp == trans_values->red &&
   2945                         *(sp + 1) == trans_values->green &&
   2946                         *(sp + 2) == trans_values->blue)
   2947                      {
   2948                         *sp = (png_byte)background->red;
   2949                         *(sp + 1) = (png_byte)background->green;
   2950                         *(sp + 2) = (png_byte)background->blue;
   2951                      }
   2952                      else
   2953                      {
   2954                         *sp = gamma_table[*sp];
   2955                         *(sp + 1) = gamma_table[*(sp + 1)];
   2956                         *(sp + 2) = gamma_table[*(sp + 2)];
   2957                      }
   2958                   }
   2959                }
   2960                else
   2961 #endif
   2962                {
   2963                   sp = row;
   2964                   for (i = 0; i < row_width; i++, sp += 3)
   2965                   {
   2966                      if (*sp == trans_values->red &&
   2967                         *(sp + 1) == trans_values->green &&
   2968                         *(sp + 2) == trans_values->blue)
   2969                      {
   2970                         *sp = (png_byte)background->red;
   2971                         *(sp + 1) = (png_byte)background->green;
   2972                         *(sp + 2) = (png_byte)background->blue;
   2973                      }
   2974                   }
   2975                }
   2976             }
   2977             else /* if (row_info->bit_depth == 16) */
   2978             {
   2979 #if defined(PNG_READ_GAMMA_SUPPORTED)
   2980                if (gamma_16 != NULL)
   2981                {
   2982                   sp = row;
   2983                   for (i = 0; i < row_width; i++, sp += 6)
   2984                   {
   2985                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   2986                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   2987                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
   2988                      if (r == trans_values->red && g == trans_values->green &&
   2989                         b == trans_values->blue)
   2990                      {
   2991                         /* background is already in screen gamma */
   2992                         *sp = (png_byte)((background->red >> 8) & 0xff);
   2993                         *(sp + 1) = (png_byte)(background->red & 0xff);
   2994                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
   2995                         *(sp + 3) = (png_byte)(background->green & 0xff);
   2996                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   2997                         *(sp + 5) = (png_byte)(background->blue & 0xff);
   2998                      }
   2999                      else
   3000                      {
   3001                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3002                         *sp = (png_byte)((v >> 8) & 0xff);
   3003                         *(sp + 1) = (png_byte)(v & 0xff);
   3004                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3005                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
   3006                         *(sp + 3) = (png_byte)(v & 0xff);
   3007                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3008                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
   3009                         *(sp + 5) = (png_byte)(v & 0xff);
   3010                      }
   3011                   }
   3012                }
   3013                else
   3014 #endif
   3015                {
   3016                   sp = row;
   3017                   for (i = 0; i < row_width; i++, sp += 6)
   3018                   {
   3019                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
   3020                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3021                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
   3022 
   3023                      if (r == trans_values->red && g == trans_values->green &&
   3024                         b == trans_values->blue)
   3025                      {
   3026                         *sp = (png_byte)((background->red >> 8) & 0xff);
   3027                         *(sp + 1) = (png_byte)(background->red & 0xff);
   3028                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3029                         *(sp + 3) = (png_byte)(background->green & 0xff);
   3030                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3031                         *(sp + 5) = (png_byte)(background->blue & 0xff);
   3032                      }
   3033                   }
   3034                }
   3035             }
   3036             break;
   3037          }
   3038          case PNG_COLOR_TYPE_GRAY_ALPHA:
   3039          {
   3040             if (row_info->bit_depth == 8)
   3041             {
   3042 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3043                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3044                    gamma_table != NULL)
   3045                {
   3046                   sp = row;
   3047                   dp = row;
   3048                   for (i = 0; i < row_width; i++, sp += 2, dp++)
   3049                   {
   3050                      png_uint_16 a = *(sp + 1);
   3051 
   3052                      if (a == 0xff)
   3053                      {
   3054                         *dp = gamma_table[*sp];
   3055                      }
   3056                      else if (a == 0)
   3057                      {
   3058                         /* background is already in screen gamma */
   3059                         *dp = (png_byte)background->gray;
   3060                      }
   3061                      else
   3062                      {
   3063                         png_byte v, w;
   3064 
   3065                         v = gamma_to_1[*sp];
   3066                         png_composite(w, v, a, background_1->gray);
   3067                         *dp = gamma_from_1[w];
   3068                      }
   3069                   }
   3070                }
   3071                else
   3072 #endif
   3073                {
   3074                   sp = row;
   3075                   dp = row;
   3076                   for (i = 0; i < row_width; i++, sp += 2, dp++)
   3077                   {
   3078                      png_byte a = *(sp + 1);
   3079 
   3080                      if (a == 0xff)
   3081                      {
   3082                         *dp = *sp;
   3083                      }
   3084 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3085                      else if (a == 0)
   3086                      {
   3087                         *dp = (png_byte)background->gray;
   3088                      }
   3089                      else
   3090                      {
   3091                         png_composite(*dp, *sp, a, background_1->gray);
   3092                      }
   3093 #else
   3094                      *dp = (png_byte)background->gray;
   3095 #endif
   3096                   }
   3097                }
   3098             }
   3099             else /* if (png_ptr->bit_depth == 16) */
   3100             {
   3101 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3102                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3103                    gamma_16_to_1 != NULL)
   3104                {
   3105                   sp = row;
   3106                   dp = row;
   3107                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
   3108                   {
   3109                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3110 
   3111                      if (a == (png_uint_16)0xffff)
   3112                      {
   3113                         png_uint_16 v;
   3114 
   3115                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3116                         *dp = (png_byte)((v >> 8) & 0xff);
   3117                         *(dp + 1) = (png_byte)(v & 0xff);
   3118                      }
   3119 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3120                      else if (a == 0)
   3121 #else
   3122                      else
   3123 #endif
   3124                      {
   3125                         /* background is already in screen gamma */
   3126                         *dp = (png_byte)((background->gray >> 8) & 0xff);
   3127                         *(dp + 1) = (png_byte)(background->gray & 0xff);
   3128                      }
   3129 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3130                      else
   3131                      {
   3132                         png_uint_16 g, v, w;
   3133 
   3134                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3135                         png_composite_16(v, g, a, background_1->gray);
   3136                         w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
   3137                         *dp = (png_byte)((w >> 8) & 0xff);
   3138                         *(dp + 1) = (png_byte)(w & 0xff);
   3139                      }
   3140 #endif
   3141                   }
   3142                }
   3143                else
   3144 #endif
   3145                {
   3146                   sp = row;
   3147                   dp = row;
   3148                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
   3149                   {
   3150                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3151                      if (a == (png_uint_16)0xffff)
   3152                      {
   3153                         png_memcpy(dp, sp, 2);
   3154                      }
   3155 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3156                      else if (a == 0)
   3157 #else
   3158                      else
   3159 #endif
   3160                      {
   3161                         *dp = (png_byte)((background->gray >> 8) & 0xff);
   3162                         *(dp + 1) = (png_byte)(background->gray & 0xff);
   3163                      }
   3164 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3165                      else
   3166                      {
   3167                         png_uint_16 g, v;
   3168 
   3169                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3170                         png_composite_16(v, g, a, background_1->gray);
   3171                         *dp = (png_byte)((v >> 8) & 0xff);
   3172                         *(dp + 1) = (png_byte)(v & 0xff);
   3173                      }
   3174 #endif
   3175                   }
   3176                }
   3177             }
   3178             break;
   3179          }
   3180          case PNG_COLOR_TYPE_RGB_ALPHA:
   3181          {
   3182             if (row_info->bit_depth == 8)
   3183             {
   3184 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3185                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3186                    gamma_table != NULL)
   3187                {
   3188                   sp = row;
   3189                   dp = row;
   3190                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
   3191                   {
   3192                      png_byte a = *(sp + 3);
   3193 
   3194                      if (a == 0xff)
   3195                      {
   3196                         *dp = gamma_table[*sp];
   3197                         *(dp + 1) = gamma_table[*(sp + 1)];
   3198                         *(dp + 2) = gamma_table[*(sp + 2)];
   3199                      }
   3200                      else if (a == 0)
   3201                      {
   3202                         /* background is already in screen gamma */
   3203                         *dp = (png_byte)background->red;
   3204                         *(dp + 1) = (png_byte)background->green;
   3205                         *(dp + 2) = (png_byte)background->blue;
   3206                      }
   3207                      else
   3208                      {
   3209                         png_byte v, w;
   3210 
   3211                         v = gamma_to_1[*sp];
   3212                         png_composite(w, v, a, background_1->red);
   3213                         *dp = gamma_from_1[w];
   3214                         v = gamma_to_1[*(sp + 1)];
   3215                         png_composite(w, v, a, background_1->green);
   3216                         *(dp + 1) = gamma_from_1[w];
   3217                         v = gamma_to_1[*(sp + 2)];
   3218                         png_composite(w, v, a, background_1->blue);
   3219                         *(dp + 2) = gamma_from_1[w];
   3220                      }
   3221                   }
   3222                }
   3223                else
   3224 #endif
   3225                {
   3226                   sp = row;
   3227                   dp = row;
   3228                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
   3229                   {
   3230                      png_byte a = *(sp + 3);
   3231 
   3232                      if (a == 0xff)
   3233                      {
   3234                         *dp = *sp;
   3235                         *(dp + 1) = *(sp + 1);
   3236                         *(dp + 2) = *(sp + 2);
   3237                      }
   3238                      else if (a == 0)
   3239                      {
   3240                         *dp = (png_byte)background->red;
   3241                         *(dp + 1) = (png_byte)background->green;
   3242                         *(dp + 2) = (png_byte)background->blue;
   3243                      }
   3244                      else
   3245                      {
   3246                         png_composite(*dp, *sp, a, background->red);
   3247                         png_composite(*(dp + 1), *(sp + 1), a,
   3248                            background->green);
   3249                         png_composite(*(dp + 2), *(sp + 2), a,
   3250                            background->blue);
   3251                      }
   3252                   }
   3253                }
   3254             }
   3255             else /* if (row_info->bit_depth == 16) */
   3256             {
   3257 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3258                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3259                    gamma_16_to_1 != NULL)
   3260                {
   3261                   sp = row;
   3262                   dp = row;
   3263                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
   3264                   {
   3265                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3266                          << 8) + (png_uint_16)(*(sp + 7)));
   3267                      if (a == (png_uint_16)0xffff)
   3268                      {
   3269                         png_uint_16 v;
   3270 
   3271                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3272                         *dp = (png_byte)((v >> 8) & 0xff);
   3273                         *(dp + 1) = (png_byte)(v & 0xff);
   3274                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3275                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
   3276                         *(dp + 3) = (png_byte)(v & 0xff);
   3277                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3278                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
   3279                         *(dp + 5) = (png_byte)(v & 0xff);
   3280                      }
   3281                      else if (a == 0)
   3282                      {
   3283                         /* background is already in screen gamma */
   3284                         *dp = (png_byte)((background->red >> 8) & 0xff);
   3285                         *(dp + 1) = (png_byte)(background->red & 0xff);
   3286                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3287                         *(dp + 3) = (png_byte)(background->green & 0xff);
   3288                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3289                         *(dp + 5) = (png_byte)(background->blue & 0xff);
   3290                      }
   3291                      else
   3292                      {
   3293                         png_uint_16 v, w, x;
   3294 
   3295                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3296                         png_composite_16(w, v, a, background_1->red);
   3297                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
   3298                         *dp = (png_byte)((x >> 8) & 0xff);
   3299                         *(dp + 1) = (png_byte)(x & 0xff);
   3300                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3301                         png_composite_16(w, v, a, background_1->green);
   3302                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
   3303                         *(dp + 2) = (png_byte)((x >> 8) & 0xff);
   3304                         *(dp + 3) = (png_byte)(x & 0xff);
   3305                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3306                         png_composite_16(w, v, a, background_1->blue);
   3307                         x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
   3308                         *(dp + 4) = (png_byte)((x >> 8) & 0xff);
   3309                         *(dp + 5) = (png_byte)(x & 0xff);
   3310                      }
   3311                   }
   3312                }
   3313                else
   3314 #endif
   3315                {
   3316                   sp = row;
   3317                   dp = row;
   3318                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
   3319                   {
   3320                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3321                         << 8) + (png_uint_16)(*(sp + 7)));
   3322                      if (a == (png_uint_16)0xffff)
   3323                      {
   3324                         png_memcpy(dp, sp, 6);
   3325                      }
   3326                      else if (a == 0)
   3327                      {
   3328                         *dp = (png_byte)((background->red >> 8) & 0xff);
   3329                         *(dp + 1) = (png_byte)(background->red & 0xff);
   3330                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3331                         *(dp + 3) = (png_byte)(background->green & 0xff);
   3332                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3333                         *(dp + 5) = (png_byte)(background->blue & 0xff);
   3334                      }
   3335                      else
   3336                      {
   3337                         png_uint_16 v;
   3338 
   3339                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3340                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
   3341                             + *(sp + 3));
   3342                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
   3343                             + *(sp + 5));
   3344 
   3345                         png_composite_16(v, r, a, background->red);
   3346                         *dp = (png_byte)((v >> 8) & 0xff);
   3347                         *(dp + 1) = (png_byte)(v & 0xff);
   3348                         png_composite_16(v, g, a, background->green);
   3349                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
   3350                         *(dp + 3) = (png_byte)(v & 0xff);
   3351                         png_composite_16(v, b, a, background->blue);
   3352                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
   3353                         *(dp + 5) = (png_byte)(v & 0xff);
   3354                      }
   3355                   }
   3356                }
   3357             }
   3358             break;
   3359          }
   3360       }
   3361 
   3362       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
   3363       {
   3364          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
   3365          row_info->channels--;
   3366          row_info->pixel_depth = (png_byte)(row_info->channels *
   3367             row_info->bit_depth);
   3368          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   3369       }
   3370    }
   3371 }
   3372 #endif
   3373 
   3374 #if defined(PNG_READ_GAMMA_SUPPORTED)
   3375 /* Gamma correct the image, avoiding the alpha channel.  Make sure
   3376  * you do this after you deal with the transparency issue on grayscale
   3377  * or RGB images. If your bit depth is 8, use gamma_table, if it
   3378  * is 16, use gamma_16_table and gamma_shift.  Build these with
   3379  * build_gamma_table().
   3380  */
   3381 void /* PRIVATE */
   3382 png_do_gamma(png_row_infop row_info, png_bytep row,
   3383    png_bytep gamma_table, png_uint_16pp gamma_16_table,
   3384    int gamma_shift)
   3385 {
   3386    png_bytep sp;
   3387    png_uint_32 i;
   3388    png_uint_32 row_width=row_info->width;
   3389 
   3390    png_debug(1, "in png_do_gamma\n");
   3391    if (
   3392 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   3393        row != NULL && row_info != NULL &&
   3394 #endif
   3395        ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
   3396         (row_info->bit_depth == 16 && gamma_16_table != NULL)))
   3397    {
   3398       switch (row_info->color_type)
   3399       {
   3400          case PNG_COLOR_TYPE_RGB:
   3401          {
   3402             if (row_info->bit_depth == 8)
   3403             {
   3404                sp = row;
   3405                for (i = 0; i < row_width; i++)
   3406                {
   3407                   *sp = gamma_table[*sp];
   3408                   sp++;
   3409                   *sp = gamma_table[*sp];
   3410                   sp++;
   3411                   *sp = gamma_table[*sp];
   3412                   sp++;
   3413                }
   3414             }
   3415             else /* if (row_info->bit_depth == 16) */
   3416             {
   3417                sp = row;
   3418                for (i = 0; i < row_width; i++)
   3419                {
   3420                   png_uint_16 v;
   3421 
   3422                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3423                   *sp = (png_byte)((v >> 8) & 0xff);
   3424                   *(sp + 1) = (png_byte)(v & 0xff);
   3425                   sp += 2;
   3426                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3427                   *sp = (png_byte)((v >> 8) & 0xff);
   3428                   *(sp + 1) = (png_byte)(v & 0xff);
   3429                   sp += 2;
   3430                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3431                   *sp = (png_byte)((v >> 8) & 0xff);
   3432                   *(sp + 1) = (png_byte)(v & 0xff);
   3433                   sp += 2;
   3434                }
   3435             }
   3436             break;
   3437          }
   3438          case PNG_COLOR_TYPE_RGB_ALPHA:
   3439          {
   3440             if (row_info->bit_depth == 8)
   3441             {
   3442                sp = row;
   3443                for (i = 0; i < row_width; i++)
   3444                {
   3445                   *sp = gamma_table[*sp];
   3446                   sp++;
   3447                   *sp = gamma_table[*sp];
   3448                   sp++;
   3449                   *sp = gamma_table[*sp];
   3450                   sp++;
   3451                   sp++;
   3452                }
   3453             }
   3454             else /* if (row_info->bit_depth == 16) */
   3455             {
   3456                sp = row;
   3457                for (i = 0; i < row_width; i++)
   3458                {
   3459                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3460                   *sp = (png_byte)((v >> 8) & 0xff);
   3461                   *(sp + 1) = (png_byte)(v & 0xff);
   3462                   sp += 2;
   3463                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3464                   *sp = (png_byte)((v >> 8) & 0xff);
   3465                   *(sp + 1) = (png_byte)(v & 0xff);
   3466                   sp += 2;
   3467                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3468                   *sp = (png_byte)((v >> 8) & 0xff);
   3469                   *(sp + 1) = (png_byte)(v & 0xff);
   3470                   sp += 4;
   3471                }
   3472             }
   3473             break;
   3474          }
   3475          case PNG_COLOR_TYPE_GRAY_ALPHA:
   3476          {
   3477             if (row_info->bit_depth == 8)
   3478             {
   3479                sp = row;
   3480                for (i = 0; i < row_width; i++)
   3481                {
   3482                   *sp = gamma_table[*sp];
   3483                   sp += 2;
   3484                }
   3485             }
   3486             else /* if (row_info->bit_depth == 16) */
   3487             {
   3488                sp = row;
   3489                for (i = 0; i < row_width; i++)
   3490                {
   3491                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3492                   *sp = (png_byte)((v >> 8) & 0xff);
   3493                   *(sp + 1) = (png_byte)(v & 0xff);
   3494                   sp += 4;
   3495                }
   3496             }
   3497             break;
   3498          }
   3499          case PNG_COLOR_TYPE_GRAY:
   3500          {
   3501             if (row_info->bit_depth == 2)
   3502             {
   3503                sp = row;
   3504                for (i = 0; i < row_width; i += 4)
   3505                {
   3506                   int a = *sp & 0xc0;
   3507                   int b = *sp & 0x30;
   3508                   int c = *sp & 0x0c;
   3509                   int d = *sp & 0x03;
   3510 
   3511                   *sp = (png_byte)(
   3512                         ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
   3513                         ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
   3514                         ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
   3515                         ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
   3516                   sp++;
   3517                }
   3518             }
   3519             if (row_info->bit_depth == 4)
   3520             {
   3521                sp = row;
   3522                for (i = 0; i < row_width; i += 2)
   3523                {
   3524                   int msb = *sp & 0xf0;
   3525                   int lsb = *sp & 0x0f;
   3526 
   3527                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
   3528                           | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
   3529                   sp++;
   3530                }
   3531             }
   3532             else if (row_info->bit_depth == 8)
   3533             {
   3534                sp = row;
   3535                for (i = 0; i < row_width; i++)
   3536                {
   3537                   *sp = gamma_table[*sp];
   3538                   sp++;
   3539                }
   3540             }
   3541             else if (row_info->bit_depth == 16)
   3542             {
   3543                sp = row;
   3544                for (i = 0; i < row_width; i++)
   3545                {
   3546                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3547                   *sp = (png_byte)((v >> 8) & 0xff);
   3548                   *(sp + 1) = (png_byte)(v & 0xff);
   3549                   sp += 2;
   3550                }
   3551             }
   3552             break;
   3553          }
   3554       }
   3555    }
   3556 }
   3557 #endif
   3558 
   3559 #if defined(PNG_READ_EXPAND_SUPPORTED)
   3560 /* Expands a palette row to an RGB or RGBA row depending
   3561  * upon whether you supply trans and num_trans.
   3562  */
   3563 void /* PRIVATE */
   3564 png_do_expand_palette(png_row_infop row_info, png_bytep row,
   3565    png_colorp palette, png_bytep trans, int num_trans)
   3566 {
   3567    int shift, value;
   3568    png_bytep sp, dp;
   3569    png_uint_32 i;
   3570    png_uint_32 row_width=row_info->width;
   3571 
   3572    png_debug(1, "in png_do_expand_palette\n");
   3573    if (
   3574 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   3575        row != NULL && row_info != NULL &&
   3576 #endif
   3577        row_info->color_type == PNG_COLOR_TYPE_PALETTE)
   3578    {
   3579       if (row_info->bit_depth < 8)
   3580       {
   3581          switch (row_info->bit_depth)
   3582          {
   3583             case 1:
   3584             {
   3585                sp = row + (png_size_t)((row_width - 1) >> 3);
   3586                dp = row + (png_size_t)row_width - 1;
   3587                shift = 7 - (int)((row_width + 7) & 0x07);
   3588                for (i = 0; i < row_width; i++)
   3589                {
   3590                   if ((*sp >> shift) & 0x01)
   3591                      *dp = 1;
   3592                   else
   3593                      *dp = 0;
   3594                   if (shift == 7)
   3595                   {
   3596                      shift = 0;
   3597                      sp--;
   3598                   }
   3599                   else
   3600                      shift++;
   3601 
   3602                   dp--;
   3603                }
   3604                break;
   3605             }
   3606             case 2:
   3607             {
   3608                sp = row + (png_size_t)((row_width - 1) >> 2);
   3609                dp = row + (png_size_t)row_width - 1;
   3610                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   3611                for (i = 0; i < row_width; i++)
   3612                {
   3613                   value = (*sp >> shift) & 0x03;
   3614                   *dp = (png_byte)value;
   3615                   if (shift == 6)
   3616                   {
   3617                      shift = 0;
   3618                      sp--;
   3619                   }
   3620                   else
   3621                      shift += 2;
   3622 
   3623                   dp--;
   3624                }
   3625                break;
   3626             }
   3627             case 4:
   3628             {
   3629                sp = row + (png_size_t)((row_width - 1) >> 1);
   3630                dp = row + (png_size_t)row_width - 1;
   3631                shift = (int)((row_width & 0x01) << 2);
   3632                for (i = 0; i < row_width; i++)
   3633                {
   3634                   value = (*sp >> shift) & 0x0f;
   3635                   *dp = (png_byte)value;
   3636                   if (shift == 4)
   3637                   {
   3638                      shift = 0;
   3639                      sp--;
   3640                   }
   3641                   else
   3642                      shift += 4;
   3643 
   3644                   dp--;
   3645                }
   3646                break;
   3647             }
   3648          }
   3649          row_info->bit_depth = 8;
   3650          row_info->pixel_depth = 8;
   3651          row_info->rowbytes = row_width;
   3652       }
   3653       switch (row_info->bit_depth)
   3654       {
   3655          case 8:
   3656          {
   3657             if (trans != NULL)
   3658             {
   3659                sp = row + (png_size_t)row_width - 1;
   3660                dp = row + (png_size_t)(row_width << 2) - 1;
   3661 
   3662                for (i = 0; i < row_width; i++)
   3663                {
   3664                   if ((int)(*sp) >= num_trans)
   3665                      *dp-- = 0xff;
   3666                   else
   3667                      *dp-- = trans[*sp];
   3668                   *dp-- = palette[*sp].blue;
   3669                   *dp-- = palette[*sp].green;
   3670                   *dp-- = palette[*sp].red;
   3671                   sp--;
   3672                }
   3673                row_info->bit_depth = 8;
   3674                row_info->pixel_depth = 32;
   3675                row_info->rowbytes = row_width * 4;
   3676                row_info->color_type = 6;
   3677                row_info->channels = 4;
   3678             }
   3679             else
   3680             {
   3681                sp = row + (png_size_t)row_width - 1;
   3682                dp = row + (png_size_t)(row_width * 3) - 1;
   3683 
   3684                for (i = 0; i < row_width; i++)
   3685                {
   3686                   *dp-- = palette[*sp].blue;
   3687                   *dp-- = palette[*sp].green;
   3688                   *dp-- = palette[*sp].red;
   3689                   sp--;
   3690                }
   3691                row_info->bit_depth = 8;
   3692                row_info->pixel_depth = 24;
   3693                row_info->rowbytes = row_width * 3;
   3694                row_info->color_type = 2;
   3695                row_info->channels = 3;
   3696             }
   3697             break;
   3698          }
   3699       }
   3700    }
   3701 }
   3702 
   3703 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
   3704  * expanded transparency value is supplied, an alpha channel is built.
   3705  */
   3706 void /* PRIVATE */
   3707 png_do_expand(png_row_infop row_info, png_bytep row,
   3708    png_color_16p trans_value)
   3709 {
   3710    int shift, value;
   3711    png_bytep sp, dp;
   3712    png_uint_32 i;
   3713    png_uint_32 row_width=row_info->width;
   3714 
   3715    png_debug(1, "in png_do_expand\n");
   3716 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   3717    if (row != NULL && row_info != NULL)
   3718 #endif
   3719    {
   3720       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   3721       {
   3722          png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
   3723 
   3724          if (row_info->bit_depth < 8)
   3725          {
   3726             switch (row_info->bit_depth)
   3727             {
   3728                case 1:
   3729                {
   3730                   gray = (png_uint_16)((gray&0x01)*0xff);
   3731                   sp = row + (png_size_t)((row_width - 1) >> 3);
   3732                   dp = row + (png_size_t)row_width - 1;
   3733                   shift = 7 - (int)((row_width + 7) & 0x07);
   3734                   for (i = 0; i < row_width; i++)
   3735                   {
   3736                      if ((*sp >> shift) & 0x01)
   3737                         *dp = 0xff;
   3738                      else
   3739                         *dp = 0;
   3740                      if (shift == 7)
   3741                      {
   3742                         shift = 0;
   3743                         sp--;
   3744                      }
   3745                      else
   3746                         shift++;
   3747 
   3748                      dp--;
   3749                   }
   3750                   break;
   3751                }
   3752                case 2:
   3753                {
   3754                   gray = (png_uint_16)((gray&0x03)*0x55);
   3755                   sp = row + (png_size_t)((row_width - 1) >> 2);
   3756                   dp = row + (png_size_t)row_width - 1;
   3757                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   3758                   for (i = 0; i < row_width; i++)
   3759                   {
   3760                      value = (*sp >> shift) & 0x03;
   3761                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
   3762                         (value << 6));
   3763                      if (shift == 6)
   3764                      {
   3765                         shift = 0;
   3766                         sp--;
   3767                      }
   3768                      else
   3769                         shift += 2;
   3770 
   3771                      dp--;
   3772                   }
   3773                   break;
   3774                }
   3775                case 4:
   3776                {
   3777                   gray = (png_uint_16)((gray&0x0f)*0x11);
   3778                   sp = row + (png_size_t)((row_width - 1) >> 1);
   3779                   dp = row + (png_size_t)row_width - 1;
   3780                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   3781                   for (i = 0; i < row_width; i++)
   3782                   {
   3783                      value = (*sp >> shift) & 0x0f;
   3784                      *dp = (png_byte)(value | (value << 4));
   3785                      if (shift == 4)
   3786                      {
   3787                         shift = 0;
   3788                         sp--;
   3789                      }
   3790                      else
   3791                         shift = 4;
   3792 
   3793                      dp--;
   3794                   }
   3795                   break;
   3796                }
   3797             }
   3798             row_info->bit_depth = 8;
   3799             row_info->pixel_depth = 8;
   3800             row_info->rowbytes = row_width;
   3801          }
   3802 
   3803          if (trans_value != NULL)
   3804          {
   3805             if (row_info->bit_depth == 8)
   3806             {
   3807                gray = gray & 0xff;
   3808                sp = row + (png_size_t)row_width - 1;
   3809                dp = row + (png_size_t)(row_width << 1) - 1;
   3810                for (i = 0; i < row_width; i++)
   3811                {
   3812                   if (*sp == gray)
   3813                      *dp-- = 0;
   3814                   else
   3815                      *dp-- = 0xff;
   3816                   *dp-- = *sp--;
   3817                }
   3818             }
   3819             else if (row_info->bit_depth == 16)
   3820             {
   3821                png_byte gray_high = (gray >> 8) & 0xff;
   3822                png_byte gray_low = gray & 0xff;
   3823                sp = row + row_info->rowbytes - 1;
   3824                dp = row + (row_info->rowbytes << 1) - 1;
   3825                for (i = 0; i < row_width; i++)
   3826                {
   3827                   if (*(sp-1) == gray_high && *(sp) == gray_low)
   3828                   {
   3829                      *dp-- = 0;
   3830                      *dp-- = 0;
   3831                   }
   3832                   else
   3833                   {
   3834                      *dp-- = 0xff;
   3835                      *dp-- = 0xff;
   3836                   }
   3837                   *dp-- = *sp--;
   3838                   *dp-- = *sp--;
   3839                }
   3840             }
   3841             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
   3842             row_info->channels = 2;
   3843             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
   3844             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
   3845                row_width);
   3846          }
   3847       }
   3848       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
   3849       {
   3850          if (row_info->bit_depth == 8)
   3851          {
   3852             png_byte red = trans_value->red & 0xff;
   3853             png_byte green = trans_value->green & 0xff;
   3854             png_byte blue = trans_value->blue & 0xff;
   3855             sp = row + (png_size_t)row_info->rowbytes - 1;
   3856             dp = row + (png_size_t)(row_width << 2) - 1;
   3857             for (i = 0; i < row_width; i++)
   3858             {
   3859                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
   3860                   *dp-- = 0;
   3861                else
   3862                   *dp-- = 0xff;
   3863                *dp-- = *sp--;
   3864                *dp-- = *sp--;
   3865                *dp-- = *sp--;
   3866             }
   3867          }
   3868          else if (row_info->bit_depth == 16)
   3869          {
   3870             png_byte red_high = (trans_value->red > 8) & 0xff;
   3871             png_byte green_high = (trans_value->green > 8) & 0xff;
   3872             png_byte blue_high = (trans_value->blue > 8) & 0xff;
   3873             png_byte red_low = trans_value->red & 0xff;
   3874             png_byte green_low = trans_value->green & 0xff;
   3875             png_byte blue_low = trans_value->blue & 0xff;
   3876             sp = row + row_info->rowbytes - 1;
   3877             dp = row + (png_size_t)(row_width << 3) - 1;
   3878             for (i = 0; i < row_width; i++)
   3879             {
   3880                if (*(sp - 5) == red_high &&
   3881                   *(sp - 4) == red_low &&
   3882                   *(sp - 3) == green_high &&
   3883                   *(sp - 2) == green_low &&
   3884                   *(sp - 1) == blue_high &&
   3885                   *(sp    ) == blue_low)
   3886                {
   3887                   *dp-- = 0;
   3888                   *dp-- = 0;
   3889                }
   3890                else
   3891                {
   3892                   *dp-- = 0xff;
   3893                   *dp-- = 0xff;
   3894                }
   3895                *dp-- = *sp--;
   3896                *dp-- = *sp--;
   3897                *dp-- = *sp--;
   3898                *dp-- = *sp--;
   3899                *dp-- = *sp--;
   3900                *dp-- = *sp--;
   3901             }
   3902          }
   3903          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   3904          row_info->channels = 4;
   3905          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
   3906          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   3907       }
   3908    }
   3909 }
   3910 #endif
   3911 
   3912 #if defined(PNG_READ_DITHER_SUPPORTED)
   3913 void /* PRIVATE */
   3914 png_do_dither(png_row_infop row_info, png_bytep row,
   3915     png_bytep palette_lookup, png_bytep dither_lookup)
   3916 {
   3917    png_bytep sp, dp;
   3918    png_uint_32 i;
   3919    png_uint_32 row_width=row_info->width;
   3920 
   3921    png_debug(1, "in png_do_dither\n");
   3922 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   3923    if (row != NULL && row_info != NULL)
   3924 #endif
   3925    {
   3926       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
   3927          palette_lookup && row_info->bit_depth == 8)
   3928       {
   3929          int r, g, b, p;
   3930          sp = row;
   3931          dp = row;
   3932          for (i = 0; i < row_width; i++)
   3933          {
   3934             r = *sp++;
   3935             g = *sp++;
   3936             b = *sp++;
   3937 
   3938             /* this looks real messy, but the compiler will reduce
   3939                it down to a reasonable formula.  For example, with
   3940                5 bits per color, we get:
   3941                p = (((r >> 3) & 0x1f) << 10) |
   3942                   (((g >> 3) & 0x1f) << 5) |
   3943                   ((b >> 3) & 0x1f);
   3944                */
   3945             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
   3946                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
   3947                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
   3948                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
   3949                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
   3950                (PNG_DITHER_BLUE_BITS)) |
   3951                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
   3952                ((1 << PNG_DITHER_BLUE_BITS) - 1));
   3953 
   3954             *dp++ = palette_lookup[p];
   3955          }
   3956          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   3957          row_info->channels = 1;
   3958          row_info->pixel_depth = row_info->bit_depth;
   3959          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   3960       }
   3961       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
   3962          palette_lookup != NULL && row_info->bit_depth == 8)
   3963       {
   3964          int r, g, b, p;
   3965          sp = row;
   3966          dp = row;
   3967          for (i = 0; i < row_width; i++)
   3968          {
   3969             r = *sp++;
   3970             g = *sp++;
   3971             b = *sp++;
   3972             sp++;
   3973 
   3974             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
   3975                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
   3976                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
   3977                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
   3978                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
   3979                (PNG_DITHER_BLUE_BITS)) |
   3980                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
   3981                ((1 << PNG_DITHER_BLUE_BITS) - 1));
   3982 
   3983             *dp++ = palette_lookup[p];
   3984          }
   3985          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   3986          row_info->channels = 1;
   3987          row_info->pixel_depth = row_info->bit_depth;
   3988          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
   3989       }
   3990       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
   3991          dither_lookup && row_info->bit_depth == 8)
   3992       {
   3993          sp = row;
   3994          for (i = 0; i < row_width; i++, sp++)
   3995          {
   3996             *sp = dither_lookup[*sp];
   3997          }
   3998       }
   3999    }
   4000 }
   4001 #endif
   4002 
   4003 #ifdef PNG_FLOATING_POINT_SUPPORTED
   4004 #if defined(PNG_READ_GAMMA_SUPPORTED)
   4005 static PNG_CONST int png_gamma_shift[] =
   4006    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
   4007 
   4008 /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
   4009  * tables, we don't make a full table if we are reducing to 8-bit in
   4010  * the future.  Note also how the gamma_16 tables are segmented so that
   4011  * we don't need to allocate > 64K chunks for a full 16-bit table.
   4012  */
   4013 void /* PRIVATE */
   4014 png_build_gamma_table(png_structp png_ptr)
   4015 {
   4016   png_debug(1, "in png_build_gamma_table\n");
   4017 
   4018   if (png_ptr->bit_depth <= 8)
   4019   {
   4020      int i;
   4021      double g;
   4022 
   4023      if (png_ptr->screen_gamma > .000001)
   4024         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
   4025      else
   4026         g = 1.0;
   4027 
   4028      png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
   4029         (png_uint_32)256);
   4030 
   4031      for (i = 0; i < 256; i++)
   4032      {
   4033         png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
   4034            g) * 255.0 + .5);
   4035      }
   4036 
   4037 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
   4038    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   4039      if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
   4040      {
   4041 
   4042         g = 1.0 / (png_ptr->gamma);
   4043 
   4044         png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
   4045            (png_uint_32)256);
   4046 
   4047         for (i = 0; i < 256; i++)
   4048         {
   4049            png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
   4050               g) * 255.0 + .5);
   4051         }
   4052 
   4053 
   4054         png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
   4055            (png_uint_32)256);
   4056 
   4057         if(png_ptr->screen_gamma > 0.000001)
   4058            g = 1.0 / png_ptr->screen_gamma;
   4059         else
   4060            g = png_ptr->gamma;   /* probably doing rgb_to_gray */
   4061 
   4062         for (i = 0; i < 256; i++)
   4063         {
   4064            png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
   4065               g) * 255.0 + .5);
   4066 
   4067         }
   4068      }
   4069 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
   4070   }
   4071   else
   4072   {
   4073      double g;
   4074      int i, j, shift, num;
   4075      int sig_bit;
   4076      png_uint_32 ig;
   4077 
   4078      if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
   4079      {
   4080         sig_bit = (int)png_ptr->sig_bit.red;
   4081         if ((int)png_ptr->sig_bit.green > sig_bit)
   4082            sig_bit = png_ptr->sig_bit.green;
   4083         if ((int)png_ptr->sig_bit.blue > sig_bit)
   4084            sig_bit = png_ptr->sig_bit.blue;
   4085      }
   4086      else
   4087      {
   4088         sig_bit = (int)png_ptr->sig_bit.gray;
   4089      }
   4090 
   4091      if (sig_bit > 0)
   4092         shift = 16 - sig_bit;
   4093      else
   4094         shift = 0;
   4095 
   4096      if (png_ptr->transformations & PNG_16_TO_8)
   4097      {
   4098         if (shift < (16 - PNG_MAX_GAMMA_8))
   4099            shift = (16 - PNG_MAX_GAMMA_8);
   4100      }
   4101 
   4102      if (shift > 8)
   4103         shift = 8;
   4104      if (shift < 0)
   4105         shift = 0;
   4106 
   4107      png_ptr->gamma_shift = (png_byte)shift;
   4108 
   4109      num = (1 << (8 - shift));
   4110 
   4111      if (png_ptr->screen_gamma > .000001)
   4112         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
   4113      else
   4114         g = 1.0;
   4115 
   4116      png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
   4117         (png_uint_32)(num * png_sizeof (png_uint_16p)));
   4118 
   4119      if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
   4120      {
   4121         double fin, fout;
   4122         png_uint_32 last, max;
   4123 
   4124         for (i = 0; i < num; i++)
   4125         {
   4126            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
   4127               (png_uint_32)(256 * png_sizeof (png_uint_16)));
   4128         }
   4129 
   4130         g = 1.0 / g;
   4131         last = 0;
   4132         for (i = 0; i < 256; i++)
   4133         {
   4134            fout = ((double)i + 0.5) / 256.0;
   4135            fin = pow(fout, g);
   4136            max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
   4137            while (last <= max)
   4138            {
   4139               png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
   4140                  [(int)(last >> (8 - shift))] = (png_uint_16)(
   4141                  (png_uint_16)i | ((png_uint_16)i << 8));
   4142               last++;
   4143            }
   4144         }
   4145         while (last < ((png_uint_32)num << 8))
   4146         {
   4147            png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
   4148               [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
   4149            last++;
   4150         }
   4151      }
   4152      else
   4153      {
   4154         for (i = 0; i < num; i++)
   4155         {
   4156            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
   4157               (png_uint_32)(256 * png_sizeof (png_uint_16)));
   4158 
   4159            ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
   4160            for (j = 0; j < 256; j++)
   4161            {
   4162               png_ptr->gamma_16_table[i][j] =
   4163                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4164                     65535.0, g) * 65535.0 + .5);
   4165            }
   4166         }
   4167      }
   4168 
   4169 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
   4170    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   4171      if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
   4172      {
   4173 
   4174         g = 1.0 / (png_ptr->gamma);
   4175 
   4176         png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
   4177            (png_uint_32)(num * png_sizeof (png_uint_16p )));
   4178 
   4179         for (i = 0; i < num; i++)
   4180         {
   4181            png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
   4182               (png_uint_32)(256 * png_sizeof (png_uint_16)));
   4183 
   4184            ig = (((png_uint_32)i *
   4185               (png_uint_32)png_gamma_shift[shift]) >> 4);
   4186            for (j = 0; j < 256; j++)
   4187            {
   4188               png_ptr->gamma_16_to_1[i][j] =
   4189                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4190                     65535.0, g) * 65535.0 + .5);
   4191            }
   4192         }
   4193 
   4194         if(png_ptr->screen_gamma > 0.000001)
   4195            g = 1.0 / png_ptr->screen_gamma;
   4196         else
   4197            g = png_ptr->gamma;   /* probably doing rgb_to_gray */
   4198 
   4199         png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
   4200            (png_uint_32)(num * png_sizeof (png_uint_16p)));
   4201 
   4202         for (i = 0; i < num; i++)
   4203         {
   4204            png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
   4205               (png_uint_32)(256 * png_sizeof (png_uint_16)));
   4206 
   4207            ig = (((png_uint_32)i *
   4208               (png_uint_32)png_gamma_shift[shift]) >> 4);
   4209            for (j = 0; j < 256; j++)
   4210            {
   4211               png_ptr->gamma_16_from_1[i][j] =
   4212                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4213                     65535.0, g) * 65535.0 + .5);
   4214            }
   4215         }
   4216      }
   4217 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
   4218   }
   4219 }
   4220 #endif
   4221 /* To do: install integer version of png_build_gamma_table here */
   4222 #endif
   4223 
   4224 #if defined(PNG_MNG_FEATURES_SUPPORTED)
   4225 /* undoes intrapixel differencing  */
   4226 void /* PRIVATE */
   4227 png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
   4228 {
   4229    png_debug(1, "in png_do_read_intrapixel\n");
   4230    if (
   4231 #if defined(PNG_USELESS_TESTS_SUPPORTED)
   4232        row != NULL && row_info != NULL &&
   4233 #endif
   4234        (row_info->color_type & PNG_COLOR_MASK_COLOR))
   4235    {
   4236       int bytes_per_pixel;
   4237       png_uint_32 row_width = row_info->width;
   4238       if (row_info->bit_depth == 8)
   4239       {
   4240          png_bytep rp;
   4241          png_uint_32 i;
   4242 
   4243          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   4244             bytes_per_pixel = 3;
   4245          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   4246             bytes_per_pixel = 4;
   4247          else
   4248             return;
   4249 
   4250          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
   4251          {
   4252             *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
   4253             *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
   4254          }
   4255       }
   4256       else if (row_info->bit_depth == 16)
   4257       {
   4258          png_bytep rp;
   4259          png_uint_32 i;
   4260 
   4261          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   4262             bytes_per_pixel = 6;
   4263          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   4264             bytes_per_pixel = 8;
   4265          else
   4266             return;
   4267 
   4268          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
   4269          {
   4270             png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
   4271             png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
   4272             png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
   4273             png_uint_32 red  = (png_uint_32)((s0+s1+65536L) & 0xffffL);
   4274             png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
   4275             *(rp  ) = (png_byte)((red >> 8) & 0xff);
   4276             *(rp+1) = (png_byte)(red & 0xff);
   4277             *(rp+4) = (png_byte)((blue >> 8) & 0xff);
   4278             *(rp+5) = (png_byte)(blue & 0xff);
   4279          }
   4280       }
   4281    }
   4282 }
   4283 #endif /* PNG_MNG_FEATURES_SUPPORTED */
   4284 #endif /* PNG_READ_SUPPORTED */
   4285