home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / png / pngpread.c < prev    next >
C/C++ Source or Header  |  2002-10-08  |  46KB  |  1,544 lines

  1.  
  2. /* pngpread.c - read a png file in push mode
  3.  *
  4.  * libpng 1.2.5rc3 - September 18, 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.       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  672.          png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  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.       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  694.         png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  695.  
  696.       png_ptr->idat_size -= save_size;
  697.       png_ptr->buffer_size -= save_size;
  698.       png_ptr->current_buffer_size -= save_size;
  699.       png_ptr->current_buffer_ptr += save_size;
  700.    }
  701.    if (!png_ptr->idat_size)
  702.    {
  703.       if (png_ptr->buffer_size < 4)
  704.       {
  705.          png_push_save_buffer(png_ptr);
  706.          return;
  707.       }
  708.  
  709.       png_crc_finish(png_ptr, 0);
  710.       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  711.       png_ptr->mode |= PNG_AFTER_IDAT;
  712.    }
  713. }
  714.  
  715. void /* PRIVATE */
  716. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  717.    png_size_t buffer_length)
  718. {
  719.    int ret;
  720.  
  721.    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
  722.       png_error(png_ptr, "Extra compression data");
  723.  
  724.    png_ptr->zstream.next_in = buffer;
  725.    png_ptr->zstream.avail_in = (uInt)buffer_length;
  726.    for(;;)
  727.    {
  728.       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  729.       if (ret != Z_OK)
  730.       {
  731.          if (ret == Z_STREAM_END)
  732.          {
  733.             if (png_ptr->zstream.avail_in)
  734.                png_error(png_ptr, "Extra compressed data");
  735.             if (!(png_ptr->zstream.avail_out))
  736.             {
  737.                png_push_process_row(png_ptr);
  738.             }
  739.  
  740.             png_ptr->mode |= PNG_AFTER_IDAT;
  741.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  742.             break;
  743.          }
  744.          else if (ret == Z_BUF_ERROR)
  745.             break;
  746.          else
  747.             png_error(png_ptr, "Decompression Error");
  748.       }
  749.       if (!(png_ptr->zstream.avail_out))
  750.       {
  751.          if ((
  752. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  753.              png_ptr->interlaced && png_ptr->pass > 6) ||
  754.              (!png_ptr->interlaced &&
  755. #endif
  756.              png_ptr->row_number == png_ptr->num_rows-1))
  757.          {
  758.            if (png_ptr->zstream.avail_in)
  759.              png_warning(png_ptr, "Too much data in IDAT chunks");
  760.            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  761.            break;
  762.          }
  763.          png_push_process_row(png_ptr);
  764.          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  765.          png_ptr->zstream.next_out = png_ptr->row_buf;
  766.       }
  767.       else
  768.          break;
  769.    }
  770. }
  771.  
  772. void /* PRIVATE */
  773. png_push_process_row(png_structp png_ptr)
  774. {
  775.    png_ptr->row_info.color_type = png_ptr->color_type;
  776.    png_ptr->row_info.width = png_ptr->iwidth;
  777.    png_ptr->row_info.channels = png_ptr->channels;
  778.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  779.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  780.  
  781.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  782.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  783.  
  784.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  785.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  786.       (int)(png_ptr->row_buf[0]));
  787.  
  788.    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
  789.       png_ptr->rowbytes + 1);
  790.  
  791.    if (png_ptr->transformations)
  792.       png_do_read_transformations(png_ptr);
  793.  
  794. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  795.    /* blow up interlaced rows to full size */
  796.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  797.    {
  798.       if (png_ptr->pass < 6)
  799. /*       old interface (pre-1.0.9):
  800.          png_do_read_interlace(&(png_ptr->row_info),
  801.             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
  802.  */
  803.          png_do_read_interlace(png_ptr);
  804.  
  805.     switch (png_ptr->pass)
  806.     {
  807.          case 0:
  808.          {
  809.             int i;
  810.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  811.             {
  812.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  813.                png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
  814.             }
  815.             if (png_ptr->pass == 2) /* pass 1 might be empty */
  816.             {
  817.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  818.                {
  819.                   png_push_have_row(png_ptr, png_bytep_NULL);
  820.                   png_read_push_finish_row(png_ptr);
  821.                }
  822.             }
  823.             if (png_ptr->pass == 4 && png_ptr->height <= 4)
  824.             {
  825.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  826.                {
  827.                   png_push_have_row(png_ptr, png_bytep_NULL);
  828.                   png_read_push_finish_row(png_ptr);
  829.                }
  830.             }
  831.             if (png_ptr->pass == 6 && png_ptr->height <= 4)
  832.             {
  833.                 png_push_have_row(png_ptr, png_bytep_NULL);
  834.                 png_read_push_finish_row(png_ptr);
  835.             }
  836.             break;
  837.          }
  838.          case 1:
  839.          {
  840.             int i;
  841.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  842.             {
  843.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  844.                png_read_push_finish_row(png_ptr);
  845.             }
  846.             if (png_ptr->pass == 2) /* skip top 4 generated rows */
  847.             {
  848.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  849.                {
  850.                   png_push_have_row(png_ptr, png_bytep_NULL);
  851.                   png_read_push_finish_row(png_ptr);
  852.                }
  853.             }
  854.             break;
  855.          }
  856.          case 2:
  857.          {
  858.             int i;
  859.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  860.             {
  861.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  862.                png_read_push_finish_row(png_ptr);
  863.             }
  864.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  865.             {
  866.                png_push_have_row(png_ptr, png_bytep_NULL);
  867.                png_read_push_finish_row(png_ptr);
  868.             }
  869.             if (png_ptr->pass == 4) /* pass 3 might be empty */
  870.             {
  871.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  872.                {
  873.                   png_push_have_row(png_ptr, png_bytep_NULL);
  874.                   png_read_push_finish_row(png_ptr);
  875.                }
  876.             }
  877.             break;
  878.          }
  879.          case 3:
  880.          {
  881.             int i;
  882.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  883.             {
  884.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  885.                png_read_push_finish_row(png_ptr);
  886.             }
  887.             if (png_ptr->pass == 4) /* skip top two generated rows */
  888.             {
  889.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  890.                {
  891.                   png_push_have_row(png_ptr, png_bytep_NULL);
  892.                   png_read_push_finish_row(png_ptr);
  893.                }
  894.             }
  895.             break;
  896.          }
  897.          case 4:
  898.          {
  899.             int i;
  900.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  901.             {
  902.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  903.                png_read_push_finish_row(png_ptr);
  904.             }
  905.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  906.             {
  907.                png_push_have_row(png_ptr, png_bytep_NULL);
  908.                png_read_push_finish_row(png_ptr);
  909.             }
  910.             if (png_ptr->pass == 6) /* pass 5 might be empty */
  911.             {
  912.                png_push_have_row(png_ptr, png_bytep_NULL);
  913.                png_read_push_finish_row(png_ptr);
  914.             }
  915.             break;
  916.          }
  917.          case 5:
  918.          {
  919.             int i;
  920.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  921.             {
  922.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  923.                png_read_push_finish_row(png_ptr);
  924.             }
  925.             if (png_ptr->pass == 6) /* skip top generated row */
  926.             {
  927.                png_push_have_row(png_ptr, png_bytep_NULL);
  928.                png_read_push_finish_row(png_ptr);
  929.             }
  930.             break;
  931.          }
  932.          case 6:
  933.          {
  934.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  935.             png_read_push_finish_row(png_ptr);
  936.             if (png_ptr->pass != 6)
  937.                break;
  938.             png_push_have_row(png_ptr, png_bytep_NULL);
  939.             png_read_push_finish_row(png_ptr);
  940.          }
  941.       }
  942.    }
  943.    else
  944. #endif
  945.    {
  946.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  947.       png_read_push_finish_row(png_ptr);
  948.    }
  949. }
  950.  
  951. void /* PRIVATE */
  952. png_read_push_finish_row(png_structp png_ptr)
  953. {
  954. #ifdef PNG_USE_LOCAL_ARRAYS
  955.    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  956.  
  957.    /* start of interlace block */
  958.    const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  959.  
  960.    /* offset to next interlace block */
  961.    const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  962.  
  963.    /* start of interlace block in the y direction */
  964.    const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  965.  
  966.    /* offset to next interlace block in the y direction */
  967.    const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  968.  
  969.    /* Width of interlace block.  This is not currently used - if you need
  970.     * it, uncomment it here and in png.h
  971.    const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
  972.    */
  973.  
  974.    /* Height of interlace block.  This is not currently used - if you need
  975.     * it, uncomment it here and in png.h
  976.    const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  977.    */
  978. #endif
  979.  
  980.    png_ptr->row_number++;
  981.    if (png_ptr->row_number < png_ptr->num_rows)
  982.       return;
  983.  
  984.    if (png_ptr->interlaced)
  985.    {
  986.       png_ptr->row_number = 0;
  987.       png_memset_check(png_ptr, png_ptr->prev_row, 0,
  988.          png_ptr->rowbytes + 1);
  989.       do
  990.       {
  991.          png_ptr->pass++;
  992.          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
  993.              (png_ptr->pass == 3 && png_ptr->width < 3) ||
  994.              (png_ptr->pass == 5 && png_ptr->width < 2))
  995.            png_ptr->pass++;
  996.  
  997.          if (png_ptr->pass > 7)
  998.             png_ptr->pass--;
  999.          if (png_ptr->pass >= 7)
  1000.             break;
  1001.  
  1002.          png_ptr->iwidth = (png_ptr->width +
  1003.             png_pass_inc[png_ptr->pass] - 1 -
  1004.             png_pass_start[png_ptr->pass]) /
  1005.             png_pass_inc[png_ptr->pass];
  1006.  
  1007.          png_ptr->irowbytes = ((png_ptr->iwidth *
  1008.             png_ptr->pixel_depth + 7) >> 3) + 1;
  1009.  
  1010.          if (png_ptr->transformations & PNG_INTERLACE)
  1011.             break;
  1012.  
  1013.          png_ptr->num_rows = (png_ptr->height +
  1014.             png_pass_yinc[png_ptr->pass] - 1 -
  1015.             png_pass_ystart[png_ptr->pass]) /
  1016.             png_pass_yinc[png_ptr->pass];
  1017.  
  1018.       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
  1019.    }
  1020. }
  1021.  
  1022. #if defined(PNG_READ_tEXt_SUPPORTED)
  1023. void /* PRIVATE */
  1024. png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1025.    length)
  1026. {
  1027.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1028.       {
  1029.          png_error(png_ptr, "Out of place tEXt");
  1030.          /* to quiet some compiler warnings */
  1031.          if(info_ptr == NULL) return;
  1032.       }
  1033.  
  1034. #ifdef PNG_MAX_MALLOC_64K
  1035.    png_ptr->skip_length = 0;  /* This may not be necessary */
  1036.  
  1037.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1038.    {
  1039.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1040.       png_ptr->skip_length = length - (png_uint_32)65535L;
  1041.       length = (png_uint_32)65535L;
  1042.    }
  1043. #endif
  1044.  
  1045.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1046.          (png_uint_32)(length+1));
  1047.    png_ptr->current_text[length] = '\0';
  1048.    png_ptr->current_text_ptr = png_ptr->current_text;
  1049.    png_ptr->current_text_size = (png_size_t)length;
  1050.    png_ptr->current_text_left = (png_size_t)length;
  1051.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  1052. }
  1053.  
  1054. void /* PRIVATE */
  1055. png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  1056. {
  1057.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1058.    {
  1059.       png_size_t text_size;
  1060.  
  1061.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1062.          text_size = png_ptr->buffer_size;
  1063.       else
  1064.          text_size = png_ptr->current_text_left;
  1065.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1066.       png_ptr->current_text_left -= text_size;
  1067.       png_ptr->current_text_ptr += text_size;
  1068.    }
  1069.    if (!(png_ptr->current_text_left))
  1070.    {
  1071.       png_textp text_ptr;
  1072.       png_charp text;
  1073.       png_charp key;
  1074.       int ret;
  1075.  
  1076.       if (png_ptr->buffer_size < 4)
  1077.       {
  1078.          png_push_save_buffer(png_ptr);
  1079.          return;
  1080.       }
  1081.  
  1082.       png_push_crc_finish(png_ptr);
  1083.  
  1084. #if defined(PNG_MAX_MALLOC_64K)
  1085.       if (png_ptr->skip_length)
  1086.          return;
  1087. #endif
  1088.  
  1089.       key = png_ptr->current_text;
  1090.  
  1091.       for (text = key; *text; text++)
  1092.          /* empty loop */ ;
  1093.  
  1094.       if (text != key + png_ptr->current_text_size)
  1095.          text++;
  1096.  
  1097.       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  1098.       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1099.       text_ptr->key = key;
  1100. #ifdef PNG_iTXt_SUPPORTED
  1101.       text_ptr->lang = NULL;
  1102.       text_ptr->lang_key = NULL;
  1103. #endif
  1104.       text_ptr->text = text;
  1105.  
  1106.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1107.  
  1108.       png_free(png_ptr, key);
  1109.       png_free(png_ptr, text_ptr);
  1110.       png_ptr->current_text = NULL;
  1111.  
  1112.       if (ret)
  1113.         png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1114.    }
  1115. }
  1116. #endif
  1117.  
  1118. #if defined(PNG_READ_zTXt_SUPPORTED)
  1119. void /* PRIVATE */
  1120. png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1121.    length)
  1122. {
  1123.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1124.       {
  1125.          png_error(png_ptr, "Out of place zTXt");
  1126.          /* to quiet some compiler warnings */
  1127.          if(info_ptr == NULL) return;
  1128.       }
  1129.  
  1130. #ifdef PNG_MAX_MALLOC_64K
  1131.    /* We can't handle zTXt chunks > 64K, since we don't have enough space
  1132.     * to be able to store the uncompressed data.  Actually, the threshold
  1133.     * is probably around 32K, but it isn't as definite as 64K is.
  1134.     */
  1135.    if (length > (png_uint_32)65535L)
  1136.    {
  1137.       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  1138.       png_push_crc_skip(png_ptr, length);
  1139.       return;
  1140.    }
  1141. #endif
  1142.  
  1143.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1144.        (png_uint_32)(length+1));
  1145.    png_ptr->current_text[length] = '\0';
  1146.    png_ptr->current_text_ptr = png_ptr->current_text;
  1147.    png_ptr->current_text_size = (png_size_t)length;
  1148.    png_ptr->current_text_left = (png_size_t)length;
  1149.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  1150. }
  1151.  
  1152. void /* PRIVATE */
  1153. png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  1154. {
  1155.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1156.    {
  1157.       png_size_t text_size;
  1158.  
  1159.       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
  1160.          text_size = png_ptr->buffer_size;
  1161.       else
  1162.          text_size = png_ptr->current_text_left;
  1163.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1164.       png_ptr->current_text_left -= text_size;
  1165.       png_ptr->current_text_ptr += text_size;
  1166.    }
  1167.    if (!(png_ptr->current_text_left))
  1168.    {
  1169.       png_textp text_ptr;
  1170.       png_charp text;
  1171.       png_charp key;
  1172.       int ret;
  1173.       png_size_t text_size, key_size;
  1174.  
  1175.       if (png_ptr->buffer_size < 4)
  1176.       {
  1177.          png_push_save_buffer(png_ptr);
  1178.          return;
  1179.       }
  1180.  
  1181.       png_push_crc_finish(png_ptr);
  1182.  
  1183.       key = png_ptr->current_text;
  1184.  
  1185.       for (text = key; *text; text++)
  1186.          /* empty loop */ ;
  1187.  
  1188.       /* zTXt can't have zero text */
  1189.       if (text == key + png_ptr->current_text_size)
  1190.       {
  1191.          png_ptr->current_text = NULL;
  1192.          png_free(png_ptr, key);
  1193.          return;
  1194.       }
  1195.  
  1196.       text++;
  1197.  
  1198.       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
  1199.       {
  1200.          png_ptr->current_text = NULL;
  1201.          png_free(png_ptr, key);
  1202.          return;
  1203.       }
  1204.  
  1205.       text++;
  1206.  
  1207.       png_ptr->zstream.next_in = (png_bytep )text;
  1208.       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  1209.          (text - key));
  1210.       png_ptr->zstream.next_out = png_ptr->zbuf;
  1211.       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1212.  
  1213.       key_size = text - key;
  1214.       text_size = 0;
  1215.       text = NULL;
  1216.       ret = Z_STREAM_END;
  1217.  
  1218.       while (png_ptr->zstream.avail_in)
  1219.       {
  1220.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1221.          if (ret != Z_OK && ret != Z_STREAM_END)
  1222.          {
  1223.             inflateReset(&png_ptr->zstream);
  1224.             png_ptr->zstream.avail_in = 0;
  1225.             png_ptr->current_text = NULL;
  1226.             png_free(png_ptr, key);
  1227.             png_free(png_ptr, text);
  1228.             return;
  1229.          }
  1230.          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
  1231.          {
  1232.             if (text == NULL)
  1233.             {
  1234.                text = (png_charp)png_malloc(png_ptr,
  1235.                   (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
  1236.                      + key_size + 1));
  1237.                png_memcpy(text + key_size, png_ptr->zbuf,
  1238.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1239.                png_memcpy(text, key, key_size);
  1240.                text_size = key_size + png_ptr->zbuf_size -
  1241.                   png_ptr->zstream.avail_out;
  1242.                *(text + text_size) = '\0';
  1243.             }
  1244.             else
  1245.             {
  1246.                png_charp tmp;
  1247.  
  1248.                tmp = text;
  1249.                text = (png_charp)png_malloc(png_ptr, text_size +
  1250.                   (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
  1251.                    + 1));
  1252.                png_memcpy(text, tmp, text_size);
  1253.                png_free(png_ptr, tmp);
  1254.                png_memcpy(text + text_size, png_ptr->zbuf,
  1255.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1256.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  1257.                *(text + text_size) = '\0';
  1258.             }
  1259.             if (ret != Z_STREAM_END)
  1260.             {
  1261.                png_ptr->zstream.next_out = png_ptr->zbuf;
  1262.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1263.             }
  1264.          }
  1265.          else
  1266.          {
  1267.             break;
  1268.          }
  1269.  
  1270.          if (ret == Z_STREAM_END)
  1271.             break;
  1272.       }
  1273.  
  1274.       inflateReset(&png_ptr->zstream);
  1275.       png_ptr->zstream.avail_in = 0;
  1276.  
  1277.       if (ret != Z_STREAM_END)
  1278.       {
  1279.          png_ptr->current_text = NULL;
  1280.          png_free(png_ptr, key);
  1281.          png_free(png_ptr, text);
  1282.          return;
  1283.       }
  1284.  
  1285.       png_ptr->current_text = NULL;
  1286.       png_free(png_ptr, key);
  1287.       key = text;
  1288.       text += key_size;
  1289.  
  1290.       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  1291.       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
  1292.       text_ptr->key = key;
  1293. #ifdef PNG_iTXt_SUPPORTED
  1294.       text_ptr->lang = NULL;
  1295.       text_ptr->lang_key = NULL;
  1296. #endif
  1297.       text_ptr->text = text;
  1298.  
  1299.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1300.  
  1301.       png_free(png_ptr, key);
  1302.       png_free(png_ptr, text_ptr);
  1303.  
  1304.       if (ret)
  1305.         png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1306.    }
  1307. }
  1308. #endif
  1309.  
  1310. #if defined(PNG_READ_iTXt_SUPPORTED)
  1311. void /* PRIVATE */
  1312. png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1313.    length)
  1314. {
  1315.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1316.       {
  1317.          png_error(png_ptr, "Out of place iTXt");
  1318.          /* to quiet some compiler warnings */
  1319.          if(info_ptr == NULL) return;
  1320.       }
  1321.  
  1322. #ifdef PNG_MAX_MALLOC_64K
  1323.    png_ptr->skip_length = 0;  /* This may not be necessary */
  1324.  
  1325.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1326.    {
  1327.       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  1328.       png_ptr->skip_length = length - (png_uint_32)65535L;
  1329.       length = (png_uint_32)65535L;
  1330.    }
  1331. #endif
  1332.  
  1333.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1334.          (png_uint_32)(length+1));
  1335.    png_ptr->current_text[length] = '\0';
  1336.    png_ptr->current_text_ptr = png_ptr->current_text;
  1337.    png_ptr->current_text_size = (png_size_t)length;
  1338.    png_ptr->current_text_left = (png_size_t)length;
  1339.    png_ptr->process_mode = PNG_READ_iTXt_MODE;
  1340. }
  1341.  
  1342. void /* PRIVATE */
  1343. png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
  1344. {
  1345.  
  1346.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1347.    {
  1348.       png_size_t text_size;
  1349.  
  1350.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1351.          text_size = png_ptr->buffer_size;
  1352.       else
  1353.          text_size = png_ptr->current_text_left;
  1354.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1355.       png_ptr->current_text_left -= text_size;
  1356.       png_ptr->current_text_ptr += text_size;
  1357.    }
  1358.    if (!(png_ptr->current_text_left))
  1359.    {
  1360.       png_textp text_ptr;
  1361.       png_charp key;
  1362.       int comp_flag;
  1363.       png_charp lang;
  1364.       png_charp lang_key;
  1365.       png_charp text;
  1366.       int ret;
  1367.  
  1368.       if (png_ptr->buffer_size < 4)
  1369.       {
  1370.          png_push_save_buffer(png_ptr);
  1371.          return;
  1372.       }
  1373.  
  1374.       png_push_crc_finish(png_ptr);
  1375.  
  1376. #if defined(PNG_MAX_MALLOC_64K)
  1377.       if (png_ptr->skip_length)
  1378.          return;
  1379. #endif
  1380.  
  1381.       key = png_ptr->current_text;
  1382.  
  1383.       for (lang = key; *lang; lang++)
  1384.          /* empty loop */ ;
  1385.  
  1386.       if (lang != key + png_ptr->current_text_size)
  1387.          lang++;
  1388.  
  1389.       comp_flag = *lang++;
  1390.       lang++;     /* skip comp_type, always zero */
  1391.  
  1392.       for (lang_key = lang; *lang_key; lang_key++)
  1393.          /* empty loop */ ;
  1394.       lang_key++;        /* skip NUL separator */
  1395.  
  1396.       for (text = lang_key; *text; text++)
  1397.          /* empty loop */ ;
  1398.  
  1399.       if (text != key + png_ptr->current_text_size)
  1400.          text++;
  1401.  
  1402.       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  1403.       text_ptr->compression = comp_flag + 2;
  1404.       text_ptr->key = key;
  1405.       text_ptr->lang = lang;
  1406.       text_ptr->lang_key = lang_key;
  1407.       text_ptr->text = text;
  1408.       text_ptr->text_length = 0;
  1409.       text_ptr->itxt_length = png_strlen(text);
  1410.  
  1411.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1412.  
  1413.       png_ptr->current_text = NULL;
  1414.  
  1415.       png_free(png_ptr, text_ptr);
  1416.       if (ret)
  1417.         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
  1418.    }
  1419. }
  1420. #endif
  1421.  
  1422. /* This function is called when we haven't found a handler for this
  1423.  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
  1424.  * name or a critical chunk), the chunk is (currently) silently ignored.
  1425.  */
  1426. void /* PRIVATE */
  1427. png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1428.    length)
  1429. {
  1430.    png_uint_32 skip=0;
  1431.    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  1432.  
  1433.    if (!(png_ptr->chunk_name[0] & 0x20))
  1434.    {
  1435. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1436.       if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1437.            HANDLE_CHUNK_ALWAYS
  1438. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1439.            && png_ptr->read_user_chunk_fn == NULL
  1440. #endif
  1441.          )
  1442. #endif
  1443.          png_chunk_error(png_ptr, "unknown critical chunk");
  1444.  
  1445.       /* to quiet compiler warnings about unused info_ptr */
  1446.       if (info_ptr == NULL)
  1447.          return;
  1448.    }
  1449.  
  1450. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1451.    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  1452.    {
  1453.        png_unknown_chunk chunk;
  1454.  
  1455. #ifdef PNG_MAX_MALLOC_64K
  1456.        if (length > (png_uint_32)65535L)
  1457.        {
  1458.            png_warning(png_ptr, "unknown chunk too large to fit in memory");
  1459.            skip = length - (png_uint_32)65535L;
  1460.            length = (png_uint_32)65535L;
  1461.        }
  1462. #endif
  1463.  
  1464.        png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
  1465.        chunk.data = (png_bytep)png_malloc(png_ptr, length);
  1466.        png_crc_read(png_ptr, chunk.data, length);
  1467.        chunk.size = length;
  1468. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1469.        if(png_ptr->read_user_chunk_fn != NULL)
  1470.        {
  1471.           /* callback to user unknown chunk handler */
  1472.           if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
  1473.           {
  1474.              if (!(png_ptr->chunk_name[0] & 0x20))
  1475.                 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1476.                      HANDLE_CHUNK_ALWAYS)
  1477.                    png_chunk_error(png_ptr, "unknown critical chunk");
  1478.           }
  1479.              png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
  1480.        }
  1481.        else
  1482. #endif
  1483.           png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
  1484.        png_free(png_ptr, chunk.data);
  1485.    }
  1486.    else
  1487. #endif
  1488.       skip=length;
  1489.    png_push_crc_skip(png_ptr, skip);
  1490. }
  1491.  
  1492. void /* PRIVATE */
  1493. png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1494. {
  1495.    if (png_ptr->info_fn != NULL)
  1496.       (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1497. }
  1498.  
  1499. void /* PRIVATE */
  1500. png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1501. {
  1502.    if (png_ptr->end_fn != NULL)
  1503.       (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1504. }
  1505.  
  1506. void /* PRIVATE */
  1507. png_push_have_row(png_structp png_ptr, png_bytep row)
  1508. {
  1509.    if (png_ptr->row_fn != NULL)
  1510.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1511.          (int)png_ptr->pass);
  1512. }
  1513.  
  1514. void PNGAPI
  1515. png_progressive_combine_row (png_structp png_ptr,
  1516.    png_bytep old_row, png_bytep new_row)
  1517. {
  1518. #ifdef PNG_USE_LOCAL_ARRAYS
  1519.    const int FARDATA png_pass_dsp_mask[7] =
  1520.       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
  1521. #endif
  1522.    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
  1523.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1524. }
  1525.  
  1526. void PNGAPI
  1527. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1528.    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1529.    png_progressive_end_ptr end_fn)
  1530. {
  1531.    png_ptr->info_fn = info_fn;
  1532.    png_ptr->row_fn = row_fn;
  1533.    png_ptr->end_fn = end_fn;
  1534.  
  1535.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1536. }
  1537.  
  1538. png_voidp PNGAPI
  1539. png_get_progressive_ptr(png_structp png_ptr)
  1540. {
  1541.    return png_ptr->io_ptr;
  1542. }
  1543. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1544.