graphics

experiments with opengl3.2/ogles3.3 on linux and win7
git clone http://frotz.net/git/graphics.git
Log | Files | Refs

pngrtran.c (148384B)


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