PNGRTRAN.C
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:97k
源码类别:

图片显示

开发平台:

Visual C++

  1. /* pngrtran.c - transforms the data in a row for png readers
  2.    libpng 1.0 beta 3 - version 0.89
  3.    For conditions of distribution and use, see copyright notice in png.h
  4.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  5.    May 25, 1996
  6.    */
  7. #define PNG_INTERNAL
  8. #include "png.h"
  9. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  10. /* handle alpha and tRNS via a background color */
  11. void
  12. png_set_background(png_structp png_ptr,
  13.    png_color_16p background_color, int background_gamma_code,
  14.    int need_expand, double background_gamma)
  15. {
  16.    png_ptr->transformations |= PNG_BACKGROUND;
  17.    png_memcpy(&(png_ptr->background), background_color,
  18.       sizeof(png_color_16));
  19.    png_ptr->background_gamma = (float)background_gamma;
  20.    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  21.    png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
  22. }
  23. #endif
  24. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  25. /* strip 16 bit depth files to 8 bit depth */
  26. void
  27. png_set_strip_16(png_structp png_ptr)
  28. {
  29.    png_ptr->transformations |= PNG_16_TO_8;
  30. }
  31. #endif
  32. #if defined(PNG_READ_DITHER_SUPPORTED)
  33. /* dither file to 8 bit.  Supply a palette, the current number
  34.    of elements in the palette, the maximum number of elements
  35.    allowed, and a histogram, if possible.  If the current number
  36.    is greater then the maximum number, the palette will be
  37.    modified to fit in the maximum number */
  38. typedef struct png_dsort_struct
  39. {
  40.    struct png_dsort_struct FAR * next;
  41.    png_byte left;
  42.    png_byte right;
  43. } png_dsort;
  44. typedef png_dsort FAR *       png_dsortp;
  45. typedef png_dsort FAR * FAR * png_dsortpp;
  46. void
  47. png_set_dither(png_structp png_ptr, png_colorp palette,
  48.    int num_palette, int maximum_colors, png_uint_16p histogram,
  49.    int full_dither)
  50. {
  51.    png_ptr->transformations |= PNG_DITHER;
  52.    if (!full_dither)
  53.    {
  54.       int i;
  55.       png_ptr->dither_index = (png_bytep)png_large_malloc(png_ptr,
  56.          num_palette * sizeof (png_byte));
  57.       for (i = 0; i < num_palette; i++)
  58.          png_ptr->dither_index[i] = (png_byte)i;
  59.    }
  60.    if (num_palette > maximum_colors)
  61.    {
  62.       if (histogram)
  63.       {
  64.          /* this is easy enough, just throw out the least used colors.
  65.             perhaps not the best solution, but good enough */
  66.          int i;
  67.          png_bytep sort;
  68.          /* initialize an array to sort colors */
  69.          sort = (png_bytep)png_large_malloc(png_ptr, num_palette * sizeof (png_byte));
  70.          /* initialize the sort array */
  71.          for (i = 0; i < num_palette; i++)
  72.             sort[i] = (png_byte)i;
  73.          /* find the least used palette entries by starting a
  74.             bubble sort, and running it until we have sorted
  75.             out enough colors.  Note that we don't care about
  76.             sorting all the colors, just finding which are
  77.             least used. */
  78.          for (i = num_palette - 1; i >= maximum_colors; i--)
  79.          {
  80.             int done; /* to stop early if the list is pre-sorted */
  81.             int j;
  82.             done = 1;
  83.             for (j = 0; j < i; j++)
  84.             {
  85.                if (histogram[sort[j]] < histogram[sort[j + 1]])
  86.                {
  87.                   png_byte t;
  88.                   t = sort[j];
  89.                   sort[j] = sort[j + 1];
  90.                   sort[j + 1] = t;
  91.                   done = 0;
  92.                }
  93.             }
  94.             if (done)
  95.                break;
  96.          }
  97.          /* swap the palette around, and set up a table, if necessary */
  98.          if (full_dither)
  99.          {
  100.             int j;
  101.             /* put all the useful colors within the max, but don't
  102.                move the others */
  103.             j = num_palette;
  104.             for (i = 0; i < maximum_colors; i++)
  105.             {
  106.                if (sort[i] >= maximum_colors)
  107.                {
  108.                   do
  109.                      j--;
  110.                   while (sort[j] >= maximum_colors);
  111.                   palette[i] = palette[j];
  112.                }
  113.             }
  114.          }
  115.          else
  116.          {
  117.             int j;
  118.             /* move all the used colors inside the max limit, and
  119.                develop a translation table */
  120.             j = num_palette;
  121.             for (i = 0; i < maximum_colors; i++)
  122.             {
  123.                /* only move the colors we need to */
  124.                if (sort[i] >= maximum_colors)
  125.                {
  126.                   png_color tmp_color;
  127.                   do
  128.                      j--;
  129.                   while (sort[j] >= maximum_colors);
  130.                   tmp_color = palette[j];
  131.                   palette[j] = palette[i];
  132.                   palette[i] = tmp_color;
  133.                   /* indicate where the color went */
  134.                   png_ptr->dither_index[j] = (png_byte)i;
  135.                   png_ptr->dither_index[i] = (png_byte)j;
  136.                }
  137.             }
  138.             /* find closest color for those colors we are not
  139.                using */
  140.             for (i = 0; i < num_palette; i++)
  141.             {
  142.                if (png_ptr->dither_index[i] >= maximum_colors)
  143.                {
  144.                   int min_d, j, min_j, index;
  145.                   /* find the closest color to one we threw out */
  146.                   index = png_ptr->dither_index[i];
  147.                   min_d = PNG_COLOR_DIST(palette[index],
  148.                         palette[0]);
  149.                   min_j = 0;
  150.                   for (j = 1; j < maximum_colors; j++)
  151.                   {
  152.                      int d;
  153.                      d = PNG_COLOR_DIST(palette[index],
  154.                         palette[j]);
  155.                      if (d < min_d)
  156.                      {
  157.                         min_d = d;
  158.                         min_j = j;
  159.                      }
  160.                   }
  161.                   /* point to closest color */
  162.                   png_ptr->dither_index[i] = (png_byte)min_j;
  163.                }
  164.             }
  165.          }
  166.          png_large_free(png_ptr, sort);
  167.       }
  168.       else
  169.       {
  170.          /* this is much harder to do simply (and quickly).  Perhaps
  171.             we need to go through a median cut routine, but those
  172.             don't always behave themselves with only a few colors
  173.             as input.  So we will just find the closest two colors,
  174.             and throw out one of them (chosen somewhat randomly).
  175.             */
  176.          int i;
  177.          int max_d;
  178.          int num_new_palette;
  179.          png_dsortpp hash;
  180.          png_bytep index_to_palette;
  181.             /* where the original index currently is in the palette */
  182.          png_bytep palette_to_index;
  183.             /* which original index points to this palette color */
  184.          /* initialize palette index arrays */
  185.          index_to_palette = (png_bytep)png_large_malloc(png_ptr,
  186.             num_palette * sizeof (png_byte));
  187.          palette_to_index = (png_bytep)png_large_malloc(png_ptr,
  188.             num_palette * sizeof (png_byte));
  189.          /* initialize the sort array */
  190.          for (i = 0; i < num_palette; i++)
  191.          {
  192.             index_to_palette[i] = (png_byte)i;
  193.             palette_to_index[i] = (png_byte)i;
  194.          }
  195.          hash = (png_dsortpp)png_large_malloc(png_ptr, 769 * sizeof (png_dsortp));
  196.          for (i = 0; i < 769; i++)
  197.             hash[i] = (png_dsortp)0;
  198. /*         png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
  199.          num_new_palette = num_palette;
  200.          /* initial wild guess at how far apart the farthest pixel
  201.             pair we will be eliminating will be.  Larger
  202.             numbers mean more areas will be allocated, Smaller
  203.             numbers run the risk of not saving enough data, and
  204.             having to do this all over again.
  205.             I have not done extensive checking on this number.
  206.             */
  207.          max_d = 96;
  208.          while (num_new_palette > maximum_colors)
  209.          {
  210.             for (i = 0; i < num_new_palette - 1; i++)
  211.             {
  212.                int j;
  213.                for (j = i + 1; j < num_new_palette; j++)
  214.                {
  215.                   int d;
  216.                   d = PNG_COLOR_DIST(palette[i], palette[j]);
  217.                   if (d <= max_d)
  218.                   {
  219.                      png_dsortp t;
  220.                      t = png_large_malloc(png_ptr, sizeof (png_dsort));
  221.                      t->next = hash[d];
  222.                      t->left = (png_byte)i;
  223.                      t->right = (png_byte)j;
  224.                      hash[d] = t;
  225.                   }
  226.                }
  227.             }
  228.             for (i = 0; i <= max_d; i++)
  229.             {
  230.                if (hash[i])
  231.                {
  232.                   png_dsortp p;
  233.                   for (p = hash[i]; p; p = p->next)
  234.                   {
  235.                      if (index_to_palette[p->left] < num_new_palette &&
  236.                         index_to_palette[p->right] < num_new_palette)
  237.                      {
  238.                         int j, next_j;
  239.                         if (num_new_palette & 1)
  240.                         {
  241.                            j = p->left;
  242.                            next_j = p->right;
  243.                         }
  244.                         else
  245.                         {
  246.                            j = p->right;
  247.                            next_j = p->left;
  248.                         }
  249.                         num_new_palette--;
  250.                         palette[index_to_palette[j]] =
  251.                            palette[num_new_palette];
  252.                         if (!full_dither)
  253.                         {
  254.                            int k;
  255.                            for (k = 0; k < num_palette; k++)
  256.                            {
  257.                               if (png_ptr->dither_index[k] ==
  258.                                  index_to_palette[j])
  259.                                  png_ptr->dither_index[k] =
  260.                                     index_to_palette[next_j];
  261.                               if (png_ptr->dither_index[k] ==
  262.                                  num_new_palette)
  263.                                  png_ptr->dither_index[k] =
  264.                                     index_to_palette[j];
  265.                            }
  266.                         }
  267.                         index_to_palette[palette_to_index[num_new_palette]] =
  268.                            index_to_palette[j];
  269.                         palette_to_index[index_to_palette[j]] =
  270.                            palette_to_index[num_new_palette];
  271.                         index_to_palette[j] = (png_byte)num_new_palette;
  272.                         palette_to_index[num_new_palette] = (png_byte)j;
  273.                      }
  274.                      if (num_new_palette <= maximum_colors)
  275.                         break;
  276.                   }
  277.                   if (num_new_palette <= maximum_colors)
  278.                      break;
  279.                }
  280.             }
  281.             for (i = 0; i < 769; i++)
  282.             {
  283.                if (hash[i])
  284.                {
  285.                   png_dsortp p;
  286.                   p = hash[i];
  287.                   while (p)
  288.                   {
  289.                      png_dsortp t;
  290.                      t = p->next;
  291.                      png_large_free(png_ptr, p);
  292.                      p = t;
  293.                   }
  294.                }
  295.                hash[i] = 0;
  296.             }
  297.             max_d += 96;
  298.          }
  299.          png_large_free(png_ptr, hash);
  300.          png_large_free(png_ptr, palette_to_index);
  301.          png_large_free(png_ptr, index_to_palette);
  302.       }
  303.       num_palette = maximum_colors;
  304.    }
  305.    if (!(png_ptr->palette))
  306.    {
  307.       png_ptr->palette = palette;
  308.    }
  309.    png_ptr->num_palette = (png_uint_16)num_palette;
  310.    if (full_dither)
  311.    {
  312.       int i;
  313.       int total_bits, num_red, num_green, num_blue;
  314.       png_uint_32 num_entries;
  315.       png_bytep distance;
  316.       total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  317.          PNG_DITHER_BLUE_BITS;
  318.       num_red = (1 << PNG_DITHER_RED_BITS);
  319.       num_green = (1 << PNG_DITHER_GREEN_BITS);
  320.       num_blue = (1 << PNG_DITHER_BLUE_BITS);
  321.       num_entries = ((png_uint_32)1 << total_bits);
  322.       png_ptr->palette_lookup = (png_bytep )png_large_malloc(png_ptr,
  323.          (png_size_t)num_entries * sizeof (png_byte));
  324.       png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte));
  325.       distance = (png_bytep )png_large_malloc(png_ptr,
  326.          (png_size_t)num_entries * sizeof (png_byte));
  327.       png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte));
  328.       for (i = 0; i < num_palette; i++)
  329.       {
  330.          int r, g, b, ir, ig, ib;
  331.          r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  332.          g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  333.          b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  334.          for (ir = 0; ir < num_red; ir++)
  335.          {
  336.             int dr, index_r;
  337.             dr = abs(ir - r);
  338.             index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  339.             for (ig = 0; ig < num_green; ig++)
  340.             {
  341.                int dg, dt, dm, index_g;
  342.                dg = abs(ig - g);
  343.                dt = dr + dg;
  344.                dm = ((dr > dg) ? dr : dg);
  345.                index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  346.                for (ib = 0; ib < num_blue; ib++)
  347.                {
  348.                   int index, db, dmax, d;
  349.                   index = index_g | ib;
  350.                   db = abs(ib - b);
  351.                   dmax = ((dm > db) ? dm : db);
  352.                   d = dmax + dt + db;
  353.                   if (d < distance[index])
  354.                   {
  355.                      distance[index] = (png_byte)d;
  356.                      png_ptr->palette_lookup[index] = (png_byte)i;
  357.                   }
  358.                }
  359.             }
  360.          }
  361.       }
  362.       png_large_free(png_ptr, distance);
  363.    }
  364. }
  365. #endif
  366. #if defined(PNG_READ_GAMMA_SUPPORTED)
  367. /* transform the image from the file_gamma to the screen_gamma */
  368. void
  369. png_set_gamma(png_structp png_ptr, double screen_gamma,
  370.    double file_gamma)
  371. {
  372.    png_ptr->transformations |= PNG_GAMMA;
  373.    png_ptr->gamma = (float)file_gamma;
  374.    png_ptr->display_gamma = (float)screen_gamma;
  375. }
  376. #endif
  377. #if defined(PNG_READ_EXPAND_SUPPORTED)
  378. /* expand paletted images to rgb, expand grayscale images of
  379.    less then 8 bit depth to 8 bit depth, and expand tRNS chunks
  380.    to alpha channels */
  381. void
  382. png_set_expand(png_structp png_ptr)
  383. {
  384.    png_ptr->transformations |= PNG_EXPAND;
  385. }
  386. #endif
  387. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  388. void
  389. png_set_gray_to_rgb(png_structp png_ptr)
  390. {
  391.    png_ptr->transformations |= PNG_GRAY_TO_RGB;
  392. }
  393. #endif
  394. /* initialize everything needed for the read.  This includes modifying
  395.    the palette */
  396. void
  397. png_init_read_transformations(png_structp png_ptr)
  398. {
  399.    int color_type;
  400.    color_type = png_ptr->color_type;
  401. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  402.    if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
  403.    {
  404.       if (color_type == PNG_COLOR_TYPE_GRAY)
  405.       {
  406.          /* expand background chunk. */
  407.          switch (png_ptr->bit_depth)
  408.          {
  409.             case 1:
  410.                png_ptr->background.gray *= (png_uint_16)0xff;
  411.                png_ptr->background.red = png_ptr->background.green =
  412.                png_ptr->background.blue = png_ptr->background.gray;
  413.                break;
  414.             case 2:
  415.                png_ptr->background.gray *= (png_uint_16)0x55;
  416.                png_ptr->background.red = png_ptr->background.green =
  417.                png_ptr->background.blue = png_ptr->background.gray;
  418.                break;
  419.             case 4:
  420.                png_ptr->background.gray *= (png_uint_16)0x11;
  421.                png_ptr->background.red = png_ptr->background.green =
  422.                png_ptr->background.blue = png_ptr->background.gray;
  423.                break;
  424.             case 8:
  425.             case 16:
  426.                png_ptr->background.red = png_ptr->background.green =
  427.                png_ptr->background.blue = png_ptr->background.gray;
  428.                break;
  429.          }
  430.       }
  431.       else if (color_type == PNG_COLOR_TYPE_PALETTE)
  432.       {
  433.          png_ptr->background.red   =
  434.             png_ptr->palette[png_ptr->background.index].red;
  435.          png_ptr->background.green =
  436.             png_ptr->palette[png_ptr->background.index].green;
  437.          png_ptr->background.blue  =
  438.             png_ptr->palette[png_ptr->background.index].blue;
  439.       }
  440.    }
  441. #endif
  442. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  443.    png_ptr->background_1 = png_ptr->background;
  444. #endif
  445. #if defined(PNG_READ_GAMMA_SUPPORTED)
  446.    if (png_ptr->transformations & PNG_GAMMA)
  447.    {
  448.       png_build_gamma_table(png_ptr);
  449. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  450.       if (png_ptr->transformations & PNG_BACKGROUND)
  451.       {
  452.          if (color_type == PNG_COLOR_TYPE_PALETTE)
  453.          {
  454.             int num_palette, i;
  455.             png_color back, back_1;
  456.             png_colorp palette;
  457.             palette = png_ptr->palette;
  458.             num_palette = png_ptr->num_palette;
  459.             back.red = png_ptr->gamma_table[png_ptr->background.red];
  460.             back.green = png_ptr->gamma_table[png_ptr->background.green];
  461.             back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  462.             back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  463.             back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  464.             back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  465.             for (i = 0; i < num_palette; i++)
  466.             {
  467.                if (i < (int)png_ptr->num_trans)
  468.                {
  469.                   if (png_ptr->trans[i] == 0)
  470.                   {
  471.                      palette[i] = back;
  472.                   }
  473.                   else if (png_ptr->trans[i] != 0xff)
  474.                   {
  475.                      int v, w;
  476.                      v = png_ptr->gamma_to_1[palette[i].red];
  477.                      w = (int)(((png_uint_32)(v) *
  478.                         (png_uint_32)(png_ptr->trans[i]) +
  479.                         (png_uint_32)(back_1.red) *
  480.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  481.                         127) / 255);
  482.                      palette[i].red = png_ptr->gamma_from_1[w];
  483.                      v = png_ptr->gamma_to_1[palette[i].green];
  484.                      w = (int)(((png_uint_32)(v) *
  485.                         (png_uint_32)(png_ptr->trans[i]) +
  486.                         (png_uint_32)(back_1.green) *
  487.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  488.                         127) / 255);
  489.                      palette[i].green = png_ptr->gamma_from_1[w];
  490.                      v = png_ptr->gamma_to_1[palette[i].blue];
  491.                      w = (int)(((png_uint_32)(v) *
  492.                         (png_uint_32)(png_ptr->trans[i]) +
  493.                         (png_uint_32)(back_1.blue) *
  494.                         (png_uint_32)(255 - png_ptr->trans[i]) +
  495.                         127) / 255);
  496.                      palette[i].blue = png_ptr->gamma_from_1[w];
  497.                   }
  498.                }
  499.                else
  500.                {
  501.                   palette[i].red = png_ptr->gamma_table[palette[i].red];
  502.                   palette[i].green = png_ptr->gamma_table[palette[i].green];
  503.                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  504.                }
  505.             }
  506.          }
  507.          else if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)
  508.          {
  509.             double g, gs, m;
  510.             m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  511.             g = 1.0;
  512.             gs = 1.0;
  513.             switch (png_ptr->background_gamma_type)
  514.             {
  515.                case PNG_BACKGROUND_GAMMA_SCREEN:
  516.                   g = (png_ptr->display_gamma);
  517.                   gs = 1.0;
  518.                   break;
  519.                case PNG_BACKGROUND_GAMMA_FILE:
  520.                   g = 1.0 / (png_ptr->gamma);
  521.                   gs = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  522.                   break;
  523.                case PNG_BACKGROUND_GAMMA_UNIQUE:
  524.                   g = 1.0 / (png_ptr->background_gamma);
  525.                   gs = 1.0 / (png_ptr->background_gamma *
  526.                      png_ptr->display_gamma);
  527.                   break;
  528.             }
  529.             if (color_type & PNG_COLOR_MASK_COLOR)
  530.             {
  531.                png_ptr->background_1.red = (png_uint_16)(pow(
  532.                   (double)png_ptr->background.red / m, g) * m + .5);
  533.                png_ptr->background_1.green = (png_uint_16)(pow(
  534.                   (double)png_ptr->background.green / m, g) * m + .5);
  535.                png_ptr->background_1.blue = (png_uint_16)(pow(
  536.                   (double)png_ptr->background.blue / m, g) * m + .5);
  537.                png_ptr->background.red = (png_uint_16)(pow(
  538.                   (double)png_ptr->background.red / m, gs) * m + .5);
  539.                png_ptr->background.green = (png_uint_16)(pow(
  540.                   (double)png_ptr->background.green / m, gs) * m + .5);
  541.                png_ptr->background.blue = (png_uint_16)(pow(
  542.                   (double)png_ptr->background.blue / m, gs) * m + .5);
  543.             }
  544.             else
  545.             {
  546.                png_ptr->background_1.gray = (png_uint_16)(pow(
  547.                   (double)png_ptr->background.gray / m, g) * m + .5);
  548.                png_ptr->background.gray = (png_uint_16)(pow(
  549.                   (double)png_ptr->background.gray / m, gs) * m + .5);
  550.             }
  551.          }
  552.       }
  553.       else
  554. #endif
  555.       if (color_type == PNG_COLOR_TYPE_PALETTE)
  556.       {
  557.          int num_palette, i;
  558.          png_colorp palette;
  559.          palette = png_ptr->palette;
  560.          num_palette = png_ptr->num_palette;
  561.          for (i = 0; i < num_palette; i++)
  562.          {
  563.             palette[i].red = png_ptr->gamma_table[palette[i].red];
  564.             palette[i].green = png_ptr->gamma_table[palette[i].green];
  565.             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  566.          }
  567.       }
  568.    }
  569. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  570.    else
  571. #endif
  572. #endif
  573. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  574.    if (png_ptr->transformations & PNG_BACKGROUND &&
  575.        color_type == PNG_COLOR_TYPE_PALETTE)
  576.    {
  577.       int i;
  578.       png_color back;
  579.       png_colorp palette;
  580.       palette = png_ptr->palette;
  581.       back.red   = (png_byte)png_ptr->background.red;
  582.       back.green = (png_byte)png_ptr->background.green;
  583.       back.blue  = (png_byte)png_ptr->background.blue;
  584.       for (i = 0; i < png_ptr->num_trans; i++)
  585.       {
  586.          if (png_ptr->trans[i] == 0)
  587.          {
  588.             palette[i] = back;
  589.          }
  590.          else if (png_ptr->trans[i] != 0xff)
  591.          {
  592.             palette[i].red = (png_byte)((
  593.                (png_uint_32)(palette[i].red) *
  594.                (png_uint_32)(png_ptr->trans[i]) +
  595.                (png_uint_32)(back.red) *
  596.                (png_uint_32)(255 - png_ptr->trans[i]) +
  597.                127) / 255);
  598.             palette[i].green = (png_byte)((
  599.                (png_uint_32)(palette[i].green) *
  600.                (png_uint_32)(png_ptr->trans[i]) +
  601.                (png_uint_32)(back.green) *
  602.                (png_uint_32)(255 - png_ptr->trans[i]) +
  603.                127) / 255);
  604.             palette[i].blue = (png_byte)((
  605.                (png_uint_32)(palette[i].blue) *
  606.                (png_uint_32)(png_ptr->trans[i]) +
  607.                (png_uint_32)(back.blue) *
  608.                (png_uint_32)(255 - png_ptr->trans[i]) +
  609.                127) / 255);
  610.          }
  611.       }
  612.    }
  613. #endif
  614. #if defined(PNG_READ_SHIFT_SUPPORTED)
  615.    if ((png_ptr->transformations & PNG_SHIFT) &&
  616.       color_type == PNG_COLOR_TYPE_PALETTE)
  617.    {
  618.       png_uint_16 i;
  619.       int sr, sg, sb;
  620.       sr = 8 - png_ptr->sig_bit.red;
  621.       if (sr < 0 || sr > 8)
  622.          sr = 0;
  623.       sg = 8 - png_ptr->sig_bit.green;
  624.       if (sg < 0 || sg > 8)
  625.          sg = 0;
  626.       sb = 8 - png_ptr->sig_bit.blue;
  627.       if (sb < 0 || sb > 8)
  628.          sb = 0;
  629.       for (i = 0; i < png_ptr->num_palette; i++)
  630.       {
  631.          png_ptr->palette[i].red >>= sr;
  632.          png_ptr->palette[i].green >>= sg;
  633.          png_ptr->palette[i].blue >>= sb;
  634.       }
  635.    }
  636. #endif
  637. }
  638. /* modify the info structure to reflect the transformations.  The
  639.    info should be updated so a png file could be written with it,
  640.    assuming the transformations result in valid png data */
  641. void
  642. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  643. {
  644. #if defined(PNG_READ_EXPAND_SUPPORTED)
  645.    if ((png_ptr->transformations & PNG_EXPAND) &&
  646.       info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  647.    {
  648.       if (png_ptr->num_trans)
  649.          info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  650.       else
  651.          info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  652.       info_ptr->bit_depth = 8;
  653.       info_ptr->num_trans = 0;
  654.    }
  655.    else if (png_ptr->transformations & PNG_EXPAND)
  656.    {
  657.       if (png_ptr->num_trans)
  658.          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  659.       if (info_ptr->bit_depth < 8)
  660.          info_ptr->bit_depth = 8;
  661.       info_ptr->num_trans = 0;
  662.    }
  663. #endif
  664. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  665.    if (png_ptr->transformations & PNG_BACKGROUND)
  666.    {
  667.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  668.       info_ptr->num_trans = 0;
  669.       info_ptr->background = png_ptr->background;
  670.    }
  671. #endif
  672. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  673.    if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
  674.       info_ptr->bit_depth = 8;
  675. #endif
  676. #if defined(PNG_READ_DITHER_SUPPORTED)
  677.    if (png_ptr->transformations & PNG_DITHER)
  678.    {
  679.       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  680.          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  681.          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  682.       {
  683.          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  684.       }
  685.    }
  686. #endif
  687. #if defined(PNG_READ_PACK_SUPPORTED)
  688.    if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
  689.       info_ptr->bit_depth = 8;
  690. #endif
  691. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  692.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  693.       !(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
  694.       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  695. #endif
  696.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  697.       info_ptr->channels = 1;
  698.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  699.       info_ptr->channels = 3;
  700.    else
  701.       info_ptr->channels = 1;
  702.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  703.       info_ptr->channels++;
  704.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  705.       info_ptr->bit_depth);
  706.    info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
  707. }
  708. /* transform the row.  The order of transformations is significant,
  709.    and is very touchy.  If you add a transformation, take care to
  710.    decide how it fits in with the other transformations here */
  711. void
  712. png_do_read_transformations(png_structp png_ptr)
  713. {
  714. #if defined(PNG_READ_EXPAND_SUPPORTED)
  715.    if ((png_ptr->transformations & PNG_EXPAND) &&
  716.       png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  717.    {
  718.       png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  719.          png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  720.    }
  721.    else if (png_ptr->transformations & PNG_EXPAND)
  722.    {
  723.       if (png_ptr->num_trans)
  724.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  725.             &(png_ptr->trans_values));
  726.       else
  727.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  728.             NULL);
  729.    }
  730. #endif
  731. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  732.    if (png_ptr->transformations & PNG_BACKGROUND)
  733.       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  734.          &(png_ptr->trans_values), &(png_ptr->background),
  735.          &(png_ptr->background_1),
  736.          png_ptr->gamma_table, png_ptr->gamma_from_1,
  737.          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  738.          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  739.          png_ptr->gamma_shift);
  740. #endif
  741. #if defined(PNG_READ_GAMMA_SUPPORTED)
  742.    if ((png_ptr->transformations & PNG_GAMMA) &&
  743.       !(png_ptr->transformations & PNG_BACKGROUND))
  744.       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  745.          png_ptr->gamma_table, png_ptr->gamma_16_table,
  746.          png_ptr->gamma_shift);
  747. #endif
  748. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  749.    if (png_ptr->transformations & PNG_16_TO_8)
  750.       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  751. #endif
  752. #if defined(PNG_READ_DITHER_SUPPORTED)
  753.    if (png_ptr->transformations & PNG_DITHER)
  754.    {
  755.       png_do_dither((png_row_infop)&(png_ptr->row_info), 
  756.          png_ptr->row_buf + 1,
  757.          png_ptr->palette_lookup,
  758.          png_ptr->dither_index);
  759.    }      
  760. #endif
  761. #if defined(PNG_READ_INVERT_SUPPORTED)
  762.    if (png_ptr->transformations & PNG_INVERT_MONO)
  763.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  764. #endif
  765. #if defined(PNG_READ_SHIFT_SUPPORTED)
  766.    if (png_ptr->transformations & PNG_SHIFT)
  767.       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  768.          &(png_ptr->shift));
  769. #endif
  770. #if defined(PNG_READ_PACK_SUPPORTED)
  771.    if (png_ptr->transformations & PNG_PACK)
  772.       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  773. #endif
  774. #if defined(PNG_READ_BGR_SUPPORTED)
  775.    if (png_ptr->transformations & PNG_BGR)
  776.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  777. #endif
  778. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  779.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  780.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  781. #endif
  782. #if defined(PNG_READ_SWAP_SUPPORTED)
  783.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  784.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  785. #endif
  786. #if defined(PNG_READ_FILLER_SUPPORTED)
  787.    if (png_ptr->transformations & PNG_FILLER)
  788.       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  789.          png_ptr->filler, png_ptr->flags);
  790. #endif
  791. }
  792. #if defined(PNG_READ_PACK_SUPPORTED)
  793. /* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  794.    without changing the actual values.  Thus, if you had a row with
  795.    a bit depth of 1, you would end up with bytes that only contained
  796.    the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  797.    png_do_shift() after this. */
  798. void
  799. png_do_unpack(png_row_infop row_info, png_bytep row)
  800. {
  801.    int shift;
  802.    png_bytep sp, dp;
  803.    png_uint_32 i;
  804.    
  805.    if (row && row_info && row_info->bit_depth < 8)
  806.    {
  807.       switch (row_info->bit_depth)
  808.       {
  809.          case 1:
  810.          {
  811.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  812.             dp = row + (png_size_t)row_info->width - 1;
  813.             shift = 7 - (int)((row_info->width + 7) & 7);
  814.             for (i = 0; i < row_info->width; i++)
  815.             {
  816.                *dp = (png_byte)((*sp >> shift) & 0x1);
  817.                if (shift == 7)
  818.                {
  819.                   shift = 0;
  820.                   sp--;
  821.                }
  822.                else
  823.                   shift++;
  824.                dp--;
  825.             }
  826.             break;
  827.          }
  828.          case 2:
  829.          {
  830.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  831.             dp = row + (png_size_t)row_info->width - 1;
  832.             shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  833.             for (i = 0; i < row_info->width; i++)
  834.             {
  835.                *dp = (png_byte)((*sp >> shift) & 0x3);
  836.                if (shift == 6)
  837.                {
  838.                   shift = 0;
  839.                   sp--;
  840.                }
  841.                else
  842.                   shift += 2;
  843.                dp--;
  844.             }
  845.             break;
  846.          }
  847.          case 4:
  848.          {
  849.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  850.             dp = row + (png_size_t)row_info->width - 1;
  851.             shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  852.             for (i = 0; i < row_info->width; i++)
  853.             {
  854.                *dp = (png_byte)((*sp >> shift) & 0xf);
  855.                if (shift == 4)
  856.                {
  857.                   shift = 0;
  858.                   sp--;
  859.                }
  860.                else
  861.                   shift = 4;
  862.                dp--;
  863.             }
  864.             break;
  865.          }
  866.       }
  867.       row_info->bit_depth = 8;
  868.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  869.       row_info->rowbytes = row_info->width * row_info->channels;
  870.    }
  871. }
  872. #endif
  873. #if defined(PNG_READ_SHIFT_SUPPORTED)
  874. /* reverse the effects of png_do_shift.  This routine merely shifts the
  875.    pixels back to their significant bits values.  Thus, if you have
  876.    a row of bit depth 8, but only 5 are significant, this will shift
  877.    the values back to 0 through 31 */
  878. void
  879. png_do_unshift(png_row_infop row_info, png_bytep row,
  880.    png_color_8p sig_bits)
  881. {
  882.    png_bytep bp;
  883.    png_uint_16 value;
  884.    png_uint_32 i;
  885.    if (row && row_info && sig_bits &&
  886.       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  887.    {
  888.       int shift[4];
  889.       int channels;
  890.       channels = 0;
  891.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  892.       {
  893.          shift[channels++] = row_info->bit_depth - sig_bits->red;
  894.          shift[channels++] = row_info->bit_depth - sig_bits->green;
  895.          shift[channels++] = row_info->bit_depth - sig_bits->blue;
  896.       }
  897.       else
  898.       {
  899.          shift[channels++] = row_info->bit_depth - sig_bits->gray;
  900.       }
  901.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  902.       {
  903.          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  904.       }
  905.       value = 0;
  906.       for (i = 0; i < channels; i++)
  907.       {
  908.          if (shift[(png_size_t)i] <= 0)
  909.             shift[(png_size_t)i] = 0;
  910.          else
  911.             value = 1;
  912.       }
  913.       if (!value)
  914.          return;
  915.       switch (row_info->bit_depth)
  916.       {
  917.          case 2:
  918.          {
  919.             for (bp = row, i = 0;
  920.                i < row_info->rowbytes;
  921.                i++, bp++)
  922.             {
  923.                *bp >>= 1;
  924.                *bp &= 0x55;
  925.             }
  926.             break;
  927.          }
  928.          case 4:
  929.          {
  930.             png_byte  mask;
  931.             mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
  932.                (png_byte)((int)0xf >> shift[0]);
  933.             for (bp = row, i = 0;
  934.                i < row_info->rowbytes;
  935.                i++, bp++)
  936.             {
  937.                *bp >>= shift[0];
  938.                *bp &= mask;
  939.             }
  940.             break;
  941.          }
  942.          case 8:
  943.          {
  944.             for (bp = row, i = 0;
  945.                i < row_info->width; i++)
  946.             {
  947.                int c;
  948.                for (c = 0; c < row_info->channels; c++, bp++)
  949.                {
  950.                   *bp >>= shift[c];
  951.                }
  952.             }
  953.             break;
  954.          }
  955.          case 16:
  956.          {
  957.             for (bp = row, i = 0;
  958.                i < row_info->width; i++)
  959.             {
  960.                int c;
  961.                for (c = 0; c < row_info->channels; c++, bp += 2)
  962.                {
  963.                   value = (png_uint_16)((*bp << 8) + *(bp + 1));
  964.                   value >>= shift[c];
  965.                   *bp = (png_byte)(value >> 8);
  966.                   *(bp + 1) = (png_byte)(value & 0xff);
  967.                }
  968.             }
  969.             break;
  970.          }
  971.       }
  972.    }
  973. }
  974. #endif
  975. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  976. /* chop rows of bit depth 16 down to 8 */
  977. void
  978. png_do_chop(png_row_infop row_info, png_bytep row)
  979. {
  980.    png_bytep sp, dp;
  981.    png_uint_32 i;
  982.    if (row && row_info && row_info->bit_depth == 16)
  983.    {
  984.       sp = row;
  985.       dp = row;
  986.       for (i = 0; i < row_info->width * row_info->channels; i++)
  987.       {
  988.          *dp = *sp;
  989. /* not yet, as I'm afraid of overflow here
  990.          *dp = ((((((png_uint_16)(*sp) << 8)) |
  991.             (png_uint_16)((*(sp + 1) - *sp) & 0xff) +
  992.             0x7f) >> 8) & 0xff);
  993. */
  994.          sp += 2;
  995.          dp++;
  996.       }
  997.       row_info->bit_depth = 8;
  998.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  999.       row_info->rowbytes = row_info->width * row_info->channels;
  1000.    }
  1001. }
  1002. #endif
  1003. #if defined(PNG_READ_FILLER_SUPPORTED)
  1004. /* add filler byte */
  1005. void
  1006. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1007.    png_byte filler, png_byte flags)
  1008. {
  1009.    png_bytep sp, dp;
  1010.    png_uint_32 i;
  1011.    if (row && row_info && row_info->color_type == 2 &&
  1012.       row_info->bit_depth == 8)
  1013.    {
  1014.       if (flags & PNG_FLAG_FILLER_AFTER)
  1015.       {
  1016.          for (i = 1, sp = row + (png_size_t)row_info->width * 3,
  1017.             dp = row + (png_size_t)row_info->width * 4;
  1018.             i < row_info->width;
  1019.             i++)
  1020.          {
  1021.             *(--dp) = filler;
  1022.             *(--dp) = *(--sp);
  1023.             *(--dp) = *(--sp);
  1024.             *(--dp) = *(--sp);
  1025.          }
  1026.          *(--dp) = filler;
  1027.          row_info->channels = 4;
  1028.          row_info->pixel_depth = 32;
  1029.          row_info->rowbytes = row_info->width * 4;
  1030.       }
  1031.       else
  1032.       {
  1033.          for (i = 0, sp = row + (png_size_t)row_info->width * 3,
  1034.             dp = row + (png_size_t)row_info->width * 4;
  1035.             i < row_info->width;
  1036.             i++)
  1037.          {
  1038.             *(--dp) = *(--sp);
  1039.             *(--dp) = *(--sp);
  1040.             *(--dp) = *(--sp);
  1041.             *(--dp) = filler;
  1042.          }
  1043.          row_info->channels = 4;
  1044.          row_info->pixel_depth = 32;
  1045.          row_info->rowbytes = row_info->width * 4;
  1046.       }
  1047.    }
  1048. }
  1049. #endif
  1050. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1051. /* expand grayscale files to rgb, with or without alpha */
  1052. void
  1053. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1054. {
  1055.    png_bytep sp, dp;
  1056.    png_uint_32 i;
  1057.    if (row && row_info && row_info->bit_depth >= 8 &&
  1058.       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1059.    {
  1060.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1061.       {
  1062.          if (row_info->bit_depth == 8)
  1063.          {
  1064.             for (i = 0, sp = row + (png_size_t)row_info->width - 1,
  1065.                dp = row + (png_size_t)row_info->width * 3 - 1;
  1066.                i < row_info->width;
  1067.                i++)
  1068.             {
  1069.                *(dp--) = *sp;
  1070.                *(dp--) = *sp;
  1071.                *(dp--) = *sp;
  1072.                sp--;
  1073.             }
  1074.          }
  1075.          else
  1076.          {
  1077.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1078.                dp = row + (png_size_t)row_info->width * 6 - 1;
  1079.                i < row_info->width;
  1080.                i++)
  1081.             {
  1082.                *(dp--) = *sp;
  1083.                *(dp--) = *(sp - 1);
  1084.                *(dp--) = *sp;
  1085.                *(dp--) = *(sp - 1);
  1086.                *(dp--) = *sp;
  1087.                *(dp--) = *(sp - 1);
  1088.                sp--;
  1089.                sp--;
  1090.             }
  1091.          }
  1092.       }
  1093.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1094.       {
  1095.          if (row_info->bit_depth == 8)
  1096.          {
  1097.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1098.                dp = row + (png_size_t)row_info->width * 4 - 1;
  1099.                i < row_info->width;
  1100.                i++)
  1101.             {
  1102.                *(dp--) = *(sp--);
  1103.                *(dp--) = *sp;
  1104.                *(dp--) = *sp;
  1105.                *(dp--) = *sp;
  1106.                sp--;
  1107.             }
  1108.          }
  1109.          else
  1110.          {
  1111.             for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1,
  1112.                dp = row + (png_size_t)row_info->width * 8 - 1;
  1113.                i < row_info->width;
  1114.                i++)
  1115.             {
  1116.                *(dp--) = *(sp--);
  1117.                *(dp--) = *(sp--);
  1118.                *(dp--) = *sp;
  1119.                *(dp--) = *(sp - 1);
  1120.                *(dp--) = *sp;
  1121.                *(dp--) = *(sp - 1);
  1122.                *(dp--) = *sp;
  1123.                *(dp--) = *(sp - 1);
  1124.                sp--;
  1125.                sp--;
  1126.             }
  1127.          }
  1128.       }
  1129.       row_info->channels += (png_byte)2;
  1130.       row_info->color_type |= PNG_COLOR_MASK_COLOR;
  1131.       row_info->pixel_depth = (png_byte)(row_info->channels *
  1132.          row_info->bit_depth);
  1133.       row_info->rowbytes = ((row_info->width *
  1134.          row_info->pixel_depth + 7) >> 3);
  1135.    }
  1136. }
  1137. #endif
  1138. /* build a grayscale palette.  Palette is assumed to be 1 << bit_depth
  1139.    large of png_color.  This lets grayscale images be treated as
  1140.    paletted.  Most useful for gamma correction and simplification
  1141.    of code. */
  1142. void
  1143. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  1144. {
  1145.    int num_palette;
  1146.    int color_inc;
  1147.    int i;
  1148.    int v;
  1149.    if (!palette)
  1150.       return;
  1151.    switch (bit_depth)
  1152.    {
  1153.       case 1:
  1154.          num_palette = 2;
  1155.          color_inc = 0xff;
  1156.          break;
  1157.       case 2:
  1158.          num_palette = 4;
  1159.          color_inc = 0x55;
  1160.          break;
  1161.       case 4:
  1162.          num_palette = 16;
  1163.          color_inc = 0x11;
  1164.          break;
  1165.       case 8:
  1166.          num_palette = 256;
  1167.          color_inc = 1;
  1168.          break;
  1169.       default:
  1170.          num_palette = 0;
  1171.          color_inc = 0;
  1172.          break;
  1173.    }
  1174.    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  1175.    {
  1176.       palette[i].red = (png_byte)v;
  1177.       palette[i].green = (png_byte)v;
  1178.       palette[i].blue = (png_byte)v;
  1179.    }
  1180. }
  1181. /* This function is currently unused? */
  1182. #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_CORRECT_PALETTE_SUPPORTED)
  1183. void
  1184. png_correct_palette(png_structp png_ptr, png_colorp palette,
  1185.    int num_palette)
  1186. {
  1187. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  1188.    if ((png_ptr->transformations & (PNG_GAMMA)) &&
  1189.       (png_ptr->transformations & (PNG_BACKGROUND)))
  1190.    {
  1191.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1192.       {
  1193.          int i;
  1194.          png_color back, back_1;
  1195.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1196.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1197.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1198.          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  1199.          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  1200.          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  1201.          for (i = 0; i < num_palette; i++)
  1202.          {
  1203.             if (i < (int)png_ptr->num_trans &&
  1204.                png_ptr->trans[i] == 0)
  1205.             {
  1206.                palette[i] = back;
  1207.             }
  1208.             else if (i < (int)png_ptr->num_trans &&
  1209.                png_ptr->trans[i] != 0xff)
  1210.             {
  1211.                int v;
  1212.                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  1213.                v = (int)(((png_uint_32)(v) *
  1214.                   (png_uint_32)(png_ptr->trans[i]) +
  1215.                   (png_uint_32)(back_1.red) *
  1216.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1217.                   127) / 255);
  1218.                palette[i].red = png_ptr->gamma_from_1[v];
  1219.                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  1220.                v = (int)(((png_uint_32)(v) *
  1221.                   (png_uint_32)(png_ptr->trans[i]) +
  1222.                   (png_uint_32)(back_1.green) *
  1223.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1224.                   127) / 255);
  1225.                palette[i].green = png_ptr->gamma_from_1[v];
  1226.                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  1227.                v = (int)(((png_uint_32)(v) *
  1228.                   (png_uint_32)(png_ptr->trans[i]) +
  1229.                   (png_uint_32)(back_1.blue) *
  1230.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1231.                   127) / 255);
  1232.                palette[i].blue = png_ptr->gamma_from_1[v];
  1233.             }
  1234.             else
  1235.             {
  1236.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1237.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1238.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1239.             }
  1240.          }
  1241.       }
  1242.       else
  1243.       {
  1244.          int i;
  1245.          png_color back;
  1246.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1247.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1248.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1249.          for (i = 0; i < num_palette; i++)
  1250.          {
  1251.             if (palette[i].red == png_ptr->trans_values.gray)
  1252.             {
  1253.                palette[i] = back;
  1254.             }
  1255.             else
  1256.             {
  1257.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1258.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1259.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1260.             }
  1261.          }
  1262.       }
  1263.    }
  1264.    else
  1265. #endif
  1266. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1267.    if (png_ptr->transformations & (PNG_GAMMA))
  1268.    {
  1269.       int i;
  1270.       for (i = 0; i < num_palette; i++)
  1271.       {
  1272.          palette[i].red = png_ptr->gamma_table[palette[i].red];
  1273.          palette[i].green = png_ptr->gamma_table[palette[i].green];
  1274.          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1275.       }
  1276.    }
  1277. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1278.    else
  1279. #endif
  1280. #endif
  1281. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1282.    if (png_ptr->transformations & (PNG_BACKGROUND))
  1283.    {
  1284.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1285.       {
  1286.          int i;
  1287.          png_color back;
  1288.          back.red   = (png_byte)png_ptr->background.red;
  1289.          back.green = (png_byte)png_ptr->background.green;
  1290.          back.blue  = (png_byte)png_ptr->background.blue;
  1291.          for (i = 0; i < num_palette; i++)
  1292.          {
  1293.             if (i >= (int)png_ptr->num_trans ||
  1294.                png_ptr->trans[i] == 0)
  1295.             {
  1296.                palette[i].red = back.red;
  1297.                palette[i].green = back.green;
  1298.                palette[i].blue = back.blue;
  1299.             }
  1300.             else if (i < (int)png_ptr->num_trans ||
  1301.                png_ptr->trans[i] != 0xff)
  1302.             {
  1303.                palette[i].red = (png_byte)((
  1304.                   (png_uint_32)(png_ptr->palette[i].red) *
  1305.                   (png_uint_32)(png_ptr->trans[i]) +
  1306.                   (png_uint_32)(back.red) *
  1307.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1308.                   127) / 255);
  1309.                palette[i].green = (png_byte)((
  1310.                   (png_uint_32)(png_ptr->palette[i].green) *
  1311.                   (png_uint_32)(png_ptr->trans[i]) +
  1312.                   (png_uint_32)(back.green) *
  1313.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1314.                   127) / 255);
  1315.                palette[i].blue = (png_byte)((
  1316.                   (png_uint_32)(png_ptr->palette[i].blue) *
  1317.                   (png_uint_32)(png_ptr->trans[i]) +
  1318.                   (png_uint_32)(back.blue) *
  1319.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1320.                   127) / 255);
  1321.             }
  1322.          }
  1323.       }
  1324.       else /* assume grayscale palette (what else could it be?) */
  1325.       {
  1326.          int i;
  1327.          for (i = 0; i < num_palette; i++)
  1328.          {
  1329.             if (i == (int)png_ptr->trans_values.gray)
  1330.             {
  1331.                palette[i].red = (png_byte)png_ptr->background.red;
  1332.                palette[i].green = (png_byte)png_ptr->background.green;
  1333.                palette[i].blue = (png_byte)png_ptr->background.blue;
  1334.             }
  1335.          }
  1336.       }
  1337.    }
  1338. #endif
  1339. }
  1340. #endif
  1341. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1342. /* replace any alpha or transparency with the supplied background color.
  1343.    background is the color.  note that paletted files are taken care of
  1344.    elsewhere */
  1345. void
  1346. png_do_background(png_row_infop row_info, png_bytep row,
  1347.    png_color_16p trans_values, png_color_16p background,
  1348.    png_color_16p background_1,
  1349.    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  1350.    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  1351.    png_uint_16pp gamma_16_to_1, int gamma_shift)
  1352. {
  1353.    png_bytep sp, dp;
  1354.    png_uint_32 i;
  1355.    int shift;
  1356.    if (row && row_info && background &&
  1357.       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  1358.       (row_info->color_type != PNG_COLOR_TYPE_PALETTE &&
  1359.       trans_values)))
  1360.    {
  1361.       switch (row_info->color_type)
  1362.       {
  1363.          case PNG_COLOR_TYPE_GRAY:
  1364.          {
  1365.             switch (row_info->bit_depth)
  1366.             {
  1367.                case 1:
  1368.                {
  1369.                   sp = row;
  1370.                   shift = 7;
  1371.                   for (i = 0; i < row_info->width; i++)
  1372.                   {
  1373.                      if (((*sp >> shift) & 0x1) ==
  1374.                         trans_values->gray)
  1375.                      {
  1376.                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  1377.                         *sp |= (png_byte)(background->gray << shift);
  1378.                      }
  1379.                      if (!shift)
  1380.                      {
  1381.                         shift = 7;
  1382.                         sp++;
  1383.                      }
  1384.                      else
  1385.                         shift--;
  1386.                   }
  1387.                   break;
  1388.                }
  1389.                case 2:
  1390.                {
  1391.                   sp = row;
  1392.                   shift = 6;
  1393.                   for (i = 0; i < row_info->width; i++)
  1394.                   {
  1395.                      if (((*sp >> shift) & 0x3) ==
  1396.                         trans_values->gray)
  1397.                      {
  1398.                         *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  1399.                         *sp |= (png_byte)(background->gray << shift);
  1400.                      }
  1401.                      if (!shift)
  1402.                      {
  1403.                         shift = 6;
  1404.                         sp++;
  1405.                      }
  1406.                      else
  1407.                         shift -= 2;
  1408.                   }
  1409.                   break;
  1410.                }
  1411.                case 4:
  1412.                {
  1413.                   sp = row;
  1414.                   shift = 4;
  1415.                   for (i = 0; i < row_info->width; i++)
  1416.                   {
  1417.                      if (((*sp >> shift) & 0xf) ==
  1418.                         trans_values->gray)
  1419.                      {
  1420.                         *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  1421.                         *sp |= (png_byte)(background->gray << shift);
  1422.                      }
  1423.                      if (!shift)
  1424.                      {
  1425.                         shift = 4;
  1426.                         sp++;
  1427.                      }
  1428.                      else
  1429.                         shift -= 4;
  1430.                   }
  1431.                   break;
  1432.                }
  1433.                case 8:
  1434.                {
  1435. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1436.                   if (gamma_table)
  1437.                   {
  1438.                      for (i = 0, sp = row;
  1439.                         i < row_info->width; i++, sp++)
  1440.                      {
  1441.                         if (*sp == trans_values->gray)
  1442.                         {
  1443.                            *sp = background->gray;
  1444.                         }
  1445.                         else
  1446.                         {
  1447.                            *sp = gamma_table[*sp];
  1448.                         }
  1449.                      }
  1450.                   }
  1451.                   else
  1452. #endif
  1453.                   {
  1454.                      for (i = 0, sp = row;
  1455.                         i < row_info->width; i++, sp++)
  1456.                      {
  1457.                         if (*sp == trans_values->gray)
  1458.                         {
  1459.                            *sp = background->gray;
  1460.                         }
  1461.                      }
  1462.                   }
  1463.                   break;
  1464.                }
  1465.                case 16:
  1466.                {
  1467. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1468.                   if (gamma_16)
  1469.                   {
  1470.                      for (i = 0, sp = row;
  1471.                         i < row_info->width; i++, sp += 2)
  1472.                      {
  1473.                         png_uint_16 v;
  1474.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1475.                            (png_uint_16)(*(sp + 1)));
  1476.                         if (v == trans_values->gray)
  1477.                         {
  1478.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1479.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1480.                         }
  1481.                         else
  1482.                         {
  1483.                            v = gamma_16[
  1484.                               *(sp + 1) >> gamma_shift][*sp];
  1485.                            *sp = (png_byte)((v >> 8) & 0xff);
  1486.                            *(sp + 1) = (png_byte)(v & 0xff);
  1487.                         }
  1488.                      }
  1489.                   }
  1490.                   else
  1491. #endif
  1492.                   {
  1493.                      for (i = 0, sp = row;
  1494.                         i < row_info->width; i++, sp += 2)
  1495.                      {
  1496.                         png_uint_16 v;
  1497.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1498.                            (png_uint_16)(*(sp + 1)));
  1499.                         if (v == trans_values->gray)
  1500.                         {
  1501.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1502.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1503.                         }
  1504.                      }
  1505.                   }
  1506.                   break;
  1507.                }
  1508.             }
  1509.             break;
  1510.          }
  1511.          case PNG_COLOR_TYPE_RGB:
  1512.          {
  1513.             if (row_info->bit_depth == 8)
  1514.             {
  1515. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1516.                if (gamma_table)
  1517.                {
  1518.                   for (i = 0, sp = row;
  1519.                      i < row_info->width; i++, sp += 3)
  1520.                   {
  1521.                      if (*sp == trans_values->red &&
  1522.                         *(sp + 1) == trans_values->green &&
  1523.                         *(sp + 2) == trans_values->blue)
  1524.                      {
  1525.                         *sp = background->red;
  1526.                         *(sp + 1) = background->green;
  1527.                         *(sp + 2) = background->blue;
  1528.                      }
  1529.                      else
  1530.                      {
  1531.                         *sp = gamma_table[*sp];
  1532.                         *(sp + 1) = gamma_table[*(sp + 1)];
  1533.                         *(sp + 2) = gamma_table[*(sp + 2)];
  1534.                      }
  1535.                   }
  1536.                }
  1537.                else
  1538. #endif
  1539.                {
  1540.                   for (i = 0, sp = row;
  1541.                      i < row_info->width; i++, sp += 3)
  1542.                   {
  1543.                      if (*sp == trans_values->red &&
  1544.                         *(sp + 1) == trans_values->green &&
  1545.                         *(sp + 2) == trans_values->blue)
  1546.                      {
  1547.                         *sp = background->red;
  1548.                         *(sp + 1) = background->green;
  1549.                         *(sp + 2) = background->blue;
  1550.                      }
  1551.                   }
  1552.                }
  1553.             }
  1554.             else if (row_info->bit_depth == 16)
  1555.             {
  1556. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1557.                if (gamma_16)
  1558.                {
  1559.                   for (i = 0, sp = row;
  1560.                      i < row_info->width; i++, sp += 6)
  1561.                   {
  1562.                      png_uint_16 r, g, b;
  1563.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1564.                         (png_uint_16)(*(sp + 1)));
  1565.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1566.                         (png_uint_16)(*(sp + 3)));
  1567.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1568.                         (png_uint_16)(*(sp + 5)));
  1569.                      if (r == trans_values->red &&
  1570.                         g == trans_values->green &&
  1571.                         b == trans_values->blue)
  1572.                      {
  1573.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1574.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1575.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1576.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1577.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1578.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1579.                      }
  1580.                      else
  1581.                      {
  1582.                         png_uint_16 v;
  1583.                         v = gamma_16[
  1584.                            *(sp + 1) >> gamma_shift][*sp];
  1585.                         *sp = (png_byte)((v >> 8) & 0xff);
  1586.                         *(sp + 1) = (png_byte)(v & 0xff);
  1587.                         v = gamma_16[
  1588.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1589.                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  1590.                         *(sp + 3) = (png_byte)(v & 0xff);
  1591.                         v = gamma_16[
  1592.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1593.                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  1594.                         *(sp + 5) = (png_byte)(v & 0xff);
  1595.                      }
  1596.                   }
  1597.                }
  1598.                else
  1599. #endif
  1600.                {
  1601.                   for (i = 0, sp = row;
  1602.                      i < row_info->width; i++, sp += 6)
  1603.                   {
  1604.                      png_uint_16 r, g, b;
  1605.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1606.                         (png_uint_16)(*(sp + 1)));
  1607.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1608.                         (png_uint_16)(*(sp + 3)));
  1609.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1610.                         (png_uint_16)(*(sp + 5)));
  1611.                      if (r == trans_values->red &&
  1612.                         g == trans_values->green &&
  1613.                         b == trans_values->blue)
  1614.                      {
  1615.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1616.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1617.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1618.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1619.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1620.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1621.                      }
  1622.                   }
  1623.                }
  1624.             }
  1625.             break;
  1626.          }
  1627.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  1628.          {
  1629.             switch (row_info->bit_depth)
  1630.             {
  1631.                case 8:
  1632.                {
  1633. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1634.                   if (gamma_to_1 && gamma_from_1 && gamma_table)
  1635.                   {
  1636.                      for (i = 0, sp = row,
  1637.                         dp = row;
  1638.                         i < row_info->width; i++, sp += 2, dp++)
  1639.                      {
  1640.                         png_uint_16 a;
  1641.                         a = *(sp + 1);
  1642.                         if (a == 0xff)
  1643.                         {
  1644.                            *dp = gamma_table[*sp];
  1645.                         }
  1646.                         else if (a == 0)
  1647.                         {
  1648.                            *dp = background->gray;
  1649.                         }
  1650.                         else
  1651.                         {
  1652.                            png_uint_16 v;
  1653.                            v = gamma_to_1[*sp];
  1654.                            v = (png_uint_16)(((png_uint_16)(v) * a +
  1655.                               (png_uint_16)background_1->gray *
  1656.                               (255 - a) + 127) / 255);
  1657.                            *dp = gamma_from_1[v];
  1658.                         }
  1659.                      }
  1660.                   }
  1661.                   else
  1662. #endif
  1663.                   {
  1664.                      for (i = 0, sp = row,
  1665.                         dp = row;
  1666.                         i < row_info->width; i++, sp += 2, dp++)
  1667.                      {
  1668.                         png_uint_16 a;
  1669.                         a = *(sp + 1);
  1670.                         if (a == 0xff)
  1671.                         {
  1672.                            *dp = *sp;
  1673.                         }
  1674.                         else if (a == 0)
  1675.                         {
  1676.                            *dp = background->gray;
  1677.                         }
  1678.                         else
  1679.                         {
  1680.                            *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1681.                               (png_uint_16)background_1->gray *
  1682.                               (255 - a) + 127) / 255);
  1683.                         }
  1684.                      }
  1685.                   }
  1686.                   break;
  1687.                }
  1688.                case 16:
  1689.                {
  1690. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1691.                   if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  1692.                   {
  1693.                      for (i = 0, sp = row,
  1694.                         dp = row;
  1695.                         i < row_info->width; i++, sp += 4, dp += 2)
  1696.                      {
  1697.                         png_uint_16 a;
  1698.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1699.                            (png_uint_16)(*(sp + 3)));
  1700.                         if (a == (png_uint_16)0xffff)
  1701.                         {
  1702.                            png_uint_32 v;
  1703.                            v = gamma_16[
  1704.                               *(sp + 1) >> gamma_shift][*sp];
  1705.                            *dp = (png_byte)((v >> 8) & 0xff);
  1706.                            *(dp + 1) = (png_byte)(v & 0xff);
  1707.                         }
  1708.                         else if (a == 0)
  1709.                         {
  1710.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1711.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1712.                         }
  1713.                         else
  1714.                         {
  1715.                            png_uint_32 g, v;
  1716.                            g = gamma_16_to_1[
  1717.                               *(sp + 1) >> gamma_shift][*sp];
  1718.                            v = (g * (png_uint_32)a +
  1719.                               (png_uint_32)background_1->gray *
  1720.                               (png_uint_32)((png_uint_16)65535L - a) +
  1721.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1722.                            v = gamma_16_from_1[(size_t)(
  1723.                               (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1724.                            *dp = (png_byte)((v >> 8) & 0xff);
  1725.                            *(dp + 1) = (png_byte)(v & 0xff);
  1726.                         }
  1727.                      }
  1728.                   }
  1729.                   else
  1730. #endif
  1731.                   {
  1732.                      for (i = 0, sp = row,
  1733.                         dp = row;
  1734.                         i < row_info->width; i++, sp += 4, dp += 2)
  1735.                      {
  1736.                         png_uint_16 a;
  1737.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1738.                            (png_uint_16)(*(sp + 3)));
  1739.                         if (a == (png_uint_16)0xffff)
  1740.                         {
  1741.                            png_memcpy(dp, sp, 2);
  1742.                         }
  1743.                         else if (a == 0)
  1744.                         {
  1745.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1746.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1747.                         }
  1748.                         else
  1749.                         {
  1750.                            png_uint_32 g, v;
  1751.                            g = ((png_uint_32)(*sp) << 8) +
  1752.                               (png_uint_32)(*(sp + 1));
  1753.                            v = (g * (png_uint_32)a +
  1754.                               (png_uint_32)background_1->gray *
  1755.                               (png_uint_32)((png_uint_16)65535L - a) +
  1756.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1757.                            *dp = (png_byte)((v >> 8) & 0xff);
  1758.                            *(dp + 1) = (png_byte)(v & 0xff);
  1759.                         }
  1760.                      }
  1761.                   }
  1762.                   break;
  1763.                }
  1764.             }
  1765.             break;
  1766.          }
  1767.          case PNG_COLOR_TYPE_RGB_ALPHA:
  1768.          {
  1769.             if (row_info->bit_depth == 8)
  1770.             {
  1771. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1772.                if (gamma_to_1 && gamma_from_1 && gamma_table)
  1773.                {
  1774.                   for (i = 0, sp = row,
  1775.                      dp = row;
  1776.                      i < row_info->width; i++, sp += 4, dp += 3)
  1777.                   {
  1778.                      png_uint_16 a;
  1779.                      a = *(sp + 3);
  1780.                      if (a == 0xff)
  1781.                      {
  1782.                         *dp = gamma_table[*sp];
  1783.                         *(dp + 1) = gamma_table[*(sp + 1)];
  1784.                         *(dp + 2) = gamma_table[*(sp + 2)];
  1785.                      }
  1786.                      else if (a == 0)
  1787.                      {
  1788.                         *dp = background->red;
  1789.                         *(dp + 1) = background->green;
  1790.                         *(dp + 2) = background->blue;
  1791.                      }
  1792.                      else
  1793.                      {
  1794.                         png_uint_16 v;
  1795.                         v = gamma_to_1[*sp];
  1796.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1797.                            (png_uint_16)background_1->red *
  1798.                            (255 - a) + 127) / 255);
  1799.                         *dp = gamma_from_1[v];
  1800.                         v = gamma_to_1[*(sp + 1)];
  1801.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1802.                            (png_uint_16)background_1->green *
  1803.                            (255 - a) + 127) / 255);
  1804.                         *(dp + 1) = gamma_from_1[v];
  1805.                         v = gamma_to_1[*(sp + 2)];
  1806.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1807.                            (png_uint_16)background_1->blue *
  1808.                            (255 - a) + 127) / 255);
  1809.                         *(dp + 2) = gamma_from_1[v];
  1810.                      }
  1811.                   }
  1812.                }
  1813.                else
  1814. #endif
  1815.                {
  1816.                   for (i = 0, sp = row,
  1817.                      dp = row;
  1818.                      i < row_info->width; i++, sp += 4, dp += 3)
  1819.                   {
  1820.                      png_uint_16 a;
  1821.                      a = *(sp + 3);
  1822.                      if (a == 0xff)
  1823.                      {
  1824.                         *dp = *sp;
  1825.                         *(dp + 1) = *(sp + 1);
  1826.                         *(dp + 2) = *(sp + 2);
  1827.                      }
  1828.                      else if (a == 0)
  1829.                      {
  1830.                         *dp = background->red;
  1831.                         *(dp + 1) = background->green;
  1832.                         *(dp + 2) = background->blue;
  1833.                      }
  1834.                      else
  1835.                      {
  1836.                         *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1837.                            (png_uint_16)background->red *
  1838.                            (255 - a) + 127) / 255);
  1839.                         *(dp + 1) = (png_byte)(((png_uint_16)(*(sp + 1)) * a +
  1840.                            (png_uint_16)background->green *
  1841.                            (255 - a) + 127) / 255);
  1842.                         *(dp + 2) = (png_byte)(((png_uint_16)(*(sp + 2)) * a +
  1843.                            (png_uint_16)background->blue *
  1844.                            (255 - a) + 127) / 255);
  1845.                      }
  1846.                   }
  1847.                }
  1848.             }
  1849.             else if (row_info->bit_depth == 16)
  1850.             {
  1851. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1852.                if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  1853.                {
  1854.                   for (i = 0, sp = row,
  1855.                      dp = row;
  1856.                      i < row_info->width; i++, sp += 8, dp += 6)
  1857.                   {
  1858.                      png_uint_16 a;
  1859.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  1860.                         (png_uint_16)(*(sp + 7)));
  1861.                      if (a == (png_uint_16)0xffff)
  1862.                      {
  1863.                         png_uint_16 v;
  1864.                         v = gamma_16[
  1865.                            *(sp + 1) >> gamma_shift][*sp];
  1866.                         *dp = (png_byte)((v >> 8) & 0xff);
  1867.                         *(dp + 1) = (png_byte)(v & 0xff);
  1868.                         v = gamma_16[
  1869.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1870.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1871.                         *(dp + 3) = (png_byte)(v & 0xff);
  1872.                         v = gamma_16[
  1873.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1874.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1875.                         *(dp + 5) = (png_byte)(v & 0xff);
  1876.                      }
  1877.                      else if (a == 0)
  1878.                      {
  1879.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  1880.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  1881.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1882.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  1883.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1884.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  1885.                      }
  1886.                      else
  1887.                      {
  1888.                         png_uint_32 v;
  1889.                         v = gamma_16_to_1[
  1890.                            *(sp + 1) >> gamma_shift][*sp];
  1891.                         v = (v * (png_uint_32)a +
  1892.                            (png_uint_32)background->red *
  1893.                            (png_uint_32)((png_uint_16)65535L - a) +
  1894.                            (png_uint_16)32767) / (png_uint_16)65535L;
  1895.                         v = gamma_16_from_1[(size_t)(
  1896.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1897.                         *dp = (png_byte)((v >> 8) & 0xff);
  1898.                         *(dp + 1) = (png_byte)(v & 0xff);
  1899.                         v = gamma_16_to_1[
  1900.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1901.                         v = (v * (png_uint_32)a +
  1902.                            (png_uint_32)background->green *
  1903.                            (png_uint_32)((png_uint_16)65535L - a) +
  1904.                            (png_uint_16)32767) / (png_uint_16)65535L;
  1905.                         v = gamma_16_from_1[(size_t)(
  1906.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1907.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1908.                         *(dp + 3) = (png_byte)(v & 0xff);
  1909.                         v = gamma_16_to_1[
  1910.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1911.                         v = (v * (png_uint_32)a +
  1912.                            (png_uint_32)background->blue *
  1913.                            (png_uint_32)((png_uint_16)65535L - a) +
  1914.                            (png_uint_16)32767) / (png_uint_16)65535L;
  1915.                         v = gamma_16_from_1[(size_t)(
  1916.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1917.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1918.                         *(dp + 5) = (png_byte)(v & 0xff);
  1919.                      }
  1920.                   }
  1921.                }
  1922.                else
  1923. #endif
  1924.                {
  1925.                   for (i = 0, sp = row,
  1926.                      dp = row;
  1927.                      i < row_info->width; i++, sp += 8, dp += 6)
  1928.                   {
  1929.                      png_uint_16 a;
  1930.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  1931.                         (png_uint_16)(*(sp + 7)));
  1932.                      if (a == (png_uint_16)0xffff)
  1933.                      {
  1934.                         png_memcpy(dp, sp, 6);
  1935.                      }
  1936.                      else if (a == 0)
  1937.                      {
  1938.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  1939.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  1940.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1941.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  1942.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1943.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  1944.                      }
  1945.                      else
  1946.                      {
  1947.                         png_uint_32 r, g, b, v;
  1948.                         r = ((png_uint_32)(*sp) << 8) +
  1949.                            (png_uint_32)(*(sp + 1));
  1950.                         g = ((png_uint_32)(*(sp + 2)) << 8) +
  1951.                            (png_uint_32)(*(sp + 3));
  1952.                         b = ((png_uint_32)(*(sp + 4)) << 8) +
  1953.                            (png_uint_32)(*(sp + 5));
  1954.                         v = (r * (png_uint_32)a +
  1955.                            (png_uint_32)background->red *
  1956.                            (png_uint_32)((png_uint_32)65535L - a) +
  1957.                            (png_uint_32)32767) / (png_uint_32)65535L;
  1958.                         *dp = (png_byte)((v >> 8) & 0xff);
  1959.                         *(dp + 1) = (png_byte)(v & 0xff);
  1960.                         v = (g * (png_uint_32)a +
  1961.                            (png_uint_32)background->green *
  1962.                            (png_uint_32)((png_uint_32)65535L - a) +
  1963.                            (png_uint_32)32767) / (png_uint_32)65535L;
  1964.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1965.                         *(dp + 3) = (png_byte)(v & 0xff);
  1966.                         v = (b * (png_uint_32)a +
  1967.                            (png_uint_32)background->blue *
  1968.                            (png_uint_32)((png_uint_32)65535L - a) +
  1969.                            (png_uint_32)32767) / (png_uint_32)65535L;
  1970.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1971.                         *(dp + 5) = (png_byte)(v & 0xff);
  1972.                      }
  1973.                   }
  1974.                }
  1975.             }
  1976.             break;
  1977.          }
  1978.       }
  1979.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1980.       {
  1981.          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1982.          row_info->channels--;
  1983.          row_info->pixel_depth = (png_byte)(row_info->channels *
  1984.             row_info->bit_depth);
  1985.          row_info->rowbytes = ((row_info->width *
  1986.             row_info->pixel_depth + 7) >> 3);
  1987.       }
  1988.    }
  1989. }
  1990. #endif
  1991. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1992. /* gamma correct the image, avoiding the alpha channel.  Make sure
  1993.    you do this after you deal with the trasparency issue on grayscale
  1994.    or rgb images. If your bit depth is 8, use gamma_table, if it is 16,
  1995.    use gamma_16_table and gamma_shift.  Build these with
  1996.    build_gamma_table().  If your bit depth <= 8, gamma correct a
  1997.    palette, not the data.  */
  1998. void
  1999. png_do_gamma(png_row_infop row_info, png_bytep row,
  2000.    png_bytep gamma_table, png_uint_16pp gamma_16_table,
  2001.    int gamma_shift)
  2002. {
  2003.    png_bytep sp;
  2004.    png_uint_32 i;
  2005.    if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) ||
  2006.       (row_info->bit_depth == 16 && gamma_16_table)))
  2007.    {
  2008.       switch (row_info->color_type)
  2009.       {
  2010.          case PNG_COLOR_TYPE_RGB:
  2011.          {
  2012.             if (row_info->bit_depth == 8)
  2013.             {
  2014.                for (i = 0, sp = row;
  2015.                   i < row_info->width; i++)
  2016.                {
  2017.                   *sp = gamma_table[*sp];
  2018.                   sp++;
  2019.                   *sp = gamma_table[*sp];
  2020.                   sp++;
  2021.                   *sp = gamma_table[*sp];
  2022.                   sp++;
  2023.                }
  2024.             }
  2025.             else if (row_info->bit_depth == 16)
  2026.             {
  2027.                for (i = 0, sp = row;
  2028.                   i < row_info->width; i++)
  2029.                {
  2030.                   png_uint_16 v;
  2031.                   v = gamma_16_table[*(sp + 1) >>
  2032.                      gamma_shift][*sp];
  2033.                   *sp = (png_byte)((v >> 8) & 0xff);
  2034.                   *(sp + 1) = (png_byte)(v & 0xff);
  2035.                   sp += 2;
  2036.                   v = gamma_16_table[*(sp + 1) >>
  2037.                      gamma_shift][*sp];
  2038.                   *sp = (png_byte)((v >> 8) & 0xff);
  2039.                   *(sp + 1) = (png_byte)(v & 0xff);
  2040.                   sp += 2;
  2041.                   v = gamma_16_table[*(sp + 1) >>
  2042.                      gamma_shift][*sp];
  2043.                   *sp = (png_byte)((v >> 8) & 0xff);
  2044.                   *(sp + 1) = (png_byte)(v & 0xff);
  2045.                   sp += 2;
  2046.                }
  2047.             }
  2048.             break;
  2049.          }
  2050.          case PNG_COLOR_TYPE_RGB_ALPHA:
  2051.          {
  2052.             if (row_info->bit_depth == 8)
  2053.             {
  2054.                for (i = 0, sp = row;
  2055.                   i < row_info->width; i++)
  2056.                {
  2057.                   *sp = gamma_table[*sp];
  2058.                   sp++;
  2059.                   *sp = gamma_table[*sp];
  2060.                   sp++;
  2061.                   *sp = gamma_table[*sp];
  2062.                   sp++;
  2063.                   sp++;
  2064.                }
  2065.             }
  2066.             else if (row_info->bit_depth == 16)
  2067.             {
  2068.                for (i = 0, sp = row;
  2069.                   i < row_info->width; i++)
  2070.                {
  2071.                   png_uint_16 v;
  2072.                   v = gamma_16_table[*(sp + 1) >>
  2073.                      gamma_shift][*sp];
  2074.                   *sp = (png_byte)((v >> 8) & 0xff);
  2075.                   *(sp + 1) = (png_byte)(v & 0xff);
  2076.                   sp += 2;
  2077.                   v = gamma_16_table[*(sp + 1) >>
  2078.                      gamma_shift][*sp];
  2079.                   *sp = (png_byte)((v >> 8) & 0xff);
  2080.                   *(sp + 1) = (png_byte)(v & 0xff);
  2081.                   sp += 2;
  2082.                   v = gamma_16_table[*(sp + 1) >>
  2083.                      gamma_shift][*sp];
  2084.                   *sp = (png_byte)((v >> 8) & 0xff);
  2085.                   *(sp + 1) = (png_byte)(v & 0xff);
  2086.                   sp += 4;
  2087.                }
  2088.             }
  2089.             break;
  2090.          }
  2091.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  2092.          {
  2093.             if (row_info->bit_depth == 8)
  2094.             {
  2095.                for (i = 0, sp = row;
  2096.                   i < row_info->width; i++)
  2097.                {
  2098.                   *sp = gamma_table[*sp];
  2099.                   sp++;
  2100.                   sp++;
  2101.                }
  2102.             }
  2103.             else if (row_info->bit_depth == 16)
  2104.             {
  2105.                for (i = 0, sp = row;
  2106.                   i < row_info->width; i++)
  2107.                {
  2108.                   png_uint_16 v;
  2109.                   v = gamma_16_table[*(sp + 1) >>
  2110.                      gamma_shift][*sp];
  2111.                   *sp = (png_byte)((v >> 8) & 0xff);
  2112.                   *(sp + 1) = (png_byte)(v & 0xff);
  2113.                   sp += 4;
  2114.                }
  2115.             }
  2116.             break;
  2117.          }
  2118.          case PNG_COLOR_TYPE_GRAY:
  2119.          {
  2120.             if (row_info->bit_depth == 8)
  2121.             {
  2122.                for (i = 0, sp = row;
  2123.                   i < row_info->width; i++)
  2124.                {
  2125.                   *sp = gamma_table[*sp];
  2126.                   sp++;
  2127.                }
  2128.             }
  2129.             else if (row_info->bit_depth == 16)
  2130.             {
  2131.                for (i = 0, sp = row;
  2132.                   i < row_info->width; i++)
  2133.                {
  2134.                   png_uint_16 v;
  2135.                   v = gamma_16_table[*(sp + 1) >>
  2136.                      gamma_shift][*sp];
  2137.                   *sp = (png_byte)((v >> 8) & 0xff);
  2138.                   *(sp + 1) = (png_byte)(v & 0xff);
  2139.                   sp += 2;
  2140.                }
  2141.             }
  2142.             break;
  2143.          }
  2144.       }
  2145.    }
  2146. }
  2147. #endif
  2148. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2149. /* expands a palette row to an rgb or rgba row depending
  2150.    upon whether you supply trans and num_trans */
  2151. void
  2152. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  2153.    png_colorp palette,
  2154.    png_bytep trans, int num_trans)
  2155. {
  2156.    int shift, value;
  2157.    png_bytep sp, dp;
  2158.    png_uint_32 i;
  2159.    if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  2160.    {
  2161.       if (row_info->bit_depth < 8)
  2162.       {
  2163.          switch (row_info->bit_depth)
  2164.          {
  2165.             case 1:
  2166.             {
  2167.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2168.                dp = row + (png_size_t)row_info->width - 1;
  2169.                shift = 7 - (int)((row_info->width + 7) & 7);
  2170.                for (i = 0; i < row_info->width; i++)
  2171.                {
  2172.                   if ((*sp >> shift) & 0x1)
  2173.                      *dp = 1;
  2174.                   else
  2175.                      *dp = 0;
  2176.                   if (shift == 7)
  2177.                   {
  2178.                      shift = 0;
  2179.                      sp--;
  2180.                   }
  2181.                   else
  2182.                      shift++;
  2183.                   dp--;
  2184.                }
  2185.                break;
  2186.             }
  2187.             case 2:
  2188.             {
  2189.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2190.                dp = row + (png_size_t)row_info->width - 1;
  2191.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2192.                for (i = 0; i < row_info->width; i++)
  2193.                {
  2194.                   value = (*sp >> shift) & 0x3;
  2195.                   *dp = (png_byte)value;
  2196.                   if (shift == 6)
  2197.                   {
  2198.                      shift = 0;
  2199.                      sp--;
  2200.                   }
  2201.                   else
  2202.                      shift += 2;
  2203.                   dp--;
  2204.                }
  2205.                break;
  2206.             }
  2207.             case 4:
  2208.             {
  2209.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2210.                dp = row + (png_size_t)row_info->width - 1;
  2211.                shift = (int)((row_info->width & 1) << 2);
  2212.                for (i = 0; i < row_info->width; i++)
  2213.                {
  2214.                   value = (*sp >> shift) & 0xf;
  2215.                   *dp = (png_byte)value;
  2216.                   if (shift == 4)
  2217.                   {
  2218.                      shift = 0;
  2219.                      sp--;
  2220.                   }
  2221.                   else
  2222.                      shift += 4;
  2223.                   dp--;
  2224.                }
  2225.                break;
  2226.             }
  2227.          }
  2228.          row_info->bit_depth = 8;
  2229.          row_info->pixel_depth = 8;
  2230.          row_info->rowbytes = row_info->width;
  2231.       }
  2232.       switch (row_info->bit_depth)
  2233.       {
  2234.          case 8:
  2235.          {
  2236.             if (trans)
  2237.             {
  2238.                sp = row + (png_size_t)row_info->width - 1;
  2239.                dp = row + (png_size_t)(row_info->width << 2) - 1;
  2240.                for (i = 0; i < row_info->width; i++)
  2241.                {
  2242.                   if (*sp >= (png_byte)num_trans)
  2243.                      *dp-- = 0xff;
  2244.                   else
  2245.                      *dp-- = trans[*sp];
  2246.                   *dp-- = palette[*sp].blue;
  2247.                   *dp-- = palette[*sp].green;
  2248.                   *dp-- = palette[*sp].red;
  2249.                   sp--;
  2250.                }
  2251.                row_info->bit_depth = 8;
  2252.                row_info->pixel_depth = 32;
  2253.                row_info->rowbytes = row_info->width * 4;
  2254.                row_info->color_type = 6;
  2255.                row_info->channels = 4;
  2256.             }
  2257.             else
  2258.             {
  2259.                sp = row + (png_size_t)row_info->width - 1;
  2260.                dp = row + (png_size_t)(row_info->width * 3) - 1;
  2261.                for (i = 0; i < row_info->width; i++)
  2262.                {
  2263.                   *dp-- = palette[*sp].blue;
  2264.                   *dp-- = palette[*sp].green;
  2265.                   *dp-- = palette[*sp].red;
  2266.                   sp--;
  2267.                }
  2268.                row_info->bit_depth = 8;
  2269.                row_info->pixel_depth = 24;
  2270.                row_info->rowbytes = row_info->width * 3;
  2271.                row_info->color_type = 2;
  2272.                row_info->channels = 3;
  2273.             }
  2274.             break;
  2275.          }
  2276.       }
  2277.    }
  2278. }
  2279. /* if the bit depth < 8, it is expanded to 8.  Also, if the
  2280.    transparency value is supplied, an alpha channel is built. */
  2281. void
  2282. png_do_expand(png_row_infop row_info, png_bytep row,
  2283.    png_color_16p trans_value)
  2284. {
  2285.    int shift, value;
  2286.    png_bytep sp, dp;
  2287.    png_uint_32 i;
  2288.    if (row && row_info)
  2289.    {
  2290.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
  2291.          row_info->bit_depth < 8)
  2292.       {
  2293.          switch (row_info->bit_depth)
  2294.          {
  2295.             case 1:
  2296.             {
  2297.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2298.                dp = row + (png_size_t)row_info->width - 1;
  2299.                shift = 7 - (int)((row_info->width + 7) & 7);
  2300.                for (i = 0; i < row_info->width; i++)
  2301.                {
  2302.                   if ((*sp >> shift) & 0x1)
  2303.                      *dp = 0xff;
  2304.                   else
  2305.                      *dp = 0;
  2306.                   if (shift == 7)
  2307.                   {
  2308.                      shift = 0;
  2309.                      sp--;
  2310.                   }
  2311.                   else
  2312.                      shift++;
  2313.                   dp--;
  2314.                }
  2315.                break;
  2316.             }
  2317.             case 2:
  2318.             {
  2319.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2320.                dp = row + (png_size_t)row_info->width - 1;
  2321.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2322.                for (i = 0; i < row_info->width; i++)
  2323.                {
  2324.                   value = (*sp >> shift) & 0x3;
  2325.                   *dp = (png_byte)(value | (value << 2) | (value << 4) |
  2326.                      (value << 6));
  2327.                   if (shift == 6)
  2328.                   {
  2329.                      shift = 0;
  2330.                      sp--;
  2331.                   }
  2332.                   else
  2333.                      shift += 2;
  2334.                   dp--;
  2335.                }
  2336.                break;
  2337.             }
  2338.             case 4:
  2339.             {
  2340.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2341.                dp = row + (png_size_t)row_info->width - 1;
  2342.                shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  2343.                for (i = 0; i < row_info->width; i++)
  2344.                {
  2345.                   value = (*sp >> shift) & 0xf;
  2346.                   *dp = (png_byte)(value | (value << 4));
  2347.                   if (shift == 4)
  2348.                   {
  2349.                      shift = 0;
  2350.                      sp--;
  2351.                   }
  2352.                   else
  2353.                      shift = 4;
  2354.                   dp--;
  2355.                }
  2356.                break;
  2357.             }
  2358.          }
  2359.          row_info->bit_depth = 8;
  2360.          row_info->pixel_depth = 8;
  2361.          row_info->rowbytes = row_info->width;
  2362.       }
  2363.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY && trans_value)
  2364.       {
  2365.          if (row_info->bit_depth == 8)
  2366.          {
  2367.             sp = row + (png_size_t)row_info->width - 1;
  2368.             dp = row + (png_size_t)(row_info->width << 1) - 1;
  2369.             for (i = 0; i < row_info->width; i++)
  2370.             {
  2371.                if (*sp == trans_value->gray)
  2372.                   *dp-- = 0;
  2373.                else
  2374.                   *dp-- = 0xff;
  2375.                *dp-- = *sp--;
  2376.             }
  2377.          }
  2378.          else if (row_info->bit_depth == 16)
  2379.          {
  2380.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2381.             dp = row + (png_size_t)(row_info->rowbytes << 1) - 1;
  2382.             for (i = 0; i < row_info->width; i++)
  2383.             {
  2384.                if (((png_uint_16)*(sp) |
  2385.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->gray)
  2386.                {
  2387.                   *dp-- = 0;
  2388.                   *dp-- = 0;
  2389.                }
  2390.                else
  2391.                {
  2392.                   *dp-- = 0xff;
  2393.                   *dp-- = 0xff;
  2394.                }
  2395.                *dp-- = *sp--;
  2396.                *dp-- = *sp--;
  2397.             }
  2398.          }
  2399.          row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  2400.          row_info->channels = 2;
  2401.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  2402.          row_info->rowbytes =
  2403.             ((row_info->width * row_info->pixel_depth) >> 3);
  2404.       }
  2405.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  2406.       {
  2407.          if (row_info->bit_depth == 8)
  2408.          {
  2409.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2410.             dp = row + (png_size_t)(row_info->width << 2) - 1;
  2411.             for (i = 0; i < row_info->width; i++)
  2412.             {
  2413.                if (*(sp - 2) == trans_value->red &&
  2414.                   *(sp - 1) == trans_value->green &&
  2415.                   *(sp - 0) == trans_value->blue)
  2416.                   *dp-- = 0;
  2417.                else
  2418.                   *dp-- = 0xff;
  2419.                *dp-- = *sp--;
  2420.                *dp-- = *sp--;
  2421.                *dp-- = *sp--;
  2422.             }
  2423.          }
  2424.          else if (row_info->bit_depth == 16)
  2425.          {
  2426.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2427.             dp = row + (png_size_t)(row_info->width << 3) - 1;
  2428.             for (i = 0; i < row_info->width; i++)
  2429.             {
  2430.                if ((((png_uint_16)*(sp - 4) |
  2431.                   ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
  2432.                   (((png_uint_16)*(sp - 2) |
  2433.                   ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
  2434.                   (((png_uint_16)*(sp - 0) |
  2435.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
  2436.                {
  2437.                   *dp-- = 0;
  2438.                   *dp-- = 0;
  2439.                }
  2440.                else
  2441.                {
  2442.                   *dp-- = 0xff;
  2443.                   *dp-- = 0xff;
  2444.                }
  2445.                *dp-- = *sp--;
  2446.                *dp-- = *sp--;
  2447.                *dp-- = *sp--;
  2448.                *dp-- = *sp--;
  2449.                *dp-- = *sp--;
  2450.                *dp-- = *sp--;
  2451.             }
  2452.          }
  2453.          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  2454.          row_info->channels = 4;
  2455.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  2456.          row_info->rowbytes =
  2457.             ((row_info->width * row_info->pixel_depth) >> 3);
  2458.       }
  2459.    }
  2460. }
  2461. #endif
  2462. #if defined(PNG_READ_DITHER_SUPPORTED)
  2463. void
  2464. png_do_dither(png_row_infop row_info, png_bytep row,
  2465.     png_bytep palette_lookup, png_bytep dither_lookup)
  2466. {
  2467.    png_bytep sp, dp;
  2468.    png_uint_32 i;
  2469.    if (row && row_info)
  2470.    {
  2471.       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  2472.          palette_lookup && row_info->bit_depth == 8)
  2473.       {
  2474.          int r, g, b, p;
  2475.          sp = row;
  2476.          dp = row;
  2477.          for (i = 0; i < row_info->width; i++)
  2478.          {
  2479.             r = *sp++;
  2480.             g = *sp++;
  2481.             b = *sp++;
  2482.             /* this looks real messy, but the compiler will reduce
  2483.                it down to a reasonable formula.  For example, with
  2484.                5 bits per color, we get:
  2485.                p = (((r >> 3) & 0x1f) << 10) |
  2486.                   (((g >> 3) & 0x1f) << 5) |
  2487.                   ((b >> 3) & 0x1f);
  2488.                */
  2489.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2490.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2491.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2492.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2493.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2494.                (PNG_DITHER_BLUE_BITS)) |
  2495.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2496.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2497.             *dp++ = palette_lookup[p];
  2498.          }
  2499.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2500.          row_info->channels = 1;
  2501.          row_info->pixel_depth = row_info->bit_depth;
  2502.          row_info->rowbytes =
  2503.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2504.       }
  2505.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  2506.          palette_lookup && row_info->bit_depth == 8)
  2507.       {
  2508.          int r, g, b, p;
  2509.          sp = row;
  2510.          dp = row;
  2511.          for (i = 0; i < row_info->width; i++)
  2512.          {
  2513.             r = *sp++;
  2514.             g = *sp++;
  2515.             b = *sp++;
  2516.             sp++;
  2517.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2518.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2519.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2520.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2521.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2522.                (PNG_DITHER_BLUE_BITS)) |
  2523.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2524.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2525.             *dp++ = palette_lookup[p];
  2526.          }
  2527.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2528.          row_info->channels = 1;
  2529.          row_info->pixel_depth = row_info->bit_depth;
  2530.          row_info->rowbytes =
  2531.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2532.       }
  2533.       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  2534.          dither_lookup && row_info->bit_depth == 8)
  2535.       {
  2536.          sp = row;
  2537.          for (i = 0; i < row_info->width; i++, sp++)
  2538.          {
  2539.             *sp = dither_lookup[*sp];
  2540.          }
  2541.       }
  2542.    }
  2543. }
  2544. #endif
  2545. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2546. static int png_gamma_shift[] =
  2547.    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
  2548. void
  2549. png_build_gamma_table(png_structp png_ptr)
  2550. {
  2551.    if (png_ptr->bit_depth <= 8)
  2552.    {
  2553.       int i;
  2554.       double g;
  2555.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2556.       png_ptr->gamma_table = (png_bytep)png_large_malloc(png_ptr,
  2557.          (png_uint_32)256);
  2558.       for (i = 0; i < 256; i++)
  2559.       {
  2560.          png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  2561.             g) * 255.0 + .5);
  2562.       }
  2563.       if (png_ptr->transformations & PNG_BACKGROUND)
  2564.       {
  2565.          g = 1.0 / (png_ptr->gamma);
  2566.          png_ptr->gamma_to_1 = (png_bytep)png_large_malloc(png_ptr,
  2567.             (png_uint_32)256);
  2568.          for (i = 0; i < 256; i++)
  2569.          {
  2570.             png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  2571.                g) * 255.0 + .5);
  2572.          }
  2573.          g = 1.0 / (png_ptr->display_gamma);
  2574.          png_ptr->gamma_from_1 = (png_bytep)png_large_malloc(png_ptr,
  2575.             (png_uint_32)256);
  2576.          for (i = 0; i < 256; i++)
  2577.          {
  2578.             png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  2579.                g) * 255.0 + .5);
  2580.          }
  2581.       }
  2582.    }
  2583.    else
  2584.    {
  2585.       double g;
  2586.       int i, j, shift, num;
  2587.       int sig_bit;
  2588.       png_uint_32 ig;
  2589.       if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  2590.       {
  2591.          sig_bit = (int)png_ptr->sig_bit.red;
  2592.          if ((int)png_ptr->sig_bit.green > sig_bit)
  2593.             sig_bit = png_ptr->sig_bit.green;
  2594.          if ((int)png_ptr->sig_bit.blue > sig_bit)
  2595.             sig_bit = png_ptr->sig_bit.blue;
  2596.       }
  2597.       else
  2598.       {
  2599.          sig_bit = (int)png_ptr->sig_bit.gray;
  2600.       }
  2601.       if (sig_bit > 0)
  2602.          shift = 16 - sig_bit;
  2603.       else
  2604.          shift = 0;
  2605.       if (png_ptr->transformations & PNG_16_TO_8)
  2606.       {
  2607.          if (shift < (16 - PNG_MAX_GAMMA_8))
  2608.             shift = (16 - PNG_MAX_GAMMA_8);
  2609.       }
  2610.       if (shift > 8)
  2611.          shift = 8;
  2612.       if (shift < 0)
  2613.          shift = 0;
  2614.       png_ptr->gamma_shift = (png_byte)shift;
  2615.       num = (1 << (8 - shift));
  2616.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2617.       png_ptr->gamma_16_table = (png_uint_16pp)png_large_malloc(png_ptr,
  2618.          num * sizeof (png_uint_16p ));
  2619.       if ((png_ptr->transformations & PNG_16_TO_8) &&
  2620.          !(png_ptr->transformations & PNG_BACKGROUND))
  2621.       {
  2622.          double fin, fout;
  2623.          png_uint_32 last, max;
  2624.          for (i = 0; i < num; i++)
  2625.          {
  2626.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2627.                256 * sizeof (png_uint_16));
  2628.          }
  2629.          g = 1.0 / g;
  2630.          last = 0;
  2631.          for (i = 0; i < 256; i++)
  2632.          {
  2633.             fout = ((double)i + 0.5) / 256.0;
  2634.             fin = pow(fout, g);
  2635.             max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  2636.             while (last <= max)
  2637.             {
  2638.                png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2639.                   [(int)(last >> (8 - shift))] = (png_uint_16)(
  2640.                   (png_uint_16)i | ((png_uint_16)i << 8));
  2641.                last++;
  2642.             }
  2643.          }
  2644.          while (last < ((png_uint_32)num << 8))
  2645.          {
  2646.             png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2647.                [(int)(last >> (8 - shift))] =
  2648.                (png_uint_16)65535L;
  2649.             last++;
  2650.          }
  2651.       }
  2652.       else
  2653.       {
  2654.          for (i = 0; i < num; i++)
  2655.          {
  2656.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2657.                256 * sizeof (png_uint_16));
  2658.             ig = (((png_uint_32)i *
  2659.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2660.             for (j = 0; j < 256; j++)
  2661.             {
  2662.                png_ptr->gamma_16_table[i][j] =
  2663.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2664.                      65535.0, g) * 65535.0 + .5);
  2665.             }
  2666.          }
  2667.       }
  2668.       if (png_ptr->transformations & PNG_BACKGROUND)
  2669.       {
  2670.          g = 1.0 / (png_ptr->gamma);
  2671.          png_ptr->gamma_16_to_1 = (png_uint_16pp)png_large_malloc(png_ptr,
  2672.             num * sizeof (png_uint_16p ));
  2673.          for (i = 0; i < num; i++)
  2674.          {
  2675.             png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2676.                256 * sizeof (png_uint_16));
  2677.             ig = (((png_uint_32)i *
  2678.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2679.             for (j = 0; j < 256; j++)
  2680.             {
  2681.                png_ptr->gamma_16_to_1[i][j] =
  2682.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2683.                      65535.0, g) * 65535.0 + .5);
  2684.             }
  2685.          }
  2686.          g = 1.0 / (png_ptr->display_gamma);
  2687.          png_ptr->gamma_16_from_1 = (png_uint_16pp)png_large_malloc(png_ptr,
  2688.             num * sizeof (png_uint_16p));
  2689.          for (i = 0; i < num; i++)
  2690.          {
  2691.             png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_large_malloc(png_ptr,
  2692.                256 * sizeof (png_uint_16));
  2693.             ig = (((png_uint_32)i *
  2694.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2695.             for (j = 0; j < 256; j++)
  2696.             {
  2697.                png_ptr->gamma_16_from_1[i][j] =
  2698.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2699.                      65535.0, g) * 65535.0 + .5);
  2700.             }
  2701.          }
  2702.       }
  2703.    }
  2704. }
  2705. #endif