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

打印编程

开发平台:

Visual C++

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