Add ktx
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
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 <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#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<unsigned char> 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<unsigned char> 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]);
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
//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<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& 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 + 2]; //R
|
||||
image[newpos + 1] = bmp[bmpos + 1]; //G
|
||||
image[newpos + 2] = bmp[bmpos + 0]; //B
|
||||
image[newpos + 3] = bmp[bmpos + 3]; //A
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc < 3) {
|
||||
std::cout << "Please provide input BMP and output PNG file names" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> bmp;
|
||||
lodepng::load_file(bmp, argv[1]);
|
||||
std::vector<unsigned char> 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<unsigned char> 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]);
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
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 = 0;
|
||||
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 = 0;
|
||||
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 = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
/*
|
||||
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<unsigned char> 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<unsigned char> png;
|
||||
std::vector<unsigned char> 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<unsigned char> png;
|
||||
std::vector<unsigned char> 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);
|
||||
}
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways).
|
||||
NOTE: these 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;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
/*
|
||||
3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways).
|
||||
NOTE: these samples overwrite the file or test.png without warning!
|
||||
*/
|
||||
|
||||
//g++ lodepng.cpp examples/example_encode.cpp -I./ -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<unsigned char>& 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<unsigned char>& image, unsigned width, unsigned height) {
|
||||
std::vector<unsigned char> 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<unsigned char>& image, unsigned width, unsigned height) {
|
||||
std::vector<unsigned char> 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<unsigned char> 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);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
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 color type is)
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#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<unsigned char> 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<unsigned char> 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]);
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
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<unsigned char> 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);
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
#include <SDL/SDL.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
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<unsigned char> 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<unsigned char> 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
std::vector<unsigned char> 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<unsigned char> 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;
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
/*
|
||||
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<unsigned char>& 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 provide input PNG and output BMP file names" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
const char* infile = argv[1];
|
||||
const char* outfile = argv[2];
|
||||
|
||||
|
||||
std::vector<unsigned char> 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<unsigned char> bmp;
|
||||
encodeBMP(bmp, &image[0], width, height);
|
||||
|
||||
lodepng::save_file(bmp, outfile);
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
/*
|
||||
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<unsigned char>& buffer) {
|
||||
// Listing chunks is based on the original file, not the decoded png info.
|
||||
const unsigned char *chunk, *end;
|
||||
end = &buffer.back() + 1;
|
||||
chunk = &buffer.front() + 8;
|
||||
|
||||
std::cout << std::endl << "Chunks:" << std::endl;
|
||||
std::cout << " type: length(s)";
|
||||
std::string last_type;
|
||||
while(chunk < end && end - chunk >= 8) {
|
||||
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) << ", ";
|
||||
|
||||
chunk = lodepng_chunk_next_const(chunk, end);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Show ASCII art preview of the image
|
||||
*/
|
||||
void displayAsciiArt(const std::vector<unsigned char>& 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<unsigned char>& 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;
|
||||
end = &buffer.back() + 1;
|
||||
begin = chunk = &buffer.front() + 8;
|
||||
|
||||
std::vector<unsigned char> zdata;
|
||||
|
||||
while(chunk < end && end - chunk >= 8) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
chunk = lodepng_chunk_next_const(chunk, end);
|
||||
}
|
||||
|
||||
//Decompress all IDAT data
|
||||
std::vector<unsigned char> 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<unsigned char> buffer;
|
||||
std::vector<unsigned char> 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);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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 <iostream>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
std::vector<unsigned char> 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]);
|
||||
}
|
||||
+142
@@ -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 -lSDL2 -O3 -o showpng
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
LodePNG SDL example
|
||||
This example displays a PNG with a checkerboard pattern to show tranparency.
|
||||
It requires the SDL2 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 <SDL2/SDL.h>
|
||||
|
||||
|
||||
/*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;
|
||||
int done;
|
||||
size_t jump = 1;
|
||||
SDL_Window* sdl_window;
|
||||
SDL_Renderer* sdl_renderer;
|
||||
SDL_Texture* sdl_texture;
|
||||
SDL_Event sdl_event;
|
||||
size_t screenw, screenh, pitch;
|
||||
Uint32* sdl_pixels;
|
||||
|
||||
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;
|
||||
|
||||
screenw = w / jump;
|
||||
screenh = h / jump;
|
||||
pitch = screenw * sizeof(Uint32);
|
||||
/* init SDL */
|
||||
SDL_CreateWindowAndRenderer(screenw, screenh, SDL_WINDOW_OPENGL, &sdl_window, &sdl_renderer);
|
||||
SDL_SetWindowTitle(sdl_window, filename);
|
||||
if(!sdl_window) {
|
||||
printf("Error, no SDL screen\n");
|
||||
return 0;
|
||||
}
|
||||
sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, screenw, screenh);
|
||||
sdl_pixels = (Uint32*)malloc(screenw * screenh * sizeof(Uint32));
|
||||
if(!sdl_pixels) {
|
||||
printf("Failed to allocate pixels\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
/* get RGBA components */
|
||||
Uint32 r = image[4 * y * w + 4 * x + 0]; /* red */
|
||||
Uint32 g = image[4 * y * w + 4 * x + 1]; /* green */
|
||||
Uint32 b = image[4 * y * w + 4 * x + 2]; /* blue */
|
||||
Uint32 a = image[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 */
|
||||
sdl_pixels[(y * screenw + x) / jump] = 65536 * r + 256 * g + b;
|
||||
}
|
||||
|
||||
/* render the pixels to the screen */
|
||||
SDL_UpdateTexture(sdl_texture, NULL, sdl_pixels, pitch);
|
||||
SDL_RenderClear(sdl_renderer);
|
||||
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
|
||||
SDL_RenderPresent(sdl_renderer);
|
||||
|
||||
/* pause until you press escape and meanwhile redraw screen */
|
||||
done = 0;
|
||||
while(done == 0) {
|
||||
while(SDL_PollEvent(&sdl_event)) {
|
||||
if(sdl_event.type == SDL_QUIT) done = 2;
|
||||
else if(SDL_GetKeyboardState(NULL)[SDLK_ESCAPE]) done = 2;
|
||||
else if(sdl_event.type == SDL_KEYDOWN) done = 1; /* press any other key for next image */
|
||||
}
|
||||
SDL_Delay(5); /* pause 5 ms so it consumes less processing power */
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
free(sdl_pixels);
|
||||
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;
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
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 -lSDL2 -O3 -o showpng
|
||||
|
||||
/*
|
||||
LodePNG SDL example
|
||||
This example displays a PNG with a checkerboard pattern to show tranparency.
|
||||
It requires the SDL2 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 <iostream>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
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;
|
||||
|
||||
size_t screenw = w / jump;
|
||||
size_t screenh = h / jump;
|
||||
size_t pitch = screenw * sizeof(Uint32);
|
||||
//init SDL
|
||||
SDL_Window* sdl_window;
|
||||
SDL_Renderer* sdl_renderer;
|
||||
SDL_CreateWindowAndRenderer(screenw, screenh, SDL_WINDOW_OPENGL, &sdl_window, &sdl_renderer);
|
||||
SDL_SetWindowTitle(sdl_window, caption.c_str());
|
||||
if(!sdl_window) {
|
||||
std::cout << "error, no SDL screen" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
SDL_Texture* sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, screenw, screenh);
|
||||
std::vector<Uint32> sdl_pixels(screenw * screenh * sizeof(Uint32));
|
||||
|
||||
//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
|
||||
sdl_pixels[(y * screenw + x) / jump] = 65536 * r + 256 * g + b;
|
||||
}
|
||||
|
||||
// render the pixels to the screen
|
||||
SDL_UpdateTexture(sdl_texture, NULL, sdl_pixels.data(), pitch);
|
||||
SDL_RenderClear(sdl_renderer);
|
||||
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
|
||||
SDL_RenderPresent(sdl_renderer);
|
||||
|
||||
//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_GetKeyboardState(NULL)[SDLK_ESCAPE]) done = 2;
|
||||
else if(event.type == SDL_KEYDOWN) done = 1; //press any other key for next image
|
||||
}
|
||||
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<unsigned char> 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user