SDL_pnglite got an update: it now loads interlaced pngs.
All what’s missing compared to the PNG spec are 16bpc images and being picky about chunks that it doesn’t use anyway.
The library’s goal is to preserve as much as possible - it saves paletted surfaces as paletted (SDL_image doesn’t), it loads paletted surfaces as such even where SDL_image converts them to some sort of RGB, it is stringent about saving colorkeys, and it doesn’t go into infinite loops where libpng does.
Also there’s a function to see if a file/rwops is a png that you’d like to load.
How does it compare with SDL_stbimage (which is what I use to load PNGs)?
As @lxnt said:
The library’s goal is to preserve as much as possible - it saves paletted surfaces as paletted
SDL_stbimage.h (and SDL_Image) don’t do that, they convert PNGs (and other supported formats) to 24bit RGB or 32bit RGBA (ok, not 100% sure if SDL_Image maybe uses other output formats as well, but probably not paletted).
I guess for most usecases, like accelerated rendering(*) 24/32bit RGB(A) is ok, but if you actually need it in a color paletted format, maybe because you want to swap the palette at runtime or something (probably with
SDL_SetSurfacePalette()) SDL_pnglite is the better choice of course.
(*) Old GPUs, like the 3Dfx Voodoo, supported paletted rendering in hardware (which could save video memory), but as far as I know newer ones do not and even if they expose support for it via OpenGL, the driver will just convert it to RGB(A) data that’s supported by the GPU, so using RGB(A) data directly shouldn’t have any disadvantages.
Yep, it grew from a need to save paletted PNGs to be able to look at the actual palette.
Then there grew a need to load paletted PNGs as is without any library second-guessing you and trashing all the palette information.
As for STB (and also lodepng) - besides the paletted image issue, I just don’t trust people merging old zlib code or outright reimplementing it, especially wrt PNG. It’s bad enough we have libpng.
I don’t think that implementing the inflate algorithm is big black magic that people can’t be trusted to do…
I never had any problems with stb_image and png, but I’m not sure I would use it in cases where it has to process untrusted data (like in a webbrowser).
TBH libpng has such a horrible API that I don’t want to use it (also, using libpng means dragging two additional libs as dependencies into a project, while stb_image is just a single header).
BTW, you mentioned that libpng can run into infinite loops, do you have details on that? As web browsers use libpng this could cause them to lock up?
I’d also like to test how stb_image.h handles those kind of files
Re paletted rendering,
Don’t forget there are projects reimplementing old games which rely on palettes.
1oom (Master of Orion 1) and OpenXcom come to mind. I’m sure much more are out there.
although SDL_pnglite was born out of need to make any sense what was wrong with a Dwarf Fortress linux renderer.
For me, stock ubunti 18.04 libpng 16.24 infiloops on parsing m1-71915ab0b1cc7350091ef7073a312d16.png and m1-7dc9db3d3e510156c619273f8f913cbe.png from google image test suite
I had to rename/remove them so that SDL_image won’t prevent my tests to complete
I guess those old games don’t use PNG though
But it’s definitely cool to have this, so new retro-style projects who want to use paletted rendering (and maybe the corresponding palette swapping tricks) can use PNG.
Thanks for the image names!
ah, you haven’t seen the modding scene.
it’s all paletted png
I didn’t test this with SDL_image, but FWIW Firefox and two image viewers (geeqie and ristretto) on my XUbuntu 18.04 say the files are broken/contain errors instead of running into an infinite loop - maybe SDL_image is doing something wrong there? (Does libpng’s dumb idea of error handling via setjmp into user code play a role here?)
stb_image.h also detects them as broken (=> loading them fails with a normal error): m1-71915ab0b1cc7350091ef7073a312d16.png" gets an “unknown image type” error, for “m1-7dc9db3d3e510156c619273f8f913cbe.png” the error string is “tRNS before PLTE”
Might be local to SDL_image.