libpng's complexity

libpng is the reference implementation of the PNG file format, which has become quite popular during the last decade thanks to the benefits of lossless compression coupled with multiple storage formats — including indexed pixmaps, RGB pixmaps with optional alpha channel, or 256 grayscale colors, adding Adam7 interlacing as an option to allow displaying incomplete drafts of images before reading all the pixmap data in the stream. It also allows for some metadata such as text comments and internal timestamps, or even unknown chunks of (meta)data, allowing it to become a container format of sorts, most infamously abused by Mozilla Firefox to implement animated PNGs through a slightly modified version of the library — because lossless RGB pixmaps with alpha transparency are so cool compared to indexed pixmaps with binary opacity...

As cool as this sounds, libpng by itself is a trap for the unexperienced and/or impatient programmer, of which I fall into the latter category.

The API allows for many different applications, resulting in a convoluted interface and some poor or missing documentation for it. Reading the manual and examples included with it does not help a lot; when skimming through the header one can find some undocumented interfaces. It's a hell of flexibility that makes me feel lost in middle of a big forest without a map.

I foolishly wrote Wesnoth-TC without knowing any of this beforehand, and ended up creating a monster known as version 1.0, which is a mess of quickly crafted ugly code that breaks under big-endian platforms and leaves huge memory leaks when running on anything. I could have used a different library but I didn't have more documentation than libpng's at the time. Now that I'm preparing to release Wesnoth-TC 1.5.0 and have learned to keep away from this library, I'm turning my attention to wrapper libraries that should be hopefully much easier to work with if I just want to read and write ARGB streams from/to PNG files.

But Wesnoth-TC 1.5.0 will still use libpng, although I'll rewrite the code that uses it. Why? Because this time, it's personal.