home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / png / pngrtran.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  134.6 KB  |  4,053 lines  |  [TEXT/CWIE]

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