Example #1
0
        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;
                }
            }
        }
Example #2
0
 private void CheckBuffer()
 {
     if (this.remainingBits == 0)
     {
         this.byteBuffer    = NeutralEndian.Read1(stream);
         this.remainingBits = 8;
     }
 }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }
Example #6
0
        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);
        }
Example #7
0
        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);
                        }
                    }
                }
            }
        }