home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / png / pngpread.c < prev    next >
C/C++ Source or Header  |  2002-07-09  |  46KB  |  1,535 lines

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