// more complex 1 or 2 bit header (possible values are 1b, 01b and 00b) smallest header used for most common // length range where bits <= 16 static void Example2_2Divisions() { MemoryStream packedData = new MemoryStream(); BitStreamWriter bitWriter = new BitStreamWriter(); const int MAX_BITS = 32; const int MED_BITS = 16; const int MIN_BITS = 13; // let's pack them into a stream! foreach (uint v in values) { uint size = CountBits(v); // if there are 16 bits or fewer, write only 16+1 bits if (size <= MED_BITS) { if (size <= MIN_BITS) { bitWriter.WriteBits(1, 1, packedData); bitWriter.WriteBits(v, MIN_BITS, packedData); } else { bitWriter.WriteBits(2, 2, packedData); bitWriter.WriteBits(v, MED_BITS, packedData); } } else { bitWriter.WriteBits(0, 2, packedData); bitWriter.WriteBits(v, MAX_BITS, packedData); } } bitWriter.WriteFlush(packedData); Console.WriteLine("Original size = {0}, packed size = {1}", values.Length * sizeof(uint), packedData.Length); // now read the data back // // rewind our stream so we can read it back packedData.Seek(0, SeekOrigin.Begin); BitStreamReader bitReader = new BitStreamReader(); uint[] output = new uint[values.Length]; for (int i = 0; i < output.Length; ++i) { uint header = bitReader.ReadBits(1, packedData); switch (header) { case 1: output[i] = bitReader.ReadBits(MIN_BITS, packedData); break; // if the bit is 0, there is a second bit with length subsections case 0: uint secondBit = bitReader.ReadBits(1, packedData); if (secondBit == 0) { output[i] = bitReader.ReadBits(MAX_BITS, packedData); } else { output[i] = bitReader.ReadBits(MED_BITS, packedData); } break; } if (output[i] == values[i]) { Console.WriteLine("Position {0} matches!", i); } } }