pngrtran.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:141k
源码类别:

打印编程

开发平台:

Visual C++

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