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 ended up writing my own, so here they are.
The BinaryWriter (I've only overridden the ones that I needed)
private class BinaryWriter : System.IO.BinaryWriter
{
private bool[] curByte = new bool[8];
private byte curBitIndx = 0;
private System.Collections.BitArray ba;
public BinaryWriter(Stream s) : base(s) { }
public override void Flush()
{
base.Write(ConvertToByte(curByte));
base.Flush();
}
public override void Write(bool value)
{
curByte[curBitIndx] = value;
curBitIndx++;
if (curBitIndx == 8)
{
base.Write(ConvertToByte(curByte));
this.curBitIndx = 0;
this.curByte = new bool[8];
}
}
public override void Write(byte value)
{
ba = new BitArray(new byte[] { value });
for (byte i = 0; i < 8; i++)
{
this.Write(ba[i]);
}
ba = null;
}
public override void Write(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
this.Write((byte)buffer[i]);
}
}
public override void Write(uint value)
{
ba = new BitArray(BitConverter.GetBytes(value));
for (byte i = 0; i < 32; i++)
{
this.Write(ba[i]);
}
ba = null;
}
public override void Write(ulong value)
{
ba = new BitArray(BitConverter.GetBytes(value));
for (byte i = 0; i < 64; i++)
{
this.Write(ba[i]);
}
ba = null;
}
public override void Write(ushort value)
{
ba = new BitArray(BitConverter.GetBytes(value));
for (byte i = 0; i < 16; i++)
{
this.Write(ba[i]);
}
ba = null;
}
private static byte ConvertToByte(bool[] bools)
{
byte b = 0;
byte bitIndex = 0;
for (int i = 0; i < 8; i++)
{
if (bools[i])
{
b |= (byte)(((byte)1) << bitIndex);
}
bitIndex++;
}
return b;
}
}
And, the BinaryReader, once again, I've only overridden the methods that I needed.
private class BinaryReader : System.IO.BinaryReader
{
private bool[] curByte = new bool[8];
private byte curBitIndx = 0;
private BitArray ba;
public BinaryReader(Stream s) : base(s)
{
ba = new BitArray(new byte[] { base.ReadByte() });
ba.CopyTo(curByte, 0);
ba = null;
}
public override bool ReadBoolean()
{
if (curBitIndx == 8)
{
ba = new BitArray(new byte[] { base.ReadByte() });
ba.CopyTo(curByte, 0);
ba = null;
this.curBitIndx = 0;
}
bool b = curByte[curBitIndx];
curBitIndx++;
return b;
}
public override byte ReadByte()
{
bool[] bar = new bool[8];
byte i;
for (i = 0; i < 8; i++)
{
bar[i] = this.ReadBoolean();
}
byte b = 0;
byte bitIndex = 0;
for (i = 0; i < 8; i++)
{
if (bar[i])
{
b |= (byte)(((byte)1) << bitIndex);
}
bitIndex++;
}
return b;
}
public override byte[] ReadBytes(int count)
{
byte[] bytes = new byte[count];
for (int i = 0; i < count; i++)
{
bytes[i] = this.ReadByte();
}
return bytes;
}
public override ushort ReadUInt16()
{
byte[] bytes = ReadBytes(2);
return BitConverter.ToUInt16(bytes, 0);
}
public override uint ReadUInt32()
{
byte[] bytes = ReadBytes(4);
return BitConverter.ToUInt32(bytes, 0);
}
public override ulong ReadUInt64()
{
byte[] bytes = ReadBytes(8);
return BitConverter.ToUInt64(bytes, 0);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With