summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lodepng.cpp66
-rw-r--r--lodepng.h7
-rw-r--r--lodepng_benchmark.cpp8
-rw-r--r--lodepng_unittest.cpp66
4 files changed, 93 insertions, 54 deletions
diff --git a/lodepng.cpp b/lodepng.cpp
index 95bc92e..37b0562 100644
--- a/lodepng.cpp
+++ b/lodepng.cpp
@@ -1,7 +1,7 @@
/*
-LodePNG version 20161127
+LodePNG version 20170917
-Copyright (c) 2005-2016 Lode Vandevenne
+Copyright (c) 2005-2017 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 = "20170917";
/*
This source file is built up in the following large parts. The code sections
@@ -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
@@ -5651,22 +5653,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))
+ /*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 = 68; /*invalid palette size, it is only allowed to be 1-256*/
- return state->error;
+ CERROR_RETURN_ERROR(state->error, 68); /*invalid palette size, it is only allowed to be 1-256*/
}
-
- if(state->encoder.auto_convert)
- {
- state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
- }
- if(state->error) return state->error;
-
if(state->encoder.zlibsettings.btype > 2)
{
CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/
@@ -5675,28 +5667,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*/
{
diff --git a/lodepng.h b/lodepng.h
index 8c634d2..d633bfa 100644
--- a/lodepng.h
+++ b/lodepng.h
@@ -1,7 +1,7 @@
/*
-LodePNG version 20161127
+LodePNG version 20170917
-Copyright (c) 2005-2016 Lode Vandevenne
+Copyright (c) 2005-2017 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
@@ -1608,6 +1608,7 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
+*) 17 sep 2017: fix memory leak for some encoder input error cases
*) 27 nov 2016: grey+alpha auto color model detection bugfix
*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort).
*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within
@@ -1757,5 +1758,5 @@ Domain: gmail dot com.
Account: lode dot vandevenne.
-Copyright (c) 2005-2016 Lode Vandevenne
+Copyright (c) 2005-2017 Lode Vandevenne
*/
diff --git a/lodepng_benchmark.cpp b/lodepng_benchmark.cpp
index 791ced0..66de123 100644
--- a/lodepng_benchmark.cpp
+++ b/lodepng_benchmark.cpp
@@ -499,10 +499,10 @@ int main(int argc, char *argv[])
}
}
- std::cout << "Total decoding time: " << total_dec_time/NUM_DECODE << "s" << std::endl;
- std::cout << "Total encoding time: " << total_enc_time << "s" << std::endl;
- std::cout << "Total input size : " << total_in_size << std::endl;
- std::cout << "Total encoded size: " << total_enc_size << std::endl;
+ std::cout << "Total decoding time: " << total_dec_time/NUM_DECODE << "s (" << ((total_in_size/1024.0/1024.0)/(total_dec_time/NUM_DECODE)) << " MB/s)" << std::endl;
+ std::cout << "Total encoding time: " << total_enc_time << "s (" << ((total_in_size/1024.0/1024.0)/(total_enc_time)) << " MB/s)" << std::endl;
+ std::cout << "Total uncompressed size : " << total_in_size << std::endl;
+ std::cout << "Total encoded size: " << total_enc_size << " (" << (100.0 * total_enc_size / total_in_size) << "%)" << std::endl;
if(verbose) std::cout << "benchmark done" << std::endl;
}
diff --git a/lodepng_unittest.cpp b/lodepng_unittest.cpp
index 5297a35..5d11b2d 100644
--- a/lodepng_unittest.cpp
+++ b/lodepng_unittest.cpp
@@ -28,6 +28,8 @@ freely, subject to the following restrictions:
/*
Testing instructions:
+*) Ensure no tests commented out below
+
*) Compile with g++ with all warnings and run the unit test
g++ lodepng.cpp lodepng_util.cpp lodepng_unittest.cpp -Wall -Wextra -Wshadow -pedantic -ansi -O3 && ./a.out
@@ -760,7 +762,8 @@ void testColorConvert()
colorConvertTest("1011010110110101", LCT_GREY, 16, "10110101", LCT_GREY, 8);
//others
- colorConvertTest("11111111 11111111 11111111 00000000 00000000 00000000", LCT_RGB, 1, "10", LCT_GREY, 1);
+ colorConvertTest("11111111 11111111 11111111 00000000 00000000 00000000", LCT_RGB, 8, "10", LCT_GREY, 1);
+ colorConvertTest("11111111 11111111 11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000", LCT_RGB, 16, "10", LCT_GREY, 1);
}
//This tests color conversions from any color model to any color model, with any bit depth
@@ -1712,26 +1715,59 @@ void testPredefinedFilters() {
for(size_t i = 0; i < h; i++) ASSERT_EQUALS(3, outfilters[i]);
}
-void testWrongWindowSizeGivesError() {
+void testEncoderErrors() {
+ std::cout << "testEncoderErrors" << std::endl;
+
std::vector<unsigned char> png;
unsigned w = 32, h = 32;
Image image;
generateTestImage(image, w, h);
- unsigned error = 0;
+
+ lodepng::State def;
lodepng::State state;
+
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+
+ // test window sizes
state.encoder.zlibsettings.windowsize = 0;
- error = lodepng::encode(png, &image.data[0], w, h, state);
- ASSERT_EQUALS(60, error);
+ ASSERT_EQUALS(60, lodepng::encode(png, &image.data[0], w, h, state));
state.encoder.zlibsettings.windowsize = 65536;
- error = lodepng::encode(png, &image.data[0], w, h, state);
- ASSERT_EQUALS(60, error);
+ ASSERT_EQUALS(60, lodepng::encode(png, &image.data[0], w, h, state));
state.encoder.zlibsettings.windowsize = 1000; // not power of two
- error = lodepng::encode(png, &image.data[0], w, h, state);
- ASSERT_EQUALS(90, error);
+ ASSERT_EQUALS(90, lodepng::encode(png, &image.data[0], w, h, state));
state.encoder.zlibsettings.windowsize = 256;
- error = lodepng::encode(png, &image.data[0], w, h, state);
- ASSERT_EQUALS(0, error);
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+
+ state = def;
+ state.info_png.color.bitdepth = 3;
+ ASSERT_EQUALS(37, lodepng::encode(png, &image.data[0], w, h, state));
+
+ state = def;
+ state.info_png.color.colortype = (LodePNGColorType)5;
+ ASSERT_EQUALS(31, lodepng::encode(png, &image.data[0], w, h, state));
+
+ state = def;
+ state.info_png.color.colortype = LCT_PALETTE;
+ ASSERT_EQUALS(68, lodepng::encode(png, &image.data[0], w, h, state));
+
+ state = def;
+ state.info_png.interlace_method = 0;
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+ state.info_png.interlace_method = 1;
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+ state.info_png.interlace_method = 2;
+ ASSERT_EQUALS(71, lodepng::encode(png, &image.data[0], w, h, state));
+
+ state = def;
+ state.encoder.zlibsettings.btype = 0;
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+ state.encoder.zlibsettings.btype = 1;
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+ state.encoder.zlibsettings.btype = 2;
+ ASSERT_EQUALS(0, lodepng::encode(png, &image.data[0], w, h, state));
+ state.encoder.zlibsettings.btype = 3;
+ ASSERT_EQUALS(61, lodepng::encode(png, &image.data[0], w, h, state));
}
void addColor(std::vector<unsigned char>& colors, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
@@ -1996,26 +2032,26 @@ void testPaletteToPaletteDecode2() {
lodepng_palette_add(&state.info_raw, 3, 3, 3, 255);
unsigned char* image2 = 0;
unsigned error2 = lodepng_decode(&image2, &width, &height, &state, &png[0], png.size());
- ASSERT_EQUALS(82, error2);
lodepng_state_cleanup(&state);
+ ASSERT_EQUALS(82, error2);
free(image2);
}
void doMain()
{
//PNG
- testPNGCodec();
+ testPNGCodec(); // this one is slow for valgrind
testPngSuiteTiny();
testPaletteFilterTypesZero();
testComplexPNG();
testPredefinedFilters();
testFuzzing();
- testWrongWindowSizeGivesError();
+ testEncoderErrors();
testPaletteToPaletteDecode();
testPaletteToPaletteDecode2();
//Colors
- testFewColors();
+ testFewColors(); // this one is slow for valgrind
testColorKeyConvert();
testColorConvert();
testColorConvert2();