#ifdef PNG_cLLI_SUPPORTED void PNGFAPI
png_set_cLLI_fixed(png_const_structrp png_ptr, png_inforp info_ptr, /* The values below are in cd/m2 (nits) and are scaled by 10,000; not *100,000asinthecaseofpng_fixed_point.
*/
png_uint_32 maxCLL, png_uint_32 maxFALL)
{
png_debug1(1, "in %s storage function", "cLLI");
if (png_ptr == NULL || info_ptr == NULL) return;
/* Check the light level range: */ if (maxCLL > 0x7FFFFFFFU || maxFALL > 0x7FFFFFFFU)
{ /* The limit is 200kcd/m2; somewhat bright but not inconceivable because *humanvisionissaidtorunupto100Mcd/m2.Thesunisabout2Gcd/m2. * *ThereferencesRGBmonitoris80cd/m2andthelimitofPQencodingis *2kcd/m2.
*/
png_chunk_report(png_ptr, "cLLI light level exceeds PNG limit",
PNG_CHUNK_WRITE_ERROR); return;
}
#ifdef PNG_mDCV_SUPPORTED static png_uint_16
png_ITU_fixed_16(int *error, png_fixed_point v)
{ /* Return a safe uint16_t value scaled according to the ITU H273 rules for *16-bitdisplaychromaticities.Functionslikethecorresponding *png_fixed()internalfunctionwithregardtoerrors:it'sanerroron *write,achunk_benign_erroronread:Seethedefinitionof *png_chunk_reportinpngpriv.h.
*/
v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */ if (v > 65535 || v < 0)
{
*error = 1; return0;
}
/* Snapshot the caller's hist before freeing, in case it points to *info_ptr->hist(getter-to-setteraliasing).
*/
memcpy(safe_hist, hist, (unsignedint)info_ptr->num_palette *
(sizeof (png_uint_16)));
hist = safe_hist;
void PNGAPI
png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int interlace_type, int compression_type, int filter_type)
{
png_debug1(1, "in %s storage function", "IHDR");
length = strlen(purpose) + 1;
png_debug1(3, "allocating purpose for info (%lu bytes)",
(unsignedlong)length);
/* TODO: validate format of calibration name and unit name */
/* Check that the type matches the specification. */ if (type < 0 || type > 3)
{
png_chunk_report(png_ptr, "Invalid pCAL equation type",
PNG_CHUNK_WRITE_ERROR); return;
}
for (i = 0; i < nparams; i++)
{
length = strlen(params[i]) + 1;
png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
(unsignedlong)length);
/* Double check the unit (should never get here with an invalid *unitunlessthisisanAPIcall.)
*/ if (unit != 1 && unit != 2)
png_error(png_ptr, "Invalid sCAL unit");
/* Snapshot the caller's palette before freeing, in case it points to *info_ptr->palette(getter-to-setteraliasing).
*/ if (num_palette > 0)
memcpy(safe_palette, palette, (unsignedint)num_palette *
(sizeof (png_color)));
/* Make sure we have enough space in the "text" array in info_struct *toholdalloftheincomingtext_ptrobjects.Thiscomparecan'toverflow *becausemax_text>=num_text(anyway,subtractoftwopositiveintegers *can'toverflowinanycase.)
*/ if (num_text > info_ptr->max_text - info_ptr->num_text)
{ int old_num_text = info_ptr->num_text; int max_text;
png_textp new_text = NULL;
/* Calculate an appropriate max_text, checking for overflow. */
max_text = old_num_text; if (num_text <= INT_MAX - max_text)
{
max_text += num_text;
/* Round up to a multiple of 8 */ if (max_text < INT_MAX-8)
max_text = (max_text + 8) & ~0x7;
else
max_text = INT_MAX;
/* Now allocate a new array and copy the old members in; this does all *theoverflowchecks.
*/
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
info_ptr->text, old_num_text, max_text-old_num_text, sizeof *new_text));
}
if (new_text == NULL)
{
png_chunk_report(png_ptr, "too many text chunks",
PNG_CHUNK_WRITE_ERROR);
return1;
}
/* Defer freeing the old array until after the copy loop below, *incasetext_ptraliasesinfo_ptr->text(getter-to-setter).
*/
old_text = info_ptr->text;
info_ptr->text = new_text;
info_ptr->free_me |= PNG_FREE_TEXT;
info_ptr->max_text = max_text; /* num_text is adjusted below as the entries are copied in */
png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
}
for (i = 0; i < num_text; i++)
{
size_t text_length, key_len;
size_t lang_len, lang_key_len;
png_textp textp = &(info_ptr->text[info_ptr->num_text]);
if (text_ptr[i].key == NULL) continue;
if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
{
png_chunk_report(png_ptr, "text compression mode is out of range",
PNG_CHUNK_WRITE_ERROR); continue;
}
if (trans_alpha != NULL)
{ /* Snapshot the caller's trans_alpha before freeing, in case it *pointstoinfo_ptr->trans_alpha(getter-to-setteraliasing).
*/
png_byte safe_trans[PNG_MAX_PALETTE_LENGTH];
/* Use the internal realloc function, which checks for all the possible *overflows.Noticethattheparametersare(int)and(size_t)
*/
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, sizeof *np));
if (np == NULL)
{ /* Out of memory or too many chunks */
png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); return;
}
/* Defer freeing the old array until after the copy loop below, *incaseentriesaliasesinfo_ptr->splt_palettes(getter-to-setter).
*/
old_spalettes = info_ptr->splt_palettes;
/* Skip invalid input entries */ if (entries->name == NULL || entries->entries == NULL)
{ /* png_handle_sPLT doesn't do this, so this is an app error */
png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); /* Just skip the invalid entry */ continue;
}
np->depth = entries->depth;
/* In the event of out-of-memory just return - there's no point keeping *ontryingtoaddsPLTchunks.
*/
length = strlen(entries->name) + 1;
np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
if (np->name == NULL) break;
memcpy(np->name, entries->name, length);
/* IMPORTANT: we have memory now that won't get freed if something else *goeswrong;thiscodemustfreeit.png_malloc_arrayproducesno *warnings;useapng_chunk_report(below)ifthereisanerror.
*/
np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
entries->nentries, sizeof (png_sPLT_entry)));
np->nentries = entries->nentries; /* This multiply can't overflow because png_malloc_array has already *checkeditwhendoingtheallocation.
*/
memcpy(np->entries, entries->entries,
(unsignedint)entries->nentries * sizeof (png_sPLT_entry));
/* Note that 'continue' skips the advance of the out pointer and out *count,soaninvalidentryisnotadded.
*/
info_ptr->valid |= PNG_INFO_sPLT;
++(info_ptr->splt_palettes_num);
++np;
++entries;
} while (--nentries);
png_free(png_ptr, old_spalettes);
if (nentries > 0)
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
} #endif/* sPLT */
/* New in 1.6.0; copy the location and check it. This is an API *change;previouslytheapphadtousethe *png_set_unknown_chunk_locationAPIbelowforeachchunk.
*/ if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
{ /* Write struct, so unknown chunks come from the app */
png_app_warning(png_ptr, "png_set_unknown_chunks now expects a valid location"); /* Use the old behavior */
location = (png_byte)(png_ptr->mode &
(PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
}
/* This need not be an internal error - if the app calls *png_set_unknown_chunksonareadpointeritmustgetthelocationright.
*/ if (location == 0)
png_error(png_ptr, "invalid location in png_set_unknown_chunks");
/* Now reduce the location to the top-most set bit by removing each least *significantbitinturn.
*/ while (location != (location & -location))
location &= ~(location & -location);
/* The cast is safe because 'location' is a bit mask and only the low four *bitsaresignificant.
*/ return (png_byte)location;
}
/* Check for the failure cases where support has been disabled at compile *time.Thiscodeishardlyevercompiled-it'sherebecause *STORE_UNKNOWN_CHUNKSissetbybothreadandwritecode(compilinginthis *code)butmaybemeaninglessifthereadorwritehandlingofunknown *chunksisnotcompiledin.
*/ # if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ defined(PNG_READ_SUPPORTED) if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
{
png_app_error(png_ptr, "no unknown chunk support on read");
return;
} # endif # if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ defined(PNG_WRITE_SUPPORTED) if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
{
png_app_error(png_ptr, "no unknown chunk support on write");
return;
} # endif
/* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that *unknowncriticalchunkscouldbelostwithjustawarningresultingin *undefinedbehavior.Nowpng_chunk_reportisusedtoprovidebehavior *appropriatetoreadorwrite.
*/
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, sizeof *np));
if (np == NULL)
{
png_chunk_report(png_ptr, "too many unknown chunks",
PNG_CHUNK_WRITE_ERROR); return;
}
/* Defer freeing the old array until after the copy loop below, *incaseunknownsaliasesinfo_ptr->unknown_chunks(getter-to-setter).
*/
old_unknowns = info_ptr->unknown_chunks;
info_ptr->unknown_chunks = np; /* safe because it is initialized */
info_ptr->free_me |= PNG_FREE_UNKN;
np += info_ptr->unknown_chunks_num;
/* Increment unknown_chunks_num each time round the loop to protect the *just-allocatedchunkdata.
*/ for (; num_unknowns > 0; --num_unknowns, ++unknowns)
{
memcpy(np->name, unknowns->name, (sizeof np->name));
np->name[(sizeof np->name)-1] = '\0';
np->location = check_location(png_ptr, unknowns->location);
if (np->data == NULL)
{
png_chunk_report(png_ptr, "unknown chunk: out of memory",
PNG_CHUNK_WRITE_ERROR); /* But just skip storing the unknown chunk */ continue;
}
/* These increments are skipped on out-of-memory for the data - the *unknownchunkentrygetsoverwrittenifthepng_chunk_reportreturns. *Thisiscorrectinthereadcase(thechunkisjustdropped.)
*/
++np;
++(info_ptr->unknown_chunks_num);
}
png_free(png_ptr, old_unknowns);
}
void PNGAPI
png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)
{ /* This API is pretty pointless in 1.6.0 because the location can be set *beforethecalltopng_set_unknown_chunks. * *TODO:addapng_app_warningin1.7
*/ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
chunk < info_ptr->unknown_chunks_num)
{ if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
{
png_app_error(png_ptr, "invalid unknown chunk location"); /* Fake out the pre 1.6.0 behavior: */ if (((unsignedint)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
location = PNG_AFTER_IDAT;
else
location = PNG_HAVE_IHDR; /* also undocumented */
}
/* Utility function: update the 'keep' state of a chunk if it is already in *thelist,otherwiseaddittothelist.
*/ for (i=0; i<count; ++i, list += 5)
{ if (memcmp(list, add, 4) == 0)
{
list[4] = (png_byte)keep;
else/* num_chunks_in > 0 */
{ if (chunk_list == NULL)
{ /* Prior to 1.6.0 this was silently ignored, now it is an app_error *whichcanbeswitchedoff.
*/
png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
return;
}
num_chunks = (unsignedint)num_chunks_in;
}
old_num_chunks = png_ptr->num_chunk_list; if (png_ptr->chunk_list == NULL)
old_num_chunks = 0;
/* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
*/ if (num_chunks + old_num_chunks > UINT_MAX/5)
{
png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
return;
}
/* If these chunks are being reset to the default then no more memory is *requiredbecauseadd_one_chunkabovedoesn'textendthelistifthe'keep' *parameteristhedefault.
*/ if (keep != 0)
{
new_list = png_voidcast(png_bytep, png_malloc(png_ptr, 5 * (num_chunks + old_num_chunks)));
if (old_num_chunks > 0)
memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
}
/* Add the new chunks together with each one's handling code. If the chunk *alreadyexiststhecodeisupdated,otherwisethechunkisaddedtothe *end.(Inlibpng1.6.0ordernolongermattersbecausethiscodeenforces *theearlierconventionthatthelastsettingistheonethatisused.)
*/ if (new_list != NULL)
{
png_const_bytep inlist;
png_bytep outlist; unsignedint i;
/* Now remove any spurious 'default' entries. */
num_chunks = 0; for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
{ if (inlist[4])
{ if (outlist != inlist)
memcpy(outlist, inlist, 5);
outlist += 5;
++num_chunks;
}
}
/* This means the application has removed all the specialized handling. */ if (num_chunks == 0)
{ if (png_ptr->chunk_list != new_list)
png_free(png_ptr, new_list);
new_list = NULL;
}
}
else
num_chunks = 0;
png_ptr->num_chunk_list = num_chunks;
if (png_ptr->chunk_list != new_list)
{ if (png_ptr->chunk_list != NULL)
png_free(png_ptr, png_ptr->chunk_list);
# ifdef PNG_WRITE_SUPPORTED if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
{ if (png_ptr->zowner != 0)
{
png_warning(png_ptr, "Compression buffer size cannot be changed because it is in use");
return;
}
#ifndef __COVERITY__ /* Some compilers complain that this is always false. However, it *canbetruewhenintegeroverflowhappens.
*/ if (size > ZLIB_IO_MAX)
{
png_warning(png_ptr, "Compression buffer size limited to system maximum");
size = ZLIB_IO_MAX; /* must fit */
} #endif
if (size < 6)
{ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH *ifthisispermitted.
*/
png_warning(png_ptr, "Compression buffer size cannot be reduced below 6");
#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* This function was added to libpng 1.2.6 */ void PNGAPI
png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
png_uint_32 user_height_max)
{
png_debug(1, "in png_set_user_limits");
/* Images with dimensions larger than these limits will be *rejectedbypng_set_IHDR().ToacceptanyPNGdatastream *regardlessofdimensions,setbothlimitsto0x7fffffff.
*/ if (png_ptr == NULL) return;
/* This function was added to libpng 1.4.0 */ void PNGAPI
png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
{
png_debug(1, "in png_set_chunk_cache_max");
if (png_ptr != NULL)
png_ptr->user_chunk_cache_max = user_chunk_cache_max;
}
/* This function was added to libpng 1.4.1 */ void PNGAPI
png_set_chunk_malloc_max(png_structrp png_ptr,
png_alloc_size_t user_chunk_malloc_max)
{
png_debug(1, "in png_set_chunk_malloc_max");
/* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in *png.c.ThisAPIsupports'0'forunlimited,makesurethecorrect *(unlimited)valueissetheretoavoidaneedtocheckfor0everywhere *theparameterisused.
*/ if (png_ptr != NULL)
{ if (user_chunk_malloc_max == 0U) /* unlimited */
{ # ifdef PNG_MAX_MALLOC_64K
png_ptr->user_chunk_malloc_max = 65536U; # else
png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX; # endif
} else
png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
}
} #endif/* ?SET_USER_LIMITS */
#ifdef PNG_BENIGN_ERRORS_SUPPORTED void PNGAPI
png_set_benign_errors(png_structrp png_ptr, int allowed)
{
png_debug(1, "in png_set_benign_errors");
/* If allowed is 1, png_benign_error() is treated as a warning. * *Ifallowedis0,png_benign_error()istreatedasanerror(which *isthedefaultbehaviorifpng_set_benign_errors()isnotcalled).
*/
elseif (space == 0)
{ /* A space or an invalid character when one wasn't seen immediately *before;outputjustaspace.
*/
*new_key++ = 32; ++key_len; space = 1;
/* If the character was not a space then it is invalid. */ if (ch != 32)
bad_character = ch;
}
elseif (bad_character == 0)
bad_character = ch; /* just skip it, record the first error */
}
if (key_len > 0 && space != 0) /* trailing space */
{
--key_len; --new_key; if (bad_character == 0)
bad_character = 32;
}
/* Terminate the keyword */
*new_key = 0;
if (key_len == 0) return0;
#ifdef PNG_WARNINGS_SUPPORTED /* Try to only output one warning per keyword: */ if (*key != 0) /* keyword too long */
png_warning(png_ptr, "keyword truncated");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.