http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java
----------------------------------------------------------------------
diff --git
a/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java
b/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java
index c36c736..17721e2 100644
---
a/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java
+++
b/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java
@@ -31,713 +31,884 @@ import org.apache.pdfbox.jbig2.util.log.Logger;
import org.apache.pdfbox.jbig2.util.log.LoggerFactory;
/**
- * This class represents a generic refinement region and implements the
procedure described in JBIG2
- * ISO standard, 6.3 and 7.4.7.
+ * This class represents a generic refinement region and implements the
procedure described in JBIG2 ISO standard, 6.3
+ * and 7.4.7.
*/
-public class GenericRefinementRegion implements Region {
- private static final Logger log =
LoggerFactory.getLogger(GenericRefinementRegion.class);
+public class GenericRefinementRegion implements Region
+{
+ private static final Logger log =
LoggerFactory.getLogger(GenericRefinementRegion.class);
- public static abstract class Template {
- protected abstract short form(short c1, short c2, short c3, short c4,
short c5);
+ public static abstract class Template
+ {
+ protected abstract short form(short c1, short c2, short c3, short c4,
short c5);
- protected abstract void setIndex(CX cx);
- }
+ protected abstract void setIndex(CX cx);
+ }
- private static class Template0 extends Template {
+ private static class Template0 extends Template
+ {
- @Override
- protected short form(short c1, short c2, short c3, short c4, short c5) {
- return (short) ((c1 << 10) | (c2 << 7) | (c3 << 4) | (c4 << 1) | c5);
- }
+ @Override
+ protected short form(short c1, short c2, short c3, short c4, short c5)
+ {
+ return (short) ((c1 << 10) | (c2 << 7) | (c3 << 4) | (c4 << 1) |
c5);
+ }
+
+ @Override
+ protected void setIndex(CX cx)
+ {
+ // Figure 14, page 22
+ cx.setIndex(0x100);
+ }
- @Override
- protected void setIndex(CX cx) {
- // Figure 14, page 22
- cx.setIndex(0x100);
}
- }
+ private static class Template1 extends Template
+ {
+
+ @Override
+ protected short form(short c1, short c2, short c3, short c4, short c5)
+ {
+ return (short) (((c1 & 0x02) << 8) | (c2 << 6) | ((c3 & 0x03) <<
4) | (c4 << 1) | c5);
+ }
- private static class Template1 extends Template {
+ @Override
+ protected void setIndex(CX cx)
+ {
+ // Figure 15, page 22
+ cx.setIndex(0x080);
+ }
- @Override
- protected short form(short c1, short c2, short c3, short c4, short c5) {
- return (short) (((c1 & 0x02) << 8) | (c2 << 6) | ((c3 & 0x03) << 4) |
(c4 << 1) | c5);
}
- @Override
- protected void setIndex(CX cx) {
- // Figure 15, page 22
- cx.setIndex(0x080);
- }
+ private static final Template T0 = new Template0();
+ private static final Template T1 = new Template1();
+
+ private SubInputStream subInputStream;
+
+ private SegmentHeader segmentHeader;
+
+ /** Region segment information flags, 7.4.1 */
+ private RegionSegmentInformation regionInfo;
- }
-
- private static final Template T0 = new Template0();
- private static final Template T1 = new Template1();
-
- private SubInputStream subInputStream;
-
- private SegmentHeader segmentHeader;
-
- /** Region segment information flags, 7.4.1 */
- private RegionSegmentInformation regionInfo;
-
- /** Generic refinement region segment flags, 7.4.7.2 */
- private boolean isTPGROn;
- private short templateID;
-
- private Template template;
- /** Generic refinement region segment AT flags, 7.4.7.3 */
- private short grAtX[];
- private short grAtY[];
-
- /** Decoded data as pixel values (use row stride/width to wrap line) */
- private Bitmap regionBitmap;
-
- /** Variables for decoding */
- private Bitmap referenceBitmap;
- private int referenceDX;
- private int referenceDY;
-
- private ArithmeticDecoder arithDecoder;
- private CX cx;
-
- /**
- * If true, AT pixels are not on their nominal location and have to be
overridden.
- */
- private boolean override;
- private boolean[] grAtOverride;
- public GenericRefinementRegion() {
- }
-
- public GenericRefinementRegion(final SubInputStream subInputStream) {
- this.subInputStream = subInputStream;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- }
-
- public GenericRefinementRegion(final SubInputStream subInputStream, final
SegmentHeader segmentHeader) {
- this.subInputStream = subInputStream;
- this.segmentHeader = segmentHeader;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- }
-
- /**
- * Parses the flags described in JBIG2 ISO standard:
- * <ul>
- * <li>7.4.7.2 Generic refinement region segment flags</li>
- * <li>7.4.7.3 Generic refinement refion segment AT flags</li>
- * </ul>
- *
- * @throws IOException
- */
- private void parseHeader() throws IOException {
- regionInfo.parseHeader();
-
- /* Bit 2-7 */
- subInputStream.readBits(6); // Dirty read...
-
- /* Bit 1 */
- if (subInputStream.readBit() == 1) {
- isTPGROn = true;
+ /** Generic refinement region segment flags, 7.4.7.2 */
+ private boolean isTPGROn;
+ private short templateID;
+
+ private Template template;
+ /** Generic refinement region segment AT flags, 7.4.7.3 */
+ private short grAtX[];
+ private short grAtY[];
+
+ /** Decoded data as pixel values (use row stride/width to wrap line) */
+ private Bitmap regionBitmap;
+
+ /** Variables for decoding */
+ private Bitmap referenceBitmap;
+ private int referenceDX;
+ private int referenceDY;
+
+ private ArithmeticDecoder arithDecoder;
+ private CX cx;
+
+ /**
+ * If true, AT pixels are not on their nominal location and have to be
overridden.
+ */
+ private boolean override;
+ private boolean[] grAtOverride;
+
+ public GenericRefinementRegion()
+ {
}
- /* Bit 0 */
- templateID = (short) subInputStream.readBit();
-
- switch (templateID){
- case 0 :
- template = T0;
- readAtPixels();
- break;
- case 1 :
- template = T1;
- break;
+ public GenericRefinementRegion(final SubInputStream subInputStream)
+ {
+ this.subInputStream = subInputStream;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
}
- }
-
- private void readAtPixels() throws IOException {
- grAtX = new short[2];
- grAtY = new short[2];
-
- /* Byte 0 */
- grAtX[0] = subInputStream.readByte();
- /* Byte 1 */
- grAtY[0] = subInputStream.readByte();
- /* Byte 2 */
- grAtX[1] = subInputStream.readByte();
- /* Byte 3 */
- grAtY[1] = subInputStream.readByte();
- }
-
- /**
- * Decode using a template and arithmetic coding, as described in 6.3.5.6
- *
- * @throws IOException if an underlying IO operation fails
- * @throws InvalidHeaderValueException if a segment header value is invalid
- * @throws IntegerMaxValueException if the maximum value limit of an integer
is exceeded
- */
- public Bitmap getRegionBitmap() throws IOException,
IntegerMaxValueException, InvalidHeaderValueException {
- if (null == regionBitmap) {
- /* 6.3.5.6 - 1) */
- int isLineTypicalPredicted = 0;
-
- if (referenceBitmap == null) {
- // Get the reference bitmap, which is the base of refinement process
- referenceBitmap = getGrReference();
- }
-
- if (arithDecoder == null) {
- arithDecoder = new ArithmeticDecoder(subInputStream);
- }
-
- if (cx == null) {
- cx = new CX(8192, 1);
- }
-
- /* 6.3.5.6 - 2) */
- regionBitmap = new Bitmap(regionInfo.getBitmapWidth(),
regionInfo.getBitmapHeight());
-
- if (templateID == 0) {
- // AT pixel may only occur in template 0
- updateOverride();
- }
-
- final int paddedWidth = (regionBitmap.getWidth() + 7) & -8;
- final int deltaRefStride = isTPGROn ? -referenceDY *
referenceBitmap.getRowStride() : 0;
- final int yOffset = deltaRefStride + 1;
-
- /* 6.3.5.6 - 3 */
- for (int y = 0; y < regionBitmap.getHeight(); y++) {
- /* 6.3.5.6 - 3 b) */
- if (isTPGROn) {
- isLineTypicalPredicted ^= decodeSLTP();
- }
-
- if (isLineTypicalPredicted == 0) {
- /* 6.3.5.6 - 3 c) */
- decodeOptimized(y, regionBitmap.getWidth(),
regionBitmap.getRowStride(), referenceBitmap.getRowStride(),
- paddedWidth, deltaRefStride, yOffset);
- } else {
- /* 6.3.5.6 - 3 d) */
- decodeTypicalPredictedLine(y, regionBitmap.getWidth(),
regionBitmap.getRowStride(),
- referenceBitmap.getRowStride(), paddedWidth, deltaRefStride);
- }
- }
+
+ public GenericRefinementRegion(final SubInputStream subInputStream,
+ final SegmentHeader segmentHeader)
+ {
+ this.subInputStream = subInputStream;
+ this.segmentHeader = segmentHeader;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
}
- /* 6.3.5.6 - 4) */
- return regionBitmap;
- }
-
- private int decodeSLTP() throws IOException {
- template.setIndex(cx);
- return arithDecoder.decode(cx);
- }
-
- private Bitmap getGrReference() throws IntegerMaxValueException,
InvalidHeaderValueException, IOException {
- final SegmentHeader[] segments = segmentHeader.getRtSegments();
- final Region region = (Region) segments[0].getSegmentData();
-
- return region.getRegionBitmap();
- }
-
- private void decodeOptimized(final int lineNumber, final int width, final
int rowStride, final int refRowStride,
- final int paddedWidth, final int deltaRefStride, final int lineOffset)
throws IOException {
-
- // Offset of the reference bitmap with respect to the bitmap being decoded
- // For example: if referenceDY = -1, y is 1 HIGHER that currY
- final int currentLine = lineNumber - referenceDY;
- final int referenceByteIndex = referenceBitmap.getByteIndex(Math.max(0,
-referenceDX), currentLine);
-
- final int byteIndex = regionBitmap.getByteIndex(Math.max(0, referenceDX),
lineNumber);
-
- switch (templateID){
- case 0 :
- decodeTemplate(lineNumber, width, rowStride, refRowStride,
paddedWidth, deltaRefStride, lineOffset, byteIndex,
- currentLine, referenceByteIndex, T0);
- break;
- case 1 :
- decodeTemplate(lineNumber, width, rowStride, refRowStride,
paddedWidth, deltaRefStride, lineOffset, byteIndex,
- currentLine, referenceByteIndex, T1);
- break;
+
+ /**
+ * Parses the flags described in JBIG2 ISO standard:
+ * <ul>
+ * <li>7.4.7.2 Generic refinement region segment flags</li>
+ * <li>7.4.7.3 Generic refinement refion segment AT flags</li>
+ * </ul>
+ *
+ * @throws IOException
+ */
+ private void parseHeader() throws IOException
+ {
+ regionInfo.parseHeader();
+
+ /* Bit 2-7 */
+ subInputStream.readBits(6); // Dirty read...
+
+ /* Bit 1 */
+ if (subInputStream.readBit() == 1)
+ {
+ isTPGROn = true;
+ }
+
+ /* Bit 0 */
+ templateID = (short) subInputStream.readBit();
+
+ switch (templateID)
+ {
+ case 0:
+ template = T0;
+ readAtPixels();
+ break;
+ case 1:
+ template = T1;
+ break;
+ }
}
- }
+ private void readAtPixels() throws IOException
+ {
+ grAtX = new short[2];
+ grAtY = new short[2];
+
+ /* Byte 0 */
+ grAtX[0] = subInputStream.readByte();
+ /* Byte 1 */
+ grAtY[0] = subInputStream.readByte();
+ /* Byte 2 */
+ grAtX[1] = subInputStream.readByte();
+ /* Byte 3 */
+ grAtY[1] = subInputStream.readByte();
+ }
- private void decodeTemplate(final int lineNumber, final int width, final int
rowStride, final int refRowStride,
- final int paddedWidth, final int deltaRefStride, final int lineOffset,
int byteIndex, final int currentLine,
- int refByteIndex, Template templateFormation) throws IOException {
- short c1, c2, c3, c4, c5;
+ /**
+ * Decode using a template and arithmetic coding, as described in 6.3.5.6
+ *
+ * @throws IOException if an underlying IO operation fails
+ * @throws InvalidHeaderValueException if a segment header value is invalid
+ * @throws IntegerMaxValueException if the maximum value limit of an
integer is exceeded
+ */
+ public Bitmap getRegionBitmap()
+ throws IOException, IntegerMaxValueException,
InvalidHeaderValueException
+ {
+ if (null == regionBitmap)
+ {
+ /* 6.3.5.6 - 1) */
+ int isLineTypicalPredicted = 0;
+
+ if (referenceBitmap == null)
+ {
+ // Get the reference bitmap, which is the base of refinement
process
+ referenceBitmap = getGrReference();
+ }
+
+ if (arithDecoder == null)
+ {
+ arithDecoder = new ArithmeticDecoder(subInputStream);
+ }
+
+ if (cx == null)
+ {
+ cx = new CX(8192, 1);
+ }
+
+ /* 6.3.5.6 - 2) */
+ regionBitmap = new Bitmap(regionInfo.getBitmapWidth(),
regionInfo.getBitmapHeight());
+
+ if (templateID == 0)
+ {
+ // AT pixel may only occur in template 0
+ updateOverride();
+ }
+
+ final int paddedWidth = (regionBitmap.getWidth() + 7) & -8;
+ final int deltaRefStride = isTPGROn ? -referenceDY *
referenceBitmap.getRowStride() : 0;
+ final int yOffset = deltaRefStride + 1;
+
+ /* 6.3.5.6 - 3 */
+ for (int y = 0; y < regionBitmap.getHeight(); y++)
+ {
+ /* 6.3.5.6 - 3 b) */
+ if (isTPGROn)
+ {
+ isLineTypicalPredicted ^= decodeSLTP();
+ }
+
+ if (isLineTypicalPredicted == 0)
+ {
+ /* 6.3.5.6 - 3 c) */
+ decodeOptimized(y, regionBitmap.getWidth(),
regionBitmap.getRowStride(),
+ referenceBitmap.getRowStride(), paddedWidth,
deltaRefStride, yOffset);
+ }
+ else
+ {
+ /* 6.3.5.6 - 3 d) */
+ decodeTypicalPredictedLine(y, regionBitmap.getWidth(),
+ regionBitmap.getRowStride(),
referenceBitmap.getRowStride(),
+ paddedWidth, deltaRefStride);
+ }
+ }
+ }
+ /* 6.3.5.6 - 4) */
+ return regionBitmap;
+ }
- int w1, w2, w3, w4;
- w1 = w2 = w3 = w4 = 0;
+ private int decodeSLTP() throws IOException
+ {
+ template.setIndex(cx);
+ return arithDecoder.decode(cx);
+ }
- if (currentLine >= 1 && (currentLine - 1) < referenceBitmap.getHeight())
- w1 = referenceBitmap.getByteAsInteger(refByteIndex - refRowStride);
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
- w2 = referenceBitmap.getByteAsInteger(refByteIndex);
- if (currentLine >= -1 && currentLine + 1 < referenceBitmap.getHeight())
- w3 = referenceBitmap.getByteAsInteger(refByteIndex + refRowStride);
- refByteIndex++;
+ private Bitmap getGrReference()
+ throws IntegerMaxValueException, InvalidHeaderValueException,
IOException
+ {
+ final SegmentHeader[] segments = segmentHeader.getRtSegments();
+ final Region region = (Region) segments[0].getSegmentData();
- if (lineNumber >= 1) {
- w4 = regionBitmap.getByteAsInteger(byteIndex - rowStride);
+ return region.getRegionBitmap();
}
- byteIndex++;
-
- final int modReferenceDX = referenceDX % 8;
- final int shiftOffset = 6 + modReferenceDX;
- final int modRefByteIdx = refByteIndex % refRowStride;
-
- if (shiftOffset >= 0) {
- c1 = (short) ((shiftOffset >= 8 ? 0 : w1 >>> shiftOffset) & 0x07);
- c2 = (short) ((shiftOffset >= 8 ? 0 : w2 >>> shiftOffset) & 0x07);
- c3 = (short) ((shiftOffset >= 8 ? 0 : w3 >>> shiftOffset) & 0x07);
- if (shiftOffset == 6 && modRefByteIdx > 1) {
- if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight()) {
- c1 |= referenceBitmap.getByteAsInteger(refByteIndex - refRowStride -
2) << 2 & 0x04;
- }
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
- c2 |= referenceBitmap.getByteAsInteger(refByteIndex - 2) << 2 & 0x04;
- }
- if (currentLine >= -1 && currentLine + 1 <
referenceBitmap.getHeight()) {
- c3 |= referenceBitmap.getByteAsInteger(refByteIndex + refRowStride -
2) << 2 & 0x04;
- }
- }
- if (shiftOffset == 0) {
- w1 = w2 = w3 = 0;
- if (modRefByteIdx < refRowStride - 1) {
- if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
- w1 = referenceBitmap.getByteAsInteger(refByteIndex - refRowStride);
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
- w2 = referenceBitmap.getByteAsInteger(refByteIndex);
- if (currentLine >= -1 && currentLine + 1 <
referenceBitmap.getHeight())
- w3 = referenceBitmap.getByteAsInteger(refByteIndex + refRowStride);
+
+ private void decodeOptimized(final int lineNumber, final int width, final
int rowStride,
+ final int refRowStride, final int paddedWidth, final int
deltaRefStride,
+ final int lineOffset) throws IOException
+ {
+
+ // Offset of the reference bitmap with respect to the bitmap being
decoded
+ // For example: if referenceDY = -1, y is 1 HIGHER that currY
+ final int currentLine = lineNumber - referenceDY;
+ final int referenceByteIndex =
referenceBitmap.getByteIndex(Math.max(0, -referenceDX),
+ currentLine);
+
+ final int byteIndex = regionBitmap.getByteIndex(Math.max(0,
referenceDX), lineNumber);
+
+ switch (templateID)
+ {
+ case 0:
+ decodeTemplate(lineNumber, width, rowStride, refRowStride,
paddedWidth, deltaRefStride,
+ lineOffset, byteIndex, currentLine, referenceByteIndex,
T0);
+ break;
+ case 1:
+ decodeTemplate(lineNumber, width, rowStride, refRowStride,
paddedWidth, deltaRefStride,
+ lineOffset, byteIndex, currentLine, referenceByteIndex,
T1);
+ break;
}
- refByteIndex++;
- }
- } else {
- c1 = (short) ((w1 << 1) & 0x07);
- c2 = (short) ((w2 << 1) & 0x07);
- c3 = (short) ((w3 << 1) & 0x07);
- w1 = w2 = w3 = 0;
- if (modRefByteIdx < refRowStride - 1) {
- if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
- w1 = referenceBitmap.getByteAsInteger(refByteIndex - refRowStride);
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
- w2 = referenceBitmap.getByteAsInteger(refByteIndex);
- if (currentLine >= -1 && currentLine + 1 < referenceBitmap.getHeight())
- w3 = referenceBitmap.getByteAsInteger(refByteIndex + refRowStride);
- refByteIndex++;
- }
- c1 |= (short) ((w1 >>> 7) & 0x07);
- c2 |= (short) ((w2 >>> 7) & 0x07);
- c3 |= (short) ((w3 >>> 7) & 0x07);
+
}
- c4 = (short) (w4 >>> 6);
- c5 = 0;
-
- final int modBitsToTrim = (2 - modReferenceDX) % 8;
- w1 <<= modBitsToTrim;
- w2 <<= modBitsToTrim;
- w3 <<= modBitsToTrim;
-
- w4 <<= 2;
-
- for (int x = 0; x < width; x++) {
- final int minorX = x & 0x07;
-
- final short tval = templateFormation.form(c1, c2, c3, c4, c5);
-
- if (override) {
- cx.setIndex(overrideAtTemplate0(tval, x, lineNumber,
- regionBitmap.getByte(regionBitmap.getByteIndex(x, lineNumber)),
minorX));
- } else {
- cx.setIndex(tval);
- }
- final int bit = arithDecoder.decode(cx);
- regionBitmap.setPixel(x, lineNumber, (byte) bit);
-
- c1 = (short) (((c1 << 1) | 0x01 & (w1 >>> 7)) & 0x07);
- c2 = (short) (((c2 << 1) | 0x01 & (w2 >>> 7)) & 0x07);
- c3 = (short) (((c3 << 1) | 0x01 & (w3 >>> 7)) & 0x07);
- c4 = (short) (((c4 << 1) | 0x01 & (w4 >>> 7)) & 0x07);
- c5 = (short) bit;
-
- if ((x - referenceDX) % 8 == 5) {
- if (((x - referenceDX) / 8) + 1 >= referenceBitmap.getRowStride()) {
- w1 = w2 = w3 = 0;
- } else {
- if (currentLine >= 1 && (currentLine - 1 <
referenceBitmap.getHeight())) {
+ private void decodeTemplate(final int lineNumber, final int width, final
int rowStride,
+ final int refRowStride, final int paddedWidth, final int
deltaRefStride,
+ final int lineOffset, int byteIndex, final int currentLine, int
refByteIndex,
+ Template templateFormation) throws IOException
+ {
+ short c1, c2, c3, c4, c5;
+
+ int w1, w2, w3, w4;
+ w1 = w2 = w3 = w4 = 0;
+
+ if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
w1 = referenceBitmap.getByteAsInteger(refByteIndex - refRowStride);
- } else {
- w1 = 0;
- }
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
+ if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
w2 = referenceBitmap.getByteAsInteger(refByteIndex);
- } else {
- w2 = 0;
- }
- if (currentLine >= -1 && (currentLine + 1) <
referenceBitmap.getHeight()) {
+ if (currentLine >= -1 && currentLine + 1 < referenceBitmap.getHeight())
w3 = referenceBitmap.getByteAsInteger(refByteIndex + refRowStride);
- } else {
- w3 = 0;
- }
- }
refByteIndex++;
- } else {
- w1 <<= 1;
- w2 <<= 1;
- w3 <<= 1;
- }
-
- if (minorX == 5 && lineNumber >= 1) {
- if ((x >> 3) + 1 >= regionBitmap.getRowStride()) {
- w4 = 0;
- } else {
- w4 = regionBitmap.getByteAsInteger(byteIndex - rowStride);
+
+ if (lineNumber >= 1)
+ {
+ w4 = regionBitmap.getByteAsInteger(byteIndex - rowStride);
}
byteIndex++;
- } else {
- w4 <<= 1;
- }
- }
- }
+ final int modReferenceDX = referenceDX % 8;
+ final int shiftOffset = 6 + modReferenceDX;
+ final int modRefByteIdx = refByteIndex % refRowStride;
+
+ if (shiftOffset >= 0)
+ {
+ c1 = (short) ((shiftOffset >= 8 ? 0 : w1 >>> shiftOffset) & 0x07);
+ c2 = (short) ((shiftOffset >= 8 ? 0 : w2 >>> shiftOffset) & 0x07);
+ c3 = (short) ((shiftOffset >= 8 ? 0 : w3 >>> shiftOffset) & 0x07);
+ if (shiftOffset == 6 && modRefByteIdx > 1)
+ {
+ if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
+ {
+ c1 |= referenceBitmap.getByteAsInteger(refByteIndex -
refRowStride - 2) << 2
+ & 0x04;
+ }
+ if (currentLine >= 0 && currentLine <
referenceBitmap.getHeight())
+ {
+ c2 |= referenceBitmap.getByteAsInteger(refByteIndex - 2)
<< 2 & 0x04;
+ }
+ if (currentLine >= -1 && currentLine + 1 <
referenceBitmap.getHeight())
+ {
+ c3 |= referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride - 2) << 2
+ & 0x04;
+ }
+ }
+ if (shiftOffset == 0)
+ {
+ w1 = w2 = w3 = 0;
+ if (modRefByteIdx < refRowStride - 1)
+ {
+ if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
+ w1 = referenceBitmap.getByteAsInteger(refByteIndex -
refRowStride);
+ if (currentLine >= 0 && currentLine <
referenceBitmap.getHeight())
+ w2 = referenceBitmap.getByteAsInteger(refByteIndex);
+ if (currentLine >= -1 && currentLine + 1 <
referenceBitmap.getHeight())
+ w3 = referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride);
+ }
+ refByteIndex++;
+ }
+ }
+ else
+ {
+ c1 = (short) ((w1 << 1) & 0x07);
+ c2 = (short) ((w2 << 1) & 0x07);
+ c3 = (short) ((w3 << 1) & 0x07);
+ w1 = w2 = w3 = 0;
+ if (modRefByteIdx < refRowStride - 1)
+ {
+ if (currentLine >= 1 && (currentLine - 1) <
referenceBitmap.getHeight())
+ w1 = referenceBitmap.getByteAsInteger(refByteIndex -
refRowStride);
+ if (currentLine >= 0 && currentLine <
referenceBitmap.getHeight())
+ w2 = referenceBitmap.getByteAsInteger(refByteIndex);
+ if (currentLine >= -1 && currentLine + 1 <
referenceBitmap.getHeight())
+ w3 = referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride);
+ refByteIndex++;
+ }
+ c1 |= (short) ((w1 >>> 7) & 0x07);
+ c2 |= (short) ((w2 >>> 7) & 0x07);
+ c3 |= (short) ((w3 >>> 7) & 0x07);
+ }
- private void updateOverride() {
- if (grAtX == null || grAtY == null) {
- log.info("AT pixels not set");
- return;
- }
+ c4 = (short) (w4 >>> 6);
+ c5 = 0;
+
+ final int modBitsToTrim = (2 - modReferenceDX) % 8;
+ w1 <<= modBitsToTrim;
+ w2 <<= modBitsToTrim;
+ w3 <<= modBitsToTrim;
+
+ w4 <<= 2;
+
+ for (int x = 0; x < width; x++)
+ {
+ final int minorX = x & 0x07;
+
+ final short tval = templateFormation.form(c1, c2, c3, c4, c5);
+
+ if (override)
+ {
+ cx.setIndex(overrideAtTemplate0(tval, x, lineNumber,
+ regionBitmap.getByte(regionBitmap.getByteIndex(x,
lineNumber)), minorX));
+ }
+ else
+ {
+ cx.setIndex(tval);
+ }
+ final int bit = arithDecoder.decode(cx);
+ regionBitmap.setPixel(x, lineNumber, (byte) bit);
+
+ c1 = (short) (((c1 << 1) | 0x01 & (w1 >>> 7)) & 0x07);
+ c2 = (short) (((c2 << 1) | 0x01 & (w2 >>> 7)) & 0x07);
+ c3 = (short) (((c3 << 1) | 0x01 & (w3 >>> 7)) & 0x07);
+ c4 = (short) (((c4 << 1) | 0x01 & (w4 >>> 7)) & 0x07);
+ c5 = (short) bit;
+
+ if ((x - referenceDX) % 8 == 5)
+ {
+ if (((x - referenceDX) / 8) + 1 >=
referenceBitmap.getRowStride())
+ {
+ w1 = w2 = w3 = 0;
+ }
+ else
+ {
+ if (currentLine >= 1 && (currentLine - 1 <
referenceBitmap.getHeight()))
+ {
+ w1 = referenceBitmap.getByteAsInteger(refByteIndex -
refRowStride);
+ }
+ else
+ {
+ w1 = 0;
+ }
+ if (currentLine >= 0 && currentLine <
referenceBitmap.getHeight())
+ {
+ w2 = referenceBitmap.getByteAsInteger(refByteIndex);
+ }
+ else
+ {
+ w2 = 0;
+ }
+ if (currentLine >= -1 && (currentLine + 1) <
referenceBitmap.getHeight())
+ {
+ w3 = referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride);
+ }
+ else
+ {
+ w3 = 0;
+ }
+ }
+ refByteIndex++;
+ }
+ else
+ {
+ w1 <<= 1;
+ w2 <<= 1;
+ w3 <<= 1;
+ }
+
+ if (minorX == 5 && lineNumber >= 1)
+ {
+ if ((x >> 3) + 1 >= regionBitmap.getRowStride())
+ {
+ w4 = 0;
+ }
+ else
+ {
+ w4 = regionBitmap.getByteAsInteger(byteIndex - rowStride);
+ }
+ byteIndex++;
+ }
+ else
+ {
+ w4 <<= 1;
+ }
- if (grAtX.length != grAtY.length) {
- log.info("AT pixel inconsistent");
- return;
+ }
}
- grAtOverride = new boolean[grAtX.length];
+ private void updateOverride()
+ {
+ if (grAtX == null || grAtY == null)
+ {
+ log.info("AT pixels not set");
+ return;
+ }
- switch (templateID){
- case 0 :
- if (grAtX[0] != -1 && grAtY[0] != -1) {
- grAtOverride[0] = true;
- override = true;
+ if (grAtX.length != grAtY.length)
+ {
+ log.info("AT pixel inconsistent");
+ return;
}
- if (grAtX[1] != -1 && grAtY[1] != -1) {
- grAtOverride[1] = true;
- override = true;
+ grAtOverride = new boolean[grAtX.length];
+
+ switch (templateID)
+ {
+ case 0:
+ if (grAtX[0] != -1 && grAtY[0] != -1)
+ {
+ grAtOverride[0] = true;
+ override = true;
+ }
+
+ if (grAtX[1] != -1 && grAtY[1] != -1)
+ {
+ grAtOverride[1] = true;
+ override = true;
+ }
+ break;
+ case 1:
+ override = false;
+ break;
}
- break;
- case 1 :
- override = false;
- break;
- }
- }
-
- private void decodeTypicalPredictedLine(final int lineNumber, final int
width, final int rowStride,
- final int refRowStride, final int paddedWidth, final int deltaRefStride)
throws IOException {
-
- // Offset of the reference bitmap with respect to the bitmap being
- // decoded
- // For example: if grReferenceDY = -1, y is 1 HIGHER that currY
- final int currentLine = lineNumber - referenceDY;
- final int refByteIndex = referenceBitmap.getByteIndex(0, currentLine);
-
- final int byteIndex = regionBitmap.getByteIndex(0, lineNumber);
-
- switch (templateID){
- case 0 :
- decodeTypicalPredictedLineTemplate0(lineNumber, width, rowStride,
refRowStride, paddedWidth, deltaRefStride,
- byteIndex, currentLine, refByteIndex);
- break;
- case 1 :
- decodeTypicalPredictedLineTemplate1(lineNumber, width, rowStride,
refRowStride, paddedWidth, deltaRefStride,
- byteIndex, currentLine, refByteIndex);
- break;
- }
- }
-
- private void decodeTypicalPredictedLineTemplate0(final int lineNumber, final
int width, final int rowStride,
- final int refRowStride, final int paddedWidth, final int deltaRefStride,
int byteIndex, final int currentLine,
- int refByteIndex) throws IOException {
- int context;
- int overriddenContext;
-
- int previousLine;
- int previousReferenceLine;
- int currentReferenceLine;
- int nextReferenceLine;
-
- if (lineNumber > 0) {
- previousLine = regionBitmap.getByteAsInteger(byteIndex - rowStride);
- } else {
- previousLine = 0;
}
- if (currentLine > 0 && currentLine <= referenceBitmap.getHeight()) {
- previousReferenceLine = referenceBitmap.getByteAsInteger(refByteIndex -
refRowStride + deltaRefStride) << 4;
- } else {
- previousReferenceLine = 0;
+ private void decodeTypicalPredictedLine(final int lineNumber, final int
width,
+ final int rowStride, final int refRowStride, final int paddedWidth,
+ final int deltaRefStride) throws IOException
+ {
+
+ // Offset of the reference bitmap with respect to the bitmap being
+ // decoded
+ // For example: if grReferenceDY = -1, y is 1 HIGHER that currY
+ final int currentLine = lineNumber - referenceDY;
+ final int refByteIndex = referenceBitmap.getByteIndex(0, currentLine);
+
+ final int byteIndex = regionBitmap.getByteIndex(0, lineNumber);
+
+ switch (templateID)
+ {
+ case 0:
+ decodeTypicalPredictedLineTemplate0(lineNumber, width, rowStride,
refRowStride,
+ paddedWidth, deltaRefStride, byteIndex, currentLine,
refByteIndex);
+ break;
+ case 1:
+ decodeTypicalPredictedLineTemplate1(lineNumber, width, rowStride,
refRowStride,
+ paddedWidth, deltaRefStride, byteIndex, currentLine,
refByteIndex);
+ break;
+ }
}
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
- currentReferenceLine = referenceBitmap.getByteAsInteger(refByteIndex +
deltaRefStride) << 1;
- } else {
- currentReferenceLine = 0;
- }
+ private void decodeTypicalPredictedLineTemplate0(final int lineNumber,
final int width,
+ final int rowStride, final int refRowStride, final int paddedWidth,
+ final int deltaRefStride, int byteIndex, final int currentLine,
int refByteIndex)
+ throws IOException
+ {
+ int context;
+ int overriddenContext;
+
+ int previousLine;
+ int previousReferenceLine;
+ int currentReferenceLine;
+ int nextReferenceLine;
+
+ if (lineNumber > 0)
+ {
+ previousLine = regionBitmap.getByteAsInteger(byteIndex -
rowStride);
+ }
+ else
+ {
+ previousLine = 0;
+ }
- if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1)) {
- nextReferenceLine = referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride + deltaRefStride);
- } else {
- nextReferenceLine = 0;
- }
+ if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
+ {
+ previousReferenceLine = referenceBitmap
+ .getByteAsInteger(refByteIndex - refRowStride +
deltaRefStride) << 4;
+ }
+ else
+ {
+ previousReferenceLine = 0;
+ }
- context = ((previousLine >> 5) & 0x6) | ((nextReferenceLine >> 2) & 0x30)
| (currentReferenceLine & 0x180)
- | (previousReferenceLine & 0xc00);
-
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
- final boolean readNextByte = nextByte < width;
- final boolean refReadNextByte = nextByte < referenceBitmap.getWidth();
-
- final int yOffset = deltaRefStride + 1;
-
- if (lineNumber > 0) {
- previousLine = (previousLine << 8)
- | (readNextByte ? regionBitmap.getByteAsInteger(byteIndex -
rowStride + 1) : 0);
- }
-
- if (currentLine > 0 && currentLine <= referenceBitmap.getHeight()) {
- previousReferenceLine = (previousReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
- refRowStride + yOffset) << 4 : 0);
- }
-
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
- currentReferenceLine = (currentReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
+ yOffset) << 1 : 0);
- }
-
- if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1))
{
- nextReferenceLine = (nextReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
+ refRowStride + yOffset) : 0);
- }
-
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- boolean isPixelTypicalPredicted = false;
- int bit = 0;
-
- // i)
- final int bitmapValue = (context >> 4) & 0x1FF;
-
- if (bitmapValue == 0x1ff) {
- isPixelTypicalPredicted = true;
- bit = 1;
- } else if (bitmapValue == 0x00) {
- isPixelTypicalPredicted = true;
- bit = 0;
- }
-
- if (!isPixelTypicalPredicted) {
- // iii) - is like 3 c) but for one pixel only
-
- if (override) {
- overriddenContext = overrideAtTemplate0(context, x + minorX,
lineNumber, result, minorX);
- cx.setIndex(overriddenContext);
- } else {
- cx.setIndex(context);
- }
- bit = arithDecoder.decode(cx);
- }
-
- final int toShift = 7 - minorX;
- result |= bit << toShift;
-
- context = ((context & 0xdb6) << 1) | bit | ((previousLine >> toShift +
5) & 0x002)
- | ((nextReferenceLine >> toShift + 2) & 0x010) |
((currentReferenceLine >> toShift) & 0x080)
- | ((previousReferenceLine >> toShift) & 0x400);
- }
- regionBitmap.setByte(byteIndex++, result);
- refByteIndex++;
- }
- }
-
- private void decodeTypicalPredictedLineTemplate1(final int lineNumber, final
int width, final int rowStride,
- final int refRowStride, final int paddedWidth, final int deltaRefStride,
int byteIndex, final int currentLine,
- int refByteIndex) throws IOException {
- int context;
- int grReferenceValue;
-
- int previousLine;
- int previousReferenceLine;
- int currentReferenceLine;
- int nextReferenceLine;
-
- if (lineNumber > 0) {
- previousLine = regionBitmap.getByteAsInteger(byteIndex - rowStride);
- } else {
- previousLine = 0;
- }
+ if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
+ {
+ currentReferenceLine = referenceBitmap
+ .getByteAsInteger(refByteIndex + deltaRefStride) << 1;
+ }
+ else
+ {
+ currentReferenceLine = 0;
+ }
- if (currentLine > 0 && currentLine <= referenceBitmap.getHeight()) {
- previousReferenceLine = referenceBitmap.getByteAsInteger(byteIndex -
refRowStride + deltaRefStride) << 2;
- } else {
- previousReferenceLine = 0;
- }
+ if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() -
1))
+ {
+ nextReferenceLine = referenceBitmap
+ .getByteAsInteger(refByteIndex + refRowStride +
deltaRefStride);
+ }
+ else
+ {
+ nextReferenceLine = 0;
+ }
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
- currentReferenceLine = referenceBitmap.getByteAsInteger(byteIndex +
deltaRefStride);
- } else {
- currentReferenceLine = 0;
+ context = ((previousLine >> 5) & 0x6) | ((nextReferenceLine >> 2) &
0x30)
+ | (currentReferenceLine & 0x180) | (previousReferenceLine &
0xc00);
+
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
+ final boolean readNextByte = nextByte < width;
+ final boolean refReadNextByte = nextByte <
referenceBitmap.getWidth();
+
+ final int yOffset = deltaRefStride + 1;
+
+ if (lineNumber > 0)
+ {
+ previousLine = (previousLine << 8) | (readNextByte
+ ? regionBitmap.getByteAsInteger(byteIndex - rowStride
+ 1) : 0);
+ }
+
+ if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
+ {
+ previousReferenceLine = (previousReferenceLine << 8)
+ | (refReadNextByte ? referenceBitmap
+ .getByteAsInteger(refByteIndex - refRowStride
+ yOffset) << 4 : 0);
+ }
+
+ if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
+ {
+ currentReferenceLine = (currentReferenceLine << 8) |
(refReadNextByte
+ ? referenceBitmap.getByteAsInteger(refByteIndex +
yOffset) << 1 : 0);
+ }
+
+ if (currentLine > -2 && currentLine < (referenceBitmap.getHeight()
- 1))
+ {
+ nextReferenceLine = (nextReferenceLine << 8) | (refReadNextByte
+ ? referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride + yOffset)
+ : 0);
+ }
+
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ boolean isPixelTypicalPredicted = false;
+ int bit = 0;
+
+ // i)
+ final int bitmapValue = (context >> 4) & 0x1FF;
+
+ if (bitmapValue == 0x1ff)
+ {
+ isPixelTypicalPredicted = true;
+ bit = 1;
+ }
+ else if (bitmapValue == 0x00)
+ {
+ isPixelTypicalPredicted = true;
+ bit = 0;
+ }
+
+ if (!isPixelTypicalPredicted)
+ {
+ // iii) - is like 3 c) but for one pixel only
+
+ if (override)
+ {
+ overriddenContext = overrideAtTemplate0(context, x +
minorX, lineNumber,
+ result, minorX);
+ cx.setIndex(overriddenContext);
+ }
+ else
+ {
+ cx.setIndex(context);
+ }
+ bit = arithDecoder.decode(cx);
+ }
+
+ final int toShift = 7 - minorX;
+ result |= bit << toShift;
+
+ context = ((context & 0xdb6) << 1) | bit | ((previousLine >>
toShift + 5) & 0x002)
+ | ((nextReferenceLine >> toShift + 2) & 0x010)
+ | ((currentReferenceLine >> toShift) & 0x080)
+ | ((previousReferenceLine >> toShift) & 0x400);
+ }
+ regionBitmap.setByte(byteIndex++, result);
+ refByteIndex++;
+ }
}
- if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1)) {
- nextReferenceLine = referenceBitmap.getByteAsInteger(byteIndex +
refRowStride + deltaRefStride);
- } else {
- nextReferenceLine = 0;
- }
+ private void decodeTypicalPredictedLineTemplate1(final int lineNumber,
final int width,
+ final int rowStride, final int refRowStride, final int paddedWidth,
+ final int deltaRefStride, int byteIndex, final int currentLine,
int refByteIndex)
+ throws IOException
+ {
+ int context;
+ int grReferenceValue;
+
+ int previousLine;
+ int previousReferenceLine;
+ int currentReferenceLine;
+ int nextReferenceLine;
+
+ if (lineNumber > 0)
+ {
+ previousLine = regionBitmap.getByteAsInteger(byteIndex -
rowStride);
+ }
+ else
+ {
+ previousLine = 0;
+ }
- context = ((previousLine >> 5) & 0x6) | ((nextReferenceLine >> 2) & 0x30)
| (currentReferenceLine & 0xc0)
- | (previousReferenceLine & 0x200);
-
- grReferenceValue = ((nextReferenceLine >> 2) & 0x70) |
(currentReferenceLine & 0xc0)
- | (previousReferenceLine & 0x700);
-
- int nextByte;
- for (int x = 0; x < paddedWidth; x = nextByte) {
- byte result = 0;
- nextByte = x + 8;
- final int minorWidth = width - x > 8 ? 8 : width - x;
- final boolean readNextByte = nextByte < width;
- final boolean refReadNextByte = nextByte < referenceBitmap.getWidth();
-
- final int yOffset = deltaRefStride + 1;
-
- if (lineNumber > 0) {
- previousLine = (previousLine << 8)
- | (readNextByte ? regionBitmap.getByteAsInteger(byteIndex -
rowStride + 1) : 0);
- }
-
- if (currentLine > 0 && currentLine <= referenceBitmap.getHeight()) {
- previousReferenceLine = (previousReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
- refRowStride + yOffset) << 2 : 0);
- }
-
- if (currentLine >= 0 && currentLine < referenceBitmap.getHeight()) {
- currentReferenceLine = (currentReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
+ yOffset) : 0);
- }
-
- if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1))
{
- nextReferenceLine = (nextReferenceLine << 8)
- | (refReadNextByte ? referenceBitmap.getByteAsInteger(refByteIndex
+ refRowStride + yOffset) : 0);
- }
-
- for (int minorX = 0; minorX < minorWidth; minorX++) {
- int bit = 0;
-
- // i)
- final int bitmapValue = (grReferenceValue >> 4) & 0x1ff;
-
- if (bitmapValue == 0x1ff) {
- bit = 1;
- } else if (bitmapValue == 0x00) {
- bit = 0;
- } else {
- cx.setIndex(context);
- bit = arithDecoder.decode(cx);
- }
-
- final int toShift = 7 - minorX;
- result |= bit << toShift;
-
- context = ((context & 0x0d6) << 1) | bit | ((previousLine >> toShift +
5) & 0x002)
- | ((nextReferenceLine >> toShift + 2) & 0x010) |
((currentReferenceLine >> toShift) & 0x040)
- | ((previousReferenceLine >> toShift) & 0x200);
-
- grReferenceValue = ((grReferenceValue & 0x0db) << 1) |
((nextReferenceLine >> toShift + 2) & 0x010)
- | ((currentReferenceLine >> toShift) & 0x080) |
((previousReferenceLine >> toShift) & 0x400);
- }
- regionBitmap.setByte(byteIndex++, result);
- refByteIndex++;
- }
- }
-
- private int overrideAtTemplate0(int context, final int x, final int y, final
int result, final int minorX)
- throws IOException {
- if (grAtOverride[0]) {
- context &= 0xfff7;
- if (grAtY[0] == 0 && grAtX[0] >= -minorX) {
- context |= (result >> (7 - (minorX + grAtX[0])) & 0x1) << 3;
- } else {
- context |= getPixel(regionBitmap, x + grAtX[0], y + grAtY[0]) << 3;
- }
- }
+ if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
+ {
+ previousReferenceLine = referenceBitmap
+ .getByteAsInteger(byteIndex - refRowStride +
deltaRefStride) << 2;
+ }
+ else
+ {
+ previousReferenceLine = 0;
+ }
- if (grAtOverride[1]) {
- context &= 0xefff;
- if (grAtY[1] == 0 && grAtX[1] >= -minorX) {
- context |= (result >> (7 - (minorX + grAtX[1])) & 0x1) << 12;
- } else {
- context |= getPixel(referenceBitmap, x + grAtX[1] + referenceDX, y +
grAtY[1] + referenceDY) << 12;
- }
- }
- return context;
- }
+ if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
+ {
+ currentReferenceLine = referenceBitmap.getByteAsInteger(byteIndex
+ deltaRefStride);
+ }
+ else
+ {
+ currentReferenceLine = 0;
+ }
- private byte getPixel(final Bitmap b, final int x, final int y) throws
IOException {
- if (x < 0 || x >= b.getWidth()) {
- return 0;
- }
- if (y < 0 || y >= b.getHeight()) {
- return 0;
+ if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() -
1))
+ {
+ nextReferenceLine = referenceBitmap
+ .getByteAsInteger(byteIndex + refRowStride +
deltaRefStride);
+ }
+ else
+ {
+ nextReferenceLine = 0;
+ }
+
+ context = ((previousLine >> 5) & 0x6) | ((nextReferenceLine >> 2) &
0x30)
+ | (currentReferenceLine & 0xc0) | (previousReferenceLine &
0x200);
+
+ grReferenceValue = ((nextReferenceLine >> 2) & 0x70) |
(currentReferenceLine & 0xc0)
+ | (previousReferenceLine & 0x700);
+
+ int nextByte;
+ for (int x = 0; x < paddedWidth; x = nextByte)
+ {
+ byte result = 0;
+ nextByte = x + 8;
+ final int minorWidth = width - x > 8 ? 8 : width - x;
+ final boolean readNextByte = nextByte < width;
+ final boolean refReadNextByte = nextByte <
referenceBitmap.getWidth();
+
+ final int yOffset = deltaRefStride + 1;
+
+ if (lineNumber > 0)
+ {
+ previousLine = (previousLine << 8) | (readNextByte
+ ? regionBitmap.getByteAsInteger(byteIndex - rowStride
+ 1) : 0);
+ }
+
+ if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
+ {
+ previousReferenceLine = (previousReferenceLine << 8)
+ | (refReadNextByte ? referenceBitmap
+ .getByteAsInteger(refByteIndex - refRowStride
+ yOffset) << 2 : 0);
+ }
+
+ if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
+ {
+ currentReferenceLine = (currentReferenceLine << 8) |
(refReadNextByte
+ ? referenceBitmap.getByteAsInteger(refByteIndex +
yOffset) : 0);
+ }
+
+ if (currentLine > -2 && currentLine < (referenceBitmap.getHeight()
- 1))
+ {
+ nextReferenceLine = (nextReferenceLine << 8) | (refReadNextByte
+ ? referenceBitmap.getByteAsInteger(refByteIndex +
refRowStride + yOffset)
+ : 0);
+ }
+
+ for (int minorX = 0; minorX < minorWidth; minorX++)
+ {
+ int bit = 0;
+
+ // i)
+ final int bitmapValue = (grReferenceValue >> 4) & 0x1ff;
+
+ if (bitmapValue == 0x1ff)
+ {
+ bit = 1;
+ }
+ else if (bitmapValue == 0x00)
+ {
+ bit = 0;
+ }
+ else
+ {
+ cx.setIndex(context);
+ bit = arithDecoder.decode(cx);
+ }
+
+ final int toShift = 7 - minorX;
+ result |= bit << toShift;
+
+ context = ((context & 0x0d6) << 1) | bit | ((previousLine >>
toShift + 5) & 0x002)
+ | ((nextReferenceLine >> toShift + 2) & 0x010)
+ | ((currentReferenceLine >> toShift) & 0x040)
+ | ((previousReferenceLine >> toShift) & 0x200);
+
+ grReferenceValue = ((grReferenceValue & 0x0db) << 1)
+ | ((nextReferenceLine >> toShift + 2) & 0x010)
+ | ((currentReferenceLine >> toShift) & 0x080)
+ | ((previousReferenceLine >> toShift) & 0x400);
+ }
+ regionBitmap.setByte(byteIndex++, result);
+ refByteIndex++;
+ }
}
- return b.getPixel(x, y);
- }
+ private int overrideAtTemplate0(int context, final int x, final int y,
final int result,
+ final int minorX) throws IOException
+ {
+ if (grAtOverride[0])
+ {
+ context &= 0xfff7;
+ if (grAtY[0] == 0 && grAtX[0] >= -minorX)
+ {
+ context |= (result >> (7 - (minorX + grAtX[0])) & 0x1) << 3;
+ }
+ else
+ {
+ context |= getPixel(regionBitmap, x + grAtX[0], y + grAtY[0])
<< 3;
+ }
+ }
- public void init(final SegmentHeader header, final SubInputStream sis)
throws IOException {
- this.segmentHeader = header;
- this.subInputStream = sis;
- this.regionInfo = new RegionSegmentInformation(subInputStream);
- parseHeader();
- }
+ if (grAtOverride[1])
+ {
+ context &= 0xefff;
+ if (grAtY[1] == 0 && grAtX[1] >= -minorX)
+ {
+ context |= (result >> (7 - (minorX + grAtX[1])) & 0x1) << 12;
+ }
+ else
+ {
+ context |= getPixel(referenceBitmap, x + grAtX[1] +
referenceDX,
+ y + grAtY[1] + referenceDY) << 12;
+ }
+ }
+ return context;
+ }
- protected void setParameters(final CX cx, final ArithmeticDecoder
arithmeticDecoder, final short grTemplate,
- final int regionWidth, final int regionHeight, final Bitmap grReference,
final int grReferenceDX,
- final int grReferenceDY, final boolean isTPGRon, final short[] grAtX,
final short[] grAtY) {
+ private byte getPixel(final Bitmap b, final int x, final int y) throws
IOException
+ {
+ if (x < 0 || x >= b.getWidth())
+ {
+ return 0;
+ }
+ if (y < 0 || y >= b.getHeight())
+ {
+ return 0;
+ }
- if (null != cx) {
- this.cx = cx;
+ return b.getPixel(x, y);
}
- if (null != arithmeticDecoder) {
- this.arithDecoder = arithmeticDecoder;
+ public void init(final SegmentHeader header, final SubInputStream sis)
throws IOException
+ {
+ this.segmentHeader = header;
+ this.subInputStream = sis;
+ this.regionInfo = new RegionSegmentInformation(subInputStream);
+ parseHeader();
}
- this.templateID = grTemplate;
+ protected void setParameters(final CX cx, final ArithmeticDecoder
arithmeticDecoder,
+ final short grTemplate, final int regionWidth, final int
regionHeight,
+ final Bitmap grReference, final int grReferenceDX, final int
grReferenceDY,
+ final boolean isTPGRon, final short[] grAtX, final short[] grAtY)
+ {
+
+ if (null != cx)
+ {
+ this.cx = cx;
+ }
+
+ if (null != arithmeticDecoder)
+ {
+ this.arithDecoder = arithmeticDecoder;
+ }
- this.regionInfo.setBitmapWidth(regionWidth);
- this.regionInfo.setBitmapHeight(regionHeight);
+ this.templateID = grTemplate;
- this.referenceBitmap = grReference;
- this.referenceDX = grReferenceDX;
- this.referenceDY = grReferenceDY;
+ this.regionInfo.setBitmapWidth(regionWidth);
+ this.regionInfo.setBitmapHeight(regionHeight);
- this.isTPGROn = isTPGRon;
+ this.referenceBitmap = grReference;
+ this.referenceDX = grReferenceDX;
+ this.referenceDY = grReferenceDY;
- this.grAtX = grAtX;
- this.grAtY = grAtY;
+ this.isTPGROn = isTPGRon;
- this.regionBitmap = null;
- }
+ this.grAtX = grAtX;
+ this.grAtY = grAtY;
- public RegionSegmentInformation getRegionInfo() {
- return regionInfo;
- }
+ this.regionBitmap = null;
+ }
+
+ public RegionSegmentInformation getRegionInfo()
+ {
+ return regionInfo;
+ }
}