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

界面编程

开发平台:

Visual C++

  1. /* pngpread.c - read a png file in push mode
  2.  *
  3.  * Last changed in libpng 1.2.32 [September 18, 2008]
  4.  * For conditions of distribution and use, see copyright notice in png.h
  5.  * Copyright (c) 1998-2008 Glenn Randers-Pehrson
  6.  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  7.  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  8.  */
  9. #define PNG_INTERNAL
  10. #include "png.h"
  11. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  12. /* push model modes */
  13. #define PNG_READ_SIG_MODE   0
  14. #define PNG_READ_CHUNK_MODE 1
  15. #define PNG_READ_IDAT_MODE  2
  16. #define PNG_SKIP_MODE       3
  17. #define PNG_READ_tEXt_MODE  4
  18. #define PNG_READ_zTXt_MODE  5
  19. #define PNG_READ_DONE_MODE  6
  20. #define PNG_READ_iTXt_MODE  7
  21. #define PNG_ERROR_MODE      8
  22. void PNGAPI
  23. png_process_data(png_structp png_ptr, png_infop info_ptr,
  24.    png_bytep buffer, png_size_t buffer_size)
  25. {
  26.    if (png_ptr == NULL || info_ptr == NULL) return;
  27.    png_push_restore_buffer(png_ptr, buffer, buffer_size);
  28.    while (png_ptr->buffer_size)
  29.    {
  30.       png_process_some_data(png_ptr, info_ptr);
  31.    }
  32. }
  33. /* What we do with the incoming data depends on what we were previously
  34.  * doing before we ran out of data...
  35.  */
  36. void /* PRIVATE */
  37. png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  38. {
  39.    if (png_ptr == NULL) return;
  40.    switch (png_ptr->process_mode)
  41.    {
  42.       case PNG_READ_SIG_MODE:
  43.       {
  44.          png_push_read_sig(png_ptr, info_ptr);
  45.          break;
  46.       }
  47.       case PNG_READ_CHUNK_MODE:
  48.       {
  49.          png_push_read_chunk(png_ptr, info_ptr);
  50.          break;
  51.       }
  52.       case PNG_READ_IDAT_MODE:
  53.       {
  54.          png_push_read_IDAT(png_ptr);
  55.          break;
  56.       }
  57. #if defined(PNG_READ_tEXt_SUPPORTED)
  58.       case PNG_READ_tEXt_MODE:
  59.       {
  60.          png_push_read_tEXt(png_ptr, info_ptr);
  61.          break;
  62.       }
  63. #endif
  64. #if defined(PNG_READ_zTXt_SUPPORTED)
  65.       case PNG_READ_zTXt_MODE:
  66.       {
  67.          png_push_read_zTXt(png_ptr, info_ptr);
  68.          break;
  69.       }
  70. #endif
  71. #if defined(PNG_READ_iTXt_SUPPORTED)
  72.       case PNG_READ_iTXt_MODE:
  73.       {
  74.          png_push_read_iTXt(png_ptr, info_ptr);
  75.          break;
  76.       }
  77. #endif
  78.       case PNG_SKIP_MODE:
  79.       {
  80.          png_push_crc_finish(png_ptr);
  81.          break;
  82.       }
  83.       default:
  84.       {
  85.          png_ptr->buffer_size = 0;
  86.          break;
  87.       }
  88.    }
  89. }
  90. /* Read any remaining signature bytes from the stream and compare them with
  91.  * the correct PNG signature.  It is possible that this routine is called
  92.  * with bytes already read from the signature, either because they have been
  93.  * checked by the calling application, or because of multiple calls to this
  94.  * routine.
  95.  */
  96. void /* PRIVATE */
  97. png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
  98. {
  99.    png_size_t num_checked = png_ptr->sig_bytes,
  100.              num_to_check = 8 - num_checked;
  101.    if (png_ptr->buffer_size < num_to_check)
  102.    {
  103.       num_to_check = png_ptr->buffer_size;
  104.    }
  105.    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
  106.       num_to_check);
  107.    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
  108.    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
  109.    {
  110.       if (num_checked < 4 &&
  111.           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
  112.          png_error(png_ptr, "Not a PNG file");
  113.       else
  114.          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
  115.    }
  116.    else
  117.    {
  118.       if (png_ptr->sig_bytes >= 8)
  119.       {
  120.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  121.       }
  122.    }
  123. }
  124. void /* PRIVATE */
  125. png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
  126. {
  127. #ifdef PNG_USE_LOCAL_ARRAYS
  128.       PNG_CONST PNG_IHDR;
  129.       PNG_CONST PNG_IDAT;
  130.       PNG_CONST PNG_IEND;
  131.       PNG_CONST PNG_PLTE;
  132. #if defined(PNG_READ_bKGD_SUPPORTED)
  133.       PNG_CONST PNG_bKGD;
  134. #endif
  135. #if defined(PNG_READ_cHRM_SUPPORTED)
  136.       PNG_CONST PNG_cHRM;
  137. #endif
  138. #if defined(PNG_READ_gAMA_SUPPORTED)
  139.       PNG_CONST PNG_gAMA;
  140. #endif
  141. #if defined(PNG_READ_hIST_SUPPORTED)
  142.       PNG_CONST PNG_hIST;
  143. #endif
  144. #if defined(PNG_READ_iCCP_SUPPORTED)
  145.       PNG_CONST PNG_iCCP;
  146. #endif
  147. #if defined(PNG_READ_iTXt_SUPPORTED)
  148.       PNG_CONST PNG_iTXt;
  149. #endif
  150. #if defined(PNG_READ_oFFs_SUPPORTED)
  151.       PNG_CONST PNG_oFFs;
  152. #endif
  153. #if defined(PNG_READ_pCAL_SUPPORTED)
  154.       PNG_CONST PNG_pCAL;
  155. #endif
  156. #if defined(PNG_READ_pHYs_SUPPORTED)
  157.       PNG_CONST PNG_pHYs;
  158. #endif
  159. #if defined(PNG_READ_sBIT_SUPPORTED)
  160.       PNG_CONST PNG_sBIT;
  161. #endif
  162. #if defined(PNG_READ_sCAL_SUPPORTED)
  163.       PNG_CONST PNG_sCAL;
  164. #endif
  165. #if defined(PNG_READ_sRGB_SUPPORTED)
  166.       PNG_CONST PNG_sRGB;
  167. #endif
  168. #if defined(PNG_READ_sPLT_SUPPORTED)
  169.       PNG_CONST PNG_sPLT;
  170. #endif
  171. #if defined(PNG_READ_tEXt_SUPPORTED)
  172.       PNG_CONST PNG_tEXt;
  173. #endif
  174. #if defined(PNG_READ_tIME_SUPPORTED)
  175.       PNG_CONST PNG_tIME;
  176. #endif
  177. #if defined(PNG_READ_tRNS_SUPPORTED)
  178.       PNG_CONST PNG_tRNS;
  179. #endif
  180. #if defined(PNG_READ_zTXt_SUPPORTED)
  181.       PNG_CONST PNG_zTXt;
  182. #endif
  183. #endif /* PNG_USE_LOCAL_ARRAYS */
  184.    /* First we make sure we have enough data for the 4 byte chunk name
  185.     * and the 4 byte chunk length before proceeding with decoding the
  186.     * chunk data.  To fully decode each of these chunks, we also make
  187.     * sure we have enough data in the buffer for the 4 byte CRC at the
  188.     * end of every chunk (except IDAT, which is handled separately).
  189.     */
  190.    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
  191.    {
  192.       png_byte chunk_length[4];
  193.       if (png_ptr->buffer_size < 8)
  194.       {
  195.          png_push_save_buffer(png_ptr);
  196.          return;
  197.       }
  198.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  199.       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
  200.       png_reset_crc(png_ptr);
  201.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  202.       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  203.       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  204.    }
  205.    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  206.      if (png_ptr->mode & PNG_AFTER_IDAT)
  207.         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
  208.    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
  209.    {
  210.       if (png_ptr->push_length != 13)
  211.          png_error(png_ptr, "Invalid IHDR length");
  212.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  213.       {
  214.          png_push_save_buffer(png_ptr);
  215.          return;
  216.       }
  217.       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
  218.    }
  219.    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
  220.    {
  221.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  222.       {
  223.          png_push_save_buffer(png_ptr);
  224.          return;
  225.       }
  226.       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
  227.       png_ptr->process_mode = PNG_READ_DONE_MODE;
  228.       png_push_have_end(png_ptr, info_ptr);
  229.    }
  230. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  231.    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
  232.    {
  233.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  234.       {
  235.          png_push_save_buffer(png_ptr);
  236.          return;
  237.       }
  238.       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  239.          png_ptr->mode |= PNG_HAVE_IDAT;
  240.       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  241.       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  242.          png_ptr->mode |= PNG_HAVE_PLTE;
  243.       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  244.       {
  245.          if (!(png_ptr->mode & PNG_HAVE_IHDR))
  246.             png_error(png_ptr, "Missing IHDR before IDAT");
  247.          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  248.                   !(png_ptr->mode & PNG_HAVE_PLTE))
  249.             png_error(png_ptr, "Missing PLTE before IDAT");
  250.       }
  251.    }
  252. #endif
  253.    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  254.    {
  255.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  256.       {
  257.          png_push_save_buffer(png_ptr);
  258.          return;
  259.       }
  260.       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
  261.    }
  262.    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  263.    {
  264.       /* If we reach an IDAT chunk, this means we have read all of the
  265.        * header chunks, and we can start reading the image (or if this
  266.        * is called after the image has been read - we have an error).
  267.        */
  268.      if (!(png_ptr->mode & PNG_HAVE_IHDR))
  269.        png_error(png_ptr, "Missing IHDR before IDAT");
  270.      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  271.          !(png_ptr->mode & PNG_HAVE_PLTE))
  272.        png_error(png_ptr, "Missing PLTE before IDAT");
  273.       if (png_ptr->mode & PNG_HAVE_IDAT)
  274.       {
  275.          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
  276.            if (png_ptr->push_length == 0)
  277.               return;
  278.          if (png_ptr->mode & PNG_AFTER_IDAT)
  279.             png_error(png_ptr, "Too many IDAT's found");
  280.       }
  281.       png_ptr->idat_size = png_ptr->push_length;
  282.       png_ptr->mode |= PNG_HAVE_IDAT;
  283.       png_ptr->process_mode = PNG_READ_IDAT_MODE;
  284.       png_push_have_info(png_ptr, info_ptr);
  285.       png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  286.       png_ptr->zstream.next_out = png_ptr->row_buf;
  287.       return;
  288.    }
  289. #if defined(PNG_READ_gAMA_SUPPORTED)
  290.    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
  291.    {
  292.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  293.       {
  294.          png_push_save_buffer(png_ptr);
  295.          return;
  296.       }
  297.       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
  298.    }
  299. #endif
  300. #if defined(PNG_READ_sBIT_SUPPORTED)
  301.    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
  302.    {
  303.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  304.       {
  305.          png_push_save_buffer(png_ptr);
  306.          return;
  307.       }
  308.       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
  309.    }
  310. #endif
  311. #if defined(PNG_READ_cHRM_SUPPORTED)
  312.    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
  313.    {
  314.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  315.       {
  316.          png_push_save_buffer(png_ptr);
  317.          return;
  318.       }
  319.       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
  320.    }
  321. #endif
  322. #if defined(PNG_READ_sRGB_SUPPORTED)
  323.    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
  324.    {
  325.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  326.       {
  327.          png_push_save_buffer(png_ptr);
  328.          return;
  329.       }
  330.       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
  331.    }
  332. #endif
  333. #if defined(PNG_READ_iCCP_SUPPORTED)
  334.    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
  335.    {
  336.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  337.       {
  338.          png_push_save_buffer(png_ptr);
  339.          return;
  340.       }
  341.       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
  342.    }
  343. #endif
  344. #if defined(PNG_READ_sPLT_SUPPORTED)
  345.    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
  346.    {
  347.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  348.       {
  349.          png_push_save_buffer(png_ptr);
  350.          return;
  351.       }
  352.       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
  353.    }
  354. #endif
  355. #if defined(PNG_READ_tRNS_SUPPORTED)
  356.    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
  357.    {
  358.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  359.       {
  360.          png_push_save_buffer(png_ptr);
  361.          return;
  362.       }
  363.       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
  364.    }
  365. #endif
  366. #if defined(PNG_READ_bKGD_SUPPORTED)
  367.    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
  368.    {
  369.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  370.       {
  371.          png_push_save_buffer(png_ptr);
  372.          return;
  373.       }
  374.       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
  375.    }
  376. #endif
  377. #if defined(PNG_READ_hIST_SUPPORTED)
  378.    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
  379.    {
  380.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  381.       {
  382.          png_push_save_buffer(png_ptr);
  383.          return;
  384.       }
  385.       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
  386.    }
  387. #endif
  388. #if defined(PNG_READ_pHYs_SUPPORTED)
  389.    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
  390.    {
  391.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  392.       {
  393.          png_push_save_buffer(png_ptr);
  394.          return;
  395.       }
  396.       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
  397.    }
  398. #endif
  399. #if defined(PNG_READ_oFFs_SUPPORTED)
  400.    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
  401.    {
  402.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  403.       {
  404.          png_push_save_buffer(png_ptr);
  405.          return;
  406.       }
  407.       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
  408.    }
  409. #endif
  410. #if defined(PNG_READ_pCAL_SUPPORTED)
  411.    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
  412.    {
  413.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  414.       {
  415.          png_push_save_buffer(png_ptr);
  416.          return;
  417.       }
  418.       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
  419.    }
  420. #endif
  421. #if defined(PNG_READ_sCAL_SUPPORTED)
  422.    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
  423.    {
  424.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  425.       {
  426.          png_push_save_buffer(png_ptr);
  427.          return;
  428.       }
  429.       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
  430.    }
  431. #endif
  432. #if defined(PNG_READ_tIME_SUPPORTED)
  433.    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
  434.    {
  435.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  436.       {
  437.          png_push_save_buffer(png_ptr);
  438.          return;
  439.       }
  440.       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
  441.    }
  442. #endif
  443. #if defined(PNG_READ_tEXt_SUPPORTED)
  444.    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
  445.    {
  446.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  447.       {
  448.          png_push_save_buffer(png_ptr);
  449.          return;
  450.       }
  451.       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
  452.    }
  453. #endif
  454. #if defined(PNG_READ_zTXt_SUPPORTED)
  455.    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
  456.    {
  457.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  458.       {
  459.          png_push_save_buffer(png_ptr);
  460.          return;
  461.       }
  462.       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
  463.    }
  464. #endif
  465. #if defined(PNG_READ_iTXt_SUPPORTED)
  466.    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
  467.    {
  468.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  469.       {
  470.          png_push_save_buffer(png_ptr);
  471.          return;
  472.       }
  473.       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
  474.    }
  475. #endif
  476.    else
  477.    {
  478.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  479.       {
  480.          png_push_save_buffer(png_ptr);
  481.          return;
  482.       }
  483.       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  484.    }
  485.    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  486. }
  487. void /* PRIVATE */
  488. png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
  489. {
  490.    png_ptr->process_mode = PNG_SKIP_MODE;
  491.    png_ptr->skip_length = skip;
  492. }
  493. void /* PRIVATE */
  494. png_push_crc_finish(png_structp png_ptr)
  495. {
  496.    if (png_ptr->skip_length && png_ptr->save_buffer_size)
  497.    {
  498.       png_size_t save_size;
  499.       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
  500.          save_size = (png_size_t)png_ptr->skip_length;
  501.       else
  502.          save_size = png_ptr->save_buffer_size;
  503.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  504.       png_ptr->skip_length -= (png_uint_32)save_size;
  505.       png_ptr->buffer_size -= save_size;
  506.       png_ptr->save_buffer_size -= save_size;
  507.       png_ptr->save_buffer_ptr += save_size;
  508.    }
  509.    if (png_ptr->skip_length && png_ptr->current_buffer_size)
  510.    {
  511.       png_size_t save_size;
  512.       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
  513.          save_size = (png_size_t)png_ptr->skip_length;
  514.       else
  515.          save_size = png_ptr->current_buffer_size;
  516.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  517.       png_ptr->skip_length -= (png_uint_32)save_size;
  518.       png_ptr->buffer_size -= save_size;
  519.       png_ptr->current_buffer_size -= save_size;
  520.       png_ptr->current_buffer_ptr += save_size;
  521.    }
  522.    if (!png_ptr->skip_length)
  523.    {
  524.       if (png_ptr->buffer_size < 4)
  525.       {
  526.          png_push_save_buffer(png_ptr);
  527.          return;
  528.       }
  529.       png_crc_finish(png_ptr, 0);
  530.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  531.    }
  532. }
  533. void PNGAPI
  534. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
  535. {
  536.    png_bytep ptr;
  537.    if (png_ptr == NULL) return;
  538.    ptr = buffer;
  539.    if (png_ptr->save_buffer_size)
  540.    {
  541.       png_size_t save_size;
  542.       if (length < png_ptr->save_buffer_size)
  543.          save_size = length;
  544.       else
  545.          save_size = png_ptr->save_buffer_size;
  546.       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
  547.       length -= save_size;
  548.       ptr += save_size;
  549.       png_ptr->buffer_size -= save_size;
  550.       png_ptr->save_buffer_size -= save_size;
  551.       png_ptr->save_buffer_ptr += save_size;
  552.    }
  553.    if (length && png_ptr->current_buffer_size)
  554.    {
  555.       png_size_t save_size;
  556.       if (length < png_ptr->current_buffer_size)
  557.          save_size = length;
  558.       else
  559.          save_size = png_ptr->current_buffer_size;
  560.       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
  561.       png_ptr->buffer_size -= save_size;
  562.       png_ptr->current_buffer_size -= save_size;
  563.       png_ptr->current_buffer_ptr += save_size;
  564.    }
  565. }
  566. void /* PRIVATE */
  567. png_push_save_buffer(png_structp png_ptr)
  568. {
  569.    if (png_ptr->save_buffer_size)
  570.    {
  571.       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  572.       {
  573.          png_size_t i, istop;
  574.          png_bytep sp;
  575.          png_bytep dp;
  576.          istop = png_ptr->save_buffer_size;
  577.          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  578.             i < istop; i++, sp++, dp++)
  579.          {
  580.             *dp = *sp;
  581.          }
  582.       }
  583.    }
  584.    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  585.       png_ptr->save_buffer_max)
  586.    {
  587.       png_size_t new_max;
  588.       png_bytep old_buffer;
  589.       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
  590.          (png_ptr->current_buffer_size + 256))
  591.       {
  592.         png_error(png_ptr, "Potential overflow of save_buffer");
  593.       }
  594.       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
  595.       old_buffer = png_ptr->save_buffer;
  596.       png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
  597.          (png_uint_32)new_max);
  598.       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
  599.       png_free(png_ptr, old_buffer);
  600.       png_ptr->save_buffer_max = new_max;
  601.    }
  602.    if (png_ptr->current_buffer_size)
  603.    {
  604.       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
  605.          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
  606.       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  607.       png_ptr->current_buffer_size = 0;
  608.    }
  609.    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  610.    png_ptr->buffer_size = 0;
  611. }
  612. void /* PRIVATE */
  613. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  614.    png_size_t buffer_length)
  615. {
  616.    png_ptr->current_buffer = buffer;
  617.    png_ptr->current_buffer_size = buffer_length;
  618.    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  619.    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  620. }
  621. void /* PRIVATE */
  622. png_push_read_IDAT(png_structp png_ptr)
  623. {
  624. #ifdef PNG_USE_LOCAL_ARRAYS
  625.    PNG_CONST PNG_IDAT;
  626. #endif
  627.    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
  628.    {
  629.       png_byte chunk_length[4];
  630.       if (png_ptr->buffer_size < 8)
  631.       {
  632.          png_push_save_buffer(png_ptr);
  633.          return;
  634.       }
  635.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  636.       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
  637.       png_reset_crc(png_ptr);
  638.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  639.       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  640.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  641.       {
  642.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  643.          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  644.             png_error(png_ptr, "Not enough compressed data");
  645.          return;
  646.       }
  647.       png_ptr->idat_size = png_ptr->push_length;
  648.    }
  649.    if (png_ptr->idat_size && png_ptr->save_buffer_size)
  650.    {
  651.       png_size_t save_size;
  652.       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
  653.       {
  654.          save_size = (png_size_t)png_ptr->idat_size;
  655.          /* check for overflow */
  656.          if ((png_uint_32)save_size != png_ptr->idat_size)
  657.             png_error(png_ptr, "save_size overflowed in pngpread");
  658.       }
  659.       else
  660.          save_size = png_ptr->save_buffer_size;
  661.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  662.       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  663.          png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  664.       png_ptr->idat_size -= (png_uint_32)save_size;
  665.       png_ptr->buffer_size -= save_size;
  666.       png_ptr->save_buffer_size -= save_size;
  667.       png_ptr->save_buffer_ptr += save_size;
  668.    }
  669.    if (png_ptr->idat_size && png_ptr->current_buffer_size)
  670.    {
  671.       png_size_t save_size;
  672.       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
  673.       {
  674.          save_size = (png_size_t)png_ptr->idat_size;
  675.          /* check for overflow */
  676.          if ((png_uint_32)save_size != png_ptr->idat_size)
  677.             png_error(png_ptr, "save_size overflowed in pngpread");
  678.       }
  679.       else
  680.          save_size = png_ptr->current_buffer_size;
  681.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  682.       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  683.         png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  684.       png_ptr->idat_size -= (png_uint_32)save_size;
  685.       png_ptr->buffer_size -= save_size;
  686.       png_ptr->current_buffer_size -= save_size;
  687.       png_ptr->current_buffer_ptr += save_size;
  688.    }
  689.    if (!png_ptr->idat_size)
  690.    {
  691.       if (png_ptr->buffer_size < 4)
  692.       {
  693.          png_push_save_buffer(png_ptr);
  694.          return;
  695.       }
  696.       png_crc_finish(png_ptr, 0);
  697.       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  698.       png_ptr->mode |= PNG_AFTER_IDAT;
  699.    }
  700. }
  701. void /* PRIVATE */
  702. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  703.    png_size_t buffer_length)
  704. {
  705.    int ret;
  706.    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
  707.       png_error(png_ptr, "Extra compression data");
  708.    png_ptr->zstream.next_in = buffer;
  709.    png_ptr->zstream.avail_in = (uInt)buffer_length;
  710.    for (;;)
  711.    {
  712.       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  713.       if (ret != Z_OK)
  714.       {
  715.          if (ret == Z_STREAM_END)
  716.          {
  717.             if (png_ptr->zstream.avail_in)
  718.                png_error(png_ptr, "Extra compressed data");
  719.             if (!(png_ptr->zstream.avail_out))
  720.             {
  721.                png_push_process_row(png_ptr);
  722.             }
  723.             png_ptr->mode |= PNG_AFTER_IDAT;
  724.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  725.             break;
  726.          }
  727.          else if (ret == Z_BUF_ERROR)
  728.             break;
  729.          else
  730.             png_error(png_ptr, "Decompression Error");
  731.       }
  732.       if (!(png_ptr->zstream.avail_out))
  733.       {
  734.          if ((
  735. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  736.              png_ptr->interlaced && png_ptr->pass > 6) ||
  737.              (!png_ptr->interlaced &&
  738. #endif
  739.              png_ptr->row_number == png_ptr->num_rows))
  740.          {
  741.            if (png_ptr->zstream.avail_in)
  742.              png_warning(png_ptr, "Too much data in IDAT chunks");
  743.            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  744.            break;
  745.          }
  746.          png_push_process_row(png_ptr);
  747.          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  748.          png_ptr->zstream.next_out = png_ptr->row_buf;
  749.       }
  750.       else
  751.          break;
  752.    }
  753. }
  754. void /* PRIVATE */
  755. png_push_process_row(png_structp png_ptr)
  756. {
  757.    png_ptr->row_info.color_type = png_ptr->color_type;
  758.    png_ptr->row_info.width = png_ptr->iwidth;
  759.    png_ptr->row_info.channels = png_ptr->channels;
  760.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  761.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  762.    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
  763.        png_ptr->row_info.width);
  764.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  765.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  766.       (int)(png_ptr->row_buf[0]));
  767.    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
  768.       png_ptr->rowbytes + 1);
  769.    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
  770.       png_do_read_transformations(png_ptr);
  771. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  772.    /* blow up interlaced rows to full size */
  773.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  774.    {
  775.       if (png_ptr->pass < 6)
  776. /*       old interface (pre-1.0.9):
  777.          png_do_read_interlace(&(png_ptr->row_info),
  778.             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
  779.  */
  780.          png_do_read_interlace(png_ptr);
  781.     switch (png_ptr->pass)
  782.     {
  783.          case 0:
  784.          {
  785.             int i;
  786.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  787.             {
  788.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  789.                png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
  790.             }
  791.             if (png_ptr->pass == 2) /* pass 1 might be empty */
  792.             {
  793.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  794.                {
  795.                   png_push_have_row(png_ptr, png_bytep_NULL);
  796.                   png_read_push_finish_row(png_ptr);
  797.                }
  798.             }
  799.             if (png_ptr->pass == 4 && png_ptr->height <= 4)
  800.             {
  801.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  802.                {
  803.                   png_push_have_row(png_ptr, png_bytep_NULL);
  804.                   png_read_push_finish_row(png_ptr);
  805.                }
  806.             }
  807.             if (png_ptr->pass == 6 && png_ptr->height <= 4)
  808.             {
  809.                 png_push_have_row(png_ptr, png_bytep_NULL);
  810.                 png_read_push_finish_row(png_ptr);
  811.             }
  812.             break;
  813.          }
  814.          case 1:
  815.          {
  816.             int i;
  817.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  818.             {
  819.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  820.                png_read_push_finish_row(png_ptr);
  821.             }
  822.             if (png_ptr->pass == 2) /* skip top 4 generated rows */
  823.             {
  824.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  825.                {
  826.                   png_push_have_row(png_ptr, png_bytep_NULL);
  827.                   png_read_push_finish_row(png_ptr);
  828.                }
  829.             }
  830.             break;
  831.          }
  832.          case 2:
  833.          {
  834.             int i;
  835.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  836.             {
  837.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  838.                png_read_push_finish_row(png_ptr);
  839.             }
  840.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  841.             {
  842.                png_push_have_row(png_ptr, png_bytep_NULL);
  843.                png_read_push_finish_row(png_ptr);
  844.             }
  845.             if (png_ptr->pass == 4) /* pass 3 might be empty */
  846.             {
  847.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  848.                {
  849.                   png_push_have_row(png_ptr, png_bytep_NULL);
  850.                   png_read_push_finish_row(png_ptr);
  851.                }
  852.             }
  853.             break;
  854.          }
  855.          case 3:
  856.          {
  857.             int i;
  858.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  859.             {
  860.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  861.                png_read_push_finish_row(png_ptr);
  862.             }
  863.             if (png_ptr->pass == 4) /* skip top two generated rows */
  864.             {
  865.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  866.                {
  867.                   png_push_have_row(png_ptr, png_bytep_NULL);
  868.                   png_read_push_finish_row(png_ptr);
  869.                }
  870.             }
  871.             break;
  872.          }
  873.          case 4:
  874.          {
  875.             int i;
  876.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  877.             {
  878.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  879.                png_read_push_finish_row(png_ptr);
  880.             }
  881.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  882.             {
  883.                png_push_have_row(png_ptr, png_bytep_NULL);
  884.                png_read_push_finish_row(png_ptr);
  885.             }
  886.             if (png_ptr->pass == 6) /* pass 5 might be empty */
  887.             {
  888.                png_push_have_row(png_ptr, png_bytep_NULL);
  889.                png_read_push_finish_row(png_ptr);
  890.             }
  891.             break;
  892.          }
  893.          case 5:
  894.          {
  895.             int i;
  896.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  897.             {
  898.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  899.                png_read_push_finish_row(png_ptr);
  900.             }
  901.             if (png_ptr->pass == 6) /* skip top generated row */
  902.             {
  903.                png_push_have_row(png_ptr, png_bytep_NULL);
  904.                png_read_push_finish_row(png_ptr);
  905.             }
  906.             break;
  907.          }
  908.          case 6:
  909.          {
  910.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  911.             png_read_push_finish_row(png_ptr);
  912.             if (png_ptr->pass != 6)
  913.                break;
  914.             png_push_have_row(png_ptr, png_bytep_NULL);
  915.             png_read_push_finish_row(png_ptr);
  916.          }
  917.       }
  918.    }
  919.    else
  920. #endif
  921.    {
  922.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  923.       png_read_push_finish_row(png_ptr);
  924.    }
  925. }
  926. void /* PRIVATE */
  927. png_read_push_finish_row(png_structp png_ptr)
  928. {
  929. #ifdef PNG_USE_LOCAL_ARRAYS
  930.    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  931.    /* start of interlace block */
  932.    PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  933.    /* offset to next interlace block */
  934.    PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  935.    /* start of interlace block in the y direction */
  936.    PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  937.    /* offset to next interlace block in the y direction */
  938.    PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  939.    /* Height of interlace block.  This is not currently used - if you need
  940.     * it, uncomment it here and in png.h
  941.    PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  942.    */
  943. #endif
  944.    png_ptr->row_number++;
  945.    if (png_ptr->row_number < png_ptr->num_rows)
  946.       return;
  947.    if (png_ptr->interlaced)
  948.    {
  949.       png_ptr->row_number = 0;
  950.       png_memset_check(png_ptr, png_ptr->prev_row, 0,
  951.          png_ptr->rowbytes + 1);
  952.       do
  953.       {
  954.          png_ptr->pass++;
  955.          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
  956.              (png_ptr->pass == 3 && png_ptr->width < 3) ||
  957.              (png_ptr->pass == 5 && png_ptr->width < 2))
  958.            png_ptr->pass++;
  959.          if (png_ptr->pass > 7)
  960.             png_ptr->pass--;
  961.          if (png_ptr->pass >= 7)
  962.             break;
  963.          png_ptr->iwidth = (png_ptr->width +
  964.             png_pass_inc[png_ptr->pass] - 1 -
  965.             png_pass_start[png_ptr->pass]) /
  966.             png_pass_inc[png_ptr->pass];
  967.          png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
  968.             png_ptr->iwidth) + 1;
  969.          if (png_ptr->transformations & PNG_INTERLACE)
  970.             break;
  971.          png_ptr->num_rows = (png_ptr->height +
  972.             png_pass_yinc[png_ptr->pass] - 1 -
  973.             png_pass_ystart[png_ptr->pass]) /
  974.             png_pass_yinc[png_ptr->pass];
  975.       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
  976.    }
  977. }
  978. #if defined(PNG_READ_tEXt_SUPPORTED)
  979. void /* PRIVATE */
  980. png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  981.    length)
  982. {
  983.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  984.       {
  985.          png_error(png_ptr, "Out of place tEXt");
  986.          info_ptr = info_ptr; /* to quiet some compiler warnings */
  987.       }
  988. #ifdef PNG_MAX_MALLOC_64K
  989.    png_ptr->skip_length = 0;  /* This may not be necessary */
  990.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  991.    {
  992.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  993.       png_ptr->skip_length = length - (png_uint_32)65535L;
  994.       length = (png_uint_32)65535L;
  995.    }
  996. #endif
  997.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  998.       (png_uint_32)(length + 1));
  999.    png_ptr->current_text[length] = '';
  1000.    png_ptr->current_text_ptr = png_ptr->current_text;
  1001.    png_ptr->current_text_size = (png_size_t)length;
  1002.    png_ptr->current_text_left = (png_size_t)length;
  1003.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  1004. }
  1005. void /* PRIVATE */
  1006. png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  1007. {
  1008.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1009.    {
  1010.       png_size_t text_size;
  1011.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1012.          text_size = png_ptr->buffer_size;
  1013.       else
  1014.          text_size = png_ptr->current_text_left;
  1015.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1016.       png_ptr->current_text_left -= text_size;
  1017.       png_ptr->current_text_ptr += text_size;
  1018.    }
  1019.    if (!(png_ptr->current_text_left))
  1020.    {
  1021.       png_textp text_ptr;
  1022.       png_charp text;
  1023.       png_charp key;
  1024.       int ret;
  1025.       if (png_ptr->buffer_size < 4)
  1026.       {
  1027.          png_push_save_buffer(png_ptr);
  1028.          return;
  1029.       }
  1030.       png_push_crc_finish(png_ptr);
  1031. #if defined(PNG_MAX_MALLOC_64K)
  1032.       if (png_ptr->skip_length)
  1033.          return;
  1034. #endif
  1035.       key = png_ptr->current_text;
  1036.       for (text = key; *text; text++)
  1037.          /* empty loop */ ;
  1038.       if (text < key + png_ptr->current_text_size)
  1039.          text++;
  1040.       text_ptr = (png_textp)png_malloc(png_ptr,
  1041.          (png_uint_32)png_sizeof(png_text));
  1042.       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1043.       text_ptr->key = key;
  1044. #ifdef PNG_iTXt_SUPPORTED
  1045.       text_ptr->lang = NULL;
  1046.       text_ptr->lang_key = NULL;
  1047. #endif
  1048.       text_ptr->text = text;
  1049.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1050.       png_free(png_ptr, key);
  1051.       png_free(png_ptr, text_ptr);
  1052.       png_ptr->current_text = NULL;
  1053.       if (ret)
  1054.         png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1055.    }
  1056. }
  1057. #endif
  1058. #if defined(PNG_READ_zTXt_SUPPORTED)
  1059. void /* PRIVATE */
  1060. png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1061.    length)
  1062. {
  1063.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1064.       {
  1065.          png_error(png_ptr, "Out of place zTXt");
  1066.          info_ptr = info_ptr; /* to quiet some compiler warnings */
  1067.       }
  1068. #ifdef PNG_MAX_MALLOC_64K
  1069.    /* We can't handle zTXt chunks > 64K, since we don't have enough space
  1070.     * to be able to store the uncompressed data.  Actually, the threshold
  1071.     * is probably around 32K, but it isn't as definite as 64K is.
  1072.     */
  1073.    if (length > (png_uint_32)65535L)
  1074.    {
  1075.       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  1076.       png_push_crc_skip(png_ptr, length);
  1077.       return;
  1078.    }
  1079. #endif
  1080.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1081.       (png_uint_32)(length + 1));
  1082.    png_ptr->current_text[length] = '';
  1083.    png_ptr->current_text_ptr = png_ptr->current_text;
  1084.    png_ptr->current_text_size = (png_size_t)length;
  1085.    png_ptr->current_text_left = (png_size_t)length;
  1086.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  1087. }
  1088. void /* PRIVATE */
  1089. png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  1090. {
  1091.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1092.    {
  1093.       png_size_t text_size;
  1094.       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
  1095.          text_size = png_ptr->buffer_size;
  1096.       else
  1097.          text_size = png_ptr->current_text_left;
  1098.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1099.       png_ptr->current_text_left -= text_size;
  1100.       png_ptr->current_text_ptr += text_size;
  1101.    }
  1102.    if (!(png_ptr->current_text_left))
  1103.    {
  1104.       png_textp text_ptr;
  1105.       png_charp text;
  1106.       png_charp key;
  1107.       int ret;
  1108.       png_size_t text_size, key_size;
  1109.       if (png_ptr->buffer_size < 4)
  1110.       {
  1111.          png_push_save_buffer(png_ptr);
  1112.          return;
  1113.       }
  1114.       png_push_crc_finish(png_ptr);
  1115.       key = png_ptr->current_text;
  1116.       for (text = key; *text; text++)
  1117.          /* empty loop */ ;
  1118.       /* zTXt can't have zero text */
  1119.       if (text >= key + png_ptr->current_text_size)
  1120.       {
  1121.          png_ptr->current_text = NULL;
  1122.          png_free(png_ptr, key);
  1123.          return;
  1124.       }
  1125.       text++;
  1126.       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
  1127.       {
  1128.          png_ptr->current_text = NULL;
  1129.          png_free(png_ptr, key);
  1130.          return;
  1131.       }
  1132.       text++;
  1133.       png_ptr->zstream.next_in = (png_bytep )text;
  1134.       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  1135.          (text - key));
  1136.       png_ptr->zstream.next_out = png_ptr->zbuf;
  1137.       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1138.       key_size = text - key;
  1139.       text_size = 0;
  1140.       text = NULL;
  1141.       ret = Z_STREAM_END;
  1142.       while (png_ptr->zstream.avail_in)
  1143.       {
  1144.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1145.          if (ret != Z_OK && ret != Z_STREAM_END)
  1146.          {
  1147.             inflateReset(&png_ptr->zstream);
  1148.             png_ptr->zstream.avail_in = 0;
  1149.             png_ptr->current_text = NULL;
  1150.             png_free(png_ptr, key);
  1151.             png_free(png_ptr, text);
  1152.             return;
  1153.          }
  1154.          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
  1155.          {
  1156.             if (text == NULL)
  1157.             {
  1158.                text = (png_charp)png_malloc(png_ptr,
  1159.                      (png_uint_32)(png_ptr->zbuf_size
  1160.                      - png_ptr->zstream.avail_out + key_size + 1));
  1161.                png_memcpy(text + key_size, png_ptr->zbuf,
  1162.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1163.                png_memcpy(text, key, key_size);
  1164.                text_size = key_size + png_ptr->zbuf_size -
  1165.                   png_ptr->zstream.avail_out;
  1166.                *(text + text_size) = '';
  1167.             }
  1168.             else
  1169.             {
  1170.                png_charp tmp;
  1171.                tmp = text;
  1172.                text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size +
  1173.                   (png_uint_32)(png_ptr->zbuf_size 
  1174.                   - png_ptr->zstream.avail_out + 1));
  1175.                png_memcpy(text, tmp, text_size);
  1176.                png_free(png_ptr, tmp);
  1177.                png_memcpy(text + text_size, png_ptr->zbuf,
  1178.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1179.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  1180.                *(text + text_size) = '';
  1181.             }
  1182.             if (ret != Z_STREAM_END)
  1183.             {
  1184.                png_ptr->zstream.next_out = png_ptr->zbuf;
  1185.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1186.             }
  1187.          }
  1188.          else
  1189.          {
  1190.             break;
  1191.          }
  1192.          if (ret == Z_STREAM_END)
  1193.             break;
  1194.       }
  1195.       inflateReset(&png_ptr->zstream);
  1196.       png_ptr->zstream.avail_in = 0;
  1197.       if (ret != Z_STREAM_END)
  1198.       {
  1199.          png_ptr->current_text = NULL;
  1200.          png_free(png_ptr, key);
  1201.          png_free(png_ptr, text);
  1202.          return;
  1203.       }
  1204.       png_ptr->current_text = NULL;
  1205.       png_free(png_ptr, key);
  1206.       key = text;
  1207.       text += key_size;
  1208.       text_ptr = (png_textp)png_malloc(png_ptr,
  1209.           (png_uint_32)png_sizeof(png_text));
  1210.       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
  1211.       text_ptr->key = key;
  1212. #ifdef PNG_iTXt_SUPPORTED
  1213.       text_ptr->lang = NULL;
  1214.       text_ptr->lang_key = NULL;
  1215. #endif
  1216.       text_ptr->text = text;
  1217.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1218.       png_free(png_ptr, key);
  1219.       png_free(png_ptr, text_ptr);
  1220.       if (ret)
  1221.         png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1222.    }
  1223. }
  1224. #endif
  1225. #if defined(PNG_READ_iTXt_SUPPORTED)
  1226. void /* PRIVATE */
  1227. png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1228.    length)
  1229. {
  1230.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1231.       {
  1232.          png_error(png_ptr, "Out of place iTXt");
  1233.          info_ptr = info_ptr; /* to quiet some compiler warnings */
  1234.       }
  1235. #ifdef PNG_MAX_MALLOC_64K
  1236.    png_ptr->skip_length = 0;  /* This may not be necessary */
  1237.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1238.    {
  1239.       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  1240.       png_ptr->skip_length = length - (png_uint_32)65535L;
  1241.       length = (png_uint_32)65535L;
  1242.    }
  1243. #endif
  1244.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1245.       (png_uint_32)(length + 1));
  1246.    png_ptr->current_text[length] = '';
  1247.    png_ptr->current_text_ptr = png_ptr->current_text;
  1248.    png_ptr->current_text_size = (png_size_t)length;
  1249.    png_ptr->current_text_left = (png_size_t)length;
  1250.    png_ptr->process_mode = PNG_READ_iTXt_MODE;
  1251. }
  1252. void /* PRIVATE */
  1253. png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
  1254. {
  1255.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1256.    {
  1257.       png_size_t text_size;
  1258.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1259.          text_size = png_ptr->buffer_size;
  1260.       else
  1261.          text_size = png_ptr->current_text_left;
  1262.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1263.       png_ptr->current_text_left -= text_size;
  1264.       png_ptr->current_text_ptr += text_size;
  1265.    }
  1266.    if (!(png_ptr->current_text_left))
  1267.    {
  1268.       png_textp text_ptr;
  1269.       png_charp key;
  1270.       int comp_flag;
  1271.       png_charp lang;
  1272.       png_charp lang_key;
  1273.       png_charp text;
  1274.       int ret;
  1275.       if (png_ptr->buffer_size < 4)
  1276.       {
  1277.          png_push_save_buffer(png_ptr);
  1278.          return;
  1279.       }
  1280.       png_push_crc_finish(png_ptr);
  1281. #if defined(PNG_MAX_MALLOC_64K)
  1282.       if (png_ptr->skip_length)
  1283.          return;
  1284. #endif
  1285.       key = png_ptr->current_text;
  1286.       for (lang = key; *lang; lang++)
  1287.          /* empty loop */ ;
  1288.       if (lang < key + png_ptr->current_text_size - 3)
  1289.          lang++;
  1290.       comp_flag = *lang++;
  1291.       lang++;     /* skip comp_type, always zero */
  1292.       for (lang_key = lang; *lang_key; lang_key++)
  1293.          /* empty loop */ ;
  1294.       lang_key++;        /* skip NUL separator */
  1295.       text=lang_key;
  1296.       if (lang_key < key + png_ptr->current_text_size - 1)
  1297.       {
  1298.         for (; *text; text++)
  1299.            /* empty loop */ ;
  1300.       }
  1301.       if (text < key + png_ptr->current_text_size)
  1302.          text++;
  1303.       text_ptr = (png_textp)png_malloc(png_ptr,
  1304.          (png_uint_32)png_sizeof(png_text));
  1305.       text_ptr->compression = comp_flag + 2;
  1306.       text_ptr->key = key;
  1307.       text_ptr->lang = lang;
  1308.       text_ptr->lang_key = lang_key;
  1309.       text_ptr->text = text;
  1310.       text_ptr->text_length = 0;
  1311.       text_ptr->itxt_length = png_strlen(text);
  1312.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1313.       png_ptr->current_text = NULL;
  1314.       png_free(png_ptr, text_ptr);
  1315.       if (ret)
  1316.         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
  1317.    }
  1318. }
  1319. #endif
  1320. /* This function is called when we haven't found a handler for this
  1321.  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
  1322.  * name or a critical chunk), the chunk is (currently) silently ignored.
  1323.  */
  1324. void /* PRIVATE */
  1325. png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1326.    length)
  1327. {
  1328.    png_uint_32 skip = 0;
  1329.    if (!(png_ptr->chunk_name[0] & 0x20))
  1330.    {
  1331. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1332.       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1333.          PNG_HANDLE_CHUNK_ALWAYS
  1334. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1335.          && png_ptr->read_user_chunk_fn == NULL
  1336. #endif
  1337.          )
  1338. #endif
  1339.          png_chunk_error(png_ptr, "unknown critical chunk");
  1340.       info_ptr = info_ptr; /* to quiet some compiler warnings */
  1341.    }
  1342. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1343.    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  1344.    {
  1345. #ifdef PNG_MAX_MALLOC_64K
  1346.       if (length > (png_uint_32)65535L)
  1347.       {
  1348.           png_warning(png_ptr, "unknown chunk too large to fit in memory");
  1349.           skip = length - (png_uint_32)65535L;
  1350.           length = (png_uint_32)65535L;
  1351.       }
  1352. #endif
  1353.       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
  1354.                  (png_charp)png_ptr->chunk_name, 
  1355.                  png_sizeof(png_ptr->unknown_chunk.name));
  1356.       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
  1357.         = '';
  1358.       png_ptr->unknown_chunk.size = (png_size_t)length;
  1359.       if (length == 0)
  1360.          png_ptr->unknown_chunk.data = NULL;
  1361.       else
  1362.       {
  1363.          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
  1364.        (png_uint_32)length);
  1365.          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
  1366.       }
  1367. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1368.       if (png_ptr->read_user_chunk_fn != NULL)
  1369.       {
  1370.          /* callback to user unknown chunk handler */
  1371.          int ret;
  1372.          ret = (*(png_ptr->read_user_chunk_fn))
  1373.            (png_ptr, &png_ptr->unknown_chunk);
  1374.          if (ret < 0)
  1375.             png_chunk_error(png_ptr, "error in user chunk");
  1376.          if (ret == 0)
  1377.          {
  1378.             if (!(png_ptr->chunk_name[0] & 0x20))
  1379.                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1380.                     PNG_HANDLE_CHUNK_ALWAYS)
  1381.                   png_chunk_error(png_ptr, "unknown critical chunk");
  1382.             png_set_unknown_chunks(png_ptr, info_ptr,
  1383.                &png_ptr->unknown_chunk, 1);
  1384.          }
  1385.       }
  1386.       else
  1387. #endif
  1388.         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
  1389.       png_free(png_ptr, png_ptr->unknown_chunk.data);
  1390.       png_ptr->unknown_chunk.data = NULL;
  1391.    }
  1392.    else
  1393. #endif
  1394.       skip=length;
  1395.    png_push_crc_skip(png_ptr, skip);
  1396. }
  1397. void /* PRIVATE */
  1398. png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1399. {
  1400.    if (png_ptr->info_fn != NULL)
  1401.       (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1402. }
  1403. void /* PRIVATE */
  1404. png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1405. {
  1406.    if (png_ptr->end_fn != NULL)
  1407.       (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1408. }
  1409. void /* PRIVATE */
  1410. png_push_have_row(png_structp png_ptr, png_bytep row)
  1411. {
  1412.    if (png_ptr->row_fn != NULL)
  1413.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1414.          (int)png_ptr->pass);
  1415. }
  1416. void PNGAPI
  1417. png_progressive_combine_row (png_structp png_ptr,
  1418.    png_bytep old_row, png_bytep new_row)
  1419. {
  1420. #ifdef PNG_USE_LOCAL_ARRAYS
  1421.    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
  1422.       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
  1423. #endif
  1424.    if (png_ptr == NULL) return;
  1425.    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
  1426.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1427. }
  1428. void PNGAPI
  1429. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1430.    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1431.    png_progressive_end_ptr end_fn)
  1432. {
  1433.    if (png_ptr == NULL) return;
  1434.    png_ptr->info_fn = info_fn;
  1435.    png_ptr->row_fn = row_fn;
  1436.    png_ptr->end_fn = end_fn;
  1437.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1438. }
  1439. png_voidp PNGAPI
  1440. png_get_progressive_ptr(png_structp png_ptr)
  1441. {
  1442.    if (png_ptr == NULL) return (NULL);
  1443.    return png_ptr->io_ptr;
  1444. }
  1445. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */