/**
 * 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.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.pdfbox.jbig2.Bitmap;
import org.apache.pdfbox.jbig2.Dictionary;
import org.apache.pdfbox.jbig2.JBIG2ImageReader;
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.HuffmanTable;
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.log.Logger;
import org.apache.pdfbox.jbig2.util.log.LoggerFactory;

/**
 * This class represents the data of segment type "Symbol dictionary". Parsing is described in 7.4.2.1.1 - 7.4.1.1.5 and
 * decoding procedure is described in 6.5.
 */
public class SymbolDictionary implements Dictionary
{

    private final Logger log = LoggerFactory.getLogger(SymbolDictionary.class);

    private SubInputStream subInputStream;

    /** Symbol dictionary flags, 7.4.2.1.1 */
    private short sdrTemplate;
    private byte sdTemplate;
    private boolean isCodingContextRetained;
    private boolean isCodingContextUsed;
    private short sdHuffAggInstanceSelection;
    private short sdHuffBMSizeSelection;
    private short sdHuffDecodeWidthSelection;
    private short sdHuffDecodeHeightSelection;
    private boolean useRefinementAggregation;
    private boolean isHuffmanEncoded;

    /** Symbol dictionary AT flags, 7.4.2.1.2 */
    private short[] sdATX;
    private short[] sdATY;

    /** Symbol dictionary refinement AT flags, 7.4.2.1.3 */
    private short[] sdrATX;
    private short[] sdrATY;

    /** Number of exported symbols, 7.4.2.1.4 */
    private int amountOfExportSymbolss;

    /** Number of new symbols, 7.4.2.1.5 */
    private int amountOfNewSymbols;

    /** Further parameters */
    private SegmentHeader segmentHeader;
    private int amountOfImportedSymbolss;
    private ArrayList<Bitmap> importSymbols;
    private int amountOfDecodedSymbols;
    private Bitmap[] newSymbols;

    /** User-supplied tables * */
    private HuffmanTable dhTable;
    private HuffmanTable dwTable;
    private HuffmanTable bmSizeTable;
    private HuffmanTable aggInstTable;

    /** Return value of that segment */
    private ArrayList<Bitmap> exportSymbols;
    private ArrayList<Bitmap> sbSymbols;

    private ArithmeticDecoder arithmeticDecoder;
    private ArithmeticIntegerDecoder iDecoder;

    private TextRegion textRegion;
    private GenericRegion genericRegion;
    private GenericRefinementRegion genericRefinementRegion;
    private CX cx;

    private CX cxIADH;
    private CX cxIADW;
    private CX cxIAAI;
    private CX cxIAEX;
    private CX cxIARDX;
    private CX cxIARDY;
    private CX cxIADT;

    protected CX cxIAID;
    private int sbSymCodeLen;

    public SymbolDictionary()
    {
    }

    public SymbolDictionary(final SubInputStream subInputStream, final SegmentHeader segmentHeader)
            throws IOException
    {
        this.subInputStream = subInputStream;
        this.segmentHeader = segmentHeader;
    }

    private void parseHeader()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        readRegionFlags();
        setAtPixels();
        setRefinementAtPixels();
        readAmountOfExportedSymbols();
        readAmountOfNewSymbols();
        setInSyms();

        if (isCodingContextUsed)
        {
            SegmentHeader[] rtSegments = segmentHeader.getRtSegments();

            for (int i = rtSegments.length - 1; i >= 0; i--)
            {

                if (rtSegments[i].getSegmentType() == 0)
                {
                    SymbolDictionary symbolDictionary = (SymbolDictionary) rtSegments[i]
                            .getSegmentData();

                    if (symbolDictionary.isCodingContextRetained)
                    {
                        /* 7.4.2.2 3) */
                        setRetainedCodingContexts(symbolDictionary);
                    }
                    break;
                }
            }
        }

        this.checkInput();
    }

    private void readRegionFlags() throws IOException
    {
        /* Bit 13-15 */
        subInputStream.readBits(3); // Dirty read... reserved bits must be 0

        /* Bit 12 */
        sdrTemplate = (short) subInputStream.readBit();

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

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

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

        /* Bit 7 */
        sdHuffAggInstanceSelection = (short) subInputStream.readBit();

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

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

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

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

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

    private void setAtPixels() throws IOException
    {
        if (!isHuffmanEncoded)
        {
            if (sdTemplate == 0)
            {
                readAtPixels(4);
            }
            else
            {
                readAtPixels(1);
            }
        }
    }

    private void setRefinementAtPixels() throws IOException
    {
        if (useRefinementAggregation && sdrTemplate == 0)
        {
            readRefinementAtPixels(2);
        }
    }

    private void readAtPixels(final int amountOfPixels) throws IOException
    {
        sdATX = new short[amountOfPixels];
        sdATY = new short[amountOfPixels];

        for (int i = 0; i < amountOfPixels; i++)
        {
            sdATX[i] = subInputStream.readByte();
            sdATY[i] = subInputStream.readByte();
        }
    }

    private void readRefinementAtPixels(final int amountOfAtPixels) throws IOException
    {
        sdrATX = new short[amountOfAtPixels];
        sdrATY = new short[amountOfAtPixels];

        for (int i = 0; i < amountOfAtPixels; i++)
        {
            sdrATX[i] = subInputStream.readByte();
            sdrATY[i] = subInputStream.readByte();
        }
    }

    private void readAmountOfExportedSymbols() throws IOException
    {
        amountOfExportSymbolss = (int) subInputStream.readBits(32); // & 0xffffffff;
    }

    private void readAmountOfNewSymbols() throws IOException
    {
        amountOfNewSymbols = (int) subInputStream.readBits(32); // & 0xffffffff;
    }

    private void setInSyms()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        if (segmentHeader.getRtSegments() != null)
        {
            retrieveImportSymbols();
        }
        else
        {
            importSymbols = new ArrayList<Bitmap>();
        }
    }

    private void setRetainedCodingContexts(final SymbolDictionary sd)
    {
        this.arithmeticDecoder = sd.arithmeticDecoder;
        this.isHuffmanEncoded = sd.isHuffmanEncoded;
        this.useRefinementAggregation = sd.useRefinementAggregation;
        this.sdTemplate = sd.sdTemplate;
        this.sdrTemplate = sd.sdrTemplate;
        this.sdATX = sd.sdATX;
        this.sdATY = sd.sdATY;
        this.sdrATX = sd.sdrATX;
        this.sdrATY = sd.sdrATY;
        this.cx = sd.cx;
    }

    private void checkInput() throws InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            if (sdTemplate != 0)
            {
                sdTemplate = 0;
            }
            if (!useRefinementAggregation)
            {
                if (isCodingContextRetained)
                {
                    isCodingContextRetained = false;
                }

                if (isCodingContextUsed)
                {
                    isCodingContextUsed = false;
                }
            }

        }
        else
        {
            if (sdHuffBMSizeSelection != 0)
            {
                sdHuffBMSizeSelection = 0;
            }
            if (sdHuffDecodeWidthSelection != 0)
            {
                sdHuffDecodeWidthSelection = 0;
            }
            if (sdHuffDecodeHeightSelection != 0)
            {
                sdHuffDecodeHeightSelection = 0;
            }
        }

        if (!useRefinementAggregation)
        {
            if (sdrTemplate != 0)
            {
                sdrTemplate = 0;
            }
        }

        if (!isHuffmanEncoded || !useRefinementAggregation)
        {
            if (sdHuffAggInstanceSelection != 0)
            {
                sdHuffAggInstanceSelection = 0;
            }
        }
    }

    /**
     * 6.5.5 Decoding the symbol dictionary
     * 
     * @return List of decoded symbol bitmaps as an <code>ArrayList</code>
     */
    public ArrayList<Bitmap> getDictionary()
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {
        long timestamp = System.currentTimeMillis();
        if (null == exportSymbols)
        {

            if (useRefinementAggregation)
                sbSymCodeLen = getSbSymCodeLen();

            if (!isHuffmanEncoded)
            {
                setCodingStatistics();
            }

            /* 6.5.5 1) */
            newSymbols = new Bitmap[amountOfNewSymbols];

            /* 6.5.5 2) */
            int[] newSymbolsWidths = null;
            if (isHuffmanEncoded && !useRefinementAggregation)
            {
                newSymbolsWidths = new int[amountOfNewSymbols];
            }

            setSymbolsArray();

            /* 6.5.5 3) */
            int heightClassHeight = 0;
            amountOfDecodedSymbols = 0;

            /* 6.5.5 4 a) */
            while (amountOfDecodedSymbols < amountOfNewSymbols)
            {

                /* 6.5.5 4 b) */
                heightClassHeight += decodeHeightClassDeltaHeight();
                int symbolWidth = 0;
                int totalWidth = 0;
                final int heightClassFirstSymbolIndex = amountOfDecodedSymbols;

                /* 6.5.5 4 c) */

                // Repeat until OOB - OOB sends a break;
                while (true)
                {
                    /* 4 c) i) */
                    final long differenceWidth = decodeDifferenceWidth();

                    /*
                     * If result is OOB, then all the symbols in this height class has been decoded; proceed to step 4
                     * d). Also exit, if the expected number of symbols have been decoded.
                     * 
                     * The latter exit condition guards against pathological cases where a symbol's DW never contains
                     * OOB and thus never terminates.
                     */
                    if (differenceWidth == Long.MAX_VALUE
                            || amountOfDecodedSymbols >= amountOfNewSymbols)
                    {
                        break;
                    }

                    symbolWidth += differenceWidth;
                    totalWidth += symbolWidth;

                    /* 4 c) ii) */
                    if (!isHuffmanEncoded || useRefinementAggregation)
                    {
                        if (!useRefinementAggregation)
                        {
                            // 6.5.8.1 - Direct coded
                            decodeDirectlyThroughGenericRegion(symbolWidth, heightClassHeight);
                        }
                        else
                        {
                            // 6.5.8.2 - Refinement/Aggregate-coded
                            decodeAggregate(symbolWidth, heightClassHeight);
                        }
                    }
                    else if (isHuffmanEncoded && !useRefinementAggregation)
                    {
                        /* 4 c) iii) */
                        newSymbolsWidths[amountOfDecodedSymbols] = symbolWidth;
                    }
                    amountOfDecodedSymbols++;
                }

                /* 6.5.5 4 d) */
                if (isHuffmanEncoded && !useRefinementAggregation)
                {
                    /* 6.5.9 */
                    final long bmSize;
                    if (sdHuffBMSizeSelection == 0)
                    {
                        bmSize = StandardTables.getTable(1).decode(subInputStream);
                    }
                    else
                    {
                        bmSize = huffDecodeBmSize();
                    }

                    subInputStream.skipBits();

                    final Bitmap heightClassCollectiveBitmap = decodeHeightClassCollectiveBitmap(
                            bmSize, heightClassHeight, totalWidth);

                    subInputStream.skipBits();
                    decodeHeightClassBitmap(heightClassCollectiveBitmap,
                            heightClassFirstSymbolIndex, heightClassHeight, newSymbolsWidths);
                }
            }

            /* 5) */
            /* 6.5.10 1) - 5) */

            final int[] exFlags = getToExportFlags();

            /* 6.5.10 6) - 8) */
            setExportedSymbols(exFlags);
        }

        if (JBIG2ImageReader.PERFORMANCE_TEST)
            log.info("SYMBOL DECODING: " + (System.currentTimeMillis() - timestamp) + " ms");

        // DictionaryViewer.viewSymbols(sdExSyms);

        return exportSymbols;
    }

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

        if (cxIADH == null)
        {
            cxIADH = new CX(512, 1);
        }

        if (cxIADW == null)
        {
            cxIADW = new CX(512, 1);
        }

        if (cxIAAI == null)
        {
            cxIAAI = new CX(512, 1);
        }

        if (cxIAEX == null)
        {
            cxIAEX = new CX(512, 1);
        }

        if (useRefinementAggregation && cxIAID == null)
        {
            cxIAID = new CX(1 << sbSymCodeLen, 1);
            cxIARDX = new CX(512, 1);
            cxIARDY = new CX(512, 1);
        }

        if (cx == null)
        {
            cx = new CX(65536, 1);
        }

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

        if (iDecoder == null)
        {
            iDecoder = new ArithmeticIntegerDecoder(arithmeticDecoder);
        }

    }

    private final void decodeHeightClassBitmap(final Bitmap heightClassCollectiveBitmap,
            final int heightClassFirstSymbol, final int heightClassHeight,
            final int[] newSymbolsWidths)
            throws IntegerMaxValueException, InvalidHeaderValueException, IOException
    {

        for (int i = heightClassFirstSymbol; i < amountOfDecodedSymbols; i++)
        {
            int startColumn = 0;

            for (int j = heightClassFirstSymbol; j <= i - 1; j++)
            {
                startColumn += newSymbolsWidths[j];
            }

            final Rectangle roi = new Rectangle(startColumn, 0, newSymbolsWidths[i],
                    heightClassHeight);
            final Bitmap symbolBitmap = Bitmaps.extract(roi, heightClassCollectiveBitmap);
            newSymbols[i] = symbolBitmap;
            sbSymbols.add(symbolBitmap);
        }
    }

    private final void decodeAggregate(final int symbolWidth, final int heightClassHeight)
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        // 6.5.8.2 1)
        // 6.5.8.2.1 - Number of symbol instances in aggregation
        final long amountOfRefinementAggregationInstances;
        if (isHuffmanEncoded)
        {
            amountOfRefinementAggregationInstances = huffDecodeRefAggNInst();
        }
        else
        {
            amountOfRefinementAggregationInstances = iDecoder.decode(cxIAAI);
        }

        if (amountOfRefinementAggregationInstances > 1)
        {
            // 6.5.8.2 2)
            decodeThroughTextRegion(symbolWidth, heightClassHeight,
                    amountOfRefinementAggregationInstances);
        }
        else if (amountOfRefinementAggregationInstances == 1)
        {
            // 6.5.8.2 3) refers to 6.5.8.2.2
            decodeRefinedSymbol(symbolWidth, heightClassHeight);
        }
    }

    private final long huffDecodeRefAggNInst() throws IOException, InvalidHeaderValueException
    {
        if (sdHuffAggInstanceSelection == 0)
        {
            return StandardTables.getTable(1).decode(subInputStream);
        }
        else if (sdHuffAggInstanceSelection == 1)
        {
            if (aggInstTable == null)
            {
                int aggregationInstanceNumber = 0;

                if (sdHuffDecodeHeightSelection == 3)
                {
                    aggregationInstanceNumber++;
                }
                if (sdHuffDecodeWidthSelection == 3)
                {
                    aggregationInstanceNumber++;
                }
                if (sdHuffBMSizeSelection == 3)
                {
                    aggregationInstanceNumber++;
                }

                aggInstTable = getUserTable(aggregationInstanceNumber);
            }
            return aggInstTable.decode(subInputStream);
        }
        return 0;
    }

    private final void decodeThroughTextRegion(final int symbolWidth, final int heightClassHeight,
            final long amountOfRefinementAggregationInstances)
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {
        if (textRegion == null)
        {
            textRegion = new TextRegion(subInputStream, null);

            textRegion.setContexts(cx, // default context
                    new CX(512, 1), // IADT
                    new CX(512, 1), // IAFS
                    new CX(512, 1), // IADS
                    new CX(512, 1), // IAIT
                    cxIAID, // IAID
                    new CX(512, 1), // IARDW
                    new CX(512, 1), // IARDH
                    new CX(512, 1), // IARDX
                    new CX(512, 1) // IARDY
            );
        }

        // 6.5.8.2.4 Concatenating the array used as parameter later.
        setSymbolsArray();

        // 6.5.8.2 2) Parameters set according to Table 17, page 36
        textRegion.setParameters(arithmeticDecoder, iDecoder, isHuffmanEncoded, true, symbolWidth,
                heightClassHeight, amountOfRefinementAggregationInstances, 1,
                (amountOfImportedSymbolss + amountOfDecodedSymbols), (short) 0, (short) 0,
                (short) 0, (short) 1, (short) 0, (short) 0, (short) 0, (short) 0, (short) 0,
                (short) 0, (short) 0, (short) 0, (short) 0, sdrTemplate, sdrATX, sdrATY, sbSymbols,
                sbSymCodeLen);

        addSymbol(textRegion);
    }

    private final void decodeRefinedSymbol(final int symbolWidth, final int heightClassHeight)
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {

        final int id;
        final int rdx;
        final int rdy;
        // long symInRefSize = 0;
        if (isHuffmanEncoded)
        {
            /* 2) - 4) */
            id = (int) subInputStream.readBits(sbSymCodeLen);
            rdx = (int) StandardTables.getTable(15).decode(subInputStream);
            rdy = (int) StandardTables.getTable(15).decode(subInputStream);

            /* 5) a) */
            /* symInRefSize = */StandardTables.getTable(1).decode(subInputStream);

            /* 5) b) - Skip over remaining bits */
            subInputStream.skipBits();
        }
        else
        {
            /* 2) - 4) */
            id = iDecoder.decodeIAID(cxIAID, sbSymCodeLen);
            rdx = (int) iDecoder.decode(cxIARDX);
            rdy = (int) iDecoder.decode(cxIARDY);
        }

        /* 6) */
        setSymbolsArray();
        final Bitmap ibo = sbSymbols.get(id);
        decodeNewSymbols(symbolWidth, heightClassHeight, ibo, rdx, rdy);

        /* 7) */
        if (isHuffmanEncoded)
        {
            subInputStream.skipBits();
            // Make sure that the processed bytes are equal to the value read in step 5 a)
        }
    }

    private final void decodeNewSymbols(final int symWidth, final int hcHeight, final Bitmap ibo,
            final int rdx, final int rdy)
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        if (genericRefinementRegion == null)
        {
            genericRefinementRegion = new GenericRefinementRegion(subInputStream);

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

            if (cx == null)
            {
                cx = new CX(65536, 1);
            }
        }

        // Parameters as shown in Table 18, page 36
        genericRefinementRegion.setParameters(cx, arithmeticDecoder, sdrTemplate, symWidth,
                hcHeight, ibo, rdx, rdy, false, sdrATX, sdrATY);

        addSymbol(genericRefinementRegion);
    }

    private final void decodeDirectlyThroughGenericRegion(final int symWidth, final int hcHeight)
            throws IOException, IntegerMaxValueException, InvalidHeaderValueException
    {
        if (genericRegion == null)
        {
            genericRegion = new GenericRegion(subInputStream);
        }

        // Parameters set according to Table 16, page 35
        genericRegion.setParameters(false, sdTemplate, false, false, sdATX, sdATY, symWidth,
                hcHeight, cx, arithmeticDecoder);

        addSymbol(genericRegion);
    }

    private final void addSymbol(final Region region)
            throws IntegerMaxValueException, InvalidHeaderValueException, IOException
    {
        final Bitmap symbol = region.getRegionBitmap();
        newSymbols[amountOfDecodedSymbols] = symbol;
        sbSymbols.add(symbol);
    }

    private final long decodeDifferenceWidth() throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            switch (sdHuffDecodeWidthSelection)
            {
            case 0:
                return StandardTables.getTable(2).decode(subInputStream);
            case 1:
                return StandardTables.getTable(3).decode(subInputStream);
            case 3:
                if (dwTable == null)
                {
                    int dwNr = 0;

                    if (sdHuffDecodeHeightSelection == 3)
                    {
                        dwNr++;
                    }
                    dwTable = getUserTable(dwNr);
                }

                return dwTable.decode(subInputStream);
            }
        }
        else
        {
            return iDecoder.decode(cxIADW);
        }
        return 0;
    }

    private final long decodeHeightClassDeltaHeight()
            throws IOException, InvalidHeaderValueException
    {
        if (isHuffmanEncoded)
        {
            return decodeHeightClassDeltaHeightWithHuffman();
        }
        else
        {
            return iDecoder.decode(cxIADH);
        }
    }

    /**
     * 6.5.6 if isHuffmanEncoded
     * 
     * @return long - Result of decoding HCDH
     * @throws IOException
     * @throws InvalidHeaderValueException
     */
    private final long decodeHeightClassDeltaHeightWithHuffman()
            throws IOException, InvalidHeaderValueException
    {
        switch (sdHuffDecodeHeightSelection)
        {
        case 0:
            return StandardTables.getTable(4).decode(subInputStream);
        case 1:
            return StandardTables.getTable(5).decode(subInputStream);
        case 3:
            if (dhTable == null)
            {
                dhTable = getUserTable(0);
            }
            return dhTable.decode(subInputStream);
        }

        return 0;
    }

    private final Bitmap decodeHeightClassCollectiveBitmap(final long bmSize,
            final int heightClassHeight, final int totalWidth) throws IOException
    {
        if (bmSize == 0)
        {
            final Bitmap heightClassCollectiveBitmap = new Bitmap(totalWidth, heightClassHeight);

            for (int i = 0; i < heightClassCollectiveBitmap.getByteArray().length; i++)
            {
                heightClassCollectiveBitmap.setByte(i, subInputStream.readByte());
            }

            return heightClassCollectiveBitmap;
        }
        else
        {
            if (genericRegion == null)
            {
                genericRegion = new GenericRegion(subInputStream);
            }

            genericRegion.setParameters(true, subInputStream.getStreamPosition(), bmSize,
                    heightClassHeight, totalWidth);

            return genericRegion.getRegionBitmap();
        }
    }

    private void setExportedSymbols(final int[] toExportFlags)
    {
        exportSymbols = new ArrayList<Bitmap>(amountOfExportSymbolss);

        for (int i = 0; i < amountOfImportedSymbolss + amountOfNewSymbols; i++)
        {

            if (toExportFlags[i] == 1)
            {
                if (i < amountOfImportedSymbolss)
                {
                    exportSymbols.add(importSymbols.get(i));
                }
                else
                {
                    exportSymbols.add(newSymbols[i - amountOfImportedSymbolss]);
                }
            }
        }
    }

    private int[] getToExportFlags() throws IOException, InvalidHeaderValueException
    {
        int currentExportFlag = 0;
        long exRunLength = 0;
        final int[] exportFlags = new int[amountOfImportedSymbolss + amountOfNewSymbols];

        for (int exportIndex = 0; exportIndex < amountOfImportedSymbolss
                + amountOfNewSymbols; exportIndex += exRunLength)
        {

            if (isHuffmanEncoded)
            {
                exRunLength = StandardTables.getTable(1).decode(subInputStream);
            }
            else
            {
                exRunLength = iDecoder.decode(cxIAEX);
            }

            if (exRunLength != 0)
            {
                for (int index = exportIndex; index < exportIndex + exRunLength; index++)
                {
                    exportFlags[index] = currentExportFlag;
                }
            }

            currentExportFlag = (currentExportFlag == 0) ? 1 : 0;
        }

        return exportFlags;
    }

    private final long huffDecodeBmSize() throws IOException, InvalidHeaderValueException
    {
        if (bmSizeTable == null)
        {
            int bmNr = 0;

            if (sdHuffDecodeHeightSelection == 3)
            {
                bmNr++;
            }

            if (sdHuffDecodeWidthSelection == 3)
            {
                bmNr++;
            }

            bmSizeTable = getUserTable(bmNr);
        }
        return bmSizeTable.decode(subInputStream);
    }

    /**
     * 6.5.8.2.3 - Setting SBSYMCODES and SBSYMCODELEN
     * 
     * @return Result of computing SBSYMCODELEN
     * @throws IOException
     */
    private int getSbSymCodeLen() throws IOException
    {
        if (isHuffmanEncoded)
        {
            return Math.max(
                    (int) (Math.ceil(
                            Math.log(amountOfImportedSymbolss + amountOfNewSymbols) / Math.log(2))),
                    1);
        }
        else
        {
            return (int) (Math
                    .ceil(Math.log(amountOfImportedSymbolss + amountOfNewSymbols) / Math.log(2)));
        }
    }

    /**
     * 6.5.8.2.4 - Setting SBSYMS
     * 
     * @throws IOException
     * @throws InvalidHeaderValueException
     * @throws IntegerMaxValueException
     */
    private final void setSymbolsArray()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        if (importSymbols == null)
        {
            retrieveImportSymbols();
        }

        if (sbSymbols == null)
        {
            sbSymbols = new ArrayList<Bitmap>();
            sbSymbols.addAll(importSymbols);
        }
    }

    /**
     * Concatenates symbols from all referred-to segments.
     * 
     * @throws IOException
     * @throws InvalidHeaderValueException
     * @throws IntegerMaxValueException
     */
    private void retrieveImportSymbols()
            throws IOException, InvalidHeaderValueException, IntegerMaxValueException
    {
        importSymbols = new ArrayList<Bitmap>();
        for (final SegmentHeader referredToSegmentHeader : segmentHeader.getRtSegments())
        {
            if (referredToSegmentHeader.getSegmentType() == 0)
            {
                final SymbolDictionary sd = (SymbolDictionary) referredToSegmentHeader
                        .getSegmentData();
                importSymbols.addAll(sd.getDictionary());
                amountOfImportedSymbolss += sd.amountOfExportSymbolss;
            }
        }
    }

    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;
    }

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