diff options
Diffstat (limited to 'lodepng.cpp')
-rw-r--r-- | lodepng.cpp | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/lodepng.cpp b/lodepng.cpp index 70381fb..c62a22f 100644 --- a/lodepng.cpp +++ b/lodepng.cpp @@ -1,7 +1,7 @@ /* -LodePNG version 20161127 +LodePNG version 20180114 -Copyright (c) 2005-2016 Lode Vandevenne +Copyright (c) 2005-2018 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -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 = "20161127"; +const char* LODEPNG_VERSION_STRING = "20180114"; /* This source file is built up in the following large parts. The code sections @@ -1171,7 +1171,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); if(code_d > 29) { - if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + if(code_d == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ @@ -3463,6 +3463,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, size_t i; ColorTree tree; size_t numpixels = w * h; + unsigned error = 0; if(lodepng_color_mode_equal(mode_out, mode_in)) { @@ -3516,7 +3517,8 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); - CERROR_TRY_RETURN(rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a)); + error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + if (error) break; } } @@ -3525,7 +3527,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, color_tree_cleanup(&tree); } - return 0; /*no error*/ + return error; } #ifdef LODEPNG_COMPILE_ENCODER @@ -4563,12 +4565,20 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* data; /*the data in the chunk*/ /*error: size of the in buffer too small to contain next chunk*/ - if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); + if((size_t)((chunk - in) + 12) > insize || chunk < in) + { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 30); + } /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ chunkLength = lodepng_chunk_length(chunk); /*error: chunk length larger than the max PNG chunk size*/ - if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63); + if(chunkLength > 2147483647) + { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 63); + } if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { @@ -4655,7 +4665,10 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ - if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); + if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) + { + CERROR_BREAK(state->error, 69); + } unknown = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS @@ -4820,6 +4833,8 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) settings->remember_unknown_chunks = 0; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ settings->ignore_crc = 0; + settings->ignore_critical = 0; + settings->ignore_end = 0; lodepng_decompress_settings_init(&settings->zlibsettings); } @@ -5651,22 +5666,12 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, *outsize = 0; state->error = 0; - lodepng_info_init(&info); - lodepng_info_copy(&info, &state->info_png); - - if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) - && (info.color.palettesize == 0 || info.color.palettesize > 256)) - { - state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ - return state->error; - } - - if(state->encoder.auto_convert) + /*check input values validity*/ + if((state->info_png.color.colortype == LCT_PALETTE || state->encoder.force_palette) + && (state->info_png.color.palettesize == 0 || state->info_png.color.palettesize > 256)) { - state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); + CERROR_RETURN_ERROR(state->error, 68); /*invalid palette size, it is only allowed to be 1-256*/ } - if(state->error) return state->error; - if(state->encoder.zlibsettings.btype > 2) { CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ @@ -5675,28 +5680,38 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, { CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ } - - state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); + state->error = checkColorValidity(state->info_png.color.colortype, state->info_png.color.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ - if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) + /* color convert and compute scanline filter types */ + lodepng_info_init(&info); + lodepng_info_copy(&info, &state->info_png); + if(state->encoder.auto_convert) { - unsigned char* converted; - size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8; - - converted = (unsigned char*)lodepng_malloc(size); - if(!converted && size) state->error = 83; /*alloc fail*/ - if(!state->error) + state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); + } + if (!state->error) + { + if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) { - state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + unsigned char* converted; + size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8; + + converted = (unsigned char*)lodepng_malloc(size); + if(!converted && size) state->error = 83; /*alloc fail*/ + if(!state->error) + { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + lodepng_free(converted); } - if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); - lodepng_free(converted); + else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); } - else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + /* output all PNG chunks */ ucvector_init(&outv); while(!state->error) /*while only executed once, to break on error*/ { |