pngrtran.c
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:148k
源码类别:

界面编程

开发平台:

Visual C++

  1. /* pngrtran.c - transforms the data in a row for PNG readers
  2.  *
  3.  * Last changed in libpng 1.2.30 [August 15, 2008]
  4.  * For conditions of distribution and use, see copyright notice in png.h
  5.  * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  6.  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  7.  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  8.  *
  9.  * This file contains functions optionally called by an application
  10.  * in order to tell libpng how to handle data when reading a PNG.
  11.  * Transformations that are used in both reading and writing are
  12.  * in pngtrans.c.
  13.  */
  14. #if ( ! defined _CRT_SECURE_NO_WARNINGS )
  15. #define _CRT_SECURE_NO_WARNINGS
  16. #endif
  17. #define PNG_INTERNAL
  18. #include "png.h"
  19. #if defined(PNG_READ_SUPPORTED)
  20. /* Set the action on getting a CRC error for an ancillary or critical chunk. */
  21. void PNGAPI
  22. png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
  23. {
  24.    png_debug(1, "in png_set_crc_action");
  25.    /* Tell libpng how we react to CRC errors in critical chunks */
  26.    if (png_ptr == NULL) return;
  27.    switch (crit_action)
  28.    {
  29.       case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
  30.          break;
  31.       case PNG_CRC_WARN_USE:                               /* warn/use data */
  32.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  33.          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
  34.          break;
  35.       case PNG_CRC_QUIET_USE:                             /* quiet/use data */
  36.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  37.          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
  38.                            PNG_FLAG_CRC_CRITICAL_IGNORE;
  39.          break;
  40.       case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
  41.          png_warning(png_ptr,
  42.             "Can't discard critical data on CRC error.");
  43.       case PNG_CRC_ERROR_QUIT:                                /* error/quit */
  44.       case PNG_CRC_DEFAULT:
  45.       default:
  46.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  47.          break;
  48.    }
  49.    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. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && 
  74.     defined(PNG_FLOATING_POINT_SUPPORTED)
  75. /* handle alpha and tRNS via a background color */
  76. void PNGAPI
  77. png_set_background(png_structp png_ptr,
  78.    png_color_16p background_color, int background_gamma_code,
  79.    int need_expand, double background_gamma)
  80. {
  81.    png_debug(1, "in png_set_background");
  82.    if (png_ptr == NULL) return;
  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.    png_ptr->transformations |= PNG_BACKGROUND;
  89.    png_memcpy(&(png_ptr->background), background_color,
  90.       png_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. #endif
  96. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  97. /* strip 16 bit depth files to 8 bit depth */
  98. void PNGAPI
  99. png_set_strip_16(png_structp png_ptr)
  100. {
  101.    png_debug(1, "in png_set_strip_16");
  102.    if (png_ptr == NULL) return;
  103.    png_ptr->transformations |= PNG_16_TO_8;
  104. }
  105. #endif
  106. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  107. void PNGAPI
  108. png_set_strip_alpha(png_structp png_ptr)
  109. {
  110.    png_debug(1, "in png_set_strip_alpha");
  111.    if (png_ptr == NULL) return;
  112.    png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
  113. }
  114. #endif
  115. #if defined(PNG_READ_DITHER_SUPPORTED)
  116. /* Dither file to 8 bit.  Supply a palette, the current number
  117.  * of elements in the palette, the maximum number of elements
  118.  * allowed, and a histogram if possible.  If the current number
  119.  * of colors is greater then the maximum number, the palette will be
  120.  * modified to fit in the maximum number.  "full_dither" indicates
  121.  * whether we need a dithering cube set up for RGB images, or if we
  122.  * simply are reducing the number of colors in a paletted image.
  123.  */
  124. typedef struct png_dsort_struct
  125. {
  126.    struct png_dsort_struct FAR * next;
  127.    png_byte left;
  128.    png_byte right;
  129. } png_dsort;
  130. typedef png_dsort FAR *       png_dsortp;
  131. typedef png_dsort FAR * FAR * png_dsortpp;
  132. void PNGAPI
  133. png_set_dither(png_structp png_ptr, png_colorp palette,
  134.    int num_palette, int maximum_colors, png_uint_16p histogram,
  135.    int full_dither)
  136. {
  137.    png_debug(1, "in png_set_dither");
  138.    if (png_ptr == NULL) return;
  139.    png_ptr->transformations |= PNG_DITHER;
  140.    if (!full_dither)
  141.    {
  142.       int i;
  143.       png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
  144.          (png_uint_32)(num_palette * png_sizeof(png_byte)));
  145.       for (i = 0; i < num_palette; i++)
  146.          png_ptr->dither_index[i] = (png_byte)i;
  147.    }
  148.    if (num_palette > maximum_colors)
  149.    {
  150.       if (histogram != NULL)
  151.       {
  152.          /* This is easy enough, just throw out the least used colors.
  153.             Perhaps not the best solution, but good enough. */
  154.          int i;
  155.          /* initialize an array to sort colors */
  156.          png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
  157.             (png_uint_32)(num_palette * png_sizeof(png_byte)));
  158.          /* initialize the dither_sort array */
  159.          for (i = 0; i < num_palette; i++)
  160.             png_ptr->dither_sort[i] = (png_byte)i;
  161.          /* Find the least used palette entries by starting a
  162.             bubble sort, and running it until we have sorted
  163.             out enough colors.  Note that we don't care about
  164.             sorting all the colors, just finding which are
  165.             least used. */
  166.          for (i = num_palette - 1; i >= maximum_colors; i--)
  167.          {
  168.             int done; /* to stop early if the list is pre-sorted */
  169.             int j;
  170.             done = 1;
  171.             for (j = 0; j < i; j++)
  172.             {
  173.                if (histogram[png_ptr->dither_sort[j]]
  174.                    < histogram[png_ptr->dither_sort[j + 1]])
  175.                {
  176.                   png_byte t;
  177.                   t = png_ptr->dither_sort[j];
  178.                   png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
  179.                   png_ptr->dither_sort[j + 1] = t;
  180.                   done = 0;
  181.                }
  182.             }
  183.             if (done)
  184.                break;
  185.          }
  186.          /* swap the palette around, and set up a table, if necessary */
  187.          if (full_dither)
  188.          {
  189.             int j = num_palette;
  190.             /* put all the useful colors within the max, but don't
  191.                move the others */
  192.             for (i = 0; i < maximum_colors; i++)
  193.             {
  194.                if ((int)png_ptr->dither_sort[i] >= maximum_colors)
  195.                {
  196.                   do
  197.                      j--;
  198.                   while ((int)png_ptr->dither_sort[j] >= maximum_colors);
  199.                   palette[i] = palette[j];
  200.                }
  201.             }
  202.          }
  203.          else
  204.          {
  205.             int j = num_palette;
  206.             /* move all the used colors inside the max limit, and
  207.                develop a translation table */
  208.             for (i = 0; i < maximum_colors; i++)
  209.             {
  210.                /* only move the colors we need to */
  211.                if ((int)png_ptr->dither_sort[i] >= maximum_colors)
  212.                {
  213.                   png_color tmp_color;
  214.                   do
  215.                      j--;
  216.                   while ((int)png_ptr->dither_sort[j] >= maximum_colors);
  217.                   tmp_color = palette[j];
  218.                   palette[j] = palette[i];
  219.                   palette[i] = tmp_color;
  220.                   /* indicate where the color went */
  221.                   png_ptr->dither_index[j] = (png_byte)i;
  222.                   png_ptr->dither_index[i] = (png_byte)j;
  223.                }
  224.             }
  225.             /* find closest color for those colors we are not using */
  226.             for (i = 0; i < num_palette; i++)
  227.             {
  228.                if ((int)png_ptr->dither_index[i] >= maximum_colors)
  229.                {
  230.                   int min_d, k, min_k, d_index;
  231.                   /* find the closest color to one we threw out */
  232.                   d_index = png_ptr->dither_index[i];
  233.                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
  234.                   for (k = 1, min_k = 0; k < maximum_colors; k++)
  235.                   {
  236.                      int d;
  237.                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);
  238.                      if (d < min_d)
  239.                      {
  240.                         min_d = d;
  241.                         min_k = k;
  242.                      }
  243.                   }
  244.                   /* point to closest color */
  245.                   png_ptr->dither_index[i] = (png_byte)min_k;
  246.                }
  247.             }
  248.          }
  249.          png_free(png_ptr, png_ptr->dither_sort);
  250.          png_ptr->dither_sort = NULL;
  251.       }
  252.       else
  253.       {
  254.          /* This is much harder to do simply (and quickly).  Perhaps
  255.             we need to go through a median cut routine, but those
  256.             don't always behave themselves with only a few colors
  257.             as input.  So we will just find the closest two colors,
  258.             and throw out one of them (chosen somewhat randomly).
  259.             [We don't understand this at all, so if someone wants to
  260.              work on improving it, be our guest - AED, GRP]
  261.             */
  262.          int i;
  263.          int max_d;
  264.          int num_new_palette;
  265.          png_dsortp t;
  266.          png_dsortpp hash;
  267.          t = NULL;
  268.          /* initialize palette index arrays */
  269.          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
  270.             (png_uint_32)(num_palette * png_sizeof(png_byte)));
  271.          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
  272.             (png_uint_32)(num_palette * png_sizeof(png_byte)));
  273.          /* initialize the sort array */
  274.          for (i = 0; i < num_palette; i++)
  275.          {
  276.             png_ptr->index_to_palette[i] = (png_byte)i;
  277.             png_ptr->palette_to_index[i] = (png_byte)i;
  278.          }
  279.          hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
  280.             png_sizeof(png_dsortp)));
  281.          for (i = 0; i < 769; i++)
  282.             hash[i] = NULL;
  283. /*         png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); */
  284.          num_new_palette = num_palette;
  285.          /* initial wild guess at how far apart the farthest pixel
  286.             pair we will be eliminating will be.  Larger
  287.             numbers mean more areas will be allocated, Smaller
  288.             numbers run the risk of not saving enough data, and
  289.             having to do this all over again.
  290.             I have not done extensive checking on this number.
  291.             */
  292.          max_d = 96;
  293.          while (num_new_palette > maximum_colors)
  294.          {
  295.             for (i = 0; i < num_new_palette - 1; i++)
  296.             {
  297.                int j;
  298.                for (j = i + 1; j < num_new_palette; j++)
  299.                {
  300.                   int d;
  301.                   d = PNG_COLOR_DIST(palette[i], palette[j]);
  302.                   if (d <= max_d)
  303.                   {
  304.                      t = (png_dsortp)png_malloc_warn(png_ptr,
  305.                          (png_uint_32)(png_sizeof(png_dsort)));
  306.                      if (t == NULL)
  307.                          break;
  308.                      t->next = hash[d];
  309.                      t->left = (png_byte)i;
  310.                      t->right = (png_byte)j;
  311.                      hash[d] = t;
  312.                   }
  313.                }
  314.                if (t == NULL)
  315.                   break;
  316.             }
  317.             if (t != NULL)
  318.             for (i = 0; i <= max_d; i++)
  319.             {
  320.                if (hash[i] != NULL)
  321.                {
  322.                   png_dsortp p;
  323.                   for (p = hash[i]; p; p = p->next)
  324.                   {
  325.                      if ((int)png_ptr->index_to_palette[p->left]
  326.                         < num_new_palette &&
  327.                         (int)png_ptr->index_to_palette[p->right]
  328.                         < num_new_palette)
  329.                      {
  330.                         int j, next_j;
  331.                         if (num_new_palette & 0x01)
  332.                         {
  333.                            j = p->left;
  334.                            next_j = p->right;
  335.                         }
  336.                         else
  337.                         {
  338.                            j = p->right;
  339.                            next_j = p->left;
  340.                         }
  341.                         num_new_palette--;
  342.                         palette[png_ptr->index_to_palette[j]]
  343.                           = palette[num_new_palette];
  344.                         if (!full_dither)
  345.                         {
  346.                            int k;
  347.                            for (k = 0; k < num_palette; k++)
  348.                            {
  349.                               if (png_ptr->dither_index[k] ==
  350.                                  png_ptr->index_to_palette[j])
  351.                                  png_ptr->dither_index[k] =
  352.                                     png_ptr->index_to_palette[next_j];
  353.                               if ((int)png_ptr->dither_index[k] ==
  354.                                  num_new_palette)
  355.                                  png_ptr->dither_index[k] =
  356.                                     png_ptr->index_to_palette[j];
  357.                            }
  358.                         }
  359.                         png_ptr->index_to_palette[png_ptr->palette_to_index
  360.                            [num_new_palette]] = png_ptr->index_to_palette[j];
  361.                         png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
  362.                            = png_ptr->palette_to_index[num_new_palette];
  363.                         png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
  364.                         png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
  365.                      }
  366.                      if (num_new_palette <= maximum_colors)
  367.                         break;
  368.                   }
  369.                   if (num_new_palette <= maximum_colors)
  370.                      break;
  371.                }
  372.             }
  373.             for (i = 0; i < 769; i++)
  374.             {
  375.                if (hash[i] != NULL)
  376.                {
  377.                   png_dsortp p = hash[i];
  378.                   while (p)
  379.                   {
  380.                      t = p->next;
  381.                      png_free(png_ptr, p);
  382.                      p = t;
  383.                   }
  384.                }
  385.                hash[i] = 0;
  386.             }
  387.             max_d += 96;
  388.          }
  389.          png_free(png_ptr, hash);
  390.          png_free(png_ptr, png_ptr->palette_to_index);
  391.          png_free(png_ptr, png_ptr->index_to_palette);
  392.          png_ptr->palette_to_index = NULL;
  393.          png_ptr->index_to_palette = NULL;
  394.       }
  395.       num_palette = maximum_colors;
  396.    }
  397.    if (png_ptr->palette == NULL)
  398.    {
  399.       png_ptr->palette = palette;
  400.    }
  401.    png_ptr->num_palette = (png_uint_16)num_palette;
  402.    if (full_dither)
  403.    {
  404.       int i;
  405.       png_bytep distance;
  406.       int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  407.          PNG_DITHER_BLUE_BITS;
  408.       int num_red = (1 << PNG_DITHER_RED_BITS);
  409.       int num_green = (1 << PNG_DITHER_GREEN_BITS);
  410.       int num_blue = (1 << PNG_DITHER_BLUE_BITS);
  411.       png_size_t num_entries = ((png_size_t)1 << total_bits);
  412.       png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
  413.          (png_uint_32)(num_entries * png_sizeof(png_byte)));
  414.       png_memset(png_ptr->palette_lookup, 0, num_entries *
  415.          png_sizeof(png_byte));
  416.       distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
  417.          png_sizeof(png_byte)));
  418.       png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
  419.       for (i = 0; i < num_palette; i++)
  420.       {
  421.          int ir, ig, ib;
  422.          int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  423.          int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  424.          int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  425.          for (ir = 0; ir < num_red; ir++)
  426.          {
  427.             /* int dr = abs(ir - r); */
  428.             int dr = ((ir > r) ? ir - r : r - ir);
  429.             int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  430.             for (ig = 0; ig < num_green; ig++)
  431.             {
  432.                /* int dg = abs(ig - g); */
  433.                int dg = ((ig > g) ? ig - g : g - ig);
  434.                int dt = dr + dg;
  435.                int dm = ((dr > dg) ? dr : dg);
  436.                int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  437.                for (ib = 0; ib < num_blue; ib++)
  438.                {
  439.                   int d_index = index_g | ib;
  440.                   /* int db = abs(ib - b); */
  441.                   int db = ((ib > b) ? ib - b : b - ib);
  442.                   int dmax = ((dm > db) ? dm : db);
  443.                   int d = dmax + dt + db;
  444.                   if (d < (int)distance[d_index])
  445.                   {
  446.                      distance[d_index] = (png_byte)d;
  447.                      png_ptr->palette_lookup[d_index] = (png_byte)i;
  448.                   }
  449.                }
  450.             }
  451.          }
  452.       }
  453.       png_free(png_ptr, distance);
  454.    }
  455. }
  456. #endif
  457. #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  458. /* Transform the image from the file_gamma to the screen_gamma.  We
  459.  * only do transformations on images where the file_gamma and screen_gamma
  460.  * are not close reciprocals, otherwise it slows things down slightly, and
  461.  * also needlessly introduces small errors.
  462.  *
  463.  * We will turn off gamma transformation later if no semitransparent entries
  464.  * are present in the tRNS array for palette images.  We can't do it here
  465.  * because we don't necessarily have the tRNS chunk yet.
  466.  */
  467. void PNGAPI
  468. png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
  469. {
  470.    png_debug(1, "in png_set_gamma");
  471.    if (png_ptr == NULL) return;
  472.    if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
  473.        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
  474.        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
  475.      png_ptr->transformations |= PNG_GAMMA;
  476.    png_ptr->gamma = (float)file_gamma;
  477.    png_ptr->screen_gamma = (float)scrn_gamma;
  478. }
  479. #endif
  480. #if defined(PNG_READ_EXPAND_SUPPORTED)
  481. /* Expand paletted images to RGB, expand grayscale images of
  482.  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
  483.  * to alpha channels.
  484.  */
  485. void PNGAPI
  486. png_set_expand(png_structp png_ptr)
  487. {
  488.    png_debug(1, "in png_set_expand");
  489.    if (png_ptr == NULL) return;
  490.    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  491.    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  492. }
  493. /* GRR 19990627:  the following three functions currently are identical
  494.  *  to png_set_expand().  However, it is entirely reasonable that someone
  495.  *  might wish to expand an indexed image to RGB but *not* expand a single,
  496.  *  fully transparent palette entry to a full alpha channel--perhaps instead
  497.  *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
  498.  *  the transparent color with a particular RGB value, or drop tRNS entirely.
  499.  *  IOW, a future version of the library may make the transformations flag
  500.  *  a bit more fine-grained, with separate bits for each of these three
  501.  *  functions.
  502.  *
  503.  *  More to the point, these functions make it obvious what libpng will be
  504.  *  doing, whereas "expand" can (and does) mean any number of things.
  505.  *
  506.  *  GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
  507.  *  to expand only the sample depth but not to expand the tRNS to alpha.
  508.  */
  509. /* Expand paletted images to RGB. */
  510. void PNGAPI
  511. png_set_palette_to_rgb(png_structp png_ptr)
  512. {
  513.    png_debug(1, "in png_set_palette_to_rgb");
  514.    if (png_ptr == NULL) return;
  515.    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  516.    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  517. }
  518. #if !defined(PNG_1_0_X)
  519. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  520. void PNGAPI
  521. png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
  522. {
  523.    png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
  524.    if (png_ptr == NULL) return;
  525.    png_ptr->transformations |= PNG_EXPAND;
  526.    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  527. }
  528. #endif
  529. #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
  530. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  531. /* Deprecated as of libpng-1.2.9 */
  532. void PNGAPI
  533. png_set_gray_1_2_4_to_8(png_structp png_ptr)
  534. {
  535.    png_debug(1, "in png_set_gray_1_2_4_to_8");
  536.    if (png_ptr == NULL) return;
  537.    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  538. }
  539. #endif
  540. /* Expand tRNS chunks to alpha channels. */
  541. void PNGAPI
  542. png_set_tRNS_to_alpha(png_structp png_ptr)
  543. {
  544.    png_debug(1, "in png_set_tRNS_to_alpha");
  545.    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  546.    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  547. }
  548. #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
  549. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  550. void PNGAPI
  551. png_set_gray_to_rgb(png_structp png_ptr)
  552. {
  553.    png_debug(1, "in png_set_gray_to_rgb");
  554.    png_ptr->transformations |= PNG_GRAY_TO_RGB;
  555.    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  556. }
  557. #endif
  558. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  559. #if defined(PNG_FLOATING_POINT_SUPPORTED)
  560. /* Convert a RGB image to a grayscale of the same width.  This allows us,
  561.  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
  562.  */
  563. void PNGAPI
  564. png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
  565.    double green)
  566. {
  567.       int red_fixed = (int)((float)red*100000.0 + 0.5);
  568.       int green_fixed = (int)((float)green*100000.0 + 0.5);
  569.       if (png_ptr == NULL) return;
  570.       png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
  571. }
  572. #endif
  573. void PNGAPI
  574. png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
  575.    png_fixed_point red, png_fixed_point green)
  576. {
  577.    png_debug(1, "in png_set_rgb_to_gray");
  578.    if (png_ptr == NULL) return;
  579.    switch(error_action)
  580.    {
  581.       case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
  582.               break;
  583.       case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
  584.               break;
  585.       case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
  586.    }
  587.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  588. #if defined(PNG_READ_EXPAND_SUPPORTED)
  589.       png_ptr->transformations |= PNG_EXPAND;
  590. #else
  591.    {
  592.       png_warning(png_ptr,
  593.         "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
  594.       png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
  595.    }
  596. #endif
  597.    {
  598.       png_uint_16 red_int, green_int;
  599.       if (red < 0 || green < 0)
  600.       {
  601.          red_int   =  6968; /* .212671 * 32768 + .5 */
  602.          green_int = 23434; /* .715160 * 32768 + .5 */
  603.       }
  604.       else if (red + green < 100000L)
  605.       {
  606.         red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
  607.         green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
  608.       }
  609.       else
  610.       {
  611.          png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
  612.          red_int   =  6968;
  613.          green_int = 23434;
  614.       }
  615.       png_ptr->rgb_to_gray_red_coeff   = red_int;
  616.       png_ptr->rgb_to_gray_green_coeff = green_int;
  617.       png_ptr->rgb_to_gray_blue_coeff  = 
  618.          (png_uint_16)(32768 - red_int - green_int);
  619.    }
  620. }
  621. #endif
  622. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || 
  623.     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || 
  624.     defined(PNG_LEGACY_SUPPORTED)
  625. void PNGAPI
  626. png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
  627.    read_user_transform_fn)
  628. {
  629.    png_debug(1, "in png_set_read_user_transform_fn");
  630.    if (png_ptr == NULL) return;
  631. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  632.    png_ptr->transformations |= PNG_USER_TRANSFORM;
  633.    png_ptr->read_user_transform_fn = read_user_transform_fn;
  634. #endif
  635. #ifdef PNG_LEGACY_SUPPORTED
  636.    if (read_user_transform_fn)
  637.       png_warning(png_ptr,
  638.         "This version of libpng does not support user transforms");
  639. #endif
  640. }
  641. #endif
  642. /* Initialize everything needed for the read.  This includes modifying
  643.  * the palette.
  644.  */
  645. void /* PRIVATE */
  646. png_init_read_transformations(png_structp png_ptr)
  647. {
  648.    png_debug(1, "in png_init_read_transformations");
  649. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  650.    if (png_ptr != NULL)
  651. #endif
  652.   {
  653. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) 
  654.  || defined(PNG_READ_GAMMA_SUPPORTED)
  655.    int color_type = png_ptr->color_type;
  656. #endif
  657. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  658. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  659.    /* Detect gray background and attempt to enable optimization
  660.     * for gray --> RGB case */
  661.    /* Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
  662.     * RGB_ALPHA (in which case need_expand is superfluous anyway), the
  663.     * background color might actually be gray yet not be flagged as such.
  664.     * This is not a problem for the current code, which uses
  665.     * PNG_BACKGROUND_IS_GRAY only to decide when to do the
  666.     * png_do_gray_to_rgb() transformation.
  667.     */
  668.    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  669.        !(color_type & PNG_COLOR_MASK_COLOR))
  670.    {
  671.           png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  672.    } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
  673.               !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  674.               (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  675.               png_ptr->background.red == png_ptr->background.green &&
  676.               png_ptr->background.red == png_ptr->background.blue)
  677.    {
  678.           png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  679.           png_ptr->background.gray = png_ptr->background.red;
  680.    }
  681. #endif
  682.    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  683.        (png_ptr->transformations & PNG_EXPAND))
  684.    {
  685.       if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
  686.       {
  687.          /* expand background and tRNS chunks */
  688.          switch (png_ptr->bit_depth)
  689.          {
  690.             case 1:
  691.                png_ptr->background.gray *= (png_uint_16)0xff;
  692.                png_ptr->background.red = png_ptr->background.green
  693.                  =  png_ptr->background.blue = png_ptr->background.gray;
  694.                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  695.                {
  696.                  png_ptr->trans_values.gray *= (png_uint_16)0xff;
  697.                  png_ptr->trans_values.red = png_ptr->trans_values.green
  698.                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  699.                }
  700.                break;
  701.             case 2:
  702.                png_ptr->background.gray *= (png_uint_16)0x55;
  703.                png_ptr->background.red = png_ptr->background.green
  704.                  = png_ptr->background.blue = png_ptr->background.gray;
  705.                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  706.                {
  707.                  png_ptr->trans_values.gray *= (png_uint_16)0x55;
  708.                  png_ptr->trans_values.red = png_ptr->trans_values.green
  709.                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  710.                }
  711.                break;
  712.             case 4:
  713.                png_ptr->background.gray *= (png_uint_16)0x11;
  714.                png_ptr->background.red = png_ptr->background.green
  715.                  = png_ptr->background.blue = png_ptr->background.gray;
  716.                if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  717.                {
  718.                  png_ptr->trans_values.gray *= (png_uint_16)0x11;
  719.                  png_ptr->trans_values.red = png_ptr->trans_values.green
  720.                    = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  721.                }
  722.                break;
  723.             case 8:
  724.             case 16:
  725.                png_ptr->background.red = png_ptr->background.green
  726.                  = png_ptr->background.blue = png_ptr->background.gray;
  727.                break;
  728.          }
  729.       }
  730.       else if (color_type == PNG_COLOR_TYPE_PALETTE)
  731.       {
  732.          png_ptr->background.red   =
  733.             png_ptr->palette[png_ptr->background.index].red;
  734.          png_ptr->background.green =
  735.             png_ptr->palette[png_ptr->background.index].green;
  736.          png_ptr->background.blue  =
  737.             png_ptr->palette[png_ptr->background.index].blue;
  738. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  739.         if (png_ptr->transformations & PNG_INVERT_ALPHA)
  740.         {
  741. #if defined(PNG_READ_EXPAND_SUPPORTED)
  742.            if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  743. #endif
  744.            {
  745.            /* invert the alpha channel (in tRNS) unless the pixels are
  746.               going to be expanded, in which case leave it for later */
  747.               int i, istop;
  748.               istop=(int)png_ptr->num_trans;
  749.               for (i=0; i<istop; i++)
  750.                  png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
  751.            }
  752.         }
  753. #endif
  754.       }
  755.    }
  756. #endif
  757. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  758.    png_ptr->background_1 = png_ptr->background;
  759. #endif
  760. #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  761.    if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
  762.        && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
  763.          < PNG_GAMMA_THRESHOLD))
  764.    {
  765.     int i, k;
  766.     k=0;
  767.     for (i=0; i<png_ptr->num_trans; i++)
  768.     {
  769.       if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
  770.         k=1; /* partial transparency is present */
  771.     }
  772.     if (k == 0)
  773.       png_ptr->transformations &= ~PNG_GAMMA;
  774.    }
  775.    if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
  776.         png_ptr->gamma != 0.0)
  777.    {
  778.       png_build_gamma_table(png_ptr);
  779. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  780.       if (png_ptr->transformations & PNG_BACKGROUND)
  781.       {
  782.          if (color_type == PNG_COLOR_TYPE_PALETTE)
  783.          {
  784.            /* could skip if no transparency and
  785.            */
  786.             png_color back, back_1;
  787.             png_colorp palette = png_ptr->palette;
  788.             int num_palette = png_ptr->num_palette;
  789.             int i;
  790.             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  791.             {
  792.                back.red = png_ptr->gamma_table[png_ptr->background.red];
  793.                back.green = png_ptr->gamma_table[png_ptr->background.green];
  794.                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  795.                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  796.                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  797.                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  798.             }
  799.             else
  800.             {
  801.                double g, gs;
  802.                switch (png_ptr->background_gamma_type)
  803.                {
  804.                   case PNG_BACKGROUND_GAMMA_SCREEN:
  805.                      g = (png_ptr->screen_gamma);
  806.                      gs = 1.0;
  807.                      break;
  808.                   case PNG_BACKGROUND_GAMMA_FILE:
  809.                      g = 1.0 / (png_ptr->gamma);
  810.                      gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  811.                      break;
  812.                   case PNG_BACKGROUND_GAMMA_UNIQUE:
  813.                      g = 1.0 / (png_ptr->background_gamma);
  814.                      gs = 1.0 / (png_ptr->background_gamma *
  815.                                  png_ptr->screen_gamma);
  816.                      break;
  817.                   default:
  818.                      g = 1.0;    /* back_1 */
  819.                      gs = 1.0;   /* back */
  820.                }
  821.                if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
  822.                {
  823.                   back.red   = (png_byte)png_ptr->background.red;
  824.                   back.green = (png_byte)png_ptr->background.green;
  825.                   back.blue  = (png_byte)png_ptr->background.blue;
  826.                }
  827.                else
  828.                {
  829.                   back.red = (png_byte)(pow(
  830.                      (double)png_ptr->background.red/255, gs) * 255.0 + .5);
  831.                   back.green = (png_byte)(pow(
  832.                      (double)png_ptr->background.green/255, gs) * 255.0 + .5);
  833.                   back.blue = (png_byte)(pow(
  834.                      (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
  835.                }
  836.                back_1.red = (png_byte)(pow(
  837.                   (double)png_ptr->background.red/255, g) * 255.0 + .5);
  838.                back_1.green = (png_byte)(pow(
  839.                   (double)png_ptr->background.green/255, g) * 255.0 + .5);
  840.                back_1.blue = (png_byte)(pow(
  841.                   (double)png_ptr->background.blue/255, g) * 255.0 + .5);
  842.             }
  843.             for (i = 0; i < num_palette; i++)
  844.             {
  845.                if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  846.                {
  847.                   if (png_ptr->trans[i] == 0)
  848.                   {
  849.                      palette[i] = back;
  850.                   }
  851.                   else /* if (png_ptr->trans[i] != 0xff) */
  852.                   {
  853.                      png_byte v, w;
  854.                      v = png_ptr->gamma_to_1[palette[i].red];
  855.                      png_composite(w, v, png_ptr->trans[i], back_1.red);
  856.                      palette[i].red = png_ptr->gamma_from_1[w];
  857.                      v = png_ptr->gamma_to_1[palette[i].green];
  858.                      png_composite(w, v, png_ptr->trans[i], back_1.green);
  859.                      palette[i].green = png_ptr->gamma_from_1[w];
  860.                      v = png_ptr->gamma_to_1[palette[i].blue];
  861.                      png_composite(w, v, png_ptr->trans[i], back_1.blue);
  862.                      palette[i].blue = png_ptr->gamma_from_1[w];
  863.                   }
  864.                }
  865.                else
  866.                {
  867.                   palette[i].red = png_ptr->gamma_table[palette[i].red];
  868.                   palette[i].green = png_ptr->gamma_table[palette[i].green];
  869.                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  870.                }
  871.             }
  872.     /* Prevent the transformations being done again, and make sure
  873.      * that the now spurious alpha channel is stripped - the code
  874.      * has just reduced background composition and gamma correction
  875.      * to a simple alpha channel strip.
  876.      */
  877.     png_ptr->transformations &= ~PNG_BACKGROUND;
  878.     png_ptr->transformations &= ~PNG_GAMMA;
  879.     png_ptr->transformations |= PNG_STRIP_ALPHA;
  880.          }
  881.          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
  882.          else
  883.          /* color_type != PNG_COLOR_TYPE_PALETTE */
  884.          {
  885.             double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  886.             double g = 1.0;
  887.             double gs = 1.0;
  888.             switch (png_ptr->background_gamma_type)
  889.             {
  890.                case PNG_BACKGROUND_GAMMA_SCREEN:
  891.                   g = (png_ptr->screen_gamma);
  892.                   gs = 1.0;
  893.                   break;
  894.                case PNG_BACKGROUND_GAMMA_FILE:
  895.                   g = 1.0 / (png_ptr->gamma);
  896.                   gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  897.                   break;
  898.                case PNG_BACKGROUND_GAMMA_UNIQUE:
  899.                   g = 1.0 / (png_ptr->background_gamma);
  900.                   gs = 1.0 / (png_ptr->background_gamma *
  901.                      png_ptr->screen_gamma);
  902.                   break;
  903.             }
  904.             png_ptr->background_1.gray = (png_uint_16)(pow(
  905.                (double)png_ptr->background.gray / m, g) * m + .5);
  906.             png_ptr->background.gray = (png_uint_16)(pow(
  907.                (double)png_ptr->background.gray / m, gs) * m + .5);
  908.             if ((png_ptr->background.red != png_ptr->background.green) ||
  909.                 (png_ptr->background.red != png_ptr->background.blue) ||
  910.                 (png_ptr->background.red != png_ptr->background.gray))
  911.             {
  912.                /* RGB or RGBA with color background */
  913.                png_ptr->background_1.red = (png_uint_16)(pow(
  914.                   (double)png_ptr->background.red / m, g) * m + .5);
  915.                png_ptr->background_1.green = (png_uint_16)(pow(
  916.                   (double)png_ptr->background.green / m, g) * m + .5);
  917.                png_ptr->background_1.blue = (png_uint_16)(pow(
  918.                   (double)png_ptr->background.blue / m, g) * m + .5);
  919.                png_ptr->background.red = (png_uint_16)(pow(
  920.                   (double)png_ptr->background.red / m, gs) * m + .5);
  921.                png_ptr->background.green = (png_uint_16)(pow(
  922.                   (double)png_ptr->background.green / m, gs) * m + .5);
  923.                png_ptr->background.blue = (png_uint_16)(pow(
  924.                   (double)png_ptr->background.blue / m, gs) * m + .5);
  925.             }
  926.             else
  927.             {
  928.                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
  929.                png_ptr->background_1.red = png_ptr->background_1.green
  930.                  = png_ptr->background_1.blue = png_ptr->background_1.gray;
  931.                png_ptr->background.red = png_ptr->background.green
  932.                  = png_ptr->background.blue = png_ptr->background.gray;
  933.             }
  934.          }
  935.       }
  936.       else
  937.       /* transformation does not include PNG_BACKGROUND */
  938. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  939.       if (color_type == PNG_COLOR_TYPE_PALETTE)
  940.       {
  941.          png_colorp palette = png_ptr->palette;
  942.          int num_palette = png_ptr->num_palette;
  943.          int i;
  944.          for (i = 0; i < num_palette; i++)
  945.          {
  946.             palette[i].red = png_ptr->gamma_table[palette[i].red];
  947.             palette[i].green = png_ptr->gamma_table[palette[i].green];
  948.             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  949.          }
  950.  /* Done the gamma correction. */
  951.  png_ptr->transformations &= ~PNG_GAMMA;
  952.       }
  953.    }
  954. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  955.    else
  956. #endif
  957. #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
  958. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  959.    /* No GAMMA transformation */
  960.    if ((png_ptr->transformations & PNG_BACKGROUND) &&
  961.        (color_type == PNG_COLOR_TYPE_PALETTE))
  962.    {
  963.       int i;
  964.       int istop = (int)png_ptr->num_trans;
  965.       png_color back;
  966.       png_colorp palette = png_ptr->palette;
  967.       back.red   = (png_byte)png_ptr->background.red;
  968.       back.green = (png_byte)png_ptr->background.green;
  969.       back.blue  = (png_byte)png_ptr->background.blue;
  970.       for (i = 0; i < istop; i++)
  971.       {
  972.          if (png_ptr->trans[i] == 0)
  973.          {
  974.             palette[i] = back;
  975.          }
  976.          else if (png_ptr->trans[i] != 0xff)
  977.          {
  978.             /* The png_composite() macro is defined in png.h */
  979.             png_composite(palette[i].red, palette[i].red,
  980.                png_ptr->trans[i], back.red);
  981.             png_composite(palette[i].green, palette[i].green,
  982.                png_ptr->trans[i], back.green);
  983.             png_composite(palette[i].blue, palette[i].blue,
  984.                png_ptr->trans[i], back.blue);
  985.          }
  986.       }
  987.       /* Handled alpha, still need to strip the channel. */
  988.       png_ptr->transformations &= ~PNG_BACKGROUND;
  989.       png_ptr->transformations |= PNG_STRIP_ALPHA;
  990.    }
  991. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  992. #if defined(PNG_READ_SHIFT_SUPPORTED)
  993.    if ((png_ptr->transformations & PNG_SHIFT) &&
  994.       (color_type == PNG_COLOR_TYPE_PALETTE))
  995.    {
  996.       png_uint_16 i;
  997.       png_uint_16 istop = png_ptr->num_palette;
  998.       int sr = 8 - png_ptr->sig_bit.red;
  999.       int sg = 8 - png_ptr->sig_bit.green;
  1000.       int sb = 8 - png_ptr->sig_bit.blue;
  1001.       if (sr < 0 || sr > 8)
  1002.          sr = 0;
  1003.       if (sg < 0 || sg > 8)
  1004.          sg = 0;
  1005.       if (sb < 0 || sb > 8)
  1006.          sb = 0;
  1007.       for (i = 0; i < istop; i++)
  1008.       {
  1009.          png_ptr->palette[i].red >>= sr;
  1010.          png_ptr->palette[i].green >>= sg;
  1011.          png_ptr->palette[i].blue >>= sb;
  1012.       }
  1013.    }
  1014. #endif  /* PNG_READ_SHIFT_SUPPORTED */
  1015.  }
  1016. #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) 
  1017.  && !defined(PNG_READ_BACKGROUND_SUPPORTED)
  1018.    if (png_ptr)
  1019.       return;
  1020. #endif
  1021. }
  1022. /* Modify the info structure to reflect the transformations.  The
  1023.  * info should be updated so a PNG file could be written with it,
  1024.  * assuming the transformations result in valid PNG data.
  1025.  */
  1026. void /* PRIVATE */
  1027. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  1028. {
  1029.    png_debug(1, "in png_read_transform_info");
  1030. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1031.    if (png_ptr->transformations & PNG_EXPAND)
  1032.    {
  1033.       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1034.       {
  1035.          if (png_ptr->num_trans &&
  1036.               (png_ptr->transformations & PNG_EXPAND_tRNS))
  1037.             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  1038.          else
  1039.             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  1040.          info_ptr->bit_depth = 8;
  1041.          info_ptr->num_trans = 0;
  1042.       }
  1043.       else
  1044.       {
  1045.          if (png_ptr->num_trans)
  1046.          {
  1047.             if (png_ptr->transformations & PNG_EXPAND_tRNS)
  1048.               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1049. #if 0 /* Removed from libpng-1.2.27 */
  1050.             else
  1051.               info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1052. #endif
  1053.          }
  1054.          if (info_ptr->bit_depth < 8)
  1055.             info_ptr->bit_depth = 8;
  1056.          info_ptr->num_trans = 0;
  1057.       }
  1058.    }
  1059. #endif
  1060. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1061.    if (png_ptr->transformations & PNG_BACKGROUND)
  1062.    {
  1063.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1064.       info_ptr->num_trans = 0;
  1065.       info_ptr->background = png_ptr->background;
  1066.    }
  1067. #endif
  1068. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1069.    if (png_ptr->transformations & PNG_GAMMA)
  1070.    {
  1071. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1072.       info_ptr->gamma = png_ptr->gamma;
  1073. #endif
  1074. #ifdef PNG_FIXED_POINT_SUPPORTED
  1075.       info_ptr->int_gamma = png_ptr->int_gamma;
  1076. #endif
  1077.    }
  1078. #endif
  1079. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1080.    if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
  1081.       info_ptr->bit_depth = 8;
  1082. #endif
  1083. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1084.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1085.       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1086. #endif
  1087. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1088.    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1089.       info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
  1090. #endif
  1091. #if defined(PNG_READ_DITHER_SUPPORTED)
  1092.    if (png_ptr->transformations & PNG_DITHER)
  1093.    {
  1094.       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1095.          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  1096.          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  1097.       {
  1098.          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  1099.       }
  1100.    }
  1101. #endif
  1102. #if defined(PNG_READ_PACK_SUPPORTED)
  1103.    if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
  1104.       info_ptr->bit_depth = 8;
  1105. #endif
  1106.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1107.       info_ptr->channels = 1;
  1108.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1109.       info_ptr->channels = 3;
  1110.    else
  1111.       info_ptr->channels = 1;
  1112. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1113.    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1114.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1115. #endif
  1116.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  1117.       info_ptr->channels++;
  1118. #if defined(PNG_READ_FILLER_SUPPORTED)
  1119.    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
  1120.    if ((png_ptr->transformations & PNG_FILLER) &&
  1121.        ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1122.        (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
  1123.    {
  1124.       info_ptr->channels++;
  1125.       /* if adding a true alpha channel not just filler */
  1126. #if !defined(PNG_1_0_X)
  1127.       if (png_ptr->transformations & PNG_ADD_ALPHA)
  1128.         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1129. #endif
  1130.    }
  1131. #endif
  1132. #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && 
  1133. defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  1134.    if (png_ptr->transformations & PNG_USER_TRANSFORM)
  1135.      {
  1136.        if (info_ptr->bit_depth < png_ptr->user_transform_depth)
  1137.          info_ptr->bit_depth = png_ptr->user_transform_depth;
  1138.        if (info_ptr->channels < png_ptr->user_transform_channels)
  1139.          info_ptr->channels = png_ptr->user_transform_channels;
  1140.      }
  1141. #endif
  1142.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  1143.       info_ptr->bit_depth);
  1144.    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
  1145. #if !defined(PNG_READ_EXPAND_SUPPORTED)
  1146.    if (png_ptr)
  1147.       return;
  1148. #endif
  1149. }
  1150. /* Transform the row.  The order of transformations is significant,
  1151.  * and is very touchy.  If you add a transformation, take care to
  1152.  * decide how it fits in with the other transformations here.
  1153.  */
  1154. void /* PRIVATE */
  1155. png_do_read_transformations(png_structp png_ptr)
  1156. {
  1157.    png_debug(1, "in png_do_read_transformations");
  1158.    if (png_ptr->row_buf == NULL)
  1159.    {
  1160. #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
  1161.       char msg[50];
  1162.       png_snprintf2(msg, 50,
  1163.          "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
  1164.          png_ptr->pass);
  1165.       png_error(png_ptr, msg);
  1166. #else
  1167.       png_error(png_ptr, "NULL row buffer");
  1168. #endif
  1169.    }
  1170. #ifdef PNG_WARN_UNINITIALIZED_ROW
  1171.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  1172.       /* Application has failed to call either png_read_start_image()
  1173.        * or png_read_update_info() after setting transforms that expand
  1174.        * pixels.  This check added to libpng-1.2.19 */
  1175. #if (PNG_WARN_UNINITIALIZED_ROW==1)
  1176.       png_error(png_ptr, "Uninitialized row");
  1177. #else
  1178.       png_warning(png_ptr, "Uninitialized row");
  1179. #endif
  1180. #endif
  1181. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1182.    if (png_ptr->transformations & PNG_EXPAND)
  1183.    {
  1184.       if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  1185.       {
  1186.          png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1187.             png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  1188.       }
  1189.       else
  1190.       {
  1191.          if (png_ptr->num_trans &&
  1192.              (png_ptr->transformations & PNG_EXPAND_tRNS))
  1193.             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1194.                &(png_ptr->trans_values));
  1195.          else
  1196.             png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1197.                NULL);
  1198.       }
  1199.    }
  1200. #endif
  1201. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1202.    if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1203.       png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1204.          PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
  1205. #endif
  1206. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1207.    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1208.    {
  1209.       int rgb_error =
  1210.          png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
  1211.       if (rgb_error)
  1212.       {
  1213.          png_ptr->rgb_to_gray_status=1;
  1214.          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 
  1215.              PNG_RGB_TO_GRAY_WARN)
  1216.             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1217.          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
  1218.              PNG_RGB_TO_GRAY_ERR)
  1219.             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1220.       }
  1221.    }
  1222. #endif
  1223. /*
  1224. From Andreas Dilger e-mail to png-implement, 26 March 1998:
  1225.   In most cases, the "simple transparency" should be done prior to doing
  1226.   gray-to-RGB, or you will have to test 3x as many bytes to check if a
  1227.   pixel is transparent.  You would also need to make sure that the
  1228.   transparency information is upgraded to RGB.
  1229.   To summarize, the current flow is:
  1230.   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
  1231.                                   with background "in place" if transparent,
  1232.                                   convert to RGB if necessary
  1233.   - Gray + alpha -> composite with gray background and remove alpha bytes,
  1234.                                   convert to RGB if necessary
  1235.   To support RGB backgrounds for gray images we need:
  1236.   - Gray + simple transparency -> convert to RGB + simple transparency, compare
  1237.                                   3 or 6 bytes and composite with background
  1238.                                   "in place" if transparent (3x compare/pixel
  1239.                                   compared to doing composite with gray bkgrnd)
  1240.   - Gray + alpha -> convert to RGB + alpha, composite with background and
  1241.                                   remove alpha bytes (3x float operations/pixel
  1242.                                   compared with composite on gray background)
  1243.   Greg's change will do this.  The reason it wasn't done before is for
  1244.   performance, as this increases the per-pixel operations.  If we would check
  1245.   in advance if the background was gray or RGB, and position the gray-to-RGB
  1246.   transform appropriately, then it would save a lot of work/time.
  1247.  */
  1248. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1249.    /* if gray -> RGB, do so now only if background is non-gray; else do later
  1250.     * for performance reasons */
  1251.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  1252.        !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
  1253.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1254. #endif
  1255. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1256.    if ((png_ptr->transformations & PNG_BACKGROUND) &&
  1257.       ((png_ptr->num_trans != 0 ) ||
  1258.       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
  1259.       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1260.          &(png_ptr->trans_values), &(png_ptr->background)
  1261. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1262.          , &(png_ptr->background_1),
  1263.          png_ptr->gamma_table, png_ptr->gamma_from_1,
  1264.          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  1265.          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  1266.          png_ptr->gamma_shift
  1267. #endif
  1268. );
  1269. #endif
  1270. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1271.    if ((png_ptr->transformations & PNG_GAMMA) &&
  1272. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1273.       !((png_ptr->transformations & PNG_BACKGROUND) &&
  1274.       ((png_ptr->num_trans != 0) ||
  1275.       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
  1276. #endif
  1277.       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
  1278.       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1279.          png_ptr->gamma_table, png_ptr->gamma_16_table,
  1280.          png_ptr->gamma_shift);
  1281. #endif
  1282. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1283.    if (png_ptr->transformations & PNG_16_TO_8)
  1284.       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1285. #endif
  1286. #if defined(PNG_READ_DITHER_SUPPORTED)
  1287.    if (png_ptr->transformations & PNG_DITHER)
  1288.    {
  1289.       png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
  1290.          png_ptr->palette_lookup, png_ptr->dither_index);
  1291.       if (png_ptr->row_info.rowbytes == (png_uint_32)0)
  1292.          png_error(png_ptr, "png_do_dither returned rowbytes=0");
  1293.    }
  1294. #endif
  1295. #if defined(PNG_READ_INVERT_SUPPORTED)
  1296.    if (png_ptr->transformations & PNG_INVERT_MONO)
  1297.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1298. #endif
  1299. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1300.    if (png_ptr->transformations & PNG_SHIFT)
  1301.       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1302.          &(png_ptr->shift));
  1303. #endif
  1304. #if defined(PNG_READ_PACK_SUPPORTED)
  1305.    if (png_ptr->transformations & PNG_PACK)
  1306.       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1307. #endif
  1308. #if defined(PNG_READ_BGR_SUPPORTED)
  1309.    if (png_ptr->transformations & PNG_BGR)
  1310.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1311. #endif
  1312. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1313.    if (png_ptr->transformations & PNG_PACKSWAP)
  1314.       png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1315. #endif
  1316. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1317.    /* if gray -> RGB, do so now only if we did not do so above */
  1318.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  1319.        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
  1320.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1321. #endif
  1322. #if defined(PNG_READ_FILLER_SUPPORTED)
  1323.    if (png_ptr->transformations & PNG_FILLER)
  1324.       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1325.          (png_uint_32)png_ptr->filler, png_ptr->flags);
  1326. #endif
  1327. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  1328.    if (png_ptr->transformations & PNG_INVERT_ALPHA)
  1329.       png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1330. #endif
  1331. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1332.    if (png_ptr->transformations & PNG_SWAP_ALPHA)
  1333.       png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1334. #endif
  1335. #if defined(PNG_READ_SWAP_SUPPORTED)
  1336.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  1337.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1338. #endif
  1339. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  1340.    if (png_ptr->transformations & PNG_USER_TRANSFORM)
  1341.     {
  1342.       if (png_ptr->read_user_transform_fn != NULL)
  1343.         (*(png_ptr->read_user_transform_fn)) /* user read transform function */
  1344.           (png_ptr,                    /* png_ptr */
  1345.            &(png_ptr->row_info),       /* row_info:     */
  1346.              /*  png_uint_32 width;          width of row */
  1347.              /*  png_uint_32 rowbytes;       number of bytes in row */
  1348.              /*  png_byte color_type;        color type of pixels */
  1349.              /*  png_byte bit_depth;         bit depth of samples */
  1350.              /*  png_byte channels;          number of channels (1-4) */
  1351.              /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
  1352.            png_ptr->row_buf + 1);      /* start of pixel data for row */
  1353. #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
  1354.       if (png_ptr->user_transform_depth)
  1355.          png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
  1356.       if (png_ptr->user_transform_channels)
  1357.          png_ptr->row_info.channels = png_ptr->user_transform_channels;
  1358. #endif
  1359.       png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
  1360.          png_ptr->row_info.channels);
  1361.       png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
  1362.          png_ptr->row_info.width);
  1363.    }
  1364. #endif
  1365. }
  1366. #if defined(PNG_READ_PACK_SUPPORTED)
  1367. /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  1368.  * without changing the actual values.  Thus, if you had a row with
  1369.  * a bit depth of 1, you would end up with bytes that only contained
  1370.  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  1371.  * png_do_shift() after this.
  1372.  */
  1373. void /* PRIVATE */
  1374. png_do_unpack(png_row_infop row_info, png_bytep row)
  1375. {
  1376.    png_debug(1, "in png_do_unpack");
  1377. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1378.    if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
  1379. #else
  1380.    if (row_info->bit_depth < 8)
  1381. #endif
  1382.    {
  1383.       png_uint_32 i;
  1384.       png_uint_32 row_width=row_info->width;
  1385.       switch (row_info->bit_depth)
  1386.       {
  1387.          case 1:
  1388.          {
  1389.             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
  1390.             png_bytep dp = row + (png_size_t)row_width - 1;
  1391.             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
  1392.             for (i = 0; i < row_width; i++)
  1393.             {
  1394.                *dp = (png_byte)((*sp >> shift) & 0x01);
  1395.                if (shift == 7)
  1396.                {
  1397.                   shift = 0;
  1398.                   sp--;
  1399.                }
  1400.                else
  1401.                   shift++;
  1402.                dp--;
  1403.             }
  1404.             break;
  1405.          }
  1406.          case 2:
  1407.          {
  1408.             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
  1409.             png_bytep dp = row + (png_size_t)row_width - 1;
  1410.             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  1411.             for (i = 0; i < row_width; i++)
  1412.             {
  1413.                *dp = (png_byte)((*sp >> shift) & 0x03);
  1414.                if (shift == 6)
  1415.                {
  1416.                   shift = 0;
  1417.                   sp--;
  1418.                }
  1419.                else
  1420.                   shift += 2;
  1421.                dp--;
  1422.             }
  1423.             break;
  1424.          }
  1425.          case 4:
  1426.          {
  1427.             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
  1428.             png_bytep dp = row + (png_size_t)row_width - 1;
  1429.             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
  1430.             for (i = 0; i < row_width; i++)
  1431.             {
  1432.                *dp = (png_byte)((*sp >> shift) & 0x0f);
  1433.                if (shift == 4)
  1434.                {
  1435.                   shift = 0;
  1436.                   sp--;
  1437.                }
  1438.                else
  1439.                   shift = 4;
  1440.                dp--;
  1441.             }
  1442.             break;
  1443.          }
  1444.       }
  1445.       row_info->bit_depth = 8;
  1446.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1447.       row_info->rowbytes = row_width * row_info->channels;
  1448.    }
  1449. }
  1450. #endif
  1451. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1452. /* Reverse the effects of png_do_shift.  This routine merely shifts the
  1453.  * pixels back to their significant bits values.  Thus, if you have
  1454.  * a row of bit depth 8, but only 5 are significant, this will shift
  1455.  * the values back to 0 through 31.
  1456.  */
  1457. void /* PRIVATE */
  1458. png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
  1459. {
  1460.    png_debug(1, "in png_do_unshift");
  1461.    if (
  1462. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1463.        row != NULL && row_info != NULL && sig_bits != NULL &&
  1464. #endif
  1465.        row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  1466.    {
  1467.       int shift[4];
  1468.       int channels = 0;
  1469.       int c;
  1470.       png_uint_16 value = 0;
  1471.       png_uint_32 row_width = row_info->width;
  1472.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  1473.       {
  1474.          shift[channels++] = row_info->bit_depth - sig_bits->red;
  1475.          shift[channels++] = row_info->bit_depth - sig_bits->green;
  1476.          shift[channels++] = row_info->bit_depth - sig_bits->blue;
  1477.       }
  1478.       else
  1479.       {
  1480.          shift[channels++] = row_info->bit_depth - sig_bits->gray;
  1481.       }
  1482.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1483.       {
  1484.          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  1485.       }
  1486.       for (c = 0; c < channels; c++)
  1487.       {
  1488.          if (shift[c] <= 0)
  1489.             shift[c] = 0;
  1490.          else
  1491.             value = 1;
  1492.       }
  1493.       if (!value)
  1494.          return;
  1495.       switch (row_info->bit_depth)
  1496.       {
  1497.          case 2:
  1498.          {
  1499.             png_bytep bp;
  1500.             png_uint_32 i;
  1501.             png_uint_32 istop = row_info->rowbytes;
  1502.             for (bp = row, i = 0; i < istop; i++)
  1503.             {
  1504.                *bp >>= 1;
  1505.                *bp++ &= 0x55;
  1506.             }
  1507.             break;
  1508.          }
  1509.          case 4:
  1510.          {
  1511.             png_bytep bp = row;
  1512.             png_uint_32 i;
  1513.             png_uint_32 istop = row_info->rowbytes;
  1514.             png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
  1515.                (png_byte)((int)0xf >> shift[0]));
  1516.             for (i = 0; i < istop; i++)
  1517.             {
  1518.                *bp >>= shift[0];
  1519.                *bp++ &= mask;
  1520.             }
  1521.             break;
  1522.          }
  1523.          case 8:
  1524.          {
  1525.             png_bytep bp = row;
  1526.             png_uint_32 i;
  1527.             png_uint_32 istop = row_width * channels;
  1528.             for (i = 0; i < istop; i++)
  1529.             {
  1530.                *bp++ >>= shift[i%channels];
  1531.             }
  1532.             break;
  1533.          }
  1534.          case 16:
  1535.          {
  1536.             png_bytep bp = row;
  1537.             png_uint_32 i;
  1538.             png_uint_32 istop = channels * row_width;
  1539.             for (i = 0; i < istop; i++)
  1540.             {
  1541.                value = (png_uint_16)((*bp << 8) + *(bp + 1));
  1542.                value >>= shift[i%channels];
  1543.                *bp++ = (png_byte)(value >> 8);
  1544.                *bp++ = (png_byte)(value & 0xff);
  1545.             }
  1546.             break;
  1547.          }
  1548.       }
  1549.    }
  1550. }
  1551. #endif
  1552. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1553. /* chop rows of bit depth 16 down to 8 */
  1554. void /* PRIVATE */
  1555. png_do_chop(png_row_infop row_info, png_bytep row)
  1556. {
  1557.    png_debug(1, "in png_do_chop");
  1558. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1559.    if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
  1560. #else
  1561.    if (row_info->bit_depth == 16)
  1562. #endif
  1563.    {
  1564.       png_bytep sp = row;
  1565.       png_bytep dp = row;
  1566.       png_uint_32 i;
  1567.       png_uint_32 istop = row_info->width * row_info->channels;
  1568.       for (i = 0; i<istop; i++, sp += 2, dp++)
  1569.       {
  1570. #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
  1571.       /* This does a more accurate scaling of the 16-bit color
  1572.        * value, rather than a simple low-byte truncation.
  1573.        *
  1574.        * What the ideal calculation should be:
  1575.        *   *dp = (((((png_uint_32)(*sp) << 8) |
  1576.        *          (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
  1577.        *
  1578.        * GRR: no, I think this is what it really should be:
  1579.        *   *dp = (((((png_uint_32)(*sp) << 8) |
  1580.        *           (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
  1581.        *
  1582.        * GRR: here's the exact calculation with shifts:
  1583.        *   temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
  1584.        *   *dp = (temp - (temp >> 8)) >> 8;
  1585.        *
  1586.        * Approximate calculation with shift/add instead of multiply/divide:
  1587.        *   *dp = ((((png_uint_32)(*sp) << 8) |
  1588.        *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
  1589.        *
  1590.        * What we actually do to avoid extra shifting and conversion:
  1591.        */
  1592.          *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
  1593. #else
  1594.        /* Simply discard the low order byte */
  1595.          *dp = *sp;
  1596. #endif
  1597.       }
  1598.       row_info->bit_depth = 8;
  1599.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1600.       row_info->rowbytes = row_info->width * row_info->channels;
  1601.    }
  1602. }
  1603. #endif
  1604. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1605. void /* PRIVATE */
  1606. png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
  1607. {
  1608.    png_debug(1, "in png_do_read_swap_alpha");
  1609. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1610.    if (row != NULL && row_info != NULL)
  1611. #endif
  1612.    {
  1613.       png_uint_32 row_width = row_info->width;
  1614.       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1615.       {
  1616.          /* This converts from RGBA to ARGB */
  1617.          if (row_info->bit_depth == 8)
  1618.          {
  1619.             png_bytep sp = row + row_info->rowbytes;
  1620.             png_bytep dp = sp;
  1621.             png_byte save;
  1622.             png_uint_32 i;
  1623.             for (i = 0; i < row_width; i++)
  1624.             {
  1625.                save = *(--sp);
  1626.                *(--dp) = *(--sp);
  1627.                *(--dp) = *(--sp);
  1628.                *(--dp) = *(--sp);
  1629.                *(--dp) = save;
  1630.             }
  1631.          }
  1632.          /* This converts from RRGGBBAA to AARRGGBB */
  1633.          else
  1634.          {
  1635.             png_bytep sp = row + row_info->rowbytes;
  1636.             png_bytep dp = sp;
  1637.             png_byte save[2];
  1638.             png_uint_32 i;
  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.             for (i = 0; i < row_width; i++)
  1664.             {
  1665.                save = *(--sp);
  1666.                *(--dp) = *(--sp);
  1667.                *(--dp) = save;
  1668.             }
  1669.          }
  1670.          /* This converts from GGAA to AAGG */
  1671.          else
  1672.          {
  1673.             png_bytep sp = row + row_info->rowbytes;
  1674.             png_bytep dp = sp;
  1675.             png_byte save[2];
  1676.             png_uint_32 i;
  1677.             for (i = 0; i < row_width; i++)
  1678.             {
  1679.                save[0] = *(--sp);
  1680.                save[1] = *(--sp);
  1681.                *(--dp) = *(--sp);
  1682.                *(--dp) = *(--sp);
  1683.                *(--dp) = save[0];
  1684.                *(--dp) = save[1];
  1685.             }
  1686.          }
  1687.       }
  1688.    }
  1689. }
  1690. #endif
  1691. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  1692. void /* PRIVATE */
  1693. png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
  1694. {
  1695.    png_debug(1, "in png_do_read_invert_alpha");
  1696. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1697.    if (row != NULL && row_info != NULL)
  1698. #endif
  1699.    {
  1700.       png_uint_32 row_width = row_info->width;
  1701.       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1702.       {
  1703.          /* This inverts the alpha channel in RGBA */
  1704.          if (row_info->bit_depth == 8)
  1705.          {
  1706.             png_bytep sp = row + row_info->rowbytes;
  1707.             png_bytep dp = sp;
  1708.             png_uint_32 i;
  1709.             for (i = 0; i < row_width; i++)
  1710.             {
  1711.                *(--dp) = (png_byte)(255 - *(--sp));
  1712. /*             This does nothing:
  1713.                *(--dp) = *(--sp);
  1714.                *(--dp) = *(--sp);
  1715.                *(--dp) = *(--sp);
  1716.                We can replace it with:
  1717. */
  1718.                sp-=3;
  1719.                dp=sp;
  1720.             }
  1721.          }
  1722.          /* This inverts the alpha channel in RRGGBBAA */
  1723.          else
  1724.          {
  1725.             png_bytep sp = row + row_info->rowbytes;
  1726.             png_bytep dp = sp;
  1727.             png_uint_32 i;
  1728.             for (i = 0; i < row_width; i++)
  1729.             {
  1730.                *(--dp) = (png_byte)(255 - *(--sp));
  1731.                *(--dp) = (png_byte)(255 - *(--sp));
  1732. /*             This does nothing:
  1733.                *(--dp) = *(--sp);
  1734.                *(--dp) = *(--sp);
  1735.                *(--dp) = *(--sp);
  1736.                *(--dp) = *(--sp);
  1737.                *(--dp) = *(--sp);
  1738.                *(--dp) = *(--sp);
  1739.                We can replace it with:
  1740. */
  1741.                sp-=6;
  1742.                dp=sp;
  1743.             }
  1744.          }
  1745.       }
  1746.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1747.       {
  1748.          /* This inverts the alpha channel in GA */
  1749.          if (row_info->bit_depth == 8)
  1750.          {
  1751.             png_bytep sp = row + row_info->rowbytes;
  1752.             png_bytep dp = sp;
  1753.             png_uint_32 i;
  1754.             for (i = 0; i < row_width; i++)
  1755.             {
  1756.                *(--dp) = (png_byte)(255 - *(--sp));
  1757.                *(--dp) = *(--sp);
  1758.             }
  1759.          }
  1760.          /* This inverts the alpha channel in GGAA */
  1761.          else
  1762.          {
  1763.             png_bytep sp  = row + row_info->rowbytes;
  1764.             png_bytep dp = sp;
  1765.             png_uint_32 i;
  1766.             for (i = 0; i < row_width; i++)
  1767.             {
  1768.                *(--dp) = (png_byte)(255 - *(--sp));
  1769.                *(--dp) = (png_byte)(255 - *(--sp));
  1770. /*
  1771.                *(--dp) = *(--sp);
  1772.                *(--dp) = *(--sp);
  1773. */
  1774.                sp-=2;
  1775.                dp=sp;
  1776.             }
  1777.          }
  1778.       }
  1779.    }
  1780. }
  1781. #endif
  1782. #if defined(PNG_READ_FILLER_SUPPORTED)
  1783. /* Add filler channel if we have RGB color */
  1784. void /* PRIVATE */
  1785. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1786.    png_uint_32 filler, png_uint_32 flags)
  1787. {
  1788.    png_uint_32 i;
  1789.    png_uint_32 row_width = row_info->width;
  1790.    png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
  1791.    png_byte lo_filler = (png_byte)(filler & 0xff);
  1792.    png_debug(1, "in png_do_read_filler");
  1793.    if (
  1794. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1795.        row != NULL  && row_info != NULL &&
  1796. #endif
  1797.        row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1798.    {
  1799.       if (row_info->bit_depth == 8)
  1800.       {
  1801.          /* This changes the data from G to GX */
  1802.          if (flags & PNG_FLAG_FILLER_AFTER)
  1803.          {
  1804.             png_bytep sp = row + (png_size_t)row_width;
  1805.             png_bytep dp =  sp + (png_size_t)row_width;
  1806.             for (i = 1; i < row_width; i++)
  1807.             {
  1808.                *(--dp) = lo_filler;
  1809.                *(--dp) = *(--sp);
  1810.             }
  1811.             *(--dp) = lo_filler;
  1812.             row_info->channels = 2;
  1813.             row_info->pixel_depth = 16;
  1814.             row_info->rowbytes = row_width * 2;
  1815.          }
  1816.       /* This changes the data from G to XG */
  1817.          else
  1818.          {
  1819.             png_bytep sp = row + (png_size_t)row_width;
  1820.             png_bytep dp = sp  + (png_size_t)row_width;
  1821.             for (i = 0; i < row_width; i++)
  1822.             {
  1823.                *(--dp) = *(--sp);
  1824.                *(--dp) = lo_filler;
  1825.             }
  1826.             row_info->channels = 2;
  1827.             row_info->pixel_depth = 16;
  1828.             row_info->rowbytes = row_width * 2;
  1829.          }
  1830.       }
  1831.       else if (row_info->bit_depth == 16)
  1832.       {
  1833.          /* This changes the data from GG to GGXX */
  1834.          if (flags & PNG_FLAG_FILLER_AFTER)
  1835.          {
  1836.             png_bytep sp = row + (png_size_t)row_width * 2;
  1837.             png_bytep dp = sp  + (png_size_t)row_width * 2;
  1838.             for (i = 1; i < row_width; i++)
  1839.             {
  1840.                *(--dp) = hi_filler;
  1841.                *(--dp) = lo_filler;
  1842.                *(--dp) = *(--sp);
  1843.                *(--dp) = *(--sp);
  1844.             }
  1845.             *(--dp) = hi_filler;
  1846.             *(--dp) = lo_filler;
  1847.             row_info->channels = 2;
  1848.             row_info->pixel_depth = 32;
  1849.             row_info->rowbytes = row_width * 4;
  1850.          }
  1851.          /* This changes the data from GG to XXGG */
  1852.          else
  1853.          {
  1854.             png_bytep sp = row + (png_size_t)row_width * 2;
  1855.             png_bytep dp = sp  + (png_size_t)row_width * 2;
  1856.             for (i = 0; i < row_width; i++)
  1857.             {
  1858.                *(--dp) = *(--sp);
  1859.                *(--dp) = *(--sp);
  1860.                *(--dp) = hi_filler;
  1861.                *(--dp) = lo_filler;
  1862.             }
  1863.             row_info->channels = 2;
  1864.             row_info->pixel_depth = 32;
  1865.             row_info->rowbytes = row_width * 4;
  1866.          }
  1867.       }
  1868.    } /* COLOR_TYPE == GRAY */
  1869.    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  1870.    {
  1871.       if (row_info->bit_depth == 8)
  1872.       {
  1873.          /* This changes the data from RGB to RGBX */
  1874.          if (flags & PNG_FLAG_FILLER_AFTER)
  1875.          {
  1876.             png_bytep sp = row + (png_size_t)row_width * 3;
  1877.             png_bytep dp = sp  + (png_size_t)row_width;
  1878.             for (i = 1; i < row_width; i++)
  1879.             {
  1880.                *(--dp) = lo_filler;
  1881.                *(--dp) = *(--sp);
  1882.                *(--dp) = *(--sp);
  1883.                *(--dp) = *(--sp);
  1884.             }
  1885.             *(--dp) = lo_filler;
  1886.             row_info->channels = 4;
  1887.             row_info->pixel_depth = 32;
  1888.             row_info->rowbytes = row_width * 4;
  1889.          }
  1890.       /* This changes the data from RGB to XRGB */
  1891.          else
  1892.          {
  1893.             png_bytep sp = row + (png_size_t)row_width * 3;
  1894.             png_bytep dp = sp + (png_size_t)row_width;
  1895.             for (i = 0; i < row_width; i++)
  1896.             {
  1897.                *(--dp) = *(--sp);
  1898.                *(--dp) = *(--sp);
  1899.                *(--dp) = *(--sp);
  1900.                *(--dp) = lo_filler;
  1901.             }
  1902.             row_info->channels = 4;
  1903.             row_info->pixel_depth = 32;
  1904.             row_info->rowbytes = row_width * 4;
  1905.          }
  1906.       }
  1907.       else if (row_info->bit_depth == 16)
  1908.       {
  1909.          /* This changes the data from RRGGBB to RRGGBBXX */
  1910.          if (flags & PNG_FLAG_FILLER_AFTER)
  1911.          {
  1912.             png_bytep sp = row + (png_size_t)row_width * 6;
  1913.             png_bytep dp = sp  + (png_size_t)row_width * 2;
  1914.             for (i = 1; i < row_width; i++)
  1915.             {
  1916.                *(--dp) = hi_filler;
  1917.                *(--dp) = lo_filler;
  1918.                *(--dp) = *(--sp);
  1919.                *(--dp) = *(--sp);
  1920.                *(--dp) = *(--sp);
  1921.                *(--dp) = *(--sp);
  1922.                *(--dp) = *(--sp);
  1923.                *(--dp) = *(--sp);
  1924.             }
  1925.             *(--dp) = hi_filler;
  1926.             *(--dp) = lo_filler;
  1927.             row_info->channels = 4;
  1928.             row_info->pixel_depth = 64;
  1929.             row_info->rowbytes = row_width * 8;
  1930.          }
  1931.          /* This changes the data from RRGGBB to XXRRGGBB */
  1932.          else
  1933.          {
  1934.             png_bytep sp = row + (png_size_t)row_width * 6;
  1935.             png_bytep dp = sp  + (png_size_t)row_width * 2;
  1936.             for (i = 0; i < row_width; i++)
  1937.             {
  1938.                *(--dp) = *(--sp);
  1939.                *(--dp) = *(--sp);
  1940.                *(--dp) = *(--sp);
  1941.                *(--dp) = *(--sp);
  1942.                *(--dp) = *(--sp);
  1943.                *(--dp) = *(--sp);
  1944.                *(--dp) = hi_filler;
  1945.                *(--dp) = lo_filler;
  1946.             }
  1947.             row_info->channels = 4;
  1948.             row_info->pixel_depth = 64;
  1949.             row_info->rowbytes = row_width * 8;
  1950.          }
  1951.       }
  1952.    } /* COLOR_TYPE == RGB */
  1953. }
  1954. #endif
  1955. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1956. /* expand grayscale files to RGB, with or without alpha */
  1957. void /* PRIVATE */
  1958. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1959. {
  1960.    png_uint_32 i;
  1961.    png_uint_32 row_width = row_info->width;
  1962.    png_debug(1, "in png_do_gray_to_rgb");
  1963.    if (row_info->bit_depth >= 8 &&
  1964. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1965.        row != NULL && row_info != NULL &&
  1966. #endif
  1967.       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1968.    {
  1969.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1970.       {
  1971.          if (row_info->bit_depth == 8)
  1972.          {