private static void Decode(Stream input, Stream output, Endianness endianness) { using (PaddedStream paddedInput = new PaddedStream(input, 2, PaddedStreamMode.Read)) { byte packetLength = NeutralEndian.Read1(paddedInput); var readBitfield = GetBitfieldReader(NeutralEndian.Read1(paddedInput)); ushort incrementingValue; ushort commonValue; InputBitStream <ushort> bitStream; Action <Stream, ushort> write2; if (endianness == Endianness.BigEndian) { incrementingValue = BigEndian.Read2(paddedInput); commonValue = BigEndian.Read2(paddedInput); bitStream = new UInt16BE_E_L_InputBitStream(paddedInput); write2 = Write2BE; } else { incrementingValue = LittleEndian.Read2(paddedInput); commonValue = LittleEndian.Read2(paddedInput); bitStream = new UInt16LE_E_L_InputBitStream(paddedInput); write2 = Write2LE; } // Loop until the end-of-data marker is found (if it is not found before the end of the stream, UInt8InputBitStream // will throw an exception) for (; ;) { if (bitStream.Get()) { int mode = bitStream.Read(2); int count = bitStream.Read(4); switch (mode) { case 0: case 1: { ushort flags = readBitfield(bitStream); ushort outv = (ushort)(bitStream.Read(packetLength) | flags); do { write2(output, outv); outv += (ushort)mode; } while (--count >= 0); } break; case 2: mode = -1; goto case 0; case 3: { // End of compressed data if (count == 0xf) { return; } do { ushort flags = readBitfield(bitStream); ushort outv = bitStream.Read(packetLength); write2(output, (ushort)(outv | flags)); } while (--count >= 0); } break; } } else { bool mode = bitStream.Get(); int count = bitStream.Read(4); if (mode) { do { write2(output, commonValue); } while (--count >= 0); } else { do { write2(output, incrementingValue++); } while (--count >= 0); } } } } }
private static void DecodeInternal(Stream source, Stream destination, ref long decompressedBytes) { UInt16LE_E_L_InputBitStream bitStream = new UInt16LE_E_L_InputBitStream(source); for (; ;) { if (bitStream.Pop()) { NeutralEndian.Write1(destination, NeutralEndian.Read1(source)); ++decompressedBytes; } else { long count = 0; long offset = 0; if (bitStream.Pop()) { byte low = NeutralEndian.Read1(source); byte high = NeutralEndian.Read1(source); count = high & 0x07; if (count == 0) { count = NeutralEndian.Read1(source); if (count == 0) { break; } if (count == 1) { continue; } } else { ++count; } offset = ~0x1FFFL | ((0xF8 & high) << 5) | low; } else { byte low = Convert.ToByte(bitStream.Pop()); byte high = Convert.ToByte(bitStream.Pop()); count = (low << 1 | high) + 1; offset = NeutralEndian.Read1(source); offset |= ~0xFFL; } for (long i = 0; i <= count; i++) { long writePosition = destination.Position; destination.Seek(writePosition + offset, SeekOrigin.Begin); byte b = NeutralEndian.Read1(destination); destination.Seek(writePosition, SeekOrigin.Begin); NeutralEndian.Write1(destination, b); } decompressedBytes += count + 1; } } }