I'm working on a bit-based B/W/Greyscale Pre-Compiled font format, and was having issues with either reading or writing the format, (I've not been able to determine where the issue was. (I do have a B/W bit-based version working, but an Aliased font doesn't look too good, as you can imagine, especially when working with a 320x200 pixel screen) ) but decided that just using a BinaryWriter would be much easier than writing to a bool[] when I pulled the image data.
The basic format of a pixel in the file looks like this:
1 - White Pixel (Shortest, as this would be most of the pixels)
00 - Black Pixel (No reason to write 10-bits for a pure black pixel, which there are a reasonable number of)
01 - Greyscale Pixel, and is followed by 1 byte describing the shade of the pixel
Now, everything is fine and dandy with writing the required info, as that's all full bytes, but the default .Net 4.0 BinaryWriter writes a Boolean value as a full byte, and as you can imagine, that negates the use of a bit-based format. So I was wondering, is there a BinaryWriter, (and BinaryReader) implementation out there that's bit-based
Edit: I ended up creating my own. (See the answer for the code.)
I don't believe there's anything in the framework for this, no. Basically you'd need to write a class to wrap a
BinaryWriter
(or just a stream) and "the byte written so far" and the number of bits written. When the number of bits gets to 8, write the byte to the underlying stream and clear.EDIT: the OP posted a possible and working implementation of the above suggestion below.
I found myself in need of this as well, so I built upon OP and filled in all the read/writes (except char & string since those are a bit special).
I also made a quick unit test try it out. For streams containing only boolean (or other custom sub-byte value types) it's obviously 87.5% cheaper, and for a random mixed stream containing 75% boolean values, it was about 33% cheaper. So could be useful for some scenarios.
Here are the both classes in case anyone else needs them, use at your own risk:
And the unit tests:
If you keep your data in a byte array (bools are of no use and take too much space, if you use them for bits, they take up a byte in memory) or in an array of a particular
struct
that fits your dataformat.Once you have an internal memory representation, you don't need a bit-based binary writer anymore. You can simply write the data to a BinaryWriter and you're done with it.
The reason for this is: the bool is, by definition, of 1 byte size in C#. The BinaryWriter simply writes what you give it.
I ended up writing my own, so here they are.
The BinaryWriter (I've only overridden the ones that I needed)
And, the BinaryReader, once again, I've only overridden the methods that I needed.