Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. /* pngpread.c - read a png file in push mode
  3.  *
  4.  * Last changed in libpng 1.5.1 [February 3, 2011]
  5.  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
  6.  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  7.  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  8.  *
  9.  * This code is released under the libpng license.
  10.  * For conditions of distribution and use, see the disclaimer
  11.  * and license in png.h
  12.  */
  13.  
  14. #include "pngpriv.h"
  15.  
  16. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  17.  
  18. /* Push model modes */
  19. #define PNG_READ_SIG_MODE   0
  20. #define PNG_READ_CHUNK_MODE 1
  21. #define PNG_READ_IDAT_MODE  2
  22. #define PNG_SKIP_MODE       3
  23. #define PNG_READ_tEXt_MODE  4
  24. #define PNG_READ_zTXt_MODE  5
  25. #define PNG_READ_DONE_MODE  6
  26. #define PNG_READ_iTXt_MODE  7
  27. #define PNG_ERROR_MODE      8
  28.  
  29. void PNGAPI
  30. png_process_data(png_structp png_ptr, png_infop info_ptr,
  31.     png_bytep buffer, png_size_t buffer_size)
  32. {
  33.    if (png_ptr == NULL || info_ptr == NULL)
  34.       return;
  35.  
  36.    png_push_restore_buffer(png_ptr, buffer, buffer_size);
  37.  
  38.    while (png_ptr->buffer_size)
  39.    {
  40.       png_process_some_data(png_ptr, info_ptr);
  41.    }
  42. }
  43.  
  44. png_size_t PNGAPI
  45. png_process_data_pause(png_structp png_ptr, int save)
  46. {
  47.    if (png_ptr != NULL)
  48.    {
  49.       /* It's easiest for the caller if we do the save, then the caller doesn't
  50.        * have to supply the same data again:
  51.        */
  52.       if (save)
  53.          png_push_save_buffer(png_ptr);
  54.       else
  55.       {
  56.          /* This includes any pending saved bytes: */
  57.          png_size_t remaining = png_ptr->buffer_size;
  58.          png_ptr->buffer_size = 0;
  59.  
  60.          /* So subtract the saved buffer size, unless all the data
  61.           * is actually 'saved', in which case we just return 0
  62.           */
  63.          if (png_ptr->save_buffer_size < remaining)
  64.             return remaining - png_ptr->save_buffer_size;
  65.       }
  66.    }
  67.  
  68.    return 0;
  69. }
  70.  
  71. png_uint_32 PNGAPI
  72. png_process_data_skip(png_structp png_ptr)
  73. {
  74.    png_uint_32 remaining = 0;
  75.  
  76.    if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
  77.       png_ptr->skip_length > 0)
  78.    {
  79.       /* At the end of png_process_data the buffer size must be 0 (see the loop
  80.        * above) so we can detect a broken call here:
  81.        */
  82.       if (png_ptr->buffer_size != 0)
  83.          png_error(png_ptr,
  84.             "png_process_data_skip called inside png_process_data");
  85.  
  86.       /* If is impossible for there to be a saved buffer at this point -
  87.        * otherwise we could not be in SKIP mode.  This will also happen if
  88.        * png_process_skip is called inside png_process_data (but only very
  89.        * rarely.)
  90.        */
  91.       if (png_ptr->save_buffer_size != 0)
  92.          png_error(png_ptr, "png_process_data_skip called with saved data");
  93.  
  94.       remaining = png_ptr->skip_length;
  95.       png_ptr->skip_length = 0;
  96.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  97.    }
  98.  
  99.    return remaining;
  100. }
  101.  
  102. /* What we do with the incoming data depends on what we were previously
  103.  * doing before we ran out of data...
  104.  */
  105. void /* PRIVATE */
  106. png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  107. {
  108.    if (png_ptr == NULL)
  109.       return;
  110.  
  111.    switch (png_ptr->process_mode)
  112.    {
  113.       case PNG_READ_SIG_MODE:
  114.       {
  115.          png_push_read_sig(png_ptr, info_ptr);
  116.          break;
  117.       }
  118.  
  119.       case PNG_READ_CHUNK_MODE:
  120.       {
  121.          png_push_read_chunk(png_ptr, info_ptr);
  122.          break;
  123.       }
  124.  
  125.       case PNG_READ_IDAT_MODE:
  126.       {
  127.          png_push_read_IDAT(png_ptr);
  128.          break;
  129.       }
  130.  
  131. #ifdef PNG_READ_tEXt_SUPPORTED
  132.       case PNG_READ_tEXt_MODE:
  133.       {
  134.          png_push_read_tEXt(png_ptr, info_ptr);
  135.          break;
  136.       }
  137.  
  138. #endif
  139. #ifdef PNG_READ_zTXt_SUPPORTED
  140.       case PNG_READ_zTXt_MODE:
  141.       {
  142.          png_push_read_zTXt(png_ptr, info_ptr);
  143.          break;
  144.       }
  145.  
  146. #endif
  147. #ifdef PNG_READ_iTXt_SUPPORTED
  148.       case PNG_READ_iTXt_MODE:
  149.       {
  150.          png_push_read_iTXt(png_ptr, info_ptr);
  151.          break;
  152.       }
  153.  
  154. #endif
  155.       case PNG_SKIP_MODE:
  156.       {
  157.          png_push_crc_finish(png_ptr);
  158.          break;
  159.       }
  160.  
  161.       default:
  162.       {
  163.          png_ptr->buffer_size = 0;
  164.          break;
  165.       }
  166.    }
  167. }
  168.  
  169. /* Read any remaining signature bytes from the stream and compare them with
  170.  * the correct PNG signature.  It is possible that this routine is called
  171.  * with bytes already read from the signature, either because they have been
  172.  * checked by the calling application, or because of multiple calls to this
  173.  * routine.
  174.  */
  175. void /* PRIVATE */
  176. png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
  177. {
  178.    png_size_t num_checked = png_ptr->sig_bytes,
  179.              num_to_check = 8 - num_checked;
  180.  
  181.    if (png_ptr->buffer_size < num_to_check)
  182.    {
  183.       num_to_check = png_ptr->buffer_size;
  184.    }
  185.  
  186.    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
  187.        num_to_check);
  188.    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
  189.  
  190.    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
  191.    {
  192.       if (num_checked < 4 &&
  193.           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
  194.          png_error(png_ptr, "Not a PNG file");
  195.  
  196.       else
  197.          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
  198.    }
  199.    else
  200.    {
  201.       if (png_ptr->sig_bytes >= 8)
  202.       {
  203.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  204.       }
  205.    }
  206. }
  207.  
  208. void /* PRIVATE */
  209. png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
  210. {
  211.       PNG_IHDR;
  212.       PNG_IDAT;
  213.       PNG_IEND;
  214.       PNG_PLTE;
  215. #ifdef PNG_READ_bKGD_SUPPORTED
  216.       PNG_bKGD;
  217. #endif
  218. #ifdef PNG_READ_cHRM_SUPPORTED
  219.       PNG_cHRM;
  220. #endif
  221. #ifdef PNG_READ_gAMA_SUPPORTED
  222.       PNG_gAMA;
  223. #endif
  224. #ifdef PNG_READ_hIST_SUPPORTED
  225.       PNG_hIST;
  226. #endif
  227. #ifdef PNG_READ_iCCP_SUPPORTED
  228.       PNG_iCCP;
  229. #endif
  230. #ifdef PNG_READ_iTXt_SUPPORTED
  231.       PNG_iTXt;
  232. #endif
  233. #ifdef PNG_READ_oFFs_SUPPORTED
  234.       PNG_oFFs;
  235. #endif
  236. #ifdef PNG_READ_pCAL_SUPPORTED
  237.       PNG_pCAL;
  238. #endif
  239. #ifdef PNG_READ_pHYs_SUPPORTED
  240.       PNG_pHYs;
  241. #endif
  242. #ifdef PNG_READ_sBIT_SUPPORTED
  243.       PNG_sBIT;
  244. #endif
  245. #ifdef PNG_READ_sCAL_SUPPORTED
  246.       PNG_sCAL;
  247. #endif
  248. #ifdef PNG_READ_sRGB_SUPPORTED
  249.       PNG_sRGB;
  250. #endif
  251. #ifdef PNG_READ_sPLT_SUPPORTED
  252.       PNG_sPLT;
  253. #endif
  254. #ifdef PNG_READ_tEXt_SUPPORTED
  255.       PNG_tEXt;
  256. #endif
  257. #ifdef PNG_READ_tIME_SUPPORTED
  258.       PNG_tIME;
  259. #endif
  260. #ifdef PNG_READ_tRNS_SUPPORTED
  261.       PNG_tRNS;
  262. #endif
  263. #ifdef PNG_READ_zTXt_SUPPORTED
  264.       PNG_zTXt;
  265. #endif
  266.  
  267.    /* First we make sure we have enough data for the 4 byte chunk name
  268.     * and the 4 byte chunk length before proceeding with decoding the
  269.     * chunk data.  To fully decode each of these chunks, we also make
  270.     * sure we have enough data in the buffer for the 4 byte CRC at the
  271.     * end of every chunk (except IDAT, which is handled separately).
  272.     */
  273.    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
  274.    {
  275.       png_byte chunk_length[4];
  276.  
  277.       if (png_ptr->buffer_size < 8)
  278.       {
  279.          png_push_save_buffer(png_ptr);
  280.          return;
  281.       }
  282.  
  283.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  284.       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
  285.       png_reset_crc(png_ptr);
  286.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  287.       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  288.       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  289.    }
  290.  
  291.    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  292.       if (png_ptr->mode & PNG_AFTER_IDAT)
  293.          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
  294.  
  295.    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
  296.    {
  297.       if (png_ptr->push_length != 13)
  298.          png_error(png_ptr, "Invalid IHDR length");
  299.  
  300.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  301.       {
  302.          png_push_save_buffer(png_ptr);
  303.          return;
  304.       }
  305.  
  306.       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
  307.    }
  308.  
  309.    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
  310.    {
  311.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  312.       {
  313.          png_push_save_buffer(png_ptr);
  314.          return;
  315.       }
  316.  
  317.       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
  318.  
  319.       png_ptr->process_mode = PNG_READ_DONE_MODE;
  320.       png_push_have_end(png_ptr, info_ptr);
  321.    }
  322.  
  323. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  324.    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
  325.    {
  326.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  327.       {
  328.          png_push_save_buffer(png_ptr);
  329.          return;
  330.       }
  331.  
  332.       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  333.          png_ptr->mode |= PNG_HAVE_IDAT;
  334.  
  335.       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  336.  
  337.       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  338.          png_ptr->mode |= PNG_HAVE_PLTE;
  339.  
  340.       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  341.       {
  342.          if (!(png_ptr->mode & PNG_HAVE_IHDR))
  343.             png_error(png_ptr, "Missing IHDR before IDAT");
  344.  
  345.          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  346.              !(png_ptr->mode & PNG_HAVE_PLTE))
  347.             png_error(png_ptr, "Missing PLTE before IDAT");
  348.       }
  349.    }
  350.  
  351. #endif
  352.    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  353.    {
  354.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  355.       {
  356.          png_push_save_buffer(png_ptr);
  357.          return;
  358.       }
  359.       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
  360.    }
  361.  
  362.    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  363.    {
  364.       /* If we reach an IDAT chunk, this means we have read all of the
  365.        * header chunks, and we can start reading the image (or if this
  366.        * is called after the image has been read - we have an error).
  367.        */
  368.  
  369.       if (!(png_ptr->mode & PNG_HAVE_IHDR))
  370.          png_error(png_ptr, "Missing IHDR before IDAT");
  371.  
  372.       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  373.           !(png_ptr->mode & PNG_HAVE_PLTE))
  374.          png_error(png_ptr, "Missing PLTE before IDAT");
  375.  
  376.       if (png_ptr->mode & PNG_HAVE_IDAT)
  377.       {
  378.          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
  379.             if (png_ptr->push_length == 0)
  380.                return;
  381.  
  382.          if (png_ptr->mode & PNG_AFTER_IDAT)
  383.             png_benign_error(png_ptr, "Too many IDATs found");
  384.       }
  385.  
  386.       png_ptr->idat_size = png_ptr->push_length;
  387.       png_ptr->mode |= PNG_HAVE_IDAT;
  388.       png_ptr->process_mode = PNG_READ_IDAT_MODE;
  389.       png_push_have_info(png_ptr, info_ptr);
  390.       png_ptr->zstream.avail_out =
  391.           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
  392.           png_ptr->iwidth) + 1;
  393.       png_ptr->zstream.next_out = png_ptr->row_buf;
  394.       return;
  395.    }
  396.  
  397. #ifdef PNG_READ_gAMA_SUPPORTED
  398.    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 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.  
  406.       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
  407.    }
  408.  
  409. #endif
  410. #ifdef PNG_READ_sBIT_SUPPORTED
  411.    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
  412.    {
  413.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  414.       {
  415.          png_push_save_buffer(png_ptr);
  416.          return;
  417.       }
  418.  
  419.       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
  420.    }
  421.  
  422. #endif
  423. #ifdef PNG_READ_cHRM_SUPPORTED
  424.    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
  425.    {
  426.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  427.       {
  428.          png_push_save_buffer(png_ptr);
  429.          return;
  430.       }
  431.  
  432.       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
  433.    }
  434.  
  435. #endif
  436. #ifdef PNG_READ_sRGB_SUPPORTED
  437.    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
  438.    {
  439.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  440.       {
  441.          png_push_save_buffer(png_ptr);
  442.          return;
  443.       }
  444.  
  445.       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
  446.    }
  447.  
  448. #endif
  449. #ifdef PNG_READ_iCCP_SUPPORTED
  450.    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
  451.    {
  452.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  453.       {
  454.          png_push_save_buffer(png_ptr);
  455.          return;
  456.       }
  457.  
  458.       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
  459.    }
  460.  
  461. #endif
  462. #ifdef PNG_READ_sPLT_SUPPORTED
  463.    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
  464.    {
  465.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  466.       {
  467.          png_push_save_buffer(png_ptr);
  468.          return;
  469.       }
  470.  
  471.       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
  472.    }
  473.  
  474. #endif
  475. #ifdef PNG_READ_tRNS_SUPPORTED
  476.    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
  477.    {
  478.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  479.       {
  480.          png_push_save_buffer(png_ptr);
  481.          return;
  482.       }
  483.  
  484.       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
  485.    }
  486.  
  487. #endif
  488. #ifdef PNG_READ_bKGD_SUPPORTED
  489.    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
  490.    {
  491.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  492.       {
  493.          png_push_save_buffer(png_ptr);
  494.          return;
  495.       }
  496.  
  497.       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
  498.    }
  499.  
  500. #endif
  501. #ifdef PNG_READ_hIST_SUPPORTED
  502.    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
  503.    {
  504.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  505.       {
  506.          png_push_save_buffer(png_ptr);
  507.          return;
  508.       }
  509.  
  510.       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
  511.    }
  512.  
  513. #endif
  514. #ifdef PNG_READ_pHYs_SUPPORTED
  515.    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
  516.    {
  517.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  518.       {
  519.          png_push_save_buffer(png_ptr);
  520.          return;
  521.       }
  522.  
  523.       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
  524.    }
  525.  
  526. #endif
  527. #ifdef PNG_READ_oFFs_SUPPORTED
  528.    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
  529.    {
  530.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  531.       {
  532.          png_push_save_buffer(png_ptr);
  533.          return;
  534.       }
  535.  
  536.       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
  537.    }
  538. #endif
  539.  
  540. #ifdef PNG_READ_pCAL_SUPPORTED
  541.    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
  542.    {
  543.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  544.       {
  545.          png_push_save_buffer(png_ptr);
  546.          return;
  547.       }
  548.  
  549.       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
  550.    }
  551.  
  552. #endif
  553. #ifdef PNG_READ_sCAL_SUPPORTED
  554.    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
  555.    {
  556.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  557.       {
  558.          png_push_save_buffer(png_ptr);
  559.          return;
  560.       }
  561.  
  562.       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
  563.    }
  564.  
  565. #endif
  566. #ifdef PNG_READ_tIME_SUPPORTED
  567.    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
  568.    {
  569.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  570.       {
  571.          png_push_save_buffer(png_ptr);
  572.          return;
  573.       }
  574.  
  575.       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
  576.    }
  577.  
  578. #endif
  579. #ifdef PNG_READ_tEXt_SUPPORTED
  580.    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
  581.    {
  582.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  583.       {
  584.          png_push_save_buffer(png_ptr);
  585.          return;
  586.       }
  587.  
  588.       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
  589.    }
  590.  
  591. #endif
  592. #ifdef PNG_READ_zTXt_SUPPORTED
  593.    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
  594.    {
  595.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  596.       {
  597.          png_push_save_buffer(png_ptr);
  598.          return;
  599.       }
  600.  
  601.       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
  602.    }
  603.  
  604. #endif
  605. #ifdef PNG_READ_iTXt_SUPPORTED
  606.    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
  607.    {
  608.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  609.       {
  610.          png_push_save_buffer(png_ptr);
  611.          return;
  612.       }
  613.  
  614.       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
  615.    }
  616.  
  617. #endif
  618.    else
  619.    {
  620.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  621.       {
  622.          png_push_save_buffer(png_ptr);
  623.          return;
  624.       }
  625.       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  626.    }
  627.  
  628.    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  629. }
  630.  
  631. void /* PRIVATE */
  632. png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
  633. {
  634.    png_ptr->process_mode = PNG_SKIP_MODE;
  635.    png_ptr->skip_length = skip;
  636. }
  637.  
  638. void /* PRIVATE */
  639. png_push_crc_finish(png_structp png_ptr)
  640. {
  641.    if (png_ptr->skip_length && png_ptr->save_buffer_size)
  642.    {
  643.       png_size_t save_size = png_ptr->save_buffer_size;
  644.       png_uint_32 skip_length = png_ptr->skip_length;
  645.  
  646.       /* We want the smaller of 'skip_length' and 'save_buffer_size', but
  647.        * they are of different types and we don't know which variable has the
  648.        * fewest bits.  Carefully select the smaller and cast it to the type of
  649.        * the larger - this cannot overflow.  Do not cast in the following test
  650.        * - it will break on either 16 or 64 bit platforms.
  651.        */
  652.       if (skip_length < save_size)
  653.          save_size = (png_size_t)skip_length;
  654.  
  655.       else
  656.          skip_length = (png_uint_32)save_size;
  657.  
  658.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  659.  
  660.       png_ptr->skip_length -= skip_length;
  661.       png_ptr->buffer_size -= save_size;
  662.       png_ptr->save_buffer_size -= save_size;
  663.       png_ptr->save_buffer_ptr += save_size;
  664.    }
  665.    if (png_ptr->skip_length && png_ptr->current_buffer_size)
  666.    {
  667.       png_size_t save_size = png_ptr->current_buffer_size;
  668.       png_uint_32 skip_length = png_ptr->skip_length;
  669.  
  670.       /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
  671.        * the same problem exists as above and the same solution.
  672.        */
  673.       if (skip_length < save_size)
  674.          save_size = (png_size_t)skip_length;
  675.  
  676.       else
  677.          skip_length = (png_uint_32)save_size;
  678.  
  679.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  680.  
  681.       png_ptr->skip_length -= skip_length;
  682.       png_ptr->buffer_size -= save_size;
  683.       png_ptr->current_buffer_size -= save_size;
  684.       png_ptr->current_buffer_ptr += save_size;
  685.    }
  686.    if (!png_ptr->skip_length)
  687.    {
  688.       if (png_ptr->buffer_size < 4)
  689.       {
  690.          png_push_save_buffer(png_ptr);
  691.          return;
  692.       }
  693.  
  694.       png_crc_finish(png_ptr, 0);
  695.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  696.    }
  697. }
  698.  
  699. void PNGCBAPI
  700. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
  701. {
  702.    png_bytep ptr;
  703.  
  704.    if (png_ptr == NULL)
  705.       return;
  706.  
  707.    ptr = buffer;
  708.    if (png_ptr->save_buffer_size)
  709.    {
  710.       png_size_t save_size;
  711.  
  712.       if (length < png_ptr->save_buffer_size)
  713.          save_size = length;
  714.  
  715.       else
  716.          save_size = png_ptr->save_buffer_size;
  717.  
  718.       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
  719.       length -= save_size;
  720.       ptr += save_size;
  721.       png_ptr->buffer_size -= save_size;
  722.       png_ptr->save_buffer_size -= save_size;
  723.       png_ptr->save_buffer_ptr += save_size;
  724.    }
  725.    if (length && png_ptr->current_buffer_size)
  726.    {
  727.       png_size_t save_size;
  728.  
  729.       if (length < png_ptr->current_buffer_size)
  730.          save_size = length;
  731.  
  732.       else
  733.          save_size = png_ptr->current_buffer_size;
  734.  
  735.       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
  736.       png_ptr->buffer_size -= save_size;
  737.       png_ptr->current_buffer_size -= save_size;
  738.       png_ptr->current_buffer_ptr += save_size;
  739.    }
  740. }
  741.  
  742. void /* PRIVATE */
  743. png_push_save_buffer(png_structp png_ptr)
  744. {
  745.    if (png_ptr->save_buffer_size)
  746.    {
  747.       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  748.       {
  749.          png_size_t i, istop;
  750.          png_bytep sp;
  751.          png_bytep dp;
  752.  
  753.          istop = png_ptr->save_buffer_size;
  754.          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  755.              i < istop; i++, sp++, dp++)
  756.          {
  757.             *dp = *sp;
  758.          }
  759.       }
  760.    }
  761.    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  762.        png_ptr->save_buffer_max)
  763.    {
  764.       png_size_t new_max;
  765.       png_bytep old_buffer;
  766.  
  767.       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
  768.           (png_ptr->current_buffer_size + 256))
  769.       {
  770.          png_error(png_ptr, "Potential overflow of save_buffer");
  771.       }
  772.  
  773.       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
  774.       old_buffer = png_ptr->save_buffer;
  775.       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
  776.           (png_size_t)new_max);
  777.  
  778.       if (png_ptr->save_buffer == NULL)
  779.       {
  780.          png_free(png_ptr, old_buffer);
  781.          png_error(png_ptr, "Insufficient memory for save_buffer");
  782.       }
  783.  
  784.       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
  785.       png_free(png_ptr, old_buffer);
  786.       png_ptr->save_buffer_max = new_max;
  787.    }
  788.    if (png_ptr->current_buffer_size)
  789.    {
  790.       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
  791.          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
  792.       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  793.       png_ptr->current_buffer_size = 0;
  794.    }
  795.    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  796.    png_ptr->buffer_size = 0;
  797. }
  798.  
  799. void /* PRIVATE */
  800. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  801.    png_size_t buffer_length)
  802. {
  803.    png_ptr->current_buffer = buffer;
  804.    png_ptr->current_buffer_size = buffer_length;
  805.    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  806.    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  807. }
  808.  
  809. void /* PRIVATE */
  810. png_push_read_IDAT(png_structp png_ptr)
  811. {
  812.    PNG_IDAT;
  813.    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
  814.    {
  815.       png_byte chunk_length[4];
  816.  
  817.       if (png_ptr->buffer_size < 8)
  818.       {
  819.          png_push_save_buffer(png_ptr);
  820.          return;
  821.       }
  822.  
  823.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  824.       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
  825.       png_reset_crc(png_ptr);
  826.       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  827.       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  828.  
  829.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  830.       {
  831.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  832.  
  833.          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  834.             png_error(png_ptr, "Not enough compressed data");
  835.  
  836.          return;
  837.       }
  838.  
  839.       png_ptr->idat_size = png_ptr->push_length;
  840.    }
  841.    if (png_ptr->idat_size && png_ptr->save_buffer_size)
  842.    {
  843.       png_size_t save_size = png_ptr->save_buffer_size;
  844.       png_uint_32 idat_size = png_ptr->idat_size;
  845.  
  846.       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
  847.        * are of different types and we don't know which variable has the fewest
  848.        * bits.  Carefully select the smaller and cast it to the type of the
  849.        * larger - this cannot overflow.  Do not cast in the following test - it
  850.        * will break on either 16 or 64 bit platforms.
  851.        */
  852.       if (idat_size < save_size)
  853.          save_size = (png_size_t)idat_size;
  854.  
  855.       else
  856.          idat_size = (png_uint_32)save_size;
  857.  
  858.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  859.  
  860.       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  861.  
  862.       png_ptr->idat_size -= idat_size;
  863.       png_ptr->buffer_size -= save_size;
  864.       png_ptr->save_buffer_size -= save_size;
  865.       png_ptr->save_buffer_ptr += save_size;
  866.    }
  867.  
  868.    if (png_ptr->idat_size && png_ptr->current_buffer_size)
  869.    {
  870.       png_size_t save_size = png_ptr->current_buffer_size;
  871.       png_uint_32 idat_size = png_ptr->idat_size;
  872.  
  873.       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
  874.        * are of different types and we don't know which variable has the fewest
  875.        * bits.  Carefully select the smaller and cast it to the type of the
  876.        * larger - this cannot overflow.
  877.        */
  878.       if (idat_size < save_size)
  879.          save_size = (png_size_t)idat_size;
  880.  
  881.       else
  882.          idat_size = (png_uint_32)save_size;
  883.  
  884.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  885.  
  886.       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  887.  
  888.       png_ptr->idat_size -= idat_size;
  889.       png_ptr->buffer_size -= save_size;
  890.       png_ptr->current_buffer_size -= save_size;
  891.       png_ptr->current_buffer_ptr += save_size;
  892.    }
  893.    if (!png_ptr->idat_size)
  894.    {
  895.       if (png_ptr->buffer_size < 4)
  896.       {
  897.          png_push_save_buffer(png_ptr);
  898.          return;
  899.       }
  900.  
  901.       png_crc_finish(png_ptr, 0);
  902.       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  903.       png_ptr->mode |= PNG_AFTER_IDAT;
  904.    }
  905. }
  906.  
  907. void /* PRIVATE */
  908. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  909.    png_size_t buffer_length)
  910. {
  911.    /* The caller checks for a non-zero buffer length. */
  912.    if (!(buffer_length > 0) || buffer == NULL)
  913.       png_error(png_ptr, "No IDAT data (internal error)");
  914.  
  915.    /* This routine must process all the data it has been given
  916.     * before returning, calling the row callback as required to
  917.     * handle the uncompressed results.
  918.     */
  919.    png_ptr->zstream.next_in = buffer;
  920.    png_ptr->zstream.avail_in = (uInt)buffer_length;
  921.  
  922.    /* Keep going until the decompressed data is all processed
  923.     * or the stream marked as finished.
  924.     */
  925.    while (png_ptr->zstream.avail_in > 0 &&
  926.           !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  927.    {
  928.       int ret;
  929.  
  930.       /* We have data for zlib, but we must check that zlib
  931.        * has someplace to put the results.  It doesn't matter
  932.        * if we don't expect any results -- it may be the input
  933.        * data is just the LZ end code.
  934.        */
  935.       if (!(png_ptr->zstream.avail_out > 0))
  936.       {
  937.          png_ptr->zstream.avail_out =
  938.              (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
  939.              png_ptr->iwidth) + 1;
  940.  
  941.          png_ptr->zstream.next_out = png_ptr->row_buf;
  942.       }
  943.  
  944.       /* Using Z_SYNC_FLUSH here means that an unterminated
  945.        * LZ stream (a stream with a missing end code) can still
  946.        * be handled, otherwise (Z_NO_FLUSH) a future zlib
  947.        * implementation might defer output and therefore
  948.        * change the current behavior (see comments in inflate.c
  949.        * for why this doesn't happen at present with zlib 1.2.5).
  950.        */
  951.       ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
  952.  
  953.       /* Check for any failure before proceeding. */
  954.       if (ret != Z_OK && ret != Z_STREAM_END)
  955.       {
  956.          /* Terminate the decompression. */
  957.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  958.  
  959.          /* This may be a truncated stream (missing or
  960.           * damaged end code).  Treat that as a warning.
  961.           */
  962.          if (png_ptr->row_number >= png_ptr->num_rows ||
  963.              png_ptr->pass > 6)
  964.             png_warning(png_ptr, "Truncated compressed data in IDAT");
  965.  
  966.          else
  967.             png_error(png_ptr, "Decompression error in IDAT");
  968.  
  969.          /* Skip the check on unprocessed input */
  970.          return;
  971.       }
  972.  
  973.       /* Did inflate output any data? */
  974.       if (png_ptr->zstream.next_out != png_ptr->row_buf)
  975.       {
  976.          /* Is this unexpected data after the last row?
  977.           * If it is, artificially terminate the LZ output
  978.           * here.
  979.           */
  980.          if (png_ptr->row_number >= png_ptr->num_rows ||
  981.              png_ptr->pass > 6)
  982.          {
  983.             /* Extra data. */
  984.             png_warning(png_ptr, "Extra compressed data in IDAT");
  985.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  986.  
  987.             /* Do no more processing; skip the unprocessed
  988.              * input check below.
  989.              */
  990.             return;
  991.          }
  992.  
  993.          /* Do we have a complete row? */
  994.          if (png_ptr->zstream.avail_out == 0)
  995.             png_push_process_row(png_ptr);
  996.       }
  997.  
  998.       /* And check for the end of the stream. */
  999.       if (ret == Z_STREAM_END)
  1000.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  1001.    }
  1002.  
  1003.    /* All the data should have been processed, if anything
  1004.     * is left at this point we have bytes of IDAT data
  1005.     * after the zlib end code.
  1006.     */
  1007.    if (png_ptr->zstream.avail_in > 0)
  1008.       png_warning(png_ptr, "Extra compression data in IDAT");
  1009. }
  1010.  
  1011. void /* PRIVATE */
  1012. png_push_process_row(png_structp png_ptr)
  1013. {
  1014.    png_ptr->row_info.color_type = png_ptr->color_type;
  1015.    png_ptr->row_info.width = png_ptr->iwidth;
  1016.    png_ptr->row_info.channels = png_ptr->channels;
  1017.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  1018.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  1019.  
  1020.    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
  1021.        png_ptr->row_info.width);
  1022.  
  1023.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  1024.        png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  1025.        (int)(png_ptr->row_buf[0]));
  1026.  
  1027.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
  1028.  
  1029.    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
  1030.       png_do_read_transformations(png_ptr);
  1031.  
  1032. #ifdef PNG_READ_INTERLACING_SUPPORTED
  1033.    /* Blow up interlaced rows to full size */
  1034.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  1035.    {
  1036.       if (png_ptr->pass < 6)
  1037. /*       old interface (pre-1.0.9):
  1038.          png_do_read_interlace(&(png_ptr->row_info),
  1039.              png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
  1040.  */
  1041.          png_do_read_interlace(png_ptr);
  1042.  
  1043.     switch (png_ptr->pass)
  1044.     {
  1045.          case 0:
  1046.          {
  1047.             int i;
  1048.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  1049.             {
  1050.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1051.                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
  1052.             }
  1053.  
  1054.             if (png_ptr->pass == 2) /* Pass 1 might be empty */
  1055.             {
  1056.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1057.                {
  1058.                   png_push_have_row(png_ptr, NULL);
  1059.                   png_read_push_finish_row(png_ptr);
  1060.                }
  1061.             }
  1062.  
  1063.             if (png_ptr->pass == 4 && png_ptr->height <= 4)
  1064.             {
  1065.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1066.                {
  1067.                   png_push_have_row(png_ptr, NULL);
  1068.                   png_read_push_finish_row(png_ptr);
  1069.                }
  1070.             }
  1071.  
  1072.             if (png_ptr->pass == 6 && png_ptr->height <= 4)
  1073.             {
  1074.                 png_push_have_row(png_ptr, NULL);
  1075.                 png_read_push_finish_row(png_ptr);
  1076.             }
  1077.  
  1078.             break;
  1079.          }
  1080.  
  1081.          case 1:
  1082.          {
  1083.             int i;
  1084.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  1085.             {
  1086.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1087.                png_read_push_finish_row(png_ptr);
  1088.             }
  1089.  
  1090.             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
  1091.             {
  1092.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1093.                {
  1094.                   png_push_have_row(png_ptr, NULL);
  1095.                   png_read_push_finish_row(png_ptr);
  1096.                }
  1097.             }
  1098.  
  1099.             break;
  1100.          }
  1101.  
  1102.          case 2:
  1103.          {
  1104.             int i;
  1105.  
  1106.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1107.             {
  1108.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1109.                png_read_push_finish_row(png_ptr);
  1110.             }
  1111.  
  1112.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1113.             {
  1114.                png_push_have_row(png_ptr, NULL);
  1115.                png_read_push_finish_row(png_ptr);
  1116.             }
  1117.  
  1118.             if (png_ptr->pass == 4) /* Pass 3 might be empty */
  1119.             {
  1120.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1121.                {
  1122.                   png_push_have_row(png_ptr, NULL);
  1123.                   png_read_push_finish_row(png_ptr);
  1124.                }
  1125.             }
  1126.  
  1127.             break;
  1128.          }
  1129.  
  1130.          case 3:
  1131.          {
  1132.             int i;
  1133.  
  1134.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  1135.             {
  1136.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1137.                png_read_push_finish_row(png_ptr);
  1138.             }
  1139.  
  1140.             if (png_ptr->pass == 4) /* Skip top two generated rows */
  1141.             {
  1142.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1143.                {
  1144.                   png_push_have_row(png_ptr, NULL);
  1145.                   png_read_push_finish_row(png_ptr);
  1146.                }
  1147.             }
  1148.  
  1149.             break;
  1150.          }
  1151.  
  1152.          case 4:
  1153.          {
  1154.             int i;
  1155.  
  1156.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1157.             {
  1158.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1159.                png_read_push_finish_row(png_ptr);
  1160.             }
  1161.  
  1162.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1163.             {
  1164.                png_push_have_row(png_ptr, NULL);
  1165.                png_read_push_finish_row(png_ptr);
  1166.             }
  1167.  
  1168.             if (png_ptr->pass == 6) /* Pass 5 might be empty */
  1169.             {
  1170.                png_push_have_row(png_ptr, NULL);
  1171.                png_read_push_finish_row(png_ptr);
  1172.             }
  1173.  
  1174.             break;
  1175.          }
  1176.  
  1177.          case 5:
  1178.          {
  1179.             int i;
  1180.  
  1181.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  1182.             {
  1183.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1184.                png_read_push_finish_row(png_ptr);
  1185.             }
  1186.  
  1187.             if (png_ptr->pass == 6) /* Skip top generated row */
  1188.             {
  1189.                png_push_have_row(png_ptr, NULL);
  1190.                png_read_push_finish_row(png_ptr);
  1191.             }
  1192.  
  1193.             break;
  1194.          }
  1195.  
  1196.          default:
  1197.          case 6:
  1198.          {
  1199.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1200.             png_read_push_finish_row(png_ptr);
  1201.  
  1202.             if (png_ptr->pass != 6)
  1203.                break;
  1204.  
  1205.             png_push_have_row(png_ptr, NULL);
  1206.             png_read_push_finish_row(png_ptr);
  1207.          }
  1208.       }
  1209.    }
  1210.    else
  1211. #endif
  1212.    {
  1213.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1214.       png_read_push_finish_row(png_ptr);
  1215.    }
  1216. }
  1217.  
  1218. void /* PRIVATE */
  1219. png_read_push_finish_row(png_structp png_ptr)
  1220. {
  1221.    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1222.  
  1223.    /* Start of interlace block */
  1224.    PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  1225.  
  1226.    /* Offset to next interlace block */
  1227.    PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  1228.  
  1229.    /* Start of interlace block in the y direction */
  1230.    PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  1231.  
  1232.    /* Offset to next interlace block in the y direction */
  1233.    PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  1234.  
  1235.    /* Height of interlace block.  This is not currently used - if you need
  1236.     * it, uncomment it here and in png.h
  1237.    PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  1238.    */
  1239.  
  1240.    png_ptr->row_number++;
  1241.    if (png_ptr->row_number < png_ptr->num_rows)
  1242.       return;
  1243.  
  1244. #ifdef PNG_READ_INTERLACING_SUPPORTED
  1245.    if (png_ptr->interlaced)
  1246.    {
  1247.       png_ptr->row_number = 0;
  1248.       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1249.  
  1250.       do
  1251.       {
  1252.          png_ptr->pass++;
  1253.          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
  1254.              (png_ptr->pass == 3 && png_ptr->width < 3) ||
  1255.              (png_ptr->pass == 5 && png_ptr->width < 2))
  1256.             png_ptr->pass++;
  1257.  
  1258.          if (png_ptr->pass > 7)
  1259.             png_ptr->pass--;
  1260.  
  1261.          if (png_ptr->pass >= 7)
  1262.             break;
  1263.  
  1264.          png_ptr->iwidth = (png_ptr->width +
  1265.              png_pass_inc[png_ptr->pass] - 1 -
  1266.              png_pass_start[png_ptr->pass]) /
  1267.              png_pass_inc[png_ptr->pass];
  1268.  
  1269.          if (png_ptr->transformations & PNG_INTERLACE)
  1270.             break;
  1271.  
  1272.          png_ptr->num_rows = (png_ptr->height +
  1273.              png_pass_yinc[png_ptr->pass] - 1 -
  1274.              png_pass_ystart[png_ptr->pass]) /
  1275.              png_pass_yinc[png_ptr->pass];
  1276.  
  1277.       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
  1278.    }
  1279. #endif /* PNG_READ_INTERLACING_SUPPORTED */
  1280. }
  1281.  
  1282. #ifdef PNG_READ_tEXt_SUPPORTED
  1283. void /* PRIVATE */
  1284. png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1285.     length)
  1286. {
  1287.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1288.       {
  1289.          PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
  1290.          png_error(png_ptr, "Out of place tEXt");
  1291.          /*NOT REACHED*/
  1292.       }
  1293.  
  1294. #ifdef PNG_MAX_MALLOC_64K
  1295.    png_ptr->skip_length = 0;  /* This may not be necessary */
  1296.  
  1297.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1298.    {
  1299.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1300.       png_ptr->skip_length = length - (png_uint_32)65535L;
  1301.       length = (png_uint_32)65535L;
  1302.    }
  1303. #endif
  1304.  
  1305.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1306.        (png_size_t)(length + 1));
  1307.    png_ptr->current_text[length] = '\0';
  1308.    png_ptr->current_text_ptr = png_ptr->current_text;
  1309.    png_ptr->current_text_size = (png_size_t)length;
  1310.    png_ptr->current_text_left = (png_size_t)length;
  1311.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  1312. }
  1313.  
  1314. void /* PRIVATE */
  1315. png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  1316. {
  1317.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1318.    {
  1319.       png_size_t text_size;
  1320.  
  1321.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1322.          text_size = png_ptr->buffer_size;
  1323.  
  1324.       else
  1325.          text_size = png_ptr->current_text_left;
  1326.  
  1327.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1328.       png_ptr->current_text_left -= text_size;
  1329.       png_ptr->current_text_ptr += text_size;
  1330.    }
  1331.    if (!(png_ptr->current_text_left))
  1332.    {
  1333.       png_textp text_ptr;
  1334.       png_charp text;
  1335.       png_charp key;
  1336.       int ret;
  1337.  
  1338.       if (png_ptr->buffer_size < 4)
  1339.       {
  1340.          png_push_save_buffer(png_ptr);
  1341.          return;
  1342.       }
  1343.  
  1344.       png_push_crc_finish(png_ptr);
  1345.  
  1346. #ifdef PNG_MAX_MALLOC_64K
  1347.       if (png_ptr->skip_length)
  1348.          return;
  1349. #endif
  1350.  
  1351.       key = png_ptr->current_text;
  1352.  
  1353.       for (text = key; *text; text++)
  1354.          /* Empty loop */ ;
  1355.  
  1356.       if (text < key + png_ptr->current_text_size)
  1357.          text++;
  1358.  
  1359.       text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
  1360.       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1361.       text_ptr->key = key;
  1362.       text_ptr->itxt_length = 0;
  1363.       text_ptr->lang = NULL;
  1364.       text_ptr->lang_key = NULL;
  1365.       text_ptr->text = text;
  1366.  
  1367.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1368.  
  1369.       png_free(png_ptr, key);
  1370.       png_free(png_ptr, text_ptr);
  1371.       png_ptr->current_text = NULL;
  1372.  
  1373.       if (ret)
  1374.          png_warning(png_ptr, "Insufficient memory to store text chunk");
  1375.    }
  1376. }
  1377. #endif
  1378.  
  1379. #ifdef PNG_READ_zTXt_SUPPORTED
  1380. void /* PRIVATE */
  1381. png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1382.    length)
  1383. {
  1384.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1385.    {
  1386.       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
  1387.       png_error(png_ptr, "Out of place zTXt");
  1388.       /*NOT REACHED*/
  1389.    }
  1390.  
  1391. #ifdef PNG_MAX_MALLOC_64K
  1392.    /* We can't handle zTXt chunks > 64K, since we don't have enough space
  1393.     * to be able to store the uncompressed data.  Actually, the threshold
  1394.     * is probably around 32K, but it isn't as definite as 64K is.
  1395.     */
  1396.    if (length > (png_uint_32)65535L)
  1397.    {
  1398.       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  1399.       png_push_crc_skip(png_ptr, length);
  1400.       return;
  1401.    }
  1402. #endif
  1403.  
  1404.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1405.        (png_size_t)(length + 1));
  1406.    png_ptr->current_text[length] = '\0';
  1407.    png_ptr->current_text_ptr = png_ptr->current_text;
  1408.    png_ptr->current_text_size = (png_size_t)length;
  1409.    png_ptr->current_text_left = (png_size_t)length;
  1410.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  1411. }
  1412.  
  1413. void /* PRIVATE */
  1414. png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  1415. {
  1416.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1417.    {
  1418.       png_size_t text_size;
  1419.  
  1420.       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
  1421.          text_size = png_ptr->buffer_size;
  1422.  
  1423.       else
  1424.          text_size = png_ptr->current_text_left;
  1425.  
  1426.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1427.       png_ptr->current_text_left -= text_size;
  1428.       png_ptr->current_text_ptr += text_size;
  1429.    }
  1430.    if (!(png_ptr->current_text_left))
  1431.    {
  1432.       png_textp text_ptr;
  1433.       png_charp text;
  1434.       png_charp key;
  1435.       int ret;
  1436.       png_size_t text_size, key_size;
  1437.  
  1438.       if (png_ptr->buffer_size < 4)
  1439.       {
  1440.          png_push_save_buffer(png_ptr);
  1441.          return;
  1442.       }
  1443.  
  1444.       png_push_crc_finish(png_ptr);
  1445.  
  1446.       key = png_ptr->current_text;
  1447.  
  1448.       for (text = key; *text; text++)
  1449.          /* Empty loop */ ;
  1450.  
  1451.       /* zTXt can't have zero text */
  1452.       if (text >= key + png_ptr->current_text_size)
  1453.       {
  1454.          png_ptr->current_text = NULL;
  1455.          png_free(png_ptr, key);
  1456.          return;
  1457.       }
  1458.  
  1459.       text++;
  1460.  
  1461.       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
  1462.       {
  1463.          png_ptr->current_text = NULL;
  1464.          png_free(png_ptr, key);
  1465.          return;
  1466.       }
  1467.  
  1468.       text++;
  1469.  
  1470.       png_ptr->zstream.next_in = (png_bytep)text;
  1471.       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  1472.           (text - key));
  1473.       png_ptr->zstream.next_out = png_ptr->zbuf;
  1474.       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1475.  
  1476.       key_size = text - key;
  1477.       text_size = 0;
  1478.       text = NULL;
  1479.       ret = Z_STREAM_END;
  1480.  
  1481.       while (png_ptr->zstream.avail_in)
  1482.       {
  1483.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1484.          if (ret != Z_OK && ret != Z_STREAM_END)
  1485.          {
  1486.             inflateReset(&png_ptr->zstream);
  1487.             png_ptr->zstream.avail_in = 0;
  1488.             png_ptr->current_text = NULL;
  1489.             png_free(png_ptr, key);
  1490.             png_free(png_ptr, text);
  1491.             return;
  1492.          }
  1493.  
  1494.          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
  1495.          {
  1496.             if (text == NULL)
  1497.             {
  1498.                text = (png_charp)png_malloc(png_ptr,
  1499.                    (png_ptr->zbuf_size
  1500.                    - png_ptr->zstream.avail_out + key_size + 1));
  1501.  
  1502.                png_memcpy(text + key_size, png_ptr->zbuf,
  1503.                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1504.  
  1505.                png_memcpy(text, key, key_size);
  1506.  
  1507.                text_size = key_size + png_ptr->zbuf_size -
  1508.                    png_ptr->zstream.avail_out;
  1509.  
  1510.                *(text + text_size) = '\0';
  1511.             }
  1512.  
  1513.             else
  1514.             {
  1515.                png_charp tmp;
  1516.  
  1517.                tmp = text;
  1518.                text = (png_charp)png_malloc(png_ptr, text_size +
  1519.                    (png_ptr->zbuf_size
  1520.                    - png_ptr->zstream.avail_out + 1));
  1521.  
  1522.                png_memcpy(text, tmp, text_size);
  1523.                png_free(png_ptr, tmp);
  1524.  
  1525.                png_memcpy(text + text_size, png_ptr->zbuf,
  1526.                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1527.  
  1528.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  1529.                *(text + text_size) = '\0';
  1530.             }
  1531.  
  1532.             if (ret != Z_STREAM_END)
  1533.             {
  1534.                png_ptr->zstream.next_out = png_ptr->zbuf;
  1535.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1536.             }
  1537.          }
  1538.          else
  1539.          {
  1540.             break;
  1541.          }
  1542.  
  1543.          if (ret == Z_STREAM_END)
  1544.             break;
  1545.       }
  1546.  
  1547.       inflateReset(&png_ptr->zstream);
  1548.       png_ptr->zstream.avail_in = 0;
  1549.  
  1550.       if (ret != Z_STREAM_END)
  1551.       {
  1552.          png_ptr->current_text = NULL;
  1553.          png_free(png_ptr, key);
  1554.          png_free(png_ptr, text);
  1555.          return;
  1556.       }
  1557.  
  1558.       png_ptr->current_text = NULL;
  1559.       png_free(png_ptr, key);
  1560.       key = text;
  1561.       text += key_size;
  1562.  
  1563.       text_ptr = (png_textp)png_malloc(png_ptr,
  1564.           png_sizeof(png_text));
  1565.       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
  1566.       text_ptr->key = key;
  1567.       text_ptr->itxt_length = 0;
  1568.       text_ptr->lang = NULL;
  1569.       text_ptr->lang_key = NULL;
  1570.       text_ptr->text = text;
  1571.  
  1572.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1573.  
  1574.       png_free(png_ptr, key);
  1575.       png_free(png_ptr, text_ptr);
  1576.  
  1577.       if (ret)
  1578.          png_warning(png_ptr, "Insufficient memory to store text chunk");
  1579.    }
  1580. }
  1581. #endif
  1582.  
  1583. #ifdef PNG_READ_iTXt_SUPPORTED
  1584. void /* PRIVATE */
  1585. png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1586.     length)
  1587. {
  1588.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1589.    {
  1590.       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
  1591.       png_error(png_ptr, "Out of place iTXt");
  1592.       /*NOT REACHED*/
  1593.    }
  1594.  
  1595. #ifdef PNG_MAX_MALLOC_64K
  1596.    png_ptr->skip_length = 0;  /* This may not be necessary */
  1597.  
  1598.    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1599.    {
  1600.       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  1601.       png_ptr->skip_length = length - (png_uint_32)65535L;
  1602.       length = (png_uint_32)65535L;
  1603.    }
  1604. #endif
  1605.  
  1606.    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1607.        (png_size_t)(length + 1));
  1608.    png_ptr->current_text[length] = '\0';
  1609.    png_ptr->current_text_ptr = png_ptr->current_text;
  1610.    png_ptr->current_text_size = (png_size_t)length;
  1611.    png_ptr->current_text_left = (png_size_t)length;
  1612.    png_ptr->process_mode = PNG_READ_iTXt_MODE;
  1613. }
  1614.  
  1615. void /* PRIVATE */
  1616. png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
  1617. {
  1618.  
  1619.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  1620.    {
  1621.       png_size_t text_size;
  1622.  
  1623.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  1624.          text_size = png_ptr->buffer_size;
  1625.  
  1626.       else
  1627.          text_size = png_ptr->current_text_left;
  1628.  
  1629.       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1630.       png_ptr->current_text_left -= text_size;
  1631.       png_ptr->current_text_ptr += text_size;
  1632.    }
  1633.  
  1634.    if (!(png_ptr->current_text_left))
  1635.    {
  1636.       png_textp text_ptr;
  1637.       png_charp key;
  1638.       int comp_flag;
  1639.       png_charp lang;
  1640.       png_charp lang_key;
  1641.       png_charp text;
  1642.       int ret;
  1643.  
  1644.       if (png_ptr->buffer_size < 4)
  1645.       {
  1646.          png_push_save_buffer(png_ptr);
  1647.          return;
  1648.       }
  1649.  
  1650.       png_push_crc_finish(png_ptr);
  1651.  
  1652. #ifdef PNG_MAX_MALLOC_64K
  1653.       if (png_ptr->skip_length)
  1654.          return;
  1655. #endif
  1656.  
  1657.       key = png_ptr->current_text;
  1658.  
  1659.       for (lang = key; *lang; lang++)
  1660.          /* Empty loop */ ;
  1661.  
  1662.       if (lang < key + png_ptr->current_text_size - 3)
  1663.          lang++;
  1664.  
  1665.       comp_flag = *lang++;
  1666.       lang++;     /* Skip comp_type, always zero */
  1667.  
  1668.       for (lang_key = lang; *lang_key; lang_key++)
  1669.          /* Empty loop */ ;
  1670.  
  1671.       lang_key++;        /* Skip NUL separator */
  1672.  
  1673.       text=lang_key;
  1674.  
  1675.       if (lang_key < key + png_ptr->current_text_size - 1)
  1676.       {
  1677.          for (; *text; text++)
  1678.             /* Empty loop */ ;
  1679.       }
  1680.  
  1681.       if (text < key + png_ptr->current_text_size)
  1682.          text++;
  1683.  
  1684.       text_ptr = (png_textp)png_malloc(png_ptr,
  1685.           png_sizeof(png_text));
  1686.  
  1687.       text_ptr->compression = comp_flag + 2;
  1688.       text_ptr->key = key;
  1689.       text_ptr->lang = lang;
  1690.       text_ptr->lang_key = lang_key;
  1691.       text_ptr->text = text;
  1692.       text_ptr->text_length = 0;
  1693.       text_ptr->itxt_length = png_strlen(text);
  1694.  
  1695.       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1696.  
  1697.       png_ptr->current_text = NULL;
  1698.  
  1699.       png_free(png_ptr, text_ptr);
  1700.       if (ret)
  1701.          png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
  1702.    }
  1703. }
  1704. #endif
  1705.  
  1706. /* This function is called when we haven't found a handler for this
  1707.  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
  1708.  * name or a critical chunk), the chunk is (currently) silently ignored.
  1709.  */
  1710. void /* PRIVATE */
  1711. png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1712.     length)
  1713. {
  1714.    png_uint_32 skip = 0;
  1715.  
  1716.    if (!(png_ptr->chunk_name[0] & 0x20))
  1717.    {
  1718. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  1719.       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1720.           PNG_HANDLE_CHUNK_ALWAYS
  1721. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  1722.           && png_ptr->read_user_chunk_fn == NULL
  1723. #endif
  1724.           )
  1725. #endif
  1726.          png_chunk_error(png_ptr, "unknown critical chunk");
  1727.  
  1728.       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
  1729.    }
  1730.  
  1731. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  1732.    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  1733.    {
  1734. #ifdef PNG_MAX_MALLOC_64K
  1735.       if (length > (png_uint_32)65535L)
  1736.       {
  1737.          png_warning(png_ptr, "unknown chunk too large to fit in memory");
  1738.          skip = length - (png_uint_32)65535L;
  1739.          length = (png_uint_32)65535L;
  1740.       }
  1741. #endif
  1742.       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
  1743.           (png_charp)png_ptr->chunk_name,
  1744.           png_sizeof(png_ptr->unknown_chunk.name));
  1745.       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
  1746.           = '\0';
  1747.  
  1748.       png_ptr->unknown_chunk.size = (png_size_t)length;
  1749.  
  1750.       if (length == 0)
  1751.          png_ptr->unknown_chunk.data = NULL;
  1752.  
  1753.       else
  1754.       {
  1755.          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
  1756.              (png_size_t)length);
  1757.          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
  1758.       }
  1759.  
  1760. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  1761.       if (png_ptr->read_user_chunk_fn != NULL)
  1762.       {
  1763.          /* Callback to user unknown chunk handler */
  1764.          int ret;
  1765.          ret = (*(png_ptr->read_user_chunk_fn))
  1766.              (png_ptr, &png_ptr->unknown_chunk);
  1767.  
  1768.          if (ret < 0)
  1769.             png_chunk_error(png_ptr, "error in user chunk");
  1770.  
  1771.          if (ret == 0)
  1772.          {
  1773.             if (!(png_ptr->chunk_name[0] & 0x20))
  1774.                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1775.                    PNG_HANDLE_CHUNK_ALWAYS)
  1776.                   png_chunk_error(png_ptr, "unknown critical chunk");
  1777.             png_set_unknown_chunks(png_ptr, info_ptr,
  1778.                 &png_ptr->unknown_chunk, 1);
  1779.          }
  1780.       }
  1781.  
  1782.       else
  1783. #endif
  1784.          png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
  1785.       png_free(png_ptr, png_ptr->unknown_chunk.data);
  1786.       png_ptr->unknown_chunk.data = NULL;
  1787.    }
  1788.  
  1789.    else
  1790. #endif
  1791.       skip=length;
  1792.    png_push_crc_skip(png_ptr, skip);
  1793. }
  1794.  
  1795. void /* PRIVATE */
  1796. png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1797. {
  1798.    if (png_ptr->info_fn != NULL)
  1799.       (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1800. }
  1801.  
  1802. void /* PRIVATE */
  1803. png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1804. {
  1805.    if (png_ptr->end_fn != NULL)
  1806.       (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1807. }
  1808.  
  1809. void /* PRIVATE */
  1810. png_push_have_row(png_structp png_ptr, png_bytep row)
  1811. {
  1812.    if (png_ptr->row_fn != NULL)
  1813.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1814.          (int)png_ptr->pass);
  1815. }
  1816.  
  1817. void PNGAPI
  1818. png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
  1819.     png_const_bytep new_row)
  1820. {
  1821.    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
  1822.       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
  1823.  
  1824.    if (png_ptr == NULL)
  1825.       return;
  1826.  
  1827.    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
  1828.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1829. }
  1830.  
  1831. void PNGAPI
  1832. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1833.     png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1834.     png_progressive_end_ptr end_fn)
  1835. {
  1836.    if (png_ptr == NULL)
  1837.       return;
  1838.  
  1839.    png_ptr->info_fn = info_fn;
  1840.    png_ptr->row_fn = row_fn;
  1841.    png_ptr->end_fn = end_fn;
  1842.  
  1843.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1844. }
  1845.  
  1846. png_voidp PNGAPI
  1847. png_get_progressive_ptr(png_const_structp png_ptr)
  1848. {
  1849.    if (png_ptr == NULL)
  1850.       return (NULL);
  1851.  
  1852.    return png_ptr->io_ptr;
  1853. }
  1854. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1855.