public void decode2D()

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


    public void decode2D(byte[] buffer,
                         byte[] compData,
                         int startX,
                         int height,
                         long tiffT4Options) {
        this.data = compData;
        compression = 3;

        bitPointer = 0;
        bytePointer = 0;

        int scanlineStride = (w + 7) / 8;

        int a0;
        int a1;
        int b1;
        int b2;
        int[] b = new int[2];
        int entry;
        int code;
        int bits;
        boolean isWhite;
        int currIndex = 0;
        int[] temp;

        // fillBits - dealt with this in readEOL
        // 1D/2D encoding - dealt with this in readEOL

        // uncompressedMode - haven't dealt with this yet.


        oneD = (int)(tiffT4Options & 0x01);
//        uncompressedMode = (int)((tiffT4Options & 0x02) >> 1);
        fillBits = (int)((tiffT4Options & 0x04) >> 2);

        // The data must start with an EOL code
        if (readEOL() != 1) {
            throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder3"));
        }

        int lineOffset = 0;
        int bitOffset;

        // Then the 1D encoded scanline data will occur, changing elements
        // array gets set.
        decodeNextScanline(buffer, lineOffset, startX);
        lineOffset += scanlineStride;

        for (int lines = 1; lines < height; lines++) {

            // Every line must begin with an EOL followed by a bit which
            // indicates whether the following scanline is 1D or 2D encoded.
            if (readEOL() == 0) {
                // 2D encoded scanline follows

                // Initialize previous scanlines changing elements, and
                // initialize current scanline's changing elements array
                temp = prevChangingElems;
                prevChangingElems = currChangingElems;
                currChangingElems = temp;
                currIndex = 0;

                // a0 has to be set just before the start of this scanline.
                a0 = -1;
                isWhite = true;
                bitOffset = startX;

                lastChangingElement = 0;

                while (bitOffset < w) {
                    // Get the next changing element
                    getNextChangingElement(a0, isWhite, b);

                    b1 = b[0];
                    b2 = b[1];

                    // Get the next seven bits
                    entry = nextLesserThan8Bits(7);

                    // Run these through the 2DCodes table
                    entry = twoDCodes[entry] & 0xff;

                    // Get the code and the number of bits used up
                    code = (entry & 0x78) >>> 3;
                    bits = entry & 0x07;

                    if (code == 0) {
                        if (!isWhite) {
                            setToBlack(buffer, lineOffset, bitOffset,
                                       b2 - bitOffset);
                        }
                        bitOffset = a0 = b2;

                        // Set pointer to consume the correct number of bits.
                        updatePointer(7 - bits);
                    } else if (code == 1) {
                        // Horizontal
                        updatePointer(7 - bits);

                        // identify the next 2 codes.
                        int number;
                        if (isWhite) {
                            number = decodeWhiteCodeWord();
                            bitOffset += number;
                            currChangingElems[currIndex++] = bitOffset;

                            number = decodeBlackCodeWord();
                            setToBlack(buffer, lineOffset, bitOffset, number);
                            bitOffset += number;
                            currChangingElems[currIndex++] = bitOffset;
                        } else {
                            number = decodeBlackCodeWord();
                            setToBlack(buffer, lineOffset, bitOffset, number);
                            bitOffset += number;
                            currChangingElems[currIndex++] = bitOffset;

                            number = decodeWhiteCodeWord();
                            bitOffset += number;
                            currChangingElems[currIndex++] = bitOffset;
                        }

                        a0 = bitOffset;
                    } else if (code <= 8) {
                        // Vertical
                        a1 = b1 + (code - 5);

                        currChangingElems[currIndex++] = a1;

                        // We write the current color till a1 - 1 pos,
                        // since a1 is where the next color starts
                        if (!isWhite) {
                            setToBlack(buffer, lineOffset, bitOffset,
                                       a1 - bitOffset);
                        }
                        bitOffset = a0 = a1;
                        isWhite = !isWhite;

                        updatePointer(7 - bits);
                    } else {
                        throw new RuntimeException(PropertyUtil.getString("TIFFFaxDecoder4"));
                    }
                }

                // Add the changing element beyond the current scanline for the
                // other color too
                currChangingElems[currIndex++] = bitOffset;
                changingElemSize = currIndex;
            } else {
                // 1D encoded scanline follows
                decodeNextScanline(buffer, lineOffset, startX);
            }

            lineOffset += scanlineStride;
        }
    }