PNG file loading

Started by
4 comments, last by Wolfdog 18 years, 9 months ago
Sorry if this is kind of hard to understand, it is hard to explain: I have been able to load PNG files without the use of any external library(except zlib, because I dont like compression algorithms) the problem I have run into is filtering for images with bit levels that are less then 8. For example in a 32 bit image each sample is 8 bits, 8 red, 8 green, 8 blue, 8 alpha. So they are all one byte, to cycle through them I use an unsigned char buffer. Im just not sure how to cycle through a buffer that every bit is a pixel like a 2 bit image (either black or white). I have been following the documentation about PNG files at http://www.w3.org/TR/PNG/ and it says that filters are applied to bytes (so does this mean bits in this case?). So my question is how can I read it one bit at a time, I was thinking of trying to read one char (8 bits) at a time then try to extract the bits from a char possibly using byte shifting or some use of the & operator. Although this would require that the buffer is aligned to 8 bit boundries (or is this safe to assume anyways?) As you can see im a little stuck here, so any help would be appricated.
Advertisement
Not really graphics related, but anyway: what you have is essentially a bitstream. Individual bits are indeed read by using an appropriate buffer byte offset, and a mask. The latter is and'ed with the buffer value, and shifted by the appropriate number of bits.

But allow me to ask a very simple question: why not use libpng ? It would save you a ton of hassle. Unless you're doing it purely for the fun or the learning experience, writing a custom PNG reader is pretty much a waste of time.
Yea, im doing it just for educational purposes. I figure it would be good to know how the PNG file format works.

I was hoping there would be an easier way perhaps like a bit data type, but oh well I guess it makes sense because fread only takes the number of bytes not bits so it has to be a byte buffer.

Thanks for the help.
If you're trying to do it by hand - yeah, what you mentioned, with bitmasks and bitshifting sounds fine. As for 8 bit alignment, beats me! You'll want to check the specs on png files. Or at least for specific program output to png (then just say you support png files from these programs.)
Btw, so you aren't getting to confused, when you said black or white you said 2 bit image :-) that'd be 1 bpp, not 2 (for black and white).

-Michael g.
I just wrote a PNG loader myself (complete - no zlib or anything :/), but it's unfortunately not as good as libpng. It's still about 5 times slower :).

I'll quote you a little bit from the spec:

Quote:Portable Network Graphics (PNG) Specification (Second Edition)
9.2 Filter types for filter method 0

Filters are applied to bytes, not to pixels, regardless of the bit depth or colour type of the image. The filters operate on the byte sequence formed by a scanline that has been represented as described in 7.2: Scanlines. If the image includes an alpha channel, the alpha data is filtered in the same way as the image data.


Fairly self-explanatory, but the filters are independant of the type of image you are dealing with. That makes things a lot easier :). The whole point of the filters is to rearrange the data into a format that compresses better in the deflate part - that just means the bytes are in more "patterns", or repetition.
Quote:Original post by Thr33d
...bit image :-) that'd be 1 bpp, not 2 (for black and white).

-Michael g.


Your right, I actually was trying to do all of the possible bit depths of png that are less then 8: 1,2,4. So I confused myself writing that out. Although after a few hours of playing around and just guessing it turns out to be a lot easier then I thought.

baldurk you are exactly right I should have read that more closly, for some reason I thought filters applied to pixels not bytes, and it says right there that I was wrong.

So in the end it turns out that it does align to 8 bit boundries, well I guess it does but my program only reads the number of bits required, so im assuming any extra bits are 0 but they are ignored anyways.

Now the only part of PNG loading I have left to finish is the adam 7 interlacing, it doesnt look too hard though. Anyways thank you guys for your help.

This topic is closed to new replies.

Advertisement