Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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