public int Decode(BitStream32 Buffer, BitStreamCtx ctx)
{
// int numbits = unary.Decode (Buffer, ctx);
// the idea is to replace unary coder by explicit inline code such that (hopefully)
// both "code" and "numbits" are stored into registers
var M = (int)Math.Min (32, Buffer.CountBits - ctx.Offset);
var code = (uint)Buffer.Read (M, ctx);
if ((code & 0x1) == 1) {
ctx.Offset -= M - 1;
return 1;
}
if (code == 0) {
throw new ArgumentException ("Integers larger than 31 bits are not supported by EliasGamma32");
}
int numbits = 0;
// Console.WriteLine ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx ");
// Console.WriteLine ("xxxxx start-read> offset: {0},\t numbits: {1},\t code: {2}", ctx.Offset, numbits, BitAccess.ToAsciiString (code));
while ((code & 0xFF) == 0) {
numbits += 8;
code >>= 8;
}
if ((code & 0xF) == 0) {
numbits += 4;
code >>= 4;
}
while ((code & 0x1) == 0) {
numbits += 1;
code >>= 1;
}
code >>= 1;
// Console.WriteLine ("xxxxx unary-read> offset: {0},\t numbits: {1},\t code: {2}", ctx.Offset, numbits, BitAccess.ToAsciiString (code));
if (numbits >= 16) {
int in_cache = M - 1 - numbits;
code |= ((uint)Buffer.Read (numbits - in_cache, ctx)) << in_cache;
} else {
ctx.Offset -= M - ((numbits << 1) + 1);
code &= (1u << numbits) - 1;
}
// Console.WriteLine ("xxxxx final-read0> offset: {0},\t numbits: {1},\t code: {3},\t number: {2}", ctx.Offset, numbits, code, BitAccess.ToAsciiString (code));
code |= (1u << numbits);
// Console.WriteLine ("xxxxx final-read1> offset: {0},\t numbits: {1},\t code: {3},\t number: {2}", ctx.Offset, numbits, code, BitAccess.ToAsciiString (code));
return (int)code;
}