Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lvandeve/lodepng.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLode <lvandeve@gmail.com>2022-05-29 01:49:56 +0300
committerLode <lvandeve@gmail.com>2022-05-29 01:49:56 +0300
commit3d9fda048393e32cc11d0c3d3caba0a85c1c2dfe (patch)
tree358d6cc4873a95a4dffde8b79a60c27f00a98d54
parent5601b8272a6850b7c5d693dd0c0e16da50be8d8d (diff)
migrate examples from SDL to SDL2, and fixes to utilities
-rw-r--r--examples/example_sdl.c88
-rw-r--r--examples/example_sdl.cpp37
-rw-r--r--lodepng_benchmark.cpp4
-rw-r--r--lodepng_unittest.cpp4
-rw-r--r--lodepng_util.cpp16
-rw-r--r--pngdetail.cpp31
6 files changed, 91 insertions, 89 deletions
diff --git a/examples/example_sdl.c b/examples/example_sdl.c
index 874bc4c..e2c58c1 100644
--- a/examples/example_sdl.c
+++ b/examples/example_sdl.c
@@ -25,31 +25,36 @@ freely, subject to the following restrictions:
/*
Compile command for Linux:
-gcc lodepng.c example_sdl.c -ansi -pedantic -Wall -Wextra -lSDL -O3 -o showpng
+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 SDL library to compile and run.
+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 <SDL/SDL.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;
- SDL_Surface* scr;
- SDL_Event event;
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);
@@ -62,62 +67,65 @@ int show(const char* filename) {
return 0;
}
- /*avoid too large window size by downscaling large image*/
-
+ /* 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");
+ 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;
}
- scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE);
- if(!scr) {
- printf("Error, no SDL screen\n");
+ 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;
}
- SDL_WM_SetCaption(filename, NULL); /*set window caption*/
- /*plot the pixels of the PNG file*/
+ /* 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));
+ /* 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*/
- bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump);
- *bufp = 65536 * r + 256 * g + b;
+ /* give the color value to the pixel of the screenbuffer */
+ sdl_pixels[(y * screenw + x) / jump] = 65536 * r + 256 * g + b;
}
- /*pause until you press escape and meanwhile redraw screen*/
- done = 0;
+ /* 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 */
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*/
+ 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_UpdateRect(scr, 0, 0, 0, 0); /*redraw screen*/
- SDL_Delay(5); /*pause 5 ms so it consumes less processing power*/
+ SDL_Delay(5); /* pause 5 ms so it consumes less processing power */
}
- /*cleanup*/
- free(image);
SDL_Quit();
+ free(sdl_pixels);
return done == 2 ? 1 : 0;
}
diff --git a/examples/example_sdl.cpp b/examples/example_sdl.cpp
index dc7dee2..ac964cf 100644
--- a/examples/example_sdl.cpp
+++ b/examples/example_sdl.cpp
@@ -24,12 +24,12 @@ freely, subject to the following restrictions:
*/
//Compile command for Linux:
-//g++ lodepng.cpp example_sdl.cpp -lSDL -O3 -o showpng
+//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 SDL library to compile and run.
+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.
*/
@@ -37,7 +37,7 @@ Press any key to see next image, or esc to quit.
#include "lodepng.h"
#include <iostream>
-#include <SDL/SDL.h>
+#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
@@ -45,17 +45,21 @@ int show(const std::string& caption, const unsigned char* rgba, unsigned w, unsi
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
- 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) {
+ 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_WM_SetCaption(caption.c_str(), NULL); //set window caption
+ 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)
@@ -73,21 +77,24 @@ int show(const std::string& caption, const unsigned char* rgba, unsigned w, unsi
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;
+ 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_GetKeyState(NULL)[SDLK_ESCAPE]) 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_UpdateRect(scr, 0, 0, 0, 0); //redraw screen
SDL_Delay(5); //pause 5 ms so it consumes less processing power
}
diff --git a/lodepng_benchmark.cpp b/lodepng_benchmark.cpp
index 09b2f5b..144d8b1 100644
--- a/lodepng_benchmark.cpp
+++ b/lodepng_benchmark.cpp
@@ -37,7 +37,7 @@ freely, subject to the following restrictions:
#include <stdio.h>
#include <stdlib.h>
-#include <SDL/SDL.h> //SDL is used for timing.
+#include <SDL2/SDL.h> //SDL is used for timing.
bool apply_mods = false;
@@ -127,7 +127,7 @@ std::vector<unsigned char> testEncode(Image& image) {
if(apply_mods) {
//state.encoder.filter_strategy = LFS_ZERO;
//state.encoder.filter_strategy = LFS_ENTROPY;
- state.encoder.filter_strategy = LFS_FOUR;
+ //state.encoder.filter_strategy = LFS_FOUR;
//state.encoder.zlibsettings.btype = 0;
//state.encoder.zlibsettings.btype = 1;
//state.encoder.auto_convert = 0;
diff --git a/lodepng_unittest.cpp b/lodepng_unittest.cpp
index a5dca86..91fcdfa 100644
--- a/lodepng_unittest.cpp
+++ b/lodepng_unittest.cpp
@@ -47,7 +47,7 @@ mv lodepng.cpp lodepng.c ; gcc -I ./ lodepng.c examples/example_decode.c -pedant
*) test other compilers
*) try lodepng_benchmark.cpp
-g++ lodepng.cpp lodepng_benchmark.cpp -Werror -Wall -Wextra -pedantic -ansi -lSDL -O3 && ./a.out testdata/corpus/''*
+g++ lodepng.cpp lodepng_benchmark.cpp -Werror -Wall -Wextra -pedantic -ansi -lSDL2 -O3 && ./a.out testdata/corpus/''*
*) try the fuzzer
clang++ -fsanitize=fuzzer -DLODEPNG_MAX_ALLOC=100000000 lodepng.cpp lodepng_fuzzer.cpp -O3 -o fuzzer && ./fuzzer
@@ -115,7 +115,7 @@ rm *.o *.obj
*) check year in copyright message at top of all files as well as at bottom of lodepng.h
*) check examples/sdl.cpp with the png test suite images (the "x" ones are expected to show error)
-g++ -I ./ lodepng.cpp examples/example_sdl.cpp -Werror -Wall -Wextra -pedantic -ansi -O3 -lSDL -o showpng && ./showpng testdata/PngSuite/''*.png
+g++ -I ./ lodepng.cpp examples/example_sdl.cpp -Werror -Wall -Wextra -pedantic -ansi -O3 -lSDL2 -o showpng && ./showpng testdata/PngSuite/''*.png
*) strip trailing spaces and ensure consistent newlines
diff --git a/lodepng_util.cpp b/lodepng_util.cpp
index 574138a..1d76b35 100644
--- a/lodepng_util.cpp
+++ b/lodepng_util.cpp
@@ -273,15 +273,12 @@ void* lodepng_malloc(size_t size);
void lodepng_free(void* ptr);
#endif /*LODEPNG_COMPILE_ALLOCATORS*/
-/* avoid needing <float.h> for FLT_MAX. This assumes IEEE 32-bit float. */
-static const float lodepng_flt_max = 3.40282346638528859811704183484516925e38f;
-
/* define infinity and NaN in a way compatible with ANSI C90 (no INFINITY or NAN macros) yet also with visual studio */
-/* visual studio doesn't allow division through a zero literal, but allows it through non-const variable set to zero */
+/* visual studio doesn't allow division through a zero literal, but allows it through public non-const variable set to zero */
float lodepng_flt_zero_ = 0.0f;
static const float lodepng_flt_inf = 1.0f / lodepng_flt_zero_; /* infinity */
static const float lodepng_flt_nan = 0.0f / lodepng_flt_zero_; /* not a number */
-
+static const float lodepng_flt_max = 3.40282346638528859811704183484516925e38f; /* avoid needing <float.h> for FLT_MAX. This assumes IEEE 32-bit float. */
/* powf polyfill, 5-6 digits accurate, 33-80% slower than powf, assumes IEEE
32-bit float, but other than that multiplatform and no math lib needed
@@ -291,15 +288,14 @@ static float lodepng_powf(float x, float y) {
int i = 0;
/* handle all the special floating point rules */
if(x == 1 || y == 0) return 1; /*these cases return 1 even if the other value is NaN, as specified*/
- if(y == 1) return x;
- if(!(x > 0 && x <= lodepng_flt_max && y == y && y <= lodepng_flt_max && y >= -lodepng_flt_max)) {
- if(y == 1) return x; /* preserves negative-0 */
+ if(y == 1) return x; /* preserves negative-0 */
+ if(!(x > 0 && x <= lodepng_flt_max && y >= -lodepng_flt_max && y <= lodepng_flt_max)) { /*all special cases*/
if(x != x || y != y) return x + y; /* nan */
if(x > 0) {
if(x > lodepng_flt_max) return y <= 0 ? (y == 0 ? 1 : 0) : x; /* x = +infinity */
} else {
if(!(y < -1073741824.0f || y > 1073741824.0f)) { /* large y always even integer, but cast would overflow */
- i = (int)y;
+ i = (int)y; /* not using floor: not using math lib */
if(i != y) {
return (x < -lodepng_flt_max) ? (y < 0 ? 0 : lodepng_flt_inf) :
(x == 0 ? (y < 0 ? lodepng_flt_inf : 0) : lodepng_flt_nan);
@@ -312,7 +308,7 @@ static float lodepng_powf(float x, float y) {
-lodepng_flt_inf : lodepng_flt_inf);
}
x = -x;
- if(x == 1) return 1;
+ if(x == 1) return 1; /* under the C++ rules, pow(-1, +/- infinity) also returns 1 */
}
if(y < -lodepng_flt_max || y > lodepng_flt_max) return ((x < 1) != (y > 0)) ? (y < 0 ? -y : y) : 0;
}
diff --git a/pngdetail.cpp b/pngdetail.cpp
index 9e6ffbb..a88a123 100644
--- a/pngdetail.cpp
+++ b/pngdetail.cpp
@@ -64,9 +64,9 @@ void showHelp() {
"E.g. 'pngdetail image.png -plc' to show png info, palette info and chunks\n"
"Options:\n"
"-o: show header summary on one line\n"
- "-h: show header info\n"
+ "-H: show header info\n"
"-p: show PNG file info\n"
- "-e: check the PNG for errors or warnings\n"
+ "-e: analyze errors or warnings\n"
"-i: show ICC profile details (if any)\n"
"-I: show ICC profile bytes\n"
"--format=<format>: display mode for -I:\n"
@@ -93,7 +93,7 @@ void showHelp() {
"-v: be more verbose\n"
"-t: expand long texts\n"
"-x: print most integer numbers in hexadecimal (includes e.g. year, num unique colors, ...)\n"
- "-?, --help: show this help" << std::endl;
+ "-?, --help, -h: show this help" << std::endl;
}
enum RenderMode {
@@ -167,7 +167,7 @@ struct Data {
bool inspected;
bool is_icc; // the file is a raw icc file, not a PNG, only -i and -I are useful
- Data(const std::string& filename) : filename(filename), error(0), inspected(false) {}
+ Data(const std::string& filename) : filename(filename), error(0), inspected(false), is_icc(false) {}
// Load the file if not already loaded
@@ -218,6 +218,8 @@ struct Data {
if(!end) end = data + buffer.size(); // no IDAT, invalid PNG but extract info anyway
inspect_chunk_by_name(data, end, state, "PLTE");
if(error) return;
+ inspect_chunk_by_name(data, end, state, "tRNS");
+ if(error) return;
inspect_chunk_by_name(data, end, state, "cHRM");
if(error) return;
inspect_chunk_by_name(data, end, state, "gAMA");
@@ -924,7 +926,7 @@ void loadWithErrorRecovery(Data& data, const Options& options, bool show_errors_
void showSingleLineSummary(Data& data, const Options& options) {
data.loadInspect();
- if(data.error) return;
+ if(data.error && data.error != 57) return; // CRC error (57) ignored here for parsing of header only
std::cout << (options.use_hex ? std::hex: std::dec);
std::cout << "Filesize: " << data.buffer.size() << " (" << data.buffer.size() / 1024 << "K)";
if(data.is_icc) {
@@ -932,7 +934,6 @@ void showSingleLineSummary(Data& data, const Options& options) {
return;
}
-
std::cout << ", " << data.w << "x" << data.h << ", ";
std::cout << "Color: " << colorTypeString(data.state.info_png.color.colortype) << ", " << data.state.info_png.color.bitdepth << " bit" << std::endl;
}
@@ -1352,12 +1353,8 @@ int main(int argc, char *argv[]) {
if(s != "-x" && s != "-v" && s != "-t") options_chosen = true;
for(size_t j = 1; j < s.size(); j++) {
char c = s[j];
- if(c == '?') {
- showHelp();
- return 0;
- }
- else if(c == 'o') options.show_one_line_summary = true;
- else if(c == 'h') options.show_header = true;
+ if(c == 'o') options.show_one_line_summary = true;
+ else if(c == 'H') options.show_header = true;
else if(c == 'i') options.show_icc_details = true;
else if(c == 'I') options.show_icc_hex = true;
else if(c == 'v') options.verbose = true;
@@ -1384,14 +1381,8 @@ int main(int argc, char *argv[]) {
else if(c == 'x') {
options.use_hex = true;
std::cout << std::hex;
- }
- else if(c == '-') {
- if(s != "--help") std::cout << "Unknown flag: " << s << ". Use -h for help" << std::endl;
- showHelp();
- return 0;
- }
- else {
- std::cout << "Unknown flag: " << c << ". Use -h for help" << std::endl;
+ } else {
+ if(s != "--help" && c != 'h' && c != '?') std::cout << "Unknown flag: " << c << ". Use -h for help" << std::endl;
showHelp();
return 0;
}