pngset.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:39k
源码类别:

打印编程

开发平台:

Visual C++

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