Пример #1
0
        public void Initialize()
        {
            Util.Verify(endAddress - startAddress >= 1, startAddress, "Bitstream is empty");

            this.input.BaseStream.Seek(endAddress - 1, SeekOrigin.Begin);
            int lastByte = this.input.ReadByte() & 0xFF;

            Util.Verify(lastByte != 0, endAddress, "Bitstream end mark not present");

            bitsConsumed = Constants.SIZE_OF_LONG - Util.HighestBit(lastByte);

            int inputSize = (int)(endAddress - startAddress);

            if (inputSize >= Constants.SIZE_OF_LONG)
            {              /* normal case */
                this.currentAddress = this.endAddress - Constants.SIZE_OF_LONG;
                this.input.BaseStream.Seek(this.currentAddress, SeekOrigin.Begin);
                this.bits = this.input.ReadInt64();
            }
            else
            {
                this.currentAddress = this.startAddress;
                bits = BitInputStream.ReadTail(this.input, this.startAddress, inputSize);

                bitsConsumed += (Constants.SIZE_OF_LONG - inputSize) * 8;
            }
        }
Пример #2
0
        private void DecodeTail(BinaryReader inputReader, long startAddress, long currentAddress, int bitsConsumed, long bits, BinaryWriter outputWriter, long outputAddress, long outputLimit)
        {
            int tableLog = this.tableLog;

            byte[] numbersOfBits = this.numbersOfBits;
            byte[] symbols       = this.symbols;

            // closer to the end
            while (outputAddress < outputLimit)
            {
                BitInputStreamLoader loader = new BitInputStreamLoader(inputReader, startAddress, currentAddress, bits, bitsConsumed);
                bool done = loader.Load();
                bitsConsumed   = loader.GetBitsConsumed();
                bits           = loader.GetBits();
                currentAddress = loader.GetCurrentAddress();
                if (done)
                {
                    break;
                }

                bitsConsumed = DecodeSymbol(outputWriter, outputAddress++, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
            }

            // not more data in bit stream, so no need to reload
            while (outputAddress < outputLimit)
            {
                bitsConsumed = DecodeSymbol(outputWriter, outputAddress++, bits, bitsConsumed, tableLog, numbersOfBits, symbols);
            }

            Util.Verify(BitInputStream.IsEndOfStream(startAddress, currentAddress, bitsConsumed), startAddress, "Bit stream is not fully consumed");
        }
Пример #3
0
        private static int DecodeSymbol(BinaryWriter outputWriter, long outputAddress, long bitContainer, int bitsConsumed, int tableLog, byte[] numbersOfBits, byte[] symbols)
        {
            int value = (int)BitInputStream.PeekBitsFast(bitsConsumed, bitContainer, tableLog);

            outputWriter.BaseStream.Seek(outputAddress, SeekOrigin.Begin);
            outputWriter.Write(symbols[value]);
            return(bitsConsumed + numbersOfBits[value]);
        }
Пример #4
0
        public static int Decompress(FiniteStateEntropyTable table, BinaryReader inputReader, long inputAddress, long inputLimit, byte[] outputBuffer)
        {
            BinaryWriter outputWriter  = new BinaryWriter(new MemoryStream(outputBuffer));
            long         outputAddress = 0;
            long         outputLimit   = outputAddress + outputBuffer.Length;

            long input  = inputAddress;
            long output = outputAddress;

            // initialize bit stream
            BitInputStreamInitializer initializer = new BitInputStreamInitializer(inputReader, input, inputLimit);

            initializer.Initialize();
            int  bitsConsumed   = initializer.GetBitsConsumed();
            long currentAddress = initializer.GetCurrentAddress();
            long bits           = initializer.GetBits();

            // initialize first FSE stream
            int state1 = (int)BitInputStream.PeekBits(bitsConsumed, bits, table.log2Size);

            bitsConsumed += table.log2Size;

            BitInputStreamLoader loader = new BitInputStreamLoader(inputReader, input, currentAddress, bits, bitsConsumed);

            loader.Load();
            bits           = loader.GetBits();
            bitsConsumed   = loader.GetBitsConsumed();
            currentAddress = loader.GetCurrentAddress();

            // initialize second FSE stream
            int state2 = (int)BitInputStream.PeekBits(bitsConsumed, bits, table.log2Size);

            bitsConsumed += table.log2Size;

            loader = new BitInputStreamLoader(inputReader, input, currentAddress, bits, bitsConsumed);
            loader.Load();
            bits           = loader.GetBits();
            bitsConsumed   = loader.GetBitsConsumed();
            currentAddress = loader.GetCurrentAddress();

            byte[] symbols       = table.symbol;
            byte[] numbersOfBits = table.numberOfBits;
            int[]  newStates     = table.newState;

            // decode 4 symbols per loop
            while (output <= outputLimit - 4)
            {
                int numberOfBits;

                outputWriter.BaseStream.Seek(output, SeekOrigin.Begin);
                outputWriter.Write(symbols[state1]);
                numberOfBits  = numbersOfBits[state1];
                state1        = (int)(newStates[state1] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits));
                bitsConsumed += numberOfBits;

                outputWriter.BaseStream.Seek(output + 1, SeekOrigin.Begin);
                outputWriter.Write(symbols[state2]);
                numberOfBits  = numbersOfBits[state2];
                state2        = (int)(newStates[state2] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits));
                bitsConsumed += numberOfBits;

                outputWriter.BaseStream.Seek(output + 2, SeekOrigin.Begin);
                outputWriter.Write(symbols[state1]);
                numberOfBits  = numbersOfBits[state1];
                state1        = (int)(newStates[state1] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits));
                bitsConsumed += numberOfBits;

                outputWriter.BaseStream.Seek(output + 3, SeekOrigin.Begin);
                outputWriter.Write(symbols[state2]);
                numberOfBits  = numbersOfBits[state2];
                state2        = (int)(newStates[state2] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits));
                bitsConsumed += numberOfBits;

                output += Constants.SIZE_OF_INT;

                loader = new BitInputStreamLoader(inputReader, input, currentAddress, bits, bitsConsumed);
                bool done = loader.Load();
                bitsConsumed   = loader.GetBitsConsumed();
                bits           = loader.GetBits();
                currentAddress = loader.GetCurrentAddress();
                if (done)
                {
                    break;
                }
            }

            while (true)
            {
                Util.Verify(output <= outputLimit - 2, input, "Output buffer is too small");
                outputWriter.BaseStream.Seek(output++, SeekOrigin.Begin);
                outputWriter.Write(symbols[state1]);
                int numberOfBits = numbersOfBits[state1];
                state1        = (int)(newStates[state1] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits));
                bitsConsumed += numberOfBits;

                loader = new BitInputStreamLoader(inputReader, input, currentAddress, bits, bitsConsumed);
                loader.Load();
                bitsConsumed   = loader.GetBitsConsumed();
                bits           = loader.GetBits();
                currentAddress = loader.GetCurrentAddress();

                if (loader.IsOverflow())
                {
                    outputWriter.BaseStream.Seek(output++, SeekOrigin.Begin);
                    outputWriter.Write(symbols[state2]);
                    break;
                }

                Util.Verify(output <= outputLimit - 2, input, "Output buffer is too small");
                outputWriter.BaseStream.Seek(output++, SeekOrigin.Begin);
                outputWriter.Write(symbols[state2]);
                int numberOfBits1 = numbersOfBits[state2];
                state2        = (int)(newStates[state2] + BitInputStream.PeekBits(bitsConsumed, bits, numberOfBits1));
                bitsConsumed += numberOfBits1;

                loader = new BitInputStreamLoader(inputReader, input, currentAddress, bits, bitsConsumed);
                loader.Load();
                bitsConsumed   = loader.GetBitsConsumed();
                bits           = loader.GetBits();
                currentAddress = loader.GetCurrentAddress();

                if (loader.IsOverflow())
                {
                    outputWriter.BaseStream.Seek(output++, SeekOrigin.Begin);
                    outputWriter.Write(symbols[state1]);
                    break;
                }
            }

            return((int)(output - outputAddress));
        }