From bfc5990976418a201c390f4d79f7ae29fa2cc53d Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Sun, 6 Nov 2016 20:51:49 +0000 Subject: [PATCH 1/6] Add CMakeFiles --- CMakeLists.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8e8e8378 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +# Auth: Alberto Taiuti + +cmake_minimum_required(VERSION 2.8) + +project(lode-png) + +# Export commands for YCM +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(lodepng + ${CMAKE_CURRENT_SOURCE_DIR}/lodepng.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_benchmark.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_unittest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_util.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/pngdetail.cpp) + +set(LODEPNG_LIBRARY lodepng PARENT_SCOPE) From 52ad042590eed2070a09951f0e53ca150b19e0ae Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Sun, 6 Nov 2016 20:52:02 +0000 Subject: [PATCH 2/6] Rm examples dir --- examples/example_4bit_palette.cpp | 106 --------- examples/example_bmp2png.cpp | 134 ------------ examples/example_decode.c | 113 ---------- examples/example_decode.cpp | 95 -------- examples/example_encode.c | 116 ---------- examples/example_encode.cpp | 97 --------- examples/example_encode_type.cpp | 79 ------- examples/example_gzip.cpp | 93 -------- examples/example_opengl.cpp | 162 -------------- examples/example_optimize_png.cpp | 133 ------------ examples/example_png2bmp.cpp | 132 ----------- examples/example_png_info.cpp | 349 ------------------------------ examples/example_reencode.cpp | 76 ------- examples/example_sdl.c | 142 ------------ examples/example_sdl.cpp | 132 ----------- 15 files changed, 1959 deletions(-) delete mode 100644 examples/example_4bit_palette.cpp delete mode 100644 examples/example_bmp2png.cpp delete mode 100644 examples/example_decode.c delete mode 100644 examples/example_decode.cpp delete mode 100644 examples/example_encode.c delete mode 100644 examples/example_encode.cpp delete mode 100644 examples/example_encode_type.cpp delete mode 100644 examples/example_gzip.cpp delete mode 100644 examples/example_opengl.cpp delete mode 100644 examples/example_optimize_png.cpp delete mode 100644 examples/example_png2bmp.cpp delete mode 100644 examples/example_png_info.cpp delete mode 100644 examples/example_reencode.cpp delete mode 100644 examples/example_sdl.c delete mode 100644 examples/example_sdl.cpp diff --git a/examples/example_4bit_palette.cpp b/examples/example_4bit_palette.cpp deleted file mode 100644 index a5e610de..00000000 --- a/examples/example_4bit_palette.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -//g++ lodepng.cpp example_4bit_palette.cpp -ansi -pedantic -Wall -Wextra -O3 - - - -/* -LodePNG 4-bit palette example. -This example encodes a 511x511 PNG with a 4-bit palette. -Both image and palette contain sine waves, resulting in a sort of plasma. -The 511 (rather than power of two 512) size is of course chosen on purpose to -confirm that scanlines not filling up an entire byte size are working. - -NOTE: a PNG image with a translucent palette is perfectly valid. However there -exist some programs that cannot correctly read those, including, surprisingly, -Gimp 2.8 image editor (until you set mode to RGB). -*/ - -#include -#include - -#include "lodepng.h" - -int main(int argc, char *argv[]) -{ - //check if user gave a filename - if(argc < 2) - { - std::cout << "please provide a filename to save to" << std::endl; - return 0; - } - - //create encoder and set settings and info (optional) - lodepng::State state; - - //generate palette - for(int i = 0; i < 16; i++) - { - unsigned char r = 127 * (1 + std::sin(5 * i * 6.28318531 / 16)); - unsigned char g = 127 * (1 + std::sin(2 * i * 6.28318531 / 16)); - unsigned char b = 127 * (1 + std::sin(3 * i * 6.28318531 / 16)); - unsigned char a = 63 * (1 + std::sin(8 * i * 6.28318531 / 16)) + 128; /*alpha channel of the palette (tRNS chunk)*/ - - //palette must be added both to input and output color mode, because in this - //sample both the raw image and the expected PNG image use that palette. - lodepng_palette_add(&state.info_png.color, r, g, b, a); - lodepng_palette_add(&state.info_raw, r, g, b, a); - } - - //both the raw image and the encoded image must get colorType 3 (palette) - state.info_png.color.colortype = LCT_PALETTE; //if you comment this line, and create the above palette in info_raw instead, then you get the same image in a RGBA PNG. - state.info_png.color.bitdepth = 4; - state.info_raw.colortype = LCT_PALETTE; - state.info_raw.bitdepth = 4; - state.encoder.auto_convert = 0; //we specify ourselves exactly what output PNG color mode we want - - //generate some image - const unsigned w = 511; - const unsigned h = 511; - std::vector image; - image.resize((w * h * 4 + 7) / 8, 0); - for(unsigned y = 0; y < h; y++) - for(unsigned x = 0; x < w; x++) - { - size_t byte_index = (y * w + x) / 2; - bool byte_half = (y * w + x) % 2 == 1; - - int color = (int)(4 * ((1 + std::sin(2.0 * 6.28318531 * x / (double)w)) - + (1 + std::sin(2.0 * 6.28318531 * y / (double)h))) ); - - image[byte_index] |= (unsigned char)(color << (byte_half ? 0 : 4)); - } - - //encode and save - std::vector buffer; - unsigned error = lodepng::encode(buffer, image.empty() ? 0 : &image[0], w, h, state); - if(error) - { - std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; - return 0; - } - lodepng::save_file(buffer, argv[1]); -} diff --git a/examples/example_bmp2png.cpp b/examples/example_bmp2png.cpp deleted file mode 100644 index c6bdd24d..00000000 --- a/examples/example_bmp2png.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2010 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* -Load a BMP image and convert it to a PNG image. This example also shows how -to use other data with the same memory structure as BMP, such as the image -format native to win32, GDI (HBITMAP, BITMAPINFO, ...) often encountered if -you're programming for Windows in Visual Studio. - -This example only supports uncompressed 24-bit RGB or 32-bit RGBA bitmaps. -For other types of BMP's, use a full fledged BMP decoder, or convert the -bitmap to 24-bit or 32-bit format. - -NOTE: it overwrites the output file without warning if it exists! -*/ - -//g++ lodepng.cpp example_bmp2png.cpp -ansi -pedantic -Wall -Wextra -O3 - -#include "lodepng.h" - -#include - -//returns 0 if all went ok, non-0 if error -//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel -unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, const std::vector& bmp) -{ - static const unsigned MINHEADER = 54; //minimum BMP header size - - if(bmp.size() < MINHEADER) return -1; - if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM' - unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts - //read width and height from BMP header - w = bmp[18] + bmp[19] * 256; - h = bmp[22] + bmp[23] * 256; - //read number of channels from BMP header - if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported. - unsigned numChannels = bmp[28] / 8; - - //The amount of scanline bytes is width of image times channels, with extra bytes added if needed - //to make it a multiple of 4 bytes. - unsigned scanlineBytes = w * numChannels; - if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4; - - unsigned dataSize = scanlineBytes * h; - if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels - - image.resize(w * h * 4); - - /* - There are 3 differences between BMP and the raw image buffer for LodePNG: - -it's upside down - -it's in BGR instead of RGB format (or BRGA instead of RGBA) - -each scanline has padding bytes to make it a multiple of 4 if needed - The 2D for loop below does all these 3 conversions at once. - */ - for(unsigned y = 0; y < h; y++) - for(unsigned x = 0; x < w; x++) - { - //pixel start byte position in the BMP - unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; - //pixel start byte position in the new raw image - unsigned newpos = 4 * y * w + 4 * x; - if(numChannels == 3) - { - image[newpos + 0] = bmp[bmpos + 2]; //R - image[newpos + 1] = bmp[bmpos + 1]; //G - image[newpos + 2] = bmp[bmpos + 0]; //B - image[newpos + 3] = 255; //A - } - else - { - image[newpos + 0] = bmp[bmpos + 3]; //R - image[newpos + 1] = bmp[bmpos + 2]; //G - image[newpos + 2] = bmp[bmpos + 1]; //B - image[newpos + 3] = bmp[bmpos + 0]; //A - } - } - return 0; -} - -int main(int argc, char *argv[]) -{ - if(argc < 3) - { - std::cout << "Please provice input PNG and output BMP file names" << std::endl; - return 0; - } - - std::vector bmp; - lodepng::load_file(bmp, argv[1]); - std::vector image; - unsigned w, h; - unsigned error = decodeBMP(image, w, h, bmp); - - if(error) - { - std::cout << "BMP decoding error " << error << std::endl; - return 0; - } - - std::vector png; - error = lodepng::encode(png, image, w, h); - - if(error) - { - std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - lodepng::save_file(png, argv[2]); - -} diff --git a/examples/example_decode.c b/examples/example_decode.c deleted file mode 100644 index 8f6ce392..00000000 --- a/examples/example_decode.c +++ /dev/null @@ -1,113 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" - -#include -#include - -/* -3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways). -*/ - -/* -Example 1 -Decode from disk to raw pixels with a single function call -*/ -void decodeOneStep(const char* filename) -{ - unsigned error; - unsigned char* image; - unsigned width, height; - - error = lodepng_decode32_file(&image, &width, &height, filename); - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); - - /*use image here*/ - - free(image); -} - -/* -Example 2 -Load PNG file from disk to memory first, then decode to raw pixels in memory. -*/ -void decodeTwoSteps(const char* filename) -{ - unsigned error; - unsigned char* image; - unsigned width, height; - unsigned char* png = 0; - size_t pngsize; - - error = lodepng_load_file(&png, &pngsize, filename); - if(!error) error = lodepng_decode32(&image, &width, &height, png, pngsize); - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); - - free(png); - - /*use image here*/ - - free(image); -} - -/* -Example 3 -Load PNG file from disk using a State, normally needed for more advanced usage. -*/ -void decodeWithState(const char* filename) -{ - unsigned error; - unsigned char* image; - unsigned width, height; - unsigned char* png = 0; - size_t pngsize; - LodePNGState state; - - lodepng_state_init(&state); - /*optionally customize the state*/ - - error = lodepng_load_file(&png, &pngsize, filename); - if(!error) error = lodepng_decode(&image, &width, &height, &state, png, pngsize); - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); - - free(png); - - /*use image here*/ - /*state contains extra information about the PNG such as text chunks, ...*/ - - lodepng_state_cleanup(&state); - free(image); -} - -int main(int argc, char *argv[]) -{ - const char* filename = argc > 1 ? argv[1] : "test.png"; - - decodeOneStep(filename); - - return 0; -} - diff --git a/examples/example_decode.cpp b/examples/example_decode.cpp deleted file mode 100644 index 76cda6e2..00000000 --- a/examples/example_decode.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" -#include - -/* -3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways). -*/ - -//g++ lodepng.cpp example_decode.cpp -ansi -pedantic -Wall -Wextra -O3 - - -//Example 1 -//Decode from disk to raw pixels with a single function call -void decodeOneStep(const char* filename) -{ - std::vector image; //the raw pixels - unsigned width, height; - - //decode - unsigned error = lodepng::decode(image, width, height, filename); - - //if there's an error, display it - if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - - //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... -} - -//Example 2 -//Load PNG file from disk to memory first, then decode to raw pixels in memory. -void decodeTwoSteps(const char* filename) -{ - std::vector png; - std::vector image; //the raw pixels - unsigned width, height; - - //load and decode - unsigned error = lodepng::load_file(png, filename); - if(!error) error = lodepng::decode(image, width, height, png); - - //if there's an error, display it - if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - - //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... -} - -//Example 3 -//Load PNG file from disk using a State, normally needed for more advanced usage. -void decodeWithState(const char* filename) -{ - std::vector png; - std::vector image; //the raw pixels - unsigned width, height; - lodepng::State state; //optionally customize this one - - unsigned error = lodepng::load_file(png, filename); //load the image file with given filename - if(!error) error = lodepng::decode(image, width, height, state, png); - - //if there's an error, display it - if(error) std::cout << "decoder error " << error << ": "<< lodepng_error_text(error) << std::endl; - - //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... - //State state contains extra information about the PNG such as text chunks, ... -} - -int main(int argc, char *argv[]) -{ - const char* filename = argc > 1 ? argv[1] : "test.png"; - - decodeOneStep(filename); -} - diff --git a/examples/example_encode.c b/examples/example_encode.c deleted file mode 100644 index 0e0f8bf1..00000000 --- a/examples/example_encode.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" - -#include -#include - -/* -3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways). -NOTE: this samples overwrite the file or test.png without warning! -*/ - -/* -Example 1 -Encode from raw pixels to disk with a single function call -The image argument has width * height RGBA pixels or width * height * 4 bytes -*/ -void encodeOneStep(const char* filename, const unsigned char* image, unsigned width, unsigned height) -{ - /*Encode the image*/ - unsigned error = lodepng_encode32_file(filename, image, width, height); - - /*if there's an error, display it*/ - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); -} - -/* -Example 2 -Encode from raw pixels to an in-memory PNG file first, then write it to disk -The image argument has width * height RGBA pixels or width * height * 4 bytes -*/ -void encodeTwoSteps(const char* filename, const unsigned char* image, unsigned width, unsigned height) -{ - unsigned char* png; - size_t pngsize; - - unsigned error = lodepng_encode32(&png, &pngsize, image, width, height); - if(!error) lodepng_save_file(png, pngsize, filename); - - /*if there's an error, display it*/ - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); - - free(png); -} - -/* -Example 3 -Save a PNG file to disk using a State, normally needed for more advanced usage. -The image argument has width * height RGBA pixels or width * height * 4 bytes -*/ -void encodeWithState(const char* filename, const unsigned char* image, unsigned width, unsigned height) -{ - unsigned error; - unsigned char* png; - size_t pngsize; - LodePNGState state; - - lodepng_state_init(&state); - /*optionally customize the state*/ - - error = lodepng_encode(&png, &pngsize, image, width, height, &state); - if(!error) lodepng_save_file(png, pngsize, filename); - - /*if there's an error, display it*/ - if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); - - lodepng_state_cleanup(&state); - free(png); -} - -int main(int argc, char *argv[]) -{ - const char* filename = argc > 1 ? argv[1] : "test.png"; - - /*generate some image*/ - unsigned width = 512, height = 512; - unsigned char* image = malloc(width * height * 4); - unsigned x, y; - for(y = 0; y < height; y++) - for(x = 0; x < width; x++) - { - image[4 * width * y + 4 * x + 0] = 255 * !(x & y); - image[4 * width * y + 4 * x + 1] = x ^ y; - image[4 * width * y + 4 * x + 2] = x | y; - image[4 * width * y + 4 * x + 3] = 255; - } - - /*run an example*/ - encodeOneStep(filename, image, width, height); - - free(image); - return 0; -} diff --git a/examples/example_encode.cpp b/examples/example_encode.cpp deleted file mode 100644 index 31dd0b89..00000000 --- a/examples/example_encode.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" -#include - -/* -3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways). -NOTE: this samples overwrite the file or test.png without warning! -*/ - -//g++ lodepng.cpp example_encode.cpp -ansi -pedantic -Wall -Wextra -O3 - -//Example 1 -//Encode from raw pixels to disk with a single function call -//The image argument has width * height RGBA pixels or width * height * 4 bytes -void encodeOneStep(const char* filename, std::vector& image, unsigned width, unsigned height) -{ - //Encode the image - unsigned error = lodepng::encode(filename, image, width, height); - - //if there's an error, display it - if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; -} - -//Example 2 -//Encode from raw pixels to an in-memory PNG file first, then write it to disk -//The image argument has width * height RGBA pixels or width * height * 4 bytes -void encodeTwoSteps(const char* filename, std::vector& image, unsigned width, unsigned height) -{ - std::vector png; - - unsigned error = lodepng::encode(png, image, width, height); - if(!error) lodepng::save_file(png, filename); - - //if there's an error, display it - if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; -} - -//Example 3 -//Save a PNG file to disk using a State, normally needed for more advanced usage. -//The image argument has width * height RGBA pixels or width * height * 4 bytes -void encodeWithState(const char* filename, std::vector& image, unsigned width, unsigned height) -{ - std::vector png; - lodepng::State state; //optionally customize this one - - unsigned error = lodepng::encode(png, image, width, height, state); - if(!error) lodepng::save_file(png, filename); - - //if there's an error, display it - if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; -} - -//saves image to filename given as argument. Warning, this overwrites the file without warning! -int main(int argc, char *argv[]) -{ - //NOTE: this sample will overwrite the file or test.png without warning! - const char* filename = argc > 1 ? argv[1] : "test.png"; - - //generate some image - unsigned width = 512, height = 512; - std::vector image; - image.resize(width * height * 4); - for(unsigned y = 0; y < height; y++) - for(unsigned x = 0; x < width; x++) - { - image[4 * width * y + 4 * x + 0] = 255 * !(x & y); - image[4 * width * y + 4 * x + 1] = x ^ y; - image[4 * width * y + 4 * x + 2] = x | y; - image[4 * width * y + 4 * x + 3] = 255; - } - - encodeOneStep(filename, image, width, height); -} diff --git a/examples/example_encode_type.cpp b/examples/example_encode_type.cpp deleted file mode 100644 index d1de926b..00000000 --- a/examples/example_encode_type.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2015 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -//g++ -I ./ lodepng.cpp examples/example_encode_type.cpp -ansi -pedantic -Wall -Wextra -O3 - - - -/* -This example shows how to enforce a certain color type of the PNG image when -encoding a PNG (because by default, LodePNG automatically chooses an optimal -color type, no matter what your raw data's colro type is) -*/ - -#include -#include - -#include "lodepng.h" - -int main(int argc, char *argv[]) -{ - //check if user gave a filename - if(argc < 2) - { - std::cout << "please provide a filename to save to" << std::endl; - return 0; - } - - //generate some image - const unsigned w = 256; - const unsigned h = 256; - std::vector image(w * h * 4); - for(unsigned y = 0; y < h; y++) - for(unsigned x = 0; x < w; x++) - { - int index = y * w * 4 + x * 4; - image[index + 0] = 0; - image[index + 1] = 0; - image[index + 2] = 0; - image[index + 3] = 255; - } - - // we're going to encode with a state rather than a convenient function, because enforcing a color type requires setting options - lodepng::State state; - // input color type - state.info_raw.colortype = LCT_RGBA; - state.info_raw.bitdepth = 8; - // output color type - state.info_png.color.colortype = LCT_RGBA; - state.info_png.color.bitdepth = 8; - state.encoder.auto_convert = 0; // without this, it would ignore the output color type specified above and choose an optimal one instead - - //encode and save - std::vector buffer; - unsigned error = lodepng::encode(buffer, &image[0], w, h, state); - if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; - else lodepng::save_file(buffer, argv[1]); -} diff --git a/examples/example_gzip.cpp b/examples/example_gzip.cpp deleted file mode 100644 index b2ddf17b..00000000 --- a/examples/example_gzip.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" -#include -#include - -/* -Encodes given file as a gzip file. - -See also the gzip specification, RFC 1952: http://www.gzip.org/zlib/rfc-gzip.html -*/ - -//g++ lodepng.cpp example_gzip.cpp -ansi -pedantic -Wall -Wextra -O3 - -//saves image to filename given as argument. Warning, this overwrites the file without warning! -int main(int argc, char *argv[]) -{ - if(argc < 2) - { - std::cout << "Please provide input filename (output is input with .gz)" << std::endl; - return 0; - } - - //NOTE: this sample will overwrite the output file without warning! - std::string infilename = argv[1]; - std::string outfilename = infilename + ".gz"; - - std::vector in; - lodepng::load_file(in, infilename); - - size_t outsize = 10; - unsigned char* out = (unsigned char*)malloc(outsize); - out[0] = 31; //ID1 - out[1] = 139; //ID2 - out[2] = 8; //CM - out[3] = 0; //FLG - //MTIME - out[4] = 0; - out[5] = 0; - out[6] = 0; - out[7] = 0; - - out[8] = 2; //2 = slow, 4 = fast compression - out[9] = 255; //OS unknown - - lodepng_deflate(&out, &outsize, &in[0], in.size(), &lodepng_default_compress_settings); - - unsigned crc = lodepng_crc32(&in[0], in.size()); - - size_t footer = outsize; - - outsize += 8; - out = (unsigned char*)realloc(out, outsize); - - //CRC - out[footer + 0] = crc % 256; - out[footer + 1] = (crc >> 8) % 256; - out[footer + 2] = (crc >> 16) % 256; - out[footer + 3] = (crc >> 24) % 256; - - //ISIZE - out[footer + 4] = in.size() % 256; - out[footer + 5] = (in.size() >> 8) % 256; - out[footer + 6] = (in.size() >> 16) % 256; - out[footer + 7] = (in.size() >> 24) % 256; - - lodepng_save_file(out, outsize, outfilename.c_str()); - - free(out); -} diff --git a/examples/example_opengl.cpp b/examples/example_opengl.cpp deleted file mode 100644 index 18798649..00000000 --- a/examples/example_opengl.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -//Compile command for Linux: -//g++ lodepng.cpp example_opengl.cpp -lSDL -lGL -O3 - -/* -LodePNG OpenGL example. Decodes a PNG and shows it in OpenGL. PNG filename -should be given as a command line parameter. - -It's written for the most basic old OpenGL version, and a correction for non -power of two textures had to be added. - -Only very few lines on the sample are about loading the PNG. Most of the -sample lines show a way to render a texture in 2D in OpenGL. - -No fancy 3D graphics are shown, it only shows the image statically. The sample -shows LodePNG can be used to load PNG images as textures in OpenGL. -*/ - -#include "lodepng.h" - -#include -#include -#include - -int main(int argc, char *argv[]) -{ - if(argc < 2) - { - std::cout << "Please provide a filename." << std::endl; - return 1; - } - const char* filename = argv[1]; - - // Load file and decode image. - std::vector image; - unsigned width, height; - unsigned error = lodepng::decode(image, width, height, filename); - - // If there's an error, display it. - if(error != 0) - { - std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; - return 1; - } - - // Here the PNG is loaded in "image". All the rest of the code is SDL and OpenGL stuff. - - int screenw = width; - if(screenw > 1024) screenw = 1024; - int screenh = height; - if(screenh > 768) screenw = 768; - - if(SDL_Init(SDL_INIT_VIDEO) < 0) - { - std::cout << "Error: Unable to init SDL: " << SDL_GetError() << std::endl; - return 1; - } - - SDL_Surface* scr = SDL_SetVideoMode(screenw, screenh, 32, SDL_OPENGL); - - if(scr == 0) - { - std::cout << "Error: Unable to set video. SDL error message: " << SDL_GetError() << std::endl; - return 1; - } - - // The official code for "Setting Your Raster Position to a Pixel Location" (i.e. set up a camera for 2D screen) - glViewport(0, 0, screenw, screenh); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, screenw, screenh, 0, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // Make some OpenGL properties better for 2D and enable alpha channel. - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - - if(glGetError() != GL_NO_ERROR) - { - std::cout << "Error initing GL" << std::endl; - return 1; - } - - // Texture size must be power of two for the primitive OpenGL version this is written for. Find next power of two. - size_t u2 = 1; while(u2 < width) u2 *= 2; - size_t v2 = 1; while(v2 < height) v2 *= 2; - // Ratio for power of two version compared to actual version, to render the non power of two image with proper size. - double u3 = (double)width / u2; - double v3 = (double)height / v2; - - // Make power of two version of the image. - std::vector image2(u2 * v2 * 4); - for(size_t y = 0; y < height; y++) - for(size_t x = 0; x < width; x++) - for(size_t c = 0; c < 4; c++) - { - image2[4 * u2 * y + 4 * x + c] = image[4 * width * y + 4 * x + c]; - } - - // Enable the texture for OpenGL. - glEnable(GL_TEXTURE_2D); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_NEAREST = no smoothing - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, 4, u2, v2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &image2[0]); - - bool done = false; - SDL_Event event = {0}; - glColor4ub(255, 255, 255, 255); - - while(!done) - { - // Quit the loop when receiving quit event. - while(SDL_PollEvent(&event)) - { - if(event.type == SDL_QUIT) done = 1; - } - - // Draw the texture on a quad, using u3 and v3 to correct non power of two texture size. - glBegin(GL_QUADS); - glTexCoord2d( 0, 0); glVertex2f( 0, 0); - glTexCoord2d(u3, 0); glVertex2f(width, 0); - glTexCoord2d(u3, v3); glVertex2f(width, height); - glTexCoord2d( 0, v3); glVertex2f( 0, height); - glEnd(); - - // Redraw and clear screen. - SDL_GL_SwapBuffers(); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //Limit frames per second, to not heat up the CPU and GPU too much. - SDL_Delay(16); - } -} diff --git a/examples/example_optimize_png.cpp b/examples/example_optimize_png.cpp deleted file mode 100644 index d64c7f22..00000000 --- a/examples/example_optimize_png.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* -This example saves the PNG with the best compression LodePNG can do, and with -unnecessary chunks removed. It tries out several combinations of settings and -keeps the smallest one. - -NOTE: This is not as good as a true PNG optimizer like optipng or pngcrush. -*/ - -//g++ lodepng.cpp example_optimize_png.cpp -ansi -pedantic -Wall -Wextra -O3 - -#include "lodepng.h" - -#include - -int main(int argc, char *argv[]) -{ - std::vector image; - unsigned w, h; - std::vector buffer; - unsigned error; - - //check if user gave a filename - if(argc < 3) - { - std::cout << "please provide in and out filename" << std::endl; - return 0; - } - - lodepng::load_file(buffer, argv[1]); - error = lodepng::decode(image, w, h, buffer); - - if(error) - { - std::cout << "decoding error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - size_t origsize = buffer.size(); - std::cout << "Original size: " << origsize << " (" << (origsize / 1024) << "K)" << std::endl; - buffer.clear(); - - //Now encode as hard as possible with several filter types and window sizes - - lodepng::State state; - state.encoder.filter_palette_zero = 0; //We try several filter types, including zero, allow trying them all on palette images too. - state.encoder.add_id = false; //Don't add LodePNG version chunk to save more bytes - state.encoder.text_compression = 1; //Not needed because we don't add text chunks, but this demonstrates another optimization setting - state.encoder.zlibsettings.nicematch = 258; //Set this to the max possible, otherwise it can hurt compression - state.encoder.zlibsettings.lazymatching = 1; //Definitely use lazy matching for better compression - state.encoder.zlibsettings.windowsize = 32768; //Use maximum possible window size for best compression - - size_t bestsize = 0; - bool inited = false; - - int beststrategy = 0; - LodePNGFilterStrategy strategies[4] = { LFS_ZERO, LFS_MINSUM, LFS_ENTROPY, LFS_BRUTE_FORCE }; - std::string strategynames[4] = { "LFS_ZERO", "LFS_MINSUM", "LFS_ENTROPY", "LFS_BRUTE_FORCE" }; - - // min match 3 allows all deflate lengths. min match 6 is similar to "Z_FILTERED" of zlib. - int minmatches[2] = { 3, 6 }; - int bestminmatch = 0; - - int autoconverts[2] = { 0, 1 }; - std::string autoconvertnames[2] = { "0", "1" }; - int bestautoconvert = 0; - - int bestblocktype = 0; - - // Try out all combinations of everything - for(int i = 0; i < 4; i++) //filter strategy - for(int j = 0; j < 2; j++) //min match - for(int k = 0; k < 2; k++) //block type (for small images only) - for(int l = 0; l < 2; l++) //color convert strategy - { - if(bestsize > 3000 && (k > 0 || l > 0)) continue; /* these only make sense on small images */ - std::vector temp; - state.encoder.filter_strategy = strategies[i]; - state.encoder.zlibsettings.minmatch = minmatches[j]; - state.encoder.zlibsettings.btype = k == 0 ? 2 : 1; - state.encoder.auto_convert = autoconverts[l]; - error = lodepng::encode(temp, image, w, h, state); - - if(error) - { - std::cout << "encoding error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - if(!inited || temp.size() < bestsize) - { - bestsize = temp.size(); - beststrategy = i; - bestminmatch = state.encoder.zlibsettings.minmatch; - bestautoconvert = l; - bestblocktype = state.encoder.zlibsettings.btype; - temp.swap(buffer); - inited = true; - } - } - - std::cout << "Chosen filter strategy: " << strategynames[beststrategy] << std::endl; - std::cout << "Chosen min match: " << bestminmatch << std::endl; - std::cout << "Chosen block type: " << bestblocktype << std::endl; - std::cout << "Chosen auto convert: " << autoconvertnames[bestautoconvert] << std::endl; - - lodepng::save_file(buffer, argv[2]); - std::cout << "New size: " << buffer.size() << " (" << (buffer.size() / 1024) << "K)" << std::endl; -} diff --git a/examples/example_png2bmp.cpp b/examples/example_png2bmp.cpp deleted file mode 100644 index 3fd8328b..00000000 --- a/examples/example_png2bmp.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -#include "lodepng.h" -#include - -/* -This example converts a PNG file to a BMP file. -NOTE: it overwrites the output file without warning if it exists! -Give the PNG and the BMP file names as command line arguments. -*/ - -/* -g++ lodepng.cpp example_png2bmp.cpp -Wall -Wextra -pedantic -ansi -lSDL -O3 -*/ - - - -//Input image must be RGB buffer (3 bytes per pixel), but you can easily make it -//support RGBA input and output by changing the inputChannels and/or outputChannels -//in the function to 4. -void encodeBMP(std::vector& bmp, const unsigned char* image, int w, int h) -{ - //3 bytes per pixel used for both input and output. - int inputChannels = 3; - int outputChannels = 3; - - //bytes 0-13 - bmp.push_back('B'); bmp.push_back('M'); //0: bfType - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //2: bfSize; size not yet known for now, filled in later. - bmp.push_back(0); bmp.push_back(0); //6: bfReserved1 - bmp.push_back(0); bmp.push_back(0); //8: bfReserved2 - bmp.push_back(54 % 256); bmp.push_back(54 / 256); bmp.push_back(0); bmp.push_back(0); //10: bfOffBits (54 header bytes) - - //bytes 14-53 - bmp.push_back(40); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //14: biSize - bmp.push_back(w % 256); bmp.push_back(w / 256); bmp.push_back(0); bmp.push_back(0); //18: biWidth - bmp.push_back(h % 256); bmp.push_back(h / 256); bmp.push_back(0); bmp.push_back(0); //22: biHeight - bmp.push_back(1); bmp.push_back(0); //26: biPlanes - bmp.push_back(outputChannels * 8); bmp.push_back(0); //28: biBitCount - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //30: biCompression - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //34: biSizeImage - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //38: biXPelsPerMeter - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //42: biYPelsPerMeter - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //46: biClrUsed - bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //50: biClrImportant - - /* - Convert the input RGBRGBRGB pixel buffer to the BMP pixel buffer format. There are 3 differences with the input buffer: - -BMP stores the rows inversed, from bottom to top - -BMP stores the color channels in BGR instead of RGB order - -BMP requires each row to have a multiple of 4 bytes, so sometimes padding bytes are added between rows - */ - - int imagerowbytes = outputChannels * w; - imagerowbytes = imagerowbytes % 4 == 0 ? imagerowbytes : imagerowbytes + (4 - imagerowbytes % 4); //must be multiple of 4 - - for(int y = h - 1; y >= 0; y--) //the rows are stored inversed in bmp - { - int c = 0; - for(int x = 0; x < imagerowbytes; x++) - { - if(x < w * outputChannels) - { - int inc = c; - //Convert RGB(A) into BGR(A) - if(c == 0) inc = 2; - else if(c == 2) inc = 0; - bmp.push_back(image[inputChannels * (w * y + x / outputChannels) + inc]); - } - else bmp.push_back(0); - c++; - if(c >= outputChannels) c = 0; - } - } - - // Fill in the size - bmp[2] = bmp.size() % 256; - bmp[3] = (bmp.size() / 256) % 256; - bmp[4] = (bmp.size() / 65536) % 256; - bmp[5] = bmp.size() / 16777216; -} - -int main(int argc, char *argv[]) -{ - if(argc < 3) - { - std::cout << "Please provice input PNG and output BMP file names" << std::endl; - return 0; - } - const char* infile = argv[1]; - const char* outfile = argv[2]; - - - std::vector image; //the raw pixels - unsigned width, height; - - unsigned error = lodepng::decode(image, width, height, infile, LCT_RGB, 8); - - if(error) - { - std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - std::vector bmp; - encodeBMP(bmp, &image[0], width, height); - - lodepng::save_file(bmp, outfile); -} diff --git a/examples/example_png_info.cpp b/examples/example_png_info.cpp deleted file mode 100644 index cd2eca60..00000000 --- a/examples/example_png_info.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -//g++ lodepng.cpp example_png_info.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3 - -/* -This sample shows a lot of information in the console about a PNG file, -including color type, text chunks, the names of all chunks in the image, -etc... -*/ - - -#include "lodepng.h" -#include - -/* -Display general info about the PNG. -*/ -void displayPNGInfo(const LodePNGInfo& info) -{ - const LodePNGColorMode& color = info.color; - - std::cout << "Compression method: " << info.compression_method << std::endl; - std::cout << "Filter method: " << info.filter_method << std::endl; - std::cout << "Interlace method: " << info.interlace_method << std::endl; - std::cout << "Color type: " << color.colortype << std::endl; - std::cout << "Bit depth: " << color.bitdepth << std::endl; - std::cout << "Bits per pixel: " << lodepng_get_bpp(&color) << std::endl; - std::cout << "Channels per pixel: " << lodepng_get_channels(&color) << std::endl; - std::cout << "Is greyscale type: " << lodepng_is_greyscale_type(&color) << std::endl; - std::cout << "Can have alpha: " << lodepng_can_have_alpha(&color) << std::endl; - std::cout << "Palette size: " << color.palettesize << std::endl; - std::cout << "Has color key: " << color.key_defined << std::endl; - if(color.key_defined) - { - std::cout << "Color key r: " << color.key_r << std::endl; - std::cout << "Color key g: " << color.key_g << std::endl; - std::cout << "Color key b: " << color.key_b << std::endl; - } - std::cout << "Texts: " << info.text_num << std::endl; - for(size_t i = 0; i < info.text_num; i++) - { - std::cout << "Text: " << info.text_keys[i] << ": " << info.text_strings[i] << std::endl << std::endl; - } - std::cout << "International texts: " << info.itext_num << std::endl; - for(size_t i = 0; i < info.itext_num; i++) - { - std::cout << "Text: " - << info.itext_keys[i] << ", " - << info.itext_langtags[i] << ", " - << info.itext_transkeys[i] << ": " - << info.itext_strings[i] << std::endl << std::endl; - } - std::cout << "Time defined: " << info.time_defined << std::endl; - if(info.time_defined) - { - const LodePNGTime& time = info.time; - std::cout << "year: " << time.year << std::endl; - std::cout << "month: " << time.month << std::endl; - std::cout << "day: " << time.day << std::endl; - std::cout << "hour: " << time.hour << std::endl; - std::cout << "minute: " << time.minute << std::endl; - std::cout << "second: " << time.second << std::endl; - } - std::cout << "Physics defined: " << info.phys_defined << std::endl; - if(info.phys_defined) - { - std::cout << "physics X: " << info.phys_x << std::endl; - std::cout << "physics Y: " << info.phys_y << std::endl; - std::cout << "physics unit: " << info.phys_unit << std::endl; - } -} - - -/* -Display the names and sizes of all chunks in the PNG file. -*/ -void displayChunkNames(const std::vector& buffer) -{ - // Listing chunks is based on the original file, not the decoded png info. - const unsigned char *chunk, *begin, *end, *next; - end = &buffer.back() + 1; - begin = chunk = &buffer.front() + 8; - - std::cout << std::endl << "Chunks:" << std::endl; - std::cout << " type: length(s)"; - std::string last_type; - while(chunk + 8 < end && chunk >= begin) - { - char type[5]; - lodepng_chunk_type(type, chunk); - if(std::string(type).size() != 4) - { - std::cout << "this is probably not a PNG" << std::endl; - return; - } - - if(last_type != type) - { - std::cout << std::endl; - std::cout << " " << type << ": "; - } - last_type = type; - - std::cout << lodepng_chunk_length(chunk) << ", "; - - next = lodepng_chunk_next_const(chunk); - if (next <= chunk) break; // integer overflow - chunk = next; - } - std::cout << std::endl; -} - - -/* -Show ASCII art preview of the image -*/ -void displayAsciiArt(const std::vector& image, unsigned w, unsigned h) -{ - if(w > 0 && h > 0) - { - std::cout << std::endl << "ASCII Art Preview: " << std::endl; - unsigned w2 = 48; - if(w < w2) w2 = w; - unsigned h2 = h * w2 / w; - h2 = (h2 * 2) / 3; //compensate for non-square characters in terminal - if(h2 > (w2 * 2)) h2 = w2 * 2; //avoid too large output - - std::cout << '+'; - for(unsigned x = 0; x < w2; x++) std::cout << '-'; - std::cout << '+' << std::endl; - for(unsigned y = 0; y < h2; y++) - { - std::cout << "|"; - for(unsigned x = 0; x < w2; x++) - { - unsigned x2 = x * w / w2; - unsigned y2 = y * h / h2; - int r = image[y2 * w * 4 + x2 * 4 + 0]; - int g = image[y2 * w * 4 + x2 * 4 + 1]; - int b = image[y2 * w * 4 + x2 * 4 + 2]; - int a = image[y2 * w * 4 + x2 * 4 + 3]; - int lightness = ((r + g + b) / 3) * a / 255; - int min = (r < g && r < b) ? r : (g < b ? g : b); - int max = (r > g && r > b) ? r : (g > b ? g : b); - int saturation = max - min; - int letter = 'i'; //i for grey, or r,y,g,c,b,m for colors - if(saturation > 32) - { - int h = lightness >= (min + max) / 2; - if(h) letter = (min == r ? 'c' : (min == g ? 'm' : 'y')); - else letter = (max == r ? 'r' : (max == g ? 'g' : 'b')); - } - int symbol = ' '; - if(lightness > 224) symbol = '@'; - else if(lightness > 128) symbol = letter - 32; - else if(lightness > 32) symbol = letter; - else if(lightness > 16) symbol = '.'; - std::cout << (char)symbol; - } - std::cout << "|"; - std::cout << std::endl; - } - std::cout << '+'; - for(unsigned x = 0; x < w2; x++) std::cout << '-'; - std::cout << '+' << std::endl; - } -} - - -/* -Show the filtertypes of each scanline in this PNG image. -*/ -void displayFilterTypes(const std::vector& buffer, bool ignore_checksums) -{ - //Get color type and interlace type - lodepng::State state; - if(ignore_checksums) - { - state.decoder.ignore_crc = 1; - state.decoder.zlibsettings.ignore_adler32 = 1; - } - unsigned w, h; - unsigned error; - error = lodepng_inspect(&w, &h, &state, &buffer[0], buffer.size()); - - if(error) - { - std::cout << "inspect error " << error << ": " << lodepng_error_text(error) << std::endl; - return; - } - - if(state.info_png.interlace_method == 1) - { - std::cout << "showing filtertypes for interlaced PNG not supported by this example" << std::endl; - return; - } - - //Read literal data from all IDAT chunks - const unsigned char *chunk, *begin, *end, *next; - end = &buffer.back() + 1; - begin = chunk = &buffer.front() + 8; - - std::vector zdata; - - while(chunk + 8 < end && chunk >= begin) - { - char type[5]; - lodepng_chunk_type(type, chunk); - if(std::string(type).size() != 4) - { - std::cout << "this is probably not a PNG" << std::endl; - return; - } - - if(std::string(type) == "IDAT") - { - const unsigned char* cdata = lodepng_chunk_data_const(chunk); - unsigned clength = lodepng_chunk_length(chunk); - if(chunk + clength + 12 > end || clength > buffer.size() || chunk + clength + 12 < begin) { - std::cout << "invalid chunk length" << std::endl; - return; - } - - for(unsigned i = 0; i < clength; i++) - { - zdata.push_back(cdata[i]); - } - } - - next = lodepng_chunk_next_const(chunk); - if (next <= chunk) break; // integer overflow - chunk = next; - } - - //Decompress all IDAT data - std::vector data; - error = lodepng::decompress(data, &zdata[0], zdata.size()); - - if(error) - { - std::cout << "decompress error " << error << ": " << lodepng_error_text(error) << std::endl; - return; - } - - //A line is 1 filter byte + all pixels - size_t linebytes = 1 + lodepng_get_raw_size(w, 1, &state.info_png.color); - - if(linebytes == 0) - { - std::cout << "error: linebytes is 0" << std::endl; - return; - } - - std::cout << "Filter types: "; - for(size_t i = 0; i < data.size(); i += linebytes) - { - std::cout << (int)(data[i]) << " "; - } - std::cout << std::endl; - -} - - -/* -Main -*/ -int main(int argc, char *argv[]) /*list the chunks*/ -{ - bool ignore_checksums = false; - std::string filename = ""; - for (int i = 1; i < argc; i++) - { - if(std::string(argv[i]) == "--ignore_checksums") ignore_checksums = true; - else filename = argv[i]; - } - if(filename == "") - { - std::cout << "Please provide a filename to preview" << std::endl; - return 0; - } - - std::vector buffer; - std::vector image; - unsigned w, h; - - lodepng::load_file(buffer, filename); //load the image file with given filename - - lodepng::State state; - if(ignore_checksums) - { - state.decoder.ignore_crc = 1; - state.decoder.zlibsettings.ignore_adler32 = 1; - } - - unsigned error = lodepng::decode(image, w, h, state, buffer); - - if(error) - { - std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - std::cout << "Filesize: " << buffer.size() << " (" << buffer.size() / 1024 << "K)" << std::endl; - std::cout << "Width: " << w << std::endl; - std::cout << "Height: " << h << std::endl; - std::cout << "Num pixels: " << w * h << std::endl; - - if(w > 0 && h > 0) - { - std::cout << "Top left pixel color:" - << " r: " << (int)image[0] - << " g: " << (int)image[1] - << " b: " << (int)image[2] - << " a: " << (int)image[3] - << std::endl; - } - - - displayPNGInfo(state.info_png); - std::cout << std::endl; - displayChunkNames(buffer); - std::cout << std::endl; - displayFilterTypes(buffer, ignore_checksums); - std::cout << std::endl; - displayAsciiArt(image, w, h); -} diff --git a/examples/example_reencode.cpp b/examples/example_reencode.cpp deleted file mode 100644 index d4386129..00000000 --- a/examples/example_reencode.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2010 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* -LodePNG decode-encode: decodes the image, then encodes it again, with all the -same information, chunks, color types, etc... as the original image had. -This sample shows how LodePNG can be used for a conforming PNG editor. -*/ - -//g++ lodepng.cpp example_reencode.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3 -o reencode - -#include "lodepng.h" - -#include - -int main(int argc, char *argv[]) -{ - std::vector image; - unsigned w, h; - std::vector buffer; - lodepng::State state; - unsigned error; - - //check if user gave a filename - if(argc < 3) - { - std::cout << "please provide in and out filename" << std::endl; - return 0; - } - - state.decoder.color_convert = 0; - state.decoder.remember_unknown_chunks = 1; //make it reproduce even unknown chunks in the saved image - - lodepng::load_file(buffer, argv[1]); - error = lodepng::decode(image, w, h, state, buffer); - if(error) - { - std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - buffer.clear(); - - state.encoder.text_compression = 1; - - error = lodepng::encode(buffer, image, w, h, state); - if(error) - { - std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - lodepng::save_file(buffer, argv[2]); -} diff --git a/examples/example_sdl.c b/examples/example_sdl.c deleted file mode 100644 index e4ae3de5..00000000 --- a/examples/example_sdl.c +++ /dev/null @@ -1,142 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -/* -Compile command for Linux: -gcc lodepng.c example_sdl.c -ansi -pedantic -Wall -Wextra -lSDL -O3 -o showpng - -*/ - -/* -LodePNG SDL example -This example displays a PNG with a checkerboard pattern to show tranparency. -It requires the SDL library to compile and run. -If multiple filenames are given to the command line, it shows all of them. -Press any key to see next image, or esc to quit. -*/ - -#include "lodepng.h" - -#include - -/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/ -int show(const char* filename) -{ - unsigned error; - unsigned char* image; - unsigned w, h, x, y; - SDL_Surface* scr; - SDL_Event event; - int done; - size_t jump = 1; - - printf("showing %s\n", filename); - - /*load the PNG in one function call*/ - error = lodepng_decode32_file(&image, &w, &h, filename); - - /*stop if there is an error*/ - if(error) - { - printf("decoder error %u: %s\n", error, lodepng_error_text(error)); - return 0; - } - - /*avoid too large window size by downscaling large image*/ - - if(w / 1024 >= jump) jump = w / 1024 + 1; - if(h / 1024 >= jump) jump = h / 1024 + 1; - - /*init SDL*/ - if(SDL_Init(SDL_INIT_VIDEO) < 0) - { - printf("Error, SDL video init failed\n"); - return 0; - } - scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE); - if(!scr) - { - printf("Error, no SDL screen\n"); - return 0; - } - SDL_WM_SetCaption(filename, NULL); /*set window caption*/ - - /*plot the pixels of the PNG file*/ - for(y = 0; y + jump - 1 < h; y += jump) - for(x = 0; x + jump - 1 < w; x += jump) - { - int checkerColor; - Uint32* bufp; - Uint32 r, g, b, a; - - /*get RGBA components*/ - r = image[4 * y * w + 4 * x + 0]; /*red*/ - g = image[4 * y * w + 4 * x + 1]; /*green*/ - b = image[4 * y * w + 4 * x + 2]; /*blue*/ - a = image[4 * y * w + 4 * x + 3]; /*alpha*/ - - /*make translucency visible by placing checkerboard pattern behind image*/ - checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2)); - r = (a * r + (255 - a) * checkerColor) / 255; - g = (a * g + (255 - a) * checkerColor) / 255; - b = (a * b + (255 - a) * checkerColor) / 255; - - /*give the color value to the pixel of the screenbuffer*/ - bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump); - *bufp = 65536 * r + 256 * g + b; - } - - /*pause until you press escape and meanwhile redraw screen*/ - done = 0; - while(done == 0) - { - while(SDL_PollEvent(&event)) - { - if(event.type == SDL_QUIT) done = 2; - else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2; - else if(event.type == SDL_KEYDOWN) done = 1; /*press any other key for next image*/ - } - SDL_UpdateRect(scr, 0, 0, 0, 0); /*redraw screen*/ - SDL_Delay(5); /*pause 5 ms so it consumes less processing power*/ - } - - /*cleanup*/ - free(image); - SDL_Quit(); - return done == 2 ? 1 : 0; -} - -int main(int argc, char* argv[]) -{ - int i; - - if(argc <= 1) printf("Please enter PNG file name(s) to display\n");; - - for(i = 1; i < argc; i++) - { - if(show(argv[i])) return 0; - } - return 0; -} diff --git a/examples/example_sdl.cpp b/examples/example_sdl.cpp deleted file mode 100644 index 0c68ef5e..00000000 --- a/examples/example_sdl.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* -LodePNG Examples - -Copyright (c) 2005-2012 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 -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -*/ - -//Compile command for Linux: -//g++ lodepng.cpp example_sdl.cpp -lSDL -O3 -o showpng - -/* -LodePNG SDL example -This example displays a PNG with a checkerboard pattern to show tranparency. -It requires the SDL library to compile and run. -If multiple filenames are given to the command line, it shows all of them. -Press any key to see next image, or esc to quit. -*/ - -#include "lodepng.h" - -#include -#include - -int show(const std::string& caption, const unsigned char* rgba, unsigned w, unsigned h) -{ - //avoid too large window size by downscaling large image - unsigned jump = 1; - if(w / 1024 >= jump) jump = w / 1024 + 1; - if(h / 1024 >= jump) jump = h / 1024 + 1; - - //init SDL - if(SDL_Init(SDL_INIT_VIDEO) < 0) - { - std::cout << "error, SDL video init failed" << std::endl; - return 0; - } - SDL_Surface* scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE); - if(!scr) - { - std::cout << "error, no SDL screen" << std::endl; - return 0; - } - SDL_WM_SetCaption(caption.c_str(), NULL); //set window caption - - //plot the pixels of the PNG file - for(unsigned y = 0; y + jump - 1 < h; y += jump) - for(unsigned x = 0; x + jump - 1 < w; x += jump) - { - //get RGBA components - Uint32 r = rgba[4 * y * w + 4 * x + 0]; //red - Uint32 g = rgba[4 * y * w + 4 * x + 1]; //green - Uint32 b = rgba[4 * y * w + 4 * x + 2]; //blue - Uint32 a = rgba[4 * y * w + 4 * x + 3]; //alpha - - //make translucency visible by placing checkerboard pattern behind image - int checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2)); - r = (a * r + (255 - a) * checkerColor) / 255; - g = (a * g + (255 - a) * checkerColor) / 255; - b = (a * b + (255 - a) * checkerColor) / 255; - - //give the color value to the pixel of the screenbuffer - Uint32* bufp; - bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump); - *bufp = 65536 * r + 256 * g + b; - } - - //pause until you press escape and meanwhile redraw screen - SDL_Event event; - int done = 0; - while(done == 0) - { - while(SDL_PollEvent(&event)) - { - if(event.type == SDL_QUIT) done = 2; - else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2; - else if(event.type == SDL_KEYDOWN) done = 1; //press any other key for next image - } - SDL_UpdateRect(scr, 0, 0, 0, 0); //redraw screen - SDL_Delay(5); //pause 5 ms so it consumes less processing power - } - - SDL_Quit(); - return done == 2 ? 1 : 0; -} - -/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/ -int showfile(const char* filename) -{ - std::cout << "showing " << filename << std::endl; - - std::vector buffer, image; - lodepng::load_file(buffer, filename); //load the image file with given filename - unsigned w, h; - unsigned error = lodepng::decode(image, w, h, buffer); //decode the png - - //stop if there is an error - if(error) - { - std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; - return 0; - } - - return show(filename, &image[0], w, h); -} - -int main(int argc, char* argv[]) -{ - if(argc <= 1) std::cout << "Please enter PNG file name(s) to display" << std::endl; - - for(int i = 1; i < argc; i++) - { - if(showfile(argv[i])) return 0; - } -} From 88231d6fb93de0ff08fc7055aa18488b2d9e305d Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Wed, 9 Nov 2016 12:46:51 +0000 Subject: [PATCH 3/6] Rm tests from build --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e8e8378..5fdc2097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_library(lodepng ${CMAKE_CURRENT_SOURCE_DIR}/lodepng.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_benchmark.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/lodepng_util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pngdetail.cpp) From 25ae365b94f040804c8de29ab1e0d7d76c79e4b8 Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Wed, 30 Nov 2016 19:39:19 +0000 Subject: [PATCH 4/6] Edit CMakeLists --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fdc2097..51b9a24e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,9 @@ -# Auth: Alberto Taiuti +# Auth: Alberto Taiuti, Github usr: snowzufer cmake_minimum_required(VERSION 2.8) project(lode-png) -# Export commands for YCM -set(CMAKE_EXPORT_COMPILE_COMMANDS 1) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_library(lodepng From 34d6f5060746e3db1a3dba5b56d5c717472fa53e Mon Sep 17 00:00:00 2001 From: Lode Date: Mon, 28 Nov 2016 01:10:26 +0100 Subject: [PATCH 5/6] grey+alpha auto color model detection bugfix --- lodepng.cpp | 24 +++++++++----- lodepng.h | 9 ++--- lodepng_unittest.cpp | 79 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 86 insertions(+), 26 deletions(-) diff --git a/lodepng.cpp b/lodepng.cpp index 8c78758f..bf237df8 100644 --- a/lodepng.cpp +++ b/lodepng.cpp @@ -1,5 +1,5 @@ /* -LodePNG version 20160501 +LodePNG version 20161127 Copyright (c) 2005-2016 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 = "20160501"; +const char* LODEPNG_VERSION_STRING = "20161127"; /* This source file is built up in the following large parts. The code sections @@ -3534,8 +3534,8 @@ void lodepng_color_profile_init(LodePNGColorProfile* profile) { profile->colored = 0; profile->key = 0; - profile->alpha = 0; profile->key_r = profile->key_g = profile->key_b = 0; + profile->alpha = 0; profile->numcolors = 0; profile->bits = 1; } @@ -3622,8 +3622,8 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, if(a != 65535 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; + profile->key = 0; alpha_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } else if(a == 0 && !profile->alpha && !profile->key) { @@ -3636,6 +3636,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; } } @@ -3651,6 +3652,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; } } @@ -3684,6 +3686,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, if(a != 255 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; + profile->key = 0; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } @@ -3698,6 +3701,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } @@ -3734,7 +3738,9 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } } } @@ -3760,7 +3766,7 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, { LodePNGColorProfile prof; unsigned error = 0; - unsigned i, n, palettebits, grey_ok, palette_ok; + unsigned i, n, palettebits, palette_ok; lodepng_color_profile_init(&prof); error = lodepng_get_color_profile(&prof, image, w, h, mode_in); @@ -3770,14 +3776,14 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, if(prof.key && w * h <= 16) { prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + prof.key = 0; if(prof.bits < 8) prof.bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } - grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ n = prof.numcolors; palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); - palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; + palette_ok = n <= 256 && prof.bits <= 8; if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ - if(grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ + if(!prof.colored && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ if(palette_ok) { @@ -3806,7 +3812,7 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) : (prof.colored ? LCT_RGB : LCT_GREY); - if(prof.key && !prof.alpha) + if(prof.key) { unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ mode_out->key_r = prof.key_r & mask; diff --git a/lodepng.h b/lodepng.h index fcf9f714..8c634d20 100644 --- a/lodepng.h +++ b/lodepng.h @@ -1,5 +1,5 @@ /* -LodePNG version 20160501 +LodePNG version 20161127 Copyright (c) 2005-2016 Lode Vandevenne @@ -559,11 +559,11 @@ Used internally by default if "auto_convert" is enabled. Public because it's use typedef struct LodePNGColorProfile { unsigned colored; /*not greyscale*/ - unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ - unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ + unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ + unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ unsigned short key_g; unsigned short key_b; - unsigned alpha; /*alpha channel or alpha palette required*/ + unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ @@ -1608,6 +1608,7 @@ yyyymmdd. Some changes aren't backwards compatible. Those are indicated with a (!) symbol. +*) 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 the limits of pure C90). diff --git a/lodepng_unittest.cpp b/lodepng_unittest.cpp index 3d7f8e0a..5297a35a 100644 --- a/lodepng_unittest.cpp +++ b/lodepng_unittest.cpp @@ -93,6 +93,7 @@ g++ -I ./ lodepng.cpp examples/example_sdl.cpp -Wall -Wextra -pedantic -ansi -O3 *) strip trailing spaces and ensure consistent newlines *) check diff of lodepng.cpp and lodepng.h before submitting +git difftool -y */ @@ -613,7 +614,7 @@ void testColor(int r, int g, int b, int a) // Tests combinations of various colors in different orders void testFewColors() { - std::cout << "codec test colors " << std::endl; + std::cout << "codec test few colors " << std::endl; Image image; image.width = 20; image.height = 20; @@ -621,22 +622,20 @@ void testFewColors() image.bitDepth = 8; image.data.resize(image.width * image.height * 4); std::vector colors; - colors.push_back(0); colors.push_back(0); colors.push_back(0); colors.push_back(255); - colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(255); - colors.push_back(128); colors.push_back(128); colors.push_back(128); colors.push_back(255); - colors.push_back(0); colors.push_back(0); colors.push_back(255); colors.push_back(255); - colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(0); - colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(1); + colors.push_back(0); colors.push_back(0); colors.push_back(0); colors.push_back(255); // black + colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(255); // white + colors.push_back(128); colors.push_back(128); colors.push_back(128); colors.push_back(255); // grey + colors.push_back(0); colors.push_back(0); colors.push_back(255); colors.push_back(255); // blue + colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(0); // transparent white + colors.push_back(255); colors.push_back(255); colors.push_back(255); colors.push_back(1); // translucent white for(size_t i = 0; i < colors.size(); i += 4) for(size_t j = 0; j < colors.size(); j += 4) for(size_t k = 0; k < colors.size(); k += 4) for(size_t l = 0; l < colors.size(); l += 4) { + //std::cout << (i/4) << " " << (j/4) << " " << (k/4) << " " << (l/4) << std::endl; for(size_t c = 0; c < 4; c++) { - /*image.data[0 + c] = colors[i + c]; - image.data[4 + c] = colors[j + c]; - image.data[8 + c] = colors[k + c];*/ for(unsigned y = 0; y < image.height; y++) for(unsigned x = 0; x < image.width; x++) { @@ -1778,35 +1777,50 @@ void testAutoColorModel(const std::vector& colors, unsigned inbit ASSERT_EQUALS(colortype, state.info_png.color.colortype); ASSERT_EQUALS(bitdepth, state.info_png.color.bitdepth); ASSERT_EQUALS(key, state.info_png.color.key_defined); + // also check that the PNG decoded correctly and has same colors as input if(inbitdepth == 8) { for(size_t i = 0; i < colors.size(); i++) ASSERT_EQUALS(colors[i], decoded[i]); } else { for(size_t i = 0; i < colors.size() / 2; i++) ASSERT_EQUALS(colors[i * 2], decoded[i]); } } void testAutoColorModels() { + // 1-bit grey std::vector grey1; for(size_t i = 0; i < 2; i++) addColor(grey1, i * 255, i * 255, i * 255, 255); testAutoColorModel(grey1, 8, LCT_GREY, 1, false); + // 2-bit grey std::vector grey2; for(size_t i = 0; i < 4; i++) addColor(grey2, i * 85, i * 85, i * 85, 255); testAutoColorModel(grey2, 8, LCT_GREY, 2, false); - + // 4-bit grey std::vector grey4; for(size_t i = 0; i < 16; i++) addColor(grey4, i * 17, i * 17, i * 17, 255); testAutoColorModel(grey4, 8, LCT_GREY, 4, false); - + // 8-bit grey std::vector grey8; for(size_t i = 0; i < 256; i++) addColor(grey8, i, i, i, 255); testAutoColorModel(grey8, 8, LCT_GREY, 8, false); - + // 16-bit grey std::vector grey16; for(size_t i = 0; i < 257; i++) addColor16(grey16, i, i, i, 65535); testAutoColorModel(grey16, 16, LCT_GREY, 16, false); + // 8-bit grey+alpha + std::vector grey8a; + for(size_t i = 0; i < 17; i++) addColor(grey8a, i, i, i, i); + testAutoColorModel(grey8a, 8, LCT_GREY_ALPHA, 8, false); + + // 16-bit grey+alpha + std::vector grey16a; + for(size_t i = 0; i < 257; i++) addColor16(grey16a, i, i, i, i); + testAutoColorModel(grey16a, 16, LCT_GREY_ALPHA, 16, false); + + + // various palette tests std::vector palette; addColor(palette, 0, 0, 1, 255); testAutoColorModel(palette, 8, LCT_PALETTE, 1, false); @@ -1823,43 +1837,73 @@ void testAutoColorModels() addColor(palette, 0, 0, 18, 1); // translucent testAutoColorModel(palette, 8, LCT_PALETTE, 8, false); + // 1-bit grey + alpha not possible, becomes palette + std::vector grey1a; + for(size_t i = 0; i < 2; i++) addColor(grey1a, i, i, i, 128); + testAutoColorModel(grey1a, 8, LCT_PALETTE, 1, false); + + // 2-bit grey + alpha not possible, becomes palette + std::vector grey2a; + for(size_t i = 0; i < 4; i++) addColor(grey2a, i, i, i, 128); + testAutoColorModel(grey2a, 8, LCT_PALETTE, 2, false); + + // 4-bit grey + alpha not possible, becomes palette + std::vector grey4a; + for(size_t i = 0; i < 16; i++) addColor(grey4a, i, i, i, 128); + testAutoColorModel(grey4a, 8, LCT_PALETTE, 4, false); + + // 8-bit rgb std::vector rgb = grey8; addColor(rgb, 255, 0, 0, 255); testAutoColorModel(rgb, 8, LCT_RGB, 8, false); + // 8-bit rgb + key std::vector rgb_key = rgb; addColor(rgb_key, 128, 0, 0, 0); testAutoColorModel(rgb_key, 8, LCT_RGB, 8, true); + // 8-bit rgb, not key due to edge case: single key color, but opaque color has same RGB value std::vector rgb_key2 = rgb_key; addColor(rgb_key2, 128, 0, 0, 255); // same color but opaque ==> no more key testAutoColorModel(rgb_key2, 8, LCT_RGBA, 8, false); + // 8-bit rgb, not key due to semi translucent std::vector rgb_key3 = rgb_key; addColor(rgb_key3, 128, 0, 0, 255); // semi-translucent ==> no more key testAutoColorModel(rgb_key3, 8, LCT_RGBA, 8, false); + // 8-bit rgb, not key due to multiple transparent colors std::vector rgb_key4 = rgb_key; addColor(rgb_key4, 128, 0, 0, 255); addColor(rgb_key4, 129, 0, 0, 255); // two different transparent colors ==> no more key testAutoColorModel(rgb_key4, 8, LCT_RGBA, 8, false); + // 1-bit grey with key std::vector grey1_key = grey1; grey1_key[7] = 0; testAutoColorModel(grey1_key, 8, LCT_GREY, 1, true); + // 2-bit grey with key std::vector grey2_key = grey2; grey2_key[7] = 0; testAutoColorModel(grey2_key, 8, LCT_GREY, 2, true); + // 4-bit grey with key std::vector grey4_key = grey4; grey4_key[7] = 0; testAutoColorModel(grey4_key, 8, LCT_GREY, 4, true); + // 8-bit grey with key std::vector grey8_key = grey8; grey8_key[7] = 0; testAutoColorModel(grey8_key, 8, LCT_GREY, 8, true); + // 16-bit grey with key + std::vector grey16_key = grey16; + grey16_key[14] = grey16_key[15] = 0; + testAutoColorModel(grey16_key, 16, LCT_GREY, 16, true); + + // a single 16-bit color, can't become palette due to being 16-bit std::vector small16; addColor16(small16, 1, 0, 0, 65535); testAutoColorModel(small16, 16, LCT_RGB, 16, false); @@ -1868,13 +1912,22 @@ void testAutoColorModels() addColor16(small16a, 1, 0, 0, 1); testAutoColorModel(small16a, 16, LCT_RGBA, 16, false); + // what we provide as 16-bit is actually representable as 8-bit, so 8-bit palette expected for single color std::vector not16; addColor16(not16, 257, 257, 257, 0); testAutoColorModel(not16, 16, LCT_PALETTE, 1, false); + // the rgb color is representable as 8-bit, but the alpha channel only as 16-bit, so ensure it uses 16-bit and not palette for this single color std::vector alpha16; addColor16(alpha16, 257, 0, 0, 10000); testAutoColorModel(alpha16, 16, LCT_RGBA, 16, false); + + // 1-bit grey, with attempt to get color key but can't do it due to opaque color with same value + std::vector grey1k; + addColor(grey1k, 0, 0, 0, 255); + addColor(grey1k, 255, 255, 255, 255); + addColor(grey1k, 255, 255, 255, 0); + testAutoColorModel(grey1k, 8, LCT_PALETTE, 2, false); } void testPaletteToPaletteDecode() { From 2493db3da4ca4bae494dc59be767dd23ce6e8932 Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Wed, 30 Nov 2016 19:51:12 +0000 Subject: [PATCH 6/6] Add examples again --- examples/example_4bit_palette.cpp | 106 +++++++++ examples/example_bmp2png.cpp | 134 ++++++++++++ examples/example_decode.c | 113 ++++++++++ examples/example_decode.cpp | 95 ++++++++ examples/example_encode.c | 116 ++++++++++ examples/example_encode.cpp | 97 +++++++++ examples/example_encode_type.cpp | 79 +++++++ examples/example_gzip.cpp | 93 ++++++++ examples/example_opengl.cpp | 162 ++++++++++++++ examples/example_optimize_png.cpp | 133 ++++++++++++ examples/example_png2bmp.cpp | 132 +++++++++++ examples/example_png_info.cpp | 349 ++++++++++++++++++++++++++++++ examples/example_reencode.cpp | 76 +++++++ examples/example_sdl.c | 142 ++++++++++++ examples/example_sdl.cpp | 132 +++++++++++ 15 files changed, 1959 insertions(+) create mode 100644 examples/example_4bit_palette.cpp create mode 100644 examples/example_bmp2png.cpp create mode 100644 examples/example_decode.c create mode 100644 examples/example_decode.cpp create mode 100644 examples/example_encode.c create mode 100644 examples/example_encode.cpp create mode 100644 examples/example_encode_type.cpp create mode 100644 examples/example_gzip.cpp create mode 100644 examples/example_opengl.cpp create mode 100644 examples/example_optimize_png.cpp create mode 100644 examples/example_png2bmp.cpp create mode 100644 examples/example_png_info.cpp create mode 100644 examples/example_reencode.cpp create mode 100644 examples/example_sdl.c create mode 100644 examples/example_sdl.cpp diff --git a/examples/example_4bit_palette.cpp b/examples/example_4bit_palette.cpp new file mode 100644 index 00000000..a5e610de --- /dev/null +++ b/examples/example_4bit_palette.cpp @@ -0,0 +1,106 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +//g++ lodepng.cpp example_4bit_palette.cpp -ansi -pedantic -Wall -Wextra -O3 + + + +/* +LodePNG 4-bit palette example. +This example encodes a 511x511 PNG with a 4-bit palette. +Both image and palette contain sine waves, resulting in a sort of plasma. +The 511 (rather than power of two 512) size is of course chosen on purpose to +confirm that scanlines not filling up an entire byte size are working. + +NOTE: a PNG image with a translucent palette is perfectly valid. However there +exist some programs that cannot correctly read those, including, surprisingly, +Gimp 2.8 image editor (until you set mode to RGB). +*/ + +#include +#include + +#include "lodepng.h" + +int main(int argc, char *argv[]) +{ + //check if user gave a filename + if(argc < 2) + { + std::cout << "please provide a filename to save to" << std::endl; + return 0; + } + + //create encoder and set settings and info (optional) + lodepng::State state; + + //generate palette + for(int i = 0; i < 16; i++) + { + unsigned char r = 127 * (1 + std::sin(5 * i * 6.28318531 / 16)); + unsigned char g = 127 * (1 + std::sin(2 * i * 6.28318531 / 16)); + unsigned char b = 127 * (1 + std::sin(3 * i * 6.28318531 / 16)); + unsigned char a = 63 * (1 + std::sin(8 * i * 6.28318531 / 16)) + 128; /*alpha channel of the palette (tRNS chunk)*/ + + //palette must be added both to input and output color mode, because in this + //sample both the raw image and the expected PNG image use that palette. + lodepng_palette_add(&state.info_png.color, r, g, b, a); + lodepng_palette_add(&state.info_raw, r, g, b, a); + } + + //both the raw image and the encoded image must get colorType 3 (palette) + state.info_png.color.colortype = LCT_PALETTE; //if you comment this line, and create the above palette in info_raw instead, then you get the same image in a RGBA PNG. + state.info_png.color.bitdepth = 4; + state.info_raw.colortype = LCT_PALETTE; + state.info_raw.bitdepth = 4; + state.encoder.auto_convert = 0; //we specify ourselves exactly what output PNG color mode we want + + //generate some image + const unsigned w = 511; + const unsigned h = 511; + std::vector image; + image.resize((w * h * 4 + 7) / 8, 0); + for(unsigned y = 0; y < h; y++) + for(unsigned x = 0; x < w; x++) + { + size_t byte_index = (y * w + x) / 2; + bool byte_half = (y * w + x) % 2 == 1; + + int color = (int)(4 * ((1 + std::sin(2.0 * 6.28318531 * x / (double)w)) + + (1 + std::sin(2.0 * 6.28318531 * y / (double)h))) ); + + image[byte_index] |= (unsigned char)(color << (byte_half ? 0 : 4)); + } + + //encode and save + std::vector buffer; + unsigned error = lodepng::encode(buffer, image.empty() ? 0 : &image[0], w, h, state); + if(error) + { + std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; + return 0; + } + lodepng::save_file(buffer, argv[1]); +} diff --git a/examples/example_bmp2png.cpp b/examples/example_bmp2png.cpp new file mode 100644 index 00000000..c6bdd24d --- /dev/null +++ b/examples/example_bmp2png.cpp @@ -0,0 +1,134 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2010 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +Load a BMP image and convert it to a PNG image. This example also shows how +to use other data with the same memory structure as BMP, such as the image +format native to win32, GDI (HBITMAP, BITMAPINFO, ...) often encountered if +you're programming for Windows in Visual Studio. + +This example only supports uncompressed 24-bit RGB or 32-bit RGBA bitmaps. +For other types of BMP's, use a full fledged BMP decoder, or convert the +bitmap to 24-bit or 32-bit format. + +NOTE: it overwrites the output file without warning if it exists! +*/ + +//g++ lodepng.cpp example_bmp2png.cpp -ansi -pedantic -Wall -Wextra -O3 + +#include "lodepng.h" + +#include + +//returns 0 if all went ok, non-0 if error +//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel +unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, const std::vector& bmp) +{ + static const unsigned MINHEADER = 54; //minimum BMP header size + + if(bmp.size() < MINHEADER) return -1; + if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM' + unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts + //read width and height from BMP header + w = bmp[18] + bmp[19] * 256; + h = bmp[22] + bmp[23] * 256; + //read number of channels from BMP header + if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported. + unsigned numChannels = bmp[28] / 8; + + //The amount of scanline bytes is width of image times channels, with extra bytes added if needed + //to make it a multiple of 4 bytes. + unsigned scanlineBytes = w * numChannels; + if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4; + + unsigned dataSize = scanlineBytes * h; + if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels + + image.resize(w * h * 4); + + /* + There are 3 differences between BMP and the raw image buffer for LodePNG: + -it's upside down + -it's in BGR instead of RGB format (or BRGA instead of RGBA) + -each scanline has padding bytes to make it a multiple of 4 if needed + The 2D for loop below does all these 3 conversions at once. + */ + for(unsigned y = 0; y < h; y++) + for(unsigned x = 0; x < w; x++) + { + //pixel start byte position in the BMP + unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; + //pixel start byte position in the new raw image + unsigned newpos = 4 * y * w + 4 * x; + if(numChannels == 3) + { + image[newpos + 0] = bmp[bmpos + 2]; //R + image[newpos + 1] = bmp[bmpos + 1]; //G + image[newpos + 2] = bmp[bmpos + 0]; //B + image[newpos + 3] = 255; //A + } + else + { + image[newpos + 0] = bmp[bmpos + 3]; //R + image[newpos + 1] = bmp[bmpos + 2]; //G + image[newpos + 2] = bmp[bmpos + 1]; //B + image[newpos + 3] = bmp[bmpos + 0]; //A + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + if(argc < 3) + { + std::cout << "Please provice input PNG and output BMP file names" << std::endl; + return 0; + } + + std::vector bmp; + lodepng::load_file(bmp, argv[1]); + std::vector image; + unsigned w, h; + unsigned error = decodeBMP(image, w, h, bmp); + + if(error) + { + std::cout << "BMP decoding error " << error << std::endl; + return 0; + } + + std::vector png; + error = lodepng::encode(png, image, w, h); + + if(error) + { + std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + lodepng::save_file(png, argv[2]); + +} diff --git a/examples/example_decode.c b/examples/example_decode.c new file mode 100644 index 00000000..8f6ce392 --- /dev/null +++ b/examples/example_decode.c @@ -0,0 +1,113 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" + +#include +#include + +/* +3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways). +*/ + +/* +Example 1 +Decode from disk to raw pixels with a single function call +*/ +void decodeOneStep(const char* filename) +{ + unsigned error; + unsigned char* image; + unsigned width, height; + + error = lodepng_decode32_file(&image, &width, &height, filename); + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); + + /*use image here*/ + + free(image); +} + +/* +Example 2 +Load PNG file from disk to memory first, then decode to raw pixels in memory. +*/ +void decodeTwoSteps(const char* filename) +{ + unsigned error; + unsigned char* image; + unsigned width, height; + unsigned char* png = 0; + size_t pngsize; + + error = lodepng_load_file(&png, &pngsize, filename); + if(!error) error = lodepng_decode32(&image, &width, &height, png, pngsize); + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); + + free(png); + + /*use image here*/ + + free(image); +} + +/* +Example 3 +Load PNG file from disk using a State, normally needed for more advanced usage. +*/ +void decodeWithState(const char* filename) +{ + unsigned error; + unsigned char* image; + unsigned width, height; + unsigned char* png = 0; + size_t pngsize; + LodePNGState state; + + lodepng_state_init(&state); + /*optionally customize the state*/ + + error = lodepng_load_file(&png, &pngsize, filename); + if(!error) error = lodepng_decode(&image, &width, &height, &state, png, pngsize); + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); + + free(png); + + /*use image here*/ + /*state contains extra information about the PNG such as text chunks, ...*/ + + lodepng_state_cleanup(&state); + free(image); +} + +int main(int argc, char *argv[]) +{ + const char* filename = argc > 1 ? argv[1] : "test.png"; + + decodeOneStep(filename); + + return 0; +} + diff --git a/examples/example_decode.cpp b/examples/example_decode.cpp new file mode 100644 index 00000000..76cda6e2 --- /dev/null +++ b/examples/example_decode.cpp @@ -0,0 +1,95 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" +#include + +/* +3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways). +*/ + +//g++ lodepng.cpp example_decode.cpp -ansi -pedantic -Wall -Wextra -O3 + + +//Example 1 +//Decode from disk to raw pixels with a single function call +void decodeOneStep(const char* filename) +{ + std::vector image; //the raw pixels + unsigned width, height; + + //decode + unsigned error = lodepng::decode(image, width, height, filename); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +//Example 2 +//Load PNG file from disk to memory first, then decode to raw pixels in memory. +void decodeTwoSteps(const char* filename) +{ + std::vector png; + std::vector image; //the raw pixels + unsigned width, height; + + //load and decode + unsigned error = lodepng::load_file(png, filename); + if(!error) error = lodepng::decode(image, width, height, png); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +//Example 3 +//Load PNG file from disk using a State, normally needed for more advanced usage. +void decodeWithState(const char* filename) +{ + std::vector png; + std::vector image; //the raw pixels + unsigned width, height; + lodepng::State state; //optionally customize this one + + unsigned error = lodepng::load_file(png, filename); //load the image file with given filename + if(!error) error = lodepng::decode(image, width, height, state, png); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": "<< lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... + //State state contains extra information about the PNG such as text chunks, ... +} + +int main(int argc, char *argv[]) +{ + const char* filename = argc > 1 ? argv[1] : "test.png"; + + decodeOneStep(filename); +} + diff --git a/examples/example_encode.c b/examples/example_encode.c new file mode 100644 index 00000000..0e0f8bf1 --- /dev/null +++ b/examples/example_encode.c @@ -0,0 +1,116 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" + +#include +#include + +/* +3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways). +NOTE: this samples overwrite the file or test.png without warning! +*/ + +/* +Example 1 +Encode from raw pixels to disk with a single function call +The image argument has width * height RGBA pixels or width * height * 4 bytes +*/ +void encodeOneStep(const char* filename, const unsigned char* image, unsigned width, unsigned height) +{ + /*Encode the image*/ + unsigned error = lodepng_encode32_file(filename, image, width, height); + + /*if there's an error, display it*/ + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); +} + +/* +Example 2 +Encode from raw pixels to an in-memory PNG file first, then write it to disk +The image argument has width * height RGBA pixels or width * height * 4 bytes +*/ +void encodeTwoSteps(const char* filename, const unsigned char* image, unsigned width, unsigned height) +{ + unsigned char* png; + size_t pngsize; + + unsigned error = lodepng_encode32(&png, &pngsize, image, width, height); + if(!error) lodepng_save_file(png, pngsize, filename); + + /*if there's an error, display it*/ + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); + + free(png); +} + +/* +Example 3 +Save a PNG file to disk using a State, normally needed for more advanced usage. +The image argument has width * height RGBA pixels or width * height * 4 bytes +*/ +void encodeWithState(const char* filename, const unsigned char* image, unsigned width, unsigned height) +{ + unsigned error; + unsigned char* png; + size_t pngsize; + LodePNGState state; + + lodepng_state_init(&state); + /*optionally customize the state*/ + + error = lodepng_encode(&png, &pngsize, image, width, height, &state); + if(!error) lodepng_save_file(png, pngsize, filename); + + /*if there's an error, display it*/ + if(error) printf("error %u: %s\n", error, lodepng_error_text(error)); + + lodepng_state_cleanup(&state); + free(png); +} + +int main(int argc, char *argv[]) +{ + const char* filename = argc > 1 ? argv[1] : "test.png"; + + /*generate some image*/ + unsigned width = 512, height = 512; + unsigned char* image = malloc(width * height * 4); + unsigned x, y; + for(y = 0; y < height; y++) + for(x = 0; x < width; x++) + { + image[4 * width * y + 4 * x + 0] = 255 * !(x & y); + image[4 * width * y + 4 * x + 1] = x ^ y; + image[4 * width * y + 4 * x + 2] = x | y; + image[4 * width * y + 4 * x + 3] = 255; + } + + /*run an example*/ + encodeOneStep(filename, image, width, height); + + free(image); + return 0; +} diff --git a/examples/example_encode.cpp b/examples/example_encode.cpp new file mode 100644 index 00000000..31dd0b89 --- /dev/null +++ b/examples/example_encode.cpp @@ -0,0 +1,97 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" +#include + +/* +3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways). +NOTE: this samples overwrite the file or test.png without warning! +*/ + +//g++ lodepng.cpp example_encode.cpp -ansi -pedantic -Wall -Wextra -O3 + +//Example 1 +//Encode from raw pixels to disk with a single function call +//The image argument has width * height RGBA pixels or width * height * 4 bytes +void encodeOneStep(const char* filename, std::vector& image, unsigned width, unsigned height) +{ + //Encode the image + unsigned error = lodepng::encode(filename, image, width, height); + + //if there's an error, display it + if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; +} + +//Example 2 +//Encode from raw pixels to an in-memory PNG file first, then write it to disk +//The image argument has width * height RGBA pixels or width * height * 4 bytes +void encodeTwoSteps(const char* filename, std::vector& image, unsigned width, unsigned height) +{ + std::vector png; + + unsigned error = lodepng::encode(png, image, width, height); + if(!error) lodepng::save_file(png, filename); + + //if there's an error, display it + if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; +} + +//Example 3 +//Save a PNG file to disk using a State, normally needed for more advanced usage. +//The image argument has width * height RGBA pixels or width * height * 4 bytes +void encodeWithState(const char* filename, std::vector& image, unsigned width, unsigned height) +{ + std::vector png; + lodepng::State state; //optionally customize this one + + unsigned error = lodepng::encode(png, image, width, height, state); + if(!error) lodepng::save_file(png, filename); + + //if there's an error, display it + if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; +} + +//saves image to filename given as argument. Warning, this overwrites the file without warning! +int main(int argc, char *argv[]) +{ + //NOTE: this sample will overwrite the file or test.png without warning! + const char* filename = argc > 1 ? argv[1] : "test.png"; + + //generate some image + unsigned width = 512, height = 512; + std::vector image; + image.resize(width * height * 4); + for(unsigned y = 0; y < height; y++) + for(unsigned x = 0; x < width; x++) + { + image[4 * width * y + 4 * x + 0] = 255 * !(x & y); + image[4 * width * y + 4 * x + 1] = x ^ y; + image[4 * width * y + 4 * x + 2] = x | y; + image[4 * width * y + 4 * x + 3] = 255; + } + + encodeOneStep(filename, image, width, height); +} diff --git a/examples/example_encode_type.cpp b/examples/example_encode_type.cpp new file mode 100644 index 00000000..d1de926b --- /dev/null +++ b/examples/example_encode_type.cpp @@ -0,0 +1,79 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2015 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +//g++ -I ./ lodepng.cpp examples/example_encode_type.cpp -ansi -pedantic -Wall -Wextra -O3 + + + +/* +This example shows how to enforce a certain color type of the PNG image when +encoding a PNG (because by default, LodePNG automatically chooses an optimal +color type, no matter what your raw data's colro type is) +*/ + +#include +#include + +#include "lodepng.h" + +int main(int argc, char *argv[]) +{ + //check if user gave a filename + if(argc < 2) + { + std::cout << "please provide a filename to save to" << std::endl; + return 0; + } + + //generate some image + const unsigned w = 256; + const unsigned h = 256; + std::vector image(w * h * 4); + for(unsigned y = 0; y < h; y++) + for(unsigned x = 0; x < w; x++) + { + int index = y * w * 4 + x * 4; + image[index + 0] = 0; + image[index + 1] = 0; + image[index + 2] = 0; + image[index + 3] = 255; + } + + // we're going to encode with a state rather than a convenient function, because enforcing a color type requires setting options + lodepng::State state; + // input color type + state.info_raw.colortype = LCT_RGBA; + state.info_raw.bitdepth = 8; + // output color type + state.info_png.color.colortype = LCT_RGBA; + state.info_png.color.bitdepth = 8; + state.encoder.auto_convert = 0; // without this, it would ignore the output color type specified above and choose an optimal one instead + + //encode and save + std::vector buffer; + unsigned error = lodepng::encode(buffer, &image[0], w, h, state); + if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl; + else lodepng::save_file(buffer, argv[1]); +} diff --git a/examples/example_gzip.cpp b/examples/example_gzip.cpp new file mode 100644 index 00000000..b2ddf17b --- /dev/null +++ b/examples/example_gzip.cpp @@ -0,0 +1,93 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" +#include +#include + +/* +Encodes given file as a gzip file. + +See also the gzip specification, RFC 1952: http://www.gzip.org/zlib/rfc-gzip.html +*/ + +//g++ lodepng.cpp example_gzip.cpp -ansi -pedantic -Wall -Wextra -O3 + +//saves image to filename given as argument. Warning, this overwrites the file without warning! +int main(int argc, char *argv[]) +{ + if(argc < 2) + { + std::cout << "Please provide input filename (output is input with .gz)" << std::endl; + return 0; + } + + //NOTE: this sample will overwrite the output file without warning! + std::string infilename = argv[1]; + std::string outfilename = infilename + ".gz"; + + std::vector in; + lodepng::load_file(in, infilename); + + size_t outsize = 10; + unsigned char* out = (unsigned char*)malloc(outsize); + out[0] = 31; //ID1 + out[1] = 139; //ID2 + out[2] = 8; //CM + out[3] = 0; //FLG + //MTIME + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + + out[8] = 2; //2 = slow, 4 = fast compression + out[9] = 255; //OS unknown + + lodepng_deflate(&out, &outsize, &in[0], in.size(), &lodepng_default_compress_settings); + + unsigned crc = lodepng_crc32(&in[0], in.size()); + + size_t footer = outsize; + + outsize += 8; + out = (unsigned char*)realloc(out, outsize); + + //CRC + out[footer + 0] = crc % 256; + out[footer + 1] = (crc >> 8) % 256; + out[footer + 2] = (crc >> 16) % 256; + out[footer + 3] = (crc >> 24) % 256; + + //ISIZE + out[footer + 4] = in.size() % 256; + out[footer + 5] = (in.size() >> 8) % 256; + out[footer + 6] = (in.size() >> 16) % 256; + out[footer + 7] = (in.size() >> 24) % 256; + + lodepng_save_file(out, outsize, outfilename.c_str()); + + free(out); +} diff --git a/examples/example_opengl.cpp b/examples/example_opengl.cpp new file mode 100644 index 00000000..18798649 --- /dev/null +++ b/examples/example_opengl.cpp @@ -0,0 +1,162 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +//Compile command for Linux: +//g++ lodepng.cpp example_opengl.cpp -lSDL -lGL -O3 + +/* +LodePNG OpenGL example. Decodes a PNG and shows it in OpenGL. PNG filename +should be given as a command line parameter. + +It's written for the most basic old OpenGL version, and a correction for non +power of two textures had to be added. + +Only very few lines on the sample are about loading the PNG. Most of the +sample lines show a way to render a texture in 2D in OpenGL. + +No fancy 3D graphics are shown, it only shows the image statically. The sample +shows LodePNG can be used to load PNG images as textures in OpenGL. +*/ + +#include "lodepng.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if(argc < 2) + { + std::cout << "Please provide a filename." << std::endl; + return 1; + } + const char* filename = argv[1]; + + // Load file and decode image. + std::vector image; + unsigned width, height; + unsigned error = lodepng::decode(image, width, height, filename); + + // If there's an error, display it. + if(error != 0) + { + std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; + return 1; + } + + // Here the PNG is loaded in "image". All the rest of the code is SDL and OpenGL stuff. + + int screenw = width; + if(screenw > 1024) screenw = 1024; + int screenh = height; + if(screenh > 768) screenw = 768; + + if(SDL_Init(SDL_INIT_VIDEO) < 0) + { + std::cout << "Error: Unable to init SDL: " << SDL_GetError() << std::endl; + return 1; + } + + SDL_Surface* scr = SDL_SetVideoMode(screenw, screenh, 32, SDL_OPENGL); + + if(scr == 0) + { + std::cout << "Error: Unable to set video. SDL error message: " << SDL_GetError() << std::endl; + return 1; + } + + // The official code for "Setting Your Raster Position to a Pixel Location" (i.e. set up a camera for 2D screen) + glViewport(0, 0, screenw, screenh); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, screenw, screenh, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Make some OpenGL properties better for 2D and enable alpha channel. + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + + if(glGetError() != GL_NO_ERROR) + { + std::cout << "Error initing GL" << std::endl; + return 1; + } + + // Texture size must be power of two for the primitive OpenGL version this is written for. Find next power of two. + size_t u2 = 1; while(u2 < width) u2 *= 2; + size_t v2 = 1; while(v2 < height) v2 *= 2; + // Ratio for power of two version compared to actual version, to render the non power of two image with proper size. + double u3 = (double)width / u2; + double v3 = (double)height / v2; + + // Make power of two version of the image. + std::vector image2(u2 * v2 * 4); + for(size_t y = 0; y < height; y++) + for(size_t x = 0; x < width; x++) + for(size_t c = 0; c < 4; c++) + { + image2[4 * u2 * y + 4 * x + c] = image[4 * width * y + 4 * x + c]; + } + + // Enable the texture for OpenGL. + glEnable(GL_TEXTURE_2D); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_NEAREST = no smoothing + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 4, u2, v2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &image2[0]); + + bool done = false; + SDL_Event event = {0}; + glColor4ub(255, 255, 255, 255); + + while(!done) + { + // Quit the loop when receiving quit event. + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_QUIT) done = 1; + } + + // Draw the texture on a quad, using u3 and v3 to correct non power of two texture size. + glBegin(GL_QUADS); + glTexCoord2d( 0, 0); glVertex2f( 0, 0); + glTexCoord2d(u3, 0); glVertex2f(width, 0); + glTexCoord2d(u3, v3); glVertex2f(width, height); + glTexCoord2d( 0, v3); glVertex2f( 0, height); + glEnd(); + + // Redraw and clear screen. + SDL_GL_SwapBuffers(); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //Limit frames per second, to not heat up the CPU and GPU too much. + SDL_Delay(16); + } +} diff --git a/examples/example_optimize_png.cpp b/examples/example_optimize_png.cpp new file mode 100644 index 00000000..d64c7f22 --- /dev/null +++ b/examples/example_optimize_png.cpp @@ -0,0 +1,133 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +This example saves the PNG with the best compression LodePNG can do, and with +unnecessary chunks removed. It tries out several combinations of settings and +keeps the smallest one. + +NOTE: This is not as good as a true PNG optimizer like optipng or pngcrush. +*/ + +//g++ lodepng.cpp example_optimize_png.cpp -ansi -pedantic -Wall -Wextra -O3 + +#include "lodepng.h" + +#include + +int main(int argc, char *argv[]) +{ + std::vector image; + unsigned w, h; + std::vector buffer; + unsigned error; + + //check if user gave a filename + if(argc < 3) + { + std::cout << "please provide in and out filename" << std::endl; + return 0; + } + + lodepng::load_file(buffer, argv[1]); + error = lodepng::decode(image, w, h, buffer); + + if(error) + { + std::cout << "decoding error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + size_t origsize = buffer.size(); + std::cout << "Original size: " << origsize << " (" << (origsize / 1024) << "K)" << std::endl; + buffer.clear(); + + //Now encode as hard as possible with several filter types and window sizes + + lodepng::State state; + state.encoder.filter_palette_zero = 0; //We try several filter types, including zero, allow trying them all on palette images too. + state.encoder.add_id = false; //Don't add LodePNG version chunk to save more bytes + state.encoder.text_compression = 1; //Not needed because we don't add text chunks, but this demonstrates another optimization setting + state.encoder.zlibsettings.nicematch = 258; //Set this to the max possible, otherwise it can hurt compression + state.encoder.zlibsettings.lazymatching = 1; //Definitely use lazy matching for better compression + state.encoder.zlibsettings.windowsize = 32768; //Use maximum possible window size for best compression + + size_t bestsize = 0; + bool inited = false; + + int beststrategy = 0; + LodePNGFilterStrategy strategies[4] = { LFS_ZERO, LFS_MINSUM, LFS_ENTROPY, LFS_BRUTE_FORCE }; + std::string strategynames[4] = { "LFS_ZERO", "LFS_MINSUM", "LFS_ENTROPY", "LFS_BRUTE_FORCE" }; + + // min match 3 allows all deflate lengths. min match 6 is similar to "Z_FILTERED" of zlib. + int minmatches[2] = { 3, 6 }; + int bestminmatch = 0; + + int autoconverts[2] = { 0, 1 }; + std::string autoconvertnames[2] = { "0", "1" }; + int bestautoconvert = 0; + + int bestblocktype = 0; + + // Try out all combinations of everything + for(int i = 0; i < 4; i++) //filter strategy + for(int j = 0; j < 2; j++) //min match + for(int k = 0; k < 2; k++) //block type (for small images only) + for(int l = 0; l < 2; l++) //color convert strategy + { + if(bestsize > 3000 && (k > 0 || l > 0)) continue; /* these only make sense on small images */ + std::vector temp; + state.encoder.filter_strategy = strategies[i]; + state.encoder.zlibsettings.minmatch = minmatches[j]; + state.encoder.zlibsettings.btype = k == 0 ? 2 : 1; + state.encoder.auto_convert = autoconverts[l]; + error = lodepng::encode(temp, image, w, h, state); + + if(error) + { + std::cout << "encoding error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + if(!inited || temp.size() < bestsize) + { + bestsize = temp.size(); + beststrategy = i; + bestminmatch = state.encoder.zlibsettings.minmatch; + bestautoconvert = l; + bestblocktype = state.encoder.zlibsettings.btype; + temp.swap(buffer); + inited = true; + } + } + + std::cout << "Chosen filter strategy: " << strategynames[beststrategy] << std::endl; + std::cout << "Chosen min match: " << bestminmatch << std::endl; + std::cout << "Chosen block type: " << bestblocktype << std::endl; + std::cout << "Chosen auto convert: " << autoconvertnames[bestautoconvert] << std::endl; + + lodepng::save_file(buffer, argv[2]); + std::cout << "New size: " << buffer.size() << " (" << (buffer.size() / 1024) << "K)" << std::endl; +} diff --git a/examples/example_png2bmp.cpp b/examples/example_png2bmp.cpp new file mode 100644 index 00000000..3fd8328b --- /dev/null +++ b/examples/example_png2bmp.cpp @@ -0,0 +1,132 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include "lodepng.h" +#include + +/* +This example converts a PNG file to a BMP file. +NOTE: it overwrites the output file without warning if it exists! +Give the PNG and the BMP file names as command line arguments. +*/ + +/* +g++ lodepng.cpp example_png2bmp.cpp -Wall -Wextra -pedantic -ansi -lSDL -O3 +*/ + + + +//Input image must be RGB buffer (3 bytes per pixel), but you can easily make it +//support RGBA input and output by changing the inputChannels and/or outputChannels +//in the function to 4. +void encodeBMP(std::vector& bmp, const unsigned char* image, int w, int h) +{ + //3 bytes per pixel used for both input and output. + int inputChannels = 3; + int outputChannels = 3; + + //bytes 0-13 + bmp.push_back('B'); bmp.push_back('M'); //0: bfType + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //2: bfSize; size not yet known for now, filled in later. + bmp.push_back(0); bmp.push_back(0); //6: bfReserved1 + bmp.push_back(0); bmp.push_back(0); //8: bfReserved2 + bmp.push_back(54 % 256); bmp.push_back(54 / 256); bmp.push_back(0); bmp.push_back(0); //10: bfOffBits (54 header bytes) + + //bytes 14-53 + bmp.push_back(40); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //14: biSize + bmp.push_back(w % 256); bmp.push_back(w / 256); bmp.push_back(0); bmp.push_back(0); //18: biWidth + bmp.push_back(h % 256); bmp.push_back(h / 256); bmp.push_back(0); bmp.push_back(0); //22: biHeight + bmp.push_back(1); bmp.push_back(0); //26: biPlanes + bmp.push_back(outputChannels * 8); bmp.push_back(0); //28: biBitCount + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //30: biCompression + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //34: biSizeImage + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //38: biXPelsPerMeter + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //42: biYPelsPerMeter + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //46: biClrUsed + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //50: biClrImportant + + /* + Convert the input RGBRGBRGB pixel buffer to the BMP pixel buffer format. There are 3 differences with the input buffer: + -BMP stores the rows inversed, from bottom to top + -BMP stores the color channels in BGR instead of RGB order + -BMP requires each row to have a multiple of 4 bytes, so sometimes padding bytes are added between rows + */ + + int imagerowbytes = outputChannels * w; + imagerowbytes = imagerowbytes % 4 == 0 ? imagerowbytes : imagerowbytes + (4 - imagerowbytes % 4); //must be multiple of 4 + + for(int y = h - 1; y >= 0; y--) //the rows are stored inversed in bmp + { + int c = 0; + for(int x = 0; x < imagerowbytes; x++) + { + if(x < w * outputChannels) + { + int inc = c; + //Convert RGB(A) into BGR(A) + if(c == 0) inc = 2; + else if(c == 2) inc = 0; + bmp.push_back(image[inputChannels * (w * y + x / outputChannels) + inc]); + } + else bmp.push_back(0); + c++; + if(c >= outputChannels) c = 0; + } + } + + // Fill in the size + bmp[2] = bmp.size() % 256; + bmp[3] = (bmp.size() / 256) % 256; + bmp[4] = (bmp.size() / 65536) % 256; + bmp[5] = bmp.size() / 16777216; +} + +int main(int argc, char *argv[]) +{ + if(argc < 3) + { + std::cout << "Please provice input PNG and output BMP file names" << std::endl; + return 0; + } + const char* infile = argv[1]; + const char* outfile = argv[2]; + + + std::vector image; //the raw pixels + unsigned width, height; + + unsigned error = lodepng::decode(image, width, height, infile, LCT_RGB, 8); + + if(error) + { + std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + std::vector bmp; + encodeBMP(bmp, &image[0], width, height); + + lodepng::save_file(bmp, outfile); +} diff --git a/examples/example_png_info.cpp b/examples/example_png_info.cpp new file mode 100644 index 00000000..cd2eca60 --- /dev/null +++ b/examples/example_png_info.cpp @@ -0,0 +1,349 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +//g++ lodepng.cpp example_png_info.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3 + +/* +This sample shows a lot of information in the console about a PNG file, +including color type, text chunks, the names of all chunks in the image, +etc... +*/ + + +#include "lodepng.h" +#include + +/* +Display general info about the PNG. +*/ +void displayPNGInfo(const LodePNGInfo& info) +{ + const LodePNGColorMode& color = info.color; + + std::cout << "Compression method: " << info.compression_method << std::endl; + std::cout << "Filter method: " << info.filter_method << std::endl; + std::cout << "Interlace method: " << info.interlace_method << std::endl; + std::cout << "Color type: " << color.colortype << std::endl; + std::cout << "Bit depth: " << color.bitdepth << std::endl; + std::cout << "Bits per pixel: " << lodepng_get_bpp(&color) << std::endl; + std::cout << "Channels per pixel: " << lodepng_get_channels(&color) << std::endl; + std::cout << "Is greyscale type: " << lodepng_is_greyscale_type(&color) << std::endl; + std::cout << "Can have alpha: " << lodepng_can_have_alpha(&color) << std::endl; + std::cout << "Palette size: " << color.palettesize << std::endl; + std::cout << "Has color key: " << color.key_defined << std::endl; + if(color.key_defined) + { + std::cout << "Color key r: " << color.key_r << std::endl; + std::cout << "Color key g: " << color.key_g << std::endl; + std::cout << "Color key b: " << color.key_b << std::endl; + } + std::cout << "Texts: " << info.text_num << std::endl; + for(size_t i = 0; i < info.text_num; i++) + { + std::cout << "Text: " << info.text_keys[i] << ": " << info.text_strings[i] << std::endl << std::endl; + } + std::cout << "International texts: " << info.itext_num << std::endl; + for(size_t i = 0; i < info.itext_num; i++) + { + std::cout << "Text: " + << info.itext_keys[i] << ", " + << info.itext_langtags[i] << ", " + << info.itext_transkeys[i] << ": " + << info.itext_strings[i] << std::endl << std::endl; + } + std::cout << "Time defined: " << info.time_defined << std::endl; + if(info.time_defined) + { + const LodePNGTime& time = info.time; + std::cout << "year: " << time.year << std::endl; + std::cout << "month: " << time.month << std::endl; + std::cout << "day: " << time.day << std::endl; + std::cout << "hour: " << time.hour << std::endl; + std::cout << "minute: " << time.minute << std::endl; + std::cout << "second: " << time.second << std::endl; + } + std::cout << "Physics defined: " << info.phys_defined << std::endl; + if(info.phys_defined) + { + std::cout << "physics X: " << info.phys_x << std::endl; + std::cout << "physics Y: " << info.phys_y << std::endl; + std::cout << "physics unit: " << info.phys_unit << std::endl; + } +} + + +/* +Display the names and sizes of all chunks in the PNG file. +*/ +void displayChunkNames(const std::vector& buffer) +{ + // Listing chunks is based on the original file, not the decoded png info. + const unsigned char *chunk, *begin, *end, *next; + end = &buffer.back() + 1; + begin = chunk = &buffer.front() + 8; + + std::cout << std::endl << "Chunks:" << std::endl; + std::cout << " type: length(s)"; + std::string last_type; + while(chunk + 8 < end && chunk >= begin) + { + char type[5]; + lodepng_chunk_type(type, chunk); + if(std::string(type).size() != 4) + { + std::cout << "this is probably not a PNG" << std::endl; + return; + } + + if(last_type != type) + { + std::cout << std::endl; + std::cout << " " << type << ": "; + } + last_type = type; + + std::cout << lodepng_chunk_length(chunk) << ", "; + + next = lodepng_chunk_next_const(chunk); + if (next <= chunk) break; // integer overflow + chunk = next; + } + std::cout << std::endl; +} + + +/* +Show ASCII art preview of the image +*/ +void displayAsciiArt(const std::vector& image, unsigned w, unsigned h) +{ + if(w > 0 && h > 0) + { + std::cout << std::endl << "ASCII Art Preview: " << std::endl; + unsigned w2 = 48; + if(w < w2) w2 = w; + unsigned h2 = h * w2 / w; + h2 = (h2 * 2) / 3; //compensate for non-square characters in terminal + if(h2 > (w2 * 2)) h2 = w2 * 2; //avoid too large output + + std::cout << '+'; + for(unsigned x = 0; x < w2; x++) std::cout << '-'; + std::cout << '+' << std::endl; + for(unsigned y = 0; y < h2; y++) + { + std::cout << "|"; + for(unsigned x = 0; x < w2; x++) + { + unsigned x2 = x * w / w2; + unsigned y2 = y * h / h2; + int r = image[y2 * w * 4 + x2 * 4 + 0]; + int g = image[y2 * w * 4 + x2 * 4 + 1]; + int b = image[y2 * w * 4 + x2 * 4 + 2]; + int a = image[y2 * w * 4 + x2 * 4 + 3]; + int lightness = ((r + g + b) / 3) * a / 255; + int min = (r < g && r < b) ? r : (g < b ? g : b); + int max = (r > g && r > b) ? r : (g > b ? g : b); + int saturation = max - min; + int letter = 'i'; //i for grey, or r,y,g,c,b,m for colors + if(saturation > 32) + { + int h = lightness >= (min + max) / 2; + if(h) letter = (min == r ? 'c' : (min == g ? 'm' : 'y')); + else letter = (max == r ? 'r' : (max == g ? 'g' : 'b')); + } + int symbol = ' '; + if(lightness > 224) symbol = '@'; + else if(lightness > 128) symbol = letter - 32; + else if(lightness > 32) symbol = letter; + else if(lightness > 16) symbol = '.'; + std::cout << (char)symbol; + } + std::cout << "|"; + std::cout << std::endl; + } + std::cout << '+'; + for(unsigned x = 0; x < w2; x++) std::cout << '-'; + std::cout << '+' << std::endl; + } +} + + +/* +Show the filtertypes of each scanline in this PNG image. +*/ +void displayFilterTypes(const std::vector& buffer, bool ignore_checksums) +{ + //Get color type and interlace type + lodepng::State state; + if(ignore_checksums) + { + state.decoder.ignore_crc = 1; + state.decoder.zlibsettings.ignore_adler32 = 1; + } + unsigned w, h; + unsigned error; + error = lodepng_inspect(&w, &h, &state, &buffer[0], buffer.size()); + + if(error) + { + std::cout << "inspect error " << error << ": " << lodepng_error_text(error) << std::endl; + return; + } + + if(state.info_png.interlace_method == 1) + { + std::cout << "showing filtertypes for interlaced PNG not supported by this example" << std::endl; + return; + } + + //Read literal data from all IDAT chunks + const unsigned char *chunk, *begin, *end, *next; + end = &buffer.back() + 1; + begin = chunk = &buffer.front() + 8; + + std::vector zdata; + + while(chunk + 8 < end && chunk >= begin) + { + char type[5]; + lodepng_chunk_type(type, chunk); + if(std::string(type).size() != 4) + { + std::cout << "this is probably not a PNG" << std::endl; + return; + } + + if(std::string(type) == "IDAT") + { + const unsigned char* cdata = lodepng_chunk_data_const(chunk); + unsigned clength = lodepng_chunk_length(chunk); + if(chunk + clength + 12 > end || clength > buffer.size() || chunk + clength + 12 < begin) { + std::cout << "invalid chunk length" << std::endl; + return; + } + + for(unsigned i = 0; i < clength; i++) + { + zdata.push_back(cdata[i]); + } + } + + next = lodepng_chunk_next_const(chunk); + if (next <= chunk) break; // integer overflow + chunk = next; + } + + //Decompress all IDAT data + std::vector data; + error = lodepng::decompress(data, &zdata[0], zdata.size()); + + if(error) + { + std::cout << "decompress error " << error << ": " << lodepng_error_text(error) << std::endl; + return; + } + + //A line is 1 filter byte + all pixels + size_t linebytes = 1 + lodepng_get_raw_size(w, 1, &state.info_png.color); + + if(linebytes == 0) + { + std::cout << "error: linebytes is 0" << std::endl; + return; + } + + std::cout << "Filter types: "; + for(size_t i = 0; i < data.size(); i += linebytes) + { + std::cout << (int)(data[i]) << " "; + } + std::cout << std::endl; + +} + + +/* +Main +*/ +int main(int argc, char *argv[]) /*list the chunks*/ +{ + bool ignore_checksums = false; + std::string filename = ""; + for (int i = 1; i < argc; i++) + { + if(std::string(argv[i]) == "--ignore_checksums") ignore_checksums = true; + else filename = argv[i]; + } + if(filename == "") + { + std::cout << "Please provide a filename to preview" << std::endl; + return 0; + } + + std::vector buffer; + std::vector image; + unsigned w, h; + + lodepng::load_file(buffer, filename); //load the image file with given filename + + lodepng::State state; + if(ignore_checksums) + { + state.decoder.ignore_crc = 1; + state.decoder.zlibsettings.ignore_adler32 = 1; + } + + unsigned error = lodepng::decode(image, w, h, state, buffer); + + if(error) + { + std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + std::cout << "Filesize: " << buffer.size() << " (" << buffer.size() / 1024 << "K)" << std::endl; + std::cout << "Width: " << w << std::endl; + std::cout << "Height: " << h << std::endl; + std::cout << "Num pixels: " << w * h << std::endl; + + if(w > 0 && h > 0) + { + std::cout << "Top left pixel color:" + << " r: " << (int)image[0] + << " g: " << (int)image[1] + << " b: " << (int)image[2] + << " a: " << (int)image[3] + << std::endl; + } + + + displayPNGInfo(state.info_png); + std::cout << std::endl; + displayChunkNames(buffer); + std::cout << std::endl; + displayFilterTypes(buffer, ignore_checksums); + std::cout << std::endl; + displayAsciiArt(image, w, h); +} diff --git a/examples/example_reencode.cpp b/examples/example_reencode.cpp new file mode 100644 index 00000000..d4386129 --- /dev/null +++ b/examples/example_reencode.cpp @@ -0,0 +1,76 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2010 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +LodePNG decode-encode: decodes the image, then encodes it again, with all the +same information, chunks, color types, etc... as the original image had. +This sample shows how LodePNG can be used for a conforming PNG editor. +*/ + +//g++ lodepng.cpp example_reencode.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3 -o reencode + +#include "lodepng.h" + +#include + +int main(int argc, char *argv[]) +{ + std::vector image; + unsigned w, h; + std::vector buffer; + lodepng::State state; + unsigned error; + + //check if user gave a filename + if(argc < 3) + { + std::cout << "please provide in and out filename" << std::endl; + return 0; + } + + state.decoder.color_convert = 0; + state.decoder.remember_unknown_chunks = 1; //make it reproduce even unknown chunks in the saved image + + lodepng::load_file(buffer, argv[1]); + error = lodepng::decode(image, w, h, state, buffer); + if(error) + { + std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + buffer.clear(); + + state.encoder.text_compression = 1; + + error = lodepng::encode(buffer, image, w, h, state); + if(error) + { + std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + lodepng::save_file(buffer, argv[2]); +} diff --git a/examples/example_sdl.c b/examples/example_sdl.c new file mode 100644 index 00000000..e4ae3de5 --- /dev/null +++ b/examples/example_sdl.c @@ -0,0 +1,142 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +Compile command for Linux: +gcc lodepng.c example_sdl.c -ansi -pedantic -Wall -Wextra -lSDL -O3 -o showpng + +*/ + +/* +LodePNG SDL example +This example displays a PNG with a checkerboard pattern to show tranparency. +It requires the SDL library to compile and run. +If multiple filenames are given to the command line, it shows all of them. +Press any key to see next image, or esc to quit. +*/ + +#include "lodepng.h" + +#include + +/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/ +int show(const char* filename) +{ + unsigned error; + unsigned char* image; + unsigned w, h, x, y; + SDL_Surface* scr; + SDL_Event event; + int done; + size_t jump = 1; + + printf("showing %s\n", filename); + + /*load the PNG in one function call*/ + error = lodepng_decode32_file(&image, &w, &h, filename); + + /*stop if there is an error*/ + if(error) + { + printf("decoder error %u: %s\n", error, lodepng_error_text(error)); + return 0; + } + + /*avoid too large window size by downscaling large image*/ + + if(w / 1024 >= jump) jump = w / 1024 + 1; + if(h / 1024 >= jump) jump = h / 1024 + 1; + + /*init SDL*/ + if(SDL_Init(SDL_INIT_VIDEO) < 0) + { + printf("Error, SDL video init failed\n"); + return 0; + } + scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE); + if(!scr) + { + printf("Error, no SDL screen\n"); + return 0; + } + SDL_WM_SetCaption(filename, NULL); /*set window caption*/ + + /*plot the pixels of the PNG file*/ + for(y = 0; y + jump - 1 < h; y += jump) + for(x = 0; x + jump - 1 < w; x += jump) + { + int checkerColor; + Uint32* bufp; + Uint32 r, g, b, a; + + /*get RGBA components*/ + r = image[4 * y * w + 4 * x + 0]; /*red*/ + g = image[4 * y * w + 4 * x + 1]; /*green*/ + b = image[4 * y * w + 4 * x + 2]; /*blue*/ + a = image[4 * y * w + 4 * x + 3]; /*alpha*/ + + /*make translucency visible by placing checkerboard pattern behind image*/ + checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2)); + r = (a * r + (255 - a) * checkerColor) / 255; + g = (a * g + (255 - a) * checkerColor) / 255; + b = (a * b + (255 - a) * checkerColor) / 255; + + /*give the color value to the pixel of the screenbuffer*/ + bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump); + *bufp = 65536 * r + 256 * g + b; + } + + /*pause until you press escape and meanwhile redraw screen*/ + done = 0; + while(done == 0) + { + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_QUIT) done = 2; + else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2; + else if(event.type == SDL_KEYDOWN) done = 1; /*press any other key for next image*/ + } + SDL_UpdateRect(scr, 0, 0, 0, 0); /*redraw screen*/ + SDL_Delay(5); /*pause 5 ms so it consumes less processing power*/ + } + + /*cleanup*/ + free(image); + SDL_Quit(); + return done == 2 ? 1 : 0; +} + +int main(int argc, char* argv[]) +{ + int i; + + if(argc <= 1) printf("Please enter PNG file name(s) to display\n");; + + for(i = 1; i < argc; i++) + { + if(show(argv[i])) return 0; + } + return 0; +} diff --git a/examples/example_sdl.cpp b/examples/example_sdl.cpp new file mode 100644 index 00000000..0c68ef5e --- /dev/null +++ b/examples/example_sdl.cpp @@ -0,0 +1,132 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +//Compile command for Linux: +//g++ lodepng.cpp example_sdl.cpp -lSDL -O3 -o showpng + +/* +LodePNG SDL example +This example displays a PNG with a checkerboard pattern to show tranparency. +It requires the SDL library to compile and run. +If multiple filenames are given to the command line, it shows all of them. +Press any key to see next image, or esc to quit. +*/ + +#include "lodepng.h" + +#include +#include + +int show(const std::string& caption, const unsigned char* rgba, unsigned w, unsigned h) +{ + //avoid too large window size by downscaling large image + unsigned jump = 1; + if(w / 1024 >= jump) jump = w / 1024 + 1; + if(h / 1024 >= jump) jump = h / 1024 + 1; + + //init SDL + if(SDL_Init(SDL_INIT_VIDEO) < 0) + { + std::cout << "error, SDL video init failed" << std::endl; + return 0; + } + SDL_Surface* scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE); + if(!scr) + { + std::cout << "error, no SDL screen" << std::endl; + return 0; + } + SDL_WM_SetCaption(caption.c_str(), NULL); //set window caption + + //plot the pixels of the PNG file + for(unsigned y = 0; y + jump - 1 < h; y += jump) + for(unsigned x = 0; x + jump - 1 < w; x += jump) + { + //get RGBA components + Uint32 r = rgba[4 * y * w + 4 * x + 0]; //red + Uint32 g = rgba[4 * y * w + 4 * x + 1]; //green + Uint32 b = rgba[4 * y * w + 4 * x + 2]; //blue + Uint32 a = rgba[4 * y * w + 4 * x + 3]; //alpha + + //make translucency visible by placing checkerboard pattern behind image + int checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2)); + r = (a * r + (255 - a) * checkerColor) / 255; + g = (a * g + (255 - a) * checkerColor) / 255; + b = (a * b + (255 - a) * checkerColor) / 255; + + //give the color value to the pixel of the screenbuffer + Uint32* bufp; + bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump); + *bufp = 65536 * r + 256 * g + b; + } + + //pause until you press escape and meanwhile redraw screen + SDL_Event event; + int done = 0; + while(done == 0) + { + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_QUIT) done = 2; + else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2; + else if(event.type == SDL_KEYDOWN) done = 1; //press any other key for next image + } + SDL_UpdateRect(scr, 0, 0, 0, 0); //redraw screen + SDL_Delay(5); //pause 5 ms so it consumes less processing power + } + + SDL_Quit(); + return done == 2 ? 1 : 0; +} + +/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/ +int showfile(const char* filename) +{ + std::cout << "showing " << filename << std::endl; + + std::vector buffer, image; + lodepng::load_file(buffer, filename); //load the image file with given filename + unsigned w, h; + unsigned error = lodepng::decode(image, w, h, buffer); //decode the png + + //stop if there is an error + if(error) + { + std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + return show(filename, &image[0], w, h); +} + +int main(int argc, char* argv[]) +{ + if(argc <= 1) std::cout << "Please enter PNG file name(s) to display" << std::endl; + + for(int i = 1; i < argc; i++) + { + if(showfile(argv[i])) return 0; + } +}