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

界面编程

开发平台:

Visual C++

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