Example #1
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);
                        }
                    }
                }
            }
        }
Example #2
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;
                }
            }
        }