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