public void decodeNextScanline()

in src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFFaxDecoder.java [593:732]


    public void decodeNextScanline(byte[] buffer,
                                   int lineOffset, int bitOffset) {
        int bits = 0;
        int code = 0;
        int isT = 0;
        int current;
        int entry;
        int twoBits;
        boolean isWhite = true;

        // Initialize starting of the changing elements array
        changingElemSize = 0;

        // While scanline not complete
        while (bitOffset < w) {
            while (isWhite) {
                // White run
                current = nextNBits(10);
                entry = white[current];

                // Get the 3 fields from the entry
                isT = entry & 0x0001;
                bits = (entry >>> 1) & 0x0f;

                if (bits == 12) {          // Additional Make up code
                    // Get the next 2 bits
                    twoBits = nextLesserThan8Bits(2);
                    // Consolidate the 2 new bits and last 2 bits into 4 bits
                    current = ((current << 2) & 0x000c) | twoBits;
                    entry = additionalMakeup[current];
                    bits = (entry >>> 1) & 0x07;     // 3 bits 0000 0111
                    code  = (entry >>> 4) & 0x0fff;  // 12 bits
                    bitOffset += code; // Skip white run

                    updatePointer(4 - bits);
                } else if (bits == 0) {     // ERROR
                    throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder0"));
                } else if (bits == 15) {    // EOL
                    throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder1"));
                } else {
                    // 11 bits - 0000 0111 1111 1111 = 0x07ff
                    code = (entry >>> 5) & 0x07ff;
                    bitOffset += code;

                    updatePointer(10 - bits);
                    if (isT == 0) {
                        isWhite = false;
                        currChangingElems[changingElemSize++] = bitOffset;
                    }
                }
            }

            // Check whether this run completed one width, if so
            // advance to next byte boundary for compression = 2.
            if (bitOffset == w) {
                if (compression == 2) {
                    advancePointer();
                }
                break;
            }

            while (!isWhite) {
                // Black run
                current = nextLesserThan8Bits(4);
                entry = initBlack[current];

                // Get the 3 fields from the entry
                isT = entry & 0x0001;
                bits = (entry >>> 1) & 0x000f;
                code = (entry >>> 5) & 0x07ff;

                if (code == 100) {
                    current = nextNBits(9);
                    entry = black[current];

                    // Get the 3 fields from the entry
                    isT = entry & 0x0001;
                    bits = (entry >>> 1) & 0x000f;
                    code = (entry >>> 5) & 0x07ff;

                    if (bits == 12) {
                        // Additional makeup codes
                        updatePointer(5);
                        current = nextLesserThan8Bits(4);
                        entry = additionalMakeup[current];
                        bits = (entry >>> 1) & 0x07;     // 3 bits 0000 0111
                        code  = (entry >>> 4) & 0x0fff;  // 12 bits

                        setToBlack(buffer, lineOffset, bitOffset, code);
                        bitOffset += code;

                        updatePointer(4 - bits);
                    } else if (bits == 15) {
                        // EOL code
                        throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder2"));
                    } else {
                        setToBlack(buffer, lineOffset, bitOffset, code);
                        bitOffset += code;

                        updatePointer(9 - bits);
                        if (isT == 0) {
                            isWhite = true;
                            currChangingElems[changingElemSize++] = bitOffset;
                        }
                    }
                } else if (code == 200) {
                    // Is a Terminating code
                    current = nextLesserThan8Bits(2);
                    entry = twoBitBlack[current];
                    code = (entry >>> 5) & 0x07ff;
                    bits = (entry >>> 1) & 0x0f;

                    setToBlack(buffer, lineOffset, bitOffset, code);
                    bitOffset += code;

                    updatePointer(2 - bits);
                    isWhite = true;
                    currChangingElems[changingElemSize++] = bitOffset;
                } else {
                    // Is a Terminating code
                    setToBlack(buffer, lineOffset, bitOffset, code);
                    bitOffset += code;

                    updatePointer(4 - bits);
                    isWhite = true;
                    currChangingElems[changingElemSize++] = bitOffset;
                }
            }

            // Check whether this run completed one width
            if (bitOffset == w) {
                if (compression == 2) {
                    advancePointer();
                }
                break;
            }
        }

        currChangingElems[changingElemSize++] = bitOffset;
    }