http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/PageInformation.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/segments/PageInformation.java 
b/src/main/java/org/apache/pdfbox/jbig2/segments/PageInformation.java
index 513dcca..73a749e 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/PageInformation.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/PageInformation.java
@@ -30,197 +30,232 @@ import org.apache.pdfbox.jbig2.util.log.LoggerFactory;
 /**
  * This class represents the segment type "Page information", 7.4.8 (page 73).
  */
-public class PageInformation implements SegmentData {
+public class PageInformation implements SegmentData
+{
 
-  private final Logger log = LoggerFactory.getLogger(PageInformation.class);
+    private final Logger log = LoggerFactory.getLogger(PageInformation.class);
 
-  private SubInputStream subInputStream;
+    private SubInputStream subInputStream;
 
-  /** Page bitmap width, four byte, 7.4.8.1 */
-  private int bitmapWidth;
+    /** Page bitmap width, four byte, 7.4.8.1 */
+    private int bitmapWidth;
 
-  /** Page bitmap height, four byte, 7.4.8.2 */
-  private int bitmapHeight;
+    /** Page bitmap height, four byte, 7.4.8.2 */
+    private int bitmapHeight;
 
-  /** Page X resolution, four byte, 7.4.8.3 */
-  private int resolutionX;
+    /** Page X resolution, four byte, 7.4.8.3 */
+    private int resolutionX;
 
-  /** Page Y resolution, four byte, 7.4.8.4 */
-  private int resolutionY;
+    /** Page Y resolution, four byte, 7.4.8.4 */
+    private int resolutionY;
 
-  /** Page segment flags, one byte, 7.4.8.5 */
-  private boolean combinationOperatorOverrideAllowed;
-  private CombinationOperator combinationOperator;
-  private boolean requiresAuxiliaryBuffer;
-  private short defaultPixelValue;
-  private boolean mightContainRefinements;
-  private boolean isLossless;
+    /** Page segment flags, one byte, 7.4.8.5 */
+    private boolean combinationOperatorOverrideAllowed;
+    private CombinationOperator combinationOperator;
+    private boolean requiresAuxiliaryBuffer;
+    private short defaultPixelValue;
+    private boolean mightContainRefinements;
+    private boolean isLossless;
 
-  /** Page striping information, two byte, 7.4.8.6 */
-  private boolean isStriped;
-  private short maxStripeSize;
+    /** Page striping information, two byte, 7.4.8.6 */
+    private boolean isStriped;
+    private short maxStripeSize;
 
-  private void parseHeader() throws IOException, InvalidHeaderValueException {
+    private void parseHeader() throws IOException, InvalidHeaderValueException
+    {
 
-    readWidthAndHeight();
-    readResolution();
+        readWidthAndHeight();
+        readResolution();
 
-    /* Bit 7 */
-    subInputStream.readBit(); // dirty read
+        /* Bit 7 */
+        subInputStream.readBit(); // dirty read
 
-    /* Bit 6 */
-    readCombinationOperatorOverrideAllowed();
+        /* Bit 6 */
+        readCombinationOperatorOverrideAllowed();
 
-    /* Bit 5 */
-    readRequiresAuxiliaryBuffer();
+        /* Bit 5 */
+        readRequiresAuxiliaryBuffer();
 
-    /* Bit 3-4 */
-    readCombinationOperator();
+        /* Bit 3-4 */
+        readCombinationOperator();
 
-    /* Bit 2 */
-    readDefaultPixelvalue();
+        /* Bit 2 */
+        readDefaultPixelvalue();
 
-    /* Bit 1 */
-    readContainsRefinement();
+        /* Bit 1 */
+        readContainsRefinement();
 
-    /* Bit 0 */
-    readIsLossless();
+        /* Bit 0 */
+        readIsLossless();
 
-    /* Bit 15 */
-    readIsStriped();
+        /* Bit 15 */
+        readIsStriped();
 
-    /* Bit 0-14 */
-    readMaxStripeSize();
+        /* Bit 0-14 */
+        readMaxStripeSize();
 
-    this.checkInput();
+        this.checkInput();
 
-  }
+    }
 
-  private void readResolution() throws IOException {
-    resolutionX = (int) subInputStream.readBits(32) & 0xffffffff;
-    resolutionY = (int) subInputStream.readBits(32) & 0xffffffff;
-  }
+    private void readResolution() throws IOException
+    {
+        resolutionX = (int) subInputStream.readBits(32) & 0xffffffff;
+        resolutionY = (int) subInputStream.readBits(32) & 0xffffffff;
+    }
 
-  private void checkInput() throws InvalidHeaderValueException {
-    if (bitmapHeight == 0xffffffffL)
-      if (!isStriped)
-        log.info("isStriped should contaion the value true");
-  }
+    private void checkInput() throws InvalidHeaderValueException
+    {
+        if (bitmapHeight == 0xffffffffL)
+            if (!isStriped)
+                log.info("isStriped should contaion the value true");
+    }
 
-  private void readCombinationOperatorOverrideAllowed() throws IOException {
-    /* Bit 6 */
-    if (subInputStream.readBit() == 1) {
-      combinationOperatorOverrideAllowed = true;
+    private void readCombinationOperatorOverrideAllowed() throws IOException
+    {
+        /* Bit 6 */
+        if (subInputStream.readBit() == 1)
+        {
+            combinationOperatorOverrideAllowed = true;
+        }
     }
-  }
 
-  private void readRequiresAuxiliaryBuffer() throws IOException {
-    /* Bit 5 */
-    if (subInputStream.readBit() == 1) {
-      requiresAuxiliaryBuffer = true;
+    private void readRequiresAuxiliaryBuffer() throws IOException
+    {
+        /* Bit 5 */
+        if (subInputStream.readBit() == 1)
+        {
+            requiresAuxiliaryBuffer = true;
+        }
     }
-  }
 
-  private void readCombinationOperator() throws IOException {
-    /* Bit 3-4 */
-    combinationOperator = 
CombinationOperator.translateOperatorCodeToEnum((short) 
(subInputStream.readBits(2) & 0xf));
-  }
+    private void readCombinationOperator() throws IOException
+    {
+        /* Bit 3-4 */
+        combinationOperator = CombinationOperator
+                .translateOperatorCodeToEnum((short) 
(subInputStream.readBits(2) & 0xf));
+    }
 
-  private void readDefaultPixelvalue() throws IOException {
-    /* Bit 2 */
-    defaultPixelValue = (short) subInputStream.readBit();
-  }
+    private void readDefaultPixelvalue() throws IOException
+    {
+        /* Bit 2 */
+        defaultPixelValue = (short) subInputStream.readBit();
+    }
 
-  private void readContainsRefinement() throws IOException {
-    /* Bit 1 */
-    if (subInputStream.readBit() == 1) {
-      mightContainRefinements = true;
+    private void readContainsRefinement() throws IOException
+    {
+        /* Bit 1 */
+        if (subInputStream.readBit() == 1)
+        {
+            mightContainRefinements = true;
+        }
     }
-  }
 
-  private void readIsLossless() throws IOException {
-    /* Bit 0 */
-    if (subInputStream.readBit() == 1) {
-      isLossless = true;
+    private void readIsLossless() throws IOException
+    {
+        /* Bit 0 */
+        if (subInputStream.readBit() == 1)
+        {
+            isLossless = true;
+        }
     }
-  }
 
-  private void readIsStriped() throws IOException {
-    /* Bit 15 */
-    if (subInputStream.readBit() == 1) {
-      isStriped = true;
+    private void readIsStriped() throws IOException
+    {
+        /* Bit 15 */
+        if (subInputStream.readBit() == 1)
+        {
+            isStriped = true;
+        }
     }
-  }
 
-  private void readMaxStripeSize() throws IOException {
-    /* Bit 0-14 */
-    maxStripeSize = (short) (subInputStream.readBits(15) & 0xffff);
-  }
+    private void readMaxStripeSize() throws IOException
+    {
+        /* Bit 0-14 */
+        maxStripeSize = (short) (subInputStream.readBits(15) & 0xffff);
+    }
 
-  private void readWidthAndHeight() throws IOException {
-    bitmapWidth = (int) subInputStream.readBits(32); // & 0xffffffff;
-    bitmapHeight = (int) subInputStream.readBits(32); // & 0xffffffff;
-  }
+    private void readWidthAndHeight() throws IOException
+    {
+        bitmapWidth = (int) subInputStream.readBits(32); // & 0xffffffff;
+        bitmapHeight = (int) subInputStream.readBits(32); // & 0xffffffff;
+    }
 
-  public void init(final SegmentHeader header, final SubInputStream sis) 
throws InvalidHeaderValueException, IOException {
-    subInputStream = sis;
+    public void init(final SegmentHeader header, final SubInputStream sis)
+            throws InvalidHeaderValueException, IOException
+    {
+        subInputStream = sis;
 
-    parseHeader();
-  }
+        parseHeader();
+    }
 
-  public int getWidth() {
-    return bitmapWidth;
-  }
+    public int getWidth()
+    {
+        return bitmapWidth;
+    }
 
-  public int getHeight() {
-    return bitmapHeight;
-  }
+    public int getHeight()
+    {
+        return bitmapHeight;
+    }
 
-  public int getResolutionX() {
-    return resolutionX;
-  }
+    public int getResolutionX()
+    {
+        return resolutionX;
+    }
 
-  public int getResolutionY() {
-    return resolutionY;
-  }
+    public int getResolutionY()
+    {
+        return resolutionY;
+    }
 
-  public short getDefaultPixelValue() {
-    return defaultPixelValue;
-  }
+    public short getDefaultPixelValue()
+    {
+        return defaultPixelValue;
+    }
 
-  public boolean isCombinationOperatorOverrideAllowed() {
-    return combinationOperatorOverrideAllowed;
-  }
+    public boolean isCombinationOperatorOverrideAllowed()
+    {
+        return combinationOperatorOverrideAllowed;
+    }
 
-  public CombinationOperator getCombinationOperator() {
-    return combinationOperator;
-  }
+    public CombinationOperator getCombinationOperator()
+    {
+        return combinationOperator;
+    }
 
-  public boolean isStriped() {
-    return isStriped;
-  }
+    public boolean isStriped()
+    {
+        return isStriped;
+    }
 
-  public short getMaxStripeSize() {
-    return maxStripeSize;
-  }
+    public short getMaxStripeSize()
+    {
+        return maxStripeSize;
+    }
 
-  public boolean isAuxiliaryBufferRequired() {
-    return requiresAuxiliaryBuffer;
-  }
+    public boolean isAuxiliaryBufferRequired()
+    {
+        return requiresAuxiliaryBuffer;
+    }
 
-  public boolean mightContainRefinements() {
-    return mightContainRefinements;
-  }
+    public boolean mightContainRefinements()
+    {
+        return mightContainRefinements;
+    }
 
-  public boolean isLossless() {
-    return isLossless;
-  }
+    public boolean isLossless()
+    {
+        return isLossless;
+    }
 
-  protected int getBitmapWidth() {
-    return bitmapWidth;
-  }
+    protected int getBitmapWidth()
+    {
+        return bitmapWidth;
+    }
 
-  protected int getBitmapHeight() {
-    return bitmapHeight;
-  }
+    protected int getBitmapHeight()
+    {
+        return bitmapHeight;
+    }
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java 
b/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
index 160d8fa..dccb7cc 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
@@ -33,188 +33,216 @@ import org.apache.pdfbox.jbig2.util.log.LoggerFactory;
 /**
  * This class represents the segment type "Pattern dictionary", 7.4.4.
  */
-public class PatternDictionary implements Dictionary {
+public class PatternDictionary implements Dictionary
+{
 
-  private final Logger log = LoggerFactory.getLogger(PatternDictionary.class);
+    private final Logger log = 
LoggerFactory.getLogger(PatternDictionary.class);
 
-  private SubInputStream subInputStream;
+    private SubInputStream subInputStream;
 
-  /** Segment data structure (only necessary if MMR is used) */
-  private long dataHeaderOffset;
-  private long dataHeaderLength;
-  private long dataOffset;
-  private long dataLength;
+    /** Segment data structure (only necessary if MMR is used) */
+    private long dataHeaderOffset;
+    private long dataHeaderLength;
+    private long dataOffset;
+    private long dataLength;
 
-  private short[] gbAtX = null;
-  private short[] gbAtY = null;
+    private short[] gbAtX = null;
+    private short[] gbAtY = null;
 
-  /** Pattern dictionary flags, 7.4.4.1.1 */
-  private boolean isMMREncoded;
-  private byte hdTemplate;
+    /** Pattern dictionary flags, 7.4.4.1.1 */
+    private boolean isMMREncoded;
+    private byte hdTemplate;
 
-  /** Width of the patterns in the pattern dictionary, 7.4.4.1.2 */
-  private short hdpWidth;
+    /** Width of the patterns in the pattern dictionary, 7.4.4.1.2 */
+    private short hdpWidth;
 
-  /** Height of the patterns in the pattern dictionary, 7.4.4.1.3 */
-  private short hdpHeight;
+    /** Height of the patterns in the pattern dictionary, 7.4.4.1.3 */
+    private short hdpHeight;
 
-  /** Decoded bitmaps, stored to be used by segments, that refer to it */
-  private ArrayList<Bitmap> patterns;
+    /** Decoded bitmaps, stored to be used by segments, that refer to it */
+    private ArrayList<Bitmap> patterns;
 
-  /**
-   * Largest gray-scale value, 7.4.4.1.4
-   * 
-   * Value: one less than the number of patterns defined in this pattern 
dictionary
-   */
-  private int grayMax;
+    /**
+     * Largest gray-scale value, 7.4.4.1.4
+     * 
+     * Value: one less than the number of patterns defined in this pattern 
dictionary
+     */
+    private int grayMax;
 
-  private void parseHeader() throws IOException, InvalidHeaderValueException {
-    /* Bit 3-7 */
-    subInputStream.readBits(5); // Dirty read ...
+    private void parseHeader() throws IOException, InvalidHeaderValueException
+    {
+        /* Bit 3-7 */
+        subInputStream.readBits(5); // Dirty read ...
 
-    /* Bit 1-2 */
-    readTemplate();
+        /* Bit 1-2 */
+        readTemplate();
 
-    /* Bit 0 */
-    readIsMMREncoded();
+        /* Bit 0 */
+        readIsMMREncoded();
 
-    readPatternWidthAndHeight();
+        readPatternWidthAndHeight();
 
-    readGrayMax();
+        readGrayMax();
 
-    /* Segment data structure */
-    computeSegmentDataStructure();
+        /* Segment data structure */
+        computeSegmentDataStructure();
 
-    this.checkInput();
-  }
+        this.checkInput();
+    }
 
-  private void readTemplate() throws IOException {
-    /* Bit 1-2 */
-    hdTemplate = (byte) subInputStream.readBits(2);
-  }
+    private void readTemplate() throws IOException
+    {
+        /* Bit 1-2 */
+        hdTemplate = (byte) subInputStream.readBits(2);
+    }
 
-  private void readIsMMREncoded() throws IOException {
-    /* Bit 0 */
-    if (subInputStream.readBit() == 1) {
-      isMMREncoded = true;
+    private void readIsMMREncoded() throws IOException
+    {
+        /* Bit 0 */
+        if (subInputStream.readBit() == 1)
+        {
+            isMMREncoded = true;
+        }
     }
-  }
 
-  private void readPatternWidthAndHeight() throws IOException {
-    hdpWidth = subInputStream.readByte();
-    hdpHeight = subInputStream.readByte();
-  }
+    private void readPatternWidthAndHeight() throws IOException
+    {
+        hdpWidth = subInputStream.readByte();
+        hdpHeight = subInputStream.readByte();
+    }
 
-  private void readGrayMax() throws IOException {
-    grayMax = (int) (subInputStream.readBits(32) & 0xffffffff);
-  }
+    private void readGrayMax() throws IOException
+    {
+        grayMax = (int) (subInputStream.readBits(32) & 0xffffffff);
+    }
 
-  private void computeSegmentDataStructure() throws IOException {
-    dataOffset = subInputStream.getStreamPosition();
-    dataHeaderLength = dataOffset - dataHeaderOffset;
-    dataLength = subInputStream.length() - dataHeaderLength;
-  }
+    private void computeSegmentDataStructure() throws IOException
+    {
+        dataOffset = subInputStream.getStreamPosition();
+        dataHeaderLength = dataOffset - dataHeaderOffset;
+        dataLength = subInputStream.length() - dataHeaderLength;
+    }
 
-  private void checkInput() throws InvalidHeaderValueException {
-    if (hdpHeight < 1 || hdpWidth < 1) {
-      throw new InvalidHeaderValueException("Width/Heigth must be greater than 
zero.");
+    private void checkInput() throws InvalidHeaderValueException
+    {
+        if (hdpHeight < 1 || hdpWidth < 1)
+        {
+            throw new InvalidHeaderValueException("Width/Heigth must be 
greater than zero.");
+        }
+
+        if (isMMREncoded)
+        {
+            if (hdTemplate != 0)
+            {
+                log.info("hdTemplate should contain the value 0");
+            }
+        }
     }
 
-    if (isMMREncoded) {
-      if (hdTemplate != 0) {
-        log.info("hdTemplate should contain the value 0");
-      }
+    /**
+     * This method decodes a pattern dictionary segment and returns an array 
of {@link Bitmap} s. Each of this
+     * {@link Bitmap}s is a pattern.<br>
+     * The procedure is described in 6.7.5 (page 43).
+     * 
+     * @return An array of {@link Bitmap}s as result of the decoding procedure.
+     */
+    public ArrayList<Bitmap> getDictionary() throws IOException, 
InvalidHeaderValueException
+    {
+        if (null == patterns)
+        {
+
+            if (!isMMREncoded)
+            {
+                setGbAtPixels();
+            }
+
+            // 2)
+            final GenericRegion genericRegion = new 
GenericRegion(subInputStream);
+            genericRegion.setParameters(isMMREncoded, dataOffset, dataLength, 
hdpHeight,
+                    (grayMax + 1) * hdpWidth, hdTemplate, false, false, gbAtX, 
gbAtY);
+
+            final Bitmap collectiveBitmap = genericRegion.getRegionBitmap();
+
+            // 4)
+            extractPatterns(collectiveBitmap);
+        }
+
+        return patterns;
     }
-  }
 
-  /**
-   * This method decodes a pattern dictionary segment and returns an array of 
{@link Bitmap} s. Each
-   * of this {@link Bitmap}s is a pattern.<br>
-   * The procedure is described in 6.7.5 (page 43).
-   * 
-   * @return An array of {@link Bitmap}s as result of the decoding procedure.
-   */
-  public ArrayList<Bitmap> getDictionary() throws IOException, 
InvalidHeaderValueException {
-    if (null == patterns) {
+    private void extractPatterns(Bitmap collectiveBitmap)
+    {
+        // 3)
+        int gray = 0;
+        patterns = new ArrayList<Bitmap>(grayMax + 1);
+
+        // 4)
+        while (gray <= grayMax)
+        {
+            // 4) a) Retrieve a pattern bitmap by extracting it out of the 
collective bitmap
+            final Rectangle roi = new Rectangle(hdpWidth * gray, 0, hdpWidth, 
hdpHeight);
+            final Bitmap patternBitmap = Bitmaps.extract(roi, 
collectiveBitmap);
+            patterns.add(patternBitmap);
+
+            // 4) b)
+            gray++;
+        }
+    }
 
-      if (!isMMREncoded) {
-        setGbAtPixels();
-      }
-
-      // 2)
-      final GenericRegion genericRegion = new GenericRegion(subInputStream);
-      genericRegion.setParameters(isMMREncoded, dataOffset, dataLength, 
hdpHeight, (grayMax + 1) * hdpWidth,
-          hdTemplate, false, false, gbAtX, gbAtY);
-
-      final Bitmap collectiveBitmap = genericRegion.getRegionBitmap();
+    private void setGbAtPixels()
+    {
+        if (hdTemplate == 0)
+        {
+            gbAtX = new short[4];
+            gbAtY = new short[4];
+            gbAtX[0] = (short) -hdpWidth;
+            gbAtY[0] = 0;
+            gbAtX[1] = -3;
+            gbAtY[1] = -1;
+            gbAtX[2] = 2;
+            gbAtY[2] = -2;
+            gbAtX[3] = -2;
+            gbAtY[3] = -2;
+
+        }
+        else
+        {
+            gbAtX = new short[1];
+            gbAtY = new short[1];
+            gbAtX[0] = (short) -hdpWidth;
+            gbAtY[0] = 0;
+        }
+    }
 
-      // 4)
-      extractPatterns(collectiveBitmap);
+    public void init(SegmentHeader header, SubInputStream sis)
+            throws InvalidHeaderValueException, IOException
+    {
+        this.subInputStream = sis;
+        parseHeader();
     }
 
-    return patterns;
-  }
+    protected boolean isMMREncoded()
+    {
+        return isMMREncoded;
+    }
+
+    protected byte getHdTemplate()
+    {
+        return hdTemplate;
+    }
 
-  private void extractPatterns(Bitmap collectiveBitmap) {
-    // 3)
-    int gray = 0;
-    patterns = new ArrayList<Bitmap>(grayMax + 1);
-
-    // 4)
-    while (gray <= grayMax) {
-      // 4) a) Retrieve a pattern bitmap by extracting it out of the 
collective bitmap
-      final Rectangle roi = new Rectangle(hdpWidth * gray, 0, hdpWidth, 
hdpHeight);
-      final Bitmap patternBitmap = Bitmaps.extract(roi, collectiveBitmap);
-      patterns.add(patternBitmap);
+    protected short getHdpWidth()
+    {
+        return hdpWidth;
+    }
 
-      // 4) b)
-      gray++;
-    }
-  }
+    protected short getHdpHeight()
+    {
+        return hdpHeight;
+    }
 
-  private void setGbAtPixels() {
-    if (hdTemplate == 0) {
-      gbAtX = new short[4];
-      gbAtY = new short[4];
-      gbAtX[0] = (short) -hdpWidth;
-      gbAtY[0] = 0;
-      gbAtX[1] = -3;
-      gbAtY[1] = -1;
-      gbAtX[2] = 2;
-      gbAtY[2] = -2;
-      gbAtX[3] = -2;
-      gbAtY[3] = -2;
-
-    } else {
-      gbAtX = new short[1];
-      gbAtY = new short[1];
-      gbAtX[0] = (short) -hdpWidth;
-      gbAtY[0] = 0;
-    }
-  }
-
-  public void init(SegmentHeader header, SubInputStream sis) throws 
InvalidHeaderValueException, IOException {
-    this.subInputStream = sis;
-    parseHeader();
-  }
-
-  protected boolean isMMREncoded() {
-    return isMMREncoded;
-  }
-
-  protected byte getHdTemplate() {
-    return hdTemplate;
-  }
-
-  protected short getHdpWidth() {
-    return hdpWidth;
-  }
-
-  protected short getHdpHeight() {
-    return hdpHeight;
-  }
-
-  protected int getGrayMax() {
-    return grayMax;
-  }
+    protected int getGrayMax()
+    {
+        return grayMax;
+    }
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/Profiles.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/segments/Profiles.java 
b/src/main/java/org/apache/pdfbox/jbig2/segments/Profiles.java
index e5eee40..9caecc9 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/Profiles.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/Profiles.java
@@ -24,8 +24,10 @@ import org.apache.pdfbox.jbig2.io.SubInputStream;
 /**
  * <b>TODO:</b> This class is not implemented yet and empty. Wait for use 
cases.
  */
-public class Profiles implements SegmentData {
+public class Profiles implements SegmentData
+{
 
-  public void init(SegmentHeader header, SubInputStream sis) {
-  }
+    public void init(SegmentHeader header, SubInputStream sis)
+    {
+    }
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformation.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformation.java 
b/src/main/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformation.java
index 6cbd9a2..2ade128 100644
--- 
a/src/main/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformation.java
+++ 
b/src/main/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformation.java
@@ -30,78 +30,92 @@ import org.apache.pdfbox.jbig2.util.CombinationOperator;
  * This class represents the "Region segment information" field, 7.4.1 (page 
50). <br>
  * Every region segment data starts with this part.
  */
-public class RegionSegmentInformation implements SegmentData {
-
-  private SubInputStream subInputStream;
-
-  /** Region segment bitmap width, 7.4.1.1 */
-  private int bitmapWidth;
-
-  /** Region segment bitmap height, 7.4.1.2 */
-  private int bitmapHeight;
-
-  /** Region segment bitmap X location, 7.4.1.3 */
-  private int xLocation;
-
-  /** Region segment bitmap Y location, 7.4.1.4 */
-  private int yLocation;
-
-  /** Region segment flags, 7.4.1.5 */
-  private CombinationOperator combinationOperator;
-
-  public RegionSegmentInformation(SubInputStream subInputStream) {
-    this.subInputStream = subInputStream;
-  }
-
-  public RegionSegmentInformation() {
-  }
-
-  public void parseHeader() throws IOException {
-    this.bitmapWidth = ((int) (subInputStream.readBits(32) & 0xffffffff));
-    this.bitmapHeight = ((int) (subInputStream.readBits(32) & 0xffffffff));
-    this.xLocation = ((int) (subInputStream.readBits(32) & 0xffffffff));
-    this.yLocation = ((int) (subInputStream.readBits(32) & 0xffffffff));
-
-    /* Bit 3-7 */
-    subInputStream.readBits(5); // Dirty read... reserved bits are 0
-
-    /* Bit 0-2 */
-    readCombinationOperator();
-  }
-
-  private void readCombinationOperator() throws IOException {
-    this.combinationOperator = 
(CombinationOperator.translateOperatorCodeToEnum((short) 
(subInputStream.readBits(3) & 0xf)));
-  }
-
-  public void init(SegmentHeader header, SubInputStream sis) throws 
InvalidHeaderValueException,
-      IntegerMaxValueException, IOException {
-  }
-
-  public void setBitmapWidth(final int bitmapWidth) {
-    this.bitmapWidth = bitmapWidth;
-  }
-
-  public int getBitmapWidth() {
-    return bitmapWidth;
-  }
-
-  public void setBitmapHeight(final int bitmapHeight) {
-    this.bitmapHeight = bitmapHeight;
-  }
-
-  public int getBitmapHeight() {
-    return bitmapHeight;
-  }
-
-  public int getXLocation() {
-    return xLocation;
-  }
-
-  public int getYLocation() {
-    return yLocation;
-  }
-
-  public CombinationOperator getCombinationOperator() {
-    return combinationOperator;
-  }
+public class RegionSegmentInformation implements SegmentData
+{
+
+    private SubInputStream subInputStream;
+
+    /** Region segment bitmap width, 7.4.1.1 */
+    private int bitmapWidth;
+
+    /** Region segment bitmap height, 7.4.1.2 */
+    private int bitmapHeight;
+
+    /** Region segment bitmap X location, 7.4.1.3 */
+    private int xLocation;
+
+    /** Region segment bitmap Y location, 7.4.1.4 */
+    private int yLocation;
+
+    /** Region segment flags, 7.4.1.5 */
+    private CombinationOperator combinationOperator;
+
+    public RegionSegmentInformation(SubInputStream subInputStream)
+    {
+        this.subInputStream = subInputStream;
+    }
+
+    public RegionSegmentInformation()
+    {
+    }
+
+    public void parseHeader() throws IOException
+    {
+        this.bitmapWidth = ((int) (subInputStream.readBits(32) & 0xffffffff));
+        this.bitmapHeight = ((int) (subInputStream.readBits(32) & 0xffffffff));
+        this.xLocation = ((int) (subInputStream.readBits(32) & 0xffffffff));
+        this.yLocation = ((int) (subInputStream.readBits(32) & 0xffffffff));
+
+        /* Bit 3-7 */
+        subInputStream.readBits(5); // Dirty read... reserved bits are 0
+
+        /* Bit 0-2 */
+        readCombinationOperator();
+    }
+
+    private void readCombinationOperator() throws IOException
+    {
+        this.combinationOperator = (CombinationOperator
+                .translateOperatorCodeToEnum((short) 
(subInputStream.readBits(3) & 0xf)));
+    }
+
+    public void init(SegmentHeader header, SubInputStream sis)
+            throws InvalidHeaderValueException, IntegerMaxValueException, 
IOException
+    {
+    }
+
+    public void setBitmapWidth(final int bitmapWidth)
+    {
+        this.bitmapWidth = bitmapWidth;
+    }
+
+    public int getBitmapWidth()
+    {
+        return bitmapWidth;
+    }
+
+    public void setBitmapHeight(final int bitmapHeight)
+    {
+        this.bitmapHeight = bitmapHeight;
+    }
+
+    public int getBitmapHeight()
+    {
+        return bitmapHeight;
+    }
+
+    public int getXLocation()
+    {
+        return xLocation;
+    }
+
+    public int getYLocation()
+    {
+        return yLocation;
+    }
+
+    public CombinationOperator getCombinationOperator()
+    {
+        return combinationOperator;
+    }
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/SymbolDictionary.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/segments/SymbolDictionary.java 
b/src/main/java/org/apache/pdfbox/jbig2/segments/SymbolDictionary.java
index 4170ff1..135ef4d 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/SymbolDictionary.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/SymbolDictionary.java
@@ -40,810 +40,999 @@ 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.
+ * 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;
+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()
+    {
+    }
 
-  /** Symbol dictionary AT flags, 7.4.2.1.2 */
-  private short[] sdATX;
-  private short[] sdATY;
+    public SymbolDictionary(final SubInputStream subInputStream, final 
SegmentHeader segmentHeader)
+            throws IOException
+    {
+        this.subInputStream = subInputStream;
+        this.segmentHeader = segmentHeader;
+    }
 
-  /** Symbol dictionary refinement AT flags, 7.4.2.1.3 */
-  private short[] sdrATX;
-  private short[] sdrATY;
+    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;
+                }
+            }
+        }
 
-  /** Number of exported symbols, 7.4.2.1.4 */
-  private int amountOfExportSymbolss;
+        this.checkInput();
+    }
 
-  /** Number of new symbols, 7.4.2.1.5 */
-  private int amountOfNewSymbols;
+    private void readRegionFlags() throws IOException
+    {
+        /* Bit 13-15 */
+        subInputStream.readBits(3); // Dirty read... reserved bits must be 0
 
-  /** Further parameters */
-  private SegmentHeader segmentHeader;
-  private int amountOfImportedSymbolss;
-  private ArrayList<Bitmap> importSymbols;
-  private int amountOfDecodedSymbols;
-  private Bitmap[] newSymbols;
+        /* Bit 12 */
+        sdrTemplate = (short) subInputStream.readBit();
 
-  /** User-supplied tables * */
-  private HuffmanTable dhTable;
-  private HuffmanTable dwTable;
-  private HuffmanTable bmSizeTable;
-  private HuffmanTable aggInstTable;
+        /* Bit 10-11 */
+        sdTemplate = (byte) (subInputStream.readBits(2) & 0xf);
 
-  /** Return value of that segment */
-  private ArrayList<Bitmap> exportSymbols;
-  private ArrayList<Bitmap> sbSymbols;
+        /* Bit 9 */
+        if (subInputStream.readBit() == 1)
+        {
+            isCodingContextRetained = true;
+        }
 
-  private ArithmeticDecoder arithmeticDecoder;
-  private ArithmeticIntegerDecoder iDecoder;
+        /* Bit 8 */
+        if (subInputStream.readBit() == 1)
+        {
+            isCodingContextUsed = true;
+        }
 
-  private TextRegion textRegion;
-  private GenericRegion genericRegion;
-  private GenericRefinementRegion genericRefinementRegion;
-  private CX cx;
+        /* Bit 7 */
+        sdHuffAggInstanceSelection = (short) subInputStream.readBit();
 
-  private CX cxIADH;
-  private CX cxIADW;
-  private CX cxIAAI;
-  private CX cxIAEX;
-  private CX cxIARDX;
-  private CX cxIARDY;
-  private CX cxIADT;
+        /* Bit 6 */
+        sdHuffBMSizeSelection = (short) subInputStream.readBit();
 
-  protected CX cxIAID;
-  private int sbSymCodeLen;
+        /* Bit 4-5 */
+        sdHuffDecodeWidthSelection = (short) (subInputStream.readBits(2) & 
0xf);
 
-  public SymbolDictionary() {
-  }
+        /* Bit 2-3 */
+        sdHuffDecodeHeightSelection = (short) (subInputStream.readBits(2) & 
0xf);
 
-  public SymbolDictionary(final SubInputStream subInputStream, final 
SegmentHeader segmentHeader) throws IOException {
-    this.subInputStream = subInputStream;
-    this.segmentHeader = segmentHeader;
-  }
+        /* Bit 1 */
+        if (subInputStream.readBit() == 1)
+        {
+            useRefinementAggregation = true;
+        }
 
-  private void parseHeader() throws IOException, InvalidHeaderValueException, 
IntegerMaxValueException {
-    readRegionFlags();
-    setAtPixels();
-    setRefinementAtPixels();
-    readAmountOfExportedSymbols();
-    readAmountOfNewSymbols();
-    setInSyms();
+        /* Bit 0 */
+        if (subInputStream.readBit() == 1)
+        {
+            isHuffmanEncoded = true;
+        }
+    }
 
-    if (isCodingContextUsed) {
-      SegmentHeader[] rtSegments = segmentHeader.getRtSegments();
+    private void setAtPixels() throws IOException
+    {
+        if (!isHuffmanEncoded)
+        {
+            if (sdTemplate == 0)
+            {
+                readAtPixels(4);
+            }
+            else
+            {
+                readAtPixels(1);
+            }
+        }
+    }
 
-      for (int i = rtSegments.length - 1; i >= 0; i--) {
+    private void setRefinementAtPixels() throws IOException
+    {
+        if (useRefinementAggregation && sdrTemplate == 0)
+        {
+            readRefinementAtPixels(2);
+        }
+    }
 
-        if (rtSegments[i].getSegmentType() == 0) {
-          SymbolDictionary symbolDictionary = (SymbolDictionary) 
rtSegments[i].getSegmentData();
+    private void readAtPixels(final int amountOfPixels) throws IOException
+    {
+        sdATX = new short[amountOfPixels];
+        sdATY = new short[amountOfPixels];
 
-          if (symbolDictionary.isCodingContextRetained) {
-            /* 7.4.2.2 3) */
-            setRetainedCodingContexts(symbolDictionary);
-          }
-          break;
+        for (int i = 0; i < amountOfPixels; i++)
+        {
+            sdATX[i] = subInputStream.readByte();
+            sdATY[i] = subInputStream.readByte();
         }
-      }
     }
 
-    this.checkInput();
-  }
+    private void readRefinementAtPixels(final int amountOfAtPixels) throws 
IOException
+    {
+        sdrATX = new short[amountOfAtPixels];
+        sdrATY = new short[amountOfAtPixels];
 
-  private void readRegionFlags() throws IOException {
-    /* Bit 13-15 */
-    subInputStream.readBits(3); // Dirty read... reserved bits must be 0
-
-    /* Bit 12 */
-    sdrTemplate = (short) subInputStream.readBit();
+        for (int i = 0; i < amountOfAtPixels; i++)
+        {
+            sdrATX[i] = subInputStream.readByte();
+            sdrATY[i] = subInputStream.readByte();
+        }
+    }
 
-    /* Bit 10-11 */
-    sdTemplate = (byte) (subInputStream.readBits(2) & 0xf);
+    private void readAmountOfExportedSymbols() throws IOException
+    {
+        amountOfExportSymbolss = (int) subInputStream.readBits(32); // & 
0xffffffff;
+    }
 
-    /* Bit 9 */
-    if (subInputStream.readBit() == 1) {
-      isCodingContextRetained = true;
+    private void readAmountOfNewSymbols() throws IOException
+    {
+        amountOfNewSymbols = (int) subInputStream.readBits(32); // & 
0xffffffff;
     }
 
-    /* Bit 8 */
-    if (subInputStream.readBit() == 1) {
-      isCodingContextUsed = true;
+    private void setInSyms()
+            throws IOException, InvalidHeaderValueException, 
IntegerMaxValueException
+    {
+        if (segmentHeader.getRtSegments() != null)
+        {
+            retrieveImportSymbols();
+        }
+        else
+        {
+            importSymbols = new ArrayList<Bitmap>();
+        }
     }
 
-    /* Bit 7 */
-    sdHuffAggInstanceSelection = (short) subInputStream.readBit();
+    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;
+    }
 
-    /* Bit 6 */
-    sdHuffBMSizeSelection = (short) subInputStream.readBit();
+    private void checkInput() throws InvalidHeaderValueException
+    {
+        if (sdHuffDecodeHeightSelection == 2)
+        {
+            log.info("sdHuffDecodeHeightSelection = " + 
sdHuffDecodeHeightSelection
+                    + " (value not permitted)");
+        }
 
-    /* Bit 4-5 */
-    sdHuffDecodeWidthSelection = (short) (subInputStream.readBits(2) & 0xf);
+        if (sdHuffDecodeWidthSelection == 2)
+        {
+            log.info("sdHuffDecodeWidthSelection = " + 
sdHuffDecodeWidthSelection
+                    + " (value not permitted)");
+        }
 
-    /* Bit 2-3 */
-    sdHuffDecodeHeightSelection = (short) (subInputStream.readBits(2) & 0xf);
+        if (isHuffmanEncoded)
+        {
+            if (sdTemplate != 0)
+            {
+                log.info("sdTemplate = " + sdTemplate + " (should be 0)");
+                sdTemplate = 0;
+            }
+            if (!useRefinementAggregation)
+            {
+                if (isCodingContextRetained)
+                {
+                    log.info("isCodingContextRetained = " + 
isCodingContextRetained
+                            + " (should be 0)");
+                    isCodingContextRetained = false;
+                }
+
+                if (isCodingContextUsed)
+                {
+                    log.info("isCodingContextUsed = " + isCodingContextUsed + 
" (should be 0)");
+                    isCodingContextUsed = false;
+                }
+            }
 
-    /* Bit 1 */
-    if (subInputStream.readBit() == 1) {
-      useRefinementAggregation = true;
-    }
+        }
+        else
+        {
+            if (sdHuffBMSizeSelection != 0)
+            {
+                log.info("sdHuffBMSizeSelection should be 0");
+                sdHuffBMSizeSelection = 0;
+            }
+            if (sdHuffDecodeWidthSelection != 0)
+            {
+                log.info("sdHuffDecodeWidthSelection should be 0");
+                sdHuffDecodeWidthSelection = 0;
+            }
+            if (sdHuffDecodeHeightSelection != 0)
+            {
+                log.info("sdHuffDecodeHeightSelection should be 0");
+                sdHuffDecodeHeightSelection = 0;
+            }
+        }
 
-    /* Bit 0 */
-    if (subInputStream.readBit() == 1) {
-      isHuffmanEncoded = true;
-    }
-  }
+        if (!useRefinementAggregation)
+        {
+            if (sdrTemplate != 0)
+            {
+                log.info("sdrTemplate = " + sdrTemplate + " (should be 0)");
+                sdrTemplate = 0;
+            }
+        }
 
-  private void setAtPixels() throws IOException {
-    if (!isHuffmanEncoded) {
-      if (sdTemplate == 0) {
-        readAtPixels(4);
-      } else {
-        readAtPixels(1);
-      }
+        if (!isHuffmanEncoded || !useRefinementAggregation)
+        {
+            if (sdHuffAggInstanceSelection != 0)
+            {
+                log.info("sdHuffAggInstanceSelection = " + 
sdHuffAggInstanceSelection
+                        + " (should be 0)");
+                sdHuffAggInstanceSelection = 0;
+            }
+        }
     }
-  }
 
-  private void setRefinementAtPixels() throws IOException {
-    if (useRefinementAggregation && sdrTemplate == 0) {
-      readRefinementAtPixels(2);
-    }
-  }
+    /**
+     * 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();
+            }
 
-  private void readAtPixels(final int amountOfPixels) throws IOException {
-    sdATX = new short[amountOfPixels];
-    sdATY = new short[amountOfPixels];
+            /* 6.5.5 1) */
+            newSymbols = new Bitmap[amountOfNewSymbols];
 
-    for (int i = 0; i < amountOfPixels; i++) {
-      sdATX[i] = subInputStream.readByte();
-      sdATY[i] = subInputStream.readByte();
-    }
-  }
+            /* 6.5.5 2) */
+            int[] newSymbolsWidths = null;
+            if (isHuffmanEncoded && !useRefinementAggregation)
+            {
+                newSymbolsWidths = new int[amountOfNewSymbols];
+            }
 
-  private void readRefinementAtPixels(final int amountOfAtPixels) throws 
IOException {
-    sdrATX = new short[amountOfAtPixels];
-    sdrATY = new short[amountOfAtPixels];
+            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);
+                }
+            }
 
-    for (int i = 0; i < amountOfAtPixels; i++) {
-      sdrATX[i] = subInputStream.readByte();
-      sdrATY[i] = subInputStream.readByte();
-    }
-  }
+            /* 5) */
+            /* 6.5.10 1) - 5) */
 
-  private void readAmountOfExportedSymbols() throws IOException {
-    amountOfExportSymbolss = (int) subInputStream.readBits(32); // & 
0xffffffff;
-  }
+            final int[] exFlags = getToExportFlags();
 
-  private void readAmountOfNewSymbols() throws IOException {
-    amountOfNewSymbols = (int) subInputStream.readBits(32); // & 0xffffffff;
-  }
+            /* 6.5.10 6) - 8) */
+            setExportedSymbols(exFlags);
+        }
 
-  private void setInSyms() throws IOException, InvalidHeaderValueException, 
IntegerMaxValueException {
-    if (segmentHeader.getRtSegments() != null) {
-      retrieveImportSymbols();
-    } else {
-      importSymbols = new ArrayList<Bitmap>();
-    }
-  }
+        if (JBIG2ImageReader.PERFORMANCE_TEST)
+            log.info("SYMBOL DECODING: " + (System.currentTimeMillis() - 
timestamp) + " ms");
 
-  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;
-  }
+        // DictionaryViewer.viewSymbols(sdExSyms);
 
-  private void checkInput() throws InvalidHeaderValueException {
-    if (sdHuffDecodeHeightSelection == 2) {
-      log.info("sdHuffDecodeHeightSelection = " + sdHuffDecodeHeightSelection 
+ " (value not permitted)");
+        return exportSymbols;
     }
 
-    if (sdHuffDecodeWidthSelection == 2) {
-      log.info("sdHuffDecodeWidthSelection = " + sdHuffDecodeWidthSelection + 
" (value not permitted)");
-    }
+    private void setCodingStatistics() throws IOException
+    {
+        if (cxIADT == null)
+        {
+            cxIADT = new CX(512, 1);
+        }
 
-    if (isHuffmanEncoded) {
-      if (sdTemplate != 0) {
-        log.info("sdTemplate = " + sdTemplate + " (should be 0)");
-        sdTemplate = 0;
-      }
-      if (!useRefinementAggregation) {
-        if (isCodingContextRetained) {
-          log.info("isCodingContextRetained = " + isCodingContextRetained + " 
(should be 0)");
-          isCodingContextRetained = false;
-        }
-
-        if (isCodingContextUsed) {
-          log.info("isCodingContextUsed = " + isCodingContextUsed + " (should 
be 0)");
-          isCodingContextUsed = false;
-        }
-      }
-
-    } else {
-      if (sdHuffBMSizeSelection != 0) {
-        log.info("sdHuffBMSizeSelection should be 0");
-        sdHuffBMSizeSelection = 0;
-      }
-      if (sdHuffDecodeWidthSelection != 0) {
-        log.info("sdHuffDecodeWidthSelection should be 0");
-        sdHuffDecodeWidthSelection = 0;
-      }
-      if (sdHuffDecodeHeightSelection != 0) {
-        log.info("sdHuffDecodeHeightSelection should be 0");
-        sdHuffDecodeHeightSelection = 0;
-      }
-    }
-
-    if (!useRefinementAggregation) {
-      if (sdrTemplate != 0) {
-        log.info("sdrTemplate = " + sdrTemplate + " (should be 0)");
-        sdrTemplate = 0;
-      }
-    }
-
-    if (!isHuffmanEncoded || !useRefinementAggregation) {
-      if (sdHuffAggInstanceSelection != 0) {
-        log.info("sdHuffAggInstanceSelection = " + sdHuffAggInstanceSelection 
+ " (should be 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++;
+        if (cxIADH == null)
+        {
+            cxIADH = new CX(512, 1);
         }
 
-        /* 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();
-          }
+        if (cxIADW == null)
+        {
+            cxIADW = new CX(512, 1);
+        }
 
-          subInputStream.skipBits();
+        if (cxIAAI == null)
+        {
+            cxIAAI = new CX(512, 1);
+        }
 
-          final Bitmap heightClassCollectiveBitmap = 
decodeHeightClassCollectiveBitmap(bmSize, heightClassHeight,
-              totalWidth);
+        if (cxIAEX == null)
+        {
+            cxIAEX = new CX(512, 1);
+        }
 
-          subInputStream.skipBits();
-          decodeHeightClassBitmap(heightClassCollectiveBitmap, 
heightClassFirstSymbolIndex, heightClassHeight,
-              newSymbolsWidths);
+        if (useRefinementAggregation && cxIAID == null)
+        {
+            cxIAID = new CX(1 << sbSymCodeLen, 1);
+            cxIARDX = new CX(512, 1);
+            cxIARDY = new CX(512, 1);
         }
-      }
 
-      /* 5) */
-      /* 6.5.10 1) - 5) */
+        if (cx == null)
+        {
+            cx = new CX(65536, 1);
+        }
 
-      final int[] exFlags = getToExportFlags();
+        if (arithmeticDecoder == null)
+        {
+            arithmeticDecoder = new ArithmeticDecoder(subInputStream);
+        }
+
+        if (iDecoder == null)
+        {
+            iDecoder = new ArithmeticIntegerDecoder(arithmeticDecoder);
+        }
 
-      /* 6.5.10 6) - 8) */
-      setExportedSymbols(exFlags);
     }
 
-    if (JBIG2ImageReader.PERFORMANCE_TEST)
-      log.info("SYMBOL DECODING: " + (System.currentTimeMillis() - timestamp) 
+ " ms");
+    private final void decodeHeightClassBitmap(final Bitmap 
heightClassCollectiveBitmap,
+            final int heightClassFirstSymbol, final int heightClassHeight,
+            final int[] newSymbolsWidths)
+            throws IntegerMaxValueException, InvalidHeaderValueException, 
IOException
+    {
 
-    // DictionaryViewer.viewSymbols(sdExSyms);
+        for (int i = heightClassFirstSymbol; i < amountOfDecodedSymbols; i++)
+        {
+            int startColumn = 0;
 
-    return exportSymbols;
-  }
+            for (int j = heightClassFirstSymbol; j <= i - 1; j++)
+            {
+                startColumn += newSymbolsWidths[j];
+            }
 
-  private void setCodingStatistics() throws IOException {
-    if (cxIADT == null) {
-      cxIADT = new CX(512, 1);
+            final Rectangle roi = new Rectangle(startColumn, 0, 
newSymbolsWidths[i],
+                    heightClassHeight);
+            final Bitmap symbolBitmap = Bitmaps.extract(roi, 
heightClassCollectiveBitmap);
+            newSymbols[i] = symbolBitmap;
+            sbSymbols.add(symbolBitmap);
+        }
     }
 
-    if (cxIADH == null) {
-      cxIADH = new CX(512, 1);
-    }
+    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)
+        {
+            log.info(
+                    "Refinement or aggregate-coded symbols may couse problems 
with huffman decoding!");
+            amountOfRefinementAggregationInstances = huffDecodeRefAggNInst();
+        }
+        else
+        {
+            amountOfRefinementAggregationInstances = iDecoder.decode(cxIAAI);
+        }
 
-    if (cxIADW == null) {
-      cxIADW = new CX(512, 1);
+        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);
+        }
     }
 
-    if (cxIAAI == null) {
-      cxIAAI = new CX(512, 1);
+    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;
     }
 
-    if (cxIAEX == null) {
-      cxIAEX = new CX(512, 1);
-    }
+    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
+            );
+        }
 
-    if (useRefinementAggregation && cxIAID == null) {
-      cxIAID = new CX(1 << sbSymCodeLen, 1);
-      cxIARDX = new CX(512, 1);
-      cxIARDY = new CX(512, 1);
-    }
+        // 6.5.8.2.4 Concatenating the array used as parameter later.
+        setSymbolsArray();
 
-    if (cx == null) {
-      cx = new CX(65536, 1);
-    }
+        // 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);
 
-    if (arithmeticDecoder == null) {
-      arithmeticDecoder = new ArithmeticDecoder(subInputStream);
+        addSymbol(textRegion);
     }
 
-    if (iDecoder == null) {
-      iDecoder = new ArithmeticIntegerDecoder(arithmeticDecoder);
-    }
+    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);
 
-  private final void decodeHeightClassBitmap(final Bitmap 
heightClassCollectiveBitmap,
-      final int heightClassFirstSymbol, final int heightClassHeight, final 
int[] newSymbolsWidths)
-      throws IntegerMaxValueException, InvalidHeaderValueException, 
IOException {
+        /* 7) */
+        if (isHuffmanEncoded)
+        {
+            subInputStream.skipBits();
+            // Make sure that the processed bytes are equal to the value read 
in step 5 a)
+        }
+    }
 
-    for (int i = heightClassFirstSymbol; i < amountOfDecodedSymbols; i++) {
-      int startColumn = 0;
+    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);
+            }
 
-      for (int j = heightClassFirstSymbol; j <= i - 1; j++) {
-        startColumn += newSymbolsWidths[j];
-      }
+            if (cx == null)
+            {
+                cx = new CX(65536, 1);
+            }
+        }
 
-      final Rectangle roi = new Rectangle(startColumn, 0, newSymbolsWidths[i], 
heightClassHeight);
-      final Bitmap symbolBitmap = Bitmaps.extract(roi, 
heightClassCollectiveBitmap);
-      newSymbols[i] = symbolBitmap;
-      sbSymbols.add(symbolBitmap);
-    }
-  }
+        // Parameters as shown in Table 18, page 36
+        genericRefinementRegion.setParameters(cx, arithmeticDecoder, 
sdrTemplate, symWidth,
+                hcHeight, ibo, rdx, rdy, false, sdrATX, sdrATY);
 
-  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) {
-      log.info("Refinement or aggregate-coded symbols may couse problems with 
huffman decoding!");
-      amountOfRefinementAggregationInstances = huffDecodeRefAggNInst();
-    } else {
-      amountOfRefinementAggregationInstances = iDecoder.decode(cxIAAI);
+        addSymbol(genericRefinementRegion);
     }
 
-    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 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 long huffDecodeRefAggNInst() throws IOException, 
InvalidHeaderValueException {
-    if (sdHuffAggInstanceSelection == 0) {
-      return StandardTables.getTable(1).decode(subInputStream);
-    } else if (sdHuffAggInstanceSelection == 1) {
-      if (aggInstTable == null) {
-        int aggregationInstanceNumber = 0;
+    private final void addSymbol(final Region region)
+            throws IntegerMaxValueException, InvalidHeaderValueException, 
IOException
+    {
+        final Bitmap symbol = region.getRegionBitmap();
+        newSymbols[amountOfDecodedSymbols] = symbol;
+        sbSymbols.add(symbol);
+    }
 
-        if (sdHuffDecodeHeightSelection == 3) {
-          aggregationInstanceNumber++;
-        }
-        if (sdHuffDecodeWidthSelection == 3) {
-          aggregationInstanceNumber++;
+    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);
+            }
         }
-        if (sdHuffBMSizeSelection == 3) {
-          aggregationInstanceNumber++;
+        else
+        {
+            return iDecoder.decode(cxIADW);
         }
+        return 0;
+    }
 
-        aggInstTable = getUserTable(aggregationInstanceNumber);
-      }
-      return aggInstTable.decode(subInputStream);
+    private final long decodeHeightClassDeltaHeight()
+            throws IOException, InvalidHeaderValueException
+    {
+        if (isHuffmanEncoded)
+        {
+            return decodeHeightClassDeltaHeightWithHuffman();
+        }
+        else
+        {
+            return iDecoder.decode(cxIADH);
+        }
     }
-    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);
+    /**
+     * 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);
+        }
 
-      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
-      );
+        return 0;
     }
 
-    // 6.5.8.2.4 Concatenating the array used as parameter later.
-    setSymbolsArray();
+    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);
 
-    // 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++;
+            for (int i = 0; i < 
heightClassCollectiveBitmap.getByteArray().length; i++)
+            {
+                heightClassCollectiveBitmap.setByte(i, 
subInputStream.readByte());
             }
-            dwTable = getUserTable(dwNr);
-          }
 
-          return dwTable.decode(subInputStream);
-      }
-    } else {
-      return iDecoder.decode(cxIADW);
+            return heightClassCollectiveBitmap;
+        }
+        else
+        {
+            if (genericRegion == null)
+            {
+                genericRegion = new GenericRegion(subInputStream);
+            }
+
+            genericRegion.setParameters(true, 
subInputStream.getStreamPosition(), bmSize,
+                    heightClassHeight, totalWidth);
+
+            return genericRegion.getRegionBitmap();
+        }
     }
-    return 0;
-  }
 
-  private final long decodeHeightClassDeltaHeight() throws IOException, 
InvalidHeaderValueException {
-    if (isHuffmanEncoded) {
-      return decodeHeightClassDeltaHeightWithHuffman();
-    } else {
-      return iDecoder.decode(cxIADH);
+    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]);
+                }
+            }
+        }
     }
-  }
 
-  /**
-   * 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);
+    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 dhTable.decode(subInputStream);
+
+        return exportFlags;
     }
 
-    return 0;
-  }
+    private final long huffDecodeBmSize() throws IOException, 
InvalidHeaderValueException
+    {
+        if (bmSizeTable == null)
+        {
+            int bmNr = 0;
+
+            if (sdHuffDecodeHeightSelection == 3)
+            {
+                bmNr++;
+            }
+
+            if (sdHuffDecodeWidthSelection == 3)
+            {
+                bmNr++;
+            }
 
-  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);
+            bmSizeTable = getUserTable(bmNr);
+        }
+        return bmSizeTable.decode(subInputStream);
+    }
 
-      for (int i = 0; i < heightClassCollectiveBitmap.getByteArray().length; 
i++) {
-        heightClassCollectiveBitmap.setByte(i, subInputStream.readByte());
-      }
+    /**
+     * 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)));
+        }
+    }
 
-      return heightClassCollectiveBitmap;
-    } else {
-      if (genericRegion == null) {
-        genericRegion = new GenericRegion(subInputStream);
-      }
+    /**
+     * 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();
+        }
 
-      genericRegion.setParameters(true, subInputStream.getStreamPosition(), 
bmSize, heightClassHeight, totalWidth);
+        if (sbSymbols == null)
+        {
+            sbSymbols = new ArrayList<Bitmap>();
+            sbSymbols.addAll(importSymbols);
+        }
+    }
 
-      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)));
+    /**
+     * 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;
+            }
+        }
     }
-  }
 
-  /**
-   * 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();
-    }
+    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;
+    }
 
-    if (sbSymbols == null) {
-      sbSymbols = new ArrayList<Bitmap>();
-      sbSymbols.addAll(importSymbols);
+    public void init(final SegmentHeader header, final SubInputStream sis)
+            throws InvalidHeaderValueException, IntegerMaxValueException, 
IOException
+    {
+        this.subInputStream = sis;
+        this.segmentHeader = header;
+        parseHeader();
     }
-  }
-
-  /**
-   * 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();
-  }
 }

Reply via email to