Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /* pngset.c - storage of image information into info struct
  3.  *
  4.  * Last changed in libpng 1.5.1 [February 3, 2011]
  5.  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
  6.  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  7.  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  8.  *
  9.  * This code is released under the libpng license.
  10.  * For conditions of distribution and use, see the disclaimer
  11.  * and license in png.h
  12.  *
  13.  * The functions here are used during reads to store data from the file
  14.  * into the info struct, and during writes to store application data
  15.  * into the info struct for writing into the file.  This abstracts the
  16.  * info struct and allows us to change the structure in the future.
  17.  */
  18.  
  19. #include "pngpriv.h"
  20.  
  21. #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  22.  
  23. #ifdef PNG_bKGD_SUPPORTED
  24. void PNGAPI
  25. png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
  26.     png_const_color_16p background)
  27. {
  28.    png_debug1(1, "in %s storage function", "bKGD");
  29.  
  30.    if (png_ptr == NULL || info_ptr == NULL)
  31.       return;
  32.  
  33.    png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
  34.    info_ptr->valid |= PNG_INFO_bKGD;
  35. }
  36. #endif
  37.  
  38. #ifdef PNG_cHRM_SUPPORTED
  39. void PNGFAPI
  40. png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
  41.     png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
  42.     png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
  43.     png_fixed_point blue_x, png_fixed_point blue_y)
  44. {
  45.    png_debug1(1, "in %s storage function", "cHRM fixed");
  46.  
  47.    if (png_ptr == NULL || info_ptr == NULL)
  48.       return;
  49.  
  50. #  ifdef PNG_CHECK_cHRM_SUPPORTED
  51.    if (png_check_cHRM_fixed(png_ptr,
  52.        white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
  53. #  endif
  54.    {
  55.       info_ptr->x_white = white_x;
  56.       info_ptr->y_white = white_y;
  57.       info_ptr->x_red   = red_x;
  58.       info_ptr->y_red   = red_y;
  59.       info_ptr->x_green = green_x;
  60.       info_ptr->y_green = green_y;
  61.       info_ptr->x_blue  = blue_x;
  62.       info_ptr->y_blue  = blue_y;
  63.       info_ptr->valid |= PNG_INFO_cHRM;
  64.    }
  65. }
  66.  
  67. #  ifdef PNG_FLOATING_POINT_SUPPORTED
  68. void PNGAPI
  69. png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
  70.     double white_x, double white_y, double red_x, double red_y,
  71.     double green_x, double green_y, double blue_x, double blue_y)
  72. {
  73.    png_set_cHRM_fixed(png_ptr, info_ptr,
  74.       png_fixed(png_ptr, white_x, "cHRM White X"),
  75.       png_fixed(png_ptr, white_y, "cHRM White Y"),
  76.       png_fixed(png_ptr, red_x, "cHRM Red X"),
  77.       png_fixed(png_ptr, red_y, "cHRM Red Y"),
  78.       png_fixed(png_ptr, green_x, "cHRM Green X"),
  79.       png_fixed(png_ptr, green_y, "cHRM Green Y"),
  80.       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
  81.       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
  82. }
  83. #  endif /* PNG_FLOATING_POINT_SUPPORTED */
  84.  
  85. #endif /* PNG_cHRM_SUPPORTED */
  86.  
  87. #ifdef PNG_gAMA_SUPPORTED
  88. void PNGFAPI
  89. png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
  90.     file_gamma)
  91. {
  92.    png_debug1(1, "in %s storage function", "gAMA");
  93.  
  94.    if (png_ptr == NULL || info_ptr == NULL)
  95.       return;
  96.  
  97.    /* Previously these values were limited, however they must be
  98.     * wrong, therefore storing them (and setting PNG_INFO_gAMA)
  99.     * must be wrong too.
  100.     */
  101.    if (file_gamma > (png_fixed_point)PNG_UINT_31_MAX)
  102.       png_warning(png_ptr, "Gamma too large, ignored");
  103.  
  104.    else if (file_gamma <= 0)
  105.       png_warning(png_ptr, "Negative or zero gamma ignored");
  106.  
  107.    else
  108.    {
  109.       info_ptr->gamma = file_gamma;
  110.       info_ptr->valid |= PNG_INFO_gAMA;
  111.    }
  112. }
  113.  
  114. #  ifdef PNG_FLOATING_POINT_SUPPORTED
  115. void PNGAPI
  116. png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
  117. {
  118.    png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
  119.        "png_set_gAMA"));
  120. }
  121. #  endif
  122. #endif
  123.  
  124. #ifdef PNG_hIST_SUPPORTED
  125. void PNGAPI
  126. png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
  127. {
  128.    int i;
  129.  
  130.    png_debug1(1, "in %s storage function", "hIST");
  131.  
  132.    if (png_ptr == NULL || info_ptr == NULL)
  133.       return;
  134.  
  135.    if (info_ptr->num_palette == 0 || info_ptr->num_palette
  136.        > PNG_MAX_PALETTE_LENGTH)
  137.    {
  138.       png_warning(png_ptr,
  139.           "Invalid palette size, hIST allocation skipped");
  140.  
  141.       return;
  142.    }
  143.  
  144.    png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
  145.  
  146.    /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
  147.     * version 1.2.1
  148.     */
  149.    png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
  150.        PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
  151.  
  152.    if (png_ptr->hist == NULL)
  153.    {
  154.       png_warning(png_ptr, "Insufficient memory for hIST chunk data");
  155.       return;
  156.    }
  157.  
  158.    for (i = 0; i < info_ptr->num_palette; i++)
  159.       png_ptr->hist[i] = hist[i];
  160.  
  161.    info_ptr->hist = png_ptr->hist;
  162.    info_ptr->valid |= PNG_INFO_hIST;
  163.    info_ptr->free_me |= PNG_FREE_HIST;
  164. }
  165. #endif
  166.  
  167. void PNGAPI
  168. png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
  169.     png_uint_32 width, png_uint_32 height, int bit_depth,
  170.     int color_type, int interlace_type, int compression_type,
  171.     int filter_type)
  172. {
  173.    png_debug1(1, "in %s storage function", "IHDR");
  174.  
  175.    if (png_ptr == NULL || info_ptr == NULL)
  176.       return;
  177.  
  178.    info_ptr->width = width;
  179.    info_ptr->height = height;
  180.    info_ptr->bit_depth = (png_byte)bit_depth;
  181.    info_ptr->color_type = (png_byte)color_type;
  182.    info_ptr->compression_type = (png_byte)compression_type;
  183.    info_ptr->filter_type = (png_byte)filter_type;
  184.    info_ptr->interlace_type = (png_byte)interlace_type;
  185.  
  186.    png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
  187.        info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
  188.        info_ptr->compression_type, info_ptr->filter_type);
  189.  
  190.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  191.       info_ptr->channels = 1;
  192.  
  193.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  194.       info_ptr->channels = 3;
  195.  
  196.    else
  197.       info_ptr->channels = 1;
  198.  
  199.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  200.       info_ptr->channels++;
  201.  
  202.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  203.  
  204.    /* Check for potential overflow */
  205.    if (width >
  206.        (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
  207.        - 48       /* bigrowbuf hack */
  208.        - 1        /* filter byte */
  209.        - 7*8      /* rounding of width to multiple of 8 pixels */
  210.        - 8)       /* extra max_pixel_depth pad */
  211.       info_ptr->rowbytes = 0;
  212.    else
  213.       info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
  214. }
  215.  
  216. #ifdef PNG_oFFs_SUPPORTED
  217. void PNGAPI
  218. png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
  219.     png_int_32 offset_x, png_int_32 offset_y, int unit_type)
  220. {
  221.    png_debug1(1, "in %s storage function", "oFFs");
  222.  
  223.    if (png_ptr == NULL || info_ptr == NULL)
  224.       return;
  225.  
  226.    info_ptr->x_offset = offset_x;
  227.    info_ptr->y_offset = offset_y;
  228.    info_ptr->offset_unit_type = (png_byte)unit_type;
  229.    info_ptr->valid |= PNG_INFO_oFFs;
  230. }
  231. #endif
  232.  
  233. #ifdef PNG_pCAL_SUPPORTED
  234. void PNGAPI
  235. png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
  236.     png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
  237.     int nparams, png_const_charp units, png_charpp params)
  238. {
  239.    png_size_t length;
  240.    int i;
  241.  
  242.    png_debug1(1, "in %s storage function", "pCAL");
  243.  
  244.    if (png_ptr == NULL || info_ptr == NULL)
  245.       return;
  246.  
  247.    length = png_strlen(purpose) + 1;
  248.    png_debug1(3, "allocating purpose for info (%lu bytes)",
  249.        (unsigned long)length);
  250.  
  251.    /* TODO: validate format of calibration name and unit name */
  252.  
  253.    /* Check that the type matches the specification. */
  254.    if (type < 0 || type > 3)
  255.       png_error(png_ptr, "Invalid pCAL equation type");
  256.  
  257.    /* Validate params[nparams] */
  258.    for (i=0; i<nparams; ++i)
  259.       if (!png_check_fp_string(params[i], png_strlen(params[i])))
  260.          png_error(png_ptr, "Invalid format for pCAL parameter");
  261.  
  262.    info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
  263.  
  264.    if (info_ptr->pcal_purpose == NULL)
  265.    {
  266.       png_warning(png_ptr, "Insufficient memory for pCAL purpose");
  267.       return;
  268.    }
  269.  
  270.    png_memcpy(info_ptr->pcal_purpose, purpose, length);
  271.  
  272.    png_debug(3, "storing X0, X1, type, and nparams in info");
  273.    info_ptr->pcal_X0 = X0;
  274.    info_ptr->pcal_X1 = X1;
  275.    info_ptr->pcal_type = (png_byte)type;
  276.    info_ptr->pcal_nparams = (png_byte)nparams;
  277.  
  278.    length = png_strlen(units) + 1;
  279.    png_debug1(3, "allocating units for info (%lu bytes)",
  280.      (unsigned long)length);
  281.  
  282.    info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
  283.  
  284.    if (info_ptr->pcal_units == NULL)
  285.    {
  286.       png_warning(png_ptr, "Insufficient memory for pCAL units");
  287.       return;
  288.    }
  289.  
  290.    png_memcpy(info_ptr->pcal_units, units, length);
  291.  
  292.    info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
  293.        (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
  294.  
  295.    if (info_ptr->pcal_params == NULL)
  296.    {
  297.       png_warning(png_ptr, "Insufficient memory for pCAL params");
  298.       return;
  299.    }
  300.  
  301.    png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
  302.  
  303.    for (i = 0; i < nparams; i++)
  304.    {
  305.       length = png_strlen(params[i]) + 1;
  306.       png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
  307.           (unsigned long)length);
  308.  
  309.       info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
  310.  
  311.       if (info_ptr->pcal_params[i] == NULL)
  312.       {
  313.          png_warning(png_ptr, "Insufficient memory for pCAL parameter");
  314.          return;
  315.       }
  316.  
  317.       png_memcpy(info_ptr->pcal_params[i], params[i], length);
  318.    }
  319.  
  320.    info_ptr->valid |= PNG_INFO_pCAL;
  321.    info_ptr->free_me |= PNG_FREE_PCAL;
  322. }
  323. #endif
  324.  
  325. #ifdef PNG_sCAL_SUPPORTED
  326. void PNGAPI
  327. png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
  328.     int unit, png_const_charp swidth, png_const_charp sheight)
  329. {
  330.    png_size_t lengthw = 0, lengthh = 0;
  331.  
  332.    png_debug1(1, "in %s storage function", "sCAL");
  333.  
  334.    if (png_ptr == NULL || info_ptr == NULL)
  335.       return;
  336.  
  337.    /* Double check the unit (should never get here with an invalid
  338.     * unit unless this is an API call.)
  339.     */
  340.    if (unit != 1 && unit != 2)
  341.       png_error(png_ptr, "Invalid sCAL unit");
  342.  
  343.    if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 ||
  344.        swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw))
  345.       png_error(png_ptr, "Invalid sCAL width");
  346.  
  347.    if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 ||
  348.        sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh))
  349.       png_error(png_ptr, "Invalid sCAL height");
  350.  
  351.    info_ptr->scal_unit = (png_byte)unit;
  352.  
  353.    ++lengthw;
  354.  
  355.    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
  356.  
  357.    info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
  358.  
  359.    if (info_ptr->scal_s_width == NULL)
  360.    {
  361.       png_warning(png_ptr, "Memory allocation failed while processing sCAL");
  362.       return;
  363.    }
  364.  
  365.    png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
  366.  
  367.    ++lengthh;
  368.  
  369.    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
  370.  
  371.    info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
  372.  
  373.    if (info_ptr->scal_s_height == NULL)
  374.    {
  375.       png_free (png_ptr, info_ptr->scal_s_width);
  376.       info_ptr->scal_s_width = NULL;
  377.  
  378.       png_warning(png_ptr, "Memory allocation failed while processing sCAL");
  379.       return;
  380.    }
  381.  
  382.    png_memcpy(info_ptr->scal_s_height, sheight, lengthh);
  383.  
  384.    info_ptr->valid |= PNG_INFO_sCAL;
  385.    info_ptr->free_me |= PNG_FREE_SCAL;
  386. }
  387.  
  388. #  ifdef PNG_FLOATING_POINT_SUPPORTED
  389. void PNGAPI
  390. png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
  391.     double height)
  392. {
  393.    png_debug1(1, "in %s storage function", "sCAL");
  394.  
  395.    /* Check the arguments. */
  396.    if (width <= 0)
  397.       png_warning(png_ptr, "Invalid sCAL width ignored");
  398.  
  399.    else if (height <= 0)
  400.       png_warning(png_ptr, "Invalid sCAL height ignored");
  401.  
  402.    else
  403.    {
  404.       /* Convert 'width' and 'height' to ASCII. */
  405.       char swidth[PNG_sCAL_MAX_DIGITS+1];
  406.       char sheight[PNG_sCAL_MAX_DIGITS+1];
  407.  
  408.       png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
  409.          PNG_sCAL_PRECISION);
  410.       png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
  411.          PNG_sCAL_PRECISION);
  412.  
  413.       png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
  414.    }
  415. }
  416. #  endif
  417.  
  418. #  ifdef PNG_FIXED_POINT_SUPPORTED
  419. void PNGAPI
  420. png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
  421.     png_fixed_point width, png_fixed_point height)
  422. {
  423.    png_debug1(1, "in %s storage function", "sCAL");
  424.  
  425.    /* Check the arguments. */
  426.    if (width <= 0)
  427.       png_warning(png_ptr, "Invalid sCAL width ignored");
  428.  
  429.    else if (height <= 0)
  430.       png_warning(png_ptr, "Invalid sCAL height ignored");
  431.  
  432.    else
  433.    {
  434.       /* Convert 'width' and 'height' to ASCII. */
  435.       char swidth[PNG_sCAL_MAX_DIGITS+1];
  436.       char sheight[PNG_sCAL_MAX_DIGITS+1];
  437.  
  438.       png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
  439.       png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);
  440.  
  441.       png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
  442.    }
  443. }
  444. #  endif
  445. #endif
  446.  
  447. #ifdef PNG_pHYs_SUPPORTED
  448. void PNGAPI
  449. png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
  450.     png_uint_32 res_x, png_uint_32 res_y, int unit_type)
  451. {
  452.    png_debug1(1, "in %s storage function", "pHYs");
  453.  
  454.    if (png_ptr == NULL || info_ptr == NULL)
  455.       return;
  456.  
  457.    info_ptr->x_pixels_per_unit = res_x;
  458.    info_ptr->y_pixels_per_unit = res_y;
  459.    info_ptr->phys_unit_type = (png_byte)unit_type;
  460.    info_ptr->valid |= PNG_INFO_pHYs;
  461. }
  462. #endif
  463.  
  464. void PNGAPI
  465. png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
  466.     png_const_colorp palette, int num_palette)
  467. {
  468.  
  469.    png_debug1(1, "in %s storage function", "PLTE");
  470.  
  471.    if (png_ptr == NULL || info_ptr == NULL)
  472.       return;
  473.  
  474.    if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
  475.    {
  476.       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  477.          png_error(png_ptr, "Invalid palette length");
  478.  
  479.       else
  480.       {
  481.          png_warning(png_ptr, "Invalid palette length");
  482.          return;
  483.       }
  484.    }
  485.  
  486.    /* It may not actually be necessary to set png_ptr->palette here;
  487.     * we do it for backward compatibility with the way the png_handle_tRNS
  488.     * function used to do the allocation.
  489.     */
  490.    png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
  491.  
  492.    /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
  493.     * of num_palette entries, in case of an invalid PNG file that has
  494.     * too-large sample values.
  495.     */
  496.    png_ptr->palette = (png_colorp)png_calloc(png_ptr,
  497.        PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
  498.  
  499.    png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
  500.    info_ptr->palette = png_ptr->palette;
  501.    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
  502.  
  503.    info_ptr->free_me |= PNG_FREE_PLTE;
  504.  
  505.    info_ptr->valid |= PNG_INFO_PLTE;
  506. }
  507.  
  508. #ifdef PNG_sBIT_SUPPORTED
  509. void PNGAPI
  510. png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
  511.     png_const_color_8p sig_bit)
  512. {
  513.    png_debug1(1, "in %s storage function", "sBIT");
  514.  
  515.    if (png_ptr == NULL || info_ptr == NULL)
  516.       return;
  517.  
  518.    png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
  519.    info_ptr->valid |= PNG_INFO_sBIT;
  520. }
  521. #endif
  522.  
  523. #ifdef PNG_sRGB_SUPPORTED
  524. void PNGAPI
  525. png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
  526. {
  527.    png_debug1(1, "in %s storage function", "sRGB");
  528.  
  529.    if (png_ptr == NULL || info_ptr == NULL)
  530.       return;
  531.  
  532.    info_ptr->srgb_intent = (png_byte)srgb_intent;
  533.    info_ptr->valid |= PNG_INFO_sRGB;
  534. }
  535.  
  536. void PNGAPI
  537. png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
  538.     int srgb_intent)
  539. {
  540.    png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
  541.  
  542.    if (png_ptr == NULL || info_ptr == NULL)
  543.       return;
  544.  
  545.    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
  546.  
  547. #  ifdef PNG_gAMA_SUPPORTED
  548.    png_set_gAMA_fixed(png_ptr, info_ptr, 45455L);
  549. #  endif
  550.  
  551. #  ifdef PNG_cHRM_SUPPORTED
  552.    png_set_cHRM_fixed(png_ptr, info_ptr,
  553.       /* color      x       y */
  554.       /* white */ 31270L, 32900L,
  555.       /* red   */ 64000L, 33000L,
  556.       /* green */ 30000L, 60000L,
  557.       /* blue  */ 15000L,  6000L
  558.    );
  559. #  endif /* cHRM */
  560. }
  561. #endif /* sRGB */
  562.  
  563.  
  564. #ifdef PNG_iCCP_SUPPORTED
  565. void PNGAPI
  566. png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
  567.     png_const_charp name, int compression_type,
  568.     png_const_bytep profile, png_uint_32 proflen)
  569. {
  570.    png_charp new_iccp_name;
  571.    png_bytep new_iccp_profile;
  572.    png_uint_32 length;
  573.  
  574.    png_debug1(1, "in %s storage function", "iCCP");
  575.  
  576.    if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
  577.       return;
  578.  
  579.    length = png_strlen(name)+1;
  580.    new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
  581.  
  582.    if (new_iccp_name == NULL)
  583.    {
  584.         png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
  585.       return;
  586.    }
  587.  
  588.    png_memcpy(new_iccp_name, name, length);
  589.    new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
  590.  
  591.    if (new_iccp_profile == NULL)
  592.    {
  593.       png_free (png_ptr, new_iccp_name);
  594.       png_warning(png_ptr,
  595.           "Insufficient memory to process iCCP profile");
  596.       return;
  597.    }
  598.  
  599.    png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
  600.  
  601.    png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
  602.  
  603.    info_ptr->iccp_proflen = proflen;
  604.    info_ptr->iccp_name = new_iccp_name;
  605.    info_ptr->iccp_profile = new_iccp_profile;
  606.    /* Compression is always zero but is here so the API and info structure
  607.     * does not have to change if we introduce multiple compression types
  608.     */
  609.    info_ptr->iccp_compression = (png_byte)compression_type;
  610.    info_ptr->free_me |= PNG_FREE_ICCP;
  611.    info_ptr->valid |= PNG_INFO_iCCP;
  612. }
  613. #endif
  614.  
  615. #ifdef PNG_TEXT_SUPPORTED
  616. void PNGAPI
  617. png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
  618.     int num_text)
  619. {
  620.    int ret;
  621.    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
  622.  
  623.    if (ret)
  624.       png_error(png_ptr, "Insufficient memory to store text");
  625. }
  626.  
  627. int /* PRIVATE */
  628. png_set_text_2(png_structp png_ptr, png_infop info_ptr,
  629.     png_const_textp text_ptr, int num_text)
  630. {
  631.    int i;
  632.  
  633.    png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
  634.        png_ptr->chunk_name[0] == '\0') ?
  635.        "text" : (png_const_charp)png_ptr->chunk_name));
  636.  
  637.    if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
  638.       return(0);
  639.  
  640.    /* Make sure we have enough space in the "text" array in info_struct
  641.     * to hold all of the incoming text_ptr objects.
  642.     */
  643.    if (info_ptr->num_text + num_text > info_ptr->max_text)
  644.    {
  645.       if (info_ptr->text != NULL)
  646.       {
  647.          png_textp old_text;
  648.          int old_max;
  649.  
  650.          old_max = info_ptr->max_text;
  651.          info_ptr->max_text = info_ptr->num_text + num_text + 8;
  652.          old_text = info_ptr->text;
  653.          info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  654.             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  655.  
  656.          if (info_ptr->text == NULL)
  657.          {
  658.             png_free(png_ptr, old_text);
  659.             return(1);
  660.          }
  661.  
  662.          png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
  663.              png_sizeof(png_text)));
  664.          png_free(png_ptr, old_text);
  665.       }
  666.  
  667.       else
  668.       {
  669.          info_ptr->max_text = num_text + 8;
  670.          info_ptr->num_text = 0;
  671.          info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  672.              (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  673.          if (info_ptr->text == NULL)
  674.             return(1);
  675.          info_ptr->free_me |= PNG_FREE_TEXT;
  676.       }
  677.  
  678.       png_debug1(3, "allocated %d entries for info_ptr->text",
  679.           info_ptr->max_text);
  680.    }
  681.    for (i = 0; i < num_text; i++)
  682.    {
  683.       png_size_t text_length, key_len;
  684.       png_size_t lang_len, lang_key_len;
  685.       png_textp textp = &(info_ptr->text[info_ptr->num_text]);
  686.  
  687.       if (text_ptr[i].key == NULL)
  688.           continue;
  689.  
  690.       if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
  691.           text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
  692.       {
  693.          png_warning(png_ptr, "text compression mode is out of range");
  694.          continue;
  695.       }
  696.  
  697.       key_len = png_strlen(text_ptr[i].key);
  698.  
  699.       if (text_ptr[i].compression <= 0)
  700.       {
  701.          lang_len = 0;
  702.          lang_key_len = 0;
  703.       }
  704.  
  705.       else
  706. #  ifdef PNG_iTXt_SUPPORTED
  707.       {
  708.          /* Set iTXt data */
  709.  
  710.          if (text_ptr[i].lang != NULL)
  711.             lang_len = png_strlen(text_ptr[i].lang);
  712.  
  713.          else
  714.             lang_len = 0;
  715.  
  716.          if (text_ptr[i].lang_key != NULL)
  717.             lang_key_len = png_strlen(text_ptr[i].lang_key);
  718.  
  719.          else
  720.             lang_key_len = 0;
  721.       }
  722. #  else /* PNG_iTXt_SUPPORTED */
  723.       {
  724.          png_warning(png_ptr, "iTXt chunk not supported");
  725.          continue;
  726.       }
  727. #  endif
  728.  
  729.       if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
  730.       {
  731.          text_length = 0;
  732. #  ifdef PNG_iTXt_SUPPORTED
  733.          if (text_ptr[i].compression > 0)
  734.             textp->compression = PNG_ITXT_COMPRESSION_NONE;
  735.  
  736.          else
  737. #  endif
  738.             textp->compression = PNG_TEXT_COMPRESSION_NONE;
  739.       }
  740.  
  741.       else
  742.       {
  743.          text_length = png_strlen(text_ptr[i].text);
  744.          textp->compression = text_ptr[i].compression;
  745.       }
  746.  
  747.       textp->key = (png_charp)png_malloc_warn(png_ptr,
  748.           (png_size_t)
  749.           (key_len + text_length + lang_len + lang_key_len + 4));
  750.  
  751.       if (textp->key == NULL)
  752.          return(1);
  753.  
  754.       png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
  755.           (unsigned long)(png_uint_32)
  756.           (key_len + lang_len + lang_key_len + text_length + 4),
  757.           textp->key);
  758.  
  759.       png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
  760.       *(textp->key + key_len) = '\0';
  761.  
  762.       if (text_ptr[i].compression > 0)
  763.       {
  764.          textp->lang = textp->key + key_len + 1;
  765.          png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
  766.          *(textp->lang + lang_len) = '\0';
  767.          textp->lang_key = textp->lang + lang_len + 1;
  768.          png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
  769.          *(textp->lang_key + lang_key_len) = '\0';
  770.          textp->text = textp->lang_key + lang_key_len + 1;
  771.       }
  772.  
  773.       else
  774.       {
  775.          textp->lang=NULL;
  776.          textp->lang_key=NULL;
  777.          textp->text = textp->key + key_len + 1;
  778.       }
  779.  
  780.       if (text_length)
  781.          png_memcpy(textp->text, text_ptr[i].text,
  782.              (png_size_t)(text_length));
  783.  
  784.       *(textp->text + text_length) = '\0';
  785.  
  786. #  ifdef PNG_iTXt_SUPPORTED
  787.       if (textp->compression > 0)
  788.       {
  789.          textp->text_length = 0;
  790.          textp->itxt_length = text_length;
  791.       }
  792.  
  793.       else
  794. #  endif
  795.       {
  796.          textp->text_length = text_length;
  797.          textp->itxt_length = 0;
  798.       }
  799.  
  800.       info_ptr->num_text++;
  801.       png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
  802.    }
  803.    return(0);
  804. }
  805. #endif
  806.  
  807. #ifdef PNG_tIME_SUPPORTED
  808. void PNGAPI
  809. png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
  810. {
  811.    png_debug1(1, "in %s storage function", "tIME");
  812.  
  813.    if (png_ptr == NULL || info_ptr == NULL ||
  814.        (png_ptr->mode & PNG_WROTE_tIME))
  815.       return;
  816.  
  817.    png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
  818.    info_ptr->valid |= PNG_INFO_tIME;
  819. }
  820. #endif
  821.  
  822. #ifdef PNG_tRNS_SUPPORTED
  823. void PNGAPI
  824. png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
  825.     png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
  826. {
  827.    png_debug1(1, "in %s storage function", "tRNS");
  828.  
  829.    if (png_ptr == NULL || info_ptr == NULL)
  830.       return;
  831.  
  832.    if (trans_alpha != NULL)
  833.    {
  834.        /* It may not actually be necessary to set png_ptr->trans_alpha here;
  835.         * we do it for backward compatibility with the way the png_handle_tRNS
  836.         * function used to do the allocation.
  837.         */
  838.  
  839.        png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
  840.  
  841.        /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
  842.        png_ptr->trans_alpha = info_ptr->trans_alpha =
  843.            (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
  844.  
  845.        if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
  846.           png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
  847.    }
  848.  
  849.    if (trans_color != NULL)
  850.    {
  851.       int sample_max = (1 << info_ptr->bit_depth);
  852.  
  853.       if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
  854.           (int)trans_color->gray > sample_max) ||
  855.           (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
  856.           ((int)trans_color->red > sample_max ||
  857.           (int)trans_color->green > sample_max ||
  858.           (int)trans_color->blue > sample_max)))
  859.          png_warning(png_ptr,
  860.             "tRNS chunk has out-of-range samples for bit_depth");
  861.  
  862.       png_memcpy(&(info_ptr->trans_color), trans_color,
  863.          png_sizeof(png_color_16));
  864.  
  865.       if (num_trans == 0)
  866.          num_trans = 1;
  867.    }
  868.  
  869.    info_ptr->num_trans = (png_uint_16)num_trans;
  870.  
  871.    if (num_trans != 0)
  872.    {
  873.       info_ptr->valid |= PNG_INFO_tRNS;
  874.       info_ptr->free_me |= PNG_FREE_TRNS;
  875.    }
  876. }
  877. #endif
  878.  
  879. #ifdef PNG_sPLT_SUPPORTED
  880. void PNGAPI
  881. png_set_sPLT(png_structp png_ptr,
  882.     png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
  883. /*
  884.  *  entries        - array of png_sPLT_t structures
  885.  *                   to be added to the list of palettes
  886.  *                   in the info structure.
  887.  *
  888.  *  nentries       - number of palette structures to be
  889.  *                   added.
  890.  */
  891. {
  892.    png_sPLT_tp np;
  893.    int i;
  894.  
  895.    if (png_ptr == NULL || info_ptr == NULL)
  896.       return;
  897.  
  898.    np = (png_sPLT_tp)png_malloc_warn(png_ptr,
  899.        (info_ptr->splt_palettes_num + nentries) *
  900.        (png_size_t)png_sizeof(png_sPLT_t));
  901.  
  902.    if (np == NULL)
  903.    {
  904.       png_warning(png_ptr, "No memory for sPLT palettes");
  905.       return;
  906.    }
  907.  
  908.    png_memcpy(np, info_ptr->splt_palettes,
  909.        info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
  910.  
  911.    png_free(png_ptr, info_ptr->splt_palettes);
  912.    info_ptr->splt_palettes=NULL;
  913.  
  914.    for (i = 0; i < nentries; i++)
  915.    {
  916.       png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
  917.       png_const_sPLT_tp from = entries + i;
  918.       png_uint_32 length;
  919.  
  920.       length = png_strlen(from->name) + 1;
  921.       to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);
  922.  
  923.       if (to->name == NULL)
  924.       {
  925.          png_warning(png_ptr,
  926.              "Out of memory while processing sPLT chunk");
  927.          continue;
  928.       }
  929.  
  930.       png_memcpy(to->name, from->name, length);
  931.       to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
  932.           (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));
  933.  
  934.       if (to->entries == NULL)
  935.       {
  936.          png_warning(png_ptr,
  937.              "Out of memory while processing sPLT chunk");
  938.          png_free(png_ptr, to->name);
  939.          to->name = NULL;
  940.          continue;
  941.       }
  942.  
  943.       png_memcpy(to->entries, from->entries,
  944.           from->nentries * png_sizeof(png_sPLT_entry));
  945.  
  946.       to->nentries = from->nentries;
  947.       to->depth = from->depth;
  948.    }
  949.  
  950.    info_ptr->splt_palettes = np;
  951.    info_ptr->splt_palettes_num += nentries;
  952.    info_ptr->valid |= PNG_INFO_sPLT;
  953.    info_ptr->free_me |= PNG_FREE_SPLT;
  954. }
  955. #endif /* PNG_sPLT_SUPPORTED */
  956.  
  957. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  958. void PNGAPI
  959. png_set_unknown_chunks(png_structp png_ptr,
  960.    png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
  961. {
  962.    png_unknown_chunkp np;
  963.    int i;
  964.  
  965.    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
  966.       return;
  967.  
  968.    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
  969.        (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
  970.        png_sizeof(png_unknown_chunk));
  971.  
  972.    if (np == NULL)
  973.    {
  974.       png_warning(png_ptr,
  975.           "Out of memory while processing unknown chunk");
  976.       return;
  977.    }
  978.  
  979.    png_memcpy(np, info_ptr->unknown_chunks,
  980.        (png_size_t)info_ptr->unknown_chunks_num *
  981.        png_sizeof(png_unknown_chunk));
  982.  
  983.    png_free(png_ptr, info_ptr->unknown_chunks);
  984.    info_ptr->unknown_chunks = NULL;
  985.  
  986.    for (i = 0; i < num_unknowns; i++)
  987.    {
  988.       png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
  989.       png_const_unknown_chunkp from = unknowns + i;
  990.  
  991.       png_memcpy(to->name, from->name, png_sizeof(from->name));
  992.       to->name[png_sizeof(to->name)-1] = '\0';
  993.       to->size = from->size;
  994.  
  995.       /* Note our location in the read or write sequence */
  996.       to->location = (png_byte)(png_ptr->mode & 0xff);
  997.  
  998.       if (from->size == 0)
  999.          to->data=NULL;
  1000.  
  1001.       else
  1002.       {
  1003.          to->data = (png_bytep)png_malloc_warn(png_ptr,
  1004.              (png_size_t)from->size);
  1005.  
  1006.          if (to->data == NULL)
  1007.          {
  1008.             png_warning(png_ptr,
  1009.                 "Out of memory while processing unknown chunk");
  1010.             to->size = 0;
  1011.          }
  1012.  
  1013.          else
  1014.             png_memcpy(to->data, from->data, from->size);
  1015.       }
  1016.    }
  1017.  
  1018.    info_ptr->unknown_chunks = np;
  1019.    info_ptr->unknown_chunks_num += num_unknowns;
  1020.    info_ptr->free_me |= PNG_FREE_UNKN;
  1021. }
  1022.  
  1023. void PNGAPI
  1024. png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
  1025.     int chunk, int location)
  1026. {
  1027.    if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
  1028.        info_ptr->unknown_chunks_num)
  1029.       info_ptr->unknown_chunks[chunk].location = (png_byte)location;
  1030. }
  1031. #endif
  1032.  
  1033.  
  1034. #ifdef PNG_MNG_FEATURES_SUPPORTED
  1035. png_uint_32 PNGAPI
  1036. png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
  1037. {
  1038.    png_debug(1, "in png_permit_mng_features");
  1039.  
  1040.    if (png_ptr == NULL)
  1041.       return (png_uint_32)0;
  1042.  
  1043.    png_ptr->mng_features_permitted =
  1044.        (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
  1045.  
  1046.    return (png_uint_32)png_ptr->mng_features_permitted;
  1047. }
  1048. #endif
  1049.  
  1050. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  1051. void PNGAPI
  1052. png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
  1053.     chunk_list, int num_chunks)
  1054. {
  1055.    png_bytep new_list, p;
  1056.    int i, old_num_chunks;
  1057.    if (png_ptr == NULL)
  1058.       return;
  1059.  
  1060.    if (num_chunks == 0)
  1061.    {
  1062.       if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
  1063.          png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  1064.  
  1065.       else
  1066.          png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  1067.  
  1068.       if (keep == PNG_HANDLE_CHUNK_ALWAYS)
  1069.          png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  1070.  
  1071.       else
  1072.          png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  1073.  
  1074.       return;
  1075.    }
  1076.  
  1077.    if (chunk_list == NULL)
  1078.       return;
  1079.  
  1080.    old_num_chunks = png_ptr->num_chunk_list;
  1081.    new_list=(png_bytep)png_malloc(png_ptr,
  1082.        (png_size_t)(5*(num_chunks + old_num_chunks)));
  1083.  
  1084.    if (png_ptr->chunk_list != NULL)
  1085.    {
  1086.       png_memcpy(new_list, png_ptr->chunk_list,
  1087.           (png_size_t)(5*old_num_chunks));
  1088.       png_free(png_ptr, png_ptr->chunk_list);
  1089.       png_ptr->chunk_list=NULL;
  1090.    }
  1091.  
  1092.    png_memcpy(new_list + 5*old_num_chunks, chunk_list,
  1093.        (png_size_t)(5*num_chunks));
  1094.  
  1095.    for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
  1096.       *p=(png_byte)keep;
  1097.  
  1098.    png_ptr->num_chunk_list = old_num_chunks + num_chunks;
  1099.    png_ptr->chunk_list = new_list;
  1100.    png_ptr->free_me |= PNG_FREE_LIST;
  1101. }
  1102. #endif
  1103.  
  1104. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  1105. void PNGAPI
  1106. png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
  1107.     png_user_chunk_ptr read_user_chunk_fn)
  1108. {
  1109.    png_debug(1, "in png_set_read_user_chunk_fn");
  1110.  
  1111.    if (png_ptr == NULL)
  1112.       return;
  1113.  
  1114.    png_ptr->read_user_chunk_fn = read_user_chunk_fn;
  1115.    png_ptr->user_chunk_ptr = user_chunk_ptr;
  1116. }
  1117. #endif
  1118.  
  1119. #ifdef PNG_INFO_IMAGE_SUPPORTED
  1120. void PNGAPI
  1121. png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
  1122. {
  1123.    png_debug1(1, "in %s storage function", "rows");
  1124.  
  1125.    if (png_ptr == NULL || info_ptr == NULL)
  1126.       return;
  1127.  
  1128.    if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
  1129.       png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
  1130.  
  1131.    info_ptr->row_pointers = row_pointers;
  1132.  
  1133.    if (row_pointers)
  1134.       info_ptr->valid |= PNG_INFO_IDAT;
  1135. }
  1136. #endif
  1137.  
  1138. void PNGAPI
  1139. png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
  1140. {
  1141.     if (png_ptr == NULL)
  1142.        return;
  1143.  
  1144.     png_free(png_ptr, png_ptr->zbuf);
  1145.  
  1146.     if (size > ZLIB_IO_MAX)
  1147.     {
  1148.        png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
  1149.        png_ptr->zbuf_size = ZLIB_IO_MAX;
  1150.        size = ZLIB_IO_MAX; /* must fit */
  1151.     }
  1152.  
  1153.     else
  1154.        png_ptr->zbuf_size = (uInt)size;
  1155.  
  1156.     png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
  1157.  
  1158.     /* The following ensures a relatively safe failure if this gets called while
  1159.      * the buffer is actually in use.
  1160.      */
  1161.     png_ptr->zstream.next_out = png_ptr->zbuf;
  1162.     png_ptr->zstream.avail_out = 0;
  1163.     png_ptr->zstream.avail_in = 0;
  1164. }
  1165.  
  1166. void PNGAPI
  1167. png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
  1168. {
  1169.    if (png_ptr && info_ptr)
  1170.       info_ptr->valid &= ~mask;
  1171. }
  1172.  
  1173.  
  1174.  
  1175. #ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1176. /* This function was added to libpng 1.2.6 */
  1177. void PNGAPI
  1178. png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
  1179.     png_uint_32 user_height_max)
  1180. {
  1181.    /* Images with dimensions larger than these limits will be
  1182.     * rejected by png_set_IHDR().  To accept any PNG datastream
  1183.     * regardless of dimensions, set both limits to 0x7ffffffL.
  1184.     */
  1185.    if (png_ptr == NULL)
  1186.       return;
  1187.  
  1188.    png_ptr->user_width_max = user_width_max;
  1189.    png_ptr->user_height_max = user_height_max;
  1190. }
  1191.  
  1192. /* This function was added to libpng 1.4.0 */
  1193. void PNGAPI
  1194. png_set_chunk_cache_max (png_structp png_ptr,
  1195.    png_uint_32 user_chunk_cache_max)
  1196. {
  1197.     if (png_ptr)
  1198.        png_ptr->user_chunk_cache_max = user_chunk_cache_max;
  1199. }
  1200.  
  1201. /* This function was added to libpng 1.4.1 */
  1202. void PNGAPI
  1203. png_set_chunk_malloc_max (png_structp png_ptr,
  1204.     png_alloc_size_t user_chunk_malloc_max)
  1205. {
  1206.    if (png_ptr)
  1207.       png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
  1208. }
  1209. #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
  1210.  
  1211.  
  1212. #ifdef PNG_BENIGN_ERRORS_SUPPORTED
  1213. void PNGAPI
  1214. png_set_benign_errors(png_structp png_ptr, int allowed)
  1215. {
  1216.    png_debug(1, "in png_set_benign_errors");
  1217.  
  1218.    if (allowed)
  1219.       png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
  1220.  
  1221.    else
  1222.       png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
  1223. }
  1224. #endif /* PNG_BENIGN_ERRORS_SUPPORTED */
  1225. #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
  1226.