mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 21:58:37 -05:00
Updated LodePNG to 2018.08.09 version
This commit is contained in:
parent
5e8e608a9c
commit
727af1238f
350
external/lodepng/lodepng.cpp
vendored
350
external/lodepng/lodepng.cpp
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
LodePNG version 20180611
|
||||
LodePNG version 20180809
|
||||
|
||||
Copyright (c) 2005-2018 Lode Vandevenne
|
||||
|
||||
@ -39,7 +39,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
|
||||
#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/
|
||||
#endif /*_MSC_VER */
|
||||
|
||||
const char* LODEPNG_VERSION_STRING = "20180611";
|
||||
const char* LODEPNG_VERSION_STRING = "20180809";
|
||||
|
||||
/*
|
||||
This source file is built up in the following large parts. The code sections
|
||||
@ -283,42 +283,29 @@ static unsigned ucvector_push_back(ucvector* p, unsigned char c)
|
||||
|
||||
#ifdef LODEPNG_COMPILE_PNG
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*returns 1 if success, 0 if failure ==> nothing done*/
|
||||
static unsigned string_resize(char** out, size_t size)
|
||||
{
|
||||
char* data = (char*)lodepng_realloc(*out, size + 1);
|
||||
if(data)
|
||||
{
|
||||
data[size] = 0; /*null termination char*/
|
||||
*out = data;
|
||||
}
|
||||
return data != 0;
|
||||
}
|
||||
|
||||
/*init a {char*, size_t} pair for use as string*/
|
||||
static void string_init(char** out)
|
||||
{
|
||||
*out = NULL;
|
||||
string_resize(out, 0);
|
||||
}
|
||||
|
||||
/*free the above pair again*/
|
||||
/*free string pointer and set it to NULL*/
|
||||
static void string_cleanup(char** out)
|
||||
{
|
||||
lodepng_free(*out);
|
||||
*out = NULL;
|
||||
}
|
||||
|
||||
static void string_set(char** out, const char* in)
|
||||
/* dynamically allocates a new string with a copy of the null terminated input text */
|
||||
static char* alloc_string(const char* in)
|
||||
{
|
||||
size_t insize = strlen(in), i;
|
||||
if(string_resize(out, insize))
|
||||
size_t insize = strlen(in);
|
||||
char* out = (char*)lodepng_malloc(insize + 1);
|
||||
if(out)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i != insize; ++i)
|
||||
{
|
||||
(*out)[i] = in[i];
|
||||
out[i] = in[i];
|
||||
}
|
||||
out[i] = 0;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
#endif /*LODEPNG_COMPILE_PNG*/
|
||||
@ -2871,11 +2858,8 @@ unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str)
|
||||
info->text_keys = new_keys;
|
||||
info->text_strings = new_strings;
|
||||
|
||||
string_init(&info->text_keys[info->text_num - 1]);
|
||||
string_set(&info->text_keys[info->text_num - 1], key);
|
||||
|
||||
string_init(&info->text_strings[info->text_num - 1]);
|
||||
string_set(&info->text_strings[info->text_num - 1], str);
|
||||
info->text_keys[info->text_num - 1] = alloc_string(key);
|
||||
info->text_strings[info->text_num - 1] = alloc_string(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2950,20 +2934,42 @@ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langt
|
||||
info->itext_transkeys = new_transkeys;
|
||||
info->itext_strings = new_strings;
|
||||
|
||||
string_init(&info->itext_keys[info->itext_num - 1]);
|
||||
string_set(&info->itext_keys[info->itext_num - 1], key);
|
||||
|
||||
string_init(&info->itext_langtags[info->itext_num - 1]);
|
||||
string_set(&info->itext_langtags[info->itext_num - 1], langtag);
|
||||
|
||||
string_init(&info->itext_transkeys[info->itext_num - 1]);
|
||||
string_set(&info->itext_transkeys[info->itext_num - 1], transkey);
|
||||
|
||||
string_init(&info->itext_strings[info->itext_num - 1]);
|
||||
string_set(&info->itext_strings[info->itext_num - 1], str);
|
||||
info->itext_keys[info->itext_num - 1] = alloc_string(key);
|
||||
info->itext_langtags[info->itext_num - 1] = alloc_string(langtag);
|
||||
info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey);
|
||||
info->itext_strings[info->itext_num - 1] = alloc_string(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* same as set but does not delete */
|
||||
static unsigned lodepng_assign_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size)
|
||||
{
|
||||
info->iccp_name = alloc_string(name);
|
||||
info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size);
|
||||
|
||||
if(!info->iccp_name || !info->iccp_profile) return 83; /*alloc fail*/
|
||||
|
||||
memcpy(info->iccp_profile, profile, profile_size);
|
||||
info->iccp_profile_size = profile_size;
|
||||
|
||||
return 0; /*ok*/
|
||||
}
|
||||
|
||||
unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size)
|
||||
{
|
||||
if(info->iccp_name) lodepng_clear_icc(info);
|
||||
|
||||
return lodepng_assign_icc(info, name, profile, profile_size);
|
||||
}
|
||||
|
||||
void lodepng_clear_icc(LodePNGInfo* info)
|
||||
{
|
||||
string_cleanup(&info->iccp_name);
|
||||
lodepng_free(info->iccp_profile);
|
||||
info->iccp_profile = NULL;
|
||||
info->iccp_profile_size = 0;
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
void lodepng_info_init(LodePNGInfo* info)
|
||||
@ -2982,6 +2988,13 @@ void lodepng_info_init(LodePNGInfo* info)
|
||||
info->time_defined = 0;
|
||||
info->phys_defined = 0;
|
||||
|
||||
info->gama_defined = 0;
|
||||
info->chrm_defined = 0;
|
||||
info->srgb_defined = 0;
|
||||
info->iccp_defined = 0;
|
||||
info->iccp_name = NULL;
|
||||
info->iccp_profile = NULL;
|
||||
|
||||
LodePNGUnknownChunks_init(info);
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
}
|
||||
@ -2993,6 +3006,8 @@ void lodepng_info_cleanup(LodePNGInfo* info)
|
||||
LodePNGText_cleanup(info);
|
||||
LodePNGIText_cleanup(info);
|
||||
|
||||
lodepng_clear_icc(info);
|
||||
|
||||
LodePNGUnknownChunks_cleanup(info);
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
}
|
||||
@ -3007,6 +3022,10 @@ unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source)
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
CERROR_TRY_RETURN(LodePNGText_copy(dest, source));
|
||||
CERROR_TRY_RETURN(LodePNGIText_copy(dest, source));
|
||||
if(source->iccp_defined)
|
||||
{
|
||||
CERROR_TRY_RETURN(lodepng_assign_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size));
|
||||
}
|
||||
|
||||
LodePNGUnknownChunks_init(dest);
|
||||
CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source));
|
||||
@ -3014,13 +3033,6 @@ unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b)
|
||||
{
|
||||
LodePNGInfo temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
/* ////////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
/*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/
|
||||
@ -4465,7 +4477,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting
|
||||
unsigned length, begin, compressed;
|
||||
char *key = 0, *langtag = 0, *transkey = 0;
|
||||
ucvector decoded;
|
||||
ucvector_init(&decoded);
|
||||
ucvector_init(&decoded); /* TODO: only use in case of compressed text */
|
||||
|
||||
while(!error) /*not really a while loop, only used to break on error*/
|
||||
{
|
||||
@ -4575,6 +4587,88 @@ static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, siz
|
||||
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static unsigned readChunk_gAMA(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
|
||||
{
|
||||
if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/
|
||||
|
||||
info->gama_defined = 1;
|
||||
info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
|
||||
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static unsigned readChunk_cHRM(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
|
||||
{
|
||||
if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/
|
||||
|
||||
info->chrm_defined = 1;
|
||||
info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3];
|
||||
info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7];
|
||||
info->chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11];
|
||||
info->chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15];
|
||||
info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19];
|
||||
info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23];
|
||||
info->chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27];
|
||||
info->chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31];
|
||||
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
|
||||
{
|
||||
if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/
|
||||
|
||||
info->srgb_defined = 1;
|
||||
info->srgb_intent = data[0];
|
||||
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
|
||||
const unsigned char* data, size_t chunkLength)
|
||||
{
|
||||
unsigned error = 0;
|
||||
unsigned i;
|
||||
|
||||
unsigned length, string2_begin;
|
||||
ucvector decoded;
|
||||
|
||||
info->iccp_defined = 1;
|
||||
if(info->iccp_name) lodepng_clear_icc(info);
|
||||
|
||||
for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
|
||||
if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/
|
||||
if(length < 1 || length > 79) return 89; /*keyword too short or long*/
|
||||
|
||||
info->iccp_name = (char*)lodepng_malloc(length + 1);
|
||||
if(!info->iccp_name) return 83; /*alloc fail*/
|
||||
|
||||
info->iccp_name[length] = 0;
|
||||
for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i];
|
||||
|
||||
if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/
|
||||
|
||||
string2_begin = length + 2;
|
||||
if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/
|
||||
|
||||
length = (unsigned)chunkLength - string2_begin;
|
||||
ucvector_init(&decoded);
|
||||
error = zlib_decompress(&decoded.data, &decoded.size,
|
||||
(unsigned char*)(&data[string2_begin]),
|
||||
length, zlibsettings);
|
||||
if(!error) {
|
||||
info->iccp_profile_size = decoded.size;
|
||||
info->iccp_profile = (unsigned char*)lodepng_malloc(decoded.size);
|
||||
if(info->iccp_profile) {
|
||||
memcpy(info->iccp_profile, decoded.data, decoded.size);
|
||||
} else {
|
||||
error = 83; /* alloc fail */
|
||||
}
|
||||
}
|
||||
ucvector_cleanup(&decoded);
|
||||
return error;
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/
|
||||
@ -4640,6 +4734,8 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
|
||||
|
||||
data = lodepng_chunk_data_const(chunk);
|
||||
|
||||
unknown = 0;
|
||||
|
||||
/*IDAT chunk, containing compressed image data*/
|
||||
if(lodepng_chunk_type_equals(chunk, "IDAT"))
|
||||
{
|
||||
@ -4716,6 +4812,26 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
|
||||
state->error = readChunk_pHYs(&state->info_png, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
else if(lodepng_chunk_type_equals(chunk, "gAMA"))
|
||||
{
|
||||
state->error = readChunk_gAMA(&state->info_png, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
else if(lodepng_chunk_type_equals(chunk, "cHRM"))
|
||||
{
|
||||
state->error = readChunk_cHRM(&state->info_png, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
else if(lodepng_chunk_type_equals(chunk, "sRGB"))
|
||||
{
|
||||
state->error = readChunk_sRGB(&state->info_png, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
else if(lodepng_chunk_type_equals(chunk, "iCCP"))
|
||||
{
|
||||
state->error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
else /*it's not an implemented chunk type, so ignore it: skip over the data*/
|
||||
{
|
||||
@ -5208,6 +5324,73 @@ static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info)
|
||||
return error;
|
||||
}
|
||||
|
||||
static unsigned addChunk_gAMA(ucvector* out, const LodePNGInfo* info)
|
||||
{
|
||||
unsigned error = 0;
|
||||
ucvector data;
|
||||
ucvector_init(&data);
|
||||
|
||||
lodepng_add32bitInt(&data, info->gama_gamma);
|
||||
|
||||
error = addChunk(out, "gAMA", data.data, data.size);
|
||||
ucvector_cleanup(&data);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static unsigned addChunk_cHRM(ucvector* out, const LodePNGInfo* info)
|
||||
{
|
||||
unsigned error = 0;
|
||||
ucvector data;
|
||||
ucvector_init(&data);
|
||||
|
||||
lodepng_add32bitInt(&data, info->chrm_white_x);
|
||||
lodepng_add32bitInt(&data, info->chrm_white_y);
|
||||
lodepng_add32bitInt(&data, info->chrm_red_x);
|
||||
lodepng_add32bitInt(&data, info->chrm_red_y);
|
||||
lodepng_add32bitInt(&data, info->chrm_green_x);
|
||||
lodepng_add32bitInt(&data, info->chrm_green_y);
|
||||
lodepng_add32bitInt(&data, info->chrm_blue_x);
|
||||
lodepng_add32bitInt(&data, info->chrm_blue_y);
|
||||
|
||||
error = addChunk(out, "cHRM", data.data, data.size);
|
||||
ucvector_cleanup(&data);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info)
|
||||
{
|
||||
unsigned char data = info->srgb_intent;
|
||||
return addChunk(out, "sRGB", &data, 1);
|
||||
}
|
||||
|
||||
static unsigned addChunk_iCCP(ucvector* out, const LodePNGInfo* info, LodePNGCompressSettings* zlibsettings)
|
||||
{
|
||||
unsigned error = 0;
|
||||
ucvector data, compressed;
|
||||
size_t i;
|
||||
|
||||
ucvector_init(&data);
|
||||
ucvector_init(&compressed);
|
||||
for(i = 0; info->iccp_name[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)info->iccp_name[i]);
|
||||
if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/
|
||||
ucvector_push_back(&data, 0); /*0 termination char*/
|
||||
ucvector_push_back(&data, 0); /*compression method: 0*/
|
||||
|
||||
error = zlib_compress(&compressed.data, &compressed.size,
|
||||
info->iccp_profile, info->iccp_profile_size, zlibsettings);
|
||||
if(!error)
|
||||
{
|
||||
for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]);
|
||||
error = addChunk(out, "iCCP", data.data, data.size);
|
||||
}
|
||||
|
||||
ucvector_cleanup(&compressed);
|
||||
ucvector_cleanup(&data);
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline,
|
||||
@ -5704,6 +5887,28 @@ static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t data
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned isGreyICCProfile(const unsigned char* profile, unsigned size)
|
||||
{
|
||||
/*
|
||||
It is a grey profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19
|
||||
are "RGB ". We do not perform any full parsing of the ICC profile here, other
|
||||
than check those 4 bytes to grayscale profile. Other than that, validity of
|
||||
the profile is not checked. This is needed only because the PNG specification
|
||||
requires using a non-grey color model if there is an ICC profile with "RGB "
|
||||
(sadly limiting compression opportunities if the input data is greyscale RGB
|
||||
data), and requires using a grey color model if it is "GRAY".
|
||||
*/
|
||||
if(size < 20) return 0;
|
||||
return profile[16] == 'G' && profile[17] == 'R' && profile[18] == 'A' && profile[19] == 'Y';
|
||||
}
|
||||
|
||||
static unsigned isRGBICCProfile(const unsigned char* profile, unsigned size)
|
||||
{
|
||||
/* See comment in isGreyICCProfile*/
|
||||
if(size < 20) return 0;
|
||||
return profile[16] == 'R' && profile[17] == 'G' && profile[18] == 'B' && profile[19] == ' ';
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
unsigned lodepng_encode(unsigned char** out, size_t* outsize,
|
||||
@ -5746,6 +5951,41 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
|
||||
{
|
||||
state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
|
||||
}
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
if(state->info_png.iccp_defined)
|
||||
{
|
||||
unsigned grey_icc = isGreyICCProfile(state->info_png.iccp_profile, state->info_png.iccp_profile_size);
|
||||
unsigned grey_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA;
|
||||
/* TODO: perhaps instead of giving errors or less optimal compression, we can automatically modify
|
||||
the ICC profile here to say "GRAY" or "RGB " to match the PNG color type, unless this will require
|
||||
non trivial changes to the rest of the ICC profile */
|
||||
if(!grey_icc && !isRGBICCProfile(state->info_png.iccp_profile, state->info_png.iccp_profile_size))
|
||||
{
|
||||
CERROR_RETURN_ERROR(state->error, 100); /* Disallowed profile color type for PNG */
|
||||
}
|
||||
if(!state->encoder.auto_convert && grey_icc != grey_png)
|
||||
{
|
||||
/* Non recoverable: encoder not allowed to convert color type, and requested color type not
|
||||
compatible with ICC color type */
|
||||
CERROR_RETURN_ERROR(state->error, 101);
|
||||
}
|
||||
if(grey_icc && !grey_png)
|
||||
{
|
||||
/* Non recoverable: trying to set greyscale ICC profile while colored pixels were given */
|
||||
CERROR_RETURN_ERROR(state->error, 102);
|
||||
/* NOTE: this relies on the fact that lodepng_auto_choose_color never returns palette for greyscale pixels */
|
||||
}
|
||||
if(!grey_icc && grey_png)
|
||||
{
|
||||
/* Recoverable but an unfortunate loss in compression density: We have greyscale pixels but
|
||||
are forced to store them in more expensive RGB format that will repeat each value 3 times
|
||||
because the PNG spec does not allow an RGB ICC profile with internal greyscale color data */
|
||||
if(info.color.colortype == LCT_GREY) info.color.colortype = LCT_RGB;
|
||||
if(info.color.colortype == LCT_GREY_ALPHA) info.color.colortype = LCT_RGBA;
|
||||
if(info.color.bitdepth < 8) info.color.bitdepth = 8;
|
||||
}
|
||||
}
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
if (!state->error)
|
||||
{
|
||||
if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
|
||||
@ -5783,6 +6023,11 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
|
||||
state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]);
|
||||
if(state->error) break;
|
||||
}
|
||||
/*color profile chunks must come before PLTE */
|
||||
if(info.iccp_defined) addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings);
|
||||
if(info.srgb_defined) addChunk_sRGB(&outv, &info);
|
||||
if(info.gama_defined) addChunk_gAMA(&outv, &info);
|
||||
if(info.chrm_defined) addChunk_cHRM(&outv, &info);
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
/*PLTE*/
|
||||
if(info.color.colortype == LCT_PALETTE)
|
||||
@ -6068,6 +6313,13 @@ const char* lodepng_error_text(unsigned code)
|
||||
case 93: return "zero width or height is invalid";
|
||||
case 94: return "header chunk must have a size of 13 bytes";
|
||||
case 95: return "integer overflow with combined idat chunk size";
|
||||
case 96: return "invalid gAMA chunk size";
|
||||
case 97: return "invalid cHRM chunk size";
|
||||
case 98: return "invalid sRGB chunk size";
|
||||
case 99: return "invalid sRGB rendering intent";
|
||||
case 100: return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY";
|
||||
case 101: return "PNG specification does not allow RGB ICC profile on grey color types and vice versa";
|
||||
case 102: return "not allowed to set greyscale ICC profile with colored pixels by PNG specification";
|
||||
}
|
||||
return "unknown error code";
|
||||
}
|
||||
|
124
external/lodepng/lodepng.h
vendored
124
external/lodepng/lodepng.h
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
LodePNG version 20180611
|
||||
LodePNG version 20180809
|
||||
|
||||
Copyright (c) 2005-2018 Lode Vandevenne
|
||||
|
||||
@ -255,7 +255,7 @@ const char* lodepng_error_text(unsigned code);
|
||||
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
|
||||
struct LodePNGDecompressSettings
|
||||
{
|
||||
/* Check LodePNGDecoderSettings for more ignorable errors */
|
||||
/* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
|
||||
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
|
||||
|
||||
/*use custom zlib decoder instead of built in one (default: null)*/
|
||||
@ -437,6 +437,10 @@ typedef struct LodePNGInfo
|
||||
text_strings, while text_keys are keywords that give a short description what
|
||||
the actual text represents, e.g. Title, Author, Description, or anything else.
|
||||
|
||||
All the string fields below including keys, names and language tags are null terminated.
|
||||
The PNG specification uses null characters for the keys, names and tags, and forbids null
|
||||
characters to appear in the main text which is why we can use null termination everywhere here.
|
||||
|
||||
A keyword is minimum 1 character and maximum 79 characters long. It's
|
||||
discouraged to use a single line length longer than 79 characters for texts.
|
||||
|
||||
@ -469,11 +473,86 @@ typedef struct LodePNGInfo
|
||||
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
|
||||
|
||||
/*
|
||||
unknown chunks
|
||||
There are 3 buffers, one for each position in the PNG where unknown chunks can appear
|
||||
each buffer contains all unknown chunks for that position consecutively
|
||||
The 3 buffers are the unknown chunks between certain critical chunks:
|
||||
0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
|
||||
Color profile related chunks: gAMA, cHRM, sRGB, iCPP
|
||||
|
||||
LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
|
||||
profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
|
||||
use these values with a color management library.
|
||||
|
||||
See the PNG, ICC and sRGB specifications for more information about the meaning of these values.
|
||||
*/
|
||||
|
||||
/* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */
|
||||
unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */
|
||||
unsigned gama_gamma; /* Gamma exponent times 100000 */
|
||||
|
||||
/* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */
|
||||
unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */
|
||||
unsigned chrm_white_x; /* White Point x times 100000 */
|
||||
unsigned chrm_white_y; /* White Point y times 100000 */
|
||||
unsigned chrm_red_x; /* Red x times 100000 */
|
||||
unsigned chrm_red_y; /* Red y times 100000 */
|
||||
unsigned chrm_green_x; /* Green x times 100000 */
|
||||
unsigned chrm_green_y; /* Green y times 100000 */
|
||||
unsigned chrm_blue_x; /* Blue x times 100000 */
|
||||
unsigned chrm_blue_y; /* Blue y times 100000 */
|
||||
|
||||
/*
|
||||
sRGB chunk: optional. May not appear at the same time as iCCP.
|
||||
If gAMA is also present gAMA must contain value 45455.
|
||||
If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000.
|
||||
*/
|
||||
unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */
|
||||
unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */
|
||||
|
||||
/*
|
||||
iCCP chunk: optional. May not appear at the same time as sRGB.
|
||||
|
||||
LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a
|
||||
separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color
|
||||
management and conversions.
|
||||
|
||||
For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC
|
||||
profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and
|
||||
enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile.
|
||||
|
||||
For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-grey
|
||||
PNG color types and a "GRAY" profile for grey PNG color types. If you disable auto_convert, you must ensure
|
||||
the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is
|
||||
enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder
|
||||
error if the pixel data has non-grey pixels for a GRAY profile, or a silent less-optimal compression of the pixel
|
||||
data if the pixels could be encoded as greyscale but the ICC profile is RGB.
|
||||
|
||||
To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so
|
||||
make sure you compute it carefully to avoid the above problems.
|
||||
*/
|
||||
unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */
|
||||
char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */
|
||||
/*
|
||||
The ICC profile in iccp_profile_size bytes.
|
||||
Don't allocate this buffer yourself. Use the init/cleanup functions
|
||||
correctly and use lodepng_set_icc and lodepng_clear_icc.
|
||||
*/
|
||||
unsigned char* iccp_profile;
|
||||
unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
|
||||
|
||||
/* End of color profile related chunks */
|
||||
|
||||
|
||||
/*
|
||||
unknown chunks: chunks not known by LodePNG, passed on byte for byte.
|
||||
|
||||
There are 3 buffers, one for each position in the PNG where unknown chunks can appear.
|
||||
Each buffer contains all unknown chunks for that position consecutively.
|
||||
The 3 positions are:
|
||||
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
|
||||
|
||||
For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag
|
||||
above in here, since the encoder will blindly follow this and could then encode an invalid PNG file
|
||||
(such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use
|
||||
this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST),
|
||||
or any non-standard PNG chunk.
|
||||
|
||||
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
|
||||
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
|
||||
*/
|
||||
@ -489,12 +568,16 @@ void lodepng_info_cleanup(LodePNGInfo* info);
|
||||
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
|
||||
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
|
||||
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
|
||||
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
|
||||
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
|
||||
|
||||
/*replaces if exists*/
|
||||
unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size);
|
||||
void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
/*
|
||||
@ -521,10 +604,14 @@ typedef struct LodePNGDecoderSettings
|
||||
{
|
||||
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
|
||||
|
||||
/* Check LodePNGDecompressSettings for more ignorable errors */
|
||||
/* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
|
||||
unsigned ignore_crc; /*ignore CRC checksums*/
|
||||
unsigned ignore_critical; /*ignore unknown critical chunks*/
|
||||
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
|
||||
/* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
|
||||
errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
|
||||
strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
|
||||
in string keys, etc... */
|
||||
|
||||
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
|
||||
|
||||
@ -558,8 +645,11 @@ typedef enum LodePNGFilterStrategy
|
||||
LFS_PREDEFINED
|
||||
} LodePNGFilterStrategy;
|
||||
|
||||
/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
|
||||
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
|
||||
/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...),
|
||||
which helps decide which color model to use for encoding.
|
||||
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.
|
||||
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
|
||||
fields in this header file.*/
|
||||
typedef struct LodePNGColorProfile
|
||||
{
|
||||
unsigned colored; /*not greyscale*/
|
||||
@ -575,7 +665,9 @@ typedef struct LodePNGColorProfile
|
||||
|
||||
void lodepng_color_profile_init(LodePNGColorProfile* profile);
|
||||
|
||||
/*Get a LodePNGColorProfile of the image.*/
|
||||
/*Get a LodePNGColorProfile of the image
|
||||
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
|
||||
fields in this header file.*/
|
||||
unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
@ -894,13 +986,15 @@ TODO:
|
||||
[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
|
||||
[.] check compatibility with various compilers - done but needs to be redone for every newer version
|
||||
[X] converting color to 16-bit per channel types
|
||||
[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
|
||||
[X] support color profile chunk types (but never let them touch RGB values by default)
|
||||
[ ] support all public PNG chunk types
|
||||
[ ] make sure encoder generates no chunks with size > (2^31)-1
|
||||
[ ] partial decoding (stream processing)
|
||||
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
|
||||
[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
|
||||
[ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
|
||||
[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ...
|
||||
[ ] errors with line numbers (and version)
|
||||
[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
|
||||
[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ...
|
||||
[ ] allow user to give data (void*) to custom allocator
|
||||
@ -1614,6 +1708,8 @@ yyyymmdd.
|
||||
Some changes aren't backwards compatible. Those are indicated with a (!)
|
||||
symbol.
|
||||
|
||||
*) 10 aug 2018: added support for gAMA, cHRM, sRGB and iCCP chunks. This change
|
||||
is backwards compatible unless you relied on unknown_chunks to use those.
|
||||
*) 11 jun 2018: less restrictive check for pixel size integer overflow
|
||||
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
|
||||
*) 17 sep 2017: fix memory leak for some encoder input error cases
|
||||
|
Loading…
Reference in New Issue
Block a user