You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2018/02/09 17:06:21 UTC
[06/14] pdfbox-jbig2 git commit: PDFBOX-4098: reformat the source
code, introduce an eclipse formatter definition
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java b/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
index a799f73..9e22ee9 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
@@ -35,901 +35,1057 @@ import org.apache.pdfbox.jbig2.util.log.LoggerFactory;
* Parsing is done as described in 7.4.5.<br>
* Decoding procedure is done as described in 6.2.5.7 and 7.4.6.4.
*/
-public class GenericRegion implements Region {
+public class GenericRegion implements Region
+{
- private final Logger log = LoggerFactory.getLogger(GenericRegion.class);
+ private final Logger log = LoggerFactory.getLogger(GenericRegion.class);
- private SubInputStream subInputStream;
- private long dataHeaderOffset;
- private long dataHeaderLength;
- private long dataOffset;
- private long dataLength;
+ private SubInputStream subInputStream;
+ private long dataHeaderOffset;
+ private long dataHeaderLength;
+ private long dataOffset;
+ private long dataLength;
- /** Region segment information field, 7.4.1 */
- private RegionSegmentInformation regionInfo;
+ /** Region segment information field, 7.4.1 */
+ private RegionSegmentInformation regionInfo;
- /** Generic region segment flags, 7.4.6.2 */
- private boolean useExtTemplates;
- private boolean isTPGDon;
- private byte gbTemplate;
- private boolean isMMREncoded;
+ /** Generic region segment flags, 7.4.6.2 */
+ private boolean useExtTemplates;
+ private boolean isTPGDon;
+ private byte gbTemplate;
+ private boolean isMMREncoded;
- /** Generic region segment AT flags, 7.4.6.3 */
- private short[] gbAtX;
- private short[] gbAtY;
- private boolean[] gbAtOverride;
+ /** Generic region segment AT flags, 7.4.6.3 */
+ private short[] gbAtX;
+ private short[] gbAtY;
+ private boolean[] gbAtOverride;
- /**
- * If true, AT pixels are not on their nominal location and have to be overridden
- */
- private boolean override;
+ /**
+ * If true, AT pixels are not on their nominal location and have to be overridden
+ */
+ private boolean override;
- /** Decoded data as pixel values (use row stride/width to wrap line) */
- private Bitmap regionBitmap;
+ /** Decoded data as pixel values (use row stride/width to wrap line) */
+ private Bitmap regionBitmap;
- private ArithmeticDecoder arithDecoder;
- private CX cx;
+ private ArithmeticDecoder arithDecoder;
+ private CX cx;
- private MMRDecompressor mmrDecompressor;
+ private MMRDecompressor mmrDecompressor;
- public GenericRegion() {
- }
+ public GenericRegion()
+ {
+ }
- public GenericRegion(final SubInputStream subInputStream) {
- this.subInputStream = subInputStream;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- }
+ public GenericRegion(final SubInputStream subInputStream)
+ {
+ this.subInputStream = subInputStream;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
+ }
- private void parseHeader() throws IOException, InvalidHeaderValueException {
- regionInfo.parseHeader();
+ private void parseHeader() throws IOException, InvalidHeaderValueException
+ {
+ regionInfo.parseHeader();
- /* Bit 5-7 */
- subInputStream.readBits(3); // Dirty read...
+ /* Bit 5-7 */
+ subInputStream.readBits(3); // Dirty read...
- /* Bit 4 */
- if (subInputStream.readBit() == 1) {
- useExtTemplates = true;
- }
+ /* Bit 4 */
+ if (subInputStream.readBit() == 1)
+ {
+ useExtTemplates = true;
+ }
- /* Bit 3 */
- if (subInputStream.readBit() == 1) {
- isTPGDon = true;
- }
+ /* Bit 3 */
+ if (subInputStream.readBit() == 1)
+ {
+ isTPGDon = true;
+ }
- /* Bit 1-2 */
- gbTemplate = (byte) (subInputStream.readBits(2) & 0xf);
+ /* Bit 1-2 */
+ gbTemplate = (byte) (subInputStream.readBits(2) & 0xf);
+
+ /* Bit 0 */
+ if (subInputStream.readBit() == 1)
+ {
+ isMMREncoded = true;
+ }
- /* Bit 0 */
- if (subInputStream.readBit() == 1) {
- isMMREncoded = true;
+ if (!isMMREncoded)
+ {
+ final int amountOfGbAt;
+ if (gbTemplate == 0)
+ {
+ if (useExtTemplates)
+ {
+ amountOfGbAt = 12;
+ }
+ else
+ {
+ amountOfGbAt = 4;
+ }
+ }
+ else
+ {
+ amountOfGbAt = 1;
+ }
+
+ readGbAtPixels(amountOfGbAt);
+ }
+
+ /* Segment data structure */
+ computeSegmentDataStructure();
+
+ this.checkInput();
}
- if (!isMMREncoded) {
- final int amountOfGbAt;
- if (gbTemplate == 0) {
- if (useExtTemplates) {
- amountOfGbAt = 12;
- } else {
- amountOfGbAt = 4;
+ private void readGbAtPixels(final int amountOfGbAt) throws IOException
+ {
+ gbAtX = new short[amountOfGbAt];
+ gbAtY = new short[amountOfGbAt];
+
+ for (int i = 0; i < amountOfGbAt; i++)
+ {
+ gbAtX[i] = subInputStream.readByte();
+ gbAtY[i] = subInputStream.readByte();
}
- } else {
- amountOfGbAt = 1;
- }
+ }
- readGbAtPixels(amountOfGbAt);
+ private void computeSegmentDataStructure() throws IOException
+ {
+ dataOffset = subInputStream.getStreamPosition();
+ dataHeaderLength = dataOffset - dataHeaderOffset;
+ dataLength = subInputStream.length() - dataHeaderLength;
}
- /* Segment data structure */
- computeSegmentDataStructure();
+ private void checkInput() throws InvalidHeaderValueException
+ {
+ if (isMMREncoded)
+ {
+ if (gbTemplate != 0)
+ {
+ log.info("gbTemplate should contain the value 0");
+ }
+ }
+ }
- this.checkInput();
- }
+ /**
+ * The procedure is described in 6.2.5.7, page 17.
+ *
+ * @return The decoded {@link Bitmap} of this region.
+ */
+ public Bitmap getRegionBitmap() throws IOException
+ {
+ if (null == regionBitmap)
+ {
+
+ if (isMMREncoded)
+ {
+
+ /*
+ * MMR DECODER CALL
+ */
+ if (null == mmrDecompressor)
+ {
+ mmrDecompressor = new MMRDecompressor(regionInfo.getBitmapWidth(),
+ regionInfo.getBitmapHeight(),
+ new SubInputStream(subInputStream, dataOffset, dataLength));
+ }
+
+ /* 6.2.6 */
+ regionBitmap = mmrDecompressor.uncompress();
+
+ }
+ else
+ {
+
+ /*
+ * ARITHMETIC DECODER PROCEDURE for generic region segments
+ */
+
+ updateOverrideFlags();
+
+ /* 6.2.5.7 - 1) */
+ int ltp = 0;
+
+ if (arithDecoder == null)
+ {
+ arithDecoder = new ArithmeticDecoder(subInputStream);
+ }
+ if (cx == null)
+ {
+ cx = new CX(65536, 1);
+ }
+
+ /* 6.2.5.7 - 2) */
+ regionBitmap = new Bitmap(regionInfo.getBitmapWidth(),
+ regionInfo.getBitmapHeight());
+
+ final int paddedWidth = (regionBitmap.getWidth() + 7) & -8;
+
+ /* 6.2.5.7 - 3 */
+ for (int line = 0; line < regionBitmap.getHeight(); line++)
+ {
+
+ /* 6.2.5.7 - 3 b) */
+ if (isTPGDon)
+ {
+ ltp ^= decodeSLTP();
+ }
+
+ /* 6.2.5.7 - 3 c) */
+ if (ltp == 1)
+ {
+ if (line > 0)
+ {
+ copyLineAbove(line);
+ }
+ }
+ else
+ {
+ /* 3 d) */
+ // NOT USED ATM - If corresponding pixel of SKIP bitmap is 0, set
+ // current pixel to 0. Something like that:
+ // if (useSkip) {
+ // for (int i = 1; i < rowstride; i++) {
+ // if (skip[pixel] == 1) {
+ // gbReg[pixel] = 0;
+ // }
+ // pixel++;
+ // }
+ // } else {
+ decodeLine(line, regionBitmap.getWidth(), regionBitmap.getRowStride(),
+ paddedWidth);
+ // }
+ }
+ }
+ }
+ }
- private void readGbAtPixels(final int amountOfGbAt) throws IOException {
- gbAtX = new short[amountOfGbAt];
- gbAtY = new short[amountOfGbAt];
+ // if (JBIG2ImageReader.DEBUG)
+ // if (header != null && header.getSegmentNr() == 3)
+ // new Testbild(gbReg.getByteArray(), (int) gbReg.getWidth(), (int) gbReg.getHeight(),
+ // gbReg.getRowStride());
- for (int i = 0; i < amountOfGbAt; i++) {
- gbAtX[i] = subInputStream.readByte();
- gbAtY[i] = subInputStream.readByte();
+ /* 4 */
+ return regionBitmap;
}
- }
- private void computeSegmentDataStructure() throws IOException {
- dataOffset = subInputStream.getStreamPosition();
- dataHeaderLength = dataOffset - dataHeaderOffset;
- dataLength = subInputStream.length() - dataHeaderLength;
- }
+ private int decodeSLTP() throws IOException
+ {
+ switch (gbTemplate)
+ {
+ case 0:
+ cx.setIndex(0x9b25);
+ break;
+ case 1:
+ cx.setIndex(0x795);
+ break;
+ case 2:
+ cx.setIndex(0xe5);
+ break;
+ case 3:
+ cx.setIndex(0x195);
+ break;
+ }
+ return arithDecoder.decode(cx);
+ }
- private void checkInput() throws InvalidHeaderValueException {
- if (isMMREncoded) {
- if (gbTemplate != 0) {
- log.info("gbTemplate should contain the value 0");
- }
+ private void decodeLine(final int lineNumber, final int width, final int rowStride,
+ final int paddedWidth) throws IOException
+ {
+ final int byteIndex = regionBitmap.getByteIndex(0, lineNumber);
+ final int idx = byteIndex - rowStride;
+
+ switch (gbTemplate)
+ {
+ case 0:
+ if (!useExtTemplates)
+ {
+ decodeTemplate0a(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
+ }
+ else
+ {
+ decodeTemplate0b(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
+ }
+ break;
+ case 1:
+ decodeTemplate1(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
+ break;
+ case 2:
+ decodeTemplate2(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
+ break;
+ case 3:
+ decodeTemplate3(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
+ break;
+ }
}
- }
- /**
- * The procedure is described in 6.2.5.7, page 17.
- *
- * @return The decoded {@link Bitmap} of this region.
- */
- public Bitmap getRegionBitmap() throws IOException {
- if (null == regionBitmap) {
+ /**
+ * Each pixel gets the value from the corresponding pixel of the row above. Line 0 cannot get copied values (source
+ * will be -1, doesn't exist).
+ *
+ * @param lineNumber - Coordinate of the row that should be set.
+ */
+ private void copyLineAbove(final int lineNumber)
+ {
+ int targetByteIndex = lineNumber * regionBitmap.getRowStride();
+ int sourceByteIndex = targetByteIndex - regionBitmap.getRowStride();
+
+ for (int i = 0; i < regionBitmap.getRowStride(); i++)
+ {
+ // Get the byte that should be copied and put it into Bitmap
+ regionBitmap.setByte(targetByteIndex++, regionBitmap.getByte(sourceByteIndex++));
+ }
+ }
+
+ private void decodeTemplate0a(final int lineNumber, final int width, final int rowStride,
+ final int paddedWidth, int byteIndex, int idx) throws IOException
+ {
+ int context;
+ int overriddenContext = 0;
- if (isMMREncoded) {
+ int line1 = 0;
+ int line2 = 0;
- /*
- * MMR DECODER CALL
- */
- if (null == mmrDecompressor) {
- mmrDecompressor = new MMRDecompressor(regionInfo.getBitmapWidth(), regionInfo.getBitmapHeight(),
- new SubInputStream(subInputStream, dataOffset, dataLength));
+ if (lineNumber >= 1)
+ {
+ line1 = regionBitmap.getByteAsInteger(idx);
}
- /* 6.2.6 */
- regionBitmap = mmrDecompressor.uncompress();
+ if (lineNumber >= 2)
+ {
+ line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 6;
+ }
- } else {
+ context = (line1 & 0xf0) | (line2 & 0x3800);
- /*
- * ARITHMETIC DECODER PROCEDURE for generic region segments
- */
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ /* 6.2.5.7 3d */
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
- updateOverrideFlags();
+ if (lineNumber > 0)
+ {
+ line1 = (line1 << 8)
+ | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
+ }
- /* 6.2.5.7 - 1) */
- int ltp = 0;
+ if (lineNumber > 1)
+ {
+ line2 = (line2 << 8) | (nextByte < width
+ ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 6 : 0);
+ }
- if (arithDecoder == null) {
- arithDecoder = new ArithmeticDecoder(subInputStream);
- }
- if (cx == null) {
- cx = new CX(65536, 1);
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ final int toShift = 7 - minorX;
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate0a(context, (x + minorX), lineNumber,
+ result, minorX, toShift);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
+
+ int bit = arithDecoder.decode(cx);
+
+ result |= bit << toShift;
+
+ context = ((context & 0x7bf7) << 1) | bit | ((line1 >> toShift) & 0x10)
+ | ((line2 >> toShift) & 0x800);
+ }
+
+ regionBitmap.setByte(byteIndex++, result);
+ idx++;
}
+ }
- /* 6.2.5.7 - 2) */
- regionBitmap = new Bitmap(regionInfo.getBitmapWidth(), regionInfo.getBitmapHeight());
+ private void decodeTemplate0b(final int lineNumber, final int width, final int rowStride,
+ final int paddedWidth, int byteIndex, int idx) throws IOException
+ {
+ int context;
+ int overriddenContext = 0;
- final int paddedWidth = (regionBitmap.getWidth() + 7) & -8;
+ int line1 = 0;
+ int line2 = 0;
- /* 6.2.5.7 - 3 */
- for (int line = 0; line < regionBitmap.getHeight(); line++) {
+ if (lineNumber >= 1)
+ {
+ line1 = regionBitmap.getByteAsInteger(idx);
+ }
- /* 6.2.5.7 - 3 b) */
- if (isTPGDon) {
- ltp ^= decodeSLTP();
- }
+ if (lineNumber >= 2)
+ {
+ line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 6;
+ }
- /* 6.2.5.7 - 3 c) */
- if (ltp == 1) {
- if (line > 0) {
- copyLineAbove(line);
+ context = (line1 & 0xf0) | (line2 & 0x3800);
+
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ /* 6.2.5.7 3d */
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
+
+ if (lineNumber > 0)
+ {
+ line1 = (line1 << 8)
+ | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
}
- } else {
- /* 3 d) */
- // NOT USED ATM - If corresponding pixel of SKIP bitmap is 0, set
- // current pixel to 0. Something like that:
- // if (useSkip) {
- // for (int i = 1; i < rowstride; i++) {
- // if (skip[pixel] == 1) {
- // gbReg[pixel] = 0;
- // }
- // pixel++;
- // }
- // } else {
- decodeLine(line, regionBitmap.getWidth(), regionBitmap.getRowStride(), paddedWidth);
- // }
- }
- }
- }
- }
-
- // if (JBIG2ImageReader.DEBUG)
- // if (header != null && header.getSegmentNr() == 3)
- // new Testbild(gbReg.getByteArray(), (int) gbReg.getWidth(), (int) gbReg.getHeight(),
- // gbReg.getRowStride());
-
- /* 4 */
- return regionBitmap;
- }
-
- private int decodeSLTP() throws IOException {
- switch (gbTemplate){
- case 0 :
- cx.setIndex(0x9b25);
- break;
- case 1 :
- cx.setIndex(0x795);
- break;
- case 2 :
- cx.setIndex(0xe5);
- break;
- case 3 :
- cx.setIndex(0x195);
- break;
- }
- return arithDecoder.decode(cx);
- }
-
- private void decodeLine(final int lineNumber, final int width, final int rowStride, final int paddedWidth)
- throws IOException {
- final int byteIndex = regionBitmap.getByteIndex(0, lineNumber);
- final int idx = byteIndex - rowStride;
-
- switch (gbTemplate){
- case 0 :
- if (!useExtTemplates) {
- decodeTemplate0a(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
- } else {
- decodeTemplate0b(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
- }
- break;
- case 1 :
- decodeTemplate1(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
- break;
- case 2 :
- decodeTemplate2(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
- break;
- case 3 :
- decodeTemplate3(lineNumber, width, rowStride, paddedWidth, byteIndex, idx);
- break;
- }
- }
-
- /**
- * Each pixel gets the value from the corresponding pixel of the row above. Line 0 cannot get
- * copied values (source will be -1, doesn't exist).
- *
- * @param lineNumber - Coordinate of the row that should be set.
- */
- private void copyLineAbove(final int lineNumber) {
- int targetByteIndex = lineNumber * regionBitmap.getRowStride();
- int sourceByteIndex = targetByteIndex - regionBitmap.getRowStride();
-
- for (int i = 0; i < regionBitmap.getRowStride(); i++) {
- // Get the byte that should be copied and put it into Bitmap
- regionBitmap.setByte(targetByteIndex++, regionBitmap.getByte(sourceByteIndex++));
- }
- }
-
- private void decodeTemplate0a(final int lineNumber, final int width, final int rowStride, final int paddedWidth,
- int byteIndex, int idx) throws IOException {
- int context;
- int overriddenContext = 0;
-
- int line1 = 0;
- int line2 = 0;
- if (lineNumber >= 1) {
- line1 = regionBitmap.getByteAsInteger(idx);
- }
-
- if (lineNumber >= 2) {
- line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 6;
- }
+ if (lineNumber > 1)
+ {
+ line2 = (line2 << 8) | (nextByte < width
+ ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 6 : 0);
+ }
- context = (line1 & 0xf0) | (line2 & 0x3800);
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ final int toShift = 7 - minorX;
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate0b(context, (x + minorX), lineNumber,
+ result, minorX, toShift);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
+
+ final int bit = arithDecoder.decode(cx);
+
+ result |= bit << toShift;
+
+ context = ((context & 0x7bf7) << 1) | bit | ((line1 >> toShift) & 0x10)
+ | ((line2 >> toShift) & 0x800);
+ }
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- /* 6.2.5.7 3d */
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
+ regionBitmap.setByte(byteIndex++, result);
+ idx++;
+ }
+ }
- if (lineNumber > 0) {
- line1 = (line1 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
- }
+ private void decodeTemplate1(final int lineNumber, int width, final int rowStride,
+ final int paddedWidth, int byteIndex, int idx) throws IOException
+ {
+ int context;
+ int overriddenContext;
- if (lineNumber > 1) {
- line2 = (line2 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 6 : 0);
- }
+ int line1 = 0;
+ int line2 = 0;
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- final int toShift = 7 - minorX;
- if (override) {
- overriddenContext = overrideAtTemplate0a(context, (x + minorX), lineNumber, result, minorX, toShift);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
+ if (lineNumber >= 1)
+ {
+ line1 = regionBitmap.getByteAsInteger(idx);
}
- int bit = arithDecoder.decode(cx);
+ if (lineNumber >= 2)
+ {
+ line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 5;
+ }
- result |= bit << toShift;
+ context = ((line1 >> 1) & 0x1f8) | ((line2 >> 1) & 0x1e00);
- context = ((context & 0x7bf7) << 1) | bit | ((line1 >> toShift) & 0x10) | ((line2 >> toShift) & 0x800);
- }
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ /* 6.2.5.7 3d */
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
- regionBitmap.setByte(byteIndex++, result);
- idx++;
- }
- }
+ if (lineNumber >= 1)
+ {
+ line1 = (line1 << 8)
+ | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
+ }
- private void decodeTemplate0b(final int lineNumber, final int width, final int rowStride, final int paddedWidth,
- int byteIndex, int idx) throws IOException {
- int context;
- int overriddenContext = 0;
+ if (lineNumber >= 2)
+ {
+ line2 = (line2 << 8) | (nextByte < width
+ ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 5 : 0);
+ }
- int line1 = 0;
- int line2 = 0;
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate1(context, x + minorX, lineNumber, result,
+ minorX);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
+
+ final int bit = arithDecoder.decode(cx);
+
+ result |= bit << 7 - minorX;
+
+ final int toShift = 8 - minorX;
+ context = ((context & 0xefb) << 1) | bit | ((line1 >> toShift) & 0x8)
+ | ((line2 >> toShift) & 0x200);
+ }
- if (lineNumber >= 1) {
- line1 = regionBitmap.getByteAsInteger(idx);
+ regionBitmap.setByte(byteIndex++, result);
+ idx++;
+ }
}
- if (lineNumber >= 2) {
- line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 6;
- }
+ private void decodeTemplate2(final int lineNumber, final int width, final int rowStride,
+ final int paddedWidth, int byteIndex, int idx) throws IOException
+ {
+ int context;
+ int overriddenContext;
- context = (line1 & 0xf0) | (line2 & 0x3800);
+ int line1 = 0;
+ int line2 = 0;
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- /* 6.2.5.7 3d */
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
+ if (lineNumber >= 1)
+ {
+ line1 = regionBitmap.getByteAsInteger(idx);
+ }
- if (lineNumber > 0) {
- line1 = (line1 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
- }
+ if (lineNumber >= 2)
+ {
+ line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 4;
+ }
- if (lineNumber > 1) {
- line2 = (line2 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 6 : 0);
- }
+ context = ((line1 >> 3) & 0x7c) | ((line2 >> 3) & 0x380);
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- final int toShift = 7 - minorX;
- if (override) {
- overriddenContext = overrideAtTemplate0b(context, (x + minorX), lineNumber, result, minorX, toShift);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
- }
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ /* 6.2.5.7 3d */
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
+
+ if (lineNumber >= 1)
+ {
+ line1 = (line1 << 8)
+ | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
+ }
- final int bit = arithDecoder.decode(cx);
+ if (lineNumber >= 2)
+ {
+ line2 = (line2 << 8) | (nextByte < width
+ ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 4 : 0);
+ }
- result |= bit << toShift;
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
- context = ((context & 0x7bf7) << 1) | bit | ((line1 >> toShift) & 0x10) | ((line2 >> toShift) & 0x800);
- }
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate2(context, x + minorX, lineNumber, result,
+ minorX);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
- regionBitmap.setByte(byteIndex++, result);
- idx++;
- }
- }
+ final int bit = arithDecoder.decode(cx);
- private void decodeTemplate1(final int lineNumber, int width, final int rowStride, final int paddedWidth,
- int byteIndex, int idx) throws IOException {
- int context;
- int overriddenContext;
+ result |= bit << (7 - minorX);
- int line1 = 0;
- int line2 = 0;
+ final int toShift = 10 - minorX;
+ context = ((context & 0x1bd) << 1) | bit | ((line1 >> toShift) & 0x4)
+ | ((line2 >> toShift) & 0x80);
+ }
- if (lineNumber >= 1) {
- line1 = regionBitmap.getByteAsInteger(idx);
+ regionBitmap.setByte(byteIndex++, result);
+ idx++;
+ }
}
- if (lineNumber >= 2) {
- line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 5;
- }
+ private void decodeTemplate3(final int lineNumber, final int width, final int rowStride,
+ final int paddedWidth, int byteIndex, int idx) throws IOException
+ {
+ int context;
+ int overriddenContext;
- context = ((line1 >> 1) & 0x1f8) | ((line2 >> 1) & 0x1e00);
+ int line1 = 0;
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- /* 6.2.5.7 3d */
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
+ if (lineNumber >= 1)
+ {
+ line1 = regionBitmap.getByteAsInteger(idx);
+ }
- if (lineNumber >= 1) {
- line1 = (line1 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
- }
+ context = (line1 >> 1) & 0x70;
- if (lineNumber >= 2) {
- line2 = (line2 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 5 : 0);
- }
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ /* 6.2.5.7 3d */
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- if (override) {
- overriddenContext = overrideAtTemplate1(context, x + minorX, lineNumber, result, minorX);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
- }
+ if (lineNumber >= 1)
+ {
+ line1 = (line1 << 8)
+ | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
+ }
+
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
- final int bit = arithDecoder.decode(cx);
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate3(context, x + minorX, lineNumber, result,
+ minorX);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
- result |= bit << 7 - minorX;
+ final int bit = arithDecoder.decode(cx);
- final int toShift = 8 - minorX;
- context = ((context & 0xefb) << 1) | bit | ((line1 >> toShift) & 0x8) | ((line2 >> toShift) & 0x200);
- }
+ result |= bit << (7 - minorX);
+ context = ((context & 0x1f7) << 1) | bit | ((line1 >> (8 - minorX)) & 0x010);
+ }
- regionBitmap.setByte(byteIndex++, result);
- idx++;
+ regionBitmap.setByte(byteIndex++, result);
+ idx++;
+ }
}
- }
- private void decodeTemplate2(final int lineNumber, final int width, final int rowStride, final int paddedWidth,
- int byteIndex, int idx) throws IOException {
- int context;
- int overriddenContext;
+ private void updateOverrideFlags()
+ {
+ if (gbAtX == null || gbAtY == null)
+ {
+ log.info("AT pixels not set");
+ return;
+ }
- int line1 = 0;
- int line2 = 0;
+ if (gbAtX.length != gbAtY.length)
+ {
+ log.info("AT pixel inconsistent, amount of x pixels: " + gbAtX.length
+ + ", amount of y pixels:" + gbAtY.length);
+ return;
+ }
- if (lineNumber >= 1) {
- line1 = regionBitmap.getByteAsInteger(idx);
- }
+ gbAtOverride = new boolean[gbAtX.length];
- if (lineNumber >= 2) {
- line2 = regionBitmap.getByteAsInteger(idx - rowStride) << 4;
- }
+ switch (gbTemplate)
+ {
+ case 0:
+ if (!useExtTemplates)
+ {
+ if (gbAtX[0] != 3 || gbAtY[0] != -1)
+ setOverrideFlag(0);
- context = ((line1 >> 3) & 0x7c) | ((line2 >> 3) & 0x380);
+ if (gbAtX[1] != -3 || gbAtY[1] != -1)
+ setOverrideFlag(1);
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- /* 6.2.5.7 3d */
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
+ if (gbAtX[2] != 2 || gbAtY[2] != -2)
+ setOverrideFlag(2);
- if (lineNumber >= 1) {
- line1 = (line1 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
- }
+ if (gbAtX[3] != -2 || gbAtY[3] != -2)
+ setOverrideFlag(3);
- if (lineNumber >= 2) {
- line2 = (line2 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx - rowStride + 1) << 4 : 0);
- }
+ }
+ else
+ {
+ if (gbAtX[0] != -2 || gbAtY[0] != 0)
+ setOverrideFlag(0);
- for (int minorX = 0; minorX < minorWidth; minorX++) {
+ if (gbAtX[1] != 0 || gbAtY[1] != -2)
+ setOverrideFlag(1);
- if (override) {
- overriddenContext = overrideAtTemplate2(context, x + minorX, lineNumber, result, minorX);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
- }
+ if (gbAtX[2] != -2 || gbAtY[2] != -1)
+ setOverrideFlag(2);
- final int bit = arithDecoder.decode(cx);
+ if (gbAtX[3] != -1 || gbAtY[3] != -2)
+ setOverrideFlag(3);
- result |= bit << (7 - minorX);
+ if (gbAtX[4] != 1 || gbAtY[4] != -2)
+ setOverrideFlag(4);
- final int toShift = 10 - minorX;
- context = ((context & 0x1bd) << 1) | bit | ((line1 >> toShift) & 0x4) | ((line2 >> toShift) & 0x80);
- }
+ if (gbAtX[5] != 2 || gbAtY[5] != -1)
+ setOverrideFlag(5);
- regionBitmap.setByte(byteIndex++, result);
- idx++;
- }
- }
+ if (gbAtX[6] != -3 || gbAtY[6] != 0)
+ setOverrideFlag(6);
- private void decodeTemplate3(final int lineNumber, final int width, final int rowStride, final int paddedWidth,
- int byteIndex, int idx) throws IOException {
- int context;
- int overriddenContext;
+ if (gbAtX[7] != -4 || gbAtY[7] != 0)
+ setOverrideFlag(7);
- int line1 = 0;
+ if (gbAtX[8] != 2 || gbAtY[8] != -2)
+ setOverrideFlag(8);
- if (lineNumber >= 1) {
- line1 = regionBitmap.getByteAsInteger(idx);
- }
+ if (gbAtX[9] != 3 || gbAtY[9] != -1)
+ setOverrideFlag(9);
- context = (line1 >> 1) & 0x70;
+ if (gbAtX[10] != -2 || gbAtY[10] != -2)
+ setOverrideFlag(10);
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- /* 6.2.5.7 3d */
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
+ if (gbAtX[11] != -3 || gbAtY[11] != -1)
+ setOverrideFlag(11);
+ }
+ break;
+ case 1:
+ if (gbAtX[0] != 3 || gbAtY[0] != -1)
+ setOverrideFlag(0);
+ break;
+ case 2:
+ if (gbAtX[0] != 2 || gbAtY[0] != -1)
+ setOverrideFlag(0);
+ break;
+ case 3:
+ if (gbAtX[0] != 2 || gbAtY[0] != -1)
+ setOverrideFlag(0);
+ break;
+ }
- if (lineNumber >= 1) {
- line1 = (line1 << 8) | (nextByte < width ? regionBitmap.getByteAsInteger(idx + 1) : 0);
- }
+ }
- for (int minorX = 0; minorX < minorWidth; minorX++) {
+ private void setOverrideFlag(final int index)
+ {
+ gbAtOverride[index] = true;
+ override = true;
+ }
- if (override) {
- overriddenContext = overrideAtTemplate3(context, x + minorX, lineNumber, result, minorX);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
+ private int overrideAtTemplate0a(int context, final int x, final int y, final int result,
+ final int minorX, final int toShift) throws IOException
+ {
+ if (gbAtOverride[0])
+ {
+ context &= 0xffef;
+ if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
+ context |= (result >> (toShift - gbAtX[0]) & 0x1) << 4;
+ else
+ context |= getPixel(x + gbAtX[0], y + gbAtY[0]) << 4;
}
- final int bit = arithDecoder.decode(cx);
+ if (gbAtOverride[1])
+ {
+ context &= 0xfbff;
+ if (gbAtY[1] == 0 && gbAtX[1] >= -minorX)
+ context |= (result >> (toShift - gbAtX[1]) & 0x1) << 10;
+ else
+ context |= getPixel(x + gbAtX[1], y + gbAtY[1]) << 10;
+ }
- result |= bit << (7 - minorX);
- context = ((context & 0x1f7) << 1) | bit | ((line1 >> (8 - minorX)) & 0x010);
- }
+ if (gbAtOverride[2])
+ {
+ context &= 0xf7ff;
+ if (gbAtY[2] == 0 && gbAtX[2] >= -minorX)
+ context |= (result >> (toShift - gbAtX[2]) & 0x1) << 11;
+ else
+ context |= getPixel(x + gbAtX[2], y + gbAtY[2]) << 11;
+ }
- regionBitmap.setByte(byteIndex++, result);
- idx++;
+ if (gbAtOverride[3])
+ {
+ context &= 0x7fff;
+ if (gbAtY[3] == 0 && gbAtX[3] >= -minorX)
+ context |= (result >> (toShift - gbAtX[3]) & 0x1) << 15;
+ else
+ context |= getPixel(x + gbAtX[3], y + gbAtY[3]) << 15;
+ }
+ return context;
}
- }
- private void updateOverrideFlags() {
- if (gbAtX == null || gbAtY == null) {
- log.info("AT pixels not set");
- return;
+ private int overrideAtTemplate0b(int context, final int x, final int y, final int result,
+ final int minorX, final int toShift) throws IOException
+ {
+ if (gbAtOverride[0])
+ {
+ context &= 0xfffd;
+ if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
+ context |= (result >> (toShift - gbAtX[0]) & 0x1) << 1;
+ else
+ context |= getPixel(x + gbAtX[0], y + gbAtY[0]) << 1;
+ }
+
+ if (gbAtOverride[1])
+ {
+ context &= 0xdfff;
+ if (gbAtY[1] == 0 && gbAtX[1] >= -minorX)
+ context |= (result >> (toShift - gbAtX[1]) & 0x1) << 13;
+ else
+ context |= getPixel(x + gbAtX[1], y + gbAtY[1]) << 13;
+ }
+ if (gbAtOverride[2])
+ {
+ context &= 0xfdff;
+ if (gbAtY[2] == 0 && gbAtX[2] >= -minorX)
+ context |= (result >> (toShift - gbAtX[2]) & 0x1) << 9;
+ else
+ context |= getPixel(x + gbAtX[2], y + gbAtY[2]) << 9;
+ }
+ if (gbAtOverride[3])
+ {
+ context &= 0xbfff;
+ if (gbAtY[3] == 0 && gbAtX[3] >= -minorX)
+ context |= (result >> (toShift - gbAtX[3]) & 0x1) << 14;
+ else
+ context |= getPixel(x + gbAtX[3], y + gbAtY[3]) << 14;
+ }
+ if (gbAtOverride[4])
+ {
+ context &= 0xefff;
+ if (gbAtY[4] == 0 && gbAtX[4] >= -minorX)
+ context |= (result >> (toShift - gbAtX[4]) & 0x1) << 12;
+ else
+ context |= getPixel(x + gbAtX[4], y + gbAtY[4]) << 12;
+ }
+ if (gbAtOverride[5])
+ {
+ context &= 0xffdf;
+ if (gbAtY[5] == 0 && gbAtX[5] >= -minorX)
+ context |= (result >> (toShift - gbAtX[5]) & 0x1) << 5;
+ else
+ context |= getPixel(x + gbAtX[5], y + gbAtY[5]) << 5;
+ }
+ if (gbAtOverride[6])
+ {
+ context &= 0xfffb;
+ if (gbAtY[6] == 0 && gbAtX[6] >= -minorX)
+ context |= (result >> (toShift - gbAtX[6]) & 0x1) << 2;
+ else
+ context |= getPixel(x + gbAtX[6], y + gbAtY[6]) << 2;
+ }
+ if (gbAtOverride[7])
+ {
+ context &= 0xfff7;
+ if (gbAtY[7] == 0 && gbAtX[7] >= -minorX)
+ context |= (result >> (toShift - gbAtX[7]) & 0x1) << 3;
+ else
+ context |= getPixel(x + gbAtX[7], y + gbAtY[7]) << 3;
+ }
+ if (gbAtOverride[8])
+ {
+ context &= 0xf7ff;
+ if (gbAtY[8] == 0 && gbAtX[8] >= -minorX)
+ context |= (result >> (toShift - gbAtX[8]) & 0x1) << 11;
+ else
+ context |= getPixel(x + gbAtX[8], y + gbAtY[8]) << 11;
+ }
+ if (gbAtOverride[9])
+ {
+ context &= 0xffef;
+ if (gbAtY[9] == 0 && gbAtX[9] >= -minorX)
+ context |= (result >> (toShift - gbAtX[9]) & 0x1) << 4;
+ else
+ context |= getPixel(x + gbAtX[9], y + gbAtY[9]) << 4;
+ }
+ if (gbAtOverride[10])
+ {
+ context &= 0x7fff;
+ if (gbAtY[10] == 0 && gbAtX[10] >= -minorX)
+ context |= (result >> (toShift - gbAtX[10]) & 0x1) << 15;
+ else
+ context |= getPixel(x + gbAtX[10], y + gbAtY[10]) << 15;
+ }
+ if (gbAtOverride[11])
+ {
+ context &= 0xfdff;
+ if (gbAtY[11] == 0 && gbAtX[11] >= -minorX)
+ context |= (result >> (toShift - gbAtX[11]) & 0x1) << 10;
+ else
+ context |= getPixel(x + gbAtX[11], y + gbAtY[11]) << 10;
+ }
+
+ return context;
}
- if (gbAtX.length != gbAtY.length) {
- log.info("AT pixel inconsistent, amount of x pixels: " + gbAtX.length + ", amount of y pixels:" + gbAtY.length);
- return;
+ private int overrideAtTemplate1(int context, final int x, final int y, final int result,
+ final int minorX) throws IOException
+ {
+ context &= 0x1ff7;
+ if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
+ return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 3);
+ else
+ return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 3);
}
- gbAtOverride = new boolean[gbAtX.length];
+ private int overrideAtTemplate2(int context, final int x, final int y, final int result,
+ final int minorX) throws IOException
+ {
+ context &= 0x3fb;
+ if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
+ return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 2);
+ else
+ return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 2);
+ }
- switch (gbTemplate){
- case 0 :
- if (!useExtTemplates) {
- if (gbAtX[0] != 3 || gbAtY[0] != -1)
- setOverrideFlag(0);
+ private int overrideAtTemplate3(int context, final int x, final int y, final int result,
+ final int minorX) throws IOException
+ {
+ context &= 0x3ef;
+ if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
+ return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 4);
+ else
+ return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 4);
+ }
- if (gbAtX[1] != -3 || gbAtY[1] != -1)
- setOverrideFlag(1);
+ private byte getPixel(final int x, final int y) throws IOException
+ {
+ if (x < 0 || x >= regionBitmap.getWidth())
+ return 0;
- if (gbAtX[2] != 2 || gbAtY[2] != -2)
- setOverrideFlag(2);
+ if (y < 0 || y >= regionBitmap.getHeight())
+ return 0;
- if (gbAtX[3] != -2 || gbAtY[3] != -2)
- setOverrideFlag(3);
+ return regionBitmap.getPixel(x, y);
+ }
- } else {
- if (gbAtX[0] != -2 || gbAtY[0] != 0)
- setOverrideFlag(0);
+ /**
+ * Used by {@link SymbolDictionary}.
+ *
+ * @param isMMREncoded the data is MMR encoded
+ * @param dataOffset the offset
+ * @param dataLength the length of the data
+ * @param gbh bitmap height
+ * @param gbw bitmap width
+ */
+ protected void setParameters(final boolean isMMREncoded, final long dataOffset,
+ final long dataLength, final int gbh, final int gbw)
+ {
+ this.isMMREncoded = isMMREncoded;
+ this.dataOffset = dataOffset;
+ this.dataLength = dataLength;
+ this.regionInfo.setBitmapHeight(gbh);
+ this.regionInfo.setBitmapWidth(gbw);
+
+ this.mmrDecompressor = null;
+ resetBitmap();
+ }
- if (gbAtX[1] != 0 || gbAtY[1] != -2)
- setOverrideFlag(1);
+ /**
+ * @param isMMREncoded the data is MMR encoded
+ * @param sdTemplate sd template
+ * @param isTPGDon is TPGDon
+ * @param useSkip use skip
+ * @param sdATX x values gbA pixels
+ * @param sdATY y values gbA pixels
+ * @param symWidth bitmap width
+ * @param hcHeight bitmap height
+ * @param cx context for the arithmetic decoder
+ * @param arithmeticDecoder the arithmetic decode to be used
+ *
+ * Used by {@link SymbolDictionary}.
+ */
+ protected void setParameters(final boolean isMMREncoded, final byte sdTemplate,
+ final boolean isTPGDon, final boolean useSkip, final short[] sdATX, final short[] sdATY,
+ final int symWidth, final int hcHeight, final CX cx,
+ final ArithmeticDecoder arithmeticDecoder)
+ {
+ this.isMMREncoded = isMMREncoded;
+ this.gbTemplate = sdTemplate;
+ this.isTPGDon = isTPGDon;
+ this.gbAtX = sdATX;
+ this.gbAtY = sdATY;
+ this.regionInfo.setBitmapWidth(symWidth);
+ this.regionInfo.setBitmapHeight(hcHeight);
+ if (null != cx)
+ this.cx = cx;
+ if (null != arithmeticDecoder)
+ this.arithDecoder = arithmeticDecoder;
+
+ this.mmrDecompressor = null;
+ resetBitmap();
+ }
- if (gbAtX[2] != -2 || gbAtY[2] != -1)
- setOverrideFlag(2);
+ /**
+ * Used by {@link PatternDictionary} and {@link HalftoneRegion}.
+ *
+ * @param isMMREncoded the data is MMR encoded
+ * @param dataOffset the offset
+ * @param dataLength the length of the data
+ * @param gbh bitmap height
+ * @param gbw bitmap width
+ * @param gbTemplate gb template
+ * @param isTPGDon is TPGDon
+ * @param useSkip use skip
+ * @param gbAtX x values of gbA pixels
+ * @param gbAtY y values of gbA pixels
+ *
+ */
+ protected void setParameters(final boolean isMMREncoded, final long dataOffset,
+ final long dataLength, final int gbh, final int gbw, final byte gbTemplate,
+ final boolean isTPGDon, final boolean useSkip, final short[] gbAtX, final short[] gbAtY)
+ {
+ this.dataOffset = dataOffset;
+ this.dataLength = dataLength;
+
+ this.regionInfo = new RegionSegmentInformation();
+ this.regionInfo.setBitmapHeight(gbh);
+ this.regionInfo.setBitmapWidth(gbw);
+ this.gbTemplate = gbTemplate;
+
+ this.isMMREncoded = isMMREncoded;
+ this.isTPGDon = isTPGDon;
+ this.gbAtX = gbAtX;
+ this.gbAtY = gbAtY;
+ }
- if (gbAtX[3] != -1 || gbAtY[3] != -2)
- setOverrideFlag(3);
+ /**
+ * Simply sets the memory-critical bitmap of this region to {@code null}.
+ */
+ protected void resetBitmap()
+ {
+ this.regionBitmap = null;
+ }
- if (gbAtX[4] != 1 || gbAtY[4] != -2)
- setOverrideFlag(4);
+ public void init(final SegmentHeader header, final SubInputStream sis)
+ throws InvalidHeaderValueException, IOException
+ {
+ this.subInputStream = sis;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
+ parseHeader();
+ }
- if (gbAtX[5] != 2 || gbAtY[5] != -1)
- setOverrideFlag(5);
+ public RegionSegmentInformation getRegionInfo()
+ {
+ return regionInfo;
+ }
- if (gbAtX[6] != -3 || gbAtY[6] != 0)
- setOverrideFlag(6);
+ protected boolean useExtTemplates()
+ {
+ return useExtTemplates;
+ }
- if (gbAtX[7] != -4 || gbAtY[7] != 0)
- setOverrideFlag(7);
+ protected boolean isTPGDon()
+ {
+ return isTPGDon;
+ }
- if (gbAtX[8] != 2 || gbAtY[8] != -2)
- setOverrideFlag(8);
+ protected byte getGbTemplate()
+ {
+ return gbTemplate;
+ }
- if (gbAtX[9] != 3 || gbAtY[9] != -1)
- setOverrideFlag(9);
+ protected boolean isMMREncoded()
+ {
+ return isMMREncoded;
+ }
- if (gbAtX[10] != -2 || gbAtY[10] != -2)
- setOverrideFlag(10);
+ protected short[] getGbAtX()
+ {
+ return gbAtX;
+ }
- if (gbAtX[11] != -3 || gbAtY[11] != -1)
- setOverrideFlag(11);
- }
- break;
- case 1 :
- if (gbAtX[0] != 3 || gbAtY[0] != -1)
- setOverrideFlag(0);
- break;
- case 2 :
- if (gbAtX[0] != 2 || gbAtY[0] != -1)
- setOverrideFlag(0);
- break;
- case 3 :
- if (gbAtX[0] != 2 || gbAtY[0] != -1)
- setOverrideFlag(0);
- break;
- }
-
- }
-
- private void setOverrideFlag(final int index) {
- gbAtOverride[index] = true;
- override = true;
- }
-
- private int overrideAtTemplate0a(int context, final int x, final int y, final int result, final int minorX,
- final int toShift) throws IOException {
- if (gbAtOverride[0]) {
- context &= 0xffef;
- if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
- context |= (result >> (toShift - gbAtX[0]) & 0x1) << 4;
- else
- context |= getPixel(x + gbAtX[0], y + gbAtY[0]) << 4;
- }
-
- if (gbAtOverride[1]) {
- context &= 0xfbff;
- if (gbAtY[1] == 0 && gbAtX[1] >= -minorX)
- context |= (result >> (toShift - gbAtX[1]) & 0x1) << 10;
- else
- context |= getPixel(x + gbAtX[1], y + gbAtY[1]) << 10;
- }
-
- if (gbAtOverride[2]) {
- context &= 0xf7ff;
- if (gbAtY[2] == 0 && gbAtX[2] >= -minorX)
- context |= (result >> (toShift - gbAtX[2]) & 0x1) << 11;
- else
- context |= getPixel(x + gbAtX[2], y + gbAtY[2]) << 11;
- }
-
- if (gbAtOverride[3]) {
- context &= 0x7fff;
- if (gbAtY[3] == 0 && gbAtX[3] >= -minorX)
- context |= (result >> (toShift - gbAtX[3]) & 0x1) << 15;
- else
- context |= getPixel(x + gbAtX[3], y + gbAtY[3]) << 15;
- }
- return context;
- }
-
- private int overrideAtTemplate0b(int context, final int x, final int y, final int result, final int minorX,
- final int toShift) throws IOException {
- if (gbAtOverride[0]) {
- context &= 0xfffd;
- if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
- context |= (result >> (toShift - gbAtX[0]) & 0x1) << 1;
- else
- context |= getPixel(x + gbAtX[0], y + gbAtY[0]) << 1;
- }
-
- if (gbAtOverride[1]) {
- context &= 0xdfff;
- if (gbAtY[1] == 0 && gbAtX[1] >= -minorX)
- context |= (result >> (toShift - gbAtX[1]) & 0x1) << 13;
- else
- context |= getPixel(x + gbAtX[1], y + gbAtY[1]) << 13;
- }
- if (gbAtOverride[2]) {
- context &= 0xfdff;
- if (gbAtY[2] == 0 && gbAtX[2] >= -minorX)
- context |= (result >> (toShift - gbAtX[2]) & 0x1) << 9;
- else
- context |= getPixel(x + gbAtX[2], y + gbAtY[2]) << 9;
- }
- if (gbAtOverride[3]) {
- context &= 0xbfff;
- if (gbAtY[3] == 0 && gbAtX[3] >= -minorX)
- context |= (result >> (toShift - gbAtX[3]) & 0x1) << 14;
- else
- context |= getPixel(x + gbAtX[3], y + gbAtY[3]) << 14;
- }
- if (gbAtOverride[4]) {
- context &= 0xefff;
- if (gbAtY[4] == 0 && gbAtX[4] >= -minorX)
- context |= (result >> (toShift - gbAtX[4]) & 0x1) << 12;
- else
- context |= getPixel(x + gbAtX[4], y + gbAtY[4]) << 12;
- }
- if (gbAtOverride[5]) {
- context &= 0xffdf;
- if (gbAtY[5] == 0 && gbAtX[5] >= -minorX)
- context |= (result >> (toShift - gbAtX[5]) & 0x1) << 5;
- else
- context |= getPixel(x + gbAtX[5], y + gbAtY[5]) << 5;
- }
- if (gbAtOverride[6]) {
- context &= 0xfffb;
- if (gbAtY[6] == 0 && gbAtX[6] >= -minorX)
- context |= (result >> (toShift - gbAtX[6]) & 0x1) << 2;
- else
- context |= getPixel(x + gbAtX[6], y + gbAtY[6]) << 2;
- }
- if (gbAtOverride[7]) {
- context &= 0xfff7;
- if (gbAtY[7] == 0 && gbAtX[7] >= -minorX)
- context |= (result >> (toShift - gbAtX[7]) & 0x1) << 3;
- else
- context |= getPixel(x + gbAtX[7], y + gbAtY[7]) << 3;
- }
- if (gbAtOverride[8]) {
- context &= 0xf7ff;
- if (gbAtY[8] == 0 && gbAtX[8] >= -minorX)
- context |= (result >> (toShift - gbAtX[8]) & 0x1) << 11;
- else
- context |= getPixel(x + gbAtX[8], y + gbAtY[8]) << 11;
- }
- if (gbAtOverride[9]) {
- context &= 0xffef;
- if (gbAtY[9] == 0 && gbAtX[9] >= -minorX)
- context |= (result >> (toShift - gbAtX[9]) & 0x1) << 4;
- else
- context |= getPixel(x + gbAtX[9], y + gbAtY[9]) << 4;
- }
- if (gbAtOverride[10]) {
- context &= 0x7fff;
- if (gbAtY[10] == 0 && gbAtX[10] >= -minorX)
- context |= (result >> (toShift - gbAtX[10]) & 0x1) << 15;
- else
- context |= getPixel(x + gbAtX[10], y + gbAtY[10]) << 15;
- }
- if (gbAtOverride[11]) {
- context &= 0xfdff;
- if (gbAtY[11] == 0 && gbAtX[11] >= -minorX)
- context |= (result >> (toShift - gbAtX[11]) & 0x1) << 10;
- else
- context |= getPixel(x + gbAtX[11], y + gbAtY[11]) << 10;
- }
-
- return context;
- }
-
- private int overrideAtTemplate1(int context, final int x, final int y, final int result, final int minorX)
- throws IOException {
- context &= 0x1ff7;
- if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
- return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 3);
- else
- return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 3);
- }
-
- private int overrideAtTemplate2(int context, final int x, final int y, final int result, final int minorX)
- throws IOException {
- context &= 0x3fb;
- if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
- return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 2);
- else
- return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 2);
- }
-
- private int overrideAtTemplate3(int context, final int x, final int y, final int result, final int minorX)
- throws IOException {
- context &= 0x3ef;
- if (gbAtY[0] == 0 && gbAtX[0] >= -minorX)
- return (context | (result >> (7 - (minorX + gbAtX[0])) & 0x1) << 4);
- else
- return (context | getPixel(x + gbAtX[0], y + gbAtY[0]) << 4);
- }
-
- private byte getPixel(final int x, final int y) throws IOException {
- if (x < 0 || x >= regionBitmap.getWidth())
- return 0;
-
- if (y < 0 || y >= regionBitmap.getHeight())
- return 0;
-
- return regionBitmap.getPixel(x, y);
- }
-
- /**
- * Used by {@link SymbolDictionary}.
- *
- * @param isMMREncoded the data is MMR encoded
- * @param dataOffset the offset
- * @param dataLength the length of the data
- * @param gbh bitmap height
- * @param gbw bitmap width
- */
- protected void setParameters(final boolean isMMREncoded, final long dataOffset, final long dataLength, final int gbh,
- final int gbw) {
- this.isMMREncoded = isMMREncoded;
- this.dataOffset = dataOffset;
- this.dataLength = dataLength;
- this.regionInfo.setBitmapHeight(gbh);
- this.regionInfo.setBitmapWidth(gbw);
-
- this.mmrDecompressor = null;
- resetBitmap();
- }
-
- /**
- * @param isMMREncoded the data is MMR encoded
- * @param sdTemplate sd template
- * @param isTPGDon is TPGDon
- * @param useSkip use skip
- * @param sdATX x values gbA pixels
- * @param sdATY y values gbA pixels
- * @param symWidth bitmap width
- * @param hcHeight bitmap height
- * @param cx context for the arithmetic decoder
- * @param arithmeticDecoder the arithmetic decode to be used
- *
- * Used by {@link SymbolDictionary}.
- */
- protected void setParameters(final boolean isMMREncoded, final byte sdTemplate, final boolean isTPGDon,
- final boolean useSkip, final short[] sdATX, final short[] sdATY, final int symWidth, final int hcHeight,
- final CX cx, final ArithmeticDecoder arithmeticDecoder) {
- this.isMMREncoded = isMMREncoded;
- this.gbTemplate = sdTemplate;
- this.isTPGDon = isTPGDon;
- this.gbAtX = sdATX;
- this.gbAtY = sdATY;
- this.regionInfo.setBitmapWidth(symWidth);
- this.regionInfo.setBitmapHeight(hcHeight);
- if (null != cx)
- this.cx = cx;
- if (null != arithmeticDecoder)
- this.arithDecoder = arithmeticDecoder;
-
- this.mmrDecompressor = null;
- resetBitmap();
- }
-
- /**
- * Used by {@link PatternDictionary} and {@link HalftoneRegion}.
- *
- * @param isMMREncoded the data is MMR encoded
- * @param dataOffset the offset
- * @param dataLength the length of the data
- * @param gbh bitmap height
- * @param gbw bitmap width
- * @param gbTemplate gb template
- * @param isTPGDon is TPGDon
- * @param useSkip use skip
- * @param gbAtX x values of gbA pixels
- * @param gbAtY y values of gbA pixels
- *
- */
- protected void setParameters(final boolean isMMREncoded, final long dataOffset, final long dataLength, final int gbh,
- final int gbw, final byte gbTemplate, final boolean isTPGDon, final boolean useSkip, final short[] gbAtX,
- final short[] gbAtY) {
- this.dataOffset = dataOffset;
- this.dataLength = dataLength;
-
- this.regionInfo = new RegionSegmentInformation();
- this.regionInfo.setBitmapHeight(gbh);
- this.regionInfo.setBitmapWidth(gbw);
- this.gbTemplate = gbTemplate;
-
- this.isMMREncoded = isMMREncoded;
- this.isTPGDon = isTPGDon;
- this.gbAtX = gbAtX;
- this.gbAtY = gbAtY;
- }
-
- /**
- * Simply sets the memory-critical bitmap of this region to {@code null}.
- */
- protected void resetBitmap() {
- this.regionBitmap = null;
- }
-
- public void init(final SegmentHeader header, final SubInputStream sis) throws InvalidHeaderValueException,
- IOException {
- this.subInputStream = sis;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- parseHeader();
- }
-
- public RegionSegmentInformation getRegionInfo() {
- return regionInfo;
- }
-
- protected boolean useExtTemplates() {
- return useExtTemplates;
- }
-
- protected boolean isTPGDon() {
- return isTPGDon;
- }
-
- protected byte getGbTemplate() {
- return gbTemplate;
- }
-
- protected boolean isMMREncoded() {
- return isMMREncoded;
- }
-
- protected short[] getGbAtX() {
- return gbAtX;
- }
-
- protected short[] getGbAtY() {
- return gbAtY;
- }
+ protected short[] getGbAtY()
+ {
+ return gbAtY;
+ }
}
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java b/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
index 4121d58..651f4b7 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
@@ -32,378 +32,431 @@ import org.apache.pdfbox.jbig2.util.log.Logger;
import org.apache.pdfbox.jbig2.util.log.LoggerFactory;
/**
- * This class represents the data of segment type "Halftone region". Parsing is described in 7.4.5,
- * page 67. Decoding procedure in 6.6.5 and 7.4.5.2.
+ * This class represents the data of segment type "Halftone region". Parsing is described in 7.4.5, page 67. Decoding
+ * procedure in 6.6.5 and 7.4.5.2.
*/
-public class HalftoneRegion implements Region {
-
- private final Logger log = LoggerFactory.getLogger(HalftoneRegion.class);
-
- private SubInputStream subInputStream;
- private SegmentHeader segmentHeader;
- private long dataHeaderOffset;
- private long dataHeaderLength;
- private long dataOffset;
- private long dataLength;
-
- /** Region segment information field, 7.4.1 */
- private RegionSegmentInformation regionInfo;
-
- /** Halftone segment information field, 7.4.5.1.1 */
- private byte hDefaultPixel;
- private CombinationOperator hCombinationOperator;
- private boolean hSkipEnabled;
- private byte hTemplate;
- private boolean isMMREncoded;
-
- /** Halftone grid position and size, 7.4.5.1.2 */
- /** Width of the gray-scale image, 7.4.5.1.2.1 */
- private int hGridWidth;
- /** Height of the gray-scale image, 7.4.5.1.2.2 */
- private int hGridHeight;
- /** Horizontal offset of the grid, 7.4.5.1.2.3 */
- private int hGridX;
- /** Vertical offset of the grid, 7.4.5.1.2.4 */
- private int hGridY;
-
- /** Halftone grid vector, 7.4.5.1.3 */
- /** Horizontal coordinate of the halftone grid vector, 7.4.5.1.3.1 */
- private int hRegionX;
- /** Vertical coordinate of the halftone grod vector, 7.4.5.1.3.2 */
- private int hRegionY;
-
- /** Decoded data */
- private Bitmap halftoneRegionBitmap;
-
- /**
- * Previously decoded data from other regions or dictionaries, stored to use as patterns in this
- * region.
- */
- private ArrayList<Bitmap> patterns;
-
- public HalftoneRegion() {
- }
-
- public HalftoneRegion(final SubInputStream subInputStream) {
- this.subInputStream = subInputStream;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- }
-
- public HalftoneRegion(final SubInputStream subInputStream, final SegmentHeader segmentHeader) {
- this.subInputStream = subInputStream;
- this.segmentHeader = segmentHeader;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- }
-
- private void parseHeader() throws IOException, InvalidHeaderValueException {
- regionInfo.parseHeader();
-
- /* Bit 7 */
- hDefaultPixel = (byte) subInputStream.readBit();
-
- /* Bit 4-6 */
- hCombinationOperator = CombinationOperator.translateOperatorCodeToEnum((short) (subInputStream.readBits(3) & 0xf));
-
- /* Bit 3 */
- if (subInputStream.readBit() == 1) {
- hSkipEnabled = true;
+public class HalftoneRegion implements Region
+{
+
+ private final Logger log = LoggerFactory.getLogger(HalftoneRegion.class);
+
+ private SubInputStream subInputStream;
+ private SegmentHeader segmentHeader;
+ private long dataHeaderOffset;
+ private long dataHeaderLength;
+ private long dataOffset;
+ private long dataLength;
+
+ /** Region segment information field, 7.4.1 */
+ private RegionSegmentInformation regionInfo;
+
+ /** Halftone segment information field, 7.4.5.1.1 */
+ private byte hDefaultPixel;
+ private CombinationOperator hCombinationOperator;
+ private boolean hSkipEnabled;
+ private byte hTemplate;
+ private boolean isMMREncoded;
+
+ /** Halftone grid position and size, 7.4.5.1.2 */
+ /** Width of the gray-scale image, 7.4.5.1.2.1 */
+ private int hGridWidth;
+ /** Height of the gray-scale image, 7.4.5.1.2.2 */
+ private int hGridHeight;
+ /** Horizontal offset of the grid, 7.4.5.1.2.3 */
+ private int hGridX;
+ /** Vertical offset of the grid, 7.4.5.1.2.4 */
+ private int hGridY;
+
+ /** Halftone grid vector, 7.4.5.1.3 */
+ /** Horizontal coordinate of the halftone grid vector, 7.4.5.1.3.1 */
+ private int hRegionX;
+ /** Vertical coordinate of the halftone grod vector, 7.4.5.1.3.2 */
+ private int hRegionY;
+
+ /** Decoded data */
+ private Bitmap halftoneRegionBitmap;
+
+ /**
+ * Previously decoded data from other regions or dictionaries, stored to use as patterns in this region.
+ */
+ private ArrayList<Bitmap> patterns;
+
+ public HalftoneRegion()
+ {
}
- /* Bit 1-2 */
- hTemplate = (byte) (subInputStream.readBits(2) & 0xf);
+ public HalftoneRegion(final SubInputStream subInputStream)
+ {
+ this.subInputStream = subInputStream;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
+ }
- /* Bit 0 */
- if (subInputStream.readBit() == 1) {
- isMMREncoded = true;
+ public HalftoneRegion(final SubInputStream subInputStream, final SegmentHeader segmentHeader)
+ {
+ this.subInputStream = subInputStream;
+ this.segmentHeader = segmentHeader;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
}
- hGridWidth = (int) (subInputStream.readBits(32) & 0xffffffff);
- hGridHeight = (int) (subInputStream.readBits(32) & 0xffffffff);
+ private void parseHeader() throws IOException, InvalidHeaderValueException
+ {
+ regionInfo.parseHeader();
+
+ /* Bit 7 */
+ hDefaultPixel = (byte) subInputStream.readBit();
+
+ /* Bit 4-6 */
+ hCombinationOperator = CombinationOperator
+ .translateOperatorCodeToEnum((short) (subInputStream.readBits(3) & 0xf));
+
+ /* Bit 3 */
+ if (subInputStream.readBit() == 1)
+ {
+ hSkipEnabled = true;
+ }
- hGridX = (int) subInputStream.readBits(32);
- hGridY = (int) subInputStream.readBits(32);
+ /* Bit 1-2 */
+ hTemplate = (byte) (subInputStream.readBits(2) & 0xf);
- hRegionX = (int) subInputStream.readBits(16) & 0xffff;
- hRegionY = (int) subInputStream.readBits(16) & 0xffff;
+ /* Bit 0 */
+ if (subInputStream.readBit() == 1)
+ {
+ isMMREncoded = true;
+ }
- /* Segment data structure */
- computeSegmentDataStructure();
+ hGridWidth = (int) (subInputStream.readBits(32) & 0xffffffff);
+ hGridHeight = (int) (subInputStream.readBits(32) & 0xffffffff);
- this.checkInput();
- }
+ hGridX = (int) subInputStream.readBits(32);
+ hGridY = (int) subInputStream.readBits(32);
- private void computeSegmentDataStructure() throws IOException {
- dataOffset = subInputStream.getStreamPosition();
- dataHeaderLength = dataOffset - dataHeaderOffset;
- dataLength = subInputStream.length() - dataHeaderLength;
- }
+ hRegionX = (int) subInputStream.readBits(16) & 0xffff;
+ hRegionY = (int) subInputStream.readBits(16) & 0xffff;
- private void checkInput() throws InvalidHeaderValueException {
- if (isMMREncoded) {
- if (hTemplate != 0) {
- log.info("hTemplate = " + hTemplate + " (should contain the value 0)");
- }
+ /* Segment data structure */
+ computeSegmentDataStructure();
- if (hSkipEnabled) {
- log.info("hSkipEnabled 0 " + hSkipEnabled + " (should contain the value false)");
- }
+ this.checkInput();
}
- }
-
- /**
- * The procedure is described in JBIG2 ISO standard, 6.6.5.
- *
- * @return The decoded {@link Bitmap} of this region.
- *
- * @throws IOException if an underlying IO operation fails
- * @throws InvalidHeaderValueException if a segment header value is invalid
- */
- public Bitmap getRegionBitmap() throws IOException, InvalidHeaderValueException {
- if (null == halftoneRegionBitmap) {
-
- /* 6.6.5, page 40 */
- /* 1) */
- halftoneRegionBitmap = new Bitmap(regionInfo.getBitmapWidth(), regionInfo.getBitmapHeight());
-
- if (patterns == null) {
- patterns = getPatterns();
- }
-
- if (hDefaultPixel == 1) {
- Arrays.fill(halftoneRegionBitmap.getByteArray(), (byte) 0xff);
- }
-
- /* 2) */
- /*
- * 6.6.5.1 Computing hSkip - At the moment SKIP is not used... we are not able to test it.
- */
- // Bitmap hSkip;
- // if (hSkipEnabled) {
- // int hPatternHeight = (int) hPats.get(0).getHeight();
- // int hPatternWidth = (int) hPats.get(0).getWidth();
- // TODO: Set or get pattern width and height from referred
- // pattern segments. The method is called like this:
- // hSkip = computeHSkip(hPatternHeight, hPatternWidth);
- // }
-
- /* 3) */
- final int bitsPerValue = (int) Math.ceil(Math.log(patterns.size()) / Math.log(2));
-
- /* 4) */
- final int[][] grayScaleValues = grayScaleDecoding(bitsPerValue);
-
- /* 5), rendering the pattern, described in 6.6.5.2 */
- renderPattern(grayScaleValues);
+
+ private void computeSegmentDataStructure() throws IOException
+ {
+ dataOffset = subInputStream.getStreamPosition();
+ dataHeaderLength = dataOffset - dataHeaderOffset;
+ dataLength = subInputStream.length() - dataHeaderLength;
}
- /* 6) */
- return halftoneRegionBitmap;
- }
-
- /**
- * This method draws the pattern into the region bitmap ({@code htReg}), as described in 6.6.5.2,
- * page 42
- */
- private void renderPattern(final int[][] grayScaleValues) {
- int x = 0, y = 0;
-
- // 1)
- for (int m = 0; m < hGridHeight; m++) {
- // a)
- for (int n = 0; n < hGridWidth; n++) {
- // i)
- x = computeX(m, n);
- y = computeY(m, n);
-
- // ii)
- final Bitmap patternBitmap = patterns.get(grayScaleValues[m][n]);
- Bitmaps.blit(patternBitmap, halftoneRegionBitmap, (x + hGridX), (y + hGridY), hCombinationOperator);
- }
+
+ private void checkInput() throws InvalidHeaderValueException
+ {
+ if (isMMREncoded)
+ {
+ if (hTemplate != 0)
+ {
+ log.info("hTemplate = " + hTemplate + " (should contain the value 0)");
+ }
+
+ if (hSkipEnabled)
+ {
+ log.info("hSkipEnabled 0 " + hSkipEnabled + " (should contain the value false)");
+ }
+ }
}
- }
-
- /**
- * @throws IOException
- * @throws InvalidHeaderValueException
- *
- */
- private ArrayList<Bitmap> getPatterns() throws InvalidHeaderValueException, IOException {
- final ArrayList<Bitmap> patterns = new ArrayList<Bitmap>();
-
- for (SegmentHeader s : segmentHeader.getRtSegments()) {
- final PatternDictionary patternDictionary = (PatternDictionary) s.getSegmentData();
- patterns.addAll(patternDictionary.getDictionary());
+
+ /**
+ * The procedure is described in JBIG2 ISO standard, 6.6.5.
+ *
+ * @return The decoded {@link Bitmap} of this region.
+ *
+ * @throws IOException if an underlying IO operation fails
+ * @throws InvalidHeaderValueException if a segment header value is invalid
+ */
+ public Bitmap getRegionBitmap() throws IOException, InvalidHeaderValueException
+ {
+ if (null == halftoneRegionBitmap)
+ {
+
+ /* 6.6.5, page 40 */
+ /* 1) */
+ halftoneRegionBitmap = new Bitmap(regionInfo.getBitmapWidth(),
+ regionInfo.getBitmapHeight());
+
+ if (patterns == null)
+ {
+ patterns = getPatterns();
+ }
+
+ if (hDefaultPixel == 1)
+ {
+ Arrays.fill(halftoneRegionBitmap.getByteArray(), (byte) 0xff);
+ }
+
+ /* 2) */
+ /*
+ * 6.6.5.1 Computing hSkip - At the moment SKIP is not used... we are not able to test it.
+ */
+ // Bitmap hSkip;
+ // if (hSkipEnabled) {
+ // int hPatternHeight = (int) hPats.get(0).getHeight();
+ // int hPatternWidth = (int) hPats.get(0).getWidth();
+ // TODO: Set or get pattern width and height from referred
+ // pattern segments. The method is called like this:
+ // hSkip = computeHSkip(hPatternHeight, hPatternWidth);
+ // }
+
+ /* 3) */
+ final int bitsPerValue = (int) Math.ceil(Math.log(patterns.size()) / Math.log(2));
+
+ /* 4) */
+ final int[][] grayScaleValues = grayScaleDecoding(bitsPerValue);
+
+ /* 5), rendering the pattern, described in 6.6.5.2 */
+ renderPattern(grayScaleValues);
+ }
+ /* 6) */
+ return halftoneRegionBitmap;
}
- return patterns;
- }
-
- /**
- * Gray-scale image decoding procedure is special for halftone region decoding and is described in
- * Annex C.5 on page 98.
- */
- private int[][] grayScaleDecoding(final int bitsPerValue) throws IOException {
-
- short[] gbAtX = null;
- short[] gbAtY = null;
-
- if (!isMMREncoded) {
- gbAtX = new short[4];
- gbAtY = new short[4];
- // Set AT pixel values
- if (hTemplate <= 1)
- gbAtX[0] = 3;
- else if (hTemplate >= 2)
- gbAtX[0] = 2;
-
- gbAtY[0] = -1;
- gbAtX[1] = -3;
- gbAtY[1] = -1;
- gbAtX[2] = 2;
- gbAtY[2] = -2;
- gbAtX[3] = -2;
- gbAtY[3] = -2;
+ /**
+ * This method draws the pattern into the region bitmap ({@code htReg}), as described in 6.6.5.2, page 42
+ */
+ private void renderPattern(final int[][] grayScaleValues)
+ {
+ int x = 0, y = 0;
+
+ // 1)
+ for (int m = 0; m < hGridHeight; m++)
+ {
+ // a)
+ for (int n = 0; n < hGridWidth; n++)
+ {
+ // i)
+ x = computeX(m, n);
+ y = computeY(m, n);
+
+ // ii)
+ final Bitmap patternBitmap = patterns.get(grayScaleValues[m][n]);
+ Bitmaps.blit(patternBitmap, halftoneRegionBitmap, (x + hGridX), (y + hGridY),
+ hCombinationOperator);
+ }
+ }
}
- Bitmap[] grayScalePlanes = new Bitmap[bitsPerValue];
+ /**
+ * @throws IOException
+ * @throws InvalidHeaderValueException
+ *
+ */
+ private ArrayList<Bitmap> getPatterns() throws InvalidHeaderValueException, IOException
+ {
+ final ArrayList<Bitmap> patterns = new ArrayList<Bitmap>();
+
+ for (SegmentHeader s : segmentHeader.getRtSegments())
+ {
+ final PatternDictionary patternDictionary = (PatternDictionary) s.getSegmentData();
+ patterns.addAll(patternDictionary.getDictionary());
+ }
- // 1)
- GenericRegion genericRegion = new GenericRegion(subInputStream);
- genericRegion.setParameters(isMMREncoded, dataOffset, dataLength, hGridHeight, hGridWidth, hTemplate, false,
- hSkipEnabled, gbAtX, gbAtY);
+ return patterns;
+ }
- // 2)
- int j = bitsPerValue - 1;
+ /**
+ * Gray-scale image decoding procedure is special for halftone region decoding and is described in Annex C.5 on page
+ * 98.
+ */
+ private int[][] grayScaleDecoding(final int bitsPerValue) throws IOException
+ {
+
+ short[] gbAtX = null;
+ short[] gbAtY = null;
+
+ if (!isMMREncoded)
+ {
+ gbAtX = new short[4];
+ gbAtY = new short[4];
+ // Set AT pixel values
+ if (hTemplate <= 1)
+ gbAtX[0] = 3;
+ else if (hTemplate >= 2)
+ gbAtX[0] = 2;
+
+ gbAtY[0] = -1;
+ gbAtX[1] = -3;
+ gbAtY[1] = -1;
+ gbAtX[2] = 2;
+ gbAtY[2] = -2;
+ gbAtX[3] = -2;
+ gbAtY[3] = -2;
+ }
- grayScalePlanes[j] = genericRegion.getRegionBitmap();
+ Bitmap[] grayScalePlanes = new Bitmap[bitsPerValue];
- while (j > 0) {
- j--;
- genericRegion.resetBitmap();
- // 3) a)
- grayScalePlanes[j] = genericRegion.getRegionBitmap();
- // 3) b)
- grayScalePlanes = combineGrayScalePlanes(grayScalePlanes, j);
- }
+ // 1)
+ GenericRegion genericRegion = new GenericRegion(subInputStream);
+ genericRegion.setParameters(isMMREncoded, dataOffset, dataLength, hGridHeight, hGridWidth,
+ hTemplate, false, hSkipEnabled, gbAtX, gbAtY);
- // 4)
- return computeGrayScaleValues(grayScalePlanes, bitsPerValue);
- }
+ // 2)
+ int j = bitsPerValue - 1;
- private Bitmap[] combineGrayScalePlanes(Bitmap[] grayScalePlanes, int j) {
- int byteIndex = 0;
- for (int y = 0; y < grayScalePlanes[j].getHeight(); y++) {
+ grayScalePlanes[j] = genericRegion.getRegionBitmap();
- for (int x = 0; x < grayScalePlanes[j].getWidth(); x += 8) {
- final byte newValue = grayScalePlanes[j + 1].getByte(byteIndex);
- final byte oldValue = grayScalePlanes[j].getByte(byteIndex);
+ while (j > 0)
+ {
+ j--;
+ genericRegion.resetBitmap();
+ // 3) a)
+ grayScalePlanes[j] = genericRegion.getRegionBitmap();
+ // 3) b)
+ grayScalePlanes = combineGrayScalePlanes(grayScalePlanes, j);
+ }
- grayScalePlanes[j].setByte(byteIndex++, Bitmaps.combineBytes(oldValue, newValue, CombinationOperator.XOR));
- }
+ // 4)
+ return computeGrayScaleValues(grayScalePlanes, bitsPerValue);
}
- return grayScalePlanes;
- }
-
- private int[][] computeGrayScaleValues(final Bitmap[] grayScalePlanes, final int bitsPerValue) {
- // Gray-scale decoding procedure, page 98
- final int[][] grayScaleValues = new int[hGridHeight][hGridWidth];
-
- // 4)
- for (int y = 0; y < hGridHeight; y++) {
- for (int x = 0; x < hGridWidth; x += 8) {
- final int minorWidth = hGridWidth - x > 8 ? 8 : hGridWidth - x;
- int byteIndex = grayScalePlanes[0].getByteIndex(x, y);
-
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- final int i = minorX + x;
- grayScaleValues[y][i] = 0;
-
- for (int j = 0; j < bitsPerValue; j++) {
- grayScaleValues[y][i] += ((grayScalePlanes[j].getByte(byteIndex) >> (7 - i & 7)) & 1) * (1 << j);
- }
+
+ private Bitmap[] combineGrayScalePlanes(Bitmap[] grayScalePlanes, int j)
+ {
+ int byteIndex = 0;
+ for (int y = 0; y < grayScalePlanes[j].getHeight(); y++)
+ {
+
+ for (int x = 0; x < grayScalePlanes[j].getWidth(); x += 8)
+ {
+ final byte newValue = grayScalePlanes[j + 1].getByte(byteIndex);
+ final byte oldValue = grayScalePlanes[j].getByte(byteIndex);
+
+ grayScalePlanes[j].setByte(byteIndex++,
+ Bitmaps.combineBytes(oldValue, newValue, CombinationOperator.XOR));
+ }
}
- }
+ return grayScalePlanes;
}
- return grayScaleValues;
- }
- private int computeX(final int m, final int n) {
- return shiftAndFill((hGridX + m * hRegionY + n * hRegionX));
- }
+ private int[][] computeGrayScaleValues(final Bitmap[] grayScalePlanes, final int bitsPerValue)
+ {
+ // Gray-scale decoding procedure, page 98
+ final int[][] grayScaleValues = new int[hGridHeight][hGridWidth];
+
+ // 4)
+ for (int y = 0; y < hGridHeight; y++)
+ {
+ for (int x = 0; x < hGridWidth; x += 8)
+ {
+ final int minorWidth = hGridWidth - x > 8 ? 8 : hGridWidth - x;
+ int byteIndex = grayScalePlanes[0].getByteIndex(x, y);
+
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ final int i = minorX + x;
+ grayScaleValues[y][i] = 0;
+
+ for (int j = 0; j < bitsPerValue; j++)
+ {
+ grayScaleValues[y][i] += ((grayScalePlanes[j]
+ .getByte(byteIndex) >> (7 - i & 7)) & 1) * (1 << j);
+ }
+ }
+ }
+ }
+ return grayScaleValues;
+ }
- private int computeY(final int m, final int n) {
- return shiftAndFill((hGridY + m * hRegionX - n * hRegionY));
- }
+ private int computeX(final int m, final int n)
+ {
+ return shiftAndFill((hGridX + m * hRegionY + n * hRegionX));
+ }
- private int shiftAndFill(int value) {
- // shift value by 8 and let the leftmost 8 bits be 0
- value >>= 8;
+ private int computeY(final int m, final int n)
+ {
+ return shiftAndFill((hGridY + m * hRegionX - n * hRegionY));
+ }
- if (value < 0) {
- // fill the leftmost 8 bits with 1
- final int bitPosition = (int) (Math.log(Integer.highestOneBit(value)) / Math.log(2));
+ private int shiftAndFill(int value)
+ {
+ // shift value by 8 and let the leftmost 8 bits be 0
+ value >>= 8;
+
+ if (value < 0)
+ {
+ // fill the leftmost 8 bits with 1
+ final int bitPosition = (int) (Math.log(Integer.highestOneBit(value)) / Math.log(2));
+
+ for (int i = 1; i < 31 - bitPosition; i++)
+ {
+ // bit flip
+ value |= 1 << (31 - i);
+ }
+ }
- for (int i = 1; i < 31 - bitPosition; i++) {
- // bit flip
- value |= 1 << (31 - i);
- }
+ return value;
}
- return value;
- }
-
- public void init(final SegmentHeader header, final SubInputStream sis) throws InvalidHeaderValueException,
- IOException {
- this.segmentHeader = header;
- this.subInputStream = sis;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- parseHeader();
- }
+ public void init(final SegmentHeader header, final SubInputStream sis)
+ throws InvalidHeaderValueException, IOException
+ {
+ this.segmentHeader = header;
+ this.subInputStream = sis;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
+ parseHeader();
+ }
- public CombinationOperator getCombinationOperator() {
- return hCombinationOperator;
- }
+ public CombinationOperator getCombinationOperator()
+ {
+ return hCombinationOperator;
+ }
- public RegionSegmentInformation getRegionInfo() {
- return regionInfo;
- }
+ public RegionSegmentInformation getRegionInfo()
+ {
+ return regionInfo;
+ }
- protected byte getHTemplate() {
- return hTemplate;
- }
+ protected byte getHTemplate()
+ {
+ return hTemplate;
+ }
- protected boolean isHSkipEnabled() {
- return hSkipEnabled;
- }
+ protected boolean isHSkipEnabled()
+ {
+ return hSkipEnabled;
+ }
- protected boolean isMMREncoded() {
- return isMMREncoded;
- }
+ protected boolean isMMREncoded()
+ {
+ return isMMREncoded;
+ }
- protected int getHGridWidth() {
- return hGridWidth;
- }
+ protected int getHGridWidth()
+ {
+ return hGridWidth;
+ }
- protected int getHGridHeight() {
- return hGridHeight;
- }
+ protected int getHGridHeight()
+ {
+ return hGridHeight;
+ }
- protected int getHGridX() {
- return hGridX;
- }
+ protected int getHGridX()
+ {
+ return hGridX;
+ }
- protected int getHGridY() {
- return hGridY;
- }
+ protected int getHGridY()
+ {
+ return hGridY;
+ }
- protected int getHRegionX() {
- return hRegionX;
- }
+ protected int getHRegionX()
+ {
+ return hRegionX;
+ }
- protected int getHRegionY() {
- return hRegionY;
- }
+ protected int getHRegionY()
+ {
+ return hRegionY;
+ }
- protected byte getHDefaultPixel() {
- return hDefaultPixel;
- }
+ protected byte getHDefaultPixel()
+ {
+ return hDefaultPixel;
+ }
}