This is an automated email from the ASF dual-hosted git repository.
tilman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pdfbox-jbig2.git
The following commit(s) were added to refs/heads/master by this push:
new c184e28 PDFBOX-6154: pass and apply HSKIP bitmap
c184e28 is described below
commit c184e2826b823623de84d25ece3c9389bc7e9dbc
Author: Tilman Hausherr <[email protected]>
AuthorDate: Fri Jan 30 12:19:46 2026 +0100
PDFBOX-6154: pass and apply HSKIP bitmap
---
.../pdfbox/jbig2/segments/GenericRegion.java | 73 ++++++++++++++++------
.../pdfbox/jbig2/segments/HalftoneRegion.java | 31 ++-------
.../pdfbox/jbig2/segments/PatternDictionary.java | 2 +-
3 files changed, 61 insertions(+), 45 deletions(-)
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 0aca534..2236275 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/GenericRegion.java
@@ -68,7 +68,8 @@ public class GenericRegion implements Region
private MMRDecompressor mmrDecompressor;
- private boolean useSkip;
+ private boolean useSkip = false;
+ private Bitmap hSkip = null;
public GenericRegion()
{
@@ -158,6 +159,7 @@ public class GenericRegion implements Region
*
* @return The decoded {@link Bitmap} of this region.
*/
+ @Override
public Bitmap getRegionBitmap() throws IOException
{
if (null == regionBitmap)
@@ -227,20 +229,9 @@ public class GenericRegion implements Region
}
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 {
+ /* 6.2.5.7 - 3 d) */
decodeLine(line, regionBitmap.getWidth(),
regionBitmap.getRowStride(),
paddedWidth);
- // }
}
}
}
@@ -378,7 +369,15 @@ public class GenericRegion implements Region
cx.setIndex(context);
}
- int bit = arithDecoder.decode(cx);
+ final int bit;
+ if (useSkip && hSkip.getPixel(x + minorX, lineNumber) == 1)
+ {
+ bit = 0;
+ }
+ else
+ {
+ bit = arithDecoder.decode(cx);
+ }
result |= bit << toShift;
@@ -446,7 +445,15 @@ public class GenericRegion implements Region
cx.setIndex(context);
}
- final int bit = arithDecoder.decode(cx);
+ final int bit;
+ if (useSkip && hSkip.getPixel(x + minorX, lineNumber) == 1)
+ {
+ bit = 0;
+ }
+ else
+ {
+ bit = arithDecoder.decode(cx);
+ }
result |= bit << toShift;
@@ -513,7 +520,15 @@ public class GenericRegion implements Region
cx.setIndex(context);
}
- final int bit = arithDecoder.decode(cx);
+ final int bit;
+ if (useSkip && hSkip.getPixel(x + minorX, lineNumber) == 1)
+ {
+ bit = 0;
+ }
+ else
+ {
+ bit = arithDecoder.decode(cx);
+ }
result |= bit << 7 - minorX;
@@ -582,7 +597,15 @@ public class GenericRegion implements Region
cx.setIndex(context);
}
- final int bit = arithDecoder.decode(cx);
+ final int bit;
+ if (useSkip && hSkip.getPixel(x + minorX, lineNumber) == 1)
+ {
+ bit = 0;
+ }
+ else
+ {
+ bit = arithDecoder.decode(cx);
+ }
result |= bit << (7 - minorX);
@@ -639,7 +662,15 @@ public class GenericRegion implements Region
cx.setIndex(context);
}
- final int bit = arithDecoder.decode(cx);
+ final int bit;
+ if (useSkip && hSkip.getPixel(x + minorX, lineNumber) == 1)
+ {
+ bit = 0;
+ }
+ else
+ {
+ bit = arithDecoder.decode(cx);
+ }
result |= bit << (7 - minorX);
context = ((context & 0x1f7) << 1) | bit | ((line1 >> (8 -
minorX)) & 0x010);
@@ -998,13 +1029,14 @@ public class GenericRegion implements Region
* @param gbTemplate gb template
* @param isTPGDon is TPGDon
* @param useSkip use skip
+ * @param hSkip the HSKIP bitmap
* @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)
+ final boolean isTPGDon, final boolean useSkip, final Bitmap hSkip,
final short[] gbAtX, final short[] gbAtY)
{
this.dataOffset = dataOffset;
this.dataLength = dataLength;
@@ -1019,6 +1051,7 @@ public class GenericRegion implements Region
this.gbAtX = gbAtX;
this.gbAtY = gbAtY;
this.useSkip = useSkip;
+ this.hSkip = hSkip;
}
/**
@@ -1029,6 +1062,7 @@ public class GenericRegion implements Region
this.regionBitmap = null;
}
+ @Override
public void init(final SegmentHeader header, final SubInputStream sis)
throws InvalidHeaderValueException, IOException
{
@@ -1037,6 +1071,7 @@ public class GenericRegion implements Region
parseHeader();
}
+ @Override
public RegionSegmentInformation getRegionInfo()
{
return regionInfo;
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 bbb4577..bad0bb9 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/HalftoneRegion.java
@@ -171,40 +171,21 @@ public class HalftoneRegion implements Region
halftoneRegionBitmap.fillBitmap((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);
- // }
-
- // leaving the above comments untouched for now.
- Bitmap hSkip;
+ /* 2) 6.6.5.1 Computing HSKIP */
+
+ Bitmap hSkip = null;
if (hSkipEnabled)
{
- // test files from Serenity:
- // bitmap-halftone-skip-grid.jbig2
- // bitmap-halftone-skip-grid-template1.jbig2
- // bitmap-halftone-skip-grid-template2.jbig2
- // bitmap-halftone-skip-grid-template3.jbig2
int hPatternHeight = (int) patterns.get(0).getHeight(); // HPW
int hPatternWidth = (int) patterns.get(0).getWidth(); // HPH
hSkip = computeHSkip(hPatternWidth, hPatternHeight);
- //TODO: what to do with the result bitmap?
- throw new IOException("HSKIP not implemented");
}
/* 3) */
final int bitsPerValue = (int) Math.ceil(Math.log(patterns.size())
/ Math.log(2));
/* 4) */
- final int[][] grayScaleValues = grayScaleDecoding(bitsPerValue);
+ final int[][] grayScaleValues = grayScaleDecoding(bitsPerValue,
hSkip);
/* 5), rendering the pattern, described in 6.6.5.2 */
renderPattern(grayScaleValues);
@@ -260,7 +241,7 @@ public class HalftoneRegion implements Region
* 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
+ private int[][] grayScaleDecoding(final int bitsPerValue, final Bitmap
hSkip) throws IOException
{
short[] gbAtX = null;
@@ -290,7 +271,7 @@ public class HalftoneRegion implements Region
// 1)
GenericRegion genericRegion = new GenericRegion(subInputStream);
genericRegion.setParameters(isMMREncoded, dataOffset, dataLength,
hGridHeight, hGridWidth,
- hTemplate, false, hSkipEnabled, gbAtX, gbAtY);
+ hTemplate, false, hSkipEnabled, hSkip, gbAtX, gbAtY);
// 2)
int j = bitsPerValue - 1;
diff --git
a/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
b/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
index eb16914..58db13e 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/segments/PatternDictionary.java
@@ -147,7 +147,7 @@ public class PatternDictionary implements Dictionary
// 2)
final GenericRegion genericRegion = new
GenericRegion(subInputStream);
genericRegion.setParameters(isMMREncoded, dataOffset, dataLength,
hdpHeight,
- (grayMax + 1) * hdpWidth, hdTemplate, false, false, gbAtX,
gbAtY);
+ (grayMax + 1) * hdpWidth, hdTemplate, false, false, null,
gbAtX, gbAtY);
final Bitmap collectiveBitmap = genericRegion.getRegionBitmap();