Esempio n. 1
0
        private static void DecodeBlockTypeAndLength(iText.IO.Codec.Brotli.Dec.State state, int treeType)
        {
            iText.IO.Codec.Brotli.Dec.BitReader br = state.br;
            int[] ringBuffers = state.blockTypeRb;
            int   offset      = treeType * 2;

            iText.IO.Codec.Brotli.Dec.BitReader.FillBitWindow(br);
            int blockType = ReadSymbol(state.blockTypeTrees, treeType * iText.IO.Codec.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);

            state.blockLength[treeType] = ReadBlockLength(state.blockLenTrees, treeType * iText.IO.Codec.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
            if (blockType == 1)
            {
                blockType = ringBuffers[offset + 1] + 1;
            }
            else if (blockType == 0)
            {
                blockType = ringBuffers[offset];
            }
            else
            {
                blockType -= 2;
            }
            if (blockType >= state.numBlockTypes[treeType])
            {
                blockType -= state.numBlockTypes[treeType];
            }
            ringBuffers[offset]     = ringBuffers[offset + 1];
            ringBuffers[offset + 1] = blockType;
        }
Esempio n. 2
0
        private static void CopyUncompressedData(iText.IO.Codec.Brotli.Dec.State state)
        {
            iText.IO.Codec.Brotli.Dec.BitReader br = state.br;
            byte[] ringBuffer = state.ringBuffer;
            // Could happen if block ends at ring buffer end.
            if (state.metaBlockLength <= 0)
            {
                iText.IO.Codec.Brotli.Dec.BitReader.Reload(br);
                state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.BlockStart;
                return;
            }
            int chunkLength = System.Math.Min(state.ringBufferSize - state.pos, state.metaBlockLength);

            iText.IO.Codec.Brotli.Dec.BitReader.CopyBytes(br, ringBuffer, state.pos, chunkLength);
            state.metaBlockLength -= chunkLength;
            state.pos             += chunkLength;
            if (state.pos == state.ringBufferSize)
            {
                state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.CopyUncompressed;
                state.bytesToWrite     = state.ringBufferSize;
                state.bytesWritten     = 0;
                state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
                return;
            }
            iText.IO.Codec.Brotli.Dec.BitReader.Reload(br);
            state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.BlockStart;
        }
Esempio n. 3
0
 /// <exception cref="System.IO.IOException"/>
 internal static void Close(iText.IO.Codec.Brotli.Dec.State state)
 {
     if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.Uninitialized)
     {
         throw new System.InvalidOperationException("State MUST be initialized");
     }
     if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.Closed)
     {
         return;
     }
     state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.Closed;
     iText.IO.Codec.Brotli.Dec.BitReader.Close(state.br);
 }
Esempio n. 4
0
        private static void DecodeLiteralBlockSwitch(iText.IO.Codec.Brotli.Dec.State state)
        {
            DecodeBlockTypeAndLength(state, 0);
            int literalBlockType = state.blockTypeRb[1];

            state.contextMapSlice  = literalBlockType << LiteralContextBits;
            state.literalTreeIndex = state.contextMap[state.contextMapSlice] & unchecked ((int)(0xFF));
            state.literalTree      = state.hGroup0.trees[state.literalTreeIndex];
            int contextMode = state.contextModes[literalBlockType];

            state.contextLookupOffset1 = iText.IO.Codec.Brotli.Dec.Context.LookupOffsets[contextMode];
            state.contextLookupOffset2 = iText.IO.Codec.Brotli.Dec.Context.LookupOffsets[contextMode + 1];
        }
Esempio n. 5
0
        private static void MaybeReallocateRingBuffer(iText.IO.Codec.Brotli.Dec.State state)
        {
            int newSize = state.maxRingBufferSize;

            if ((long)newSize > state.expectedTotalSize)
            {
                /* TODO: Handle 2GB+ cases more gracefully. */
                int minimalNewSize = (int)state.expectedTotalSize + state.customDictionary.Length;
                while ((newSize >> 1) > minimalNewSize)
                {
                    newSize >>= 1;
                }
                if (!state.inputEnd && newSize < 16384 && state.maxRingBufferSize >= 16384)
                {
                    newSize = 16384;
                }
            }
            if (newSize <= state.ringBufferSize)
            {
                return;
            }
            int ringBufferSizeWithSlack = newSize + iText.IO.Codec.Brotli.Dec.Dictionary.MaxTransformedWordLength;

            byte[] newBuffer = new byte[ringBufferSizeWithSlack];
            if (state.ringBuffer != null)
            {
                System.Array.Copy(state.ringBuffer, 0, newBuffer, 0, state.ringBufferSize);
            }
            else if (state.customDictionary.Length != 0)
            {
                /* Prepend custom dictionary, if any. */
                int length = state.customDictionary.Length;
                int offset = 0;
                if (length > state.maxBackwardDistance)
                {
                    offset = length - state.maxBackwardDistance;
                    length = state.maxBackwardDistance;
                }
                System.Array.Copy(state.customDictionary, offset, newBuffer, 0, length);
                state.pos           = length;
                state.bytesToIgnore = length;
            }
            state.ringBuffer     = newBuffer;
            state.ringBufferSize = newSize;
        }
Esempio n. 6
0
        /// <summary>Associate input with decoder state.</summary>
        /// <param name="state">uninitialized state without associated input</param>
        /// <param name="input">compressed data source</param>
        internal static void SetInput(iText.IO.Codec.Brotli.Dec.State state, System.IO.Stream input)
        {
            if (state.runningState != iText.IO.Codec.Brotli.Dec.RunningState.Uninitialized)
            {
                throw new System.InvalidOperationException("State MUST be uninitialized");
            }
            iText.IO.Codec.Brotli.Dec.BitReader.Init(state.br, input);
            int windowBits = DecodeWindowBits(state.br);

            if (windowBits == 9)
            {
                /* Reserved case for future expansion. */
                throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid 'windowBits' code");
            }
            state.maxRingBufferSize   = 1 << windowBits;
            state.maxBackwardDistance = state.maxRingBufferSize - 16;
            state.runningState        = iText.IO.Codec.Brotli.Dec.RunningState.BlockStart;
        }
Esempio n. 7
0
        private static bool WriteRingBuffer(iText.IO.Codec.Brotli.Dec.State state)
        {
            /* Ignore custom dictionary bytes. */
            if (state.bytesToIgnore != 0)
            {
                state.bytesWritten += state.bytesToIgnore;
                state.bytesToIgnore = 0;
            }
            int toWrite = System.Math.Min(state.outputLength - state.outputUsed, state.bytesToWrite - state.bytesWritten);

            if (toWrite != 0)
            {
                System.Array.Copy(state.ringBuffer, state.bytesWritten, state.output, state.outputOffset + state.outputUsed, toWrite);
                state.outputUsed   += toWrite;
                state.bytesWritten += toWrite;
            }
            return(state.outputUsed < state.outputLength);
        }
Esempio n. 8
0
 /// <summary>Reads next metablock header.</summary>
 /// <param name="state">decoding state</param>
 private static void ReadMetablockInfo(iText.IO.Codec.Brotli.Dec.State state)
 {
     iText.IO.Codec.Brotli.Dec.BitReader br = state.br;
     if (state.inputEnd)
     {
         state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.Finished;
         state.bytesToWrite     = state.pos;
         state.bytesWritten     = 0;
         state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
         return;
     }
     // TODO: Reset? Do we need this?
     state.hGroup0.codes = null;
     state.hGroup0.trees = null;
     state.hGroup1.codes = null;
     state.hGroup1.trees = null;
     state.hGroup2.codes = null;
     state.hGroup2.trees = null;
     iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
     DecodeMetaBlockLength(br, state);
     if (state.metaBlockLength == 0 && !state.isMetadata)
     {
         return;
     }
     if (state.isUncompressed || state.isMetadata)
     {
         iText.IO.Codec.Brotli.Dec.BitReader.JumpToByteBoundary(br);
         state.runningState = state.isMetadata ? iText.IO.Codec.Brotli.Dec.RunningState.ReadMetadata : iText.IO.Codec.Brotli.Dec.RunningState.CopyUncompressed;
     }
     else
     {
         state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.CompressedBlockStart;
     }
     if (state.isMetadata)
     {
         return;
     }
     state.expectedTotalSize += state.metaBlockLength;
     if (state.ringBufferSize < state.maxRingBufferSize)
     {
         MaybeReallocateRingBuffer(state);
     }
 }
Esempio n. 9
0
        /// <summary>Actual decompress implementation.</summary>
        internal static void Decompress(iText.IO.Codec.Brotli.Dec.State state)
        {
            if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.Uninitialized)
            {
                throw new System.InvalidOperationException("Can't decompress until initialized");
            }
            if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.Closed)
            {
                throw new System.InvalidOperationException("Can't decompress after close");
            }
            iText.IO.Codec.Brotli.Dec.BitReader br = state.br;
            int ringBufferMask = state.ringBufferSize - 1;

            byte[] ringBuffer = state.ringBuffer;
            while (state.runningState != iText.IO.Codec.Brotli.Dec.RunningState.Finished)
            {
                switch (state.runningState)
                {
                case iText.IO.Codec.Brotli.Dec.RunningState.BlockStart:
                {
                    // TODO: extract cases to methods for the better readability.
                    if (state.metaBlockLength < 0)
                    {
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid metablock length");
                    }
                    ReadMetablockInfo(state);
                    /* Ring-buffer would be reallocated here. */
                    ringBufferMask = state.ringBufferSize - 1;
                    ringBuffer     = state.ringBuffer;
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.CompressedBlockStart:
                {
                    ReadMetablockHuffmanCodesAndContextMaps(state);
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                    goto case iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.MainLoop:
                {
                    // Fall through
                    if (state.metaBlockLength <= 0)
                    {
                        state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.BlockStart;
                        continue;
                    }
                    iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
                    if (state.blockLength[1] == 0)
                    {
                        DecodeCommandBlockSwitch(state);
                    }
                    state.blockLength[1]--;
                    iText.IO.Codec.Brotli.Dec.BitReader.FillBitWindow(br);
                    int cmdCode  = ReadSymbol(state.hGroup1.codes, state.treeCommandOffset, br);
                    int rangeIdx = (int)(((uint)cmdCode) >> 6);
                    state.distanceCode = 0;
                    if (rangeIdx >= 2)
                    {
                        rangeIdx          -= 2;
                        state.distanceCode = -1;
                    }
                    int insertCode = iText.IO.Codec.Brotli.Dec.Prefix.InsertRangeLut[rangeIdx] + (((int)(((uint)cmdCode) >> 3)) & 7);
                    int copyCode   = iText.IO.Codec.Brotli.Dec.Prefix.CopyRangeLut[rangeIdx] + (cmdCode & 7);
                    state.insertLength = iText.IO.Codec.Brotli.Dec.Prefix.InsertLengthOffset[insertCode] + iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, iText.IO.Codec.Brotli.Dec.Prefix.InsertLengthNBits[insertCode]);
                    state.copyLength   = iText.IO.Codec.Brotli.Dec.Prefix.CopyLengthOffset[copyCode] + iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, iText.IO.Codec.Brotli.Dec.Prefix.CopyLengthNBits[copyCode]);
                    state.j            = 0;
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop;
                    goto case iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop:
                {
                    // Fall through
                    if (state.trivialLiteralContext)
                    {
                        while (state.j < state.insertLength)
                        {
                            iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
                            if (state.blockLength[0] == 0)
                            {
                                DecodeLiteralBlockSwitch(state);
                            }
                            state.blockLength[0]--;
                            iText.IO.Codec.Brotli.Dec.BitReader.FillBitWindow(br);
                            ringBuffer[state.pos] = unchecked ((byte)ReadSymbol(state.hGroup0.codes, state.literalTree, br));
                            state.j++;
                            if (state.pos++ == ringBufferMask)
                            {
                                state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop;
                                state.bytesToWrite     = state.ringBufferSize;
                                state.bytesWritten     = 0;
                                state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
                                break;
                            }
                        }
                    }
                    else
                    {
                        int prevByte1 = ringBuffer[(state.pos - 1) & ringBufferMask] & unchecked ((int)(0xFF));
                        int prevByte2 = ringBuffer[(state.pos - 2) & ringBufferMask] & unchecked ((int)(0xFF));
                        while (state.j < state.insertLength)
                        {
                            iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
                            if (state.blockLength[0] == 0)
                            {
                                DecodeLiteralBlockSwitch(state);
                            }
                            int literalTreeIndex = state.contextMap[state.contextMapSlice + (iText.IO.Codec.Brotli.Dec.Context.Lookup[state.contextLookupOffset1 + prevByte1] | iText.IO.Codec.Brotli.Dec.Context.Lookup[state.contextLookupOffset2 + prevByte2])] & unchecked ((int)(0xFF));
                            state.blockLength[0]--;
                            prevByte2 = prevByte1;
                            iText.IO.Codec.Brotli.Dec.BitReader.FillBitWindow(br);
                            prevByte1             = ReadSymbol(state.hGroup0.codes, state.hGroup0.trees[literalTreeIndex], br);
                            ringBuffer[state.pos] = unchecked ((byte)prevByte1);
                            state.j++;
                            if (state.pos++ == ringBufferMask)
                            {
                                state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop;
                                state.bytesToWrite     = state.ringBufferSize;
                                state.bytesWritten     = 0;
                                state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
                                break;
                            }
                        }
                    }
                    if (state.runningState != iText.IO.Codec.Brotli.Dec.RunningState.InsertLoop)
                    {
                        continue;
                    }
                    state.metaBlockLength -= state.insertLength;
                    if (state.metaBlockLength <= 0)
                    {
                        state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                        continue;
                    }
                    if (state.distanceCode < 0)
                    {
                        iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
                        if (state.blockLength[2] == 0)
                        {
                            DecodeDistanceBlockSwitch(state);
                        }
                        state.blockLength[2]--;
                        iText.IO.Codec.Brotli.Dec.BitReader.FillBitWindow(br);
                        state.distanceCode = ReadSymbol(state.hGroup2.codes, state.hGroup2.trees[state.distContextMap[state.distContextMapSlice + (state.copyLength > 4 ? 3 : state.copyLength - 2)] & unchecked ((int)(0xFF))], br);
                        if (state.distanceCode >= state.numDirectDistanceCodes)
                        {
                            state.distanceCode -= state.numDirectDistanceCodes;
                            int postfix = state.distanceCode & state.distancePostfixMask;
                            state.distanceCode = (int)(((uint)state.distanceCode) >> state.distancePostfixBits);
                            int n      = ((int)(((uint)state.distanceCode) >> 1)) + 1;
                            int offset = ((2 + (state.distanceCode & 1)) << n) - 4;
                            state.distanceCode = state.numDirectDistanceCodes + postfix + ((offset + iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, n)) << state.distancePostfixBits);
                        }
                    }
                    // Convert the distance code to the actual distance by possibly looking up past distances
                    // from the ringBuffer.
                    state.distance = TranslateShortCodes(state.distanceCode, state.distRb, state.distRbIdx);
                    if (state.distance < 0)
                    {
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Negative distance");
                    }
                    // COV_NF_LINE
                    if (state.maxDistance != state.maxBackwardDistance && state.pos < state.maxBackwardDistance)
                    {
                        state.maxDistance = state.pos;
                    }
                    else
                    {
                        state.maxDistance = state.maxBackwardDistance;
                    }
                    state.copyDst = state.pos;
                    if (state.distance > state.maxDistance)
                    {
                        state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.Transform;
                        continue;
                    }
                    if (state.distanceCode > 0)
                    {
                        state.distRb[state.distRbIdx & 3] = state.distance;
                        state.distRbIdx++;
                    }
                    if (state.copyLength > state.metaBlockLength)
                    {
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
                    }
                    // COV_NF_LINE
                    state.j            = 0;
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.CopyLoop;
                    goto case iText.IO.Codec.Brotli.Dec.RunningState.CopyLoop;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.CopyLoop:
                {
                    // fall through
                    int src        = (state.pos - state.distance) & ringBufferMask;
                    int dst        = state.pos;
                    int copyLength = state.copyLength - state.j;
                    if ((src + copyLength < ringBufferMask) && (dst + copyLength < ringBufferMask))
                    {
                        for (int k = 0; k < copyLength; ++k)
                        {
                            ringBuffer[dst++] = ringBuffer[src++];
                        }
                        state.j += copyLength;
                        state.metaBlockLength -= copyLength;
                        state.pos             += copyLength;
                    }
                    else
                    {
                        for (; state.j < state.copyLength;)
                        {
                            ringBuffer[state.pos] = ringBuffer[(state.pos - state.distance) & ringBufferMask];
                            state.metaBlockLength--;
                            state.j++;
                            if (state.pos++ == ringBufferMask)
                            {
                                state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.CopyLoop;
                                state.bytesToWrite     = state.ringBufferSize;
                                state.bytesWritten     = 0;
                                state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
                                break;
                            }
                        }
                    }
                    if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.CopyLoop)
                    {
                        state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                    }
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.Transform:
                {
                    if (state.copyLength >= iText.IO.Codec.Brotli.Dec.Dictionary.MinWordLength && state.copyLength <= iText.IO.Codec.Brotli.Dec.Dictionary.MaxWordLength)
                    {
                        int offset       = iText.IO.Codec.Brotli.Dec.Dictionary.OffsetsByLength[state.copyLength];
                        int wordId       = state.distance - state.maxDistance - 1;
                        int shift        = iText.IO.Codec.Brotli.Dec.Dictionary.SizeBitsByLength[state.copyLength];
                        int mask         = (1 << shift) - 1;
                        int wordIdx      = wordId & mask;
                        int transformIdx = (int)(((uint)wordId) >> shift);
                        offset += wordIdx * state.copyLength;
                        if (transformIdx < iText.IO.Codec.Brotli.Dec.Transform.Transforms.Length)
                        {
                            int len = iText.IO.Codec.Brotli.Dec.Transform.TransformDictionaryWord(ringBuffer, state.copyDst, iText.IO.Codec.Brotli.Dec.Dictionary.GetData(), offset, state.copyLength, iText.IO.Codec.Brotli.Dec.Transform.Transforms[transformIdx]);
                            state.copyDst         += len;
                            state.pos             += len;
                            state.metaBlockLength -= len;
                            if (state.copyDst >= state.ringBufferSize)
                            {
                                state.nextRunningState = iText.IO.Codec.Brotli.Dec.RunningState.CopyWrapBuffer;
                                state.bytesToWrite     = state.ringBufferSize;
                                state.bytesWritten     = 0;
                                state.runningState     = iText.IO.Codec.Brotli.Dec.RunningState.Write;
                                continue;
                            }
                        }
                        else
                        {
                            throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
                        }
                    }
                    else
                    {
                        // COV_NF_LINE
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
                    }
                    // COV_NF_LINE
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.CopyWrapBuffer:
                {
                    System.Array.Copy(ringBuffer, state.ringBufferSize, ringBuffer, 0, state.copyDst - state.ringBufferSize);
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.MainLoop;
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.ReadMetadata:
                {
                    while (state.metaBlockLength > 0)
                    {
                        iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
                        // Optimize
                        iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 8);
                        state.metaBlockLength--;
                    }
                    state.runningState = iText.IO.Codec.Brotli.Dec.RunningState.BlockStart;
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.CopyUncompressed:
                {
                    CopyUncompressedData(state);
                    continue;
                }

                case iText.IO.Codec.Brotli.Dec.RunningState.Write:
                {
                    if (!WriteRingBuffer(state))
                    {
                        // Output buffer is full.
                        return;
                    }
                    if (state.pos >= state.maxBackwardDistance)
                    {
                        state.maxDistance = state.maxBackwardDistance;
                    }
                    state.pos         &= ringBufferMask;
                    state.runningState = state.nextRunningState;
                    continue;
                }

                default:
                {
                    throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Unexpected state " + state.runningState);
                }
                }
            }
            if (state.runningState == iText.IO.Codec.Brotli.Dec.RunningState.Finished)
            {
                if (state.metaBlockLength < 0)
                {
                    throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Invalid metablock length");
                }
                iText.IO.Codec.Brotli.Dec.BitReader.JumpToByteBoundary(br);
                iText.IO.Codec.Brotli.Dec.BitReader.CheckHealth(state.br, true);
            }
        }
Esempio n. 10
0
 internal static void SetCustomDictionary(iText.IO.Codec.Brotli.Dec.State state, byte[] data)
 {
     state.customDictionary = (data == null) ? new byte[0] : data;
 }
Esempio n. 11
0
        private static void DecodeMetaBlockLength(iText.IO.Codec.Brotli.Dec.BitReader br, iText.IO.Codec.Brotli.Dec.State state)
        {
            state.inputEnd        = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 1) == 1;
            state.metaBlockLength = 0;
            state.isUncompressed  = false;
            state.isMetadata      = false;
            if (state.inputEnd && iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 1) != 0)
            {
                return;
            }
            int sizeNibbles = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 2) + 4;

            if (sizeNibbles == 7)
            {
                state.isMetadata = true;
                if (iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 1) != 0)
                {
                    throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Corrupted reserved bit");
                }
                int sizeBytes = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 2);
                if (sizeBytes == 0)
                {
                    return;
                }
                for (int i = 0; i < sizeBytes; i++)
                {
                    int bits = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 8);
                    if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1)
                    {
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Exuberant nibble");
                    }
                    state.metaBlockLength |= bits << (i * 8);
                }
            }
            else
            {
                for (int i = 0; i < sizeNibbles; i++)
                {
                    int bits = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 4);
                    if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4)
                    {
                        throw new iText.IO.Codec.Brotli.Dec.BrotliRuntimeException("Exuberant nibble");
                    }
                    state.metaBlockLength |= bits << (i * 4);
                }
            }
            state.metaBlockLength++;
            if (!state.inputEnd)
            {
                state.isUncompressed = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 1) == 1;
            }
        }
Esempio n. 12
0
        private static void ReadMetablockHuffmanCodesAndContextMaps(iText.IO.Codec.Brotli.Dec.State state)
        {
            iText.IO.Codec.Brotli.Dec.BitReader br = state.br;
            for (int i = 0; i < 3; i++)
            {
                state.numBlockTypes[i] = DecodeVarLenUnsignedByte(br) + 1;
                state.blockLength[i]   = 1 << 28;
                if (state.numBlockTypes[i] > 1)
                {
                    ReadHuffmanCode(state.numBlockTypes[i] + 2, state.blockTypeTrees, i * iText.IO.Codec.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
                    ReadHuffmanCode(NumBlockLengthCodes, state.blockLenTrees, i * iText.IO.Codec.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
                    state.blockLength[i] = ReadBlockLength(state.blockLenTrees, i * iText.IO.Codec.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
                }
            }
            iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
            state.distancePostfixBits    = iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 2);
            state.numDirectDistanceCodes = NumDistanceShortCodes + (iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 4) << state.distancePostfixBits);
            state.distancePostfixMask    = (1 << state.distancePostfixBits) - 1;
            int numDistanceCodes = state.numDirectDistanceCodes + (48 << state.distancePostfixBits);

            // TODO: Reuse?
            state.contextModes = new byte[state.numBlockTypes[0]];
            for (int i = 0; i < state.numBlockTypes[0];)
            {
                /* Ensure that less than 256 bits read between readMoreInput. */
                int limit = System.Math.Min(i + 96, state.numBlockTypes[0]);
                for (; i < limit; ++i)
                {
                    state.contextModes[i] = unchecked ((byte)(iText.IO.Codec.Brotli.Dec.BitReader.ReadBits(br, 2) << 1));
                }
                iText.IO.Codec.Brotli.Dec.BitReader.ReadMoreInput(br);
            }
            // TODO: Reuse?
            state.contextMap = new byte[state.numBlockTypes[0] << LiteralContextBits];
            int numLiteralTrees = DecodeContextMap(state.numBlockTypes[0] << LiteralContextBits, state.contextMap, br);

            state.trivialLiteralContext = true;
            for (int j = 0; j < state.numBlockTypes[0] << LiteralContextBits; j++)
            {
                if (state.contextMap[j] != j >> LiteralContextBits)
                {
                    state.trivialLiteralContext = false;
                    break;
                }
            }
            // TODO: Reuse?
            state.distContextMap = new byte[state.numBlockTypes[2] << DistanceContextBits];
            int numDistTrees = DecodeContextMap(state.numBlockTypes[2] << DistanceContextBits, state.distContextMap, br);

            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup0, NumLiteralCodes, numLiteralTrees);
            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup1, NumInsertAndCopyCodes, state.numBlockTypes[1]);
            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup2, numDistanceCodes, numDistTrees);
            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup0, br);
            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup1, br);
            iText.IO.Codec.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup2, br);
            state.contextMapSlice      = 0;
            state.distContextMapSlice  = 0;
            state.contextLookupOffset1 = iText.IO.Codec.Brotli.Dec.Context.LookupOffsets[state.contextModes[0]];
            state.contextLookupOffset2 = iText.IO.Codec.Brotli.Dec.Context.LookupOffsets[state.contextModes[0] + 1];
            state.literalTreeIndex     = 0;
            state.literalTree          = state.hGroup0.trees[0];
            state.treeCommandOffset    = state.hGroup1.trees[0];
            // TODO: == 0?
            state.blockTypeRb[0] = state.blockTypeRb[2] = state.blockTypeRb[4] = 1;
            state.blockTypeRb[1] = state.blockTypeRb[3] = state.blockTypeRb[5] = 0;
        }
Esempio n. 13
0
 private static void DecodeDistanceBlockSwitch(iText.IO.Codec.Brotli.Dec.State state)
 {
     DecodeBlockTypeAndLength(state, 2);
     state.distContextMapSlice = state.blockTypeRb[5] << DistanceContextBits;
 }
Esempio n. 14
0
 private static void DecodeCommandBlockSwitch(iText.IO.Codec.Brotli.Dec.State state)
 {
     DecodeBlockTypeAndLength(state, 1);
     state.treeCommandOffset = state.hGroup1.trees[state.blockTypeRb[3]];
 }