01-10-09 - Simple Image

libPNG is such overcomplicated shizzle. I could easily make a little image format that was just BMP with a LZ that was like maybe 1000 lines of code and just put it in a header, STB style. Hell I could toss in a lossy wavelet image coder for another 1000 lines of code. It wouldn't be the best in the world, but it would be good enough and super simple. Unfortunately I guess there's no point cuz it's not a standard and whatnot. (Using arithcoding instead of Huffman is part of what could make both of those so easy to write).

WIC is obviously a good thing in theory - it's sillythat every app has its own image readers & writers (I mean Amiga OS did this perfectly back in 1892 so get with the last century bitches). On the other hand, the fact that it's closed source and MS-only and in fact requires .NET 3.5 makes it pretty much ass.

A simple open-source multi-platform generic image IO library that's based on pluggable components and supports every format is such an obvious thing that we should have. It should be super simple C. You shouldn't have to recompile apps to get new plug-ins, so it should be DLL's in a dir in Windows and whatever similar thing on other OS'es. (but you should also easily be able to just compile all the plug-ins into your app as a static lib if you want to do that).

One thing that mucks it up is that many of the image formats allow all kinds of complicated nonsense in them, and if you want to support all that then your API starts getting really complicated and ugly. Personally I'm inclined to only support rectangular bit-plane images (eg. N components, each component is B bits, and they are interleaved in one of a handful of simple ways, like ABCABC or AAABBBCCC ).

All compressors unfortunately have this problem that they start off super simple but become huge messes when you add lots of features.

ADDENDUM : Oh fucking cock hole. I put a PNG loader in my image thing and now all my apps depend on libPNG.dll and zlib.dll , so I have to distribute those with every damn exe, and worry about dll's being in path and so on. They also cause failures at startup if they're not found, when really they should just fail if I actually try to load a PNG. (of course I could do that by doing LoadLibrary by hand and querying for the functions, but I have to call like 100 functions to load a PNG so doing that would be a pain). Urg bother.


NeARAZ said...

stb_image.h to the rescue?

Michael said...

I recently hit this -- just switching the dll projects over to static libs (so I could forget about dll delivery) worked for me.

Also, windows GDI+ provides png/jpg bitmap class so I'm using it for now; and there's a mac equiv for my other platforms.

cbloom said...

Yeah, switching to static libs is better, though libpng doesn't ship a static lib so I have to build their project (fingers crossed), and it also sucks cuz I make a whole bunch of tiny command line utils like "crop" , "resize" , etc. and now they'll all be 250k

Hmm.. it seems like you should be able to "link in a DLL" , like actually grab the code out of the DLL at link time and turn it into a static linkage, is that possible?

... STB_image is totally almost awesome. I didn't realize he had PNG in there too or I would've just used that instead of getting into libpng at all. However, it doesn't really fix the retarded overcomplex format - he just supports a simple subset of PNG which is a little bit disturbing to me.

nothings said...

Since I added interlaced support, I think these days the only PNG restriction in stb_image is 8-bit depth. I guess it wouldn't be that hard to add 1/2/4-bit unpacking, but you just don't find those in the wild very much anyway (since it compresses on bytes with an arithmetic-y prediction, it's not going to work very well for bit-packed stuff, I think... although that's already true for paletted stuff too).

I recently hit this -- just switching the dll projects over to static libs (so I could forget about dll delivery) worked for me.

Just be careful of what libs you do this with, since LGPL libs require shipping as DLLs. (I guess this isn't true for zlib and libpng, at least, so it does work in this case.)

Sam said...

I too have used GDI+ which should be pretty much automatically available everywhere (so one less DLL to think about). It's a bit of mucking around because you have to create a bunch of crap to just copy the data out into a char array (create a stream, GlobalAlloc a buffer, etc) but at least you don't have to distribute extra DLLs (though of course then it's not linked into your binary).

old rants