LCOV - code coverage report
Current view: directory - media/libpng - pngset.c (source / functions) Found Hit Coverage
Test: app.info Lines: 270 51 18.9 %
Date: 2012-06-02 Functions: 20 5 25.0 %

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

Generated by: LCOV version 1.7