private final int uncompressGetNextCodeLittleEndian()

in src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java [105:179]


        private final int uncompressGetNextCodeLittleEndian()
        {
            try
            {

                // the number of bits to fill (offset difference)
                int bitsToFill = offset - lastOffset;

                // check whether we can refill, or need to fill in absolute mode
                if (bitsToFill < 0 || bitsToFill > 24)
                {
                    // refill at absolute offset
                    int byteOffset = (offset >> 3) - bufferBase; // offset>>3 is equivalent to offset/8

                    if (byteOffset >= bufferTop)
                    {
                        byteOffset += bufferBase;
                        fillBuffer(byteOffset);
                        byteOffset -= bufferBase;
                    }

                    lastCode = (buffer[byteOffset] & 0xff) << 16
                            | (buffer[byteOffset + 1] & 0xff) << 8
                            | (buffer[byteOffset + 2] & 0xff);

                    int bitOffset = offset & 7; // equivalent to offset%8
                    lastCode <<= bitOffset;
                }
                else
                {
                    // the offset to the next byte boundary as seen from the last offset
                    int bitOffset = lastOffset & 7;
                    final int avail = 7 - bitOffset;

                    // check whether there are enough bits in the "queue"
                    if (bitsToFill <= avail)
                    {
                        lastCode <<= bitsToFill;
                    }
                    else
                    {
                        int byteOffset = (lastOffset >> 3) + 3 - bufferBase;

                        if (byteOffset >= bufferTop)
                        {
                            byteOffset += bufferBase;
                            fillBuffer(byteOffset);
                            byteOffset -= bufferBase;
                        }

                        bitOffset = 8 - bitOffset;
                        do
                        {
                            lastCode <<= bitOffset;
                            lastCode |= buffer[byteOffset] & 0xff;
                            bitsToFill -= bitOffset;
                            byteOffset++;
                            bitOffset = 8;
                        } while (bitsToFill >= 8);

                        lastCode <<= bitsToFill; // shift the rest
                    }
                }
                lastOffset = offset;

                return lastCode;
            }
            catch (IOException e)
            {
                // will this actually happen? only with broken data, I'd say.
                throw new ArrayIndexOutOfBoundsException(
                        "Corrupted RLE data caused by an IOException while reading raw data: "
                                + e.toString());
            }
        }