PNGPREAD.C
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:38k
源码类别:

图片显示

开发平台:

Visual C++

  1. /* pngpread.c - read a png file in push mode
  2.    libpng 1.0 beta 3 - version 0.89
  3.    For conditions of distribution and use, see copyright notice in png.h
  4.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  5.    May 25, 1996
  6.    */
  7. #define PNG_INTERNAL
  8. #include "png.h"
  9. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  10. void
  11. png_process_data(png_structp png_ptr, png_infop info,
  12.    png_bytep buffer, png_uint_32 buffer_size)
  13. {
  14.    png_push_restore_buffer(png_ptr, buffer, buffer_size);
  15.    while (png_ptr->buffer_size)
  16.    {
  17.       png_process_some_data(png_ptr, info);
  18.    }
  19. }
  20. void
  21. png_process_some_data(png_structp png_ptr, png_infop info)
  22. {
  23.    switch (png_ptr->process_mode)
  24.    {
  25.       case PNG_READ_SIG_MODE:
  26.       {
  27.          png_push_read_sig(png_ptr);
  28.          break;
  29.       }
  30.       case PNG_READ_CHUNK_MODE:
  31.       {
  32.          png_push_read_chunk(png_ptr, info);
  33.          break;
  34.       }
  35.       case PNG_READ_IDAT_MODE:
  36.       {
  37.          png_push_read_IDAT(png_ptr);
  38.          break;
  39.       }
  40.       case PNG_READ_PLTE_MODE:
  41.       {
  42.          png_push_read_PLTE(png_ptr, info);
  43.          break;
  44.       }
  45. #if defined(PNG_READ_tEXt_SUPPORTED)
  46.       case PNG_READ_tEXt_MODE:
  47.       {
  48.          png_push_read_tEXt(png_ptr, info);
  49.          break;
  50.       }
  51. #endif
  52. #if defined(PNG_READ_zTXt_SUPPORTED)
  53.       case PNG_READ_zTXt_MODE:
  54.       {
  55.          png_push_read_zTXt(png_ptr, info);
  56.          break;
  57.       }
  58. #endif
  59.       case PNG_READ_END_MODE:
  60.       {
  61.          png_push_read_end(png_ptr, info);
  62.          break;
  63.       }
  64.       case PNG_SKIP_MODE:
  65.       {
  66.          png_push_skip(png_ptr);
  67.          break;
  68.       }
  69.       default:
  70.       {
  71.          png_ptr->buffer_size = 0;
  72.          break;
  73.       }
  74.    }
  75. }
  76. void
  77. png_push_read_sig(png_structp png_ptr)
  78. {
  79.    png_byte sig[8];
  80.    if (png_ptr->buffer_size < 8)
  81.    {
  82.       png_push_save_buffer(png_ptr);
  83.       return;
  84.    }
  85.    png_push_fill_buffer(png_ptr, sig, 8);
  86.    if (png_check_sig(sig, 8))
  87.    {
  88.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  89.    }
  90.    else
  91.    {
  92.       png_error(png_ptr, "Not a PNG file");
  93.    }
  94. }
  95. void
  96. png_push_read_chunk(png_structp png_ptr, png_infop info)
  97. {
  98.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  99.    {
  100.       png_byte chunk_start[8];
  101.       if (png_ptr->buffer_size < 8)
  102.       {
  103.          png_push_save_buffer(png_ptr);
  104.          return;
  105.       }
  106.       png_push_fill_buffer(png_ptr, chunk_start, 8);
  107.       png_ptr->push_length = png_get_uint_32(chunk_start);
  108.       png_memcpy(png_ptr->push_chunk_name, (png_voidp)(chunk_start + 4), 4);
  109.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  110.       png_reset_crc(png_ptr);
  111.       png_calculate_crc(png_ptr, chunk_start + 4, 4);
  112.    }
  113.    if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4))
  114.    {
  115.       if (png_ptr->mode != PNG_BEFORE_IHDR)
  116.          png_error(png_ptr, "Out of place IHDR");
  117.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  118.       {
  119.          png_push_save_buffer(png_ptr);
  120.          return;
  121.       }
  122.       png_handle_IHDR(png_ptr, info, png_ptr->push_length);
  123.       png_push_check_crc(png_ptr);
  124.       png_ptr->mode = PNG_HAVE_IHDR;
  125.    }
  126.    else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4))
  127.    {
  128.       if (png_ptr->mode != PNG_HAVE_IHDR)
  129.          png_error(png_ptr, "Missing IHDR");
  130. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  131.       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  132.          png_push_crc_skip(png_ptr, length);
  133.       else
  134. #else
  135.       {
  136.          png_push_handle_PLTE(png_ptr, png_ptr->push_length);
  137.       }
  138. #endif
  139.       png_ptr->mode = PNG_HAVE_PLTE;
  140.    }
  141.    else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  142.    {
  143.       png_ptr->idat_size = png_ptr->push_length;
  144.       png_ptr->mode = PNG_HAVE_IDAT;
  145.       png_ptr->process_mode = PNG_READ_IDAT_MODE;
  146.       png_push_have_info(png_ptr, info);
  147.       png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
  148.       png_ptr->zstream->next_out = png_ptr->row_buf;
  149.       return;
  150.    }
  151.    else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4))
  152.    {
  153.       png_error(png_ptr, "No image in file");
  154.    }
  155. #if defined(PNG_READ_gAMA_SUPPORTED)
  156.    else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4))
  157.    {
  158.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  159.       {
  160.          png_push_save_buffer(png_ptr);
  161.          return;
  162.       }
  163.       if (png_ptr->mode != PNG_HAVE_IHDR)
  164.          png_error(png_ptr, "Out of place gAMA");
  165.       png_handle_gAMA(png_ptr, info, png_ptr->push_length);
  166.       png_push_check_crc(png_ptr);
  167.    }
  168. #endif
  169. #if defined(PNG_READ_sBIT_SUPPORTED)
  170.    else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4))
  171.    {
  172.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  173.       {
  174.          png_push_save_buffer(png_ptr);
  175.          return;
  176.       }
  177.       if (png_ptr->mode != PNG_HAVE_IHDR)
  178.          png_error(png_ptr, "Out of place sBIT");
  179.       png_handle_sBIT(png_ptr, info, png_ptr->push_length);
  180.       png_push_check_crc(png_ptr);
  181.    }
  182. #endif
  183. #if defined(PNG_READ_cHRM_SUPPORTED)
  184.    else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4))
  185.    {
  186.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  187.       {
  188.          png_push_save_buffer(png_ptr);
  189.          return;
  190.       }
  191.       if (png_ptr->mode != PNG_HAVE_IHDR)
  192.          png_error(png_ptr, "Out of place cHRM");
  193.       png_handle_cHRM(png_ptr, info, png_ptr->push_length);
  194.       png_push_check_crc(png_ptr);
  195.    }
  196. #endif
  197. #if defined(PNG_READ_tRNS_SUPPORTED)
  198.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4))
  199.    {
  200.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  201.       {
  202.          png_push_save_buffer(png_ptr);
  203.          return;
  204.       }
  205.       if (png_ptr->mode != PNG_HAVE_IHDR &&
  206.          png_ptr->mode != PNG_HAVE_PLTE)
  207.          png_error(png_ptr, "Out of place tRNS");
  208.       png_handle_tRNS(png_ptr, info, png_ptr->push_length);
  209.       png_push_check_crc(png_ptr);
  210.    }
  211. #endif
  212. #if defined(PNG_READ_bKGD_SUPPORTED)
  213.    else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4))
  214.    {
  215.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  216.       {
  217.          png_push_save_buffer(png_ptr);
  218.          return;
  219.       }
  220.       if (png_ptr->mode != PNG_HAVE_IHDR &&
  221.          png_ptr->mode != PNG_HAVE_PLTE)
  222.          png_error(png_ptr, "Out of place bKGD");
  223.       png_handle_bKGD(png_ptr, info, png_ptr->push_length);
  224.       png_push_check_crc(png_ptr);
  225.    }
  226. #endif
  227. #if defined(PNG_READ_hIST_SUPPORTED)
  228.    else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4))
  229.    {
  230.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  231.       {
  232.          png_push_save_buffer(png_ptr);
  233.          return;
  234.       }
  235.       if (png_ptr->mode != PNG_HAVE_PLTE)
  236.          png_error(png_ptr, "Out of place hIST");
  237.       png_handle_hIST(png_ptr, info, png_ptr->push_length);
  238.       png_push_check_crc(png_ptr);
  239.    }
  240. #endif
  241. #if defined(PNG_READ_pHYs_SUPPORTED)
  242.    else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4))
  243.    {
  244.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  245.       {
  246.          png_push_save_buffer(png_ptr);
  247.          return;
  248.       }
  249.       if (png_ptr->mode != PNG_HAVE_IHDR &&
  250.          png_ptr->mode != PNG_HAVE_PLTE)
  251.          png_error(png_ptr, "Out of place pHYs");
  252.       png_handle_pHYs(png_ptr, info, png_ptr->push_length);
  253.       png_push_check_crc(png_ptr);
  254.    }
  255. #endif
  256. #if defined(PNG_READ_oFFs_SUPPORTED)
  257.    else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4))
  258.    {
  259.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  260.       {
  261.          png_push_save_buffer(png_ptr);
  262.          return;
  263.       }
  264.       if (png_ptr->mode != PNG_HAVE_IHDR &&
  265.          png_ptr->mode != PNG_HAVE_PLTE)
  266.          png_error(png_ptr, "Out of place oFFs");
  267.       png_handle_oFFs(png_ptr, info, png_ptr->push_length);
  268.       png_push_check_crc(png_ptr);
  269.    }
  270. #endif
  271. #if defined(PNG_READ_tIME_SUPPORTED)
  272.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4))
  273.    {
  274.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  275.       {
  276.          png_push_save_buffer(png_ptr);
  277.          return;
  278.       }
  279.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  280.          png_ptr->mode == PNG_AFTER_IEND)
  281.          png_error(png_ptr, "Out of place tIME");
  282.       png_handle_tIME(png_ptr, info, png_ptr->push_length);
  283.       png_push_check_crc(png_ptr);
  284.    }
  285. #endif
  286. #if defined(PNG_READ_tEXt_SUPPORTED)
  287.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4))
  288.    {
  289.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  290.          png_ptr->mode == PNG_AFTER_IEND)
  291.          png_error(png_ptr, "Out of place tEXt");
  292.       png_push_handle_tEXt(png_ptr, png_ptr->push_length);
  293.    }
  294. #endif
  295. #if defined(PNG_READ_zTXt_SUPPORTED)
  296.    else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4))
  297.    {
  298.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  299.          png_ptr->mode == PNG_AFTER_IEND)
  300.          png_error(png_ptr, "Out of place zTXt");
  301.       png_push_handle_zTXt(png_ptr, png_ptr->push_length);
  302.    }
  303. #endif
  304.    else
  305.    {
  306.       if (png_ptr->push_chunk_name[0] <41 || png_ptr->push_chunk_name[0]> 122 ||
  307.           (png_ptr->push_chunk_name[0]>90 && png_ptr->push_chunk_name[0]< 97) ||
  308.           png_ptr->push_chunk_name[1] <41 || png_ptr->push_chunk_name[1]> 122 ||
  309.           (png_ptr->push_chunk_name[1]>90 && png_ptr->push_chunk_name[1]< 97) ||
  310.           png_ptr->push_chunk_name[2] <41 || png_ptr->push_chunk_name[2]> 122 ||
  311.           (png_ptr->push_chunk_name[2]>90 && png_ptr->push_chunk_name[2]< 97) ||
  312.           png_ptr->push_chunk_name[3] <41 || png_ptr->push_chunk_name[3]> 122 ||
  313.           (png_ptr->push_chunk_name[3]>90 && png_ptr->push_chunk_name[3]< 97))
  314.       {
  315.          char msg[200];
  316.          sprintf(msg, "Invalid chunk type 0x%02X 0x%02X 0x%02X 0x%02X",
  317.             png_ptr->push_chunk_name[0], png_ptr->push_chunk_name[1],
  318.             png_ptr->push_chunk_name[2], png_ptr->push_chunk_name[3]);
  319.          png_error(png_ptr, msg);
  320.       }
  321.       if ((png_ptr->push_chunk_name[0] & 0x20) == 0)
  322.       {
  323.          char msg[200];
  324.          sprintf(msg, "Unknown critical chunk %c%c%c%c",
  325.             png_ptr->push_chunk_name[0], png_ptr->push_chunk_name[1],
  326.             png_ptr->push_chunk_name[2], png_ptr->push_chunk_name[3]);
  327.          png_error(png_ptr, msg);
  328.       }
  329.       png_push_crc_skip(png_ptr, png_ptr->push_length);
  330.    }
  331.    png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  332. }
  333. void
  334. png_push_check_crc(png_structp png_ptr)
  335. {
  336.    png_byte crc_buf[4];
  337.    png_uint_32 crc;
  338.    png_push_fill_buffer(png_ptr, crc_buf, 4);
  339.    crc = png_get_uint_32(crc_buf);
  340.    if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
  341.       (png_ptr->crc & 0xffffffffL))
  342.       png_error(png_ptr, "Bad CRC value");
  343. }
  344. void
  345. png_push_crc_skip(png_structp png_ptr, png_uint_32 length)
  346. {
  347.    png_ptr->process_mode = PNG_SKIP_MODE;
  348.    png_ptr->skip_length = length;
  349. }
  350. void
  351. png_push_skip(png_structp png_ptr)
  352. {
  353.    if (png_ptr->skip_length && png_ptr->save_buffer_size)
  354.    {
  355.       png_uint_32 save_size;
  356.       if (png_ptr->skip_length < png_ptr->save_buffer_size)
  357.          save_size = png_ptr->skip_length;
  358.       else
  359.          save_size = png_ptr->save_buffer_size;
  360.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  361.       png_ptr->skip_length -= save_size;
  362.       png_ptr->buffer_size -= save_size;
  363.       png_ptr->save_buffer_size -= save_size;
  364.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  365.    }
  366.    if (png_ptr->skip_length && png_ptr->current_buffer_size)
  367.    {
  368.       png_uint_32 save_size;
  369.       if (png_ptr->skip_length < png_ptr->current_buffer_size)
  370.          save_size = png_ptr->skip_length;
  371.       else
  372.          save_size = png_ptr->current_buffer_size;
  373.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  374.       png_ptr->skip_length -= save_size;
  375.       png_ptr->buffer_size -= save_size;
  376.       png_ptr->current_buffer_size -= save_size;
  377.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  378.    }
  379.    if (!png_ptr->skip_length)
  380.    {
  381.       if (png_ptr->buffer_size < 4)
  382.       {
  383.          png_push_save_buffer(png_ptr);
  384.          return;
  385.       }
  386.       png_push_check_crc(png_ptr);
  387.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  388.    }
  389. }
  390. void
  391. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer,
  392.    png_uint_32 length)
  393. {
  394.    png_bytep ptr;
  395.    ptr = buffer;
  396.    if (png_ptr->save_buffer_size)
  397.    {
  398.       png_uint_32 save_size;
  399.       if (length < png_ptr->save_buffer_size)
  400.          save_size = length;
  401.       else
  402.          save_size = png_ptr->save_buffer_size;
  403.       png_memcpy(ptr, png_ptr->save_buffer_ptr, (png_size_t)save_size);
  404.       length -= save_size;
  405.       ptr += (png_size_t)save_size;
  406.       png_ptr->buffer_size -= save_size;
  407.       png_ptr->save_buffer_size -= save_size;
  408.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  409.    }
  410.    if (length && png_ptr->current_buffer_size)
  411.    {
  412.       png_uint_32 save_size;
  413.       if (length < png_ptr->current_buffer_size)
  414.          save_size = length;
  415.       else
  416.          save_size = png_ptr->current_buffer_size;
  417.       png_memcpy(ptr, png_ptr->current_buffer_ptr, (png_size_t)save_size);
  418.       png_ptr->buffer_size -= save_size;
  419.       png_ptr->current_buffer_size -= save_size;
  420.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  421.    }
  422. }
  423. void
  424. png_push_save_buffer(png_structp png_ptr)
  425. {
  426.    if (png_ptr->save_buffer_size)
  427.    {
  428.       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  429.       {
  430.          int i;
  431.          png_bytep sp;
  432.          png_bytep dp;
  433.          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  434.             i < png_ptr->save_buffer_size;
  435.             i++, sp++, dp++)
  436.          {
  437.             *dp = *sp;
  438.          }
  439.       }
  440.    }
  441.    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  442.       png_ptr->save_buffer_max)
  443.    {
  444.       int new_max;
  445.       png_bytep old_buffer;
  446.       new_max = (int)(png_ptr->save_buffer_size +
  447.          png_ptr->current_buffer_size + 256);
  448.       old_buffer = png_ptr->save_buffer;
  449.       png_ptr->save_buffer = (png_bytep)
  450.          png_large_malloc(png_ptr, new_max);
  451.       png_memcpy(png_ptr->save_buffer, old_buffer,
  452.          (png_size_t)png_ptr->save_buffer_size);
  453.       png_large_free(png_ptr, old_buffer);
  454.         png_ptr->save_buffer_max = new_max;
  455.    }
  456.    if (png_ptr->current_buffer_size)
  457.    {
  458.       png_memcpy(png_ptr->save_buffer +
  459.          (png_size_t)png_ptr->save_buffer_size,
  460.          png_ptr->current_buffer_ptr,
  461.          (png_size_t)png_ptr->current_buffer_size);
  462.       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  463.       png_ptr->current_buffer_size = 0;
  464.    }
  465.    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  466.    png_ptr->buffer_size = 0;
  467. }
  468. void
  469. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  470.    png_uint_32 buffer_length)
  471. {
  472.    png_ptr->current_buffer = buffer;
  473.    png_ptr->current_buffer_size = buffer_length;
  474.    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  475.    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  476. }
  477. void
  478. png_push_read_IDAT(png_structp png_ptr)
  479. {
  480.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  481.    {
  482.       png_byte chunk_start[8];
  483.       if (png_ptr->buffer_size < 8)
  484.       {
  485.          png_push_save_buffer(png_ptr);
  486.          return;
  487.       }
  488.       png_push_fill_buffer(png_ptr, chunk_start, 8);
  489.       png_ptr->push_length = png_get_uint_32(chunk_start);
  490.       png_memcpy(png_ptr->push_chunk_name,
  491.          (png_voidp)(chunk_start + 4), 4);
  492.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  493.       png_reset_crc(png_ptr);
  494.       png_calculate_crc(png_ptr, chunk_start + 4, 4);
  495.       if (png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  496.       {
  497.          png_ptr->process_mode = PNG_READ_END_MODE;
  498.          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  499.             png_error(png_ptr, "Not enough compressed data");
  500.          return;
  501.       }
  502.       png_ptr->idat_size = png_ptr->push_length;
  503.    }
  504.    if (png_ptr->idat_size && png_ptr->save_buffer_size)
  505.    {
  506.       png_uint_32 save_size;
  507.       if (png_ptr->idat_size < png_ptr->save_buffer_size)
  508.          save_size = png_ptr->idat_size;
  509.       else
  510.          save_size = png_ptr->save_buffer_size;
  511.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  512.       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  513.       png_ptr->idat_size -= save_size;
  514.       png_ptr->buffer_size -= save_size;
  515.       png_ptr->save_buffer_size -= save_size;
  516.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  517.    }
  518.    if (png_ptr->idat_size && png_ptr->current_buffer_size)
  519.    {
  520.       png_uint_32 save_size;
  521.       if (png_ptr->idat_size < png_ptr->current_buffer_size)
  522.          save_size = png_ptr->idat_size;
  523.       else
  524.          save_size = png_ptr->current_buffer_size;
  525.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  526.       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  527.       png_ptr->idat_size -= save_size;
  528.       png_ptr->buffer_size -= save_size;
  529.       png_ptr->current_buffer_size -= save_size;
  530.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  531.    }
  532.    if (!png_ptr->idat_size)
  533.    {
  534.       if (png_ptr->buffer_size < 4)
  535.       {
  536.          png_push_save_buffer(png_ptr);
  537.          return;
  538.       }
  539.       png_push_check_crc(png_ptr);
  540.       png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  541.    }
  542. }
  543. void
  544. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  545.    png_uint_32 buffer_length)
  546. {
  547.    int ret;
  548.    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
  549.       png_error(png_ptr, "Extra compression data");
  550.    png_ptr->zstream->next_in = buffer;
  551.    png_ptr->zstream->avail_in = (uInt)buffer_length;
  552.    do
  553.    {
  554.       ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  555.       if (ret == Z_STREAM_END)
  556.       {
  557.          if (png_ptr->zstream->avail_in)
  558.             png_error(png_ptr, "Extra compressed data");
  559.          if (!png_ptr->zstream->avail_out)
  560.          {
  561.             png_push_process_row(png_ptr);
  562.          }
  563.          png_ptr->mode = PNG_AT_LAST_IDAT;
  564.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  565.          break;
  566.       }
  567.       if (ret != Z_OK)
  568.          png_error(png_ptr, "Decompression Error");
  569.       if (!(png_ptr->zstream->avail_out))
  570.       {
  571.          png_push_process_row(png_ptr);
  572.          png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
  573.          png_ptr->zstream->next_out = png_ptr->row_buf;
  574.       }
  575.    } while (png_ptr->zstream->avail_in);
  576. }
  577. void
  578. png_push_process_row(png_structp png_ptr)
  579. {
  580.    png_ptr->row_info.color_type = png_ptr->color_type;
  581.    png_ptr->row_info.width = png_ptr->iwidth;
  582.    png_ptr->row_info.channels = png_ptr->channels;
  583.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  584.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  585.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  586.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  587.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  588.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  589.       (int)(png_ptr->row_buf[0]));
  590.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
  591.    if (png_ptr->transformations)
  592.       png_do_read_transformations(png_ptr);
  593. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  594.    /* blow up interlaced rows to full size */
  595.    if (png_ptr->interlaced &&
  596.       (png_ptr->transformations & PNG_INTERLACE))
  597.    {
  598.       if (png_ptr->pass < 6)
  599.          png_do_read_interlace(&(png_ptr->row_info),
  600.             png_ptr->row_buf + 1, png_ptr->pass);
  601.       switch (png_ptr->pass)
  602.       {
  603.          case 0:
  604.          {
  605.             int i;
  606.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  607.             {
  608.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  609.                png_read_push_finish_row(png_ptr);
  610.             }
  611.             break;
  612.          }
  613.          case 1:
  614.          {
  615.             int i;
  616.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  617.             {
  618.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  619.                png_read_push_finish_row(png_ptr);
  620.             }
  621.             if (png_ptr->pass == 2)
  622.             {
  623.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  624.                {
  625.                   png_push_have_row(png_ptr, NULL);
  626.                   png_read_push_finish_row(png_ptr);
  627.                }
  628.             }
  629.             break;
  630.          }
  631.          case 2:
  632.          {
  633.             int i;
  634.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  635.             {
  636.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  637.                png_read_push_finish_row(png_ptr);
  638.             }
  639.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  640.             {
  641.                png_push_have_row(png_ptr, NULL);
  642.                png_read_push_finish_row(png_ptr);
  643.             }
  644.             break;
  645.          }
  646.          case 3:
  647.          {
  648.             int i;
  649.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  650.             {
  651.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  652.                png_read_push_finish_row(png_ptr);
  653.             }
  654.             if (png_ptr->pass == 4)
  655.             {
  656.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  657.                {
  658.                   png_push_have_row(png_ptr, NULL);
  659.                   png_read_push_finish_row(png_ptr);
  660.                }
  661.             }
  662.             break;
  663.          }
  664.          case 4:
  665.          {
  666.             int i;
  667.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  668.             {
  669.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  670.                png_read_push_finish_row(png_ptr);
  671.             }
  672.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  673.             {
  674.                png_push_have_row(png_ptr, NULL);
  675.                png_read_push_finish_row(png_ptr);
  676.             }
  677.             break;
  678.          }
  679.          case 5:
  680.          {
  681.             int i;
  682.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  683.             {
  684.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  685.                png_read_push_finish_row(png_ptr);
  686.             }
  687.             if (png_ptr->pass == 6)
  688.             {
  689.                png_push_have_row(png_ptr, NULL);
  690.                png_read_push_finish_row(png_ptr);
  691.             }
  692.             break;
  693.          }
  694.          case 6:
  695.          {
  696.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  697.             png_read_push_finish_row(png_ptr);
  698.             if (png_ptr->pass != 6)
  699.                break;
  700.             png_push_have_row(png_ptr, NULL);
  701.             png_read_push_finish_row(png_ptr);
  702.          }
  703.       }
  704.    }
  705.    else
  706. #endif
  707.    {
  708.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  709.       png_read_push_finish_row(png_ptr);
  710.    }
  711. }
  712. void
  713. png_read_push_finish_row(png_structp png_ptr)
  714. {
  715.    png_ptr->row_number++;
  716.    if (png_ptr->row_number < png_ptr->num_rows)
  717.       return;
  718.    if (png_ptr->interlaced)
  719.    {
  720.       png_ptr->row_number = 0;
  721.       png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  722.       do
  723.       {
  724.          png_ptr->pass++;
  725.          if (png_ptr->pass >= 7)
  726.             break;
  727.          png_ptr->iwidth = (png_ptr->width +
  728.             png_pass_inc[png_ptr->pass] - 1 -
  729.             png_pass_start[png_ptr->pass]) /
  730.             png_pass_inc[png_ptr->pass];
  731.          png_ptr->irowbytes = ((png_ptr->iwidth *
  732.             png_ptr->pixel_depth + 7) >> 3) + 1;
  733.          if (!(png_ptr->transformations & PNG_INTERLACE))
  734.          {
  735.             png_ptr->num_rows = (png_ptr->height +
  736.                png_pass_yinc[png_ptr->pass] - 1 -
  737.                png_pass_ystart[png_ptr->pass]) /
  738.                png_pass_yinc[png_ptr->pass];
  739.             if (!(png_ptr->num_rows))
  740.                continue;
  741.          }
  742.          if (png_ptr->transformations & PNG_INTERLACE)
  743.             break;
  744.       } while (png_ptr->iwidth == 0);
  745.    }
  746. }
  747. void
  748. png_push_handle_PLTE(png_structp png_ptr, png_uint_32 length)
  749. {
  750.    if (length % 3)
  751.       png_error(png_ptr, "Invalid palette chunk");
  752.    png_ptr->num_palette = (png_uint_16)(length / 3);
  753.    png_ptr->cur_palette = 0;
  754.    png_ptr->palette = (png_colorp)png_large_malloc(png_ptr,
  755.       png_ptr->num_palette * sizeof (png_color));
  756.    png_ptr->process_mode = PNG_READ_PLTE_MODE;
  757. }
  758. void
  759. png_push_read_PLTE(png_structp png_ptr, png_infop info)
  760. {
  761.    while (png_ptr->cur_palette < png_ptr->num_palette &&
  762.       png_ptr->buffer_size >= 3)
  763.    {
  764.       png_byte buf[3];
  765.       png_push_fill_buffer(png_ptr, buf, 3);
  766.       png_calculate_crc(png_ptr, buf, 3);
  767.       /* don't depend upon png_color being any order */
  768.       png_ptr->palette[png_ptr->cur_palette].red = buf[0];
  769.       png_ptr->palette[png_ptr->cur_palette].green = buf[1];
  770.       png_ptr->palette[png_ptr->cur_palette].blue = buf[2];
  771.       png_ptr->cur_palette++;
  772.    }
  773.    if (png_ptr->cur_palette == png_ptr->num_palette &&
  774.       png_ptr->buffer_size >= 4)
  775.    {
  776.       png_push_check_crc(png_ptr);
  777.       png_read_PLTE(png_ptr, info, png_ptr->palette, png_ptr->num_palette);
  778.       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  779.    }
  780.    else
  781.    {
  782.       png_push_save_buffer(png_ptr);
  783.    }
  784. }
  785. #if defined(PNG_READ_tEXt_SUPPORTED)
  786. void
  787. png_push_handle_tEXt(png_structp png_ptr, png_uint_32 length)
  788. {
  789.    png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1);
  790.    png_ptr->current_text[(png_size_t)length] = '';
  791.    png_ptr->current_text_ptr = png_ptr->current_text;
  792.    png_ptr->current_text_size = length;
  793.    png_ptr->current_text_left = length;
  794.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  795. }
  796. void
  797. png_push_read_tEXt(png_structp png_ptr, png_infop info)
  798. {
  799.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  800.    {
  801.       png_uint_32 text_size;
  802.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  803.          text_size = png_ptr->buffer_size;
  804.       else
  805.          text_size = png_ptr->current_text_left;
  806.       png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  807.          text_size);
  808.       png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  809.          text_size);
  810.       png_ptr->current_text_left -= text_size;
  811.       png_ptr->current_text_ptr += (png_size_t)text_size;
  812.    }
  813.    if (!(png_ptr->current_text_left))
  814.    {
  815.       png_charp text;
  816.       png_charp key;
  817.       if (png_ptr->buffer_size < 4)
  818.       {
  819.          png_push_save_buffer(png_ptr);
  820.          return;
  821.       }
  822.       png_push_check_crc(png_ptr);
  823.       key = png_ptr->current_text;
  824.       png_ptr->current_text = 0;
  825.       for (text = key; *text; text++)
  826.          /* empty loop */ ;
  827.       if (text != key + (png_size_t)png_ptr->current_text_size)
  828.          text++;
  829.       png_read_tEXt(png_ptr, info, key, text,
  830.          png_ptr->current_text_size - (text - key));
  831.       if (png_ptr->mode == PNG_AT_LAST_IDAT ||
  832.          png_ptr->mode == PNG_AFTER_IDAT)
  833.       {
  834.          png_ptr->process_mode = PNG_READ_END_MODE;
  835.       }
  836.       else
  837.       {
  838.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  839.       }
  840.    }
  841. }
  842. #endif
  843. #if defined(PNG_READ_zTXt_SUPPORTED)
  844. void
  845. png_push_handle_zTXt(png_structp png_ptr,
  846.    png_uint_32 length)
  847. {
  848.    png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1);
  849.    png_ptr->current_text[(png_size_t)length] = '';
  850.    png_ptr->current_text_ptr = png_ptr->current_text;
  851.    png_ptr->current_text_size = length;
  852.    png_ptr->current_text_left = length;
  853.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  854. }
  855. void
  856. png_push_read_zTXt(png_structp png_ptr, png_infop info)
  857. {
  858.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  859.    {
  860.       png_uint_32 text_size;
  861.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  862.          text_size = png_ptr->buffer_size;
  863.       else
  864.          text_size = png_ptr->current_text_left;
  865.       png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  866.          text_size);
  867.       png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  868.          text_size);
  869.       png_ptr->current_text_left -= text_size;
  870.       png_ptr->current_text_ptr += (png_size_t)text_size;
  871.    }
  872.    if (!(png_ptr->current_text_left))
  873.    {
  874.       png_charp text;
  875.       png_charp key;
  876.       int ret;
  877.       png_uint_32 text_size, key_size;
  878.       if (png_ptr->buffer_size < 4)
  879.       {
  880.          png_push_save_buffer(png_ptr);
  881.          return;
  882.       }
  883.       png_push_check_crc(png_ptr);
  884.       key = png_ptr->current_text;
  885.       png_ptr->current_text = 0;
  886.       for (text = key; *text; text++)
  887.          /* empty loop */ ;
  888.       /* zTXt can't have zero text */
  889.       if (text == key + (png_size_t)png_ptr->current_text_size)
  890.       {
  891.          png_large_free(png_ptr, key);
  892.          return;
  893.       }
  894.       text++;
  895.       if (*text) /* check compression byte */
  896.       {
  897.          png_large_free(png_ptr, key);
  898.          return;
  899.       }
  900.       text++;
  901.       png_ptr->zstream->next_in = (png_bytep )text;
  902.       png_ptr->zstream->avail_in = (uInt)(png_ptr->current_text_size -
  903.          (text - key));
  904.       png_ptr->zstream->next_out = png_ptr->zbuf;
  905.       png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
  906.       key_size = text - key;
  907.       text_size = 0;
  908.       text = NULL;
  909.       ret = Z_STREAM_END;
  910.       while (png_ptr->zstream->avail_in)
  911.       {
  912.          ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  913.          if (ret != Z_OK && ret != Z_STREAM_END)
  914.          {
  915.             inflateReset(png_ptr->zstream);
  916.             png_ptr->zstream->avail_in = 0;
  917.             png_large_free(png_ptr, key);
  918.             png_large_free(png_ptr, text);
  919.             return;
  920.          }
  921.          if (!png_ptr->zstream->avail_out || ret == Z_STREAM_END)
  922.          {
  923.             if (!text)
  924.             {
  925.                text = (png_charp)png_large_malloc(png_ptr,
  926.                   png_ptr->zbuf_size - png_ptr->zstream->avail_out +
  927.                      key_size + 1);
  928.                png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
  929.                   (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  930.                png_memcpy(text, key, (png_size_t)key_size);
  931.                text_size = key_size + (png_size_t)png_ptr->zbuf_size -
  932.                   png_ptr->zstream->avail_out;
  933.                *(text + (png_size_t)text_size) = '';
  934.             }
  935.             else
  936.             {
  937.                png_charp tmp;
  938.                tmp = text;
  939.                text = png_large_malloc(png_ptr, text_size +
  940.                   png_ptr->zbuf_size - png_ptr->zstream->avail_out + 1);
  941.                png_memcpy(text, tmp, (png_size_t)text_size);
  942.                png_large_free(png_ptr, tmp);
  943.                png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
  944.                   (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  945.                text_size += png_ptr->zbuf_size - png_ptr->zstream->avail_out;
  946.                *(text + (png_size_t)text_size) = '';
  947.             }
  948.             if (ret != Z_STREAM_END)
  949.             {
  950.                png_ptr->zstream->next_out = png_ptr->zbuf;
  951.                png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  952.             }
  953.          }
  954.          else
  955.          {
  956.             break;
  957.          }
  958.          if (ret == Z_STREAM_END)
  959.             break;
  960.       }
  961.       inflateReset(png_ptr->zstream);
  962.       png_ptr->zstream->avail_in = 0;
  963.       if (ret != Z_STREAM_END)
  964.       {
  965.          png_large_free(png_ptr, key);
  966.          png_large_free(png_ptr, text);
  967.          return;
  968.       }
  969.       png_large_free(png_ptr, key);
  970.       key = text;
  971.       text += (png_size_t)key_size;
  972.       text_size -= key_size;
  973.       png_read_zTXt(png_ptr, info, key, text, text_size, 0);
  974.       if (png_ptr->mode == PNG_AT_LAST_IDAT ||
  975.          png_ptr->mode == PNG_AFTER_IDAT)
  976.       {
  977.          png_ptr->process_mode = PNG_READ_END_MODE;
  978.       }
  979.       else
  980.       {
  981.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  982.       }
  983.    }
  984. }
  985. #endif
  986. void
  987. png_push_have_info(png_structp png_ptr, png_infop info)
  988. {
  989.    if (png_ptr->info_fn)
  990.       (*(png_ptr->info_fn))(png_ptr, info);
  991. }
  992. void
  993. png_push_have_end(png_structp png_ptr, png_infop info)
  994. {
  995.    if (png_ptr->end_fn)
  996.       (*(png_ptr->end_fn))(png_ptr, info);
  997. }
  998. void
  999. png_push_have_row(png_structp png_ptr, png_bytep row)
  1000. {
  1001.    if (png_ptr->row_fn)
  1002.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1003.          (int)png_ptr->pass);
  1004. }
  1005. png_voidp
  1006. png_get_progressive_ptr(png_structp png_ptr)
  1007. {
  1008.    return png_ptr->io_ptr;
  1009. }
  1010. void
  1011. png_push_read_end(png_structp png_ptr, png_infop info)
  1012. {
  1013.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  1014.    {
  1015.       png_byte chunk_start[8];
  1016.       if (png_ptr->buffer_size < 8)
  1017.       {
  1018.          png_push_save_buffer(png_ptr);
  1019.          return;
  1020.       }
  1021.       png_push_fill_buffer(png_ptr, chunk_start, 8);
  1022.       png_ptr->push_length = png_get_uint_32(chunk_start);
  1023.       png_memcpy(png_ptr->push_chunk_name, (png_voidp)(chunk_start + 4), 4);
  1024.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  1025.       png_reset_crc(png_ptr);
  1026.       png_calculate_crc(png_ptr, chunk_start + 4, 4);
  1027.    }
  1028.    if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4))
  1029.    {
  1030.       png_error(png_ptr, "Invalid IHDR after IDAT");
  1031.    }
  1032.    else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4))
  1033.    {
  1034.       png_error(png_ptr, "Invalid PLTE after IDAT");
  1035.    }
  1036.    else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  1037.    {
  1038.       if (png_ptr->push_length > 0 || png_ptr->mode != PNG_AT_LAST_IDAT)
  1039.          png_error(png_ptr, "Too many IDAT's found");
  1040.    }
  1041.    else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4))
  1042.    {
  1043.       if (png_ptr->push_length)
  1044.          png_error(png_ptr, "Invalid IEND chunk");
  1045.       if (png_ptr->buffer_size < 4)
  1046.       {
  1047.          png_push_save_buffer(png_ptr);
  1048.          return;
  1049.       }
  1050.       png_push_check_crc(png_ptr);
  1051.       png_ptr->mode = PNG_AFTER_IEND;
  1052.       png_ptr->process_mode = PNG_READ_DONE_MODE;
  1053.       png_push_have_end(png_ptr, info);
  1054.    }
  1055. #if defined(PNG_READ_gAMA_SUPPORTED)
  1056.    else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4))
  1057.    {
  1058.       png_error(png_ptr, "Invalid gAMA after IDAT");
  1059.    }
  1060. #endif
  1061. #if defined(PNG_READ_sBIT_SUPPORTED)
  1062.    else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4))
  1063.    {
  1064.       png_error(png_ptr, "Invalid sBIT after IDAT");
  1065.    }
  1066. #endif
  1067. #if defined(PNG_READ_cHRM_SUPPORTED)
  1068.    else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4))
  1069.    {
  1070.       png_error(png_ptr, "Invalid cHRM after IDAT");
  1071.    }
  1072. #endif
  1073. #if defined(PNG_READ_tRNS_SUPPORTED)
  1074.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4))
  1075.    {
  1076.       png_error(png_ptr, "Invalid tRNS after IDAT");
  1077.    }
  1078. #endif
  1079. #if defined(PNG_READ_bKGD_SUPPORTED)
  1080.    else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4))
  1081.    {
  1082.       png_error(png_ptr, "Invalid bKGD after IDAT");
  1083.    }
  1084. #endif
  1085. #if defined(PNG_READ_hIST_SUPPORTED)
  1086.    else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4))
  1087.    {
  1088.       png_error(png_ptr, "Invalid hIST after IDAT");
  1089.    }
  1090. #endif
  1091. #if defined(PNG_READ_pHYs_SUPPORTED)
  1092.    else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4))
  1093.    {
  1094.       png_error(png_ptr, "Invalid pHYs after IDAT");
  1095.    }
  1096. #endif
  1097. #if defined(PNG_READ_oFFs_SUPPORTED)
  1098.    else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4))
  1099.    {
  1100.       png_error(png_ptr, "Invalid oFFs after IDAT");
  1101.    }
  1102. #endif
  1103. #if defined(PNG_READ_tIME_SUPPORTED)
  1104.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4))
  1105.    {
  1106.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  1107.       {
  1108.          png_push_save_buffer(png_ptr);
  1109.          return;
  1110.       }
  1111.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1112.          png_ptr->mode == PNG_AFTER_IEND)
  1113.          png_error(png_ptr, "Out of place tIME");
  1114.       png_handle_tIME(png_ptr, info, png_ptr->push_length);
  1115.       png_push_check_crc(png_ptr);
  1116.    }
  1117. #endif
  1118. #if defined(PNG_READ_tEXt_SUPPORTED)
  1119.    else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4))
  1120.    {
  1121.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1122.          png_ptr->mode == PNG_AFTER_IEND)
  1123.          png_error(png_ptr, "Out of place tEXt");
  1124.       png_push_handle_tEXt(png_ptr, png_ptr->push_length);
  1125.    }
  1126. #endif
  1127. #if defined(PNG_READ_zTXt_SUPPORTED)
  1128.    else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4))
  1129.    {
  1130.       if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1131.          png_ptr->mode == PNG_AFTER_IEND)
  1132.          png_error(png_ptr, "Out of place zTXt");
  1133.       png_push_handle_zTXt(png_ptr, png_ptr->push_length);
  1134.    }
  1135. #endif
  1136.    else
  1137.    {
  1138.       if (png_ptr->push_chunk_name[0] <41 || png_ptr->push_chunk_name[0]> 122 ||
  1139.           (png_ptr->push_chunk_name[0]>90 && png_ptr->push_chunk_name[0]< 97) ||
  1140.           png_ptr->push_chunk_name[1] <41 || png_ptr->push_chunk_name[1]> 122 ||
  1141.           (png_ptr->push_chunk_name[1]>90 && png_ptr->push_chunk_name[1]< 97) ||
  1142.           png_ptr->push_chunk_name[2] <41 || png_ptr->push_chunk_name[2]> 122 ||
  1143.           (png_ptr->push_chunk_name[2]>90 && png_ptr->push_chunk_name[2]< 97) ||
  1144.           png_ptr->push_chunk_name[3] <41 || png_ptr->push_chunk_name[3]> 122 ||
  1145.           (png_ptr->push_chunk_name[3]>90 && png_ptr->push_chunk_name[3]< 97))
  1146.       {
  1147.          char msg[45];
  1148.          sprintf(msg, "Invalid chunk type 0x%02X 0x%02X 0x%02X 0x%02X",
  1149.             png_ptr->push_chunk_name[0], png_ptr->push_chunk_name[1],
  1150.             png_ptr->push_chunk_name[2], png_ptr->push_chunk_name[3]);
  1151.          png_error(png_ptr, msg);
  1152.       }
  1153.       if ((png_ptr->push_chunk_name[0] & 0x20) == 0)
  1154.       {
  1155.          char msg[40];
  1156.          sprintf(msg, "Unknown critical chunk %c%c%c%c",
  1157.             png_ptr->push_chunk_name[0], png_ptr->push_chunk_name[1],
  1158.             png_ptr->push_chunk_name[2], png_ptr->push_chunk_name[3]);
  1159.          png_error(png_ptr, msg);
  1160.       }
  1161.       png_push_crc_skip(png_ptr, png_ptr->push_length);
  1162.    }
  1163.    if (png_ptr->mode == PNG_AT_LAST_IDAT)
  1164.       png_ptr->mode = PNG_AFTER_IDAT;
  1165.    png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  1166. }
  1167. void
  1168. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1169.    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1170.    png_progressive_end_ptr end_fn)
  1171. {
  1172.    png_ptr->info_fn = info_fn;
  1173.    png_ptr->row_fn = row_fn;
  1174.    png_ptr->end_fn = end_fn;
  1175.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1176. }
  1177. void
  1178. png_progressive_combine_row (png_structp png_ptr,
  1179.    png_bytep old_row, png_bytep new_row)
  1180. {
  1181.    if (new_row)
  1182.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1183. }
  1184. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */