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