libspng
libspng copied to clipboard
Push mode decoding
Introduce a feature similar to libpng's push mode (png_process_data()
), this could implemented on top of the existing codepaths but will require some refactoring to support incremental decoding.
Depends on #38
I've been looking at using libspng to replace libpng in NetSurf and I was about to request progressive decoding when I found this. At the moment we use libpng's png_process_data()
. The use case is a web browser, where we want to make a start on decoding the image as the data arrives, rather than delaying until it has all been fetched entirely.
I think there will need to be some kind of callback when the header has been decoded (and we know the required image pixel dimensions), to let the client allocate the output memory.
A push style API needs to have no callbacks at all because languages that perform I/O inside with coroutines cannot yield from a C callback. It's the only reason I can't replace my Lua ffi binding of libpng with libspng.
Are the callbacks for libpng's push style API optional? How would you know if you reached the start or end of image data, the end of the file, etc?
I'm not sure what you're asking, but I thought about it some more and I decided that progressive loading is just not worth it in 2021, the user experience is worse with progressive loading than without and it complicates programming so I see no wins here.
I'm not sure what you're asking
I'm asking how you're doing I/O with the libpng ffi binding, png_process_data()
itself does not require a callback but I've only seen it used in conjunction with image info / row callbacks, by saying
A push style API needs to have no callbacks at all
do you mean you're not using image info / row callbacks either? I thought for push mode decoding you had to set those with png_set_progressive_read_fn()
.
To be clear, libpng doesn't have a push-style API either, it's all callback based (including png_process_data[1]). When I said "the only reason I can't replace..." what I should've said is "this feature would justify for me the effort of making a new binding and dump libpng". I didn't mean to imply that libpng already has this feature because it doesn't (libjpeg has it).
In any case I think I'll still bind libspng (its simplicity alone is worth it) and just forget about the whole progressive loading thing.
[1] https://refspecs.linuxbase.org/LSB_4.1.0/LSB-Desktop-generic/LSB-Desktop-generic/libpng12.png.process.data.1.html
Would the spng binding also use ffi? I have an incomplete project meant for PUC Lua called spng-lua.
Yes, I only do ffi if I can help it.
I'm not sure what you're asking, but I thought about it some more and I decided that progressive loading is just not worth it in 2021, the user experience is worse with progressive loading than without and it complicates programming so I see no wins here.
For me, progressive loading will be particularly important when APNG is supported. My use case is a web browser. On a slow connection there is no reason to wait to start decoding the first frame of an animation until the entire file has been fetched.
Good point. I wonder if APNG will win the contest for replacing animated gifs though or will it be AVIF or something else? Right now I don't see a clear winner.
Btw, the LuaJIT binding is ready at https://luapower.com/libspng with code at https://github.com/luapower/libspng
At the moment APNG is more widely used and more widely supported.
- https://caniuse.com/apng
- https://caniuse.com/avif