From 2ccff76a584c8e1566779c8daddc757b9bf87a56 Mon Sep 17 00:00:00 2001 From: Lode Date: Mon, 18 Jan 2016 22:33:46 +0100 Subject: various fixes --- lodepng.cpp | 28 +++++++++++++++++++++------- lodepng.h | 6 +++--- pngdetail.cpp | 32 +++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/lodepng.cpp b/lodepng.cpp index 8b6076d..8665292 100644 --- a/lodepng.cpp +++ b/lodepng.cpp @@ -1,7 +1,7 @@ /* -LodePNG version 20151208 +LodePNG version 20160118 -Copyright (c) 2005-2015 Lode Vandevenne +Copyright (c) 2005-2016 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 @@ -42,7 +42,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 = "20151208"; +const char* LODEPNG_VERSION_STRING = "20160118"; /* This source file is built up in the following large parts. The code sections @@ -2684,12 +2684,18 @@ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { - return (w * h * lodepng_get_bpp(color) + 7) / 8; + /*will not overflow for any color type if roughly w * h < 268435455*/ + int bpp = lodepng_get_bpp(color); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { - return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8; + /*will not overflow for any color type if roughly w * h < 268435455*/ + int bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } @@ -2698,7 +2704,10 @@ size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colorty /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) { - return h * ((w * lodepng_get_bpp(color) + 7) / 8); + /*will not overflow for any color type if roughly w * h < 268435455*/ + int bpp = lodepng_get_bpp(color); + size_t line = ((w / 8) * bpp) + ((w & 7) * bpp + 7) / 8; + return h * line; } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -3855,7 +3864,11 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, { CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ } - if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') + if(lodepng_chunk_length(in + 8) != 13) + { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ } @@ -5923,6 +5936,7 @@ const char* lodepng_error_text(unsigned code) case 91: return "invalid decompressed idat size"; case 92: return "too many pixels, not supported"; case 93: return "zero width or height is invalid"; + case 94: return "header chunk must have a size of 13 bytes"; } return "unknown error code"; } diff --git a/lodepng.h b/lodepng.h index 8b8e2d4..2cda86f 100644 --- a/lodepng.h +++ b/lodepng.h @@ -1,7 +1,7 @@ /* -LodePNG version 20151208 +LodePNG version 20160118 -Copyright (c) 2005-2015 Lode Vandevenne +Copyright (c) 2005-2016 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 @@ -1709,5 +1709,5 @@ Domain: gmail dot com. Account: lode dot vandevenne. -Copyright (c) 2005-2015 Lode Vandevenne +Copyright (c) 2005-2016 Lode Vandevenne */ diff --git a/pngdetail.cpp b/pngdetail.cpp index d62b6dd..0f2b602 100644 --- a/pngdetail.cpp +++ b/pngdetail.cpp @@ -48,6 +48,7 @@ everything except huge output: #include "lodepng_util.h" #include #include +#include #include #include @@ -169,7 +170,8 @@ void displayChunkNames(const std::vector& buffer, const Options& { std::vector names; std::vector sizes; - lodepng::getChunkInfo(names, sizes, buffer); + unsigned error = lodepng::getChunkInfo(names, sizes, buffer); + if(error) std::cout << "Error while identifying chunks. Listing identified chunks anyway." << std::endl; if(options.show_chunks2) { @@ -197,6 +199,17 @@ void displayChunkNames(const std::vector& buffer, const Options& } std::cout << std::endl; } + + std::map typedict; + for(size_t i = 0; i < names.size(); i++) { + typedict[names[i]] = true; + } + + if(!error) { + if(!typedict["IHDR"]) std::cout << "Error: no IHDR chunk" << std::endl; + if(!typedict["IDAT"]) std::cout << "Error: no IDAT chunk" << std::endl; + if(!typedict["IEND"]) std::cout << "Error: no IEND chunk" << std::endl; + } } void RGBtoHSL(unsigned char r, unsigned char g, unsigned char b, unsigned char* h, unsigned char* s, unsigned char* l) { @@ -784,6 +797,23 @@ unsigned showFileInfo(const std::string& filename, const Options& options) state.info_raw.bitdepth = 16; error = lodepng::decode(image, w, h, state, buffer); + // In case of checksum errors, disable checksums + while (error == 57 || error == 58) { + if(error == 57) + { + std::cout << "Error: invalid CRC checksum" << std::endl; + state.decoder.ignore_crc = 1; + error = lodepng::decode(image, w, h, state, buffer); + } + + if(error == 58) + { + std::cout << "Error: invalid Adler32 checksum" << std::endl; + state.decoder.zlibsettings.ignore_adler32 = 1; + error = lodepng::decode(image, w, h, state, buffer); + } + } + if(error) { std::cout << "Decoder error " << error << ": " << lodepng_error_text(error) << std::endl; -- cgit v1.2.3