pngrtran.c
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:143k
源码类别:

Windows Mobile

开发平台:

Visual C++

  1.                *(dp--) = *(sp--);
  2.             }
  3.          }
  4.       }
  5.       row_info->channels += (png_byte)2;
  6.       row_info->color_type |= PNG_COLOR_MASK_COLOR;
  7.       row_info->pixel_depth = (png_byte)(row_info->channels *
  8.          row_info->bit_depth);
  9.       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  10.    }
  11. }
  12. #endif
  13. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  14. /* reduce RGB files to grayscale, with or without alpha
  15.  * using the equation given in Poynton's ColorFAQ at
  16.  * <http://www.inforamp.net/~poynton/>
  17.  * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
  18.  *
  19.  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
  20.  *
  21.  *  We approximate this with
  22.  *
  23.  *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
  24.  *
  25.  *  which can be expressed with integers as
  26.  *
  27.  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
  28.  *
  29.  *  The calculation is to be done in a linear colorspace.
  30.  *
  31.  *  Other integer coefficents can be used via png_set_rgb_to_gray().
  32.  */
  33. int /* PRIVATE */
  34. png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
  35. {
  36.    png_uint_32 i;
  37.    png_uint_32 row_width = row_info->width;
  38.    int rgb_error = 0;
  39.    png_debug(1, "in png_do_rgb_to_grayn");
  40.    if (
  41. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  42.        row != NULL && row_info != NULL &&
  43. #endif
  44.       (row_info->color_type & PNG_COLOR_MASK_COLOR))
  45.    {
  46.       png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
  47.       png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
  48.       png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
  49.       if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  50.       {
  51.          if (row_info->bit_depth == 8)
  52.          {
  53. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  54.             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
  55.             {
  56.                png_bytep sp = row;
  57.                png_bytep dp = row;
  58.                for (i = 0; i < row_width; i++)
  59.                {
  60.                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
  61.                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
  62.                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
  63.                   if(red != green || red != blue)
  64.                   {
  65.                      rgb_error |= 1;
  66.                      *(dp++) = png_ptr->gamma_from_1[
  67.                        (rc*red+gc*green+bc*blue)>>15];
  68.                   }
  69.                   else
  70.                      *(dp++) = *(sp-1);
  71.                }
  72.             }
  73.             else
  74. #endif
  75.             {
  76.                png_bytep sp = row;
  77.                png_bytep dp = row;
  78.                for (i = 0; i < row_width; i++)
  79.                {
  80.                   png_byte red   = *(sp++);
  81.                   png_byte green = *(sp++);
  82.                   png_byte blue  = *(sp++);
  83.                   if(red != green || red != blue)
  84.                   {
  85.                      rgb_error |= 1;
  86.                      *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
  87.                   }
  88.                   else
  89.                      *(dp++) = *(sp-1);
  90.                }
  91.             }
  92.          }
  93.          else /* RGB bit_depth == 16 */
  94.          {
  95. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  96.             if (png_ptr->gamma_16_to_1 != NULL &&
  97.                 png_ptr->gamma_16_from_1 != NULL)
  98.             {
  99.                png_bytep sp = row;
  100.                png_bytep dp = row;
  101.                for (i = 0; i < row_width; i++)
  102.                {
  103.                   png_uint_16 red, green, blue, w;
  104.                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  105.                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  106.                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  107.                   if(red == green && red == blue)
  108.                      w = red;
  109.                   else
  110.                   {
  111.                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
  112.                                   png_ptr->gamma_shift][red>>8];
  113.                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
  114.                                   png_ptr->gamma_shift][green>>8];
  115.                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
  116.                                   png_ptr->gamma_shift][blue>>8];
  117.                      png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
  118.                                   + bc*blue_1)>>15);
  119.                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
  120.                          png_ptr->gamma_shift][gray16 >> 8];
  121.                      rgb_error |= 1;
  122.                   }
  123.                   *(dp++) = (png_byte)((w>>8) & 0xff);
  124.                   *(dp++) = (png_byte)(w & 0xff);
  125.                }
  126.             }
  127.             else
  128. #endif
  129.             {
  130.                png_bytep sp = row;
  131.                png_bytep dp = row;
  132.                for (i = 0; i < row_width; i++)
  133.                {
  134.                   png_uint_16 red, green, blue, gray16;
  135.                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  136.                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  137.                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  138.                   if(red != green || red != blue)
  139.                      rgb_error |= 1;
  140.                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
  141.                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
  142.                   *(dp++) = (png_byte)(gray16 & 0xff);
  143.                }
  144.             }
  145.          }
  146.       }
  147.       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  148.       {
  149.          if (row_info->bit_depth == 8)
  150.          {
  151. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  152.             if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
  153.             {
  154.                png_bytep sp = row;
  155.                png_bytep dp = row;
  156.                for (i = 0; i < row_width; i++)
  157.                {
  158.                   png_byte red   = png_ptr->gamma_to_1[*(sp++)];
  159.                   png_byte green = png_ptr->gamma_to_1[*(sp++)];
  160.                   png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
  161.                   if(red != green || red != blue)
  162.                      rgb_error |= 1;
  163.                   *(dp++) =  png_ptr->gamma_from_1
  164.                              [(rc*red + gc*green + bc*blue)>>15];
  165.                   *(dp++) = *(sp++);  /* alpha */
  166.                }
  167.             }
  168.             else
  169. #endif
  170.             {
  171.                png_bytep sp = row;
  172.                png_bytep dp = row;
  173.                for (i = 0; i < row_width; i++)
  174.                {
  175.                   png_byte red   = *(sp++);
  176.                   png_byte green = *(sp++);
  177.                   png_byte blue  = *(sp++);
  178.                   if(red != green || red != blue)
  179.                      rgb_error |= 1;
  180.                   *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
  181.                   *(dp++) = *(sp++);  /* alpha */
  182.                }
  183.             }
  184.          }
  185.          else /* RGBA bit_depth == 16 */
  186.          {
  187. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  188.             if (png_ptr->gamma_16_to_1 != NULL &&
  189.                 png_ptr->gamma_16_from_1 != NULL)
  190.             {
  191.                png_bytep sp = row;
  192.                png_bytep dp = row;
  193.                for (i = 0; i < row_width; i++)
  194.                {
  195.                   png_uint_16 red, green, blue, w;
  196.                   red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  197.                   green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  198.                   blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  199.                   if(red == green && red == blue)
  200.                      w = red;
  201.                   else
  202.                   {
  203.                      png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
  204.                                   png_ptr->gamma_shift][red>>8];
  205.                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
  206.                                   png_ptr->gamma_shift][green>>8];
  207.                      png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
  208.                                   png_ptr->gamma_shift][blue>>8];
  209.                      png_uint_16 gray16  = (png_uint_16)((rc * red_1
  210.                                   + gc * green_1 + bc * blue_1)>>15);
  211.                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
  212.                          png_ptr->gamma_shift][gray16 >> 8];
  213.                      rgb_error |= 1;
  214.                   }
  215.                   *(dp++) = (png_byte)((w>>8) & 0xff);
  216.                   *(dp++) = (png_byte)(w & 0xff);
  217.                   *(dp++) = *(sp++);  /* alpha */
  218.                   *(dp++) = *(sp++);
  219.                }
  220.             }
  221.             else
  222. #endif
  223.             {
  224.                png_bytep sp = row;
  225.                png_bytep dp = row;
  226.                for (i = 0; i < row_width; i++)
  227.                {
  228.                   png_uint_16 red, green, blue, gray16;
  229.                   red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  230.                   green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  231.                   blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  232.                   if(red != green || red != blue)
  233.                      rgb_error |= 1;
  234.                   gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
  235.                   *(dp++) = (png_byte)((gray16>>8) & 0xff);
  236.                   *(dp++) = (png_byte)(gray16 & 0xff);
  237.                   *(dp++) = *(sp++);  /* alpha */
  238.                   *(dp++) = *(sp++);
  239.                }
  240.             }
  241.          }
  242.       }
  243.    row_info->channels -= (png_byte)2;
  244.       row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
  245.       row_info->pixel_depth = (png_byte)(row_info->channels *
  246.          row_info->bit_depth);
  247.       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  248.    }
  249.    return rgb_error;
  250. }
  251. #endif
  252. /* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
  253.  * large of png_color.  This lets grayscale images be treated as
  254.  * paletted.  Most useful for gamma correction and simplification
  255.  * of code.
  256.  */
  257. void PNGAPI
  258. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  259. {
  260.    int num_palette;
  261.    int color_inc;
  262.    int i;
  263.    int v;
  264.    png_debug(1, "in png_do_build_grayscale_paletten");
  265.    if (palette == NULL)
  266.       return;
  267.    switch (bit_depth)
  268.    {
  269.       case 1:
  270.          num_palette = 2;
  271.          color_inc = 0xff;
  272.          break;
  273.       case 2:
  274.          num_palette = 4;
  275.          color_inc = 0x55;
  276.          break;
  277.       case 4:
  278.          num_palette = 16;
  279.          color_inc = 0x11;
  280.          break;
  281.       case 8:
  282.          num_palette = 256;
  283.          color_inc = 1;
  284.          break;
  285.       default:
  286.          num_palette = 0;
  287.          color_inc = 0;
  288.          break;
  289.    }
  290.    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  291.    {
  292.       palette[i].red = (png_byte)v;
  293.       palette[i].green = (png_byte)v;
  294.       palette[i].blue = (png_byte)v;
  295.    }
  296. }
  297. /* This function is currently unused.  Do we really need it? */
  298. #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
  299. void /* PRIVATE */
  300. png_correct_palette(png_structp png_ptr, png_colorp palette,
  301.    int num_palette)
  302. {
  303.    png_debug(1, "in png_correct_paletten");
  304. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && 
  305.     defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  306.    if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
  307.    {
  308.       png_color back, back_1;
  309.       if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  310.       {
  311.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  312.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  313.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  314.          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  315.          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  316.          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  317.       }
  318.       else
  319.       {
  320.          double g;
  321.          g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
  322.          if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
  323.              fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
  324.          {
  325.             back.red = png_ptr->background.red;
  326.             back.green = png_ptr->background.green;
  327.             back.blue = png_ptr->background.blue;
  328.          }
  329.          else
  330.          {
  331.             back.red =
  332.                (png_byte)(pow((double)png_ptr->background.red/255, g) *
  333.                 255.0 + 0.5);
  334.             back.green =
  335.                (png_byte)(pow((double)png_ptr->background.green/255, g) *
  336.                 255.0 + 0.5);
  337.             back.blue =
  338.                (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  339.                 255.0 + 0.5);
  340.          }
  341.          g = 1.0 / png_ptr->background_gamma;
  342.          back_1.red =
  343.             (png_byte)(pow((double)png_ptr->background.red/255, g) *
  344.              255.0 + 0.5);
  345.          back_1.green =
  346.             (png_byte)(pow((double)png_ptr->background.green/255, g) *
  347.              255.0 + 0.5);
  348.          back_1.blue =
  349.             (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  350.              255.0 + 0.5);
  351.       }
  352.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  353.       {
  354.          png_uint_32 i;
  355.          for (i = 0; i < (png_uint_32)num_palette; i++)
  356.          {
  357.             if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
  358.             {
  359.                palette[i] = back;
  360.             }
  361.             else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  362.             {
  363.                png_byte v, w;
  364.                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  365.                png_composite(w, v, png_ptr->trans[i], back_1.red);
  366.                palette[i].red = png_ptr->gamma_from_1[w];
  367.                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  368.                png_composite(w, v, png_ptr->trans[i], back_1.green);
  369.                palette[i].green = png_ptr->gamma_from_1[w];
  370.                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  371.                png_composite(w, v, png_ptr->trans[i], back_1.blue);
  372.                palette[i].blue = png_ptr->gamma_from_1[w];
  373.             }
  374.             else
  375.             {
  376.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  377.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  378.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  379.             }
  380.          }
  381.       }
  382.       else
  383.       {
  384.          int i;
  385.          for (i = 0; i < num_palette; i++)
  386.          {
  387.             if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
  388.             {
  389.                palette[i] = back;
  390.             }
  391.             else
  392.             {
  393.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  394.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  395.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  396.             }
  397.          }
  398.       }
  399.    }
  400.    else
  401. #endif
  402. #if defined(PNG_READ_GAMMA_SUPPORTED)
  403.    if (png_ptr->transformations & PNG_GAMMA)
  404.    {
  405.       int i;
  406.       for (i = 0; i < num_palette; i++)
  407.       {
  408.          palette[i].red = png_ptr->gamma_table[palette[i].red];
  409.          palette[i].green = png_ptr->gamma_table[palette[i].green];
  410.          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  411.       }
  412.    }
  413. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  414.    else
  415. #endif
  416. #endif
  417. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  418.    if (png_ptr->transformations & PNG_BACKGROUND)
  419.    {
  420.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  421.       {
  422.          png_color back;
  423.          back.red   = (png_byte)png_ptr->background.red;
  424.          back.green = (png_byte)png_ptr->background.green;
  425.          back.blue  = (png_byte)png_ptr->background.blue;
  426.          for (i = 0; i < (int)png_ptr->num_trans; i++)
  427.          {
  428.             if (png_ptr->trans[i] == 0)
  429.             {
  430.                palette[i].red = back.red;
  431.                palette[i].green = back.green;
  432.                palette[i].blue = back.blue;
  433.             }
  434.             else if (png_ptr->trans[i] != 0xff)
  435.             {
  436.                png_composite(palette[i].red, png_ptr->palette[i].red,
  437.                   png_ptr->trans[i], back.red);
  438.                png_composite(palette[i].green, png_ptr->palette[i].green,
  439.                   png_ptr->trans[i], back.green);
  440.                png_composite(palette[i].blue, png_ptr->palette[i].blue,
  441.                   png_ptr->trans[i], back.blue);
  442.             }
  443.          }
  444.       }
  445.       else /* assume grayscale palette (what else could it be?) */
  446.       {
  447.          int i;
  448.          for (i = 0; i < num_palette; i++)
  449.          {
  450.             if (i == (png_byte)png_ptr->trans_values.gray)
  451.             {
  452.                palette[i].red = (png_byte)png_ptr->background.red;
  453.                palette[i].green = (png_byte)png_ptr->background.green;
  454.                palette[i].blue = (png_byte)png_ptr->background.blue;
  455.             }
  456.          }
  457.       }
  458.    }
  459. #endif
  460. }
  461. #endif
  462. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  463. /* Replace any alpha or transparency with the supplied background color.
  464.  * "background" is already in the screen gamma, while "background_1" is
  465.  * at a gamma of 1.0.  Paletted files have already been taken care of.
  466.  */
  467. void /* PRIVATE */
  468. png_do_background(png_row_infop row_info, png_bytep row,
  469.    png_color_16p trans_values, png_color_16p background
  470. #if defined(PNG_READ_GAMMA_SUPPORTED)
  471.    , png_color_16p background_1,
  472.    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  473.    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  474.    png_uint_16pp gamma_16_to_1, int gamma_shift
  475. #endif
  476.    )
  477. {
  478.    png_bytep sp, dp;
  479.    png_uint_32 i;
  480.    png_uint_32 row_width=row_info->width;
  481.    int shift;
  482.    png_debug(1, "in png_do_backgroundn");
  483.    if (background != NULL &&
  484. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  485.        row != NULL && row_info != NULL &&
  486. #endif
  487.       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  488.       (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
  489.    {
  490.       switch (row_info->color_type)
  491.       {
  492.          case PNG_COLOR_TYPE_GRAY:
  493.          {
  494.             switch (row_info->bit_depth)
  495.             {
  496.                case 1:
  497.                {
  498.                   sp = row;
  499.                   shift = 7;
  500.                   for (i = 0; i < row_width; i++)
  501.                   {
  502.                      if ((png_uint_16)((*sp >> shift) & 0x01)
  503.                         == trans_values->gray)
  504.                      {
  505.                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  506.                         *sp |= (png_byte)(background->gray << shift);
  507.                      }
  508.                      if (!shift)
  509.                      {
  510.                         shift = 7;
  511.                         sp++;
  512.                      }
  513.                      else
  514.                         shift--;
  515.                   }
  516.                   break;
  517.                }
  518.                case 2:
  519.                {
  520. #if defined(PNG_READ_GAMMA_SUPPORTED)
  521.                   if (gamma_table != NULL)
  522.                   {
  523.                      sp = row;
  524.                      shift = 6;
  525.                      for (i = 0; i < row_width; i++)
  526.                      {
  527.                         if ((png_uint_16)((*sp >> shift) & 0x03)
  528.                             == trans_values->gray)
  529.                         {
  530.                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  531.                            *sp |= (png_byte)(background->gray << shift);
  532.                         }
  533.                         else
  534.                         {
  535.                            png_byte p = (png_byte)((*sp >> shift) & 0x03);
  536.                            png_byte g = (png_byte)((gamma_table [p | (p << 2) |
  537.                                (p << 4) | (p << 6)] >> 6) & 0x03);
  538.                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  539.                            *sp |= (png_byte)(g << shift);
  540.                         }
  541.                         if (!shift)
  542.                         {
  543.                            shift = 6;
  544.                            sp++;
  545.                         }
  546.                         else
  547.                            shift -= 2;
  548.                      }
  549.                   }
  550.                   else
  551. #endif
  552.                   {
  553.                      sp = row;
  554.                      shift = 6;
  555.                      for (i = 0; i < row_width; i++)
  556.                      {
  557.                         if ((png_uint_16)((*sp >> shift) & 0x03)
  558.                             == trans_values->gray)
  559.                         {
  560.                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  561.                            *sp |= (png_byte)(background->gray << shift);
  562.                         }
  563.                         if (!shift)
  564.                         {
  565.                            shift = 6;
  566.                            sp++;
  567.                         }
  568.                         else
  569.                            shift -= 2;
  570.                      }
  571.                   }
  572.                   break;
  573.                }
  574.                case 4:
  575.                {
  576. #if defined(PNG_READ_GAMMA_SUPPORTED)
  577.                   if (gamma_table != NULL)
  578.                   {
  579.                      sp = row;
  580.                      shift = 4;
  581.                      for (i = 0; i < row_width; i++)
  582.                      {
  583.                         if ((png_uint_16)((*sp >> shift) & 0x0f)
  584.                             == trans_values->gray)
  585.                         {
  586.                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  587.                            *sp |= (png_byte)(background->gray << shift);
  588.                         }
  589.                         else
  590.                         {
  591.                            png_byte p = (png_byte)((*sp >> shift) & 0x0f);
  592.                            png_byte g = (png_byte)((gamma_table[p |
  593.                              (p << 4)] >> 4) & 0x0f);
  594.                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  595.                            *sp |= (png_byte)(g << shift);
  596.                         }
  597.                         if (!shift)
  598.                         {
  599.                            shift = 4;
  600.                            sp++;
  601.                         }
  602.                         else
  603.                            shift -= 4;
  604.                      }
  605.                   }
  606.                   else
  607. #endif
  608.                   {
  609.                      sp = row;
  610.                      shift = 4;
  611.                      for (i = 0; i < row_width; i++)
  612.                      {
  613.                         if ((png_uint_16)((*sp >> shift) & 0x0f)
  614.                             == trans_values->gray)
  615.                         {
  616.                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  617.                            *sp |= (png_byte)(background->gray << shift);
  618.                         }
  619.                         if (!shift)
  620.                         {
  621.                            shift = 4;
  622.                            sp++;
  623.                         }
  624.                         else
  625.                            shift -= 4;
  626.                      }
  627.                   }
  628.                   break;
  629.                }
  630.                case 8:
  631.                {
  632. #if defined(PNG_READ_GAMMA_SUPPORTED)
  633.                   if (gamma_table != NULL)
  634.                   {
  635.                      sp = row;
  636.                      for (i = 0; i < row_width; i++, sp++)
  637.                      {
  638.                         if (*sp == trans_values->gray)
  639.                         {
  640.                            *sp = (png_byte)background->gray;
  641.                         }
  642.                         else
  643.                         {
  644.                            *sp = gamma_table[*sp];
  645.                         }
  646.                      }
  647.                   }
  648.                   else
  649. #endif
  650.                   {
  651.                      sp = row;
  652.                      for (i = 0; i < row_width; i++, sp++)
  653.                      {
  654.                         if (*sp == trans_values->gray)
  655.                         {
  656.                            *sp = (png_byte)background->gray;
  657.                         }
  658.                      }
  659.                   }
  660.                   break;
  661.                }
  662.                case 16:
  663.                {
  664. #if defined(PNG_READ_GAMMA_SUPPORTED)
  665.                   if (gamma_16 != NULL)
  666.                   {
  667.                      sp = row;
  668.                      for (i = 0; i < row_width; i++, sp += 2)
  669.                      {
  670.                         png_uint_16 v;
  671.                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  672.                         if (v == trans_values->gray)
  673.                         {
  674.                            /* background is already in screen gamma */
  675.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  676.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  677.                         }
  678.                         else
  679.                         {
  680.                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  681.                            *sp = (png_byte)((v >> 8) & 0xff);
  682.                            *(sp + 1) = (png_byte)(v & 0xff);
  683.                         }
  684.                      }
  685.                   }
  686.                   else
  687. #endif
  688.                   {
  689.                      sp = row;
  690.                      for (i = 0; i < row_width; i++, sp += 2)
  691.                      {
  692.                         png_uint_16 v;
  693.                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  694.                         if (v == trans_values->gray)
  695.                         {
  696.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  697.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  698.                         }
  699.                      }
  700.                   }
  701.                   break;
  702.                }
  703.             }
  704.             break;
  705.          }
  706.          case PNG_COLOR_TYPE_RGB:
  707.          {
  708.             if (row_info->bit_depth == 8)
  709.             {
  710. #if defined(PNG_READ_GAMMA_SUPPORTED)
  711.                if (gamma_table != NULL)
  712.                {
  713.                   sp = row;
  714.                   for (i = 0; i < row_width; i++, sp += 3)
  715.                   {
  716.                      if (*sp == trans_values->red &&
  717.                         *(sp + 1) == trans_values->green &&
  718.                         *(sp + 2) == trans_values->blue)
  719.                      {
  720.                         *sp = (png_byte)background->red;
  721.                         *(sp + 1) = (png_byte)background->green;
  722.                         *(sp + 2) = (png_byte)background->blue;
  723.                      }
  724.                      else
  725.                      {
  726.                         *sp = gamma_table[*sp];
  727.                         *(sp + 1) = gamma_table[*(sp + 1)];
  728.                         *(sp + 2) = gamma_table[*(sp + 2)];
  729.                      }
  730.                   }
  731.                }
  732.                else
  733. #endif
  734.                {
  735.                   sp = row;
  736.                   for (i = 0; i < row_width; i++, sp += 3)
  737.                   {
  738.                      if (*sp == trans_values->red &&
  739.                         *(sp + 1) == trans_values->green &&
  740.                         *(sp + 2) == trans_values->blue)
  741.                      {
  742.                         *sp = (png_byte)background->red;
  743.                         *(sp + 1) = (png_byte)background->green;
  744.                         *(sp + 2) = (png_byte)background->blue;
  745.                      }
  746.                   }
  747.                }
  748.             }
  749.             else /* if (row_info->bit_depth == 16) */
  750.             {
  751. #if defined(PNG_READ_GAMMA_SUPPORTED)
  752.                if (gamma_16 != NULL)
  753.                {
  754.                   sp = row;
  755.                   for (i = 0; i < row_width; i++, sp += 6)
  756.                   {
  757.                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  758.                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  759.                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
  760.                      if (r == trans_values->red && g == trans_values->green &&
  761.                         b == trans_values->blue)
  762.                      {
  763.                         /* background is already in screen gamma */
  764.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  765.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  766.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  767.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  768.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  769.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  770.                      }
  771.                      else
  772.                      {
  773.                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  774.                         *sp = (png_byte)((v >> 8) & 0xff);
  775.                         *(sp + 1) = (png_byte)(v & 0xff);
  776.                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  777.                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  778.                         *(sp + 3) = (png_byte)(v & 0xff);
  779.                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  780.                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  781.                         *(sp + 5) = (png_byte)(v & 0xff);
  782.                      }
  783.                   }
  784.                }
  785.                else
  786. #endif
  787.                {
  788.                   sp = row;
  789.                   for (i = 0; i < row_width; i++, sp += 6)
  790.                   {
  791.                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
  792.                      png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  793.                      png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
  794.                      if (r == trans_values->red && g == trans_values->green &&
  795.                         b == trans_values->blue)
  796.                      {
  797.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  798.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  799.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  800.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  801.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  802.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  803.                      }
  804.                   }
  805.                }
  806.             }
  807.             break;
  808.          }
  809.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  810.          {
  811.             if (row_info->bit_depth == 8)
  812.             {
  813. #if defined(PNG_READ_GAMMA_SUPPORTED)
  814.                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  815.                    gamma_table != NULL)
  816.                {
  817.                   sp = row;
  818.                   dp = row;
  819.                   for (i = 0; i < row_width; i++, sp += 2, dp++)
  820.                   {
  821.                      png_uint_16 a = *(sp + 1);
  822.                      if (a == 0xff)
  823.                      {
  824.                         *dp = gamma_table[*sp];
  825.                      }
  826.                      else if (a == 0)
  827.                      {
  828.                         /* background is already in screen gamma */
  829.                         *dp = (png_byte)background->gray;
  830.                      }
  831.                      else
  832.                      {
  833.                         png_byte v, w;
  834.                         v = gamma_to_1[*sp];
  835.                         png_composite(w, v, a, background_1->gray);
  836.                         *dp = gamma_from_1[w];
  837.                      }
  838.                   }
  839.                }
  840.                else
  841. #endif
  842.                {
  843.                   sp = row;
  844.                   dp = row;
  845.                   for (i = 0; i < row_width; i++, sp += 2, dp++)
  846.                   {
  847.                      png_byte a = *(sp + 1);
  848.                      if (a == 0xff)
  849.                      {
  850.                         *dp = *sp;
  851.                      }
  852. #if defined(PNG_READ_GAMMA_SUPPORTED)
  853.                      else if (a == 0)
  854.                      {
  855.                         *dp = (png_byte)background->gray;
  856.                      }
  857.                      else
  858.                      {
  859.                         png_composite(*dp, *sp, a, background_1->gray);
  860.                      }
  861. #else
  862.                      *dp = (png_byte)background->gray;
  863. #endif
  864.                   }
  865.                }
  866.             }
  867.             else /* if (png_ptr->bit_depth == 16) */
  868.             {
  869. #if defined(PNG_READ_GAMMA_SUPPORTED)
  870.                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  871.                    gamma_16_to_1 != NULL)
  872.                {
  873.                   sp = row;
  874.                   dp = row;
  875.                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
  876.                   {
  877.                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  878.                      if (a == (png_uint_16)0xffff)
  879.                      {
  880.                         png_uint_16 v;
  881.                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  882.                         *dp = (png_byte)((v >> 8) & 0xff);
  883.                         *(dp + 1) = (png_byte)(v & 0xff);
  884.                      }
  885. #if defined(PNG_READ_GAMMA_SUPPORTED)
  886.                      else if (a == 0)
  887. #else
  888.                      else
  889. #endif
  890.                      {
  891.                         /* background is already in screen gamma */
  892.                         *dp = (png_byte)((background->gray >> 8) & 0xff);
  893.                         *(dp + 1) = (png_byte)(background->gray & 0xff);
  894.                      }
  895. #if defined(PNG_READ_GAMMA_SUPPORTED)
  896.                      else
  897.                      {
  898.                         png_uint_16 g, v, w;
  899.                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  900.                         png_composite_16(v, g, a, background_1->gray);
  901.                         w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
  902.                         *dp = (png_byte)((w >> 8) & 0xff);
  903.                         *(dp + 1) = (png_byte)(w & 0xff);
  904.                      }
  905. #endif
  906.                   }
  907.                }
  908.                else
  909. #endif
  910.                {
  911.                   sp = row;
  912.                   dp = row;
  913.                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
  914.                   {
  915.                      png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  916.                      if (a == (png_uint_16)0xffff)
  917.                      {
  918.                         png_memcpy(dp, sp, 2);
  919.                      }
  920. #if defined(PNG_READ_GAMMA_SUPPORTED)
  921.                      else if (a == 0)
  922. #else
  923.                      else
  924. #endif
  925.                      {
  926.                         *dp = (png_byte)((background->gray >> 8) & 0xff);
  927.                         *(dp + 1) = (png_byte)(background->gray & 0xff);
  928.                      }
  929. #if defined(PNG_READ_GAMMA_SUPPORTED)
  930.                      else
  931.                      {
  932.                         png_uint_16 g, v;
  933.                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  934.                         png_composite_16(v, g, a, background_1->gray);
  935.                         *dp = (png_byte)((v >> 8) & 0xff);
  936.                         *(dp + 1) = (png_byte)(v & 0xff);
  937.                      }
  938. #endif
  939.                   }
  940.                }
  941.             }
  942.             break;
  943.          }
  944.          case PNG_COLOR_TYPE_RGB_ALPHA:
  945.          {
  946.             if (row_info->bit_depth == 8)
  947.             {
  948. #if defined(PNG_READ_GAMMA_SUPPORTED)
  949.                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  950.                    gamma_table != NULL)
  951.                {
  952.                   sp = row;
  953.                   dp = row;
  954.                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
  955.                   {
  956.                      png_byte a = *(sp + 3);
  957.                      if (a == 0xff)
  958.                      {
  959.                         *dp = gamma_table[*sp];
  960.                         *(dp + 1) = gamma_table[*(sp + 1)];
  961.                         *(dp + 2) = gamma_table[*(sp + 2)];
  962.                      }
  963.                      else if (a == 0)
  964.                      {
  965.                         /* background is already in screen gamma */
  966.                         *dp = (png_byte)background->red;
  967.                         *(dp + 1) = (png_byte)background->green;
  968.                         *(dp + 2) = (png_byte)background->blue;
  969.                      }
  970.                      else
  971.                      {
  972.                         png_byte v, w;
  973.                         v = gamma_to_1[*sp];
  974.                         png_composite(w, v, a, background_1->red);
  975.                         *dp = gamma_from_1[w];
  976.                         v = gamma_to_1[*(sp + 1)];
  977.                         png_composite(w, v, a, background_1->green);
  978.                         *(dp + 1) = gamma_from_1[w];
  979.                         v = gamma_to_1[*(sp + 2)];
  980.                         png_composite(w, v, a, background_1->blue);
  981.                         *(dp + 2) = gamma_from_1[w];
  982.                      }
  983.                   }
  984.                }
  985.                else
  986. #endif
  987.                {
  988.                   sp = row;
  989.                   dp = row;
  990.                   for (i = 0; i < row_width; i++, sp += 4, dp += 3)
  991.                   {
  992.                      png_byte a = *(sp + 3);
  993.                      if (a == 0xff)
  994.                      {
  995.                         *dp = *sp;
  996.                         *(dp + 1) = *(sp + 1);
  997.                         *(dp + 2) = *(sp + 2);
  998.                      }
  999.                      else if (a == 0)
  1000.                      {
  1001.                         *dp = (png_byte)background->red;
  1002.                         *(dp + 1) = (png_byte)background->green;
  1003.                         *(dp + 2) = (png_byte)background->blue;
  1004.                      }
  1005.                      else
  1006.                      {
  1007.                         png_composite(*dp, *sp, a, background->red);
  1008.                         png_composite(*(dp + 1), *(sp + 1), a,
  1009.                            background->green);
  1010.                         png_composite(*(dp + 2), *(sp + 2), a,
  1011.                            background->blue);
  1012.                      }
  1013.                   }
  1014.                }
  1015.             }
  1016.             else /* if (row_info->bit_depth == 16) */
  1017.             {
  1018. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1019.                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  1020.                    gamma_16_to_1 != NULL)
  1021.                {
  1022.                   sp = row;
  1023.                   dp = row;
  1024.                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
  1025.                   {
  1026.                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
  1027.                          << 8) + (png_uint_16)(*(sp + 7)));
  1028.                      if (a == (png_uint_16)0xffff)
  1029.                      {
  1030.                         png_uint_16 v;
  1031.                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  1032.                         *dp = (png_byte)((v >> 8) & 0xff);
  1033.                         *(dp + 1) = (png_byte)(v & 0xff);
  1034.                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  1035.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1036.                         *(dp + 3) = (png_byte)(v & 0xff);
  1037.                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  1038.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1039.                         *(dp + 5) = (png_byte)(v & 0xff);
  1040.                      }
  1041.                      else if (a == 0)
  1042.                      {
  1043.                         /* background is already in screen gamma */
  1044.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  1045.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  1046.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1047.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  1048.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1049.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  1050.                      }
  1051.                      else
  1052.                      {
  1053.                         png_uint_16 v, w, x;
  1054.                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  1055.                         png_composite_16(w, v, a, background_1->red);
  1056.                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  1057.                         *dp = (png_byte)((x >> 8) & 0xff);
  1058.                         *(dp + 1) = (png_byte)(x & 0xff);
  1059.                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
  1060.                         png_composite_16(w, v, a, background_1->green);
  1061.                         x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  1062.                         *(dp + 2) = (png_byte)((x >> 8) & 0xff);
  1063.                         *(dp + 3) = (png_byte)(x & 0xff);
  1064.                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
  1065.                         png_composite_16(w, v, a, background_1->blue);
  1066.                         x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
  1067.                         *(dp + 4) = (png_byte)((x >> 8) & 0xff);
  1068.                         *(dp + 5) = (png_byte)(x & 0xff);
  1069.                      }
  1070.                   }
  1071.                }
  1072.                else
  1073. #endif
  1074.                {
  1075.                   sp = row;
  1076.                   dp = row;
  1077.                   for (i = 0; i < row_width; i++, sp += 8, dp += 6)
  1078.                   {
  1079.                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
  1080.                         << 8) + (png_uint_16)(*(sp + 7)));
  1081.                      if (a == (png_uint_16)0xffff)
  1082.                      {
  1083.                         png_memcpy(dp, sp, 6);
  1084.                      }
  1085.                      else if (a == 0)
  1086.                      {
  1087.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  1088.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  1089.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1090.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  1091.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1092.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  1093.                      }
  1094.                      else
  1095.                      {
  1096.                         png_uint_16 v;
  1097.                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  1098.                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
  1099.                             + *(sp + 3));
  1100.                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
  1101.                             + *(sp + 5));
  1102.                         png_composite_16(v, r, a, background->red);
  1103.                         *dp = (png_byte)((v >> 8) & 0xff);
  1104.                         *(dp + 1) = (png_byte)(v & 0xff);
  1105.                         png_composite_16(v, g, a, background->green);
  1106.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1107.                         *(dp + 3) = (png_byte)(v & 0xff);
  1108.                         png_composite_16(v, b, a, background->blue);
  1109.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1110.                         *(dp + 5) = (png_byte)(v & 0xff);
  1111.                      }
  1112.                   }
  1113.                }
  1114.             }
  1115.             break;
  1116.          }
  1117.       }
  1118.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1119.       {
  1120.          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1121.          row_info->channels--;
  1122.          row_info->pixel_depth = (png_byte)(row_info->channels *
  1123.             row_info->bit_depth);
  1124.          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  1125.       }
  1126.    }
  1127. }
  1128. #endif
  1129. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1130. /* Gamma correct the image, avoiding the alpha channel.  Make sure
  1131.  * you do this after you deal with the transparency issue on grayscale
  1132.  * or RGB images. If your bit depth is 8, use gamma_table, if it
  1133.  * is 16, use gamma_16_table and gamma_shift.  Build these with
  1134.  * build_gamma_table().
  1135.  */
  1136. void /* PRIVATE */
  1137. png_do_gamma(png_row_infop row_info, png_bytep row,
  1138.    png_bytep gamma_table, png_uint_16pp gamma_16_table,
  1139.    int gamma_shift)
  1140. {
  1141.    png_bytep sp;
  1142.    png_uint_32 i;
  1143.    png_uint_32 row_width=row_info->width;
  1144.    png_debug(1, "in png_do_gamman");
  1145.    if (
  1146. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1147.        row != NULL && row_info != NULL &&
  1148. #endif
  1149.        ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
  1150.         (row_info->bit_depth == 16 && gamma_16_table != NULL)))
  1151.    {
  1152.       switch (row_info->color_type)
  1153.       {
  1154.          case PNG_COLOR_TYPE_RGB:
  1155.          {
  1156.             if (row_info->bit_depth == 8)
  1157.             {
  1158.                sp = row;
  1159.                for (i = 0; i < row_width; i++)
  1160.                {
  1161.                   *sp = gamma_table[*sp];
  1162.                   sp++;
  1163.                   *sp = gamma_table[*sp];
  1164.                   sp++;
  1165.                   *sp = gamma_table[*sp];
  1166.                   sp++;
  1167.                }
  1168.             }
  1169.             else /* if (row_info->bit_depth == 16) */
  1170.             {
  1171.                sp = row;
  1172.                for (i = 0; i < row_width; i++)
  1173.                {
  1174.                   png_uint_16 v;
  1175.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1176.                   *sp = (png_byte)((v >> 8) & 0xff);
  1177.                   *(sp + 1) = (png_byte)(v & 0xff);
  1178.                   sp += 2;
  1179.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1180.                   *sp = (png_byte)((v >> 8) & 0xff);
  1181.                   *(sp + 1) = (png_byte)(v & 0xff);
  1182.                   sp += 2;
  1183.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1184.                   *sp = (png_byte)((v >> 8) & 0xff);
  1185.                   *(sp + 1) = (png_byte)(v & 0xff);
  1186.                   sp += 2;
  1187.                }
  1188.             }
  1189.             break;
  1190.          }
  1191.          case PNG_COLOR_TYPE_RGB_ALPHA:
  1192.          {
  1193.             if (row_info->bit_depth == 8)
  1194.             {
  1195.                sp = row;
  1196.                for (i = 0; i < row_width; i++)
  1197.                {
  1198.                   *sp = gamma_table[*sp];
  1199.                   sp++;
  1200.                   *sp = gamma_table[*sp];
  1201.                   sp++;
  1202.                   *sp = gamma_table[*sp];
  1203.                   sp++;
  1204.                   sp++;
  1205.                }
  1206.             }
  1207.             else /* if (row_info->bit_depth == 16) */
  1208.             {
  1209.                sp = row;
  1210.                for (i = 0; i < row_width; i++)
  1211.                {
  1212.                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1213.                   *sp = (png_byte)((v >> 8) & 0xff);
  1214.                   *(sp + 1) = (png_byte)(v & 0xff);
  1215.                   sp += 2;
  1216.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1217.                   *sp = (png_byte)((v >> 8) & 0xff);
  1218.                   *(sp + 1) = (png_byte)(v & 0xff);
  1219.                   sp += 2;
  1220.                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1221.                   *sp = (png_byte)((v >> 8) & 0xff);
  1222.                   *(sp + 1) = (png_byte)(v & 0xff);
  1223.                   sp += 4;
  1224.                }
  1225.             }
  1226.             break;
  1227.          }
  1228.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  1229.          {
  1230.             if (row_info->bit_depth == 8)
  1231.             {
  1232.                sp = row;
  1233.                for (i = 0; i < row_width; i++)
  1234.                {
  1235.                   *sp = gamma_table[*sp];
  1236.                   sp += 2;
  1237.                }
  1238.             }
  1239.             else /* if (row_info->bit_depth == 16) */
  1240.             {
  1241.                sp = row;
  1242.                for (i = 0; i < row_width; i++)
  1243.                {
  1244.                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1245.                   *sp = (png_byte)((v >> 8) & 0xff);
  1246.                   *(sp + 1) = (png_byte)(v & 0xff);
  1247.                   sp += 4;
  1248.                }
  1249.             }
  1250.             break;
  1251.          }
  1252.          case PNG_COLOR_TYPE_GRAY:
  1253.          {
  1254.             if (row_info->bit_depth == 2)
  1255.             {
  1256.                sp = row;
  1257.                for (i = 0; i < row_width; i += 4)
  1258.                {
  1259.                   int a = *sp & 0xc0;
  1260.                   int b = *sp & 0x30;
  1261.                   int c = *sp & 0x0c;
  1262.                   int d = *sp & 0x03;
  1263.                   *sp = (png_byte)(
  1264.                         ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
  1265.                         ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
  1266.                         ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
  1267.                         ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
  1268.                   sp++;
  1269.                }
  1270.             }
  1271.             if (row_info->bit_depth == 4)
  1272.             {
  1273.                sp = row;
  1274.                for (i = 0; i < row_width; i += 2)
  1275.                {
  1276.                   int msb = *sp & 0xf0;
  1277.                   int lsb = *sp & 0x0f;
  1278.                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
  1279.                           | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
  1280.                   sp++;
  1281.                }
  1282.             }
  1283.             else if (row_info->bit_depth == 8)
  1284.             {
  1285.                sp = row;
  1286.                for (i = 0; i < row_width; i++)
  1287.                {
  1288.                   *sp = gamma_table[*sp];
  1289.                   sp++;
  1290.                }
  1291.             }
  1292.             else if (row_info->bit_depth == 16)
  1293.             {
  1294.                sp = row;
  1295.                for (i = 0; i < row_width; i++)
  1296.                {
  1297.                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  1298.                   *sp = (png_byte)((v >> 8) & 0xff);
  1299.                   *(sp + 1) = (png_byte)(v & 0xff);
  1300.                   sp += 2;
  1301.                }
  1302.             }
  1303.             break;
  1304.          }
  1305.       }
  1306.    }
  1307. }
  1308. #endif
  1309. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1310. /* Expands a palette row to an RGB or RGBA row depending
  1311.  * upon whether you supply trans and num_trans.
  1312.  */
  1313. void /* PRIVATE */
  1314. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  1315.    png_colorp palette, png_bytep trans, int num_trans)
  1316. {
  1317.    int shift, value;
  1318.    png_bytep sp, dp;
  1319.    png_uint_32 i;
  1320.    png_uint_32 row_width=row_info->width;
  1321.    png_debug(1, "in png_do_expand_paletten");
  1322.    if (
  1323. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1324.        row != NULL && row_info != NULL &&
  1325. #endif
  1326.        row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  1327.    {
  1328.       if (row_info->bit_depth < 8)
  1329.       {
  1330.          switch (row_info->bit_depth)
  1331.          {
  1332.             case 1:
  1333.             {
  1334.                sp = row + (png_size_t)((row_width - 1) >> 3);
  1335.                dp = row + (png_size_t)row_width - 1;
  1336.                shift = 7 - (int)((row_width + 7) & 0x07);
  1337.                for (i = 0; i < row_width; i++)
  1338.                {
  1339.                   if ((*sp >> shift) & 0x01)
  1340.                      *dp = 1;
  1341.                   else
  1342.                      *dp = 0;
  1343.                   if (shift == 7)
  1344.                   {
  1345.                      shift = 0;
  1346.                      sp--;
  1347.                   }
  1348.                   else
  1349.                      shift++;
  1350.                   dp--;
  1351.                }
  1352.                break;
  1353.             }
  1354.             case 2:
  1355.             {
  1356.                sp = row + (png_size_t)((row_width - 1) >> 2);
  1357.                dp = row + (png_size_t)row_width - 1;
  1358.                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  1359.                for (i = 0; i < row_width; i++)
  1360.                {
  1361.                   value = (*sp >> shift) & 0x03;
  1362.                   *dp = (png_byte)value;
  1363.                   if (shift == 6)
  1364.                   {
  1365.                      shift = 0;
  1366.                      sp--;
  1367.                   }
  1368.                   else
  1369.                      shift += 2;
  1370.                   dp--;
  1371.                }
  1372.                break;
  1373.             }
  1374.             case 4:
  1375.             {
  1376.                sp = row + (png_size_t)((row_width - 1) >> 1);
  1377.                dp = row + (png_size_t)row_width - 1;
  1378.                shift = (int)((row_width & 0x01) << 2);
  1379.                for (i = 0; i < row_width; i++)
  1380.                {
  1381.                   value = (*sp >> shift) & 0x0f;
  1382.                   *dp = (png_byte)value;
  1383.                   if (shift == 4)
  1384.                   {
  1385.                      shift = 0;
  1386.                      sp--;
  1387.                   }
  1388.                   else
  1389.                      shift += 4;
  1390.                   dp--;
  1391.                }
  1392.                break;
  1393.             }
  1394.          }
  1395.          row_info->bit_depth = 8;
  1396.          row_info->pixel_depth = 8;
  1397.          row_info->rowbytes = row_width;
  1398.       }
  1399.       switch (row_info->bit_depth)
  1400.       {
  1401.          case 8:
  1402.          {
  1403.             if (trans != NULL)
  1404.             {
  1405.                sp = row + (png_size_t)row_width - 1;
  1406.                dp = row + (png_size_t)(row_width << 2) - 1;
  1407.                for (i = 0; i < row_width; i++)
  1408.                {
  1409.                   if ((int)(*sp) >= num_trans)
  1410.                      *dp-- = 0xff;
  1411.                   else
  1412.                      *dp-- = trans[*sp];
  1413.                   *dp-- = palette[*sp].blue;
  1414.                   *dp-- = palette[*sp].green;
  1415.                   *dp-- = palette[*sp].red;
  1416.                   sp--;
  1417.                }
  1418.                row_info->bit_depth = 8;
  1419.                row_info->pixel_depth = 32;
  1420.                row_info->rowbytes = row_width * 4;
  1421.                row_info->color_type = 6;
  1422.                row_info->channels = 4;
  1423.             }
  1424.             else
  1425.             {
  1426.                sp = row + (png_size_t)row_width - 1;
  1427.                dp = row + (png_size_t)(row_width * 3) - 1;
  1428.                for (i = 0; i < row_width; i++)
  1429.                {
  1430.                   *dp-- = palette[*sp].blue;
  1431.                   *dp-- = palette[*sp].green;
  1432.                   *dp-- = palette[*sp].red;
  1433.                   sp--;
  1434.                }
  1435.                row_info->bit_depth = 8;
  1436.                row_info->pixel_depth = 24;
  1437.                row_info->rowbytes = row_width * 3;
  1438.                row_info->color_type = 2;
  1439.                row_info->channels = 3;
  1440.             }
  1441.             break;
  1442.          }
  1443.       }
  1444.    }
  1445. }
  1446. /* If the bit depth < 8, it is expanded to 8.  Also, if the
  1447.  * transparency value is supplied, an alpha channel is built.
  1448.  */
  1449. void /* PRIVATE */
  1450. png_do_expand(png_row_infop row_info, png_bytep row,
  1451.    png_color_16p trans_value)
  1452. {
  1453.    int shift, value;
  1454.    png_bytep sp, dp;
  1455.    png_uint_32 i;
  1456.    png_uint_32 row_width=row_info->width;
  1457.    png_debug(1, "in png_do_expandn");
  1458. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1459.    if (row != NULL && row_info != NULL)
  1460. #endif
  1461.    {
  1462.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1463.       {
  1464.          png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
  1465.          if (row_info->bit_depth < 8)
  1466.          {
  1467.             switch (row_info->bit_depth)
  1468.             {
  1469.                case 1:
  1470.                {
  1471.                   gray = (png_uint_16)(gray*0xff);
  1472.                   sp = row + (png_size_t)((row_width - 1) >> 3);
  1473.                   dp = row + (png_size_t)row_width - 1;
  1474.                   shift = 7 - (int)((row_width + 7) & 0x07);
  1475.                   for (i = 0; i < row_width; i++)
  1476.                   {
  1477.                      if ((*sp >> shift) & 0x01)
  1478.                         *dp = 0xff;
  1479.                      else
  1480.                         *dp = 0;
  1481.                      if (shift == 7)
  1482.                      {
  1483.                         shift = 0;
  1484.                         sp--;
  1485.                      }
  1486.                      else
  1487.                         shift++;
  1488.                      dp--;
  1489.                   }
  1490.                   break;
  1491.                }
  1492.                case 2:
  1493.                {
  1494.                   gray = (png_uint_16)(gray*0x55);
  1495.                   sp = row + (png_size_t)((row_width - 1) >> 2);
  1496.                   dp = row + (png_size_t)row_width - 1;
  1497.                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  1498.                   for (i = 0; i < row_width; i++)
  1499.                   {
  1500.                      value = (*sp >> shift) & 0x03;
  1501.                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
  1502.                         (value << 6));
  1503.                      if (shift == 6)
  1504.                      {
  1505.                         shift = 0;
  1506.                         sp--;
  1507.                      }
  1508.                      else
  1509.                         shift += 2;
  1510.                      dp--;
  1511.                   }
  1512.                   break;
  1513.                }
  1514.                case 4:
  1515.                {
  1516.                   gray = (png_uint_16)(gray*0x11);
  1517.                   sp = row + (png_size_t)((row_width - 1) >> 1);
  1518.                   dp = row + (png_size_t)row_width - 1;
  1519.                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
  1520.                   for (i = 0; i < row_width; i++)
  1521.                   {
  1522.                      value = (*sp >> shift) & 0x0f;
  1523.                      *dp = (png_byte)(value | (value << 4));
  1524.                      if (shift == 4)
  1525.                      {
  1526.                         shift = 0;
  1527.                         sp--;
  1528.                      }
  1529.                      else
  1530.                         shift = 4;
  1531.                      dp--;
  1532.                   }
  1533.                   break;
  1534.                }
  1535.             }
  1536.             row_info->bit_depth = 8;
  1537.             row_info->pixel_depth = 8;
  1538.             row_info->rowbytes = row_width;
  1539.          }
  1540.          if (trans_value != NULL)
  1541.          {
  1542.             if (row_info->bit_depth == 8)
  1543.             {
  1544.                sp = row + (png_size_t)row_width - 1;
  1545.                dp = row + (png_size_t)(row_width << 1) - 1;
  1546.                for (i = 0; i < row_width; i++)
  1547.                {
  1548.                   if (*sp == gray)
  1549.                      *dp-- = 0;
  1550.                   else
  1551.                      *dp-- = 0xff;
  1552.                   *dp-- = *sp--;
  1553.                }
  1554.             }
  1555.             else if (row_info->bit_depth == 16)
  1556.             {
  1557.                sp = row + row_info->rowbytes - 1;
  1558.                dp = row + (row_info->rowbytes << 1) - 1;
  1559.                for (i = 0; i < row_width; i++)
  1560.                {
  1561.                   if (((png_uint_16)*(sp) |
  1562.                      ((png_uint_16)*(sp - 1) << 8)) == gray)
  1563.                   {
  1564.                      *dp-- = 0;
  1565.                      *dp-- = 0;
  1566.                   }
  1567.                   else
  1568.                   {
  1569.                      *dp-- = 0xff;
  1570.                      *dp-- = 0xff;
  1571.                   }
  1572.                   *dp-- = *sp--;
  1573.                   *dp-- = *sp--;
  1574.                }
  1575.             }
  1576.             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  1577.             row_info->channels = 2;
  1578.             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  1579.             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
  1580.                row_width);
  1581.          }
  1582.       }
  1583.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  1584.       {
  1585.          if (row_info->bit_depth == 8)
  1586.          {
  1587.             sp = row + (png_size_t)row_info->rowbytes - 1;
  1588.             dp = row + (png_size_t)(row_width << 2) - 1;
  1589.             for (i = 0; i < row_width; i++)
  1590.             {
  1591.                if (*(sp - 2) == trans_value->red &&
  1592.                   *(sp - 1) == trans_value->green &&
  1593.                   *(sp - 0) == trans_value->blue)
  1594.                   *dp-- = 0;
  1595.                else
  1596.                   *dp-- = 0xff;
  1597.                *dp-- = *sp--;
  1598.                *dp-- = *sp--;
  1599.                *dp-- = *sp--;
  1600.             }
  1601.          }
  1602.          else if (row_info->bit_depth == 16)
  1603.          {
  1604.             sp = row + row_info->rowbytes - 1;
  1605.             dp = row + (png_size_t)(row_width << 3) - 1;
  1606.             for (i = 0; i < row_width; i++)
  1607.             {
  1608.                if ((((png_uint_16)*(sp - 4) |
  1609.                   ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
  1610.                   (((png_uint_16)*(sp - 2) |
  1611.                   ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
  1612.                   (((png_uint_16)*(sp - 0) |
  1613.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
  1614.                {
  1615.                   *dp-- = 0;
  1616.                   *dp-- = 0;
  1617.                }
  1618.                else
  1619.                {
  1620.                   *dp-- = 0xff;
  1621.                   *dp-- = 0xff;
  1622.                }
  1623.                *dp-- = *sp--;
  1624.                *dp-- = *sp--;
  1625.                *dp-- = *sp--;
  1626.                *dp-- = *sp--;
  1627.                *dp-- = *sp--;
  1628.                *dp-- = *sp--;
  1629.             }
  1630.          }
  1631.          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  1632.          row_info->channels = 4;
  1633.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  1634.          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  1635.       }
  1636.    }
  1637. }
  1638. #endif
  1639. #if defined(PNG_READ_DITHER_SUPPORTED)
  1640. void /* PRIVATE */
  1641. png_do_dither(png_row_infop row_info, png_bytep row,
  1642.     png_bytep palette_lookup, png_bytep dither_lookup)
  1643. {
  1644.    png_bytep sp, dp;
  1645.    png_uint_32 i;
  1646.    png_uint_32 row_width=row_info->width;
  1647.    png_debug(1, "in png_do_dithern");
  1648. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1649.    if (row != NULL && row_info != NULL)
  1650. #endif
  1651.    {
  1652.       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  1653.          palette_lookup && row_info->bit_depth == 8)
  1654.       {
  1655.          int r, g, b, p;
  1656.          sp = row;
  1657.          dp = row;
  1658.          for (i = 0; i < row_width; i++)
  1659.          {
  1660.             r = *sp++;
  1661.             g = *sp++;
  1662.             b = *sp++;
  1663.             /* this looks real messy, but the compiler will reduce
  1664.                it down to a reasonable formula.  For example, with
  1665.                5 bits per color, we get:
  1666.                p = (((r >> 3) & 0x1f) << 10) |
  1667.                   (((g >> 3) & 0x1f) << 5) |
  1668.                   ((b >> 3) & 0x1f);
  1669.                */
  1670.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  1671.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  1672.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  1673.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  1674.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  1675.                (PNG_DITHER_BLUE_BITS)) |
  1676.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  1677.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  1678.             *dp++ = palette_lookup[p];
  1679.          }
  1680.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  1681.          row_info->channels = 1;
  1682.          row_info->pixel_depth = row_info->bit_depth;
  1683.          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  1684.       }
  1685.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  1686.          palette_lookup != NULL && row_info->bit_depth == 8)
  1687.       {
  1688.          int r, g, b, p;
  1689.          sp = row;
  1690.          dp = row;
  1691.          for (i = 0; i < row_width; i++)
  1692.          {
  1693.             r = *sp++;
  1694.             g = *sp++;
  1695.             b = *sp++;
  1696.             sp++;
  1697.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  1698.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  1699.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  1700.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  1701.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  1702.                (PNG_DITHER_BLUE_BITS)) |
  1703.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  1704.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  1705.             *dp++ = palette_lookup[p];
  1706.          }
  1707.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  1708.          row_info->channels = 1;
  1709.          row_info->pixel_depth = row_info->bit_depth;
  1710.          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  1711.       }
  1712.       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  1713.          dither_lookup && row_info->bit_depth == 8)
  1714.       {
  1715.          sp = row;
  1716.          for (i = 0; i < row_width; i++, sp++)
  1717.          {
  1718.             *sp = dither_lookup[*sp];
  1719.          }
  1720.       }
  1721.    }
  1722. }
  1723. #endif
  1724. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1725. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1726. static int png_gamma_shift[] =
  1727.    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
  1728. /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
  1729.  * tables, we don't make a full table if we are reducing to 8-bit in
  1730.  * the future.  Note also how the gamma_16 tables are segmented so that
  1731.  * we don't need to allocate > 64K chunks for a full 16-bit table.
  1732.  */
  1733. void /* PRIVATE */
  1734. png_build_gamma_table(png_structp png_ptr)
  1735. {
  1736.   png_debug(1, "in png_build_gamma_tablen");
  1737.   if(png_ptr->gamma != 0.0)
  1738.   {
  1739.    if (png_ptr->bit_depth <= 8)
  1740.    {
  1741.       int i;
  1742.       double g;
  1743.       if (png_ptr->screen_gamma > .000001)
  1744.          g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  1745.       else
  1746.          g = 1.0;
  1747.       png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
  1748.          (png_uint_32)256);
  1749.       for (i = 0; i < 256; i++)
  1750.       {
  1751.          png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  1752.             g) * 255.0 + .5);
  1753.       }
  1754. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || 
  1755.     defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1756.       if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
  1757.       {
  1758.          g = 1.0 / (png_ptr->gamma);
  1759.          png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
  1760.             (png_uint_32)256);
  1761.          for (i = 0; i < 256; i++)
  1762.          {
  1763.             png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  1764.                g) * 255.0 + .5);
  1765.          }
  1766.          png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
  1767.             (png_uint_32)256);
  1768.          if(png_ptr->screen_gamma > 0.000001)
  1769.             g = 1.0 / png_ptr->screen_gamma;
  1770.          else
  1771.             g = png_ptr->gamma;   /* probably doing rgb_to_gray */
  1772.          for (i = 0; i < 256; i++)
  1773.          {
  1774.             png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  1775.                g) * 255.0 + .5);
  1776.          }
  1777.       }
  1778. #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
  1779.    }
  1780.    else
  1781.    {
  1782.       double g;
  1783.       int i, j, shift, num;
  1784.       int sig_bit;
  1785.       png_uint_32 ig;
  1786.       if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1787.       {
  1788.          sig_bit = (int)png_ptr->sig_bit.red;
  1789.          if ((int)png_ptr->sig_bit.green > sig_bit)
  1790.             sig_bit = png_ptr->sig_bit.green;
  1791.          if ((int)png_ptr->sig_bit.blue > sig_bit)
  1792.             sig_bit = png_ptr->sig_bit.blue;
  1793.       }
  1794.       else
  1795.       {
  1796.          sig_bit = (int)png_ptr->sig_bit.gray;
  1797.       }
  1798.       if (sig_bit > 0)
  1799.          shift = 16 - sig_bit;
  1800.       else
  1801.          shift = 0;
  1802.       if (png_ptr->transformations & PNG_16_TO_8)
  1803.       {
  1804.          if (shift < (16 - PNG_MAX_GAMMA_8))
  1805.             shift = (16 - PNG_MAX_GAMMA_8);
  1806.       }
  1807.       if (shift > 8)
  1808.          shift = 8;
  1809.       if (shift < 0)
  1810.          shift = 0;
  1811.       png_ptr->gamma_shift = (png_byte)shift;
  1812.       num = (1 << (8 - shift));
  1813.       if (png_ptr->screen_gamma > .000001)
  1814.          g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  1815.       else
  1816.          g = 1.0;
  1817.       png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
  1818.          (png_uint_32)(num * png_sizeof (png_uint_16p)));
  1819.       if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
  1820.       {
  1821.          double fin, fout;
  1822.          png_uint_32 last, max;
  1823.          for (i = 0; i < num; i++)
  1824.          {
  1825.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  1826.                (png_uint_32)(256 * png_sizeof (png_uint_16)));
  1827.          }
  1828.          g = 1.0 / g;
  1829.          last = 0;
  1830.          for (i = 0; i < 256; i++)
  1831.          {
  1832.             fout = ((double)i + 0.5) / 256.0;
  1833.             fin = pow(fout, g);
  1834.             max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  1835.             while (last <= max)
  1836.             {
  1837.                png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  1838.                   [(int)(last >> (8 - shift))] = (png_uint_16)(
  1839.                   (png_uint_16)i | ((png_uint_16)i << 8));
  1840.                last++;
  1841.             }
  1842.          }
  1843.          while (last < ((png_uint_32)num << 8))
  1844.          {
  1845.             png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  1846.                [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
  1847.             last++;
  1848.          }
  1849.       }
  1850.       else
  1851.       {
  1852.          for (i = 0; i < num; i++)
  1853.          {
  1854.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  1855.                (png_uint_32)(256 * png_sizeof (png_uint_16)));
  1856.             ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
  1857.             for (j = 0; j < 256; j++)
  1858.             {
  1859.                png_ptr->gamma_16_table[i][j] =
  1860.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  1861.                      65535.0, g) * 65535.0 + .5);
  1862.             }
  1863.          }
  1864.       }
  1865. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || 
  1866.     defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1867.       if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
  1868.       {
  1869.          g = 1.0 / (png_ptr->gamma);
  1870.          png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
  1871.             (png_uint_32)(num * png_sizeof (png_uint_16p )));
  1872.          for (i = 0; i < num; i++)
  1873.          {
  1874.             png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
  1875.                (png_uint_32)(256 * png_sizeof (png_uint_16)));
  1876.             ig = (((png_uint_32)i *
  1877.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  1878.             for (j = 0; j < 256; j++)
  1879.             {
  1880.                png_ptr->gamma_16_to_1[i][j] =
  1881.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  1882.                      65535.0, g) * 65535.0 + .5);
  1883.             }
  1884.          }
  1885.          if(png_ptr->screen_gamma > 0.000001)
  1886.             g = 1.0 / png_ptr->screen_gamma;
  1887.          else
  1888.             g = png_ptr->gamma;   /* probably doing rgb_to_gray */
  1889.          png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
  1890.             (png_uint_32)(num * png_sizeof (png_uint_16p)));
  1891.          for (i = 0; i < num; i++)
  1892.          {
  1893.             png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
  1894.                (png_uint_32)(256 * png_sizeof (png_uint_16)));
  1895.             ig = (((png_uint_32)i *
  1896.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  1897.             for (j = 0; j < 256; j++)
  1898.             {
  1899.                png_ptr->gamma_16_from_1[i][j] =
  1900.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  1901.                      65535.0, g) * 65535.0 + .5);
  1902.             }
  1903.          }
  1904.       }
  1905. #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
  1906.    }
  1907.  }
  1908. }
  1909. #endif
  1910. /* To do: install integer version of png_build_gamma_table here */
  1911. #endif
  1912. #if defined(PNG_MNG_FEATURES_SUPPORTED)
  1913. /* undoes intrapixel differencing  */
  1914. void /* PRIVATE */
  1915. png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
  1916. {
  1917.    png_debug(1, "in png_do_read_intrapixeln");
  1918.    if (
  1919. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1920.        row != NULL && row_info != NULL &&
  1921. #endif
  1922.        (row_info->color_type & PNG_COLOR_MASK_COLOR))
  1923.    {
  1924.       int bytes_per_pixel;
  1925.       png_uint_32 row_width = row_info->width;
  1926.       if (row_info->bit_depth == 8)
  1927.       {
  1928.          png_bytep rp;
  1929.          png_uint_32 i;
  1930.          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  1931.             bytes_per_pixel = 3;
  1932.          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1933.             bytes_per_pixel = 4;
  1934.          else
  1935.             return;
  1936.          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
  1937.          {
  1938.             *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
  1939.             *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
  1940.          }
  1941.       }
  1942.       else if (row_info->bit_depth == 16)
  1943.       {
  1944.          png_bytep rp;
  1945.          png_uint_32 i;
  1946.          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  1947.             bytes_per_pixel = 6;
  1948.          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1949.             bytes_per_pixel = 8;
  1950.          else
  1951.             return;
  1952.          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
  1953.          {
  1954.             png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
  1955.             png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
  1956.             png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
  1957.             png_uint_32 red  = (png_uint_32)((s0+s1+65536L) & 0xffffL);
  1958.             png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
  1959.             *(rp  ) = (png_byte)((red >> 8) & 0xff);
  1960.             *(rp+1) = (png_byte)(red & 0xff);
  1961.             *(rp+4) = (png_byte)((blue >> 8) & 0xff);
  1962.             *(rp+5) = (png_byte)(blue & 0xff);
  1963.          }
  1964.       }
  1965.    }
  1966. }
  1967. #endif /* PNG_MNG_FEATURES_SUPPORTED */