static void UnpackV2(byte[] input, byte[] output) { output[output.Length - 1] = input[36]; using (var mem = new MemoryStream(input, 38, input.Length - 38)) using (var bits = new ReverseBitStream(mem)) { for (int dst = 0; dst < output.Length; dst += 2) { if (0 != bits.GetNextBit()) { output[dst + 1] = (byte)bits.GetBits(8); output[dst] = (byte)bits.GetBits(8); } else { int j; for (j = 0; j < 30; j += 2) { if (0 != bits.GetNextBit()) { break; } } output[dst] = input[4 + j]; output[dst + 1] = input[5 + j]; } } } }
static void UnpackV3(byte[] input, byte[] output) { int src = 4; int dst = 0; if (output.Length <= 128) { Buffer.BlockCopy(input, src, output, dst, output.Length); return; } Buffer.BlockCopy(input, src, output, dst, 128); src += 128; dst += 128; using (var mem = new MemoryStream(input, src, input.Length - src)) using (var bits = new ReverseBitStream(mem)) { while (dst < output.Length) { if (0 != bits.GetNextBit()) { int offset = bits.GetBits(7) + 1; int count = bits.GetBits(4) + 2; Binary.CopyOverlapped(output, dst - offset, dst, count); dst += count; } else { output[dst++] = (byte)bits.GetBits(8); } } } }
static void UnpackV1(byte[] input, byte[] output) { int dst = 0; using (var mem = new MemoryStream(input, 4, input.Length - 4)) using (var bits = new ReverseBitStream(mem)) { while (dst < output.Length) { int count = bits.GetBits(4); if (0 != bits.GetNextBit()) { for (int i = 0; i <= count; ++i) { output[dst++] = (byte)bits.GetBits(8); } } else { byte b = (byte)bits.GetBits(8); for (int i = 0; i < count; ++i) { output[dst++] = b; } } } } }