/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.pdfbox.jbig2.segments;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.pdfbox.jbig2.Bitmap;
import org.apache.pdfbox.jbig2.Region;
import org.apache.pdfbox.jbig2.SegmentHeader;
import org.apache.pdfbox.jbig2.decoder.arithmetic.ArithmeticDecoder;
import org.apache.pdfbox.jbig2.decoder.arithmetic.ArithmeticIntegerDecoder;
import org.apache.pdfbox.jbig2.decoder.arithmetic.CX;
import org.apache.pdfbox.jbig2.decoder.huffman.EncodedTable;
import org.apache.pdfbox.jbig2.decoder.huffman.FixedSizeTable;
import org.apache.pdfbox.jbig2.decoder.huffman.HuffmanTable;
import org.apache.pdfbox.jbig2.decoder.huffman.HuffmanTable.Code;
import org.apache.pdfbox.jbig2.decoder.huffman.StandardTables;
import org.apache.pdfbox.jbig2.err.IntegerMaxValueException;
import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
import org.apache.pdfbox.jbig2.image.Bitmaps;
import org.apache.pdfbox.jbig2.io.SubInputStream;
import org.apache.pdfbox.jbig2.util.CombinationOperator;

/**
 * This class represented the segment type "Text region", 7.4.3, page 56.
 */
public class TextRegion implements Region
{
    private SubInputStream subInputStream;

    /** Region segment information field, 7.4.1 */
    private RegionSegmentInformation regionInfo;

    /** Text region segment flags, 7.4.3.1.1 */
    private short sbrTemplate;
    private short sbdsOffset; /* 6.4.8 */
    private short defaultPixel;
    private CombinationOperator combinationOperator;
    private short isTransposed;
    private short referenceCorner;
    private short logSBStrips;
    private boolean useRefinement;
    private boolean isHuffmanEncoded;

    /** Text region segment Huffman flags, 7.4.3.1.2 */
    private short sbHuffRSize;
    private short sbHuffRDY;
    private short sbHuffRDX;
    private short sbHuffRDHeight;
    private short sbHuffRDWidth;
    private short sbHuffDT;
    private short sbHuffDS;
    private short sbHuffFS;

    /** Text region refinement AT flags, 7.4.3.1.3 */
    private short sbrATX[];
    private short sbrATY[];

    /** Number of symbol instances, 7.4.3.1.4 */
    private long amountOfSymbolInstances;

    /** Further parameters */
    private long currentS;
    private int sbStrips;
    private int amountOfSymbols;

    private Bitmap regionBitmap;
    private ArrayList<Bitmap> symbols = new ArrayList<Bitmap>();

    private ArithmeticDecoder arithmeticDecoder;
    private ArithmeticIntegerDecoder integerDecoder;
    private GenericRefinementRegion genericRefinementRegion;

    private CX cxIADT;
    private CX cxIAFS;
    private CX cxIADS;
    private CX cxIAIT;
    private CX cxIARI;
    private CX cxIARDW;
    private CX cxIARDH;
    private CX cxIAID;
    private CX cxIARDX;
    private CX cxIARDY;
    private CX cx;

    /** codeTable including a code to each symbol used in that region */
    private int symbolCodeLength;
    private FixedSizeTable symbolCodeTable;
    private SegmentHeader segmentHeader;

    /** User-supplied tables * */
    private HuffmanTable fsTable;
    private HuffmanTable dsTable;
    private HuffmanTable table;
    private HuffmanTable rdwTable;
    private HuffmanTable rdhTable;
    private HuffmanTable rdxTable;
    private HuffmanTable rdyTable;
    private HuffmanTable rSizeTable;

    public TextRegion()
    {
    }

    public TextRegion(SubInputStream subInputStream, SegmentHeader segmentHeader)
    {
        this.subInputStream = subInputStream;
        this.regionInfo = new RegionSegmentInformation(subInputStream);
        this.segmentHeader = segmentHeader;
    }

    private void parseHeader()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {

        regionInfo.parseHeader();

        readRegionFlags();

        if (isHuffmanEncoded)
        {
            readHuffmanFlags();
        }

        readUseRefinement();

        readAmountOfSymbolInstances();

        /* 7.4.3.1.7 */
        getSymbols();

        computeSymbolCodeLength();

        this.checkInput();
    }

    private void readRegionFlags() throws IOException
    {
        /* Bit 15 */
        sbrTemplate = (short) subInputStream.readBit();

        /* Bit 10-14 */
        sbdsOffset = (short) (subInputStream.readBits(5));
        if (sbdsOffset > 0x0f)
        {
            sbdsOffset -= 0x20;
        }

        /* Bit 9 */
        defaultPixel = (short) subInputStream.readBit();

        /* Bit 7-8 */
        combinationOperator = CombinationOperator
                .translateOperatorCodeToEnum((short) (subInputStream.readBits(2) & 0x3));

        /* Bit 6 */
        isTransposed = (short) subInputStream.readBit();

        /* Bit 4-5 */
        referenceCorner = (short) (subInputStream.readBits(2) & 0x3);

        /* Bit 2-3 */
        logSBStrips = (short) (subInputStream.readBits(2) & 0x3);
        sbStrips = (1 << logSBStrips);

        /* Bit 1 */
        if (subInputStream.readBit() == 1)
        {
            useRefinement = true;
        }

        /* Bit 0 */
        if (subInputStream.readBit() == 1)
        {
            isHuffmanEncoded = true;
        }
    }

    private void readHuffmanFlags() throws IOException
    {
        /* Bit 15 */
        subInputStream.readBit(); // Dirty read...

        /* Bit 14 */
        sbHuffRSize = (short) subInputStream.readBit();

        /* Bit 12-13 */
        sbHuffRDY = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 10-11 */
        sbHuffRDX = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 8-9 */
        sbHuffRDHeight = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 6-7 */
        sbHuffRDWidth = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 4-5 */
        sbHuffDT = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 2-3 */
        sbHuffDS = (short) (subInputStream.readBits(2) & 0xf);

        /* Bit 0-1 */
        sbHuffFS = (short) (subInputStream.readBits(2) & 0xf);
    }

    private void readUseRefinement() throws IOException
    {
        if (useRefinement && sbrTemplate == 0)
        {
            sbrATX = new short[2];
            sbrATY = new short[2];

            /* Byte 0 */
            sbrATX[0] = subInputStream.readByte();

            /* Byte 1 */
            sbrATY[0] = subInputStream.readByte();

            /* Byte 2 */
            sbrATX[1] = subInputStream.readByte();

            /* Byte 3 */
            sbrATY[1] = subInputStream.readByte();
        }
    }

    private void readAmountOfSymbolInstances() throws IOException
    {
        amountOfSymbolInstances = subInputStream.readBits(32) & 0xffffffff;

        // sanity check: don't decode more than one symbol per pixel
        long pixels = (long) regionInfo.getBitmapWidth() * (long) regionInfo.getBitmapHeight();
        if (pixels < amountOfSymbolInstances)
        {
            amountOfSymbolInstances = pixels;
        }
    }

    private void getSymbols()
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {
        if (segmentHeader.getRtSegments() != null)
        {
            initSymbols();
        }
    }

    private void computeSymbolCodeLength() throws IOException
    {
        if (isHuffmanEncoded)
        {
            symbolIDCodeLengths();
        }
        else
        {
            symbolCodeLength = (int) Math.ceil((Math.log(amountOfSymbols) / Math.log(2)));
        }
    }

    private void checkInput() throws InvalidHeaderValueException
    {

        if (!useRefinement)
        {
            if (sbrTemplate != 0)
            {
                sbrTemplate = 0;
            }
        }

        if (sbHuffFS == 2 || sbHuffRDWidth == 2 || sbHuffRDHeight == 2 || sbHuffRDX == 2
                || sbHuffRDY == 2)
        {
            throw new InvalidHeaderValueException(
                    "Huffman flag value of text region segment is not permitted");
        }

        if (!useRefinement)
        {
            if (sbHuffRSize != 0)
            {
                sbHuffRSize = 0;
            }
            if (sbHuffRDY != 0)
            {
                sbHuffRDY = 0;
            }
            if (sbHuffRDX != 0)
            {
                sbHuffRDX = 0;
            }
            if (sbHuffRDWidth != 0)
            {
                sbHuffRDWidth = 0;
            }
            if (sbHuffRDHeight != 0)
            {
                sbHuffRDHeight = 0;
            }
        }
    }

    public Bitmap getRegionBitmap()
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {

        if (!isHuffmanEncoded)
        {
            setCodingStatistics();
        }

        createRegionBitmap();
        decodeSymbolInstances();

        /* 4) */
        return regionBitmap;
    }

    private void setCodingStatistics() throws IOException
    {
        if (cxIADT == null)
            cxIADT = new CX(512, 1);

        if (cxIAFS == null)
            cxIAFS = new CX(512, 1);

        if (cxIADS == null)
            cxIADS = new CX(512, 1);

        if (cxIAIT == null)
            cxIAIT = new CX(512, 1);

        if (cxIARI == null)
            cxIARI = new CX(512, 1);

        if (cxIARDW == null)
            cxIARDW = new CX(512, 1);

        if (cxIARDH == null)
            cxIARDH = new CX(512, 1);

        if (cxIAID == null)
            cxIAID = new CX(1 << symbolCodeLength, 1);

        if (cxIARDX == null)
            cxIARDX = new CX(512, 1);

        if (cxIARDY == null)
            cxIARDY = new CX(512, 1);

        if (arithmeticDecoder == null)
            arithmeticDecoder = new ArithmeticDecoder(subInputStream);

        if (integerDecoder == null)
            integerDecoder = new ArithmeticIntegerDecoder(arithmeticDecoder);
    }

    private void createRegionBitmap()
    {

        /* 6.4.5 */
        final int width = regionInfo.getBitmapWidth();
        final int height = regionInfo.getBitmapHeight();
        regionBitmap = new Bitmap(width, height);

        /* 1) */
        if (defaultPixel != 0)
        {
            Arrays.fill(regionBitmap.getByteArray(), (byte) 0xff);
        }
    }

    private final long decodeStripT() throws IOException, InvalidHeaderValueException
    {

        long stripT = 0;
        /* 2) */
        if (isHuffmanEncoded)
        {
            /* 6.4.6 */
            if (sbHuffDT == 3)
            {
                // TODO test user-specified table
                if (table == null)
                {
                    int dtNr = 0;

                    if (sbHuffFS == 3)
                    {
                        dtNr++;
                    }

                    if (sbHuffDS == 3)
                    {
                        dtNr++;
                    }

                    table = getUserTable(dtNr);
                }
                stripT = table.decode(subInputStream);
            }
            else
            {
                stripT = StandardTables.getTable(11 + sbHuffDT).decode(subInputStream);
            }
        }
        else
        {
            stripT = integerDecoder.decode(cxIADT);
        }

        return stripT * -(sbStrips);
    }

    private void decodeSymbolInstances()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {

        long stripT = decodeStripT();

        /* Last two sentences of 6.4.5 2) */
        long firstS = 0;
        long instanceCounter = 0;

        /* 6.4.5 3 a) */
        while (instanceCounter < amountOfSymbolInstances)
        {

            final long dT = decodeDT();
            stripT += dT;
            long dfS = 0;

            /* 3 c) symbol instances in the strip */
            boolean first = true;
            currentS = 0;

            // do until OOB
            for (;;)
            {
                /* 3 c) i) - first symbol instance in the strip */
                if (first)
                {
                    /* 6.4.7 */
                    dfS = decodeDfS();
                    firstS += dfS;
                    currentS = firstS;
                    first = false;
                    /* 3 c) ii) - the remaining symbol instances in the strip */
                }
                else
                {
                    /* 6.4.8 */
                    final long idS = decodeIdS();

                    /*
                     * If result is OOB, then all the symbol instances in this strip have been decoded; proceed to step
                     * 3 d) respectively 3 b). Also exit, if the expected number of instances have been decoded.
                     * 
                     * The latter exit condition guards against pathological cases where a strip's S never contains OOB
                     * and thus never terminates as illustrated in
                     * https://bugs.chromium.org/p/chromium/issues/detail?id=450971 case pdfium-loop2.pdf.
                     */
                    if (idS == Long.MAX_VALUE || instanceCounter >= amountOfSymbolInstances)
                        break;

                    currentS += (idS + sbdsOffset);
                }

                /* 3 c) iii) */
                final long currentT = decodeCurrentT();
                final long t = stripT + currentT;

                /* 3 c) iv) */
                final long id = decodeID();

                /* 3 c) v) */
                final long r = decodeRI();
                /* 6.4.11 */
                final Bitmap ib = decodeIb(r, id);

                /* vi) */
                blit(ib, t);

                instanceCounter++;
            }
        }
    }

    private final long decodeDT() throws IOException
    {
        /* 3) b) */
        /* 6.4.6 */
        long dT;
        if (isHuffmanEncoded)
        {
            if (sbHuffDT == 3)
            {
                dT = table.decode(subInputStream);
            }
            else
            {
                dT = StandardTables.getTable(11 + sbHuffDT).decode(subInputStream);
            }
        }
        else
        {
            dT = integerDecoder.decode(cxIADT);
        }

        return (dT * sbStrips);
    }

    private final long decodeDfS() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffFS == 3)
            {
                if (fsTable == null)
                {
                    fsTable = getUserTable(0);
                }
                return fsTable.decode(subInputStream);
            }
            else
            {
                return StandardTables.getTable(6 + sbHuffFS).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIAFS);
        }
    }

    private final long decodeIdS() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffDS == 3)
            {
                // TODO test user-specified table
                if (dsTable == null)
                {
                    int dsNr = 0;
                    if (sbHuffFS == 3)
                    {
                        dsNr++;
                    }

                    dsTable = getUserTable(dsNr);
                }
                return dsTable.decode(subInputStream);

            }
            else
            {
                return StandardTables.getTable(8 + sbHuffDS).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIADS);
        }
    }

    private final long decodeCurrentT() throws IOException
    {
        if (sbStrips != 1)
        {
            if (isHuffmanEncoded)
            {
                return subInputStream.readBits(logSBStrips);
            }
            else
            {
                return integerDecoder.decode(cxIAIT);
            }
        }

        return 0;
    }

    private final long decodeID() throws IOException
    {
        if (isHuffmanEncoded)
        {
            if (symbolCodeTable == null)
            {
                return subInputStream.readBits(symbolCodeLength);
            }

            return symbolCodeTable.decode(subInputStream);
        }
        else
        {
            return integerDecoder.decodeIAID(cxIAID, symbolCodeLength);
        }
    }

    private final long decodeRI() throws IOException
    {
        if (useRefinement)
        {
            if (isHuffmanEncoded)
            {
                return subInputStream.readBit();
            }
            else
            {
                return integerDecoder.decode(cxIARI);
            }
        }
        return 0;
    }

    private final Bitmap decodeIb(long r, long id)
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        Bitmap ib;

        if (r == 0)
        {
            ib = symbols.get((int) id);
        }
        else
        {
            /* 1) - 4) */
            final long rdw = decodeRdw();
            final long rdh = decodeRdh();
            final long rdx = decodeRdx();
            final long rdy = decodeRdy();

            /* 5) */
            /* long symInRefSize = 0; */
            if (isHuffmanEncoded)
            {
                /* symInRefSize = */decodeSymInRefSize();
                subInputStream.skipBits();
            }

            /* 6) */
            final Bitmap ibo = symbols.get((int) id);
            final int wo = ibo.getWidth();
            final int ho = ibo.getHeight();

            final int genericRegionReferenceDX = (int) ((rdw >> 1) + rdx);
            final int genericRegionReferenceDY = (int) ((rdh >> 1) + rdy);

            if (genericRefinementRegion == null)
            {
                genericRefinementRegion = new GenericRefinementRegion(subInputStream);
            }

            genericRefinementRegion.setParameters(cx, arithmeticDecoder, sbrTemplate,
                    (int) (wo + rdw), (int) (ho + rdh), ibo, genericRegionReferenceDX,
                    genericRegionReferenceDY, false, sbrATX, sbrATY);

            ib = genericRefinementRegion.getRegionBitmap();

            /* 7 */
            if (isHuffmanEncoded)
            {
                subInputStream.skipBits();
            }
        }
        return ib;
    }

    private final long decodeRdw() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffRDWidth == 3)
            {
                // TODO test user-specified table
                if (rdwTable == null)
                {
                    int rdwNr = 0;
                    if (sbHuffFS == 3)
                    {
                        rdwNr++;
                    }

                    if (sbHuffDS == 3)
                    {
                        rdwNr++;
                    }

                    if (sbHuffDT == 3)
                    {
                        rdwNr++;
                    }

                    rdwTable = getUserTable(rdwNr);
                }
                return rdwTable.decode(subInputStream);

            }
            else
            {
                return StandardTables.getTable(14 + sbHuffRDWidth).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIARDW);
        }
    }

    private final long decodeRdh() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffRDHeight == 3)
            {
                if (rdhTable == null)
                {
                    int rdhNr = 0;

                    if (sbHuffFS == 3)
                    {
                        rdhNr++;
                    }

                    if (sbHuffDS == 3)
                    {
                        rdhNr++;
                    }

                    if (sbHuffDT == 3)
                    {
                        rdhNr++;
                    }

                    if (sbHuffRDWidth == 3)
                    {
                        rdhNr++;
                    }

                    rdhTable = getUserTable(rdhNr);
                }
                return rdhTable.decode(subInputStream);
            }
            else
            {
                return StandardTables.getTable(14 + sbHuffRDHeight).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIARDH);
        }
    }

    private final long decodeRdx() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffRDX == 3)
            {
                if (rdxTable == null)
                {
                    int rdxNr = 0;
                    if (sbHuffFS == 3)
                    {
                        rdxNr++;
                    }

                    if (sbHuffDS == 3)
                    {
                        rdxNr++;
                    }

                    if (sbHuffDT == 3)
                    {
                        rdxNr++;
                    }

                    if (sbHuffRDWidth == 3)
                    {
                        rdxNr++;
                    }

                    if (sbHuffRDHeight == 3)
                    {
                        rdxNr++;
                    }

                    rdxTable = getUserTable(rdxNr);
                }
                return rdxTable.decode(subInputStream);
            }
            else
            {
                return StandardTables.getTable(14 + sbHuffRDX).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIARDX);
        }
    }

    private final long decodeRdy() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sbHuffRDY == 3)
            {
                if (rdyTable == null)
                {
                    int rdyNr = 0;
                    if (sbHuffFS == 3)
                    {
                        rdyNr++;
                    }

                    if (sbHuffDS == 3)
                    {
                        rdyNr++;
                    }

                    if (sbHuffDT == 3)
                    {
                        rdyNr++;
                    }

                    if (sbHuffRDWidth == 3)
                    {
                        rdyNr++;
                    }

                    if (sbHuffRDHeight == 3)
                    {
                        rdyNr++;
                    }

                    if (sbHuffRDX == 3)
                    {
                        rdyNr++;
                    }

                    rdyTable = getUserTable(rdyNr);
                }
                return rdyTable.decode(subInputStream);
            }
            else
            {
                return StandardTables.getTable(14 + sbHuffRDY).decode(subInputStream);
            }
        }
        else
        {
            return integerDecoder.decode(cxIARDY);
        }
    }

    private final long decodeSymInRefSize() throws IOException, InvalidHeaderValueException
    {
        if (sbHuffRSize == 0)
        {
            return StandardTables.getTable(1).decode(subInputStream);
        }
        else
        {
            if (rSizeTable == null)
            {
                int rSizeNr = 0;

                if (sbHuffFS == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffDS == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffDT == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffRDWidth == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffRDHeight == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffRDX == 3)
                {
                    rSizeNr++;
                }

                if (sbHuffRDY == 3)
                {
                    rSizeNr++;
                }

                rSizeTable = getUserTable(rSizeNr);
            }
            return rSizeTable.decode(subInputStream);
        }

    }

    private final void blit(Bitmap ib, long t)
    {
        if (isTransposed == 0 && (referenceCorner == 2 || referenceCorner == 3))
        {
            currentS += ib.getWidth() - 1;
        }
        else if (isTransposed == 1 && (referenceCorner == 0 || referenceCorner == 2))
        {
            currentS += ib.getHeight() - 1;
        }

        /* vii) */
        long s = currentS;

        /* viii) */
        if (isTransposed == 1)
        {
            final long swap = t;
            t = s;
            s = swap;
        }

        if (referenceCorner != 1)
        {
            if (referenceCorner == 0)
            {
                // BL
                t -= ib.getHeight() - 1;
            }
            else if (referenceCorner == 2)
            {
                // BR
                t -= ib.getHeight() - 1;
                s -= ib.getWidth() - 1;
            }
            else if (referenceCorner == 3)
            {
                // TR
                s -= ib.getWidth() - 1;
            }
        }

        Bitmaps.blit(ib, regionBitmap, (int) s, (int) t, combinationOperator);

        /* x) */
        if (isTransposed == 0 && (referenceCorner == 0 || referenceCorner == 1))
        {
            currentS += ib.getWidth() - 1;
        }

        if (isTransposed == 1 && (referenceCorner == 1 || referenceCorner == 3))
        {
            currentS += ib.getHeight() - 1;
        }

    }

    private void initSymbols()
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {
        for (final SegmentHeader segment : segmentHeader.getRtSegments())
        {
            if (segment.getSegmentType() == 0)
            {
                final SymbolDictionary sd = (SymbolDictionary) segment.getSegmentData();

                sd.cxIAID = cxIAID;
                symbols.addAll(sd.getDictionary());
            }
        }
        amountOfSymbols = symbols.size();
    }

    private HuffmanTable getUserTable(final int tablePosition)
            throws InvalidHeaderValueException, IOException
    {
        int tableCounter = 0;

        for (final SegmentHeader referredToSegmentHeader : segmentHeader.getRtSegments())
        {
            if (referredToSegmentHeader.getSegmentType() == 53)
            {
                if (tableCounter == tablePosition)
                {
                    final Table t = (Table) referredToSegmentHeader.getSegmentData();
                    return new EncodedTable(t);
                }
                else
                {
                    tableCounter++;
                }
            }
        }
        return null;
    }

    private void symbolIDCodeLengths() throws IOException
    {
        /* 1) - 2) */
        final List<Code> runCodeTable = new ArrayList<Code>();

        for (int i = 0; i < 35; i++)
        {
            final int prefLen = (int) (subInputStream.readBits(4) & 0xf);
            if (prefLen > 0)
            {
                runCodeTable.add(new Code(prefLen, 0, i, false));
            }
        }

        HuffmanTable ht = new FixedSizeTable(runCodeTable);

        /* 3) - 5) */
        long previousCodeLength = 0;

        int counter = 0;
        final List<Code> sbSymCodes = new ArrayList<Code>();
        while (counter < amountOfSymbols)
        {
            final long code = ht.decode(subInputStream);
            if (code < 32)
            {
                if (code > 0)
                {
                    sbSymCodes.add(new Code((int) code, 0, counter, false));
                }

                previousCodeLength = code;
                counter++;
            }
            else
            {

                long runLength = 0;
                long currCodeLength = 0;
                if (code == 32)
                {
                    runLength = 3 + subInputStream.readBits(2);
                    if (counter > 0)
                    {
                        currCodeLength = previousCodeLength;
                    }
                }
                else if (code == 33)
                {
                    runLength = 3 + subInputStream.readBits(3);
                }
                else if (code == 34)
                {
                    runLength = 11 + subInputStream.readBits(7);
                }

                for (int j = 0; j < runLength; j++)
                {
                    if (currCodeLength > 0)
                    {
                        sbSymCodes.add(new Code((int) currCodeLength, 0, counter, false));
                    }
                    counter++;
                }
            }
        }

        /* 6) - Skip over remaining bits in the last Byte read */
        subInputStream.skipBits();

        /* 7) */
        symbolCodeTable = new FixedSizeTable(sbSymCodes);

    }

    public void init(SegmentHeader header, SubInputStream sis)
            throws InvalidHeaderValueException, IntegerMaxValueException, IOException
    {
        this.segmentHeader = header;
        this.subInputStream = sis;
        this.regionInfo = new RegionSegmentInformation(subInputStream);
        parseHeader();
    }

    protected void setContexts(CX cx, CX cxIADT, CX cxIAFS, CX cxIADS, CX cxIAIT, CX cxIAID,
            CX cxIARDW, CX cxIARDH, CX cxIARDX, CX cxIARDY)
    {
        this.cx = cx;

        this.cxIADT = cxIADT;
        this.cxIAFS = cxIAFS;
        this.cxIADS = cxIADS;
        this.cxIAIT = cxIAIT;

        this.cxIAID = cxIAID;

        this.cxIARDW = cxIARDW;
        this.cxIARDH = cxIARDH;
        this.cxIARDX = cxIARDX;
        this.cxIARDY = cxIARDY;
    }

    protected void setParameters(ArithmeticDecoder arithmeticDecoder,
            ArithmeticIntegerDecoder iDecoder, boolean isHuffmanEncoded, boolean sbRefine, int sbw,
            int sbh, long sbNumInstances, int sbStrips, int sbNumSyms, short sbDefaultPixel,
            short sbCombinationOperator, short transposed, short refCorner, short sbdsOffset,
            short sbHuffFS, short sbHuffDS, short sbHuffDT, short sbHuffRDWidth,
            short sbHuffRDHeight, short sbHuffRDX, short sbHuffRDY, short sbHuffRSize,
            short sbrTemplate, short sbrATX[], short sbrATY[], ArrayList<Bitmap> sbSyms,
            int sbSymCodeLen)
    {

        this.arithmeticDecoder = arithmeticDecoder;

        this.integerDecoder = iDecoder;

        this.isHuffmanEncoded = isHuffmanEncoded;
        this.useRefinement = sbRefine;

        this.regionInfo.setBitmapWidth(sbw);
        this.regionInfo.setBitmapHeight(sbh);

        this.amountOfSymbolInstances = sbNumInstances;
        this.sbStrips = sbStrips;
        this.amountOfSymbols = sbNumSyms;
        this.defaultPixel = sbDefaultPixel;
        this.combinationOperator = CombinationOperator
                .translateOperatorCodeToEnum(sbCombinationOperator);
        this.isTransposed = transposed;
        this.referenceCorner = refCorner;
        this.sbdsOffset = sbdsOffset;

        this.sbHuffFS = sbHuffFS;
        this.sbHuffDS = sbHuffDS;
        this.sbHuffDT = sbHuffDT;
        this.sbHuffRDWidth = sbHuffRDWidth;
        this.sbHuffRDHeight = sbHuffRDHeight;
        this.sbHuffRDX = sbHuffRDX;
        this.sbHuffRDY = sbHuffRDY;
        this.sbHuffRSize = sbHuffRSize;

        this.sbrTemplate = sbrTemplate;
        this.sbrATX = sbrATX;
        this.sbrATY = sbrATY;

        this.symbols = sbSyms;
        this.symbolCodeLength = sbSymCodeLen;
    }

    public RegionSegmentInformation getRegionInfo()
    {
        return regionInfo;
    }
}
