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