update lodepng to 20190824 version from mainstream.

git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1623 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
Ozkan Sezer 2019-08-28 00:10:02 +00:00
parent e4eae98ab4
commit 0e6c4f27cc
2 changed files with 111 additions and 140 deletions

View file

@ -1,5 +1,5 @@
/*
LodePNG version 20190814
LodePNG version 20190824
Copyright (c) 2005-2019 Lode Vandevenne
@ -44,7 +44,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 = "20190814";
const char* LODEPNG_VERSION_STRING = "20190824";
/*
This source file is built up in the following large parts. The code sections
@ -317,10 +317,12 @@ static char* alloc_string(const char* in) {
/* ////////////////////////////////////////////////////////////////////////// */
static
unsigned lodepng_read32bitInt(const unsigned char* buffer) {
return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) | ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]);
#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)
static unsigned lodepng_read32bitInt(const unsigned char* buffer) {
return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) |
((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]);
}
#endif /*defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)*/
#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
/*buffer must have at least 4 allocated bytes available*/
@ -332,13 +334,6 @@ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) {
}
#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/
#ifdef LODEPNG_COMPILE_ENCODER
static void lodepng_add32bitInt(ucvector* buffer, unsigned value) {
ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/
lodepng_set32bitInt(&buffer->data[buffer->size - 4], value);
}
#endif /*LODEPNG_COMPILE_ENCODER*/
/* ////////////////////////////////////////////////////////////////////////// */
/* / File IO / */
/* ////////////////////////////////////////////////////////////////////////// */
@ -1886,7 +1881,7 @@ static unsigned deflateDynamic(LodePNGBitWriter* writer, Hash* hash,
/*write the lenghts of the lit/len AND the dist alphabet*/
for(i = 0; i != bitlen_lld_e.size; ++i) {
writeBitsReversed(writer, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]),
HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i]));
HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i]));
/*extra bits of repeat codes*/
if(bitlen_lld_e.data[i] == 16) writeBits(writer, bitlen_lld_e.data[++i], 2);
else if(bitlen_lld_e.data[i] == 17) writeBits(writer, bitlen_lld_e.data[++i], 3);
@ -2116,40 +2111,38 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsi
unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
size_t insize, const LodePNGCompressSettings* settings) {
/*initially, *out must be NULL and outsize 0, if you just give some random *out
that's pointing to a non allocated buffer, this'll crash*/
ucvector outv;
size_t i;
unsigned error;
unsigned char* deflatedata = 0;
size_t deflatesize = 0;
/*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
unsigned FLEVEL = 0;
unsigned FDICT = 0;
unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
unsigned FCHECK = 31 - CMFFLG % 31;
CMFFLG += FCHECK;
/*ucvector-controlled version of the output buffer, for dynamic array*/
ucvector_init_buffer(&outv, *out, *outsize);
ucvector_push_back(&outv, (unsigned char)(CMFFLG >> 8));
ucvector_push_back(&outv, (unsigned char)(CMFFLG & 255));
error = deflate(&deflatedata, &deflatesize, in, insize, settings);
*out = NULL;
*outsize = 0;
if(!error) {
*outsize = deflatesize + 6;
*out = (unsigned char*)lodepng_malloc(*outsize);
if(!out) error = 83; /*alloc fail*/
}
if(!error) {
unsigned ADLER32 = adler32(in, (unsigned)insize);
for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]);
lodepng_free(deflatedata);
lodepng_add32bitInt(&outv, ADLER32);
/*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
unsigned FLEVEL = 0;
unsigned FDICT = 0;
unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
unsigned FCHECK = 31 - CMFFLG % 31;
CMFFLG += FCHECK;
(*out)[0] = (unsigned char)(CMFFLG >> 8);
(*out)[1] = (unsigned char)(CMFFLG & 255);
for(i = 0; i != deflatesize; ++i) (*out)[i + 2] = deflatedata[i];
lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32);
}
*out = outv.data;
*outsize = outv.size;
lodepng_free(deflatedata);
return error;
}
@ -2604,8 +2597,7 @@ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) {
|| lodepng_has_palette_alpha(info);
}
static
size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) {
static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) {
size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
size_t n = (size_t)w * (size_t)h;
return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u;
@ -2827,6 +2819,8 @@ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langt
/* same as set but does not delete */
static unsigned lodepng_assign_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) {
if(profile_size == 0) return 100; /*invalid ICC profile size*/
info->iccp_name = alloc_string(name);
info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size);
@ -4393,12 +4387,16 @@ static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSetting
&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) {
lodepng_memcpy(info->iccp_profile, decoded.data, decoded.size);
if(decoded.size) {
info->iccp_profile_size = decoded.size;
info->iccp_profile = (unsigned char*)lodepng_malloc(decoded.size);
if(info->iccp_profile) {
lodepng_memcpy(info->iccp_profile, decoded.data, decoded.size);
} else {
error = 83; /* alloc fail */
}
} else {
error = 83; /* alloc fail */
error = 100; /*invalid ICC profile size*/
}
}
ucvector_cleanup(&decoded);
@ -4466,8 +4464,8 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
const unsigned char* chunk;
size_t i;
ucvector idat; /*the data from idat chunks*/
ucvector scanlines;
size_t predict;
unsigned char* scanlines = 0;
size_t scanlines_size = 0, expected_size = 0;
size_t outsize = 0;
/*for unknown chunk order*/
@ -4610,28 +4608,35 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
if(!IEND) chunk = lodepng_chunk_next_const(chunk);
}
ucvector_init(&scanlines);
/*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation.
If the decompressed size does not match the prediction, the image must be corrupt.*/
if(state->info_png.interlace_method == 0) {
predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color);
expected_size = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color);
} else {
/*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/
/*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/
const LodePNGColorMode* color = &state->info_png.color;
predict = 0;
predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color);
if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color);
predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color);
if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color);
predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color);
if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color);
predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color);
expected_size = 0;
expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color);
if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color);
expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color);
if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color);
expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color);
if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color);
expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color);
}
if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/
if(!state->error) {
state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
/* This allocated data will be realloced by zlib_decompress, initially at
smaller size again. But the fact that it's already allocated at full size
here speeds the multiple reallocs up. TODO: make zlib_decompress support
receiving already allocated buffer with expected size instead. */
scanlines = (unsigned char*)lodepng_malloc(expected_size);
if(!scanlines) state->error = 83; /*alloc fail*/
scanlines_size = 0;
}
if(!state->error) {
state->error = zlib_decompress(&scanlines, &scanlines_size, idat.data,
idat.size, &state->decoder.zlibsettings);
if(!state->error && scanlines.size != predict) state->error = 91; /*decompressed size doesn't match prediction*/
if(!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/
}
ucvector_cleanup(&idat);
@ -4642,9 +4647,9 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
}
if(!state->error) {
for(i = 0; i < outsize; i++) (*out)[i] = 0;
state->error = postProcessScanlines(*out, scanlines.data, *w, *h, &state->info_png);
state->error = postProcessScanlines(*out, scanlines, *w, *h, &state->info_png);
}
ucvector_cleanup(&scanlines);
lodepng_free(scanlines);
}
unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
@ -4800,22 +4805,17 @@ static void writeSignature(ucvector* out) {
static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h,
LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) {
unsigned error = 0;
ucvector header;
ucvector_init(&header);
unsigned char data[13];
lodepng_add32bitInt(&header, w); /*width*/
lodepng_add32bitInt(&header, h); /*height*/
ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/
ucvector_push_back(&header, (unsigned char)colortype); /*color type*/
ucvector_push_back(&header, 0); /*compression method*/
ucvector_push_back(&header, 0); /*filter method*/
ucvector_push_back(&header, interlace_method); /*interlace method*/
lodepng_set32bitInt(data + 0, w); /*width*/
lodepng_set32bitInt(data + 4, h); /*height*/
data[8] = (unsigned char)bitdepth; /*bit depth*/
data[9] = (unsigned char)colortype; /*color type*/
data[10] = 0; /*compression method*/
data[11] = 0; /*filter method*/
data[12] = interlace_method; /*interlace method*/
error = addChunk(out, "IHDR", header.data, header.size);
ucvector_cleanup(&header);
return error;
return addChunk(out, "IHDR", data, sizeof(data));
}
static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) {
@ -4968,33 +4968,29 @@ static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* ke
}
static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) {
unsigned error = 0;
ucvector bKGD;
ucvector_init(&bKGD);
unsigned char data[6];
size_t size = 0;
if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) {
ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8));
ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255));
data[0] = (unsigned char)(info->background_r >> 8);
data[1] = (unsigned char)(info->background_r & 255);
size = 2;
} else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) {
ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8));
ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255));
ucvector_push_back(&bKGD, (unsigned char)(info->background_g >> 8));
ucvector_push_back(&bKGD, (unsigned char)(info->background_g & 255));
ucvector_push_back(&bKGD, (unsigned char)(info->background_b >> 8));
ucvector_push_back(&bKGD, (unsigned char)(info->background_b & 255));
data[0] = (unsigned char)(info->background_r >> 8);
data[1] = (unsigned char)(info->background_r & 255);
data[2] = (unsigned char)(info->background_g >> 8);
data[3] = (unsigned char)(info->background_g & 255);
data[4] = (unsigned char)(info->background_b >> 8);
data[5] = (unsigned char)(info->background_b & 255);
size = 6;
} else if(info->color.colortype == LCT_PALETTE) {
ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); /*palette index*/
data[0] =(unsigned char)(info->background_r & 255); /*palette index*/
size = 1;
}
error = addChunk(out, "bKGD", bKGD.data, bKGD.size);
ucvector_cleanup(&bKGD);
return error;
return addChunk(out, "bKGD", data, size);
}
static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) {
unsigned error = 0;
unsigned char* data = (unsigned char*)lodepng_malloc(7);
if(!data) return 83; /*alloc fail*/
unsigned char data[7];
data[0] = (unsigned char)(time->year >> 8);
data[1] = (unsigned char)(time->year & 255);
data[2] = (unsigned char)time->month;
@ -5002,57 +4998,33 @@ static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) {
data[4] = (unsigned char)time->hour;
data[5] = (unsigned char)time->minute;
data[6] = (unsigned char)time->second;
error = addChunk(out, "tIME", data, 7);
lodepng_free(data);
return error;
return addChunk(out, "tIME", data, sizeof(data));
}
static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) {
unsigned error = 0;
ucvector data;
ucvector_init(&data);
lodepng_add32bitInt(&data, info->phys_x);
lodepng_add32bitInt(&data, info->phys_y);
ucvector_push_back(&data, info->phys_unit);
error = addChunk(out, "pHYs", data.data, data.size);
ucvector_cleanup(&data);
return error;
unsigned char data[9];
lodepng_set32bitInt(data + 0, info->phys_x);
lodepng_set32bitInt(data + 4, info->phys_y); data[8] = info->phys_unit;
return addChunk(out, "pHYs", data, sizeof(data));
}
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;
unsigned char data[4];
lodepng_set32bitInt(data, info->gama_gamma);
return addChunk(out, "gAMA", data, sizeof(data));
}
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;
unsigned char data[32];
lodepng_set32bitInt(data + 0, info->chrm_white_x);
lodepng_set32bitInt(data + 4, info->chrm_white_y);
lodepng_set32bitInt(data + 8, info->chrm_red_x);
lodepng_set32bitInt(data + 12, info->chrm_red_y);
lodepng_set32bitInt(data + 16, info->chrm_green_x);
lodepng_set32bitInt(data + 20, info->chrm_green_y);
lodepng_set32bitInt(data + 24, info->chrm_blue_x);
lodepng_set32bitInt(data + 28, info->chrm_blue_y);
return addChunk(out, "cHRM", data, sizeof(data));
}
static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info) {

View file

@ -1,5 +1,5 @@
/*
LodePNG version 20190814
LodePNG version 20190824
Copyright (c) 2005-2019 Lode Vandevenne
@ -275,8 +275,7 @@ struct LodePNGDecompressSettings {
const unsigned char*, size_t,
const LodePNGDecompressSettings*);
/*use custom deflate decoder instead of built in one (default: null)
if custom_zlib is used, custom_deflate is ignored since only the built in
zlib function will call custom_deflate*/
if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/
unsigned (*custom_inflate)(unsigned char**, size_t*,
const unsigned char*, size_t,
const LodePNGDecompressSettings*);