Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. /* pngread.c - read a PNG file
  3.  *
  4.  * Last changed in libpng 1.5.1 [$RDATE%]
  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.  * This file contains routines that an application calls directly to
  14.  * read a PNG file or stream.
  15.  */
  16.  
  17. #include "pngpriv.h"
  18.  
  19. #ifdef PNG_READ_SUPPORTED
  20.  
  21. /* Create a PNG structure for reading, and allocate any memory needed. */
  22. PNG_FUNCTION(png_structp,PNGAPI
  23. png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
  24.     png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
  25. {
  26.  
  27. #ifdef PNG_USER_MEM_SUPPORTED
  28.    return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
  29.        warn_fn, NULL, NULL, NULL));
  30. }
  31.  
  32. /* Alternate create PNG structure for reading, and allocate any memory
  33.  * needed.
  34.  */
  35. PNG_FUNCTION(png_structp,PNGAPI
  36. png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
  37.     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
  38.     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
  39. {
  40. #endif /* PNG_USER_MEM_SUPPORTED */
  41.  
  42. #ifdef PNG_SETJMP_SUPPORTED
  43.    volatile
  44. #endif
  45.    png_structp png_ptr;
  46.    volatile int png_cleanup_needed = 0;
  47.  
  48. #ifdef PNG_SETJMP_SUPPORTED
  49. #ifdef USE_FAR_KEYWORD
  50.    jmp_buf png_jmpbuf;
  51. #endif
  52. #endif
  53.  
  54.    int i;
  55.  
  56.    png_debug(1, "in png_create_read_struct");
  57.  
  58. #ifdef PNG_USER_MEM_SUPPORTED
  59.    png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
  60.        malloc_fn, mem_ptr);
  61. #else
  62.    png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
  63. #endif
  64.    if (png_ptr == NULL)
  65.       return (NULL);
  66.  
  67.    /* Added at libpng-1.2.6 */
  68. #ifdef PNG_USER_LIMITS_SUPPORTED
  69.    png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
  70.    png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
  71.  
  72. #  ifdef PNG_USER_CHUNK_CACHE_MAX
  73.    /* Added at libpng-1.2.43 and 1.4.0 */
  74.    png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
  75. #  endif
  76.  
  77. #  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
  78.    /* Added at libpng-1.2.43 and 1.4.1 */
  79.    png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
  80. #  endif
  81. #endif
  82.  
  83. #ifdef PNG_SETJMP_SUPPORTED
  84. /* Applications that neglect to set up their own setjmp() and then
  85.    encounter a png_error() will longjmp here.  Since the jmpbuf is
  86.    then meaningless we abort instead of returning. */
  87. #ifdef USE_FAR_KEYWORD
  88.    if (setjmp(png_jmpbuf))
  89. #else
  90.    if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
  91. #endif
  92.       PNG_ABORT();
  93. #ifdef USE_FAR_KEYWORD
  94.    png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf));
  95. #endif
  96. #endif /* PNG_SETJMP_SUPPORTED */
  97.  
  98. #ifdef PNG_USER_MEM_SUPPORTED
  99.    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
  100. #endif
  101.  
  102.    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
  103.  
  104.    if (user_png_ver)
  105.    {
  106.       i = 0;
  107.  
  108.       do
  109.       {
  110.          if (user_png_ver[i] != png_libpng_ver[i])
  111.             png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
  112.       } while (png_libpng_ver[i++]);
  113.    }
  114.  
  115.    else
  116.       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
  117.  
  118.  
  119.    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
  120.    {
  121.      /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
  122.       * we must recompile any applications that use any older library version.
  123.       * For versions after libpng 1.0, we will be compatible, so we need
  124.       * only check the first digit.
  125.       */
  126.       if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
  127.           (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
  128.           (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
  129.       {
  130. #ifdef PNG_CONSOLE_IO_SUPPORTED
  131.          char msg[80];
  132.          if (user_png_ver)
  133.          {
  134.             png_snprintf2(msg, 80,
  135.                 "Application built with libpng-%.20s"
  136.                 " but running with %.20s",
  137.                 user_png_ver,
  138.                 png_libpng_ver);
  139.             png_warning(png_ptr, msg);
  140.          }
  141. #else
  142.          png_warning(png_ptr,
  143.              "Incompatible libpng version in application and library");
  144. #endif
  145. #ifdef PNG_ERROR_NUMBERS_SUPPORTED
  146.          png_ptr->flags = 0;
  147. #endif
  148.  
  149.          png_cleanup_needed = 1;
  150.       }
  151.    }
  152.  
  153.    if (!png_cleanup_needed)
  154.    {
  155.    /* Initialize zbuf - compression buffer */
  156.    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
  157.    png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size);
  158.  
  159.    if (png_ptr->zbuf == NULL)
  160.       png_cleanup_needed = 1;
  161.    }
  162.  
  163.    png_ptr->zstream.zalloc = png_zalloc;
  164.    png_ptr->zstream.zfree = png_zfree;
  165.    png_ptr->zstream.opaque = (voidpf)png_ptr;
  166.  
  167.    if (!png_cleanup_needed)
  168.    {
  169.       switch (inflateInit(&png_ptr->zstream))
  170.       {
  171.          case Z_OK:
  172.             break; /* Do nothing */
  173.  
  174.          case Z_MEM_ERROR:
  175.             png_warning(png_ptr, "zlib memory error");
  176.             png_cleanup_needed = 1;
  177.             break;
  178.  
  179.          case Z_STREAM_ERROR:
  180.             png_warning(png_ptr, "zlib stream error");
  181.             png_cleanup_needed = 1;
  182.             break;
  183.  
  184.          case Z_VERSION_ERROR:
  185.             png_warning(png_ptr, "zlib version error");
  186.             png_cleanup_needed = 1;
  187.             break;
  188.  
  189.          default: png_warning(png_ptr, "Unknown zlib error");
  190.             png_cleanup_needed = 1;
  191.       }
  192.    }
  193.  
  194.    if (png_cleanup_needed)
  195.    {
  196.       /* Clean up PNG structure and deallocate any memory. */
  197.       png_free(png_ptr, png_ptr->zbuf);
  198.       png_ptr->zbuf = NULL;
  199. #ifdef PNG_USER_MEM_SUPPORTED
  200.       png_destroy_struct_2((png_voidp)png_ptr,
  201.           (png_free_ptr)free_fn, (png_voidp)mem_ptr);
  202. #else
  203.       png_destroy_struct((png_voidp)png_ptr);
  204. #endif
  205.       return (NULL);
  206.    }
  207.  
  208.    png_ptr->zstream.next_out = png_ptr->zbuf;
  209.    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  210.  
  211.    png_set_read_fn(png_ptr, NULL, NULL);
  212.  
  213.  
  214.    return (png_ptr);
  215. }
  216.  
  217.  
  218. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  219. /* Read the information before the actual image data.  This has been
  220.  * changed in v0.90 to allow reading a file that already has the magic
  221.  * bytes read from the stream.  You can tell libpng how many bytes have
  222.  * been read from the beginning of the stream (up to the maximum of 8)
  223.  * via png_set_sig_bytes(), and we will only check the remaining bytes
  224.  * here.  The application can then have access to the signature bytes we
  225.  * read if it is determined that this isn't a valid PNG file.
  226.  */
  227. void PNGAPI
  228. png_read_info(png_structp png_ptr, png_infop info_ptr)
  229. {
  230.    png_debug(1, "in png_read_info");
  231.  
  232.    if (png_ptr == NULL || info_ptr == NULL)
  233.       return;
  234.  
  235.    /* Read and check the PNG file signature. */
  236.    png_read_sig(png_ptr, info_ptr);
  237.  
  238.    for (;;)
  239.    {
  240.       PNG_IHDR;
  241.       PNG_IDAT;
  242.       PNG_IEND;
  243.       PNG_PLTE;
  244. #ifdef PNG_READ_bKGD_SUPPORTED
  245.       PNG_bKGD;
  246. #endif
  247. #ifdef PNG_READ_cHRM_SUPPORTED
  248.       PNG_cHRM;
  249. #endif
  250. #ifdef PNG_READ_gAMA_SUPPORTED
  251.       PNG_gAMA;
  252. #endif
  253. #ifdef PNG_READ_hIST_SUPPORTED
  254.       PNG_hIST;
  255. #endif
  256. #ifdef PNG_READ_iCCP_SUPPORTED
  257.       PNG_iCCP;
  258. #endif
  259. #ifdef PNG_READ_iTXt_SUPPORTED
  260.       PNG_iTXt;
  261. #endif
  262. #ifdef PNG_READ_oFFs_SUPPORTED
  263.       PNG_oFFs;
  264. #endif
  265. #ifdef PNG_READ_pCAL_SUPPORTED
  266.       PNG_pCAL;
  267. #endif
  268. #ifdef PNG_READ_pHYs_SUPPORTED
  269.       PNG_pHYs;
  270. #endif
  271. #ifdef PNG_READ_sBIT_SUPPORTED
  272.       PNG_sBIT;
  273. #endif
  274. #ifdef PNG_READ_sCAL_SUPPORTED
  275.       PNG_sCAL;
  276. #endif
  277. #ifdef PNG_READ_sPLT_SUPPORTED
  278.       PNG_sPLT;
  279. #endif
  280. #ifdef PNG_READ_sRGB_SUPPORTED
  281.       PNG_sRGB;
  282. #endif
  283. #ifdef PNG_READ_tEXt_SUPPORTED
  284.       PNG_tEXt;
  285. #endif
  286. #ifdef PNG_READ_tIME_SUPPORTED
  287.       PNG_tIME;
  288. #endif
  289. #ifdef PNG_READ_tRNS_SUPPORTED
  290.       PNG_tRNS;
  291. #endif
  292. #ifdef PNG_READ_zTXt_SUPPORTED
  293.       PNG_zTXt;
  294. #endif
  295.       png_uint_32 length = png_read_chunk_header(png_ptr);
  296.       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
  297.  
  298.       /* This should be a binary subdivision search or a hash for
  299.        * matching the chunk name rather than a linear search.
  300.        */
  301.       if (!png_memcmp(chunk_name, png_IDAT, 4))
  302.          if (png_ptr->mode & PNG_AFTER_IDAT)
  303.             png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
  304.  
  305.       if (!png_memcmp(chunk_name, png_IHDR, 4))
  306.          png_handle_IHDR(png_ptr, info_ptr, length);
  307.  
  308.       else if (!png_memcmp(chunk_name, png_IEND, 4))
  309.          png_handle_IEND(png_ptr, info_ptr, length);
  310.  
  311. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  312.       else if (png_handle_as_unknown(png_ptr, chunk_name))
  313.       {
  314.          if (!png_memcmp(chunk_name, png_IDAT, 4))
  315.             png_ptr->mode |= PNG_HAVE_IDAT;
  316.  
  317.          png_handle_unknown(png_ptr, info_ptr, length);
  318.  
  319.          if (!png_memcmp(chunk_name, png_PLTE, 4))
  320.             png_ptr->mode |= PNG_HAVE_PLTE;
  321.  
  322.          else if (!png_memcmp(chunk_name, png_IDAT, 4))
  323.          {
  324.             if (!(png_ptr->mode & PNG_HAVE_IHDR))
  325.                png_error(png_ptr, "Missing IHDR before IDAT");
  326.  
  327.             else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  328.                 !(png_ptr->mode & PNG_HAVE_PLTE))
  329.                png_error(png_ptr, "Missing PLTE before IDAT");
  330.  
  331.             break;
  332.          }
  333.       }
  334. #endif
  335.       else if (!png_memcmp(chunk_name, png_PLTE, 4))
  336.          png_handle_PLTE(png_ptr, info_ptr, length);
  337.  
  338.       else if (!png_memcmp(chunk_name, png_IDAT, 4))
  339.       {
  340.          if (!(png_ptr->mode & PNG_HAVE_IHDR))
  341.             png_error(png_ptr, "Missing IHDR before IDAT");
  342.  
  343.          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  344.              !(png_ptr->mode & PNG_HAVE_PLTE))
  345.             png_error(png_ptr, "Missing PLTE before IDAT");
  346.  
  347.          png_ptr->idat_size = length;
  348.          png_ptr->mode |= PNG_HAVE_IDAT;
  349.          break;
  350.       }
  351.  
  352. #ifdef PNG_READ_bKGD_SUPPORTED
  353.       else if (!png_memcmp(chunk_name, png_bKGD, 4))
  354.          png_handle_bKGD(png_ptr, info_ptr, length);
  355. #endif
  356.  
  357. #ifdef PNG_READ_cHRM_SUPPORTED
  358.       else if (!png_memcmp(chunk_name, png_cHRM, 4))
  359.          png_handle_cHRM(png_ptr, info_ptr, length);
  360. #endif
  361.  
  362. #ifdef PNG_READ_gAMA_SUPPORTED
  363.       else if (!png_memcmp(chunk_name, png_gAMA, 4))
  364.          png_handle_gAMA(png_ptr, info_ptr, length);
  365. #endif
  366.  
  367. #ifdef PNG_READ_hIST_SUPPORTED
  368.       else if (!png_memcmp(chunk_name, png_hIST, 4))
  369.          png_handle_hIST(png_ptr, info_ptr, length);
  370. #endif
  371.  
  372. #ifdef PNG_READ_oFFs_SUPPORTED
  373.       else if (!png_memcmp(chunk_name, png_oFFs, 4))
  374.          png_handle_oFFs(png_ptr, info_ptr, length);
  375. #endif
  376.  
  377. #ifdef PNG_READ_pCAL_SUPPORTED
  378.       else if (!png_memcmp(chunk_name, png_pCAL, 4))
  379.          png_handle_pCAL(png_ptr, info_ptr, length);
  380. #endif
  381.  
  382. #ifdef PNG_READ_sCAL_SUPPORTED
  383.       else if (!png_memcmp(chunk_name, png_sCAL, 4))
  384.          png_handle_sCAL(png_ptr, info_ptr, length);
  385. #endif
  386.  
  387. #ifdef PNG_READ_pHYs_SUPPORTED
  388.       else if (!png_memcmp(chunk_name, png_pHYs, 4))
  389.          png_handle_pHYs(png_ptr, info_ptr, length);
  390. #endif
  391.  
  392. #ifdef PNG_READ_sBIT_SUPPORTED
  393.       else if (!png_memcmp(chunk_name, png_sBIT, 4))
  394.          png_handle_sBIT(png_ptr, info_ptr, length);
  395. #endif
  396.  
  397. #ifdef PNG_READ_sRGB_SUPPORTED
  398.       else if (!png_memcmp(chunk_name, png_sRGB, 4))
  399.          png_handle_sRGB(png_ptr, info_ptr, length);
  400. #endif
  401.  
  402. #ifdef PNG_READ_iCCP_SUPPORTED
  403.       else if (!png_memcmp(chunk_name, png_iCCP, 4))
  404.          png_handle_iCCP(png_ptr, info_ptr, length);
  405. #endif
  406.  
  407. #ifdef PNG_READ_sPLT_SUPPORTED
  408.       else if (!png_memcmp(chunk_name, png_sPLT, 4))
  409.          png_handle_sPLT(png_ptr, info_ptr, length);
  410. #endif
  411.  
  412. #ifdef PNG_READ_tEXt_SUPPORTED
  413.       else if (!png_memcmp(chunk_name, png_tEXt, 4))
  414.          png_handle_tEXt(png_ptr, info_ptr, length);
  415. #endif
  416.  
  417. #ifdef PNG_READ_tIME_SUPPORTED
  418.       else if (!png_memcmp(chunk_name, png_tIME, 4))
  419.          png_handle_tIME(png_ptr, info_ptr, length);
  420. #endif
  421.  
  422. #ifdef PNG_READ_tRNS_SUPPORTED
  423.       else if (!png_memcmp(chunk_name, png_tRNS, 4))
  424.          png_handle_tRNS(png_ptr, info_ptr, length);
  425. #endif
  426.  
  427. #ifdef PNG_READ_zTXt_SUPPORTED
  428.       else if (!png_memcmp(chunk_name, png_zTXt, 4))
  429.          png_handle_zTXt(png_ptr, info_ptr, length);
  430. #endif
  431.  
  432. #ifdef PNG_READ_iTXt_SUPPORTED
  433.       else if (!png_memcmp(chunk_name, png_iTXt, 4))
  434.          png_handle_iTXt(png_ptr, info_ptr, length);
  435. #endif
  436.  
  437.       else
  438.          png_handle_unknown(png_ptr, info_ptr, length);
  439.    }
  440. }
  441. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  442.  
  443. /* Optional call to update the users info_ptr structure */
  444. void PNGAPI
  445. png_read_update_info(png_structp png_ptr, png_infop info_ptr)
  446. {
  447.    png_debug(1, "in png_read_update_info");
  448.  
  449.    if (png_ptr == NULL)
  450.       return;
  451.  
  452.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  453.       png_read_start_row(png_ptr);
  454.  
  455.    else
  456.       png_warning(png_ptr,
  457.           "Ignoring extra png_read_update_info() call;"
  458.           " row buffer not reallocated");
  459.  
  460.    png_read_transform_info(png_ptr, info_ptr);
  461. }
  462.  
  463. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  464. /* Initialize palette, background, etc, after transformations
  465.  * are set, but before any reading takes place.  This allows
  466.  * the user to obtain a gamma-corrected palette, for example.
  467.  * If the user doesn't call this, we will do it ourselves.
  468.  */
  469. void PNGAPI
  470. png_start_read_image(png_structp png_ptr)
  471. {
  472.    png_debug(1, "in png_start_read_image");
  473.  
  474.    if (png_ptr == NULL)
  475.       return;
  476.  
  477.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  478.       png_read_start_row(png_ptr);
  479.    else
  480.       png_warning(png_ptr,
  481.           "Ignoring extra png_start_read_image() call;"
  482.           " row buffer not reallocated");
  483. }
  484. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  485.  
  486. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  487. void PNGAPI
  488. png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
  489. {
  490.    PNG_IDAT;
  491.    PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
  492.        0xff};
  493.    PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
  494.    int ret;
  495.  
  496.    if (png_ptr == NULL)
  497.       return;
  498.  
  499.    png_debug2(1, "in png_read_row (row %lu, pass %d)",
  500.        (unsigned long)png_ptr->row_number, png_ptr->pass);
  501.  
  502.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  503.       png_read_start_row(png_ptr);
  504.  
  505.    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
  506.    {
  507.    /* Check for transforms that have been set but were defined out */
  508. #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
  509.    if (png_ptr->transformations & PNG_INVERT_MONO)
  510.       png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
  511. #endif
  512.  
  513. #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
  514.    if (png_ptr->transformations & PNG_FILLER)
  515.       png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
  516. #endif
  517.  
  518. #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
  519.     !defined(PNG_READ_PACKSWAP_SUPPORTED)
  520.    if (png_ptr->transformations & PNG_PACKSWAP)
  521.       png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
  522. #endif
  523.  
  524. #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
  525.    if (png_ptr->transformations & PNG_PACK)
  526.       png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
  527. #endif
  528.  
  529. #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
  530.    if (png_ptr->transformations & PNG_SHIFT)
  531.       png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
  532. #endif
  533.  
  534. #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
  535.    if (png_ptr->transformations & PNG_BGR)
  536.       png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
  537. #endif
  538.  
  539. #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
  540.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  541.       png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
  542. #endif
  543.    }
  544.  
  545. #ifdef PNG_READ_INTERLACING_SUPPORTED
  546.    /* If interlaced and we do not need a new row, combine row and return */
  547.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  548.    {
  549.       switch (png_ptr->pass)
  550.       {
  551.          case 0:
  552.             if (png_ptr->row_number & 0x07)
  553.             {
  554.                if (dsp_row != NULL)
  555.                   png_combine_row(png_ptr, dsp_row,
  556.                      png_pass_dsp_mask[png_ptr->pass]);
  557.                png_read_finish_row(png_ptr);
  558.                return;
  559.             }
  560.             break;
  561.  
  562.          case 1:
  563.             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
  564.             {
  565.                if (dsp_row != NULL)
  566.                   png_combine_row(png_ptr, dsp_row,
  567.                       png_pass_dsp_mask[png_ptr->pass]);
  568.  
  569.                png_read_finish_row(png_ptr);
  570.                return;
  571.             }
  572.             break;
  573.  
  574.          case 2:
  575.             if ((png_ptr->row_number & 0x07) != 4)
  576.             {
  577.                if (dsp_row != NULL && (png_ptr->row_number & 4))
  578.                   png_combine_row(png_ptr, dsp_row,
  579.                       png_pass_dsp_mask[png_ptr->pass]);
  580.  
  581.                png_read_finish_row(png_ptr);
  582.                return;
  583.             }
  584.             break;
  585.  
  586.          case 3:
  587.             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
  588.             {
  589.                if (dsp_row != NULL)
  590.                   png_combine_row(png_ptr, dsp_row,
  591.                       png_pass_dsp_mask[png_ptr->pass]);
  592.  
  593.                png_read_finish_row(png_ptr);
  594.                return;
  595.             }
  596.             break;
  597.  
  598.          case 4:
  599.             if ((png_ptr->row_number & 3) != 2)
  600.             {
  601.                if (dsp_row != NULL && (png_ptr->row_number & 2))
  602.                   png_combine_row(png_ptr, dsp_row,
  603.                       png_pass_dsp_mask[png_ptr->pass]);
  604.  
  605.                png_read_finish_row(png_ptr);
  606.                return;
  607.             }
  608.             break;
  609.          case 5:
  610.             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
  611.             {
  612.                if (dsp_row != NULL)
  613.                   png_combine_row(png_ptr, dsp_row,
  614.                       png_pass_dsp_mask[png_ptr->pass]);
  615.  
  616.                png_read_finish_row(png_ptr);
  617.                return;
  618.             }
  619.             break;
  620.  
  621.          default:
  622.          case 6:
  623.             if (!(png_ptr->row_number & 1))
  624.             {
  625.                png_read_finish_row(png_ptr);
  626.                return;
  627.             }
  628.             break;
  629.       }
  630.    }
  631. #endif
  632.  
  633.    if (!(png_ptr->mode & PNG_HAVE_IDAT))
  634.       png_error(png_ptr, "Invalid attempt to read row data");
  635.  
  636.    png_ptr->zstream.next_out = png_ptr->row_buf;
  637.    png_ptr->zstream.avail_out =
  638.        (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
  639.        png_ptr->iwidth) + 1);
  640.  
  641.    do
  642.    {
  643.       if (!(png_ptr->zstream.avail_in))
  644.       {
  645.          while (!png_ptr->idat_size)
  646.          {
  647.             png_crc_finish(png_ptr, 0);
  648.  
  649.             png_ptr->idat_size = png_read_chunk_header(png_ptr);
  650.             if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  651.                png_error(png_ptr, "Not enough image data");
  652.          }
  653.          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
  654.          png_ptr->zstream.next_in = png_ptr->zbuf;
  655.          if (png_ptr->zbuf_size > png_ptr->idat_size)
  656.             png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
  657.          png_crc_read(png_ptr, png_ptr->zbuf,
  658.              (png_size_t)png_ptr->zstream.avail_in);
  659.          png_ptr->idat_size -= png_ptr->zstream.avail_in;
  660.       }
  661.  
  662.       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  663.  
  664.       if (ret == Z_STREAM_END)
  665.       {
  666.          if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
  667.             png_ptr->idat_size)
  668.             png_benign_error(png_ptr, "Extra compressed data");
  669.          png_ptr->mode |= PNG_AFTER_IDAT;
  670.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  671.          break;
  672.       }
  673.  
  674.       if (ret != Z_OK)
  675.          png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
  676.              "Decompression error");
  677.  
  678.    } while (png_ptr->zstream.avail_out);
  679.  
  680.    png_ptr->row_info.color_type = png_ptr->color_type;
  681.    png_ptr->row_info.width = png_ptr->iwidth;
  682.    png_ptr->row_info.channels = png_ptr->channels;
  683.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  684.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  685.    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
  686.        png_ptr->row_info.width);
  687.  
  688.    if (png_ptr->row_buf[0])
  689.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  690.        png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  691.        (int)(png_ptr->row_buf[0]));
  692.  
  693.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
  694.  
  695. #ifdef PNG_MNG_FEATURES_SUPPORTED
  696.    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
  697.        (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
  698.    {
  699.       /* Intrapixel differencing */
  700.       png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
  701.    }
  702. #endif
  703.  
  704.  
  705.    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
  706.       png_do_read_transformations(png_ptr);
  707.  
  708. #ifdef PNG_READ_INTERLACING_SUPPORTED
  709.    /* Blow up interlaced rows to full size */
  710.    if (png_ptr->interlaced &&
  711.       (png_ptr->transformations & PNG_INTERLACE))
  712.    {
  713.       if (png_ptr->pass < 6)
  714.          /* Old interface (pre-1.0.9):
  715.           * png_do_read_interlace(&(png_ptr->row_info),
  716.           *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
  717.           */
  718.          png_do_read_interlace(png_ptr);
  719.  
  720.       if (dsp_row != NULL)
  721.          png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]);
  722.  
  723.       if (row != NULL)
  724.          png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]);
  725.    }
  726.  
  727.    else
  728. #endif
  729.    {
  730.       if (row != NULL)
  731.          png_combine_row(png_ptr, row, 0xff);
  732.  
  733.       if (dsp_row != NULL)
  734.          png_combine_row(png_ptr, dsp_row, 0xff);
  735.    }
  736.    png_read_finish_row(png_ptr);
  737.  
  738.    if (png_ptr->read_row_fn != NULL)
  739.       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
  740. }
  741. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  742.  
  743. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  744. /* Read one or more rows of image data.  If the image is interlaced,
  745.  * and png_set_interlace_handling() has been called, the rows need to
  746.  * contain the contents of the rows from the previous pass.  If the
  747.  * image has alpha or transparency, and png_handle_alpha()[*] has been
  748.  * called, the rows contents must be initialized to the contents of the
  749.  * screen.
  750.  *
  751.  * "row" holds the actual image, and pixels are placed in it
  752.  * as they arrive.  If the image is displayed after each pass, it will
  753.  * appear to "sparkle" in.  "display_row" can be used to display a
  754.  * "chunky" progressive image, with finer detail added as it becomes
  755.  * available.  If you do not want this "chunky" display, you may pass
  756.  * NULL for display_row.  If you do not want the sparkle display, and
  757.  * you have not called png_handle_alpha(), you may pass NULL for rows.
  758.  * If you have called png_handle_alpha(), and the image has either an
  759.  * alpha channel or a transparency chunk, you must provide a buffer for
  760.  * rows.  In this case, you do not have to provide a display_row buffer
  761.  * also, but you may.  If the image is not interlaced, or if you have
  762.  * not called png_set_interlace_handling(), the display_row buffer will
  763.  * be ignored, so pass NULL to it.
  764.  *
  765.  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
  766.  */
  767.  
  768. void PNGAPI
  769. png_read_rows(png_structp png_ptr, png_bytepp row,
  770.     png_bytepp display_row, png_uint_32 num_rows)
  771. {
  772.    png_uint_32 i;
  773.    png_bytepp rp;
  774.    png_bytepp dp;
  775.  
  776.    png_debug(1, "in png_read_rows");
  777.  
  778.    if (png_ptr == NULL)
  779.       return;
  780.  
  781.    rp = row;
  782.    dp = display_row;
  783.    if (rp != NULL && dp != NULL)
  784.       for (i = 0; i < num_rows; i++)
  785.       {
  786.          png_bytep rptr = *rp++;
  787.          png_bytep dptr = *dp++;
  788.  
  789.          png_read_row(png_ptr, rptr, dptr);
  790.       }
  791.  
  792.    else if (rp != NULL)
  793.       for (i = 0; i < num_rows; i++)
  794.       {
  795.          png_bytep rptr = *rp;
  796.          png_read_row(png_ptr, rptr, NULL);
  797.          rp++;
  798.       }
  799.  
  800.    else if (dp != NULL)
  801.       for (i = 0; i < num_rows; i++)
  802.       {
  803.          png_bytep dptr = *dp;
  804.          png_read_row(png_ptr, NULL, dptr);
  805.          dp++;
  806.       }
  807. }
  808. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  809.  
  810. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  811. /* Read the entire image.  If the image has an alpha channel or a tRNS
  812.  * chunk, and you have called png_handle_alpha()[*], you will need to
  813.  * initialize the image to the current image that PNG will be overlaying.
  814.  * We set the num_rows again here, in case it was incorrectly set in
  815.  * png_read_start_row() by a call to png_read_update_info() or
  816.  * png_start_read_image() if png_set_interlace_handling() wasn't called
  817.  * prior to either of these functions like it should have been.  You can
  818.  * only call this function once.  If you desire to have an image for
  819.  * each pass of a interlaced image, use png_read_rows() instead.
  820.  *
  821.  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
  822.  */
  823. void PNGAPI
  824. png_read_image(png_structp png_ptr, png_bytepp image)
  825. {
  826.    png_uint_32 i, image_height;
  827.    int pass, j;
  828.    png_bytepp rp;
  829.  
  830.    png_debug(1, "in png_read_image");
  831.  
  832.    if (png_ptr == NULL)
  833.       return;
  834.  
  835. #ifdef PNG_READ_INTERLACING_SUPPORTED
  836.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  837.    {
  838.       pass = png_set_interlace_handling(png_ptr);
  839.       /* And make sure transforms are initialized. */
  840.       png_start_read_image(png_ptr);
  841.    }
  842.    else
  843.    {
  844.       if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
  845.       {
  846.          /* Caller called png_start_read_image or png_read_update_info without
  847.           * first turning on the PNG_INTERLACE transform.  We can fix this here,
  848.           * but the caller should do it!
  849.           */
  850.          png_warning(png_ptr, "Interlace handling should be turned on when "
  851.             "using png_read_image");
  852.          /* Make sure this is set correctly */
  853.          png_ptr->num_rows = png_ptr->height;
  854.       }
  855.  
  856.       /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
  857.        * the above error case.
  858.        */
  859.       pass = png_set_interlace_handling(png_ptr);
  860.    }
  861. #else
  862.    if (png_ptr->interlaced)
  863.       png_error(png_ptr,
  864.           "Cannot read interlaced image -- interlace handler disabled");
  865.  
  866.    pass = 1;
  867. #endif
  868.  
  869.    image_height=png_ptr->height;
  870.  
  871.    for (j = 0; j < pass; j++)
  872.    {
  873.       rp = image;
  874.       for (i = 0; i < image_height; i++)
  875.       {
  876.          png_read_row(png_ptr, *rp, NULL);
  877.          rp++;
  878.       }
  879.    }
  880. }
  881. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  882.  
  883. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  884. /* Read the end of the PNG file.  Will not read past the end of the
  885.  * file, will verify the end is accurate, and will read any comments
  886.  * or time information at the end of the file, if info is not NULL.
  887.  */
  888. void PNGAPI
  889. png_read_end(png_structp png_ptr, png_infop info_ptr)
  890. {
  891.    png_debug(1, "in png_read_end");
  892.  
  893.    if (png_ptr == NULL)
  894.       return;
  895.  
  896.    png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
  897.  
  898.    do
  899.    {
  900.       PNG_IHDR;
  901.       PNG_IDAT;
  902.       PNG_IEND;
  903.       PNG_PLTE;
  904. #ifdef PNG_READ_bKGD_SUPPORTED
  905.       PNG_bKGD;
  906. #endif
  907. #ifdef PNG_READ_cHRM_SUPPORTED
  908.       PNG_cHRM;
  909. #endif
  910. #ifdef PNG_READ_gAMA_SUPPORTED
  911.       PNG_gAMA;
  912. #endif
  913. #ifdef PNG_READ_hIST_SUPPORTED
  914.       PNG_hIST;
  915. #endif
  916. #ifdef PNG_READ_iCCP_SUPPORTED
  917.       PNG_iCCP;
  918. #endif
  919. #ifdef PNG_READ_iTXt_SUPPORTED
  920.       PNG_iTXt;
  921. #endif
  922. #ifdef PNG_READ_oFFs_SUPPORTED
  923.       PNG_oFFs;
  924. #endif
  925. #ifdef PNG_READ_pCAL_SUPPORTED
  926.       PNG_pCAL;
  927. #endif
  928. #ifdef PNG_READ_pHYs_SUPPORTED
  929.       PNG_pHYs;
  930. #endif
  931. #ifdef PNG_READ_sBIT_SUPPORTED
  932.       PNG_sBIT;
  933. #endif
  934. #ifdef PNG_READ_sCAL_SUPPORTED
  935.       PNG_sCAL;
  936. #endif
  937. #ifdef PNG_READ_sPLT_SUPPORTED
  938.       PNG_sPLT;
  939. #endif
  940. #ifdef PNG_READ_sRGB_SUPPORTED
  941.       PNG_sRGB;
  942. #endif
  943. #ifdef PNG_READ_tEXt_SUPPORTED
  944.       PNG_tEXt;
  945. #endif
  946. #ifdef PNG_READ_tIME_SUPPORTED
  947.       PNG_tIME;
  948. #endif
  949. #ifdef PNG_READ_tRNS_SUPPORTED
  950.       PNG_tRNS;
  951. #endif
  952. #ifdef PNG_READ_zTXt_SUPPORTED
  953.       PNG_zTXt;
  954. #endif
  955.       png_uint_32 length = png_read_chunk_header(png_ptr);
  956.       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
  957.  
  958.       if (!png_memcmp(chunk_name, png_IHDR, 4))
  959.          png_handle_IHDR(png_ptr, info_ptr, length);
  960.  
  961.       else if (!png_memcmp(chunk_name, png_IEND, 4))
  962.          png_handle_IEND(png_ptr, info_ptr, length);
  963.  
  964. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  965.       else if (png_handle_as_unknown(png_ptr, chunk_name))
  966.       {
  967.          if (!png_memcmp(chunk_name, png_IDAT, 4))
  968.          {
  969.             if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
  970.                png_benign_error(png_ptr, "Too many IDATs found");
  971.          }
  972.          png_handle_unknown(png_ptr, info_ptr, length);
  973.          if (!png_memcmp(chunk_name, png_PLTE, 4))
  974.             png_ptr->mode |= PNG_HAVE_PLTE;
  975.       }
  976. #endif
  977.  
  978.       else if (!png_memcmp(chunk_name, png_IDAT, 4))
  979.       {
  980.          /* Zero length IDATs are legal after the last IDAT has been
  981.           * read, but not after other chunks have been read.
  982.           */
  983.          if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
  984.             png_benign_error(png_ptr, "Too many IDATs found");
  985.  
  986.          png_crc_finish(png_ptr, length);
  987.       }
  988.       else if (!png_memcmp(chunk_name, png_PLTE, 4))
  989.          png_handle_PLTE(png_ptr, info_ptr, length);
  990.  
  991. #ifdef PNG_READ_bKGD_SUPPORTED
  992.       else if (!png_memcmp(chunk_name, png_bKGD, 4))
  993.          png_handle_bKGD(png_ptr, info_ptr, length);
  994. #endif
  995.  
  996. #ifdef PNG_READ_cHRM_SUPPORTED
  997.       else if (!png_memcmp(chunk_name, png_cHRM, 4))
  998.          png_handle_cHRM(png_ptr, info_ptr, length);
  999. #endif
  1000.  
  1001. #ifdef PNG_READ_gAMA_SUPPORTED
  1002.       else if (!png_memcmp(chunk_name, png_gAMA, 4))
  1003.          png_handle_gAMA(png_ptr, info_ptr, length);
  1004. #endif
  1005.  
  1006. #ifdef PNG_READ_hIST_SUPPORTED
  1007.       else if (!png_memcmp(chunk_name, png_hIST, 4))
  1008.          png_handle_hIST(png_ptr, info_ptr, length);
  1009. #endif
  1010.  
  1011. #ifdef PNG_READ_oFFs_SUPPORTED
  1012.       else if (!png_memcmp(chunk_name, png_oFFs, 4))
  1013.          png_handle_oFFs(png_ptr, info_ptr, length);
  1014. #endif
  1015.  
  1016. #ifdef PNG_READ_pCAL_SUPPORTED
  1017.       else if (!png_memcmp(chunk_name, png_pCAL, 4))
  1018.          png_handle_pCAL(png_ptr, info_ptr, length);
  1019. #endif
  1020.  
  1021. #ifdef PNG_READ_sCAL_SUPPORTED
  1022.       else if (!png_memcmp(chunk_name, png_sCAL, 4))
  1023.          png_handle_sCAL(png_ptr, info_ptr, length);
  1024. #endif
  1025.  
  1026. #ifdef PNG_READ_pHYs_SUPPORTED
  1027.       else if (!png_memcmp(chunk_name, png_pHYs, 4))
  1028.          png_handle_pHYs(png_ptr, info_ptr, length);
  1029. #endif
  1030.  
  1031. #ifdef PNG_READ_sBIT_SUPPORTED
  1032.       else if (!png_memcmp(chunk_name, png_sBIT, 4))
  1033.          png_handle_sBIT(png_ptr, info_ptr, length);
  1034. #endif
  1035.  
  1036. #ifdef PNG_READ_sRGB_SUPPORTED
  1037.       else if (!png_memcmp(chunk_name, png_sRGB, 4))
  1038.          png_handle_sRGB(png_ptr, info_ptr, length);
  1039. #endif
  1040.  
  1041. #ifdef PNG_READ_iCCP_SUPPORTED
  1042.       else if (!png_memcmp(chunk_name, png_iCCP, 4))
  1043.          png_handle_iCCP(png_ptr, info_ptr, length);
  1044. #endif
  1045.  
  1046. #ifdef PNG_READ_sPLT_SUPPORTED
  1047.       else if (!png_memcmp(chunk_name, png_sPLT, 4))
  1048.          png_handle_sPLT(png_ptr, info_ptr, length);
  1049. #endif
  1050.  
  1051. #ifdef PNG_READ_tEXt_SUPPORTED
  1052.       else if (!png_memcmp(chunk_name, png_tEXt, 4))
  1053.          png_handle_tEXt(png_ptr, info_ptr, length);
  1054. #endif
  1055.  
  1056. #ifdef PNG_READ_tIME_SUPPORTED
  1057.       else if (!png_memcmp(chunk_name, png_tIME, 4))
  1058.          png_handle_tIME(png_ptr, info_ptr, length);
  1059. #endif
  1060.  
  1061. #ifdef PNG_READ_tRNS_SUPPORTED
  1062.       else if (!png_memcmp(chunk_name, png_tRNS, 4))
  1063.          png_handle_tRNS(png_ptr, info_ptr, length);
  1064. #endif
  1065.  
  1066. #ifdef PNG_READ_zTXt_SUPPORTED
  1067.       else if (!png_memcmp(chunk_name, png_zTXt, 4))
  1068.          png_handle_zTXt(png_ptr, info_ptr, length);
  1069. #endif
  1070.  
  1071. #ifdef PNG_READ_iTXt_SUPPORTED
  1072.       else if (!png_memcmp(chunk_name, png_iTXt, 4))
  1073.          png_handle_iTXt(png_ptr, info_ptr, length);
  1074. #endif
  1075.  
  1076.       else
  1077.          png_handle_unknown(png_ptr, info_ptr, length);
  1078.    } while (!(png_ptr->mode & PNG_HAVE_IEND));
  1079. }
  1080. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  1081.  
  1082. /* Free all memory used by the read */
  1083. void PNGAPI
  1084. png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
  1085.     png_infopp end_info_ptr_ptr)
  1086. {
  1087.    png_structp png_ptr = NULL;
  1088.    png_infop info_ptr = NULL, end_info_ptr = NULL;
  1089. #ifdef PNG_USER_MEM_SUPPORTED
  1090.    png_free_ptr free_fn = NULL;
  1091.    png_voidp mem_ptr = NULL;
  1092. #endif
  1093.  
  1094.    png_debug(1, "in png_destroy_read_struct");
  1095.  
  1096.    if (png_ptr_ptr != NULL)
  1097.       png_ptr = *png_ptr_ptr;
  1098.    if (png_ptr == NULL)
  1099.       return;
  1100.  
  1101. #ifdef PNG_USER_MEM_SUPPORTED
  1102.    free_fn = png_ptr->free_fn;
  1103.    mem_ptr = png_ptr->mem_ptr;
  1104. #endif
  1105.  
  1106.    if (info_ptr_ptr != NULL)
  1107.       info_ptr = *info_ptr_ptr;
  1108.  
  1109.    if (end_info_ptr_ptr != NULL)
  1110.       end_info_ptr = *end_info_ptr_ptr;
  1111.  
  1112.    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
  1113.  
  1114.    if (info_ptr != NULL)
  1115.    {
  1116. #ifdef PNG_TEXT_SUPPORTED
  1117.       png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
  1118. #endif
  1119.  
  1120. #ifdef PNG_USER_MEM_SUPPORTED
  1121.       png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
  1122.           (png_voidp)mem_ptr);
  1123. #else
  1124.       png_destroy_struct((png_voidp)info_ptr);
  1125. #endif
  1126.       *info_ptr_ptr = NULL;
  1127.    }
  1128.  
  1129.    if (end_info_ptr != NULL)
  1130.    {
  1131. #ifdef PNG_READ_TEXT_SUPPORTED
  1132.       png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
  1133. #endif
  1134. #ifdef PNG_USER_MEM_SUPPORTED
  1135.       png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
  1136.           (png_voidp)mem_ptr);
  1137. #else
  1138.       png_destroy_struct((png_voidp)end_info_ptr);
  1139. #endif
  1140.       *end_info_ptr_ptr = NULL;
  1141.    }
  1142.  
  1143.    if (png_ptr != NULL)
  1144.    {
  1145. #ifdef PNG_USER_MEM_SUPPORTED
  1146.       png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
  1147.           (png_voidp)mem_ptr);
  1148. #else
  1149.       png_destroy_struct((png_voidp)png_ptr);
  1150. #endif
  1151.       *png_ptr_ptr = NULL;
  1152.    }
  1153. }
  1154.  
  1155. /* Free all memory used by the read (old method) */
  1156. void /* PRIVATE */
  1157. png_read_destroy(png_structp png_ptr, png_infop info_ptr,
  1158.     png_infop end_info_ptr)
  1159. {
  1160. #ifdef PNG_SETJMP_SUPPORTED
  1161.    jmp_buf tmp_jmp;
  1162. #endif
  1163.    png_error_ptr error_fn;
  1164.    png_error_ptr warning_fn;
  1165.    png_voidp error_ptr;
  1166. #ifdef PNG_USER_MEM_SUPPORTED
  1167.    png_free_ptr free_fn;
  1168. #endif
  1169.  
  1170.    png_debug(1, "in png_read_destroy");
  1171.  
  1172.    if (info_ptr != NULL)
  1173.       png_info_destroy(png_ptr, info_ptr);
  1174.  
  1175.    if (end_info_ptr != NULL)
  1176.       png_info_destroy(png_ptr, end_info_ptr);
  1177.  
  1178.    png_free(png_ptr, png_ptr->zbuf);
  1179.    png_free(png_ptr, png_ptr->big_row_buf);
  1180.    png_free(png_ptr, png_ptr->prev_row);
  1181.    png_free(png_ptr, png_ptr->chunkdata);
  1182.  
  1183. #ifdef PNG_READ_QUANTIZE_SUPPORTED
  1184.    png_free(png_ptr, png_ptr->palette_lookup);
  1185.    png_free(png_ptr, png_ptr->quantize_index);
  1186. #endif
  1187.  
  1188. #ifdef PNG_READ_GAMMA_SUPPORTED
  1189.    png_free(png_ptr, png_ptr->gamma_table);
  1190. #endif
  1191.  
  1192. #ifdef PNG_READ_BACKGROUND_SUPPORTED
  1193.    png_free(png_ptr, png_ptr->gamma_from_1);
  1194.    png_free(png_ptr, png_ptr->gamma_to_1);
  1195. #endif
  1196.  
  1197.    if (png_ptr->free_me & PNG_FREE_PLTE)
  1198.       png_zfree(png_ptr, png_ptr->palette);
  1199.    png_ptr->free_me &= ~PNG_FREE_PLTE;
  1200.  
  1201. #if defined(PNG_tRNS_SUPPORTED) || \
  1202.     defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  1203.    if (png_ptr->free_me & PNG_FREE_TRNS)
  1204.       png_free(png_ptr, png_ptr->trans_alpha);
  1205.    png_ptr->free_me &= ~PNG_FREE_TRNS;
  1206. #endif
  1207.  
  1208. #ifdef PNG_READ_hIST_SUPPORTED
  1209.    if (png_ptr->free_me & PNG_FREE_HIST)
  1210.       png_free(png_ptr, png_ptr->hist);
  1211.    png_ptr->free_me &= ~PNG_FREE_HIST;
  1212. #endif
  1213.  
  1214. #ifdef PNG_READ_GAMMA_SUPPORTED
  1215.    if (png_ptr->gamma_16_table != NULL)
  1216.    {
  1217.       int i;
  1218.       int istop = (1 << (8 - png_ptr->gamma_shift));
  1219.       for (i = 0; i < istop; i++)
  1220.       {
  1221.          png_free(png_ptr, png_ptr->gamma_16_table[i]);
  1222.       }
  1223.    png_free(png_ptr, png_ptr->gamma_16_table);
  1224.    }
  1225.  
  1226. #ifdef PNG_READ_BACKGROUND_SUPPORTED
  1227.    if (png_ptr->gamma_16_from_1 != NULL)
  1228.    {
  1229.       int i;
  1230.       int istop = (1 << (8 - png_ptr->gamma_shift));
  1231.       for (i = 0; i < istop; i++)
  1232.       {
  1233.          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
  1234.       }
  1235.    png_free(png_ptr, png_ptr->gamma_16_from_1);
  1236.    }
  1237.    if (png_ptr->gamma_16_to_1 != NULL)
  1238.    {
  1239.       int i;
  1240.       int istop = (1 << (8 - png_ptr->gamma_shift));
  1241.       for (i = 0; i < istop; i++)
  1242.       {
  1243.          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
  1244.       }
  1245.    png_free(png_ptr, png_ptr->gamma_16_to_1);
  1246.    }
  1247. #endif
  1248. #endif
  1249.  
  1250. #ifdef PNG_TIME_RFC1123_SUPPORTED
  1251.    png_free(png_ptr, png_ptr->time_buffer);
  1252. #endif
  1253.  
  1254.    inflateEnd(&png_ptr->zstream);
  1255.  
  1256. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  1257.    png_free(png_ptr, png_ptr->save_buffer);
  1258. #endif
  1259.  
  1260. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  1261. #ifdef PNG_TEXT_SUPPORTED
  1262.    png_free(png_ptr, png_ptr->current_text);
  1263. #endif /* PNG_TEXT_SUPPORTED */
  1264. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1265.  
  1266.    /* Save the important info out of the png_struct, in case it is
  1267.     * being used again.
  1268.     */
  1269. #ifdef PNG_SETJMP_SUPPORTED
  1270.    png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
  1271. #endif
  1272.  
  1273.    error_fn = png_ptr->error_fn;
  1274.    warning_fn = png_ptr->warning_fn;
  1275.    error_ptr = png_ptr->error_ptr;
  1276. #ifdef PNG_USER_MEM_SUPPORTED
  1277.    free_fn = png_ptr->free_fn;
  1278. #endif
  1279.  
  1280.    png_memset(png_ptr, 0, png_sizeof(png_struct));
  1281.  
  1282.    png_ptr->error_fn = error_fn;
  1283.    png_ptr->warning_fn = warning_fn;
  1284.    png_ptr->error_ptr = error_ptr;
  1285. #ifdef PNG_USER_MEM_SUPPORTED
  1286.    png_ptr->free_fn = free_fn;
  1287. #endif
  1288.  
  1289. #ifdef PNG_SETJMP_SUPPORTED
  1290.    png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
  1291. #endif
  1292.  
  1293. }
  1294.  
  1295. void PNGAPI
  1296. png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
  1297. {
  1298.    if (png_ptr == NULL)
  1299.       return;
  1300.  
  1301.    png_ptr->read_row_fn = read_row_fn;
  1302. }
  1303.  
  1304.  
  1305. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  1306. #ifdef PNG_INFO_IMAGE_SUPPORTED
  1307. void PNGAPI
  1308. png_read_png(png_structp png_ptr, png_infop info_ptr,
  1309.                            int transforms,
  1310.                            voidp params)
  1311. {
  1312.    int row;
  1313.  
  1314.    if (png_ptr == NULL)
  1315.       return;
  1316.  
  1317.    /* png_read_info() gives us all of the information from the
  1318.     * PNG file before the first IDAT (image data chunk).
  1319.     */
  1320.    png_read_info(png_ptr, info_ptr);
  1321.    if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
  1322.       png_error(png_ptr, "Image is too high to process with png_read_png()");
  1323.  
  1324.    /* -------------- image transformations start here ------------------- */
  1325.  
  1326. #ifdef PNG_READ_16_TO_8_SUPPORTED
  1327.    /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
  1328.     */
  1329.    if (transforms & PNG_TRANSFORM_STRIP_16)
  1330.       png_set_strip_16(png_ptr);
  1331. #endif
  1332.  
  1333. #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
  1334.    /* Strip alpha bytes from the input data without combining with
  1335.     * the background (not recommended).
  1336.     */
  1337.    if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
  1338.       png_set_strip_alpha(png_ptr);
  1339. #endif
  1340.  
  1341. #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
  1342.    /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
  1343.     * byte into separate bytes (useful for paletted and grayscale images).
  1344.     */
  1345.    if (transforms & PNG_TRANSFORM_PACKING)
  1346.       png_set_packing(png_ptr);
  1347. #endif
  1348.  
  1349. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  1350.    /* Change the order of packed pixels to least significant bit first
  1351.     * (not useful if you are using png_set_packing).
  1352.     */
  1353.    if (transforms & PNG_TRANSFORM_PACKSWAP)
  1354.       png_set_packswap(png_ptr);
  1355. #endif
  1356.  
  1357. #ifdef PNG_READ_EXPAND_SUPPORTED
  1358.    /* Expand paletted colors into true RGB triplets
  1359.     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
  1360.     * Expand paletted or RGB images with transparency to full alpha
  1361.     * channels so the data will be available as RGBA quartets.
  1362.     */
  1363.    if (transforms & PNG_TRANSFORM_EXPAND)
  1364.       if ((png_ptr->bit_depth < 8) ||
  1365.           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
  1366.           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
  1367.          png_set_expand(png_ptr);
  1368. #endif
  1369.  
  1370.    /* We don't handle background color or gamma transformation or quantizing.
  1371.     */
  1372.  
  1373. #ifdef PNG_READ_INVERT_SUPPORTED
  1374.    /* Invert monochrome files to have 0 as white and 1 as black
  1375.     */
  1376.    if (transforms & PNG_TRANSFORM_INVERT_MONO)
  1377.       png_set_invert_mono(png_ptr);
  1378. #endif
  1379.  
  1380. #ifdef PNG_READ_SHIFT_SUPPORTED
  1381.    /* If you want to shift the pixel values from the range [0,255] or
  1382.     * [0,65535] to the original [0,7] or [0,31], or whatever range the
  1383.     * colors were originally in:
  1384.     */
  1385.    if ((transforms & PNG_TRANSFORM_SHIFT)
  1386.        && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
  1387.    {
  1388.       png_color_8p sig_bit;
  1389.  
  1390.       png_get_sBIT(png_ptr, info_ptr, &sig_bit);
  1391.       png_set_shift(png_ptr, sig_bit);
  1392.    }
  1393. #endif
  1394.  
  1395. #ifdef PNG_READ_BGR_SUPPORTED
  1396.    /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
  1397.    if (transforms & PNG_TRANSFORM_BGR)
  1398.       png_set_bgr(png_ptr);
  1399. #endif
  1400.  
  1401. #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
  1402.    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
  1403.    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
  1404.       png_set_swap_alpha(png_ptr);
  1405. #endif
  1406.  
  1407. #ifdef PNG_READ_SWAP_SUPPORTED
  1408.    /* Swap bytes of 16 bit files to least significant byte first */
  1409.    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
  1410.       png_set_swap(png_ptr);
  1411. #endif
  1412.  
  1413. /* Added at libpng-1.2.41 */
  1414. #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
  1415.    /* Invert the alpha channel from opacity to transparency */
  1416.    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
  1417.       png_set_invert_alpha(png_ptr);
  1418. #endif
  1419.  
  1420. /* Added at libpng-1.2.41 */
  1421. #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
  1422.    /* Expand grayscale image to RGB */
  1423.    if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
  1424.       png_set_gray_to_rgb(png_ptr);
  1425. #endif
  1426.  
  1427.    /* We don't handle adding filler bytes */
  1428.  
  1429.    /* Optional call to gamma correct and add the background to the palette
  1430.     * and update info structure.  REQUIRED if you are expecting libpng to
  1431.     * update the palette for you (i.e., you selected such a transform above).
  1432.     */
  1433.    png_read_update_info(png_ptr, info_ptr);
  1434.  
  1435.    /* -------------- image transformations end here ------------------- */
  1436.  
  1437.    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
  1438.    if (info_ptr->row_pointers == NULL)
  1439.    {
  1440.       png_uint_32 iptr;
  1441.  
  1442.       info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
  1443.           info_ptr->height * png_sizeof(png_bytep));
  1444.       for (iptr=0; iptr<info_ptr->height; iptr++)
  1445.          info_ptr->row_pointers[iptr] = NULL;
  1446.  
  1447.       info_ptr->free_me |= PNG_FREE_ROWS;
  1448.  
  1449.       for (row = 0; row < (int)info_ptr->height; row++)
  1450.          info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
  1451.             png_get_rowbytes(png_ptr, info_ptr));
  1452.    }
  1453.  
  1454.    png_read_image(png_ptr, info_ptr->row_pointers);
  1455.    info_ptr->valid |= PNG_INFO_IDAT;
  1456.  
  1457.    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
  1458.    png_read_end(png_ptr, info_ptr);
  1459.  
  1460.    PNG_UNUSED(transforms)   /* Quiet compiler warnings */
  1461.    PNG_UNUSED(params)
  1462.  
  1463. }
  1464. #endif /* PNG_INFO_IMAGE_SUPPORTED */
  1465. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  1466. #endif /* PNG_READ_SUPPORTED */
  1467.