private static void DecodeInternal(Stream source, Stream destination, ref long decompressedBytes) { UInt8_NE_H_InputBitStream bitStream = new UInt8_NE_H_InputBitStream(source); for (; ;) { if (bitStream.Pop()) { NeutralEndian.Write1(destination, NeutralEndian.Read1(source)); ++decompressedBytes; } else { long count = 0; long offset = 0; if (bitStream.Pop()) { byte high = NeutralEndian.Read1(source); byte low = NeutralEndian.Read1(source); count = high & 0x07; if (count == 0) { count = NeutralEndian.Read1(source); if (count == 0) { break; } count += 9; } else { count = 10 - count; } offset = ~0x1FFFL | ((0xF8 & high) << 5) | low; } else { offset = NeutralEndian.Read1(source); offset |= ~0xFFL; byte low = Convert.ToByte(bitStream.Pop()); byte high = Convert.ToByte(bitStream.Pop()); count = (low << 1 | high) + 2; } 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; } } }
private void CheckBuffer() { if (this.remainingBits == 0) { this.byteBuffer = NeutralEndian.Read1(stream); this.remainingBits = 8; } }
public UInt8_E_L_InputBitStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } this.stream = stream; this.remainingBits = 8; this.byteBuffer = NeutralEndian.Read1(stream); }
public override byte Read(int count) { this.CheckBuffer(); if (this.remainingBits < count) { int delta = count - this.remainingBits; byte lowBits = (byte)(this.byteBuffer << delta); this.byteBuffer = NeutralEndian.Read1(stream); this.remainingBits = 8 - delta; ushort highBits = (byte)(this.byteBuffer >> this.remainingBits); this.byteBuffer ^= (byte)(highBits << this.remainingBits); return((byte)(lowBits | highBits)); } this.remainingBits -= count; byte bits = (byte)(this.byteBuffer >> this.remainingBits); this.byteBuffer ^= (byte)(bits << this.remainingBits); return(bits); }
private static void DecodeHeader(Stream input, Stream output, DecodingCodeTreeNode codeTree) { byte outputValue = 0; byte inputValue; // Loop until a byte with value 0xFF is encountered while ((inputValue = NeutralEndian.Read1(input)) != 0xFF) { if ((inputValue & 0x80) != 0) { outputValue = (byte)(inputValue & 0xF); inputValue = NeutralEndian.Read1(input); } codeTree.SetCode( NeutralEndian.Read1(input), inputValue & 0xF, new NibbleRun(outputValue, (byte)(((inputValue & 0x70) >> 4) + 1))); } // Store a special nibble run for inline RLE sequences (code = 0b111111, length = 6) // Length = 0xFF in the nibble run is just a marker value that will be handled specially in DecodeInternal codeTree.SetCode(0x3F, 6, new NibbleRun(0, 0xFF)); }
private static void Decode(Stream input, Stream output, long size) { long end = input.Position + size; UInt8_NE_L_InputBitStream bitStream = new UInt8_NE_L_InputBitStream(input); List <byte> outputBuffer = new List <byte>(); while (input.Position < end) { if (bitStream.Pop()) { if (input.Position >= end) { break; } outputBuffer.Add(NeutralEndian.Read1(input)); } else { if (input.Position >= end) { break; } int offset = NeutralEndian.Read1(input); if (input.Position >= end) { break; } byte count = NeutralEndian.Read1(input); // We've just read 2 bytes: %llllllll %hhhhcccc // offset = %hhhhllllllll + 0x12, count = %cccc + 3 offset |= (ushort)((count & 0xF0) << 4); offset += 0x12; offset &= 0xFFF; offset |= (ushort)(outputBuffer.Count & 0xF000); count &= 0xF; count += 3; if (offset >= outputBuffer.Count) { offset -= 0x1000; } outputBuffer.AddRange(new byte[count]); if (offset < 0) { // Zero-fill for (int destinationIndex = outputBuffer.Count - count; destinationIndex < outputBuffer.Count; ++destinationIndex) { outputBuffer[destinationIndex] = 0; } } else { // Dictionary reference if (offset < outputBuffer.Count) { for (int sourceIndex = offset, destinationIndex = outputBuffer.Count - count; destinationIndex < outputBuffer.Count; sourceIndex++, destinationIndex++) { outputBuffer[destinationIndex] = outputBuffer[sourceIndex]; } } } } } byte[] bytes = outputBuffer.ToArray(); output.Write(bytes, 0, bytes.Length); }
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); } } } } }