polaroid-pp

Schlieren and contour plot tool
git clone https://git.0xfab.ch/polaroid-pp.git
Log | Files | Refs | Submodules | README | LICENSE

pngrtran.c (148417B)


      1 
      2 /* pngrtran.c - transforms the data in a row for PNG readers
      3  *
      4  * Last changed in libpng 1.2.51 [February 6, 2014]
      5  * Copyright (c) 1998-2014 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       {
    921         k=1; /* Partial transparency is present */
    922         break;
    923       }
    924     }
    925     if (k == 0)
    926       png_ptr->transformations &= ~PNG_GAMMA;
    927    }
    928 
    929    if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
    930         png_ptr->gamma != 0.0)
    931    {
    932       png_build_gamma_table(png_ptr);
    933 
    934 #ifdef PNG_READ_BACKGROUND_SUPPORTED
    935       if (png_ptr->transformations & PNG_BACKGROUND)
    936       {
    937          if (color_type == PNG_COLOR_TYPE_PALETTE)
    938          {
    939            /* Could skip if no transparency */
    940             png_color back, back_1;
    941             png_colorp palette = png_ptr->palette;
    942             int num_palette = png_ptr->num_palette;
    943             int i;
    944             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
    945             {
    946                back.red = png_ptr->gamma_table[png_ptr->background.red];
    947                back.green = png_ptr->gamma_table[png_ptr->background.green];
    948                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
    949 
    950                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
    951                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
    952                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
    953             }
    954             else
    955             {
    956                double g, gs;
    957 
    958                switch (png_ptr->background_gamma_type)
    959                {
    960                   case PNG_BACKGROUND_GAMMA_SCREEN:
    961                      g = (png_ptr->screen_gamma);
    962                      gs = 1.0;
    963                      break;
    964 
    965                   case PNG_BACKGROUND_GAMMA_FILE:
    966                      g = 1.0 / (png_ptr->gamma);
    967                      gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
    968                      break;
    969 
    970                   case PNG_BACKGROUND_GAMMA_UNIQUE:
    971                      g = 1.0 / (png_ptr->background_gamma);
    972                      gs = 1.0 / (png_ptr->background_gamma *
    973                                  png_ptr->screen_gamma);
    974                      break;
    975                   default:
    976                      g = 1.0;    /* back_1 */
    977                      gs = 1.0;   /* back */
    978                }
    979 
    980                if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
    981                {
    982                   back.red   = (png_byte)png_ptr->background.red;
    983                   back.green = (png_byte)png_ptr->background.green;
    984                   back.blue  = (png_byte)png_ptr->background.blue;
    985                }
    986                else
    987                {
    988                   back.red = (png_byte)(pow(
    989                      (double)png_ptr->background.red/255, gs) * 255.0 + .5);
    990                   back.green = (png_byte)(pow(
    991                      (double)png_ptr->background.green/255, gs) * 255.0
    992                          + .5);
    993                   back.blue = (png_byte)(pow(
    994                      (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
    995                }
    996 
    997                back_1.red = (png_byte)(pow(
    998                   (double)png_ptr->background.red/255, g) * 255.0 + .5);
    999                back_1.green = (png_byte)(pow(
   1000                   (double)png_ptr->background.green/255, g) * 255.0 + .5);
   1001                back_1.blue = (png_byte)(pow(
   1002                   (double)png_ptr->background.blue/255, g) * 255.0 + .5);
   1003             }
   1004             for (i = 0; i < num_palette; i++)
   1005             {
   1006                if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
   1007                {
   1008                   if (png_ptr->trans[i] == 0)
   1009                   {
   1010                      palette[i] = back;
   1011                   }
   1012                   else /* if (png_ptr->trans[i] != 0xff) */
   1013                   {
   1014                      png_byte v, w;
   1015 
   1016                      v = png_ptr->gamma_to_1[palette[i].red];
   1017                      png_composite(w, v, png_ptr->trans[i], back_1.red);
   1018                      palette[i].red = png_ptr->gamma_from_1[w];
   1019 
   1020                      v = png_ptr->gamma_to_1[palette[i].green];
   1021                      png_composite(w, v, png_ptr->trans[i], back_1.green);
   1022                      palette[i].green = png_ptr->gamma_from_1[w];
   1023 
   1024                      v = png_ptr->gamma_to_1[palette[i].blue];
   1025                      png_composite(w, v, png_ptr->trans[i], back_1.blue);
   1026                      palette[i].blue = png_ptr->gamma_from_1[w];
   1027                   }
   1028                }
   1029                else
   1030                {
   1031                   palette[i].red = png_ptr->gamma_table[palette[i].red];
   1032                   palette[i].green = png_ptr->gamma_table[palette[i].green];
   1033                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   1034                }
   1035             }
   1036             /* Prevent the transformations being done again, and make sure
   1037              * that the now spurious alpha channel is stripped - the code
   1038              * has just reduced background composition and gamma correction
   1039              * to a simple alpha channel strip.
   1040              */
   1041             png_ptr->transformations &= ~PNG_BACKGROUND;
   1042             png_ptr->transformations &= ~PNG_GAMMA;
   1043             png_ptr->transformations |= PNG_STRIP_ALPHA;
   1044          }
   1045          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
   1046          else
   1047          /* color_type != PNG_COLOR_TYPE_PALETTE */
   1048          {
   1049             double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
   1050             double g = 1.0;
   1051             double gs = 1.0;
   1052 
   1053             switch (png_ptr->background_gamma_type)
   1054             {
   1055                case PNG_BACKGROUND_GAMMA_SCREEN:
   1056                   g = (png_ptr->screen_gamma);
   1057                   gs = 1.0;
   1058                   break;
   1059 
   1060                case PNG_BACKGROUND_GAMMA_FILE:
   1061                   g = 1.0 / (png_ptr->gamma);
   1062                   gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
   1063                   break;
   1064 
   1065                case PNG_BACKGROUND_GAMMA_UNIQUE:
   1066                   g = 1.0 / (png_ptr->background_gamma);
   1067                   gs = 1.0 / (png_ptr->background_gamma *
   1068                      png_ptr->screen_gamma);
   1069                   break;
   1070             }
   1071 
   1072             png_ptr->background_1.gray = (png_uint_16)(pow(
   1073                (double)png_ptr->background.gray / m, g) * m + .5);
   1074             png_ptr->background.gray = (png_uint_16)(pow(
   1075                (double)png_ptr->background.gray / m, gs) * m + .5);
   1076 
   1077             if ((png_ptr->background.red != png_ptr->background.green) ||
   1078                 (png_ptr->background.red != png_ptr->background.blue) ||
   1079                 (png_ptr->background.red != png_ptr->background.gray))
   1080             {
   1081                /* RGB or RGBA with color background */
   1082                png_ptr->background_1.red = (png_uint_16)(pow(
   1083                   (double)png_ptr->background.red / m, g) * m + .5);
   1084                png_ptr->background_1.green = (png_uint_16)(pow(
   1085                   (double)png_ptr->background.green / m, g) * m + .5);
   1086                png_ptr->background_1.blue = (png_uint_16)(pow(
   1087                   (double)png_ptr->background.blue / m, g) * m + .5);
   1088                png_ptr->background.red = (png_uint_16)(pow(
   1089                   (double)png_ptr->background.red / m, gs) * m + .5);
   1090                png_ptr->background.green = (png_uint_16)(pow(
   1091                   (double)png_ptr->background.green / m, gs) * m + .5);
   1092                png_ptr->background.blue = (png_uint_16)(pow(
   1093                   (double)png_ptr->background.blue / m, gs) * m + .5);
   1094             }
   1095             else
   1096             {
   1097                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
   1098                png_ptr->background_1.red = png_ptr->background_1.green
   1099                  = png_ptr->background_1.blue = png_ptr->background_1.gray;
   1100                png_ptr->background.red = png_ptr->background.green
   1101                  = png_ptr->background.blue = png_ptr->background.gray;
   1102             }
   1103          }
   1104       }
   1105       else
   1106       /* Transformation does not include PNG_BACKGROUND */
   1107 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
   1108       if (color_type == PNG_COLOR_TYPE_PALETTE)
   1109       {
   1110          png_colorp palette = png_ptr->palette;
   1111          int num_palette = png_ptr->num_palette;
   1112          int i;
   1113 
   1114          for (i = 0; i < num_palette; i++)
   1115          {
   1116             palette[i].red = png_ptr->gamma_table[palette[i].red];
   1117             palette[i].green = png_ptr->gamma_table[palette[i].green];
   1118             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   1119          }
   1120 
   1121          /* Done the gamma correction. */
   1122          png_ptr->transformations &= ~PNG_GAMMA;
   1123       }
   1124    }
   1125 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1126    else
   1127 #endif
   1128 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
   1129 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1130    /* No GAMMA transformation */
   1131    if ((png_ptr->transformations & PNG_BACKGROUND) &&
   1132        (color_type == PNG_COLOR_TYPE_PALETTE))
   1133    {
   1134       int i;
   1135       int istop = (int)png_ptr->num_trans;
   1136       png_color back;
   1137       png_colorp palette = png_ptr->palette;
   1138 
   1139       back.red   = (png_byte)png_ptr->background.red;
   1140       back.green = (png_byte)png_ptr->background.green;
   1141       back.blue  = (png_byte)png_ptr->background.blue;
   1142 
   1143       for (i = 0; i < istop; i++)
   1144       {
   1145          if (png_ptr->trans[i] == 0)
   1146          {
   1147             palette[i] = back;
   1148          }
   1149          else if (png_ptr->trans[i] != 0xff)
   1150          {
   1151             /* The png_composite() macro is defined in png.h */
   1152             png_composite(palette[i].red, palette[i].red,
   1153                png_ptr->trans[i], back.red);
   1154             png_composite(palette[i].green, palette[i].green,
   1155                png_ptr->trans[i], back.green);
   1156             png_composite(palette[i].blue, palette[i].blue,
   1157                png_ptr->trans[i], back.blue);
   1158          }
   1159       }
   1160 
   1161       /* Handled alpha, still need to strip the channel. */
   1162       png_ptr->transformations &= ~PNG_BACKGROUND;
   1163       png_ptr->transformations |= PNG_STRIP_ALPHA;
   1164    }
   1165 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
   1166 
   1167 #ifdef PNG_READ_SHIFT_SUPPORTED
   1168    if ((png_ptr->transformations & PNG_SHIFT) &&
   1169       !(png_ptr->transformations & PNG_EXPAND) &&
   1170       (color_type == PNG_COLOR_TYPE_PALETTE))
   1171    {
   1172       png_uint_16 i;
   1173       png_uint_16 istop = png_ptr->num_palette;
   1174       int sr = 8 - png_ptr->sig_bit.red;
   1175       int sg = 8 - png_ptr->sig_bit.green;
   1176       int sb = 8 - png_ptr->sig_bit.blue;
   1177 
   1178       if (sr < 0 || sr > 8)
   1179          sr = 0;
   1180       if (sg < 0 || sg > 8)
   1181          sg = 0;
   1182       if (sb < 0 || sb > 8)
   1183          sb = 0;
   1184       for (i = 0; i < istop; i++)
   1185       {
   1186          png_ptr->palette[i].red >>= sr;
   1187          png_ptr->palette[i].green >>= sg;
   1188          png_ptr->palette[i].blue >>= sb;
   1189       }
   1190 
   1191       png_ptr->transformations &= ~PNG_SHIFT;
   1192    }
   1193 #endif  /* PNG_READ_SHIFT_SUPPORTED */
   1194  }
   1195 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
   1196  && !defined(PNG_READ_BACKGROUND_SUPPORTED)
   1197    if (png_ptr)
   1198       return;
   1199 #endif
   1200 }
   1201 
   1202 /* Modify the info structure to reflect the transformations.  The
   1203  * info should be updated so a PNG file could be written with it,
   1204  * assuming the transformations result in valid PNG data.
   1205  */
   1206 void /* PRIVATE */
   1207 png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
   1208 {
   1209    png_debug(1, "in png_read_transform_info");
   1210 
   1211 #ifdef PNG_READ_EXPAND_SUPPORTED
   1212    if (png_ptr->transformations & PNG_EXPAND)
   1213    {
   1214       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1215       {
   1216          if (png_ptr->num_trans)
   1217             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   1218          else
   1219             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
   1220          info_ptr->bit_depth = 8;
   1221          info_ptr->num_trans = 0;
   1222       }
   1223       else
   1224       {
   1225          if (png_ptr->num_trans)
   1226          {
   1227             if (png_ptr->transformations & PNG_EXPAND_tRNS)
   1228               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   1229          }
   1230          if (info_ptr->bit_depth < 8)
   1231             info_ptr->bit_depth = 8;
   1232          info_ptr->num_trans = 0;
   1233       }
   1234    }
   1235 #endif
   1236 
   1237 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1238    if (png_ptr->transformations & PNG_BACKGROUND)
   1239    {
   1240       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
   1241       info_ptr->num_trans = 0;
   1242       info_ptr->background = png_ptr->background;
   1243    }
   1244 #endif
   1245 
   1246 #ifdef PNG_READ_GAMMA_SUPPORTED
   1247    if (png_ptr->transformations & PNG_GAMMA)
   1248    {
   1249 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1250       info_ptr->gamma = png_ptr->gamma;
   1251 #endif
   1252 #ifdef PNG_FIXED_POINT_SUPPORTED
   1253       info_ptr->int_gamma = png_ptr->int_gamma;
   1254 #endif
   1255    }
   1256 #endif
   1257 
   1258 #ifdef PNG_READ_16_TO_8_SUPPORTED
   1259    if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
   1260       info_ptr->bit_depth = 8;
   1261 #endif
   1262 
   1263 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   1264    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   1265       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
   1266 #endif
   1267 
   1268 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   1269    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
   1270       info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
   1271 #endif
   1272 
   1273 #ifdef PNG_READ_DITHER_SUPPORTED
   1274    if (png_ptr->transformations & PNG_DITHER)
   1275    {
   1276       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
   1277           (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
   1278           png_ptr->palette_lookup && info_ptr->bit_depth == 8)
   1279       {
   1280          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
   1281       }
   1282    }
   1283 #endif
   1284 
   1285 #ifdef PNG_READ_PACK_SUPPORTED
   1286    if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
   1287       info_ptr->bit_depth = 8;
   1288 #endif
   1289 
   1290    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1291       info_ptr->channels = 1;
   1292    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
   1293       info_ptr->channels = 3;
   1294    else
   1295       info_ptr->channels = 1;
   1296 
   1297 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   1298    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
   1299       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
   1300 #endif
   1301 
   1302    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
   1303       info_ptr->channels++;
   1304 
   1305 #ifdef PNG_READ_FILLER_SUPPORTED
   1306    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
   1307    if ((png_ptr->transformations & PNG_FILLER) &&
   1308        ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
   1309        (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
   1310    {
   1311       info_ptr->channels++;
   1312       /* If adding a true alpha channel not just filler */
   1313 #ifndef PNG_1_0_X
   1314       if (png_ptr->transformations & PNG_ADD_ALPHA)
   1315         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   1316 #endif
   1317    }
   1318 #endif
   1319 
   1320 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
   1321 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   1322    if (png_ptr->transformations & PNG_USER_TRANSFORM)
   1323      {
   1324        if (info_ptr->bit_depth < png_ptr->user_transform_depth)
   1325          info_ptr->bit_depth = png_ptr->user_transform_depth;
   1326        if (info_ptr->channels < png_ptr->user_transform_channels)
   1327          info_ptr->channels = png_ptr->user_transform_channels;
   1328      }
   1329 #endif
   1330 
   1331    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
   1332       info_ptr->bit_depth);
   1333 
   1334    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
   1335 
   1336 #ifndef PNG_READ_EXPAND_SUPPORTED
   1337    if (png_ptr)
   1338       return;
   1339 #endif
   1340 }
   1341 
   1342 /* Transform the row.  The order of transformations is significant,
   1343  * and is very touchy.  If you add a transformation, take care to
   1344  * decide how it fits in with the other transformations here.
   1345  */
   1346 void /* PRIVATE */
   1347 png_do_read_transformations(png_structp png_ptr)
   1348 {
   1349    png_debug(1, "in png_do_read_transformations");
   1350 
   1351    if (png_ptr->row_buf == NULL)
   1352    {
   1353 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
   1354       char msg[50];
   1355 
   1356       png_snprintf2(msg, 50,
   1357          "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
   1358          png_ptr->pass);
   1359       png_error(png_ptr, msg);
   1360 #else
   1361       png_error(png_ptr, "NULL row buffer");
   1362 #endif
   1363    }
   1364 #ifdef PNG_WARN_UNINITIALIZED_ROW
   1365    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
   1366       /* Application has failed to call either png_read_start_image()
   1367        * or png_read_update_info() after setting transforms that expand
   1368        * pixels.  This check added to libpng-1.2.19
   1369        */
   1370 #if (PNG_WARN_UNINITIALIZED_ROW==1)
   1371       png_error(png_ptr, "Uninitialized row");
   1372 #else
   1373       png_warning(png_ptr, "Uninitialized row");
   1374 #endif
   1375 #endif
   1376 
   1377 #ifdef PNG_READ_EXPAND_SUPPORTED
   1378    if (png_ptr->transformations & PNG_EXPAND)
   1379    {
   1380       if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
   1381       {
   1382          png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1383             png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
   1384       }
   1385       else
   1386       {
   1387          if (png_ptr->num_trans &&
   1388              (png_ptr->transformations & PNG_EXPAND_tRNS))
   1389             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1390                &(png_ptr->trans_values));
   1391          else
   1392             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1393                NULL);
   1394       }
   1395    }
   1396 #endif
   1397 
   1398 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   1399    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
   1400       png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1401          PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
   1402 #endif
   1403 
   1404 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   1405    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
   1406    {
   1407       int rgb_error =
   1408          png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info),
   1409              png_ptr->row_buf + 1);
   1410       if (rgb_error)
   1411       {
   1412          png_ptr->rgb_to_gray_status=1;
   1413          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   1414              PNG_RGB_TO_GRAY_WARN)
   1415             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   1416          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   1417              PNG_RGB_TO_GRAY_ERR)
   1418             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   1419       }
   1420    }
   1421 #endif
   1422 
   1423 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
   1424  *
   1425  *   In most cases, the "simple transparency" should be done prior to doing
   1426  *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
   1427  *   pixel is transparent.  You would also need to make sure that the
   1428  *   transparency information is upgraded to RGB.
   1429  *
   1430  *   To summarize, the current flow is:
   1431  *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
   1432  *                                   with background "in place" if transparent,
   1433  *                                   convert to RGB if necessary
   1434  *   - Gray + alpha -> composite with gray background and remove alpha bytes,
   1435  *                                   convert to RGB if necessary
   1436  *
   1437  *   To support RGB backgrounds for gray images we need:
   1438  *   - Gray + simple transparency -> convert to RGB + simple transparency,
   1439  *                                   compare 3 or 6 bytes and composite with
   1440  *                                   background "in place" if transparent
   1441  *                                   (3x compare/pixel compared to doing
   1442  *                                   composite with gray bkgrnd)
   1443  *   - Gray + alpha -> convert to RGB + alpha, composite with background and
   1444  *                                   remove alpha bytes (3x float
   1445  *                                   operations/pixel compared with composite
   1446  *                                   on gray background)
   1447  *
   1448  *  Greg's change will do this.  The reason it wasn't done before is for
   1449  *  performance, as this increases the per-pixel operations.  If we would check
   1450  *  in advance if the background was gray or RGB, and position the gray-to-RGB
   1451  *  transform appropriately, then it would save a lot of work/time.
   1452  */
   1453 
   1454 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   1455    /* If gray -> RGB, do so now only if background is non-gray; else do later
   1456     * for performance reasons
   1457     */
   1458    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
   1459        !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
   1460       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1461 #endif
   1462 
   1463 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1464    if ((png_ptr->transformations & PNG_BACKGROUND) &&
   1465       ((png_ptr->num_trans != 0 ) ||
   1466       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
   1467       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1468          &(png_ptr->trans_values), &(png_ptr->background)
   1469 #ifdef PNG_READ_GAMMA_SUPPORTED
   1470          , &(png_ptr->background_1),
   1471          png_ptr->gamma_table, png_ptr->gamma_from_1,
   1472          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
   1473          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
   1474          png_ptr->gamma_shift
   1475 #endif
   1476 );
   1477 #endif
   1478 
   1479 #ifdef PNG_READ_GAMMA_SUPPORTED
   1480    if ((png_ptr->transformations & PNG_GAMMA) &&
   1481 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1482        !((png_ptr->transformations & PNG_BACKGROUND) &&
   1483        ((png_ptr->num_trans != 0) ||
   1484        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
   1485 #endif
   1486        (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
   1487       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1488           png_ptr->gamma_table, png_ptr->gamma_16_table,
   1489           png_ptr->gamma_shift);
   1490 #endif
   1491 
   1492 #ifdef PNG_READ_16_TO_8_SUPPORTED
   1493    if (png_ptr->transformations & PNG_16_TO_8)
   1494       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1495 #endif
   1496 
   1497 #ifdef PNG_READ_DITHER_SUPPORTED
   1498    if (png_ptr->transformations & PNG_DITHER)
   1499    {
   1500       png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
   1501          png_ptr->palette_lookup, png_ptr->dither_index);
   1502       if (png_ptr->row_info.rowbytes == (png_uint_32)0)
   1503          png_error(png_ptr, "png_do_dither returned rowbytes=0");
   1504    }
   1505 #endif
   1506 
   1507 #ifdef PNG_READ_INVERT_SUPPORTED
   1508    if (png_ptr->transformations & PNG_INVERT_MONO)
   1509       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1510 #endif
   1511 
   1512 #ifdef PNG_READ_SHIFT_SUPPORTED
   1513    if (png_ptr->transformations & PNG_SHIFT)
   1514       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1515          &(png_ptr->shift));
   1516 #endif
   1517 
   1518 #ifdef PNG_READ_PACK_SUPPORTED
   1519    if (png_ptr->transformations & PNG_PACK)
   1520       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1521 #endif
   1522 
   1523 #ifdef PNG_READ_BGR_SUPPORTED
   1524    if (png_ptr->transformations & PNG_BGR)
   1525       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1526 #endif
   1527 
   1528 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   1529    if (png_ptr->transformations & PNG_PACKSWAP)
   1530       png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1531 #endif
   1532 
   1533 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   1534    /* If gray -> RGB, do so now only if we did not do so above */
   1535    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
   1536        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
   1537       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1538 #endif
   1539 
   1540 #ifdef PNG_READ_FILLER_SUPPORTED
   1541    if (png_ptr->transformations & PNG_FILLER)
   1542       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
   1543          (png_uint_32)png_ptr->filler, png_ptr->flags);
   1544 #endif
   1545 
   1546 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   1547    if (png_ptr->transformations & PNG_INVERT_ALPHA)
   1548       png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1549 #endif
   1550 
   1551 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   1552    if (png_ptr->transformations & PNG_SWAP_ALPHA)
   1553       png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1554 #endif
   1555 
   1556 #ifdef PNG_READ_SWAP_SUPPORTED
   1557    if (png_ptr->transformations & PNG_SWAP_BYTES)
   1558       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
   1559 #endif
   1560 
   1561 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
   1562    if (png_ptr->transformations & PNG_USER_TRANSFORM)
   1563     {
   1564       if (png_ptr->read_user_transform_fn != NULL)
   1565          (*(png_ptr->read_user_transform_fn)) /* User read transform function */
   1566             (png_ptr,                    /* png_ptr */
   1567                &(png_ptr->row_info),     /* row_info: */
   1568                /*  png_uint_32 width;       width of row */
   1569                /*  png_uint_32 rowbytes;    number of bytes in row */
   1570                /*  png_byte color_type;     color type of pixels */
   1571                /*  png_byte bit_depth;      bit depth of samples */
   1572                /*  png_byte channels;       number of channels (1-4) */
   1573                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
   1574                png_ptr->row_buf + 1);    /* start of pixel data for row */
   1575 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
   1576       if (png_ptr->user_transform_depth)
   1577          png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
   1578       if (png_ptr->user_transform_channels)
   1579          png_ptr->row_info.channels = png_ptr->user_transform_channels;
   1580 #endif
   1581       png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
   1582          png_ptr->row_info.channels);
   1583       png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
   1584          png_ptr->row_info.width);
   1585    }
   1586 #endif
   1587 
   1588 }
   1589 
   1590 #ifdef PNG_READ_PACK_SUPPORTED
   1591 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
   1592  * without changing the actual values.  Thus, if you had a row with
   1593  * a bit depth of 1, you would end up with bytes that only contained
   1594  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
   1595  * png_do_shift() after this.
   1596  */
   1597 void /* PRIVATE */
   1598 png_do_unpack(png_row_infop row_info, png_bytep row)
   1599 {
   1600    png_debug(1, "in png_do_unpack");
   1601 
   1602 #ifdef PNG_USELESS_TESTS_SUPPORTED
   1603    if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
   1604 #else
   1605    if (row_info->bit_depth < 8)
   1606 #endif
   1607    {
   1608       png_uint_32 i;
   1609       png_uint_32 row_width=row_info->width;
   1610 
   1611       switch (row_info->bit_depth)
   1612       {
   1613          case 1:
   1614          {
   1615             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
   1616             png_bytep dp = row + (png_size_t)row_width - 1;
   1617             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
   1618             for (i = 0; i < row_width; i++)
   1619             {
   1620                *dp = (png_byte)((*sp >> shift) & 0x01);
   1621                if (shift == 7)
   1622                {
   1623                   shift = 0;
   1624                   sp--;
   1625                }
   1626                else
   1627                   shift++;
   1628 
   1629                dp--;
   1630             }
   1631             break;
   1632          }
   1633 
   1634          case 2:
   1635          {
   1636 
   1637             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
   1638             png_bytep dp = row + (png_size_t)row_width - 1;
   1639             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   1640             for (i = 0; i < row_width; i++)
   1641             {
   1642                *dp = (png_byte)((*sp >> shift) & 0x03);
   1643                if (shift == 6)
   1644                {
   1645                   shift = 0;
   1646                   sp--;
   1647                }
   1648                else
   1649                   shift += 2;
   1650 
   1651                dp--;
   1652             }
   1653             break;
   1654          }
   1655 
   1656          case 4:
   1657          {
   1658             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
   1659             png_bytep dp = row + (png_size_t)row_width - 1;
   1660             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   1661             for (i = 0; i < row_width; i++)
   1662             {
   1663                *dp = (png_byte)((*sp >> shift) & 0x0f);
   1664                if (shift == 4)
   1665                {
   1666                   shift = 0;
   1667                   sp--;
   1668                }
   1669                else
   1670                   shift = 4;
   1671 
   1672                dp--;
   1673             }
   1674             break;
   1675          }
   1676       }
   1677       row_info->bit_depth = 8;
   1678       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   1679       row_info->rowbytes = row_width * row_info->channels;
   1680    }
   1681 }
   1682 #endif
   1683 
   1684 #ifdef PNG_READ_SHIFT_SUPPORTED
   1685 /* Reverse the effects of png_do_shift.  This routine merely shifts the
   1686  * pixels back to their significant bits values.  Thus, if you have
   1687  * a row of bit depth 8, but only 5 are significant, this will shift
   1688  * the values back to 0 through 31.
   1689  */
   1690 void /* PRIVATE */
   1691 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
   1692 {
   1693    png_debug(1, "in png_do_unshift");
   1694 
   1695    if (
   1696 #ifdef PNG_USELESS_TESTS_SUPPORTED
   1697        row != NULL && row_info != NULL && sig_bits != NULL &&
   1698 #endif
   1699        row_info->color_type != PNG_COLOR_TYPE_PALETTE)
   1700    {
   1701       int shift[4];
   1702       int channels = 0;
   1703       int c;
   1704       png_uint_16 value = 0;
   1705       png_uint_32 row_width = row_info->width;
   1706 
   1707       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
   1708       {
   1709          shift[channels++] = row_info->bit_depth - sig_bits->red;
   1710          shift[channels++] = row_info->bit_depth - sig_bits->green;
   1711          shift[channels++] = row_info->bit_depth - sig_bits->blue;
   1712       }
   1713       else
   1714       {
   1715          shift[channels++] = row_info->bit_depth - sig_bits->gray;
   1716       }
   1717       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
   1718       {
   1719          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
   1720       }
   1721 
   1722       for (c = 0; c < channels; c++)
   1723       {
   1724          if (shift[c] <= 0)
   1725             shift[c] = 0;
   1726          else
   1727             value = 1;
   1728       }
   1729 
   1730       if (!value)
   1731          return;
   1732 
   1733       switch (row_info->bit_depth)
   1734       {
   1735          case 2:
   1736          {
   1737             png_bytep bp;
   1738             png_uint_32 i;
   1739             png_uint_32 istop = row_info->rowbytes;
   1740 
   1741             for (bp = row, i = 0; i < istop; i++)
   1742             {
   1743                *bp >>= 1;
   1744                *bp++ &= 0x55;
   1745             }
   1746             break;
   1747          }
   1748 
   1749          case 4:
   1750          {
   1751             png_bytep bp = row;
   1752             png_uint_32 i;
   1753             png_uint_32 istop = row_info->rowbytes;
   1754             png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
   1755                (png_byte)((int)0xf >> shift[0]));
   1756 
   1757             for (i = 0; i < istop; i++)
   1758             {
   1759                *bp >>= shift[0];
   1760                *bp++ &= mask;
   1761             }
   1762             break;
   1763          }
   1764 
   1765          case 8:
   1766          {
   1767             png_bytep bp = row;
   1768             png_uint_32 i;
   1769             png_uint_32 istop = row_width * channels;
   1770 
   1771             for (i = 0; i < istop; i++)
   1772             {
   1773                *bp++ >>= shift[i%channels];
   1774             }
   1775             break;
   1776          }
   1777 
   1778          case 16:
   1779          {
   1780             png_bytep bp = row;
   1781             png_uint_32 i;
   1782             png_uint_32 istop = channels * row_width;
   1783 
   1784             for (i = 0; i < istop; i++)
   1785             {
   1786                value = (png_uint_16)((*bp << 8) + *(bp + 1));
   1787                value >>= shift[i%channels];
   1788                *bp++ = (png_byte)(value >> 8);
   1789                *bp++ = (png_byte)(value & 0xff);
   1790             }
   1791             break;
   1792          }
   1793       }
   1794    }
   1795 }
   1796 #endif
   1797 
   1798 #ifdef PNG_READ_16_TO_8_SUPPORTED
   1799 /* Chop rows of bit depth 16 down to 8 */
   1800 void /* PRIVATE */
   1801 png_do_chop(png_row_infop row_info, png_bytep row)
   1802 {
   1803    png_debug(1, "in png_do_chop");
   1804 
   1805 #ifdef PNG_USELESS_TESTS_SUPPORTED
   1806    if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
   1807 #else
   1808    if (row_info->bit_depth == 16)
   1809 #endif
   1810    {
   1811       png_bytep sp = row;
   1812       png_bytep dp = row;
   1813       png_uint_32 i;
   1814       png_uint_32 istop = row_info->width * row_info->channels;
   1815 
   1816       for (i = 0; i<istop; i++, sp += 2, dp++)
   1817       {
   1818 #ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
   1819       /* This does a more accurate scaling of the 16-bit color
   1820        * value, rather than a simple low-byte truncation.
   1821        *
   1822        * What the ideal calculation should be:
   1823        *   *dp = (((((png_uint_32)(*sp) << 8) |
   1824        *          (png_uint_32)(*(sp + 1))) * 255 + 127)
   1825        *          / (png_uint_32)65535L;
   1826        *
   1827        * GRR: no, I think this is what it really should be:
   1828        *   *dp = (((((png_uint_32)(*sp) << 8) |
   1829        *           (png_uint_32)(*(sp + 1))) + 128L)
   1830        *           / (png_uint_32)257L;
   1831        *
   1832        * GRR: here's the exact calculation with shifts:
   1833        *   temp = (((png_uint_32)(*sp) << 8) |
   1834        *           (png_uint_32)(*(sp + 1))) + 128L;
   1835        *   *dp = (temp - (temp >> 8)) >> 8;
   1836        *
   1837        * Approximate calculation with shift/add instead of multiply/divide:
   1838        *   *dp = ((((png_uint_32)(*sp) << 8) |
   1839        *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
   1840        *
   1841        * What we actually do to avoid extra shifting and conversion:
   1842        */
   1843 
   1844          *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
   1845 #else
   1846        /* Simply discard the low order byte */
   1847          *dp = *sp;
   1848 #endif
   1849       }
   1850       row_info->bit_depth = 8;
   1851       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   1852       row_info->rowbytes = row_info->width * row_info->channels;
   1853    }
   1854 }
   1855 #endif
   1856 
   1857 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   1858 void /* PRIVATE */
   1859 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
   1860 {
   1861    png_debug(1, "in png_do_read_swap_alpha");
   1862 
   1863 #ifdef PNG_USELESS_TESTS_SUPPORTED
   1864    if (row != NULL && row_info != NULL)
   1865 #endif
   1866    {
   1867       png_uint_32 row_width = row_info->width;
   1868       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   1869       {
   1870          /* This converts from RGBA to ARGB */
   1871          if (row_info->bit_depth == 8)
   1872          {
   1873             png_bytep sp = row + row_info->rowbytes;
   1874             png_bytep dp = sp;
   1875             png_byte save;
   1876             png_uint_32 i;
   1877 
   1878             for (i = 0; i < row_width; i++)
   1879             {
   1880                save = *(--sp);
   1881                *(--dp) = *(--sp);
   1882                *(--dp) = *(--sp);
   1883                *(--dp) = *(--sp);
   1884                *(--dp) = save;
   1885             }
   1886          }
   1887          /* This converts from RRGGBBAA to AARRGGBB */
   1888          else
   1889          {
   1890             png_bytep sp = row + row_info->rowbytes;
   1891             png_bytep dp = sp;
   1892             png_byte save[2];
   1893             png_uint_32 i;
   1894 
   1895             for (i = 0; i < row_width; i++)
   1896             {
   1897                save[0] = *(--sp);
   1898                save[1] = *(--sp);
   1899                *(--dp) = *(--sp);
   1900                *(--dp) = *(--sp);
   1901                *(--dp) = *(--sp);
   1902                *(--dp) = *(--sp);
   1903                *(--dp) = *(--sp);
   1904                *(--dp) = *(--sp);
   1905                *(--dp) = save[0];
   1906                *(--dp) = save[1];
   1907             }
   1908          }
   1909       }
   1910       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   1911       {
   1912          /* This converts from GA to AG */
   1913          if (row_info->bit_depth == 8)
   1914          {
   1915             png_bytep sp = row + row_info->rowbytes;
   1916             png_bytep dp = sp;
   1917             png_byte save;
   1918             png_uint_32 i;
   1919 
   1920             for (i = 0; i < row_width; i++)
   1921             {
   1922                save = *(--sp);
   1923                *(--dp) = *(--sp);
   1924                *(--dp) = save;
   1925             }
   1926          }
   1927          /* This converts from GGAA to AAGG */
   1928          else
   1929          {
   1930             png_bytep sp = row + row_info->rowbytes;
   1931             png_bytep dp = sp;
   1932             png_byte save[2];
   1933             png_uint_32 i;
   1934 
   1935             for (i = 0; i < row_width; i++)
   1936             {
   1937                save[0] = *(--sp);
   1938                save[1] = *(--sp);
   1939                *(--dp) = *(--sp);
   1940                *(--dp) = *(--sp);
   1941                *(--dp) = save[0];
   1942                *(--dp) = save[1];
   1943             }
   1944          }
   1945       }
   1946    }
   1947 }
   1948 #endif
   1949 
   1950 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   1951 void /* PRIVATE */
   1952 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
   1953 {
   1954    png_debug(1, "in png_do_read_invert_alpha");
   1955 
   1956 #ifdef PNG_USELESS_TESTS_SUPPORTED
   1957    if (row != NULL && row_info != NULL)
   1958 #endif
   1959    {
   1960       png_uint_32 row_width = row_info->width;
   1961       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   1962       {
   1963          /* This inverts the alpha channel in RGBA */
   1964          if (row_info->bit_depth == 8)
   1965          {
   1966             png_bytep sp = row + row_info->rowbytes;
   1967             png_bytep dp = sp;
   1968             png_uint_32 i;
   1969 
   1970             for (i = 0; i < row_width; i++)
   1971             {
   1972                *(--dp) = (png_byte)(255 - *(--sp));
   1973 
   1974 /*             This does nothing:
   1975                *(--dp) = *(--sp);
   1976                *(--dp) = *(--sp);
   1977                *(--dp) = *(--sp);
   1978                We can replace it with:
   1979 */
   1980                sp-=3;
   1981                dp=sp;
   1982             }
   1983          }
   1984          /* This inverts the alpha channel in RRGGBBAA */
   1985          else
   1986          {
   1987             png_bytep sp = row + row_info->rowbytes;
   1988             png_bytep dp = sp;
   1989             png_uint_32 i;
   1990 
   1991             for (i = 0; i < row_width; i++)
   1992             {
   1993                *(--dp) = (png_byte)(255 - *(--sp));
   1994                *(--dp) = (png_byte)(255 - *(--sp));
   1995 
   1996 /*             This does nothing:
   1997                *(--dp) = *(--sp);
   1998                *(--dp) = *(--sp);
   1999                *(--dp) = *(--sp);
   2000                *(--dp) = *(--sp);
   2001                *(--dp) = *(--sp);
   2002                *(--dp) = *(--sp);
   2003                We can replace it with:
   2004 */
   2005                sp-=6;
   2006                dp=sp;
   2007             }
   2008          }
   2009       }
   2010       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2011       {
   2012          /* This inverts the alpha channel in GA */
   2013          if (row_info->bit_depth == 8)
   2014          {
   2015             png_bytep sp = row + row_info->rowbytes;
   2016             png_bytep dp = sp;
   2017             png_uint_32 i;
   2018 
   2019             for (i = 0; i < row_width; i++)
   2020             {
   2021                *(--dp) = (png_byte)(255 - *(--sp));
   2022                *(--dp) = *(--sp);
   2023             }
   2024          }
   2025          /* This inverts the alpha channel in GGAA */
   2026          else
   2027          {
   2028             png_bytep sp  = row + row_info->rowbytes;
   2029             png_bytep dp = sp;
   2030             png_uint_32 i;
   2031 
   2032             for (i = 0; i < row_width; i++)
   2033             {
   2034                *(--dp) = (png_byte)(255 - *(--sp));
   2035                *(--dp) = (png_byte)(255 - *(--sp));
   2036 /*
   2037                *(--dp) = *(--sp);
   2038                *(--dp) = *(--sp);
   2039 */
   2040                sp-=2;
   2041                dp=sp;
   2042             }
   2043          }
   2044       }
   2045    }
   2046 }
   2047 #endif
   2048 
   2049 #ifdef PNG_READ_FILLER_SUPPORTED
   2050 /* Add filler channel if we have RGB color */
   2051 void /* PRIVATE */
   2052 png_do_read_filler(png_row_infop row_info, png_bytep row,
   2053    png_uint_32 filler, png_uint_32 flags)
   2054 {
   2055    png_uint_32 i;
   2056    png_uint_32 row_width = row_info->width;
   2057 
   2058    png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
   2059    png_byte lo_filler = (png_byte)(filler & 0xff);
   2060 
   2061    png_debug(1, "in png_do_read_filler");
   2062 
   2063    if (
   2064 #ifdef PNG_USELESS_TESTS_SUPPORTED
   2065        row != NULL  && row_info != NULL &&
   2066 #endif
   2067        row_info->color_type == PNG_COLOR_TYPE_GRAY)
   2068    {
   2069       if (row_info->bit_depth == 8)
   2070       {
   2071          /* This changes the data from G to GX */
   2072          if (flags & PNG_FLAG_FILLER_AFTER)
   2073          {
   2074             png_bytep sp = row + (png_size_t)row_width;
   2075             png_bytep dp =  sp + (png_size_t)row_width;
   2076             for (i = 1; i < row_width; i++)
   2077             {
   2078                *(--dp) = lo_filler;
   2079                *(--dp) = *(--sp);
   2080             }
   2081             *(--dp) = lo_filler;
   2082             row_info->channels = 2;
   2083             row_info->pixel_depth = 16;
   2084             row_info->rowbytes = row_width * 2;
   2085          }
   2086       /* This changes the data from G to XG */
   2087          else
   2088          {
   2089             png_bytep sp = row + (png_size_t)row_width;
   2090             png_bytep dp = sp  + (png_size_t)row_width;
   2091             for (i = 0; i < row_width; i++)
   2092             {
   2093                *(--dp) = *(--sp);
   2094                *(--dp) = lo_filler;
   2095             }
   2096             row_info->channels = 2;
   2097             row_info->pixel_depth = 16;
   2098             row_info->rowbytes = row_width * 2;
   2099          }
   2100       }
   2101       else if (row_info->bit_depth == 16)
   2102       {
   2103          /* This changes the data from GG to GGXX */
   2104          if (flags & PNG_FLAG_FILLER_AFTER)
   2105          {
   2106             png_bytep sp = row + (png_size_t)row_width * 2;
   2107             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2108             for (i = 1; i < row_width; i++)
   2109             {
   2110                *(--dp) = hi_filler;
   2111                *(--dp) = lo_filler;
   2112                *(--dp) = *(--sp);
   2113                *(--dp) = *(--sp);
   2114             }
   2115             *(--dp) = hi_filler;
   2116             *(--dp) = lo_filler;
   2117             row_info->channels = 2;
   2118             row_info->pixel_depth = 32;
   2119             row_info->rowbytes = row_width * 4;
   2120          }
   2121          /* This changes the data from GG to XXGG */
   2122          else
   2123          {
   2124             png_bytep sp = row + (png_size_t)row_width * 2;
   2125             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2126             for (i = 0; i < row_width; i++)
   2127             {
   2128                *(--dp) = *(--sp);
   2129                *(--dp) = *(--sp);
   2130                *(--dp) = hi_filler;
   2131                *(--dp) = lo_filler;
   2132             }
   2133             row_info->channels = 2;
   2134             row_info->pixel_depth = 32;
   2135             row_info->rowbytes = row_width * 4;
   2136          }
   2137       }
   2138    } /* COLOR_TYPE == GRAY */
   2139    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   2140    {
   2141       if (row_info->bit_depth == 8)
   2142       {
   2143          /* This changes the data from RGB to RGBX */
   2144          if (flags & PNG_FLAG_FILLER_AFTER)
   2145          {
   2146             png_bytep sp = row + (png_size_t)row_width * 3;
   2147             png_bytep dp = sp  + (png_size_t)row_width;
   2148             for (i = 1; i < row_width; i++)
   2149             {
   2150                *(--dp) = lo_filler;
   2151                *(--dp) = *(--sp);
   2152                *(--dp) = *(--sp);
   2153                *(--dp) = *(--sp);
   2154             }
   2155             *(--dp) = lo_filler;
   2156             row_info->channels = 4;
   2157             row_info->pixel_depth = 32;
   2158             row_info->rowbytes = row_width * 4;
   2159          }
   2160       /* This changes the data from RGB to XRGB */
   2161          else
   2162          {
   2163             png_bytep sp = row + (png_size_t)row_width * 3;
   2164             png_bytep dp = sp + (png_size_t)row_width;
   2165             for (i = 0; i < row_width; i++)
   2166             {
   2167                *(--dp) = *(--sp);
   2168                *(--dp) = *(--sp);
   2169                *(--dp) = *(--sp);
   2170                *(--dp) = lo_filler;
   2171             }
   2172             row_info->channels = 4;
   2173             row_info->pixel_depth = 32;
   2174             row_info->rowbytes = row_width * 4;
   2175          }
   2176       }
   2177       else if (row_info->bit_depth == 16)
   2178       {
   2179          /* This changes the data from RRGGBB to RRGGBBXX */
   2180          if (flags & PNG_FLAG_FILLER_AFTER)
   2181          {
   2182             png_bytep sp = row + (png_size_t)row_width * 6;
   2183             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2184             for (i = 1; i < row_width; i++)
   2185             {
   2186                *(--dp) = hi_filler;
   2187                *(--dp) = lo_filler;
   2188                *(--dp) = *(--sp);
   2189                *(--dp) = *(--sp);
   2190                *(--dp) = *(--sp);
   2191                *(--dp) = *(--sp);
   2192                *(--dp) = *(--sp);
   2193                *(--dp) = *(--sp);
   2194             }
   2195             *(--dp) = hi_filler;
   2196             *(--dp) = lo_filler;
   2197             row_info->channels = 4;
   2198             row_info->pixel_depth = 64;
   2199             row_info->rowbytes = row_width * 8;
   2200          }
   2201          /* This changes the data from RRGGBB to XXRRGGBB */
   2202          else
   2203          {
   2204             png_bytep sp = row + (png_size_t)row_width * 6;
   2205             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2206             for (i = 0; i < row_width; i++)
   2207             {
   2208                *(--dp) = *(--sp);
   2209                *(--dp) = *(--sp);
   2210                *(--dp) = *(--sp);
   2211                *(--dp) = *(--sp);
   2212                *(--dp) = *(--sp);
   2213                *(--dp) = *(--sp);
   2214                *(--dp) = hi_filler;
   2215                *(--dp) = lo_filler;
   2216             }
   2217             row_info->channels = 4;
   2218             row_info->pixel_depth = 64;
   2219             row_info->rowbytes = row_width * 8;
   2220          }
   2221       }
   2222    } /* COLOR_TYPE == RGB */
   2223 }
   2224 #endif
   2225 
   2226 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   2227 /* Expand grayscale files to RGB, with or without alpha */
   2228 void /* PRIVATE */
   2229 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
   2230 {
   2231    png_uint_32 i;
   2232    png_uint_32 row_width = row_info->width;
   2233 
   2234    png_debug(1, "in png_do_gray_to_rgb");
   2235 
   2236    if (row_info->bit_depth >= 8 &&
   2237 #ifdef PNG_USELESS_TESTS_SUPPORTED
   2238        row != NULL && row_info != NULL &&
   2239 #endif
   2240       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
   2241    {
   2242       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   2243       {
   2244          if (row_info->bit_depth == 8)
   2245          {
   2246             png_bytep sp = row + (png_size_t)row_width - 1;
   2247             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2248             for (i = 0; i < row_width; i++)
   2249             {
   2250                *(dp--) = *sp;
   2251                *(dp--) = *sp;
   2252                *(dp--) = *(sp--);
   2253             }
   2254          }
   2255          else
   2256          {
   2257             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2258             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2259             for (i = 0; i < row_width; i++)
   2260             {
   2261                *(dp--) = *sp;
   2262                *(dp--) = *(sp - 1);
   2263                *(dp--) = *sp;
   2264                *(dp--) = *(sp - 1);
   2265                *(dp--) = *(sp--);
   2266                *(dp--) = *(sp--);
   2267             }
   2268          }
   2269       }
   2270       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2271       {
   2272          if (row_info->bit_depth == 8)
   2273          {
   2274             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2275             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2276             for (i = 0; i < row_width; i++)
   2277             {
   2278                *(dp--) = *(sp--);
   2279                *(dp--) = *sp;
   2280                *(dp--) = *sp;
   2281                *(dp--) = *(sp--);
   2282             }
   2283          }
   2284          else
   2285          {
   2286             png_bytep sp = row + (png_size_t)row_width * 4 - 1;
   2287             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2288             for (i = 0; i < row_width; i++)
   2289             {
   2290                *(dp--) = *(sp--);
   2291                *(dp--) = *(sp--);
   2292                *(dp--) = *sp;
   2293                *(dp--) = *(sp - 1);
   2294                *(dp--) = *sp;
   2295                *(dp--) = *(sp - 1);
   2296                *(dp--) = *(sp--);
   2297                *(dp--) = *(sp--);
   2298             }
   2299          }
   2300       }
   2301       row_info->channels += (png_byte)2;
   2302       row_info->color_type |= PNG_COLOR_MASK_COLOR;
   2303       row_info->pixel_depth = (png_byte)(row_info->channels *
   2304          row_info->bit_depth);
   2305       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   2306    }
   2307 }
   2308 #endif
   2309 
   2310 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   2311 /* Reduce RGB files to grayscale, with or without alpha
   2312  * using the equation given in Poynton's ColorFAQ at
   2313  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
   2314  * New link:
   2315  * <http://www.poynton.com/notes/colour_and_gamma/>
   2316  * Charles Poynton poynton at poynton.com
   2317  *
   2318  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
   2319  *
   2320  *  We approximate this with
   2321  *
   2322  *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
   2323  *
   2324  *  which can be expressed with integers as
   2325  *
   2326  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
   2327  *
   2328  *  The calculation is to be done in a linear colorspace.
   2329  *
   2330  *  Other integer coefficents can be used via png_set_rgb_to_gray().
   2331  */
   2332 int /* PRIVATE */
   2333 png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
   2334 
   2335 {
   2336    png_uint_32 i;
   2337 
   2338    png_uint_32 row_width = row_info->width;
   2339    int rgb_error = 0;
   2340 
   2341    png_debug(1, "in png_do_rgb_to_gray");
   2342 
   2343    if (
   2344 #ifdef PNG_USELESS_TESTS_SUPPORTED
   2345        row != NULL && row_info != NULL &&
   2346 #endif
   2347       (row_info->color_type & PNG_COLOR_MASK_COLOR))
   2348    {
   2349       png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
   2350       png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
   2351       png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
   2352 
   2353       if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   2354       {
   2355          if (row_info->bit_depth == 8)
   2356          {
   2357 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2358             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
   2359             {
   2360                png_bytep sp = row;
   2361                png_bytep dp = row;
   2362 
   2363                for (i = 0; i < row_width; i++)
   2364                {
   2365                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
   2366                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
   2367                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
   2368                   if (red != green || red != blue)
   2369                   {
   2370                      rgb_error |= 1;
   2371                      *(dp++) = png_ptr->gamma_from_1[
   2372                        (rc*red + gc*green + bc*blue)>>15];
   2373                   }
   2374                   else
   2375                      *(dp++) = *(sp - 1);
   2376                }
   2377             }
   2378             else
   2379 #endif
   2380             {
   2381                png_bytep sp = row;
   2382                png_bytep dp = row;
   2383                for (i = 0; i < row_width; i++)
   2384                {
   2385                   png_byte red   = *(sp++);
   2386                   png_byte green = *(sp++);
   2387                   png_byte blue  = *(sp++);
   2388                   if (red != green || red != blue)
   2389                   {
   2390                      rgb_error |= 1;
   2391                      *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
   2392                   }
   2393                   else
   2394                      *(dp++) = *(sp - 1);
   2395                }
   2396             }
   2397          }
   2398 
   2399          else /* RGB bit_depth == 16 */
   2400          {
   2401 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2402             if (png_ptr->gamma_16_to_1 != NULL &&
   2403                 png_ptr->gamma_16_from_1 != NULL)
   2404             {
   2405                png_bytep sp = row;
   2406                png_bytep dp = row;
   2407                for (i = 0; i < row_width; i++)
   2408                {
   2409                   png_uint_16 red, green, blue, w;
   2410 
   2411                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2412                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2413                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2414 
   2415                   if (red == green && red == blue)
   2416                      w = red;
   2417                   else
   2418                   {
   2419                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
   2420                                   png_ptr->gamma_shift][red>>8];
   2421                      png_uint_16 green_1 =
   2422                          png_ptr->gamma_16_to_1[(green&0xff) >>
   2423                                   png_ptr->gamma_shift][green>>8];
   2424                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
   2425                                   png_ptr->gamma_shift][blue>>8];
   2426                      png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
   2427                                   + bc*blue_1)>>15);
   2428                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
   2429                          png_ptr->gamma_shift][gray16 >> 8];
   2430                      rgb_error |= 1;
   2431                   }
   2432 
   2433                   *(dp++) = (png_byte)((w>>8) & 0xff);
   2434                   *(dp++) = (png_byte)(w & 0xff);
   2435                }
   2436             }
   2437             else
   2438 #endif
   2439             {
   2440                png_bytep sp = row;
   2441                png_bytep dp = row;
   2442                for (i = 0; i < row_width; i++)
   2443                {
   2444                   png_uint_16 red, green, blue, gray16;
   2445 
   2446                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2447                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2448                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2449 
   2450                   if (red != green || red != blue)
   2451                      rgb_error |= 1;
   2452                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
   2453                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
   2454                   *(dp++) = (png_byte)(gray16 & 0xff);
   2455                }
   2456             }
   2457          }
   2458       }
   2459       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   2460       {
   2461          if (row_info->bit_depth == 8)
   2462          {
   2463 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2464             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
   2465             {
   2466                png_bytep sp = row;
   2467                png_bytep dp = row;
   2468                for (i = 0; i < row_width; i++)
   2469                {
   2470                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
   2471                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
   2472                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
   2473                   if (red != green || red != blue)
   2474                      rgb_error |= 1;
   2475                   *(dp++) =  png_ptr->gamma_from_1
   2476                              [(rc*red + gc*green + bc*blue)>>15];
   2477                   *(dp++) = *(sp++);  /* alpha */
   2478                }
   2479             }
   2480             else
   2481 #endif
   2482             {
   2483                png_bytep sp = row;
   2484                png_bytep dp = row;
   2485                for (i = 0; i < row_width; i++)
   2486                {
   2487                   png_byte red   = *(sp++);
   2488                   png_byte green = *(sp++);
   2489                   png_byte blue  = *(sp++);
   2490                   if (red != green || red != blue)
   2491                      rgb_error |= 1;
   2492                   *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
   2493                   *(dp++) = *(sp++);  /* alpha */
   2494                }
   2495             }
   2496          }
   2497          else /* RGBA bit_depth == 16 */
   2498          {
   2499 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   2500             if (png_ptr->gamma_16_to_1 != NULL &&
   2501                 png_ptr->gamma_16_from_1 != NULL)
   2502             {
   2503                png_bytep sp = row;
   2504                png_bytep dp = row;
   2505                for (i = 0; i < row_width; i++)
   2506                {
   2507                   png_uint_16 red, green, blue, w;
   2508 
   2509                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2510                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2511                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
   2512 
   2513                   if (red == green && red == blue)
   2514                      w = red;
   2515                   else
   2516                   {
   2517                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
   2518                          png_ptr->gamma_shift][red>>8];
   2519                      png_uint_16 green_1 =
   2520                          png_ptr->gamma_16_to_1[(green&0xff) >>
   2521                          png_ptr->gamma_shift][green>>8];
   2522                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
   2523                          png_ptr->gamma_shift][blue>>8];
   2524                      png_uint_16 gray16  = (png_uint_16)((rc * red_1
   2525                          + gc * green_1 + bc * blue_1)>>15);
   2526                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
   2527                          png_ptr->gamma_shift][gray16 >> 8];
   2528                      rgb_error |= 1;
   2529                   }
   2530 
   2531                   *(dp++) = (png_byte)((w>>8) & 0xff);
   2532                   *(dp++) = (png_byte)(w & 0xff);
   2533                   *(dp++) = *(sp++);  /* alpha */
   2534                   *(dp++) = *(sp++);
   2535                }
   2536             }
   2537             else
   2538 #endif
   2539             {
   2540                png_bytep sp = row;
   2541                png_bytep dp = row;
   2542                for (i = 0; i < row_width; i++)
   2543                {
   2544                   png_uint_16 red, green, blue, gray16;
   2545                   red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2546                   green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2547                   blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
   2548                   if (red != green || red != blue)
   2549                      rgb_error |= 1;
   2550                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
   2551                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
   2552                   *(dp++) = (png_byte)(gray16 & 0xff);
   2553                   *(dp++) = *(sp++);  /* alpha */
   2554                   *(dp++) = *(sp++);
   2555                }
   2556             }
   2557          }
   2558       }
   2559    row_info->channels -= (png_byte)2;
   2560       row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
   2561       row_info->pixel_depth = (png_byte)(row_info->channels *
   2562          row_info->bit_depth);
   2563       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   2564    }
   2565    return rgb_error;
   2566 }
   2567 #endif
   2568 
   2569 /* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
   2570  * large of png_color.  This lets grayscale images be treated as
   2571  * paletted.  Most useful for gamma correction and simplification
   2572  * of code.
   2573  */
   2574 void PNGAPI
   2575 png_build_grayscale_palette(int bit_depth, png_colorp palette)
   2576 {
   2577    int num_palette;
   2578    int color_inc;
   2579    int i;
   2580    int v;
   2581 
   2582    png_debug(1, "in png_do_build_grayscale_palette");
   2583 
   2584    if (palette == NULL)
   2585       return;
   2586 
   2587    switch (bit_depth)
   2588    {
   2589       case 1:
   2590          num_palette = 2;
   2591          color_inc = 0xff;
   2592          break;
   2593 
   2594       case 2:
   2595          num_palette = 4;
   2596          color_inc = 0x55;
   2597          break;
   2598 
   2599       case 4:
   2600          num_palette = 16;
   2601          color_inc = 0x11;
   2602          break;
   2603 
   2604       case 8:
   2605          num_palette = 256;
   2606          color_inc = 1;
   2607          break;
   2608 
   2609       default:
   2610          num_palette = 0;
   2611          color_inc = 0;
   2612          break;
   2613    }
   2614 
   2615    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
   2616    {
   2617       palette[i].red = (png_byte)v;
   2618       palette[i].green = (png_byte)v;
   2619       palette[i].blue = (png_byte)v;
   2620    }
   2621 }
   2622 
   2623 /* This function is currently unused.  Do we really need it? */
   2624 #if defined(PNG_READ_DITHER_SUPPORTED) && \
   2625   defined(PNG_CORRECT_PALETTE_SUPPORTED)
   2626 void /* PRIVATE */
   2627 png_correct_palette(png_structp png_ptr, png_colorp palette,
   2628    int num_palette)
   2629 {
   2630    png_debug(1, "in png_correct_palette");
   2631 
   2632 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
   2633     defined(PNG_READ_GAMMA_SUPPORTED) && \
   2634   defined(PNG_FLOATING_POINT_SUPPORTED)
   2635    if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
   2636    {
   2637       png_color back, back_1;
   2638 
   2639       if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
   2640       {
   2641          back.red = png_ptr->gamma_table[png_ptr->background.red];
   2642          back.green = png_ptr->gamma_table[png_ptr->background.green];
   2643          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
   2644 
   2645          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
   2646          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
   2647          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
   2648       }
   2649       else
   2650       {
   2651          double g;
   2652 
   2653          g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
   2654 
   2655          if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN
   2656              || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
   2657          {
   2658             back.red = png_ptr->background.red;
   2659             back.green = png_ptr->background.green;
   2660             back.blue = png_ptr->background.blue;
   2661          }
   2662          else
   2663          {
   2664             back.red =
   2665                (png_byte)(pow((double)png_ptr->background.red/255, g) *
   2666                 255.0 + 0.5);
   2667             back.green =
   2668                (png_byte)(pow((double)png_ptr->background.green/255, g) *
   2669                 255.0 + 0.5);
   2670             back.blue =
   2671                (png_byte)(pow((double)png_ptr->background.blue/255, g) *
   2672                 255.0 + 0.5);
   2673          }
   2674 
   2675          g = 1.0 / png_ptr->background_gamma;
   2676 
   2677          back_1.red =
   2678             (png_byte)(pow((double)png_ptr->background.red/255, g) *
   2679              255.0 + 0.5);
   2680          back_1.green =
   2681             (png_byte)(pow((double)png_ptr->background.green/255, g) *
   2682              255.0 + 0.5);
   2683          back_1.blue =
   2684             (png_byte)(pow((double)png_ptr->background.blue/255, g) *
   2685              255.0 + 0.5);
   2686       }
   2687 
   2688       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   2689       {
   2690          png_uint_32 i;
   2691 
   2692          for (i = 0; i < (png_uint_32)num_palette; i++)
   2693          {
   2694             if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
   2695             {
   2696                palette[i] = back;
   2697             }
   2698             else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
   2699             {
   2700                png_byte v, w;
   2701 
   2702                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
   2703                png_composite(w, v, png_ptr->trans[i], back_1.red);
   2704                palette[i].red = png_ptr->gamma_from_1[w];
   2705 
   2706                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
   2707                png_composite(w, v, png_ptr->trans[i], back_1.green);
   2708                palette[i].green = png_ptr->gamma_from_1[w];
   2709 
   2710                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
   2711                png_composite(w, v, png_ptr->trans[i], back_1.blue);
   2712                palette[i].blue = png_ptr->gamma_from_1[w];
   2713             }
   2714             else
   2715             {
   2716                palette[i].red = png_ptr->gamma_table[palette[i].red];
   2717                palette[i].green = png_ptr->gamma_table[palette[i].green];
   2718                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2719             }
   2720          }
   2721       }
   2722       else
   2723       {
   2724          int i;
   2725 
   2726          for (i = 0; i < num_palette; i++)
   2727          {
   2728             if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
   2729             {
   2730                palette[i] = back;
   2731             }
   2732             else
   2733             {
   2734                palette[i].red = png_ptr->gamma_table[palette[i].red];
   2735                palette[i].green = png_ptr->gamma_table[palette[i].green];
   2736                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2737             }
   2738          }
   2739       }
   2740    }
   2741    else
   2742 #endif
   2743 #ifdef PNG_READ_GAMMA_SUPPORTED
   2744    if (png_ptr->transformations & PNG_GAMMA)
   2745    {
   2746       int i;
   2747 
   2748       for (i = 0; i < num_palette; i++)
   2749       {
   2750          palette[i].red = png_ptr->gamma_table[palette[i].red];
   2751          palette[i].green = png_ptr->gamma_table[palette[i].green];
   2752          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   2753       }
   2754    }
   2755 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   2756    else
   2757 #endif
   2758 #endif
   2759 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   2760    if (png_ptr->transformations & PNG_BACKGROUND)
   2761    {
   2762       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   2763       {
   2764          png_color back;
   2765 
   2766          back.red   = (png_byte)png_ptr->background.red;
   2767          back.green = (png_byte)png_ptr->background.green;
   2768          back.blue  = (png_byte)png_ptr->background.blue;
   2769 
   2770          for (i = 0; i < (int)png_ptr->num_trans; i++)
   2771          {
   2772             if (png_ptr->trans[i] == 0)
   2773             {
   2774                palette[i].red = back.red;
   2775                palette[i].green = back.green;
   2776                palette[i].blue = back.blue;
   2777             }
   2778             else if (png_ptr->trans[i] != 0xff)
   2779             {
   2780                png_composite(palette[i].red, png_ptr->palette[i].red,
   2781                   png_ptr->trans[i], back.red);
   2782                png_composite(palette[i].green, png_ptr->palette[i].green,
   2783                   png_ptr->trans[i], back.green);
   2784                png_composite(palette[i].blue, png_ptr->palette[i].blue,
   2785                   png_ptr->trans[i], back.blue);
   2786             }
   2787          }
   2788       }
   2789       else /* Assume grayscale palette (what else could it be?) */
   2790       {
   2791          int i;
   2792 
   2793          for (i = 0; i < num_palette; i++)
   2794          {
   2795             if (i == (png_byte)png_ptr->trans_values.gray)
   2796             {
   2797                palette[i].red = (png_byte)png_ptr->background.red;
   2798                palette[i].green = (png_byte)png_ptr->background.green;
   2799                palette[i].blue = (png_byte)png_ptr->background.blue;
   2800             }
   2801          }
   2802       }
   2803    }
   2804 #endif
   2805 }
   2806 #endif
   2807 
   2808 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   2809 /* Replace any alpha or transparency with the supplied background color.
   2810  * "background" is already in the screen gamma, while "background_1" is
   2811  * at a gamma of 1.0.  Paletted files have already been taken care of.
   2812  */
   2813 void /* PRIVATE */
   2814 png_do_background(png_row_infop row_info, png_bytep row,
   2815    png_color_16p trans_values, png_color_16p background
   2816 #ifdef PNG_READ_GAMMA_SUPPORTED
   2817    , png_color_16p background_1,
   2818    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
   2819    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
   2820    png_uint_16pp gamma_16_to_1, int gamma_shift
   2821 #endif
   2822    )
   2823 {
   2824    png_bytep sp, dp;
   2825    png_uint_32 i;
   2826    png_uint_32 row_width=row_info->width;
   2827    int shift;
   2828 
   2829    png_debug(1, "in png_do_background");
   2830 
   2831    if (background != NULL &&
   2832 #ifdef PNG_USELESS_TESTS_SUPPORTED
   2833        row != NULL && row_info != NULL &&
   2834 #endif
   2835       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
   2836       (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
   2837    {
   2838       switch (row_info->color_type)
   2839       {
   2840          case PNG_COLOR_TYPE_GRAY:
   2841          {
   2842             switch (row_info->bit_depth)
   2843             {
   2844                case 1:
   2845                {
   2846                   sp = row;
   2847                   shift = 7;
   2848                   for (i = 0; i < row_width; i++)
   2849                   {
   2850                      if ((png_uint_16)((*sp >> shift) & 0x01)
   2851                         == trans_values->gray)
   2852                      {
   2853                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
   2854                         *sp |= (png_byte)(background->gray << shift);
   2855                      }
   2856                      if (!shift)
   2857                      {
   2858                         shift = 7;
   2859                         sp++;
   2860                      }
   2861                      else
   2862                         shift--;
   2863                   }
   2864                   break;
   2865                }
   2866 
   2867                case 2:
   2868                {
   2869 #ifdef PNG_READ_GAMMA_SUPPORTED
   2870                   if (gamma_table != NULL)
   2871                   {
   2872                      sp = row;
   2873                      shift = 6;
   2874                      for (i = 0; i < row_width; i++)
   2875                      {
   2876                         if ((png_uint_16)((*sp >> shift) & 0x03)
   2877                             == trans_values->gray)
   2878                         {
   2879                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2880                            *sp |= (png_byte)(background->gray << shift);
   2881                         }
   2882                         else
   2883                         {
   2884                            png_byte p = (png_byte)((*sp >> shift) & 0x03);
   2885                            png_byte g = (png_byte)((gamma_table [p | (p << 2) |
   2886                                (p << 4) | (p << 6)] >> 6) & 0x03);
   2887                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2888                            *sp |= (png_byte)(g << shift);
   2889                         }
   2890                         if (!shift)
   2891                         {
   2892                            shift = 6;
   2893                            sp++;
   2894                         }
   2895                         else
   2896                            shift -= 2;
   2897                      }
   2898                   }
   2899                   else
   2900 #endif
   2901                   {
   2902                      sp = row;
   2903                      shift = 6;
   2904                      for (i = 0; i < row_width; i++)
   2905                      {
   2906                         if ((png_uint_16)((*sp >> shift) & 0x03)
   2907                             == trans_values->gray)
   2908                         {
   2909                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2910                            *sp |= (png_byte)(background->gray << shift);
   2911                         }
   2912                         if (!shift)
   2913                         {
   2914                            shift = 6;
   2915                            sp++;
   2916                         }
   2917                         else
   2918                            shift -= 2;
   2919                      }
   2920                   }
   2921                   break;
   2922                }
   2923 
   2924                case 4:
   2925                {
   2926 #ifdef PNG_READ_GAMMA_SUPPORTED
   2927                   if (gamma_table != NULL)
   2928                   {
   2929                      sp = row;
   2930                      shift = 4;
   2931                      for (i = 0; i < row_width; i++)
   2932                      {
   2933                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   2934                             == trans_values->gray)
   2935                         {
   2936                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2937                            *sp |= (png_byte)(background->gray << shift);
   2938                         }
   2939                         else
   2940                         {
   2941                            png_byte p = (png_byte)((*sp >> shift) & 0x0f);
   2942                            png_byte g = (png_byte)((gamma_table[p |
   2943                              (p << 4)] >> 4) & 0x0f);
   2944                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2945                            *sp |= (png_byte)(g << shift);
   2946                         }
   2947                         if (!shift)
   2948                         {
   2949                            shift = 4;
   2950                            sp++;
   2951                         }
   2952                         else
   2953                            shift -= 4;
   2954                      }
   2955                   }
   2956                   else
   2957 #endif
   2958                   {
   2959                      sp = row;
   2960                      shift = 4;
   2961                      for (i = 0; i < row_width; i++)
   2962                      {
   2963                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   2964                             == trans_values->gray)
   2965                         {
   2966                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2967                            *sp |= (png_byte)(background->gray << shift);
   2968                         }
   2969                         if (!shift)
   2970                         {
   2971                            shift = 4;
   2972                            sp++;
   2973                         }
   2974                         else
   2975                            shift -= 4;
   2976                      }
   2977                   }
   2978                   break;
   2979                }
   2980 
   2981                case 8:
   2982                {
   2983 #ifdef PNG_READ_GAMMA_SUPPORTED
   2984                   if (gamma_table != NULL)
   2985                   {
   2986                      sp = row;
   2987                      for (i = 0; i < row_width; i++, sp++)
   2988                      {
   2989                         if (*sp == trans_values->gray)
   2990                         {
   2991                            *sp = (png_byte)background->gray;
   2992                         }
   2993                         else
   2994                         {
   2995                            *sp = gamma_table[*sp];
   2996                         }
   2997                      }
   2998                   }
   2999                   else
   3000 #endif
   3001                   {
   3002                      sp = row;
   3003                      for (i = 0; i < row_width; i++, sp++)
   3004                      {
   3005                         if (*sp == trans_values->gray)
   3006                         {
   3007                            *sp = (png_byte)background->gray;
   3008                         }
   3009                      }
   3010                   }
   3011                   break;
   3012                }
   3013 
   3014                case 16:
   3015                {
   3016 #ifdef PNG_READ_GAMMA_SUPPORTED
   3017                   if (gamma_16 != NULL)
   3018                   {
   3019                      sp = row;
   3020                      for (i = 0; i < row_width; i++, sp += 2)
   3021                      {
   3022                         png_uint_16 v;
   3023 
   3024                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3025                         if (v == trans_values->gray)
   3026                         {
   3027                            /* Background is already in screen gamma */
   3028                            *sp = (png_byte)((background->gray >> 8) & 0xff);
   3029                            *(sp + 1) = (png_byte)(background->gray & 0xff);
   3030                         }
   3031                         else
   3032                         {
   3033                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3034                            *sp = (png_byte)((v >> 8) & 0xff);
   3035                            *(sp + 1) = (png_byte)(v & 0xff);
   3036                         }
   3037                      }
   3038                   }
   3039                   else
   3040 #endif
   3041                   {
   3042                      sp = row;
   3043                      for (i = 0; i < row_width; i++, sp += 2)
   3044                      {
   3045                         png_uint_16 v;
   3046 
   3047                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3048                         if (v == trans_values->gray)
   3049                         {
   3050                            *sp = (png_byte)((background->gray >> 8) & 0xff);
   3051                            *(sp + 1) = (png_byte)(background->gray & 0xff);
   3052                         }
   3053                      }
   3054                   }
   3055                   break;
   3056                }
   3057             }
   3058             break;
   3059          }
   3060 
   3061          case PNG_COLOR_TYPE_RGB:
   3062          {
   3063             if (row_info->bit_depth == 8)
   3064             {
   3065 #ifdef PNG_READ_GAMMA_SUPPORTED
   3066                if (gamma_table != NULL)
   3067                {
   3068                   sp = row;
   3069                   for (i = 0; i < row_width; i++, sp += 3)
   3070                   {
   3071                      if (*sp == trans_values->red &&
   3072                         *(sp + 1) == trans_values->green &&
   3073                         *(sp + 2) == trans_values->blue)
   3074                      {
   3075                         *sp = (png_byte)background->red;
   3076                         *(sp + 1) = (png_byte)background->green;
   3077                         *(sp + 2) = (png_byte)background->blue;
   3078                      }
   3079                      else
   3080                      {
   3081                         *sp = gamma_table[*sp];
   3082                         *(sp + 1) = gamma_table[*(sp + 1)];
   3083                         *(sp + 2) = gamma_table[*(sp + 2)];
   3084                      }
   3085                   }
   3086                }
   3087                else
   3088 #endif
   3089                {
   3090                   sp = row;
   3091                   for (i = 0; i < row_width; i++, sp += 3)
   3092                   {
   3093                      if (*sp == trans_values->red &&
   3094                         *(sp + 1) == trans_values->green &&
   3095                         *(sp + 2) == trans_values->blue)
   3096                      {
   3097                         *sp = (png_byte)background->red;
   3098                         *(sp + 1) = (png_byte)background->green;
   3099                         *(sp + 2) = (png_byte)background->blue;
   3100                      }
   3101                   }
   3102                }
   3103             }
   3104             else /* if (row_info->bit_depth == 16) */
   3105             {
   3106 #ifdef PNG_READ_GAMMA_SUPPORTED
   3107                if (gamma_16 != NULL)
   3108                {
   3109                   sp = row;
   3110                   for (i = 0; i < row_width; i++, sp += 6)
   3111                   {
   3112                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3113                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3114                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
   3115                      if (r == trans_values->red && g == trans_values->green &&
   3116                         b == trans_values->blue)
   3117                      {
   3118                         /* Background is already in screen gamma */
   3119                         *sp = (png_byte)((background->red >> 8) & 0xff);
   3120                         *(sp + 1) = (png_byte)(background->red & 0xff);
   3121                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3122                         *(sp + 3) = (png_byte)(background->green & 0xff);
   3123                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3124                         *(sp + 5) = (png_byte)(background->blue & 0xff);
   3125                      }
   3126                      else
   3127                      {
   3128                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3129                         *sp = (png_byte)((v >> 8) & 0xff);
   3130                         *(sp + 1) = (png_byte)(v & 0xff);
   3131                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3132                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
   3133                         *(sp + 3) = (png_byte)(v & 0xff);
   3134                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3135                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
   3136                         *(sp + 5) = (png_byte)(v & 0xff);
   3137                      }
   3138                   }
   3139                }
   3140                else
   3141 #endif
   3142                {
   3143                   sp = row;
   3144                   for (i = 0; i < row_width; i++, sp += 6)
   3145                   {
   3146                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
   3147                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3148                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
   3149 
   3150                      if (r == trans_values->red && g == trans_values->green &&
   3151                         b == trans_values->blue)
   3152                      {
   3153                         *sp = (png_byte)((background->red >> 8) & 0xff);
   3154                         *(sp + 1) = (png_byte)(background->red & 0xff);
   3155                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3156                         *(sp + 3) = (png_byte)(background->green & 0xff);
   3157                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3158                         *(sp + 5) = (png_byte)(background->blue & 0xff);
   3159                      }
   3160                   }
   3161                }
   3162             }
   3163             break;
   3164          }
   3165 
   3166          case PNG_COLOR_TYPE_GRAY_ALPHA:
   3167          {
   3168             if (row_info->bit_depth == 8)
   3169             {
   3170 #ifdef PNG_READ_GAMMA_SUPPORTED
   3171                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3172                    gamma_table != NULL)
   3173                {
   3174                   sp = row;
   3175                   dp = row;
   3176                   for (i = 0; i < row_width; i++, sp += 2, dp++)
   3177                   {
   3178                      png_uint_16 a = *(sp + 1);
   3179 
   3180                      if (a == 0xff)
   3181                      {
   3182                         *dp = gamma_table[*sp];
   3183                      }
   3184                      else if (a == 0)
   3185                      {
   3186                         /* Background is already in screen gamma */
   3187                         *dp = (png_byte)background->gray;
   3188                      }
   3189                      else
   3190                      {
   3191                         png_byte v, w;
   3192 
   3193                         v = gamma_to_1[*sp];
   3194                         png_composite(w, v, a, background_1->gray);
   3195                         *dp = gamma_from_1[w];
   3196                      }
   3197                   }
   3198                }
   3199                else
   3200 #endif
   3201                {
   3202                   sp = row;
   3203                   dp = row;
   3204                   for (i = 0; i < row_width; i++, sp += 2, dp++)
   3205                   {
   3206                      png_byte a = *(sp + 1);
   3207 
   3208                      if (a == 0xff)
   3209                      {
   3210                         *dp = *sp;
   3211                      }
   3212 #ifdef PNG_READ_GAMMA_SUPPORTED
   3213                      else if (a == 0)
   3214                      {
   3215                         *dp = (png_byte)background->gray;
   3216                      }
   3217                      else
   3218                      {
   3219                         png_composite(*dp, *sp, a, background_1->gray);
   3220                      }
   3221 #else
   3222                      *dp = (png_byte)background->gray;
   3223 #endif
   3224                   }
   3225                }
   3226             }
   3227             else /* if (png_ptr->bit_depth == 16) */
   3228             {
   3229 #ifdef PNG_READ_GAMMA_SUPPORTED
   3230                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3231                    gamma_16_to_1 != NULL)
   3232                {
   3233                   sp = row;
   3234                   dp = row;
   3235                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
   3236                   {
   3237                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3238 
   3239                      if (a == (png_uint_16)0xffff)
   3240                      {
   3241                         png_uint_16 v;
   3242 
   3243                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3244                         *dp = (png_byte)((v >> 8) & 0xff);
   3245                         *(dp + 1) = (png_byte)(v & 0xff);
   3246                      }
   3247 #ifdef PNG_READ_GAMMA_SUPPORTED
   3248                      else if (a == 0)
   3249 #else
   3250                      else
   3251 #endif
   3252                      {
   3253                         /* Background is already in screen gamma */
   3254                         *dp = (png_byte)((background->gray >> 8) & 0xff);
   3255                         *(dp + 1) = (png_byte)(background->gray & 0xff);
   3256                      }
   3257 #ifdef PNG_READ_GAMMA_SUPPORTED
   3258                      else
   3259                      {
   3260                         png_uint_16 g, v, w;
   3261 
   3262                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3263                         png_composite_16(v, g, a, background_1->gray);
   3264                         w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
   3265                         *dp = (png_byte)((w >> 8) & 0xff);
   3266                         *(dp + 1) = (png_byte)(w & 0xff);
   3267                      }
   3268 #endif
   3269                   }
   3270                }
   3271                else
   3272 #endif
   3273                {
   3274                   sp = row;
   3275                   dp = row;
   3276                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
   3277                   {
   3278                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
   3279                      if (a == (png_uint_16)0xffff)
   3280                      {
   3281                         png_memcpy(dp, sp, 2);
   3282                      }
   3283 #ifdef PNG_READ_GAMMA_SUPPORTED
   3284                      else if (a == 0)
   3285 #else
   3286                      else
   3287 #endif
   3288                      {
   3289                         *dp = (png_byte)((background->gray >> 8) & 0xff);
   3290                         *(dp + 1) = (png_byte)(background->gray & 0xff);
   3291                      }
   3292 #ifdef PNG_READ_GAMMA_SUPPORTED
   3293                      else
   3294                      {
   3295                         png_uint_16 g, v;
   3296 
   3297                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3298                         png_composite_16(v, g, a, background_1->gray);
   3299                         *dp = (png_byte)((v >> 8) & 0xff);
   3300                         *(dp + 1) = (png_byte)(v & 0xff);
   3301                      }
   3302 #endif
   3303                   }
   3304                }
   3305             }
   3306             break;
   3307          }
   3308 
   3309          case PNG_COLOR_TYPE_RGB_ALPHA:
   3310          {
   3311             if (row_info->bit_depth == 8)
   3312             {
   3313 #ifdef PNG_READ_GAMMA_SUPPORTED
   3314                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3315                    gamma_table != NULL)
   3316                {
   3317                   sp = row;
   3318                   dp = row;
   3319                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
   3320                   {
   3321                      png_byte a = *(sp + 3);
   3322 
   3323                      if (a == 0xff)
   3324                      {
   3325                         *dp = gamma_table[*sp];
   3326                         *(dp + 1) = gamma_table[*(sp + 1)];
   3327                         *(dp + 2) = gamma_table[*(sp + 2)];
   3328                      }
   3329                      else if (a == 0)
   3330                      {
   3331                         /* Background is already in screen gamma */
   3332                         *dp = (png_byte)background->red;
   3333                         *(dp + 1) = (png_byte)background->green;
   3334                         *(dp + 2) = (png_byte)background->blue;
   3335                      }
   3336                      else
   3337                      {
   3338                         png_byte v, w;
   3339 
   3340                         v = gamma_to_1[*sp];
   3341                         png_composite(w, v, a, background_1->red);
   3342                         *dp = gamma_from_1[w];
   3343                         v = gamma_to_1[*(sp + 1)];
   3344                         png_composite(w, v, a, background_1->green);
   3345                         *(dp + 1) = gamma_from_1[w];
   3346                         v = gamma_to_1[*(sp + 2)];
   3347                         png_composite(w, v, a, background_1->blue);
   3348                         *(dp + 2) = gamma_from_1[w];
   3349                      }
   3350                   }
   3351                }
   3352                else
   3353 #endif
   3354                {
   3355                   sp = row;
   3356                   dp = row;
   3357                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
   3358                   {
   3359                      png_byte a = *(sp + 3);
   3360 
   3361                      if (a == 0xff)
   3362                      {
   3363                         *dp = *sp;
   3364                         *(dp + 1) = *(sp + 1);
   3365                         *(dp + 2) = *(sp + 2);
   3366                      }
   3367                      else if (a == 0)
   3368                      {
   3369                         *dp = (png_byte)background->red;
   3370                         *(dp + 1) = (png_byte)background->green;
   3371                         *(dp + 2) = (png_byte)background->blue;
   3372                      }
   3373                      else
   3374                      {
   3375                         png_composite(*dp, *sp, a, background->red);
   3376                         png_composite(*(dp + 1), *(sp + 1), a,
   3377                            background->green);
   3378                         png_composite(*(dp + 2), *(sp + 2), a,
   3379                            background->blue);
   3380                      }
   3381                   }
   3382                }
   3383             }
   3384             else /* if (row_info->bit_depth == 16) */
   3385             {
   3386 #ifdef PNG_READ_GAMMA_SUPPORTED
   3387                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3388                    gamma_16_to_1 != NULL)
   3389                {
   3390                   sp = row;
   3391                   dp = row;
   3392                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
   3393                   {
   3394                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3395                          << 8) + (png_uint_16)(*(sp + 7)));
   3396                      if (a == (png_uint_16)0xffff)
   3397                      {
   3398                         png_uint_16 v;
   3399 
   3400                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3401                         *dp = (png_byte)((v >> 8) & 0xff);
   3402                         *(dp + 1) = (png_byte)(v & 0xff);
   3403                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3404                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
   3405                         *(dp + 3) = (png_byte)(v & 0xff);
   3406                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3407                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
   3408                         *(dp + 5) = (png_byte)(v & 0xff);
   3409                      }
   3410                      else if (a == 0)
   3411                      {
   3412                         /* Background is already in screen gamma */
   3413                         *dp = (png_byte)((background->red >> 8) & 0xff);
   3414                         *(dp + 1) = (png_byte)(background->red & 0xff);
   3415                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3416                         *(dp + 3) = (png_byte)(background->green & 0xff);
   3417                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3418                         *(dp + 5) = (png_byte)(background->blue & 0xff);
   3419                      }
   3420                      else
   3421                      {
   3422                         png_uint_16 v, w, x;
   3423 
   3424                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3425                         png_composite_16(w, v, a, background_1->red);
   3426                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
   3427                         *dp = (png_byte)((x >> 8) & 0xff);
   3428                         *(dp + 1) = (png_byte)(x & 0xff);
   3429                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3430                         png_composite_16(w, v, a, background_1->green);
   3431                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
   3432                         *(dp + 2) = (png_byte)((x >> 8) & 0xff);
   3433                         *(dp + 3) = (png_byte)(x & 0xff);
   3434                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3435                         png_composite_16(w, v, a, background_1->blue);
   3436                         x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
   3437                         *(dp + 4) = (png_byte)((x >> 8) & 0xff);
   3438                         *(dp + 5) = (png_byte)(x & 0xff);
   3439                      }
   3440                   }
   3441                }
   3442                else
   3443 #endif
   3444                {
   3445                   sp = row;
   3446                   dp = row;
   3447                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
   3448                   {
   3449                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3450                         << 8) + (png_uint_16)(*(sp + 7)));
   3451                      if (a == (png_uint_16)0xffff)
   3452                      {
   3453                         png_memcpy(dp, sp, 6);
   3454                      }
   3455                      else if (a == 0)
   3456                      {
   3457                         *dp = (png_byte)((background->red >> 8) & 0xff);
   3458                         *(dp + 1) = (png_byte)(background->red & 0xff);
   3459                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
   3460                         *(dp + 3) = (png_byte)(background->green & 0xff);
   3461                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
   3462                         *(dp + 5) = (png_byte)(background->blue & 0xff);
   3463                      }
   3464                      else
   3465                      {
   3466                         png_uint_16 v;
   3467 
   3468                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3469                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
   3470                             + *(sp + 3));
   3471                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
   3472                             + *(sp + 5));
   3473 
   3474                         png_composite_16(v, r, a, background->red);
   3475                         *dp = (png_byte)((v >> 8) & 0xff);
   3476                         *(dp + 1) = (png_byte)(v & 0xff);
   3477                         png_composite_16(v, g, a, background->green);
   3478                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
   3479                         *(dp + 3) = (png_byte)(v & 0xff);
   3480                         png_composite_16(v, b, a, background->blue);
   3481                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
   3482                         *(dp + 5) = (png_byte)(v & 0xff);
   3483                      }
   3484                   }
   3485                }
   3486             }
   3487             break;
   3488          }
   3489       }
   3490 
   3491       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
   3492       {
   3493          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
   3494          row_info->channels--;
   3495          row_info->pixel_depth = (png_byte)(row_info->channels *
   3496             row_info->bit_depth);
   3497          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   3498       }
   3499    }
   3500 }
   3501 #endif
   3502 
   3503 #ifdef PNG_READ_GAMMA_SUPPORTED
   3504 /* Gamma correct the image, avoiding the alpha channel.  Make sure
   3505  * you do this after you deal with the transparency issue on grayscale
   3506  * or RGB images. If your bit depth is 8, use gamma_table, if it
   3507  * is 16, use gamma_16_table and gamma_shift.  Build these with
   3508  * build_gamma_table().
   3509  */
   3510 void /* PRIVATE */
   3511 png_do_gamma(png_row_infop row_info, png_bytep row,
   3512    png_bytep gamma_table, png_uint_16pp gamma_16_table,
   3513    int gamma_shift)
   3514 {
   3515    png_bytep sp;
   3516    png_uint_32 i;
   3517    png_uint_32 row_width=row_info->width;
   3518 
   3519    png_debug(1, "in png_do_gamma");
   3520 
   3521    if (
   3522 #ifdef PNG_USELESS_TESTS_SUPPORTED
   3523        row != NULL && row_info != NULL &&
   3524 #endif
   3525        ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
   3526         (row_info->bit_depth == 16 && gamma_16_table != NULL)))
   3527    {
   3528       switch (row_info->color_type)
   3529       {
   3530          case PNG_COLOR_TYPE_RGB:
   3531          {
   3532             if (row_info->bit_depth == 8)
   3533             {
   3534                sp = row;
   3535                for (i = 0; i < row_width; i++)
   3536                {
   3537                   *sp = gamma_table[*sp];
   3538                   sp++;
   3539                   *sp = gamma_table[*sp];
   3540                   sp++;
   3541                   *sp = gamma_table[*sp];
   3542                   sp++;
   3543                }
   3544             }
   3545             else /* if (row_info->bit_depth == 16) */
   3546             {
   3547                sp = row;
   3548                for (i = 0; i < row_width; i++)
   3549                {
   3550                   png_uint_16 v;
   3551 
   3552                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3553                   *sp = (png_byte)((v >> 8) & 0xff);
   3554                   *(sp + 1) = (png_byte)(v & 0xff);
   3555                   sp += 2;
   3556                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3557                   *sp = (png_byte)((v >> 8) & 0xff);
   3558                   *(sp + 1) = (png_byte)(v & 0xff);
   3559                   sp += 2;
   3560                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3561                   *sp = (png_byte)((v >> 8) & 0xff);
   3562                   *(sp + 1) = (png_byte)(v & 0xff);
   3563                   sp += 2;
   3564                }
   3565             }
   3566             break;
   3567          }
   3568 
   3569          case PNG_COLOR_TYPE_RGB_ALPHA:
   3570          {
   3571             if (row_info->bit_depth == 8)
   3572             {
   3573                sp = row;
   3574                for (i = 0; i < row_width; i++)
   3575                {
   3576                   *sp = gamma_table[*sp];
   3577                   sp++;
   3578                   *sp = gamma_table[*sp];
   3579                   sp++;
   3580                   *sp = gamma_table[*sp];
   3581                   sp++;
   3582                   sp++;
   3583                }
   3584             }
   3585             else /* if (row_info->bit_depth == 16) */
   3586             {
   3587                sp = row;
   3588                for (i = 0; i < row_width; i++)
   3589                {
   3590                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3591                   *sp = (png_byte)((v >> 8) & 0xff);
   3592                   *(sp + 1) = (png_byte)(v & 0xff);
   3593                   sp += 2;
   3594                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3595                   *sp = (png_byte)((v >> 8) & 0xff);
   3596                   *(sp + 1) = (png_byte)(v & 0xff);
   3597                   sp += 2;
   3598                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3599                   *sp = (png_byte)((v >> 8) & 0xff);
   3600                   *(sp + 1) = (png_byte)(v & 0xff);
   3601                   sp += 4;
   3602                }
   3603             }
   3604             break;
   3605          }
   3606 
   3607          case PNG_COLOR_TYPE_GRAY_ALPHA:
   3608          {
   3609             if (row_info->bit_depth == 8)
   3610             {
   3611                sp = row;
   3612                for (i = 0; i < row_width; i++)
   3613                {
   3614                   *sp = gamma_table[*sp];
   3615                   sp += 2;
   3616                }
   3617             }
   3618             else /* if (row_info->bit_depth == 16) */
   3619             {
   3620                sp = row;
   3621                for (i = 0; i < row_width; i++)
   3622                {
   3623                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3624                   *sp = (png_byte)((v >> 8) & 0xff);
   3625                   *(sp + 1) = (png_byte)(v & 0xff);
   3626                   sp += 4;
   3627                }
   3628             }
   3629             break;
   3630          }
   3631 
   3632          case PNG_COLOR_TYPE_GRAY:
   3633          {
   3634             if (row_info->bit_depth == 2)
   3635             {
   3636                sp = row;
   3637                for (i = 0; i < row_width; i += 4)
   3638                {
   3639                   int a = *sp & 0xc0;
   3640                   int b = *sp & 0x30;
   3641                   int c = *sp & 0x0c;
   3642                   int d = *sp & 0x03;
   3643 
   3644                   *sp = (png_byte)(
   3645                       ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
   3646                       ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
   3647                       ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
   3648                       ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
   3649                   sp++;
   3650                }
   3651             }
   3652 
   3653             if (row_info->bit_depth == 4)
   3654             {
   3655                sp = row;
   3656                for (i = 0; i < row_width; i += 2)
   3657                {
   3658                   int msb = *sp & 0xf0;
   3659                   int lsb = *sp & 0x0f;
   3660 
   3661                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
   3662                       | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
   3663                   sp++;
   3664                }
   3665             }
   3666 
   3667             else if (row_info->bit_depth == 8)
   3668             {
   3669                sp = row;
   3670                for (i = 0; i < row_width; i++)
   3671                {
   3672                   *sp = gamma_table[*sp];
   3673                   sp++;
   3674                }
   3675             }
   3676 
   3677             else if (row_info->bit_depth == 16)
   3678             {
   3679                sp = row;
   3680                for (i = 0; i < row_width; i++)
   3681                {
   3682                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3683                   *sp = (png_byte)((v >> 8) & 0xff);
   3684                   *(sp + 1) = (png_byte)(v & 0xff);
   3685                   sp += 2;
   3686                }
   3687             }
   3688             break;
   3689          }
   3690       }
   3691    }
   3692 }
   3693 #endif
   3694 
   3695 #ifdef PNG_READ_EXPAND_SUPPORTED
   3696 /* Expands a palette row to an RGB or RGBA row depending
   3697  * upon whether you supply trans and num_trans.
   3698  */
   3699 void /* PRIVATE */
   3700 png_do_expand_palette(png_row_infop row_info, png_bytep row,
   3701    png_colorp palette, png_bytep trans, int num_trans)
   3702 {
   3703    int shift, value;
   3704    png_bytep sp, dp;
   3705    png_uint_32 i;
   3706    png_uint_32 row_width=row_info->width;
   3707 
   3708    png_debug(1, "in png_do_expand_palette");
   3709 
   3710    if (
   3711 #ifdef PNG_USELESS_TESTS_SUPPORTED
   3712        row != NULL && row_info != NULL &&
   3713 #endif
   3714        row_info->color_type == PNG_COLOR_TYPE_PALETTE)
   3715    {
   3716       if (row_info->bit_depth < 8)
   3717       {
   3718          switch (row_info->bit_depth)
   3719          {
   3720             case 1:
   3721             {
   3722                sp = row + (png_size_t)((row_width - 1) >> 3);
   3723                dp = row + (png_size_t)row_width - 1;
   3724                shift = 7 - (int)((row_width + 7) & 0x07);
   3725                for (i = 0; i < row_width; i++)
   3726                {
   3727                   if ((*sp >> shift) & 0x01)
   3728                      *dp = 1;
   3729                   else
   3730                      *dp = 0;
   3731                   if (shift == 7)
   3732                   {
   3733                      shift = 0;
   3734                      sp--;
   3735                   }
   3736                   else
   3737                      shift++;
   3738 
   3739                   dp--;
   3740                }
   3741                break;
   3742             }
   3743 
   3744             case 2:
   3745             {
   3746                sp = row + (png_size_t)((row_width - 1) >> 2);
   3747                dp = row + (png_size_t)row_width - 1;
   3748                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   3749                for (i = 0; i < row_width; i++)
   3750                {
   3751                   value = (*sp >> shift) & 0x03;
   3752                   *dp = (png_byte)value;
   3753                   if (shift == 6)
   3754                   {
   3755                      shift = 0;
   3756                      sp--;
   3757                   }
   3758                   else
   3759                      shift += 2;
   3760 
   3761                   dp--;
   3762                }
   3763                break;
   3764             }
   3765 
   3766             case 4:
   3767             {
   3768                sp = row + (png_size_t)((row_width - 1) >> 1);
   3769                dp = row + (png_size_t)row_width - 1;
   3770                shift = (int)((row_width & 0x01) << 2);
   3771                for (i = 0; i < row_width; i++)
   3772                {
   3773                   value = (*sp >> shift) & 0x0f;
   3774                   *dp = (png_byte)value;
   3775                   if (shift == 4)
   3776                   {
   3777                      shift = 0;
   3778                      sp--;
   3779                   }
   3780                   else
   3781                      shift += 4;
   3782 
   3783                   dp--;
   3784                }
   3785                break;
   3786             }
   3787          }
   3788          row_info->bit_depth = 8;
   3789          row_info->pixel_depth = 8;
   3790          row_info->rowbytes = row_width;
   3791       }
   3792       switch (row_info->bit_depth)
   3793       {
   3794          case 8:
   3795          {
   3796             if (trans != NULL)
   3797             {
   3798                sp = row + (png_size_t)row_width - 1;
   3799                dp = row + (png_size_t)(row_width << 2) - 1;
   3800 
   3801                for (i = 0; i < row_width; i++)
   3802                {
   3803                   if ((int)(*sp) >= num_trans)
   3804                      *dp-- = 0xff;
   3805                   else
   3806                      *dp-- = trans[*sp];
   3807                   *dp-- = palette[*sp].blue;
   3808                   *dp-- = palette[*sp].green;
   3809                   *dp-- = palette[*sp].red;
   3810                   sp--;
   3811                }
   3812                row_info->bit_depth = 8;
   3813                row_info->pixel_depth = 32;
   3814                row_info->rowbytes = row_width * 4;
   3815                row_info->color_type = 6;
   3816                row_info->channels = 4;
   3817             }
   3818             else
   3819             {
   3820                sp = row + (png_size_t)row_width - 1;
   3821                dp = row + (png_size_t)(row_width * 3) - 1;
   3822 
   3823                for (i = 0; i < row_width; i++)
   3824                {
   3825                   *dp-- = palette[*sp].blue;
   3826                   *dp-- = palette[*sp].green;
   3827                   *dp-- = palette[*sp].red;
   3828                   sp--;
   3829                }
   3830 
   3831                row_info->bit_depth = 8;
   3832                row_info->pixel_depth = 24;
   3833                row_info->rowbytes = row_width * 3;
   3834                row_info->color_type = 2;
   3835                row_info->channels = 3;
   3836             }
   3837             break;
   3838          }
   3839       }
   3840    }
   3841 }
   3842 
   3843 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
   3844  * expanded transparency value is supplied, an alpha channel is built.
   3845  */
   3846 void /* PRIVATE */
   3847 png_do_expand(png_row_infop row_info, png_bytep row,
   3848    png_color_16p trans_value)
   3849 {
   3850    int shift, value;
   3851    png_bytep sp, dp;
   3852    png_uint_32 i;
   3853    png_uint_32 row_width=row_info->width;
   3854 
   3855    png_debug(1, "in png_do_expand");
   3856 
   3857 #ifdef PNG_USELESS_TESTS_SUPPORTED
   3858    if (row != NULL && row_info != NULL)
   3859 #endif
   3860    {
   3861       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   3862       {
   3863          png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
   3864 
   3865          if (row_info->bit_depth < 8)
   3866          {
   3867             switch (row_info->bit_depth)
   3868             {
   3869                case 1:
   3870                {
   3871                   gray = (png_uint_16)((gray&0x01)*0xff);
   3872                   sp = row + (png_size_t)((row_width - 1) >> 3);
   3873                   dp = row + (png_size_t)row_width - 1;
   3874                   shift = 7 - (int)((row_width + 7) & 0x07);
   3875                   for (i = 0; i < row_width; i++)
   3876                   {
   3877                      if ((*sp >> shift) & 0x01)
   3878                         *dp = 0xff;
   3879                      else
   3880                         *dp = 0;
   3881                      if (shift == 7)
   3882                      {
   3883                         shift = 0;
   3884                         sp--;
   3885                      }
   3886                      else
   3887                         shift++;
   3888 
   3889                      dp--;
   3890                   }
   3891                   break;
   3892                }
   3893 
   3894                case 2:
   3895                {
   3896                   gray = (png_uint_16)((gray&0x03)*0x55);
   3897                   sp = row + (png_size_t)((row_width - 1) >> 2);
   3898                   dp = row + (png_size_t)row_width - 1;
   3899                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   3900                   for (i = 0; i < row_width; i++)
   3901                   {
   3902                      value = (*sp >> shift) & 0x03;
   3903                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
   3904                         (value << 6));
   3905                      if (shift == 6)
   3906                      {
   3907                         shift = 0;
   3908                         sp--;
   3909                      }
   3910                      else
   3911                         shift += 2;
   3912 
   3913                      dp--;
   3914                   }
   3915                   break;
   3916                }
   3917 
   3918                case 4:
   3919                {
   3920                   gray = (png_uint_16)((gray&0x0f)*0x11);
   3921                   sp = row + (png_size_t)((row_width - 1) >> 1);
   3922                   dp = row + (png_size_t)row_width - 1;
   3923                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   3924                   for (i = 0; i < row_width; i++)
   3925                   {
   3926                      value = (*sp >> shift) & 0x0f;
   3927                      *dp = (png_byte)(value | (value << 4));
   3928                      if (shift == 4)
   3929                      {
   3930                         shift = 0;
   3931                         sp--;
   3932                      }
   3933                      else
   3934                         shift = 4;
   3935 
   3936                      dp--;
   3937                   }
   3938                   break;
   3939                }
   3940             }
   3941 
   3942             row_info->bit_depth = 8;
   3943             row_info->pixel_depth = 8;
   3944             row_info->rowbytes = row_width;
   3945          }
   3946 
   3947          if (trans_value != NULL)
   3948          {
   3949             if (row_info->bit_depth == 8)
   3950             {
   3951                gray = gray & 0xff;
   3952                sp = row + (png_size_t)row_width - 1;
   3953                dp = row + (png_size_t)(row_width << 1) - 1;
   3954                for (i = 0; i < row_width; i++)
   3955                {
   3956                   if (*sp == gray)
   3957                      *dp-- = 0;
   3958                   else
   3959                      *dp-- = 0xff;
   3960                   *dp-- = *sp--;
   3961                }
   3962             }
   3963 
   3964             else if (row_info->bit_depth == 16)
   3965             {
   3966                png_byte gray_high = (gray >> 8) & 0xff;
   3967                png_byte gray_low = gray & 0xff;
   3968                sp = row + row_info->rowbytes - 1;
   3969                dp = row + (row_info->rowbytes << 1) - 1;
   3970                for (i = 0; i < row_width; i++)
   3971                {
   3972                   if (*(sp - 1) == gray_high && *(sp) == gray_low)
   3973                   {
   3974                      *dp-- = 0;
   3975                      *dp-- = 0;
   3976                   }
   3977                   else
   3978                   {
   3979                      *dp-- = 0xff;
   3980                      *dp-- = 0xff;
   3981                   }
   3982                   *dp-- = *sp--;
   3983                   *dp-- = *sp--;
   3984                }
   3985             }
   3986 
   3987             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
   3988             row_info->channels = 2;
   3989             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
   3990             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
   3991                row_width);
   3992          }
   3993       }
   3994       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
   3995       {
   3996          if (row_info->bit_depth == 8)
   3997          {
   3998             png_byte red = trans_value->red & 0xff;
   3999             png_byte green = trans_value->green & 0xff;
   4000             png_byte blue = trans_value->blue & 0xff;
   4001             sp = row + (png_size_t)row_info->rowbytes - 1;
   4002             dp = row + (png_size_t)(row_width << 2) - 1;
   4003             for (i = 0; i < row_width; i++)
   4004             {
   4005                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
   4006                   *dp-- = 0;
   4007                else
   4008                   *dp-- = 0xff;
   4009                *dp-- = *sp--;
   4010                *dp-- = *sp--;
   4011                *dp-- = *sp--;
   4012             }
   4013          }
   4014          else if (row_info->bit_depth == 16)
   4015          {
   4016             png_byte red_high = (trans_value->red >> 8) & 0xff;
   4017             png_byte green_high = (trans_value->green >> 8) & 0xff;
   4018             png_byte blue_high = (trans_value->blue >> 8) & 0xff;
   4019             png_byte red_low = trans_value->red & 0xff;
   4020             png_byte green_low = trans_value->green & 0xff;
   4021             png_byte blue_low = trans_value->blue & 0xff;
   4022             sp = row + row_info->rowbytes - 1;
   4023             dp = row + (png_size_t)(row_width << 3) - 1;
   4024             for (i = 0; i < row_width; i++)
   4025             {
   4026                if (*(sp - 5) == red_high &&
   4027                   *(sp - 4) == red_low &&
   4028                   *(sp - 3) == green_high &&
   4029                   *(sp - 2) == green_low &&
   4030                   *(sp - 1) == blue_high &&
   4031                   *(sp    ) == blue_low)
   4032                {
   4033                   *dp-- = 0;
   4034                   *dp-- = 0;
   4035                }
   4036                else
   4037                {
   4038                   *dp-- = 0xff;
   4039                   *dp-- = 0xff;
   4040                }
   4041                *dp-- = *sp--;
   4042                *dp-- = *sp--;
   4043                *dp-- = *sp--;
   4044                *dp-- = *sp--;
   4045                *dp-- = *sp--;
   4046                *dp-- = *sp--;
   4047             }
   4048          }
   4049          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   4050          row_info->channels = 4;
   4051          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
   4052          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4053       }
   4054    }
   4055 }
   4056 #endif
   4057 
   4058 #ifdef PNG_READ_DITHER_SUPPORTED
   4059 void /* PRIVATE */
   4060 png_do_dither(png_row_infop row_info, png_bytep row,
   4061     png_bytep palette_lookup, png_bytep dither_lookup)
   4062 {
   4063    png_bytep sp, dp;
   4064    png_uint_32 i;
   4065    png_uint_32 row_width=row_info->width;
   4066 
   4067    png_debug(1, "in png_do_dither");
   4068 
   4069 #ifdef PNG_USELESS_TESTS_SUPPORTED
   4070    if (row != NULL && row_info != NULL)
   4071 #endif
   4072    {
   4073       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
   4074          palette_lookup && row_info->bit_depth == 8)
   4075       {
   4076          int r, g, b, p;
   4077          sp = row;
   4078          dp = row;
   4079          for (i = 0; i < row_width; i++)
   4080          {
   4081             r = *sp++;
   4082             g = *sp++;
   4083             b = *sp++;
   4084 
   4085             /* This looks real messy, but the compiler will reduce
   4086              * it down to a reasonable formula.  For example, with
   4087              * 5 bits per color, we get:
   4088              * p = (((r >> 3) & 0x1f) << 10) |
   4089              *    (((g >> 3) & 0x1f) << 5) |
   4090              *    ((b >> 3) & 0x1f);
   4091              */
   4092             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
   4093                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
   4094                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
   4095                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
   4096                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
   4097                (PNG_DITHER_BLUE_BITS)) |
   4098                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
   4099                ((1 << PNG_DITHER_BLUE_BITS) - 1));
   4100 
   4101             *dp++ = palette_lookup[p];
   4102          }
   4103          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   4104          row_info->channels = 1;
   4105          row_info->pixel_depth = row_info->bit_depth;
   4106          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4107       }
   4108       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
   4109          palette_lookup != NULL && row_info->bit_depth == 8)
   4110       {
   4111          int r, g, b, p;
   4112          sp = row;
   4113          dp = row;
   4114          for (i = 0; i < row_width; i++)
   4115          {
   4116             r = *sp++;
   4117             g = *sp++;
   4118             b = *sp++;
   4119             sp++;
   4120 
   4121             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
   4122                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
   4123                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
   4124                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
   4125                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
   4126                (PNG_DITHER_BLUE_BITS)) |
   4127                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
   4128                ((1 << PNG_DITHER_BLUE_BITS) - 1));
   4129 
   4130             *dp++ = palette_lookup[p];
   4131          }
   4132          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   4133          row_info->channels = 1;
   4134          row_info->pixel_depth = row_info->bit_depth;
   4135          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4136       }
   4137       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
   4138          dither_lookup && row_info->bit_depth == 8)
   4139       {
   4140          sp = row;
   4141          for (i = 0; i < row_width; i++, sp++)
   4142          {
   4143             *sp = dither_lookup[*sp];
   4144          }
   4145       }
   4146    }
   4147 }
   4148 #endif
   4149 
   4150 #ifdef PNG_FLOATING_POINT_SUPPORTED
   4151 #ifdef PNG_READ_GAMMA_SUPPORTED
   4152 static PNG_CONST int png_gamma_shift[] =
   4153    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
   4154 
   4155 /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
   4156  * tables, we don't make a full table if we are reducing to 8-bit in
   4157  * the future.  Note also how the gamma_16 tables are segmented so that
   4158  * we don't need to allocate > 64K chunks for a full 16-bit table.
   4159  *
   4160  * See the PNG extensions document for an integer algorithm for creating
   4161  * the gamma tables.  Maybe we will implement that here someday.
   4162  *
   4163  * We should only reach this point if
   4164  *
   4165  *      the file_gamma is known (i.e., the gAMA or sRGB chunk is present,
   4166  *      or the application has provided a file_gamma)
   4167  *
   4168  *   AND
   4169  *      {
   4170  *         the screen_gamma is known
   4171  *      OR
   4172  *
   4173  *         RGB_to_gray transformation is being performed
   4174  *      }
   4175  *
   4176  *   AND
   4177  *      {
   4178  *         the screen_gamma is different from the reciprocal of the
   4179  *         file_gamma by more than the specified threshold
   4180  *
   4181  *      OR
   4182  *
   4183  *         a background color has been specified and the file_gamma
   4184  *         and screen_gamma are not 1.0, within the specified threshold.
   4185  *      }
   4186  */
   4187 
   4188 void /* PRIVATE */
   4189 png_build_gamma_table(png_structp png_ptr)
   4190 {
   4191   png_debug(1, "in png_build_gamma_table");
   4192 
   4193   if (png_ptr->bit_depth <= 8)
   4194   {
   4195      int i;
   4196      double g;
   4197 
   4198      if (png_ptr->screen_gamma > .000001)
   4199         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
   4200 
   4201      else
   4202         g = 1.0;
   4203 
   4204      png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
   4205         (png_uint_32)256);
   4206 
   4207      for (i = 0; i < 256; i++)
   4208      {
   4209         png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
   4210            g) * 255.0 + .5);
   4211      }
   4212 
   4213 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
   4214    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   4215      if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
   4216      {
   4217 
   4218         g = 1.0 / (png_ptr->gamma);
   4219 
   4220         png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
   4221            (png_uint_32)256);
   4222 
   4223         for (i = 0; i < 256; i++)
   4224         {
   4225            png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
   4226               g) * 255.0 + .5);
   4227         }
   4228 
   4229 
   4230         png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
   4231            (png_uint_32)256);
   4232 
   4233         if (png_ptr->screen_gamma > 0.000001)
   4234            g = 1.0 / png_ptr->screen_gamma;
   4235 
   4236         else
   4237            g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
   4238 
   4239         for (i = 0; i < 256; i++)
   4240         {
   4241            png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
   4242               g) * 255.0 + .5);
   4243 
   4244         }
   4245      }
   4246 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
   4247   }
   4248   else
   4249   {
   4250      double g;
   4251      int i, j, shift, num;
   4252      int sig_bit;
   4253      png_uint_32 ig;
   4254 
   4255      if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
   4256      {
   4257         sig_bit = (int)png_ptr->sig_bit.red;
   4258 
   4259         if ((int)png_ptr->sig_bit.green > sig_bit)
   4260            sig_bit = png_ptr->sig_bit.green;
   4261 
   4262         if ((int)png_ptr->sig_bit.blue > sig_bit)
   4263            sig_bit = png_ptr->sig_bit.blue;
   4264      }
   4265      else
   4266      {
   4267         sig_bit = (int)png_ptr->sig_bit.gray;
   4268      }
   4269 
   4270      if (sig_bit > 0)
   4271         shift = 16 - sig_bit;
   4272 
   4273      else
   4274         shift = 0;
   4275 
   4276      if (png_ptr->transformations & PNG_16_TO_8)
   4277      {
   4278         if (shift < (16 - PNG_MAX_GAMMA_8))
   4279            shift = (16 - PNG_MAX_GAMMA_8);
   4280      }
   4281 
   4282      if (shift > 8)
   4283         shift = 8;
   4284 
   4285      if (shift < 0)
   4286         shift = 0;
   4287 
   4288      png_ptr->gamma_shift = (png_byte)shift;
   4289 
   4290      num = (1 << (8 - shift));
   4291 
   4292      if (png_ptr->screen_gamma > .000001)
   4293         g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
   4294      else
   4295         g = 1.0;
   4296 
   4297      png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr,
   4298         (png_uint_32)(num * png_sizeof(png_uint_16p)));
   4299 
   4300      if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
   4301      {
   4302         double fin, fout;
   4303         png_uint_32 last, max;
   4304 
   4305         for (i = 0; i < num; i++)
   4306         {
   4307            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
   4308               (png_uint_32)(256 * png_sizeof(png_uint_16)));
   4309         }
   4310 
   4311         g = 1.0 / g;
   4312         last = 0;
   4313         for (i = 0; i < 256; i++)
   4314         {
   4315            fout = ((double)i + 0.5) / 256.0;
   4316            fin = pow(fout, g);
   4317            max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
   4318            while (last <= max)
   4319            {
   4320               png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
   4321                  [(int)(last >> (8 - shift))] = (png_uint_16)(
   4322                  (png_uint_16)i | ((png_uint_16)i << 8));
   4323               last++;
   4324            }
   4325         }
   4326         while (last < ((png_uint_32)num << 8))
   4327         {
   4328            png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
   4329               [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
   4330            last++;
   4331         }
   4332      }
   4333      else
   4334      {
   4335         for (i = 0; i < num; i++)
   4336         {
   4337            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
   4338               (png_uint_32)(256 * png_sizeof(png_uint_16)));
   4339 
   4340            ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
   4341 
   4342            for (j = 0; j < 256; j++)
   4343            {
   4344               png_ptr->gamma_16_table[i][j] =
   4345                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4346                     65535.0, g) * 65535.0 + .5);
   4347            }
   4348         }
   4349      }
   4350 
   4351 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
   4352    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
   4353      if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
   4354      {
   4355 
   4356         g = 1.0 / (png_ptr->gamma);
   4357 
   4358         png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr,
   4359            (png_uint_32)(num * png_sizeof(png_uint_16p )));
   4360 
   4361         for (i = 0; i < num; i++)
   4362         {
   4363            png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
   4364               (png_uint_32)(256 * png_sizeof(png_uint_16)));
   4365 
   4366            ig = (((png_uint_32)i *
   4367               (png_uint_32)png_gamma_shift[shift]) >> 4);
   4368            for (j = 0; j < 256; j++)
   4369            {
   4370               png_ptr->gamma_16_to_1[i][j] =
   4371                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4372                     65535.0, g) * 65535.0 + .5);
   4373            }
   4374         }
   4375 
   4376         if (png_ptr->screen_gamma > 0.000001)
   4377            g = 1.0 / png_ptr->screen_gamma;
   4378 
   4379         else
   4380            g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
   4381 
   4382         png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr,
   4383            (png_uint_32)(num * png_sizeof(png_uint_16p)));
   4384 
   4385         for (i = 0; i < num; i++)
   4386         {
   4387            png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
   4388               (png_uint_32)(256 * png_sizeof(png_uint_16)));
   4389 
   4390            ig = (((png_uint_32)i *
   4391               (png_uint_32)png_gamma_shift[shift]) >> 4);
   4392 
   4393            for (j = 0; j < 256; j++)
   4394            {
   4395               png_ptr->gamma_16_from_1[i][j] =
   4396                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
   4397                     65535.0, g) * 65535.0 + .5);
   4398            }
   4399         }
   4400      }
   4401 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
   4402   }
   4403 }
   4404 #endif
   4405 /* To do: install integer version of png_build_gamma_table here */
   4406 #endif
   4407 
   4408 #ifdef PNG_MNG_FEATURES_SUPPORTED
   4409 /* Undoes intrapixel differencing  */
   4410 void /* PRIVATE */
   4411 png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
   4412 {
   4413    png_debug(1, "in png_do_read_intrapixel");
   4414 
   4415    if (
   4416 #ifdef PNG_USELESS_TESTS_SUPPORTED
   4417        row != NULL && row_info != NULL &&
   4418 #endif
   4419        (row_info->color_type & PNG_COLOR_MASK_COLOR))
   4420    {
   4421       int bytes_per_pixel;
   4422       png_uint_32 row_width = row_info->width;
   4423       if (row_info->bit_depth == 8)
   4424       {
   4425          png_bytep rp;
   4426          png_uint_32 i;
   4427 
   4428          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   4429             bytes_per_pixel = 3;
   4430 
   4431          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   4432             bytes_per_pixel = 4;
   4433 
   4434          else
   4435             return;
   4436 
   4437          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
   4438          {
   4439             *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
   4440             *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
   4441          }
   4442       }
   4443       else if (row_info->bit_depth == 16)
   4444       {
   4445          png_bytep rp;
   4446          png_uint_32 i;
   4447 
   4448          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   4449             bytes_per_pixel = 6;
   4450 
   4451          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   4452             bytes_per_pixel = 8;
   4453 
   4454          else
   4455             return;
   4456 
   4457          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
   4458          {
   4459             png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
   4460             png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
   4461             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
   4462             png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
   4463             png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
   4464             *(rp  ) = (png_byte)((red >> 8) & 0xff);
   4465             *(rp+1) = (png_byte)(red & 0xff);
   4466             *(rp+4) = (png_byte)((blue >> 8) & 0xff);
   4467             *(rp+5) = (png_byte)(blue & 0xff);
   4468          }
   4469       }
   4470    }
   4471 }
   4472 #endif /* PNG_MNG_FEATURES_SUPPORTED */
   4473 #endif /* PNG_READ_SUPPORTED */