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