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

图片显示

开发平台:

Visual C++

  1. /* pngwutil.c - utilities to write a png file
  2.    libpng 1.0 beta 3 - version 0.89
  3.    For conditions of distribution and use, see copyright notice in png.h
  4.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  5.    May 25, 1996
  6.    */
  7. #define PNG_INTERNAL
  8. #include "png.h"
  9. /* place a 32 bit number into a buffer in png byte order.  We work
  10.    with unsigned numbers for convenience, you may have to cast
  11.    signed numbers (if you use any, most png data is unsigned). */
  12. void
  13. png_save_uint_32(png_bytep buf, png_uint_32 i)
  14. {
  15.    buf[0] = (png_byte)((i >> 24) & 0xff);
  16.    buf[1] = (png_byte)((i >> 16) & 0xff);
  17.    buf[2] = (png_byte)((i >> 8) & 0xff);
  18.    buf[3] = (png_byte)(i & 0xff);
  19. }
  20. /* place a 16 bit number into a buffer in png byte order */
  21. void
  22. png_save_uint_16(png_bytep buf, png_uint_16 i)
  23. {
  24.    buf[0] = (png_byte)((i >> 8) & 0xff);
  25.    buf[1] = (png_byte)(i & 0xff);
  26. }
  27. /* write a 32 bit number */
  28. void
  29. png_write_uint_32(png_structp png_ptr, png_uint_32 i)
  30. {
  31.    png_byte buf[4];
  32.    buf[0] = (png_byte)((i >> 24) & 0xff);
  33.    buf[1] = (png_byte)((i >> 16) & 0xff);
  34.    buf[2] = (png_byte)((i >> 8) & 0xff);
  35.    buf[3] = (png_byte)(i & 0xff);
  36.    png_write_data(png_ptr, buf, 4);
  37. }
  38. /* write a 16 bit number */
  39. void
  40. png_write_uint_16(png_structp png_ptr, png_uint_16 i)
  41. {
  42.    png_byte buf[2];
  43.    buf[0] = (png_byte)((i >> 8) & 0xff);
  44.    buf[1] = (png_byte)(i & 0xff);
  45.    png_write_data(png_ptr, buf, 2);
  46. }
  47. /* Write a png chunk all at once.  The type is an array of ASCII characters
  48.    representing the chunk name.  The array must be at least 4 bytes in
  49.    length, and does not need to be null terminated.  To be safe, pass the
  50.    pre-defined chunk names here, and if you need a new one, define it
  51.    where the others are defined.  The length is the length of the data.
  52.    All the data must be present.  If that is not possible, use the
  53.    png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
  54.    functions instead.  */
  55. void
  56. png_write_chunk(png_structp png_ptr, png_bytep type,
  57.    png_bytep data, png_uint_32 length)
  58. {
  59.    /* write length */
  60.    png_write_uint_32(png_ptr, length);
  61.    /* write chunk name */
  62.    png_write_data(png_ptr, type, (png_uint_32)4);
  63.    /* reset the crc and run the chunk name over it */
  64.    png_reset_crc(png_ptr);
  65.    png_calculate_crc(png_ptr, type, (png_uint_32)4);
  66.    /* write the data and update the crc */
  67.    if (length)
  68.    {
  69.       png_calculate_crc(png_ptr, data, length);
  70.       png_write_data(png_ptr, data, length);
  71.    }
  72.    /* write the crc */
  73.    png_write_uint_32(png_ptr, ~png_ptr->crc);
  74. }
  75. /* Write the start of a png chunk.  The type is the chunk type.
  76.    The total_length is the sum of the lengths of all the data you will be
  77.    passing in png_write_chunk_data() */
  78. void
  79. png_write_chunk_start(png_structp png_ptr, png_bytep type,
  80.    png_uint_32 total_length)
  81. {
  82.    /* write the length */
  83.    png_write_uint_32(png_ptr, total_length);
  84.    /* write the chunk name */
  85.    png_write_data(png_ptr, type, (png_uint_32)4);
  86.    /* reset the crc and run it over the chunk name */
  87.    png_reset_crc(png_ptr);
  88.    png_calculate_crc(png_ptr, type, (png_uint_32)4);
  89. }
  90. /* write the data of a png chunk started with png_write_chunk_start().
  91.    Note that multiple calls to this function are allowed, and that the
  92.    sum of the lengths from these calls *must* add up to the total_length
  93.    given to png_write_chunk_start() */
  94. void
  95. png_write_chunk_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
  96. {
  97.    /* write the data, and run the crc over it */
  98.    if (length)
  99.    {
  100.       png_calculate_crc(png_ptr, data, length);
  101.       png_write_data(png_ptr, data, length);
  102.    }
  103. }
  104. /* finish a chunk started with png_write_chunk_start() */
  105. void
  106. png_write_chunk_end(png_structp png_ptr)
  107. {
  108.    /* write the crc */
  109.    png_write_uint_32(png_ptr, ~png_ptr->crc);
  110. }
  111. /* simple function to write the signature */
  112. void
  113. png_write_sig(png_structp png_ptr)
  114. {
  115.    /* write the 8 byte signature */
  116.    png_write_data(png_ptr, png_sig, (png_uint_32)8);
  117. }
  118. /* Write the IHDR chunk, and update the png_struct with the necessary
  119.    information.  Note that the rest of this code depends upon this
  120.    information being correct.  */
  121. void
  122. png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
  123.    int bit_depth, int color_type, int compression_type, int filter_type,
  124.    int interlace_type)
  125. {
  126.    png_byte buf[13]; /* buffer to store the IHDR info */
  127.    /* Check that we have valid input data from the application info */
  128.    switch (color_type)
  129.    {
  130.       case 0:
  131.          switch (bit_depth)
  132.          {
  133.             case 1:
  134.             case 2:
  135.             case 4:
  136.             case 8:
  137.             case 16: png_ptr->channels = 1; break;
  138.             default: png_error(png_ptr, "Invalid bit depth for grayscale image");
  139.          }
  140.          break;
  141.       case 2:
  142.          if (bit_depth != 8 && bit_depth != 16)
  143.             png_error(png_ptr, "Invalid bit depth for RGB image");
  144.          png_ptr->channels = 3;
  145.          break;
  146.       case 3:
  147.          switch (bit_depth)
  148.          {
  149.             case 1:
  150.             case 2:
  151.             case 4:
  152.             case 8: png_ptr->channels = 1; break;
  153.             default: png_error(png_ptr, "Invalid bit depth for paletted image");
  154.          }
  155.          break;
  156.       case 4:
  157.          if (bit_depth != 8 && bit_depth != 16)
  158.             png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
  159.          png_ptr->channels = 2;
  160.          break;
  161.       case 6:
  162.          if (bit_depth != 8 && bit_depth != 16)
  163.             png_error(png_ptr, "Invalid bit depth for RGBA image");
  164.          png_ptr->channels = 4;
  165.          break;
  166.       default:
  167.          png_error(png_ptr, "Invalid image color type specified");
  168.    }
  169.    if (compression_type != 0)
  170.    {
  171.       png_warning(png_ptr, "Invalid compression type specified");
  172.       compression_type = 0;
  173.    }
  174.    if (filter_type != 0)
  175.    {
  176.       png_warning(png_ptr, "Invalid filter type specified");
  177.       filter_type = 0;
  178.    }
  179.    if (interlace_type != 0 && interlace_type != 1)
  180.    {
  181.       png_warning(png_ptr, "Invalid interlace type specified");
  182.       interlace_type = 1;
  183.    }
  184.    /* save off the relevent information */
  185.    png_ptr->bit_depth = (png_byte)bit_depth;
  186.    png_ptr->color_type = (png_byte)color_type;
  187.    png_ptr->interlaced = (png_byte)interlace_type;
  188.    png_ptr->width = width;
  189.    png_ptr->height = height;
  190.    png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
  191.    png_ptr->rowbytes = ((width * (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
  192.    /* set the usr info, so any transformations can modify it */
  193.    png_ptr->usr_width = png_ptr->width;
  194.    png_ptr->usr_bit_depth = png_ptr->bit_depth;
  195.    png_ptr->usr_channels = png_ptr->channels;
  196.    /* pack the header information into the buffer */
  197.    png_save_uint_32(buf, width);
  198.    png_save_uint_32(buf + 4, height);
  199.    buf[8] = (png_byte)bit_depth;
  200.    buf[9] = (png_byte)color_type;
  201.    buf[10] = (png_byte)compression_type;
  202.    buf[11] = (png_byte)filter_type;
  203.    buf[12] = (png_byte)interlace_type;
  204.    /* write the chunk */
  205.    png_write_chunk(png_ptr, png_IHDR, buf, (png_uint_32)13);
  206.    /* initialize zlib with png info */
  207.    png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream));
  208.    png_ptr->zstream->zalloc = png_zalloc;
  209.    png_ptr->zstream->zfree = png_zfree;
  210.    png_ptr->zstream->opaque = (voidpf)png_ptr;
  211.    if (!(png_ptr->do_filter))
  212.    {
  213.       if (png_ptr->color_type == 3 || png_ptr->bit_depth < 8)
  214.          png_ptr->do_filter = PNG_FILTER_NONE;
  215.       else
  216.          png_ptr->do_filter = PNG_ALL_FILTERS;
  217.    }
  218.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
  219.    {
  220.       if (png_ptr->do_filter != PNG_FILTER_NONE)
  221.          png_ptr->zlib_strategy = Z_FILTERED;
  222.       else
  223.          png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
  224.    }
  225.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
  226.       png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
  227.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
  228.       png_ptr->zlib_mem_level = 8;
  229.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
  230.       png_ptr->zlib_window_bits = 15;
  231.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
  232.       png_ptr->zlib_method = 8;
  233.    deflateInit2(png_ptr->zstream, png_ptr->zlib_level,
  234.       png_ptr->zlib_method,
  235.       png_ptr->zlib_window_bits,
  236.       png_ptr->zlib_mem_level,
  237.       png_ptr->zlib_strategy);
  238.    png_ptr->zstream->next_out = png_ptr->zbuf;
  239.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  240.    png_ptr->mode = PNG_HAVE_IHDR;
  241. }
  242. /* write the palette.  We are careful not to trust png_color to be in the
  243.    correct order for PNG, so people can redefine it to any convient
  244.    structure. */
  245. void
  246. png_write_PLTE(png_structp png_ptr, png_colorp palette, int number)
  247. {
  248.    int i;
  249.    png_colorp pal_ptr;
  250.    png_byte buf[3];
  251.    if (number == 0 || number > 256)
  252.    {
  253.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  254.       {
  255.          png_error(png_ptr, "Invalid number of colors in palette");
  256.       }
  257.       else
  258.       {
  259.          png_warning(png_ptr, "Invalid number of colors in palette");
  260.          return;
  261.       }
  262.    }
  263.    png_ptr->num_palette = number;
  264.    png_write_chunk_start(png_ptr, png_PLTE, number * 3);
  265.    for (i = 0, pal_ptr = palette;
  266.       i < number;
  267.       i++, pal_ptr++)
  268.    {
  269.       buf[0] = pal_ptr->red;
  270.       buf[1] = pal_ptr->green;
  271.       buf[2] = pal_ptr->blue;
  272.       png_write_chunk_data(png_ptr, buf, (png_uint_32)3);
  273.    }
  274.    png_write_chunk_end(png_ptr);
  275.    png_ptr->mode |= PNG_HAVE_PLTE;
  276. }
  277. /* write an IDAT chunk */
  278. void
  279. png_write_IDAT(png_structp png_ptr, png_bytep data, png_uint_32 length)
  280. {
  281.    png_write_chunk(png_ptr, png_IDAT, data, length);
  282.    png_ptr->mode |= PNG_HAVE_IDAT;
  283. }
  284. /* write an IEND chunk */
  285. void
  286. png_write_IEND(png_structp png_ptr)
  287. {
  288.    png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0);
  289.    png_ptr->mode |= PNG_AFTER_IEND;
  290. }
  291. #if defined(PNG_WRITE_gAMA_SUPPORTED)
  292. /* write a gAMA chunk */
  293. void
  294. png_write_gAMA(png_structp png_ptr, double gamma)
  295. {
  296.    png_uint_32 igamma;
  297.    png_byte buf[4];
  298.    /* gamma is saved in 1/100,000ths */
  299.    igamma = (png_uint_32)(gamma * 100000.0 + 0.5);
  300.    png_save_uint_32(buf, igamma);
  301.    png_write_chunk(png_ptr, png_gAMA, buf, (png_uint_32)4);
  302. }
  303. #endif
  304. #if defined(PNG_WRITE_sBIT_SUPPORTED)
  305. /* write the sBIT chunk */
  306. void
  307. png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
  308. {
  309.    png_byte buf[4];
  310.    int size;
  311.    /* make sure we don't depend upon the order of PNG_COLOR_8 */
  312.    if (color_type & PNG_COLOR_MASK_COLOR)
  313.    {
  314.       int maxbits;
  315.       maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8:png_ptr->usr_bit_depth;
  316.       if (sbit->red == 0 || sbit->red > maxbits || 
  317.           sbit->green == 0 || sbit->green > maxbits || 
  318.           sbit->blue == 0 || sbit->blue > maxbits)
  319.       {
  320.          png_warning(png_ptr, "Invalid sBIT depth specified");
  321.          return;
  322.       }
  323.       buf[0] = sbit->red;
  324.       buf[1] = sbit->green;
  325.       buf[2] = sbit->blue;
  326.       size = 3;
  327.    }
  328.    else
  329.    {
  330.       if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
  331.       {
  332.          png_warning(png_ptr, "Invalid sBIT depth specified");
  333.          return;
  334.       }
  335.       buf[0] = sbit->gray;
  336.       size = 1;
  337.    }
  338.    if (color_type & PNG_COLOR_MASK_ALPHA)
  339.    {
  340.       if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
  341.       {
  342.          png_warning(png_ptr, "Invalid sBIT depth specified");
  343.          return;
  344.       }
  345.       buf[size++] = sbit->alpha;
  346.    }
  347.    png_write_chunk(png_ptr, png_sBIT, buf, (png_uint_32)size);
  348. }
  349. #endif
  350. #if defined(PNG_WRITE_cHRM_SUPPORTED)
  351. /* write the cHRM chunk */
  352. void
  353. png_write_cHRM ( png_structp png_ptr, double white_x, double white_y,
  354.    double red_x, double red_y, double green_x, double green_y,
  355.    double blue_x, double blue_y)
  356. {
  357.    png_uint_32 itemp;
  358.    png_byte buf[32];
  359.    /* each value is saved int 1/100,000ths */
  360.    if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
  361.        white_x + white_y > 1.0)
  362.    {
  363.       png_warning(png_ptr, "Invalid cHRM white point specified");
  364.       return;
  365.    }
  366.    itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
  367.    png_save_uint_32(buf, itemp);
  368.    itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
  369.    png_save_uint_32(buf + 4, itemp);
  370.    if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
  371.        red_x + red_y > 1.0)
  372.    {
  373.       png_warning(png_ptr, "Invalid cHRM red point specified");
  374.       return;
  375.    }
  376.    itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
  377.    png_save_uint_32(buf + 8, itemp);
  378.    itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
  379.    png_save_uint_32(buf + 12, itemp);
  380.    if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
  381.        green_x + green_y > 1.0)
  382.    {
  383.       png_warning(png_ptr, "Invalid cHRM green point specified");
  384.       return;
  385.    }
  386.    itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
  387.    png_save_uint_32(buf + 16, itemp);
  388.    itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
  389.    png_save_uint_32(buf + 20, itemp);
  390.    if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
  391.        blue_x + blue_y > 1.0)
  392.    {
  393.       png_warning(png_ptr, "Invalid cHRM blue point specified");
  394.       return;
  395.    }
  396.    itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
  397.    png_save_uint_32(buf + 24, itemp);
  398.    itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
  399.    png_save_uint_32(buf + 28, itemp);
  400.    png_write_chunk(png_ptr, png_cHRM, buf, (png_uint_32)32);
  401. }
  402. #endif
  403. #if defined(PNG_WRITE_tRNS_SUPPORTED)
  404. /* write the tRNS chunk */
  405. void
  406. png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
  407.    int num_trans, int color_type)
  408. {
  409.    png_byte buf[6];
  410.    if (color_type == PNG_COLOR_TYPE_PALETTE)
  411.    {
  412.       if (num_trans <= 0 || num_trans > png_ptr->num_palette)
  413.       {
  414.          png_warning(png_ptr,"Invalid number of transparent colors specified");
  415.          return;
  416.       }
  417.       /* write the chunk out as it is */
  418.       png_write_chunk(png_ptr, png_tRNS, trans, (png_uint_32)num_trans);
  419.    }
  420.    else if (color_type == PNG_COLOR_TYPE_GRAY)
  421.    {
  422.       /* one 16 bit value */
  423.       png_save_uint_16(buf, tran->gray);
  424.       png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)2);
  425.    }
  426.    else if (color_type == PNG_COLOR_TYPE_RGB)
  427.    {
  428.       /* three 16 bit values */
  429.       png_save_uint_16(buf, tran->red);
  430.       png_save_uint_16(buf + 2, tran->green);
  431.       png_save_uint_16(buf + 4, tran->blue);
  432.       png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)6);
  433.    }
  434.    else
  435.    {
  436.       png_warning(png_ptr, "Can't write tRNS with and alpha channel");
  437.    }
  438. }
  439. #endif
  440. #if defined(PNG_WRITE_bKGD_SUPPORTED)
  441. /* write the background chunk */
  442. void
  443. png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
  444. {
  445.    png_byte buf[6];
  446.    if (color_type == PNG_COLOR_TYPE_PALETTE)
  447.    {
  448.       if (back->index > png_ptr->num_palette)
  449.       {
  450.          png_warning(png_ptr, "Invalid background palette index");
  451.          return;
  452.       }
  453.       buf[0] = back->index;
  454.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)1);
  455.    }
  456.    else if (color_type & PNG_COLOR_MASK_COLOR)
  457.    {
  458.       png_save_uint_16(buf, back->red);
  459.       png_save_uint_16(buf + 2, back->green);
  460.       png_save_uint_16(buf + 4, back->blue);
  461.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
  462.    }
  463.    else
  464.    {
  465.       png_save_uint_16(buf, back->gray);
  466.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
  467.    }
  468. }
  469. #endif
  470. #if defined(PNG_WRITE_hIST_SUPPORTED)
  471. /* write the histogram */
  472. void
  473. png_write_hIST(png_structp png_ptr, png_uint_16p hist, int number)
  474. {
  475.    int i;
  476.    png_byte buf[3];
  477.    if (number <= 0 || number > png_ptr->num_palette)
  478.    {
  479.       png_warning(png_ptr, "Invalid number of histogram entries specified");
  480.       return;
  481.    }
  482.    png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
  483.    for (i = 0; i < number; i++)
  484.    {
  485.       png_save_uint_16(buf, hist[i]);
  486.       png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
  487.    }
  488.    png_write_chunk_end(png_ptr);
  489. }
  490. #endif
  491. #if defined(PNG_WRITE_tEXt_SUPPORTED)
  492. /* write a tEXt chunk */
  493. void
  494. png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
  495.    png_uint_32 text_len)
  496. {
  497.    int key_len;
  498.    key_len = png_strlen(key);
  499.    if (key_len == 0)
  500.    {
  501.       png_warning(png_ptr, "Invalid text keyword length");
  502.       return;
  503.    }
  504.    else if (key_len > 80)
  505.    {
  506.       png_warning(png_ptr, "Text keyword length restricted to 80 charactersn");
  507.       key[80] = '';
  508.       key_len = 80;
  509.    }
  510.    /* make sure we count the 0 after the key */
  511.    png_write_chunk_start(png_ptr, png_tEXt,
  512.       (png_uint_32)(key_len + text_len + 1));
  513.    /* key has an 0 at the end.  How nice */
  514.    png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
  515.    if (text && text_len)
  516.       png_write_chunk_data(png_ptr, (png_bytep )text, (png_uint_32)text_len);
  517.    png_write_chunk_end(png_ptr);
  518. }
  519. #endif
  520. #if defined(PNG_WRITE_zTXt_SUPPORTED)
  521. /* write a compressed chunk */
  522. void
  523. png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
  524.    png_uint_32 text_len, int compression)
  525. {
  526.    int key_len;
  527.    char buf[1];
  528.    int i, ret;
  529.    png_charpp output_ptr = NULL; /* array of pointers to output */
  530.    int num_output_ptr = 0; /* number of output pointers used */
  531.    int max_output_ptr = 0; /* size of output_ptr */
  532.    key_len = png_strlen(key);
  533.    if (key_len == 0)
  534.    {
  535.       png_warning(png_ptr, "Invalid text keyword length");
  536.       return;
  537.    }
  538.    else if (key_len > 80)
  539.    {
  540.       png_warning(png_ptr, "Text keyword length restricted to 80 charactersn");
  541.       key[80] = '';
  542.       key_len = 80;
  543.    }
  544.    if (compression != 0)
  545.    {
  546.       png_warning(png_ptr, "Only type 0 compression allowed for textn");
  547.       compression = 0;
  548.    }
  549.    /* we can't write the chunk until we find out how much data we have,
  550.       which means we need to run the compresser first, and save the
  551.       output.  This shouldn't be a problem, as the vast majority of
  552.       comments should be reasonable, but we will set up an array of
  553.       malloced pointers to be sure. */
  554.    /* set up the compression buffers */
  555.    png_ptr->zstream->avail_in = (uInt)text_len;
  556.    png_ptr->zstream->next_in = (Bytef *)text;
  557.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  558.    png_ptr->zstream->next_out = (Bytef *)png_ptr->zbuf;
  559.    /* this is the same compression loop as in png_write_row() */
  560.    do
  561.    {
  562.       /* compress the data */
  563.       ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
  564.       if (ret != Z_OK)
  565.       {
  566.          /* error */
  567.          if (png_ptr->zstream->msg)
  568.             png_error(png_ptr, png_ptr->zstream->msg);
  569.          else
  570.             png_error(png_ptr, "zlib error");
  571.       }
  572.       /* check to see if we need more room */
  573.       if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in)
  574.       {
  575.          /* make sure the output array has room */
  576.          if (num_output_ptr >= max_output_ptr)
  577.          {
  578.             png_uint_32 old_max;
  579.             old_max = max_output_ptr;
  580.             max_output_ptr = num_output_ptr + 4;
  581.             if (output_ptr)
  582.             {
  583.                png_charpp old_ptr;
  584.                old_ptr = output_ptr;
  585.                output_ptr = (png_charpp)png_large_malloc(png_ptr,
  586.                   max_output_ptr * sizeof (png_charpp));
  587.                png_memcpy(output_ptr, old_ptr,
  588.                   (png_size_t)(old_max * sizeof (png_charp)));
  589.                png_large_free(png_ptr, old_ptr);
  590.             }
  591.             else
  592.                output_ptr = (png_charpp)png_large_malloc(png_ptr,
  593.                   max_output_ptr * sizeof (png_charp));
  594.          }
  595.          /* save the data */
  596.          output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
  597.             png_ptr->zbuf_size);
  598.          png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
  599.             (png_size_t)png_ptr->zbuf_size);
  600.          num_output_ptr++;
  601.          /* and reset the buffer */
  602.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  603.          png_ptr->zstream->next_out = png_ptr->zbuf;
  604.       }
  605.    /* continue until we don't have anymore to compress */
  606.    } while (png_ptr->zstream->avail_in);
  607.    /* finish the compression */
  608.    do
  609.    {
  610.       /* tell zlib we are finished */
  611.       ret = deflate(png_ptr->zstream, Z_FINISH);
  612.       if (ret != Z_OK && ret != Z_STREAM_END)
  613.       {
  614.          /* we got an error */
  615.          if (png_ptr->zstream->msg)
  616.             png_error(png_ptr, png_ptr->zstream->msg);
  617.          else
  618.             png_error(png_ptr, "zlib error");
  619.       }
  620.       /* check to see if we need more room */
  621.       if (!png_ptr->zstream->avail_out && ret == Z_OK)
  622.       {
  623.          /* check to make sure our output array has room */
  624.          if (num_output_ptr >= max_output_ptr)
  625.          {
  626.             png_uint_32 old_max;
  627.             old_max = max_output_ptr;
  628.             max_output_ptr = num_output_ptr + 4;
  629.             if (output_ptr)
  630.             {
  631.                png_charpp old_ptr;
  632.                old_ptr = output_ptr;
  633.                output_ptr = (png_charpp)png_large_malloc(png_ptr,
  634.                   max_output_ptr * sizeof (png_charpp));
  635.                png_memcpy(output_ptr, old_ptr,
  636.                   (png_size_t)(old_max * sizeof (png_charp)));
  637.                png_large_free(png_ptr, old_ptr);
  638.             }
  639.             else
  640.                output_ptr = (png_charpp)png_large_malloc(png_ptr,
  641.                   max_output_ptr * sizeof (png_charp));
  642.          }
  643.          /* save off the data */
  644.          output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
  645.             png_ptr->zbuf_size);
  646.          png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
  647.             (png_size_t)png_ptr->zbuf_size);
  648.          num_output_ptr++;
  649.          /* and reset the buffer pointers */
  650.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  651.          png_ptr->zstream->next_out = png_ptr->zbuf;
  652.       }
  653.    } while (ret != Z_STREAM_END);
  654.    /* text length is number of buffers plus last buffer */
  655.    text_len = png_ptr->zbuf_size * num_output_ptr;
  656.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  657.       text_len += (png_uint_32)(png_ptr->zbuf_size -
  658.          png_ptr->zstream->avail_out);
  659.    /* write start of chunk */
  660.    png_write_chunk_start(png_ptr, png_zTXt,
  661.       (png_uint_32)(key_len + text_len + 2));
  662.    /* write key */
  663.    png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
  664.    buf[0] = (png_byte)compression;
  665.    /* write compression */
  666.    png_write_chunk_data(png_ptr, (png_bytep )buf, (png_uint_32)1);
  667.    /* write saved output buffers, if any */
  668.    for (i = 0; i < num_output_ptr; i++)
  669.    {
  670.       png_write_chunk_data(png_ptr, (png_bytep )output_ptr[i], png_ptr->zbuf_size);
  671.       png_large_free(png_ptr, output_ptr[i]);
  672.    }
  673.    if (max_output_ptr)
  674.       png_large_free(png_ptr, output_ptr);
  675.    /* write anything left in zbuf */
  676.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  677.       png_write_chunk_data(png_ptr, png_ptr->zbuf,
  678.          png_ptr->zbuf_size - png_ptr->zstream->avail_out);
  679.    /* close the chunk */
  680.    png_write_chunk_end(png_ptr);
  681.    /* reset zlib for another zTXt or the image data */
  682.    deflateReset(png_ptr->zstream);
  683. }
  684. #endif
  685. #if defined(PNG_WRITE_pHYs_SUPPORTED)
  686. /* write the pHYs chunk */
  687. void
  688. png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
  689.    png_uint_32 y_pixels_per_unit,
  690.    int unit_type)
  691. {
  692.    png_byte buf[9];
  693.    if (unit_type >= PNG_RESOLUTION_LAST)
  694.       png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
  695.    png_save_uint_32(buf, x_pixels_per_unit);
  696.    png_save_uint_32(buf + 4, y_pixels_per_unit);
  697.    buf[8] = (png_byte)unit_type;
  698.    png_write_chunk(png_ptr, png_pHYs, buf, (png_uint_32)9);
  699. }
  700. #endif
  701. #if defined(PNG_WRITE_oFFs_SUPPORTED)
  702. /* write the oFFs chunk */
  703. void
  704. png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
  705.    png_uint_32 y_offset,
  706.    int unit_type)
  707. {
  708.    png_byte buf[9];
  709.    if (unit_type >= PNG_OFFSET_LAST)
  710.       png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
  711.    png_save_uint_32(buf, x_offset);
  712.    png_save_uint_32(buf + 4, y_offset);
  713.    buf[8] = (png_byte)unit_type;
  714.    png_write_chunk(png_ptr, png_oFFs, buf, (png_uint_32)9);
  715. }
  716. #endif
  717. #if defined(PNG_WRITE_tIME_SUPPORTED)
  718. /* write the tIME chunk.  Use either png_convert_from_struct_tm()
  719.    or png_convert_from_time_t(), or fill in the structure yourself */
  720. void
  721. png_write_tIME(png_structp png_ptr, png_timep mod_time)
  722. {
  723.    png_byte buf[7];
  724.    if (mod_time->month  > 12 || mod_time->month  < 1 ||
  725.        mod_time->day    > 31 || mod_time->day    < 1 ||
  726.        mod_time->hour   > 23 || mod_time->second > 60)
  727.    {
  728.       png_warning(png_ptr, "Invalid time specified for tIME chunk");
  729.       return;
  730.    }
  731.    png_save_uint_16(buf, mod_time->year);
  732.    buf[2] = mod_time->month;
  733.    buf[3] = mod_time->day;
  734.    buf[4] = mod_time->hour;
  735.    buf[5] = mod_time->minute;
  736.    buf[6] = mod_time->second;
  737.    png_write_chunk(png_ptr, png_tIME, buf, (png_uint_32)7);
  738. }
  739. #endif
  740. /* initializes the row writing capability of libpng */
  741. void
  742. png_write_start_row(png_structp png_ptr)
  743. {
  744.    /* set up row buffer */
  745.    png_ptr->row_buf = (png_bytep )png_large_malloc(png_ptr,
  746.       (((png_uint_32)png_ptr->usr_channels *
  747.       (png_uint_32)png_ptr->usr_bit_depth *
  748.       png_ptr->width + 7) >> 3) + 1);
  749.    png_ptr->row_buf[0] = 0;
  750.    /* set up filtering buffer, if using this filter */
  751.    if (png_ptr->do_filter & PNG_FILTER_SUB)
  752.    {
  753.       png_ptr->sub_row = (png_bytep )png_large_malloc(png_ptr,
  754.          png_ptr->rowbytes + 1);
  755.       png_ptr->sub_row[0] = 1;  /* Set the row filter type */
  756.    }
  757.    /* We only need to keep the previous row if we are using one of these */
  758.    if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
  759.    {
  760.      /* set up previous row buffer */
  761.       png_ptr->prev_row = (png_bytep )png_large_malloc(png_ptr,
  762.          (((png_uint_32)png_ptr->usr_channels *
  763.          (png_uint_32)png_ptr->usr_bit_depth *
  764.          png_ptr->width + 7) >> 3) + 1);
  765.       png_memset(png_ptr->prev_row, 0, (((png_uint_32)png_ptr->usr_channels *
  766.          (png_uint_32)png_ptr->usr_bit_depth * png_ptr->width + 7) >> 3) + 1);
  767.       if (png_ptr->do_filter & PNG_FILTER_UP)
  768.       {
  769.          png_ptr->up_row = (png_bytep )png_large_malloc(png_ptr,
  770.             png_ptr->rowbytes + 1);
  771.          png_ptr->up_row[0] = 2;  /* Set the row filter type */
  772.       }
  773.       if (png_ptr->do_filter & PNG_FILTER_AVG)
  774.       {
  775.          png_ptr->avg_row = (png_bytep )png_large_malloc(png_ptr,
  776.             png_ptr->rowbytes + 1);
  777.          png_ptr->avg_row[0] = 3;  /* Set the row filter type */
  778.       }
  779.       if (png_ptr->do_filter & PNG_FILTER_PAETH)
  780.       {
  781.          png_ptr->paeth_row = (png_bytep )png_large_malloc(png_ptr,
  782.             png_ptr->rowbytes + 1);
  783.          png_ptr->paeth_row[0] = 4;  /* Set the row filter type */
  784.       }
  785.    }
  786.    /* if interlaced, we need to set up width and height of pass */
  787.    if (png_ptr->interlaced)
  788.    {
  789.       if (!(png_ptr->transformations & PNG_INTERLACE))
  790.       {
  791.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  792.             png_pass_ystart[0]) / png_pass_yinc[0];
  793.          png_ptr->usr_width = (png_ptr->width +
  794.             png_pass_inc[0] - 1 -
  795.             png_pass_start[0]) /
  796.             png_pass_inc[0];
  797.       }
  798.       else
  799.       {
  800.          png_ptr->num_rows = png_ptr->height;
  801.          png_ptr->usr_width = png_ptr->width;
  802.       }
  803.    }
  804.    else
  805.    {
  806.       png_ptr->num_rows = png_ptr->height;
  807.       png_ptr->usr_width = png_ptr->width;
  808.    }
  809.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  810.    png_ptr->zstream->next_out = png_ptr->zbuf;
  811. }
  812. /* Internal use only.   Called when finished processing a row of data */
  813. void
  814. png_write_finish_row(png_structp png_ptr)
  815. {
  816.    int ret;
  817.    /* next row */
  818.    png_ptr->row_number++;
  819.    /* see if we are done */
  820.    if (png_ptr->row_number < png_ptr->num_rows)
  821.       return;
  822.    /* if interlaced, go to next pass */
  823.    if (png_ptr->interlaced)
  824.    {
  825.       png_ptr->row_number = 0;
  826.       if (png_ptr->transformations & PNG_INTERLACE)
  827.       {
  828.          png_ptr->pass++;
  829.       }
  830.       else
  831.       {
  832.          /* loop until we find a non-zero width or height pass */
  833.          do
  834.          {
  835.             png_ptr->pass++;
  836.             if (png_ptr->pass >= 7)
  837.                break;
  838.             png_ptr->usr_width = (png_ptr->width +
  839.                png_pass_inc[png_ptr->pass] - 1 -
  840.                png_pass_start[png_ptr->pass]) /
  841.                png_pass_inc[png_ptr->pass];
  842.             png_ptr->num_rows = (png_ptr->height +
  843.                png_pass_yinc[png_ptr->pass] - 1 -
  844.                png_pass_ystart[png_ptr->pass]) /
  845.                png_pass_yinc[png_ptr->pass];
  846.             if (png_ptr->transformations & PNG_INTERLACE)
  847.                break;
  848.          } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
  849.       }
  850.       /* reset the row above the image for the next pass */
  851.       if (png_ptr->pass < 7)
  852.       {
  853.          if (png_ptr->prev_row)
  854.             png_memset(png_ptr->prev_row, 0,
  855.                (((png_uint_32)png_ptr->usr_channels *
  856.                (png_uint_32)png_ptr->usr_bit_depth *
  857.                png_ptr->width + 7) >> 3) + 1);
  858.          return;
  859.       }
  860.    }
  861.    /* if we get here, we've just written the last row, so we need
  862.       to flush the compressor */
  863.    do
  864.    {
  865.       /* tell the compressor we are done */
  866.       ret = deflate(png_ptr->zstream, Z_FINISH);
  867.       /* check for an error */
  868.       if (ret != Z_OK && ret != Z_STREAM_END)
  869.       {
  870.          if (png_ptr->zstream->msg)
  871.             png_error(png_ptr, png_ptr->zstream->msg);
  872.          else
  873.             png_error(png_ptr, "zlib error");
  874.       }
  875.       /* check to see if we need more room */
  876.       if (!png_ptr->zstream->avail_out && ret == Z_OK)
  877.       {
  878.          png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  879.          png_ptr->zstream->next_out = png_ptr->zbuf;
  880.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  881.       }
  882.    } while (ret != Z_STREAM_END);
  883.    /* write any extra space */
  884.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  885.    {
  886.       png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
  887.          png_ptr->zstream->avail_out);
  888.    }
  889.    deflateReset(png_ptr->zstream);
  890. }
  891. #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
  892. /* pick out the correct pixels for the interlace pass.
  893.    The basic idea here is to go through the row with a source
  894.    pointer and a destination pointer (sp and dp), and copy the
  895.    correct pixels for the pass.  As the row gets compacted,
  896.    sp will always be >= dp, so we should never overwrite anything.
  897.    See the default: case for the easiest code to understand.
  898.    */
  899. void
  900. png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
  901. {
  902.    /* we don't have to do anything on the last pass (6) */
  903.    if (row && row_info && pass < 6)
  904.    {
  905.       /* each pixel depth is handled seperately */
  906.       switch (row_info->pixel_depth)
  907.       {
  908.          case 1:
  909.          {
  910.             png_bytep sp;
  911.             png_bytep dp;
  912.             int shift;
  913.             int d;
  914.             int value;
  915.             png_uint_32 i;
  916.             dp = row;
  917.             d = 0;
  918.             shift = 7;
  919.             for (i = png_pass_start[pass];
  920.                i < row_info->width;
  921.                i += png_pass_inc[pass])
  922.             {
  923.                sp = row + (png_size_t)(i >> 3);
  924.                value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
  925.                d |= (value << shift);
  926.                if (shift == 0)
  927.                {
  928.                   shift = 7;
  929.                   *dp++ = (png_byte)d;
  930.                   d = 0;
  931.                }
  932.                else
  933.                   shift--;
  934.             }
  935.             if (shift != 7)
  936.                *dp = (png_byte)d;
  937.             break;
  938.          }
  939.          case 2:
  940.          {
  941.             png_bytep sp;
  942.             png_bytep dp;
  943.             int shift;
  944.             int d;
  945.             int value;
  946.             png_uint_32 i;
  947.             dp = row;
  948.             shift = 6;
  949.             d = 0;
  950.             for (i = png_pass_start[pass];
  951.                i < row_info->width;
  952.                i += png_pass_inc[pass])
  953.             {
  954.                sp = row + (png_size_t)(i >> 2);
  955.                value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
  956.                d |= (value << shift);
  957.                if (shift == 0)
  958.                {
  959.                   shift = 6;
  960.                   *dp++ = (png_byte)d;
  961.                   d = 0;
  962.                }
  963.                else
  964.                   shift -= 2;
  965.             }
  966.             if (shift != 6)
  967.                    *dp = (png_byte)d;
  968.             break;
  969.          }
  970.          case 4:
  971.          {
  972.             png_bytep sp;
  973.             png_bytep dp;
  974.             int shift;
  975.             int d;
  976.             int value;
  977.             png_uint_32 i;
  978.             dp = row;
  979.             shift = 4;
  980.             d = 0;
  981.             for (i = png_pass_start[pass];
  982.                i < row_info->width;
  983.                i += png_pass_inc[pass])
  984.             {
  985.                sp = row + (png_size_t)(i >> 1);
  986.                value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
  987.                d |= (value << shift);
  988.                if (shift == 0)
  989.                {
  990.                   shift = 4;
  991.                   *dp++ = (png_byte)d;
  992.                   d = 0;
  993.                }
  994.                else
  995.                   shift -= 4;
  996.             }
  997.             if (shift != 4)
  998.                *dp = (png_byte)d;
  999.             break;
  1000.          }
  1001.          default:
  1002.          {
  1003.             png_bytep sp;
  1004.             png_bytep dp;
  1005.             png_uint_32 i;
  1006.             int pixel_bytes;
  1007.             /* start at the beginning */
  1008.             dp = row;
  1009.             /* find out how many bytes each pixel takes up */
  1010.             pixel_bytes = (row_info->pixel_depth >> 3);
  1011.             /* loop through the row, only looking at the pixels that
  1012.                matter */
  1013.             for (i = png_pass_start[pass];
  1014.                i < row_info->width;
  1015.                i += png_pass_inc[pass])
  1016.             {
  1017.                /* find out where the original pixel is */
  1018.                sp = row + (png_size_t)(i * pixel_bytes);
  1019.                /* move the pixel */
  1020.                if (dp != sp)
  1021.                   png_memcpy(dp, sp, pixel_bytes);
  1022.                /* next pixel */
  1023.                dp += pixel_bytes;
  1024.             }
  1025.             break;
  1026.          }
  1027.       }
  1028.       /* set new row width */
  1029.       row_info->width = (row_info->width +
  1030.          png_pass_inc[pass] - 1 -
  1031.          png_pass_start[pass]) /
  1032.          png_pass_inc[pass];
  1033.       row_info->rowbytes = ((row_info->width *
  1034.          row_info->pixel_depth + 7) >> 3);
  1035.    }
  1036. }
  1037. #endif
  1038. /* this filters the row, chooses which filter to use, if it has not already
  1039.  * been given by the application, and then writes the row out with the
  1040.  * chosen filter */
  1041. void
  1042. png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
  1043. {
  1044.    png_bytep prev_row, best_row, row_buf;
  1045.    png_uint_32 mins;
  1046.    int bpp;
  1047.    /* find out how many bytes offset each pixel is */
  1048.    bpp = (row_info->pixel_depth + 7) / 8;
  1049.    prev_row = png_ptr->prev_row;
  1050.    best_row = row_buf = png_ptr->row_buf;
  1051.    mins = 0xffffffff;
  1052.    /* the prediction method we use is to find which method provides
  1053.       the smallest value when summing the abs of the distances from
  1054.       zero using anything >= 128 as negitive numbers. */
  1055.    /* We don't need to test the 'no filter' case if this is the only filter
  1056.     * that has been chosen, as it doesn't actually do anything to the data. */
  1057.    if (png_ptr->do_filter & PNG_FILTER_NONE &&
  1058.        png_ptr->do_filter != PNG_FILTER_NONE)
  1059.    {
  1060.       png_bytep rp;
  1061.       png_uint_32 sum = 0;
  1062.       int i, v;
  1063.       for (i = 0, rp = row_buf + 1; i < row_info->rowbytes; i++, rp++)
  1064.       {
  1065.          v = *rp;
  1066.          sum += (v < 128) ? v : 256 - v;
  1067.       }
  1068.       mins = sum;
  1069.    }
  1070.    /* sub filter */
  1071.    if (png_ptr->do_filter & PNG_FILTER_SUB)
  1072.    {
  1073.       png_bytep rp, dp, lp;
  1074.       png_uint_32 sum = 0;
  1075.       int i, v;
  1076.       for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
  1077.            i++, rp++, dp++)
  1078.       {
  1079.          v = *dp = *rp;
  1080.          sum += (v < 128) ? v : 256 - v;
  1081.       }
  1082.       for (lp = row_buf + 1; i < row_info->rowbytes; i++, rp++, lp++, dp++)
  1083.       {
  1084.          v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
  1085.          sum += (v < 128) ? v : 256 - v;
  1086.       }
  1087.       if (sum < mins)
  1088.       {
  1089.          mins = sum;
  1090.          best_row = png_ptr->sub_row;
  1091.       }
  1092.    }
  1093.    /* up filter */
  1094.    if (png_ptr->do_filter & PNG_FILTER_UP)
  1095.    {
  1096.       png_bytep rp, dp, pp;
  1097.       png_uint_32 sum = 0;
  1098.       int i, v;
  1099.       for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
  1100.            pp = prev_row + 1; i < row_info->rowbytes; i++, rp++, pp++, dp++)
  1101.       {
  1102.          v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
  1103.          sum += (v < 128) ? v : 256 - v;
  1104.       }
  1105.       if (sum < mins)
  1106.       {
  1107.          mins = sum;
  1108.          best_row = png_ptr->up_row;
  1109.       }
  1110.    }
  1111.    /* avg filter */
  1112.    if (png_ptr->do_filter & PNG_FILTER_AVG)
  1113.    {
  1114.       png_bytep rp, dp, pp, lp;
  1115.       png_uint_32 sum = 0;
  1116.       int i, v;
  1117.       for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
  1118.            pp = prev_row + 1; i < bpp; i++, rp++, pp++, dp++)
  1119.       {
  1120.          v = *dp = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
  1121.          sum += (v < 128) ? v : 256 - v;
  1122.       }
  1123.       for (lp = row_buf + 1; i < row_info->rowbytes;
  1124.            i++, rp++, pp++, lp++, dp++)
  1125.       {
  1126.          v = *dp = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff);
  1127.          sum += (v < 128) ? v : 256 - v;
  1128.       }
  1129.       if (sum < mins)
  1130.       {
  1131.          mins = sum;
  1132.          best_row = png_ptr->avg_row;
  1133.       }
  1134.    }
  1135.    /* paeth filter */
  1136.    if (png_ptr->do_filter & PNG_FILTER_PAETH)
  1137.    {
  1138.       png_bytep rp, dp, pp, cp, lp;
  1139.       png_uint_32 sum = 0;
  1140.       int i, v;
  1141.       for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
  1142.            pp = prev_row + 1; i < bpp; i++, rp++, pp++, dp++)
  1143.       {
  1144.          v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
  1145.          sum += (v < 128) ? v : 256 - v;
  1146.       }
  1147.       for (lp = row_buf + 1, cp = prev_row + 1; i < row_info->rowbytes;
  1148.            i++, rp++, pp++, lp++, dp++, cp++)
  1149.       {
  1150.          int a, b, c, pa, pb, pc, p;
  1151.          b = *pp;
  1152.          c = *cp;
  1153.          a = *lp;
  1154.          p = a + b - c;
  1155.          pa = abs(p - a);
  1156.          pb = abs(p - b);
  1157.          pc = abs(p - c);
  1158.          if (pa <= pb && pa <= pc)
  1159.             p = a;
  1160.          else if (pb <= pc)
  1161.             p = b;
  1162.          else
  1163.             p = c;
  1164.          v = *dp = (png_byte)(((int)*rp - p) & 0xff);
  1165.          sum += (v < 128) ? v : 256 - v;
  1166.       }
  1167.       if (sum < mins)
  1168.       {
  1169.          best_row = png_ptr->paeth_row;
  1170.       }
  1171.    }
  1172.    /* Do the actual writing of the filtered row data from the chosen filter */
  1173.    png_write_filtered_row(png_ptr, best_row);
  1174. }
  1175. /* do the actual writing of a filtered row */
  1176. void
  1177. png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
  1178. {
  1179.    /* set up the zlib input buffer */
  1180.    png_ptr->zstream->next_in = filtered_row;
  1181.    png_ptr->zstream->avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
  1182.    /* repeat until we have compressed all the data */
  1183.    do
  1184.    {
  1185.       int ret; /* return of zlib */
  1186.       /* compress the data */
  1187.       ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
  1188.       /* check for compression errors */
  1189.       if (ret != Z_OK)
  1190.       {
  1191.          if (png_ptr->zstream->msg)
  1192.             png_error(png_ptr, png_ptr->zstream->msg);
  1193.          else
  1194.             png_error(png_ptr, "zlib error");
  1195.       }
  1196.       /* see if it is time to write another IDAT */
  1197.       if (!png_ptr->zstream->avail_out)
  1198.       {
  1199.          /* write the IDAT and reset the zlib output buffer */
  1200.          png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  1201.          png_ptr->zstream->next_out = png_ptr->zbuf;
  1202.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  1203.       }
  1204.    /* repeat until all data has been compressed */
  1205.    } while (png_ptr->zstream->avail_in);
  1206.    /* swap the current and previous rows */
  1207.    if (png_ptr->prev_row)
  1208.    {
  1209.       png_bytep tptr;
  1210.       tptr = png_ptr->prev_row;
  1211.       png_ptr->prev_row = png_ptr->row_buf;
  1212.       png_ptr->row_buf = tptr;
  1213.    }
  1214.    /* finish row - updates counters and flushes zlib if last row */
  1215.    png_write_finish_row(png_ptr);
  1216. #if defined(PNG_WRITE_FLUSH_SUPPORTED)
  1217.    png_ptr->flush_rows++;
  1218.    if (png_ptr->flush_dist > 0 &&
  1219.        png_ptr->flush_rows >= png_ptr->flush_dist)
  1220.    {
  1221.       png_write_flush(png_ptr);
  1222.    }
  1223. #endif /* PNG_WRITE_FLUSH_SUPPORTED */
  1224. }