You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ms...@apache.org on 2026/05/13 11:14:47 UTC

(pdfbox-jbig2) branch master updated (8d85907 -> 02e9162)

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/pdfbox-jbig2.git


    from 8d85907  PDFBOX-5660: add default to switch
     new cb40b3c  PDFBOX-6151: Add ArithmeticDecoderBenchmark with JMH/JFR profiling infrastructure
     new 02e9162  PDFBOX-6151: Deprecate DefaultInputStreamFactory in favour of direct ImageInputStream construction

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pom.xml                                            |  58 ++++++++-
 .../pdfbox/jbig2/io/DefaultInputStreamFactory.java |  10 ++
 .../java/org/apache/pdfbox/jbig2/ChecksumTest.java |   5 +-
 .../apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java  |   5 +-
 .../apache/pdfbox/jbig2/JBIG2ImageReaderTest.java  |  17 +--
 .../org/apache/pdfbox/jbig2/JBIG2PageTest.java     |  11 +-
 .../arithmetic/ArithmeticDecoderBenchmark.java     | 132 +++++++++++++++++++++
 .../decoder/arithmetic/ArithmeticDecoderTest.java  |   8 +-
 .../arithmetic/ArithmeticIntegerDecoderTest.java   |   5 +-
 .../jbig2/decoder/mmr/MMRDecompressorTest.java     |   5 +-
 .../apache/pdfbox/jbig2/image/BitmapsBlitTest.java |   8 +-
 .../pdfbox/jbig2/image/BitmapsChecksumTest.java    |   9 +-
 .../pdfbox/jbig2/segments/GenericRegionTest.java   |  14 +--
 .../pdfbox/jbig2/segments/HalftoneRegionTest.java  |   5 +-
 .../pdfbox/jbig2/segments/PageInformationTest.java |  11 +-
 .../jbig2/segments/PatternDictionaryTest.java      |  11 +-
 .../segments/RegionSegmentInformationTest.java     |   5 +-
 .../pdfbox/jbig2/segments/TextRegionTest.java      |   5 +-
 18 files changed, 245 insertions(+), 79 deletions(-)
 create mode 100644 src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderBenchmark.java


(pdfbox-jbig2) 02/02: PDFBOX-6151: Deprecate DefaultInputStreamFactory in favour of direct ImageInputStream construction

Posted by ms...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pdfbox-jbig2.git

commit 02e9162f8761ed298460ffcfef94f3c7f2a0b272
Author: Maruan Sahyoun <sa...@fileaffairs.de>
AuthorDate: Wed May 13 13:14:14 2026 +0200

    PDFBOX-6151: Deprecate DefaultInputStreamFactory in favour of direct ImageInputStream construction
---
 .../pdfbox/jbig2/io/DefaultInputStreamFactory.java      | 10 ++++++++++
 src/test/java/org/apache/pdfbox/jbig2/ChecksumTest.java |  5 ++---
 .../org/apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java   |  5 ++---
 .../org/apache/pdfbox/jbig2/JBIG2ImageReaderTest.java   | 17 ++++++-----------
 .../java/org/apache/pdfbox/jbig2/JBIG2PageTest.java     | 11 ++++-------
 .../jbig2/decoder/arithmetic/ArithmeticDecoderTest.java |  8 +++-----
 .../arithmetic/ArithmeticIntegerDecoderTest.java        |  5 ++---
 .../pdfbox/jbig2/decoder/mmr/MMRDecompressorTest.java   |  5 ++---
 .../org/apache/pdfbox/jbig2/image/BitmapsBlitTest.java  |  8 +++-----
 .../apache/pdfbox/jbig2/image/BitmapsChecksumTest.java  |  9 +++------
 .../apache/pdfbox/jbig2/segments/GenericRegionTest.java | 14 +++++---------
 .../pdfbox/jbig2/segments/HalftoneRegionTest.java       |  5 ++---
 .../pdfbox/jbig2/segments/PageInformationTest.java      | 11 ++++-------
 .../pdfbox/jbig2/segments/PatternDictionaryTest.java    | 11 ++++-------
 .../jbig2/segments/RegionSegmentInformationTest.java    |  5 ++---
 .../apache/pdfbox/jbig2/segments/TextRegionTest.java    |  5 ++---
 16 files changed, 56 insertions(+), 78 deletions(-)

diff --git a/src/main/java/org/apache/pdfbox/jbig2/io/DefaultInputStreamFactory.java b/src/main/java/org/apache/pdfbox/jbig2/io/DefaultInputStreamFactory.java
index 06bd618..b89f1e2 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/io/DefaultInputStreamFactory.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/io/DefaultInputStreamFactory.java
@@ -24,6 +24,16 @@ import javax.imageio.stream.FileCacheImageInputStream;
 import javax.imageio.stream.ImageInputStream;
 import javax.imageio.stream.MemoryCacheImageInputStream;
 
+/**
+ * @deprecated This factory provides no way to configure its behaviour and 
+ * does not document the tradeoff it makes: it defaults to
+ * {@link FileCacheImageInputStream} (file-backed, lower memory usage) with
+ * {@link MemoryCacheImageInputStream} only as a fallback on I/O failure.
+ * Callers should construct the appropriate {@link ImageInputStream} directly
+ * based on their own memory and performance requirements.
+ * This class will be removed in a future release.
+ */
+@Deprecated
 public class DefaultInputStreamFactory implements InputStreamFactory
 {
 
diff --git a/src/test/java/org/apache/pdfbox/jbig2/ChecksumTest.java b/src/test/java/org/apache/pdfbox/jbig2/ChecksumTest.java
index eee945e..b53b1df 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/ChecksumTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/ChecksumTest.java
@@ -27,8 +27,8 @@ import java.util.Arrays;
 import java.util.Collection;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -130,8 +130,7 @@ public class ChecksumTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         JBIG2Document doc = new JBIG2Document(iis);
 
diff --git a/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java b/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java
index 59864d0..8a6d7b9 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderDemo.java
@@ -29,11 +29,11 @@ import java.net.URL;
 
 import javax.imageio.ImageReadParam;
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.err.JBIG2Exception;
 import org.apache.pdfbox.jbig2.image.Bitmaps;
 import org.apache.pdfbox.jbig2.image.FilterType;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 
 public class JBIG2ImageReaderDemo
 {
@@ -50,8 +50,7 @@ public class JBIG2ImageReaderDemo
     public void show() throws IOException, JBIG2Exception
     {
         InputStream inputStream = new FileInputStream(new File(filepath));
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
 
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
 
diff --git a/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderTest.java b/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderTest.java
index 4e1361b..653d31d 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/JBIG2ImageReaderTest.java
@@ -29,10 +29,10 @@ import java.io.InputStream;
 import javax.imageio.ImageReadParam;
 import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.err.IntegerMaxValueException;
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -67,8 +67,7 @@ public class JBIG2ImageReaderTest
 
         InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
 
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         imageReader.setInput(imageInputStream);
@@ -95,8 +94,7 @@ public class JBIG2ImageReaderTest
 
         InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
 
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         imageReader.setInput(imageInputStream);
@@ -118,8 +116,7 @@ public class JBIG2ImageReaderTest
 
         InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         imageReader.setInput(imageInputStream);
         BufferedImage bufferedImage = imageReader.read(imageIndex, null);
@@ -140,8 +137,7 @@ public class JBIG2ImageReaderTest
 
         InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         imageReader.setInput(imageInputStream);
         Raster raster = imageReader.readRaster(imageIndex, null);
@@ -156,8 +152,7 @@ public class JBIG2ImageReaderTest
         String filepath = "/images/002.jb2";
 
         InputStream inputStream = getClass().getResourceAsStream(filepath);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream imageInputStream = disf.getInputStream(inputStream);
+        ImageInputStream imageInputStream = new MemoryCacheImageInputStream(inputStream);
         JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         imageReader.setInput(imageInputStream);
         int numImages = imageReader.getNumImages(true);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/JBIG2PageTest.java b/src/test/java/org/apache/pdfbox/jbig2/JBIG2PageTest.java
index fab0a1b..1c2747f 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/JBIG2PageTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/JBIG2PageTest.java
@@ -27,11 +27,11 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.err.JBIG2Exception;
 import org.apache.pdfbox.jbig2.image.Bitmaps;
 import org.apache.pdfbox.jbig2.image.FilterType;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -53,8 +53,7 @@ public class JBIG2PageTest
         int pageNumber = 1;
 
         InputStream is = new FileInputStream(inputFile);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
         JBIG2Document doc = new JBIG2Document(iis);
 
         Bitmap pageBitmap = doc.getPage(pageNumber).getBitmap();
@@ -78,8 +77,7 @@ public class JBIG2PageTest
         int pageNumber = 1;
 
         InputStream is = new FileInputStream(inputFile);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
 
         for (int i = 0; i < runs; i++)
         {
@@ -108,8 +106,7 @@ public class JBIG2PageTest
         System.out.println("File: " + path);
 
         InputStream is = getClass().getResourceAsStream(path);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
 
         for (int j = 1; j <= pages; j++)
         {
diff --git a/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderTest.java b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderTest.java
index e8a06a7..20d375a 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderTest.java
@@ -19,8 +19,8 @@ package org.apache.pdfbox.jbig2.decoder.arithmetic;
 
 import java.io.InputStream;
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -161,8 +161,7 @@ public class ArithmeticDecoderTest
     public void decodeTest() throws Throwable
     {
         InputStream is = getClass().getResourceAsStream("/images/arith/encoded testsequence");
-        DefaultInputStreamFactory factory = new DefaultInputStreamFactory();
-        ImageInputStream iis = factory.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
 
         ArithmeticDecoder decoder = new ArithmeticDecoder(iis);
 
@@ -178,8 +177,7 @@ public class ArithmeticDecoderTest
     public void decodeTestWithTracadataComparison() throws Throwable
     {
         InputStream is = getClass().getResourceAsStream("/images/arith/encoded testsequence");
-        DefaultInputStreamFactory factory = new DefaultInputStreamFactory();
-        ImageInputStream iis = factory.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
 
         ArithmeticDecoder decoder = new ArithmeticDecoder(iis);
         CX cx = new CX(1, 0);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoderTest.java b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoderTest.java
index bff6e63..5947431 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoderTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoderTest.java
@@ -20,8 +20,8 @@ package org.apache.pdfbox.jbig2.decoder.arithmetic;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -32,8 +32,7 @@ public class ArithmeticIntegerDecoderTest
     public void decodeTest() throws Throwable
     {
         InputStream is = getClass().getResourceAsStream("/images/arith/encoded testsequence");
-        DefaultInputStreamFactory isFactory = new DefaultInputStreamFactory();
-        ImageInputStream iis = isFactory.getInputStream(is);
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
 
         ArithmeticDecoder ad = new ArithmeticDecoder(iis);
         ArithmeticIntegerDecoder aid = new ArithmeticIntegerDecoder(ad);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressorTest.java b/src/test/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressorTest.java
index 2c4fd3c..20dfa07 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressorTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressorTest.java
@@ -26,10 +26,10 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.Bitmap;
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.junit.Test;
 
@@ -54,8 +54,7 @@ public class MMRDecompressorTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        final DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        final ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         // Sixth Segment (number 5)
         final SubInputStream sis = new SubInputStream(iis, 252, 38);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsBlitTest.java b/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsBlitTest.java
index ba1126d..fd0367a 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsBlitTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsBlitTest.java
@@ -27,11 +27,11 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.Bitmap;
 import org.apache.pdfbox.jbig2.JBIG2DocumentFacade;
 import org.apache.pdfbox.jbig2.err.JBIG2Exception;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 import org.junit.Test;
 
@@ -48,8 +48,7 @@ public class BitmapsBlitTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        final DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        final ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         final JBIG2DocumentFacade doc = new JBIG2DocumentFacade(iis);
 
@@ -70,8 +69,7 @@ public class BitmapsBlitTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        final DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        final ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         final JBIG2DocumentFacade doc = new JBIG2DocumentFacade(iis);
 
diff --git a/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsChecksumTest.java b/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsChecksumTest.java
index df52097..02e4ae9 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsChecksumTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/image/BitmapsChecksumTest.java
@@ -35,13 +35,12 @@ import java.util.Collection;
 
 import javax.imageio.ImageReadParam;
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.Bitmap;
 import org.apache.pdfbox.jbig2.JBIG2DocumentFacade;
 import org.apache.pdfbox.jbig2.PreconfiguredImageReadParam;
 import org.apache.pdfbox.jbig2.err.JBIG2Exception;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
-import org.apache.pdfbox.jbig2.io.InputStreamFactory;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -115,8 +114,7 @@ public class BitmapsChecksumTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        final InputStreamFactory disf = new DefaultInputStreamFactory();
-        final ImageInputStream iis = disf.getInputStream(inputStream);
+        final ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         final JBIG2DocumentFacade doc = new JBIG2DocumentFacade(iis);
         final Bitmap b = doc.getPageBitmap(pageNumber);
@@ -155,8 +153,7 @@ public class BitmapsChecksumTest
 
             final InputStream inputStream = new FileInputStream(inputFile);
 
-            final InputStreamFactory disf = new DefaultInputStreamFactory();
-            final ImageInputStream iis = disf.getInputStream(inputStream);
+            final ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
             final JBIG2DocumentFacade doc = new JBIG2DocumentFacade(iis);
             final Bitmap b = doc.getPageBitmap(pageNumber);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/GenericRegionTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/GenericRegionTest.java
index 545a05d..98d0c45 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/GenericRegionTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/GenericRegionTest.java
@@ -25,11 +25,11 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.TestImage;
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
 import org.apache.pdfbox.jbig2.image.Bitmaps;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 import org.junit.Assert;
@@ -48,8 +48,7 @@ public class GenericRegionTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
 
         // Twelfth Segment (number 11)
         SubInputStream sis = new SubInputStream(iis, 523, 35);
@@ -92,8 +91,7 @@ public class GenericRegionTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Twelfth Segment (number 11)
         SubInputStream sis = new SubInputStream(iis, 523, 35);
         GenericRegion gr = new GenericRegion();
@@ -113,8 +111,7 @@ public class GenericRegionTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Twelfth Segment (number 11)
         SubInputStream sis = new SubInputStream(iis, 523, 35);
         GenericRegion gr = new GenericRegion(sis);
@@ -134,8 +131,7 @@ public class GenericRegionTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Fifth Segment (number 4)
         SubInputStream sis = new SubInputStream(iis, 190, 59);
         GenericRegion gr = new GenericRegion(sis);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/HalftoneRegionTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/HalftoneRegionTest.java
index 6de0a80..ea4a7f3 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/HalftoneRegionTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/HalftoneRegionTest.java
@@ -25,9 +25,9 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 import org.junit.Assert;
@@ -46,8 +46,7 @@ public class HalftoneRegionTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Seventh Segment (number 6)
         SubInputStream sis = new SubInputStream(iis, 302, 87);
         HalftoneRegion hr = new HalftoneRegion(sis);
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/PageInformationTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/PageInformationTest.java
index dc0659f..abb63cc 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/PageInformationTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/PageInformationTest.java
@@ -25,9 +25,9 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 import org.junit.Assert;
@@ -47,8 +47,7 @@ public class PageInformationTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Second Segment (number 1)
         SubInputStream sis = new SubInputStream(iis, 59, 19);
         PageInformation pi = new PageInformation();
@@ -76,8 +75,7 @@ public class PageInformationTest
         // skip test if input stream isn't available
         assumeTrue(inputStream != null && inputStream.available() > 0);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Second Segment (number 1)
         SubInputStream sis = new SubInputStream(iis, 59, 19);
         PageInformation pi = new PageInformation();
@@ -95,8 +93,7 @@ public class PageInformationTest
         // skip test if input stream isn't available
         assumeTrue(inputStream != null && inputStream.available() > 0);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Second Segment (number 1)
         SubInputStream sis = new SubInputStream(iis, 59, 19);
         PageInformation pi = new PageInformation();
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/PatternDictionaryTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/PatternDictionaryTest.java
index 6f8b2fb..66e0216 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/PatternDictionaryTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/PatternDictionaryTest.java
@@ -26,11 +26,11 @@ import java.io.InputStream;
 import java.util.ArrayList;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.Bitmap;
 import org.apache.pdfbox.jbig2.TestImage;
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.junit.Assert;
 import org.junit.Ignore;
@@ -48,8 +48,7 @@ public class PatternDictionaryTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Sixth Segment (number 5)
         SubInputStream sis = new SubInputStream(iis, 245, 45);
         PatternDictionary pd = new PatternDictionary();
@@ -75,8 +74,7 @@ public class PatternDictionaryTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Sixth Segment (number 5)
         SubInputStream sis = new SubInputStream(iis, 245, 45);
 
@@ -103,8 +101,7 @@ public class PatternDictionaryTest
 
         final InputStream inputStream = new FileInputStream(inputFile);
 
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         // Twelfth Segment (number 12)
         SubInputStream sis = new SubInputStream(iis, 569, 28);
 
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformationTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformationTest.java
index bfc3089..b9f97ee 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformationTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/RegionSegmentInformationTest.java
@@ -25,8 +25,8 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.apache.pdfbox.jbig2.io.SubInputStream;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 import org.junit.Test;
@@ -44,8 +44,7 @@ public class RegionSegmentInformationTest
         assumeTrue(inputFile.exists());
 
         InputStream inputStream = new FileInputStream(inputFile);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         SubInputStream sis = new SubInputStream(iis, 130, 49);
         RegionSegmentInformation rsi = new RegionSegmentInformation(sis);
         rsi.parseHeader();
diff --git a/src/test/java/org/apache/pdfbox/jbig2/segments/TextRegionTest.java b/src/test/java/org/apache/pdfbox/jbig2/segments/TextRegionTest.java
index ad5421b..f65d228 100644
--- a/src/test/java/org/apache/pdfbox/jbig2/segments/TextRegionTest.java
+++ b/src/test/java/org/apache/pdfbox/jbig2/segments/TextRegionTest.java
@@ -26,13 +26,13 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
 
 import org.apache.pdfbox.jbig2.JBIG2ImageReader;
 import org.apache.pdfbox.jbig2.JBIG2ImageReaderSpi;
 import org.apache.pdfbox.jbig2.TestImage;
 import org.apache.pdfbox.jbig2.err.IntegerMaxValueException;
 import org.apache.pdfbox.jbig2.err.InvalidHeaderValueException;
-import org.apache.pdfbox.jbig2.io.DefaultInputStreamFactory;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -55,8 +55,7 @@ public class TextRegionTest
         assumeTrue(inputFile.exists());
 
         InputStream inputStream = new FileInputStream(inputFile);
-        DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
-        ImageInputStream iis = disf.getInputStream(inputStream);
+        ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
         JBIG2ImageReader jb2 = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
         jb2.setInput(iis);
         BufferedImage b = jb2.read(pageNumber);


(pdfbox-jbig2) 01/02: PDFBOX-6151: Add ArithmeticDecoderBenchmark with JMH/JFR profiling infrastructure

Posted by ms...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pdfbox-jbig2.git

commit cb40b3cd0439fd8f7f89f36109fc9e72bc905010
Author: Maruan Sahyoun <sa...@fileaffairs.de>
AuthorDate: Wed May 13 13:12:35 2026 +0200

    PDFBOX-6151: Add ArithmeticDecoderBenchmark with JMH/JFR profiling infrastructure
---
 pom.xml                                            |  58 ++++++++-
 .../arithmetic/ArithmeticDecoderBenchmark.java     | 132 +++++++++++++++++++++
 2 files changed, 189 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index bc2e316..4c4aa07 100644
--- a/pom.xml
+++ b/pom.xml
@@ -432,6 +432,62 @@
                 </plugins>
             </build>
         </profile>
+
+<profile>
+    <id>benchmark-jfr</id>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <debug>false</debug>
+                    <optimize>true</optimize>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.openjdk.jmh</groupId>
+                            <artifactId>jmh-generator-annprocess</artifactId>
+                            <version>1.37</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>run-benchmarks-jfr</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>exec</goal>  <!-- forked JVM — JFR sees only JMH -->
+                        </goals>
+                        <configuration>
+                            <executable>java</executable>
+                            <classpathScope>test</classpathScope>
+                            <arguments>
+                                <argument>-classpath</argument>
+                                <classpath/>  <!-- expands to full test classpath -->
+                                <argument>-XX:+FlightRecorder</argument>
+                                <argument>-XX:StartFlightRecording=filename=${project.build.directory}/arithmetic-decoder.jfr,settings=profile,dumponexit=true</argument>
+                                <argument>org.openjdk.jmh.Main</argument>
+                                <argument>.*ArithmeticDecoder.*</argument>
+                                <argument>-rf</argument>
+                                <argument>json</argument>
+                                <argument>-rff</argument>
+                                <argument>${project.build.directory}/benchmark-results.json</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</profile>        
+
+
     <profile>
         <id>benchmark</id>
         <build>
@@ -467,7 +523,7 @@
                                 <mainClass>org.openjdk.jmh.Main</mainClass>
                                 <classpathScope>test</classpathScope>
                                 <arguments>
-                                    <argument>.*Benchmark.*</argument>
+                                    <argument>.*DecoderBenchmark.*</argument>
                                     <argument>-rf</argument>
                                     <argument>json</argument>
                                     <argument>-rff</argument>
diff --git a/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderBenchmark.java b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderBenchmark.java
new file mode 100644
index 0000000..816c631
--- /dev/null
+++ b/src/test/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoderBenchmark.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.jbig2.decoder.arithmetic;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Baseline benchmark for ArithmeticDecoder.
+ *
+ * Run with: mvn clean test -Pbenchmark
+ * Results:  target/benchmark-results.json
+ *
+ * Fork is intentionally 0 — the benchmark profile uses exec-maven-plugin
+ * which already provides an isolated JVM. Warmup is increased to compensate.
+ */
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 3, time = 2, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)  // 10s iterations
+@Fork(0)
+public class ArithmeticDecoderBenchmark {
+
+    private byte[] encodedBytes;
+    private ArithmeticDecoder decoder;
+
+    private int symbolsDecoded;
+    private volatile int expectedSymbolCount = -1;
+
+    // -----------------------------------------------------------------------
+    // Setup / TearDown
+    // -----------------------------------------------------------------------
+
+    @Setup(Level.Trial)
+    public void loadBytes() throws IOException {
+        InputStream is = getClass()
+                .getResourceAsStream("/images/arith/encoded testsequence");
+        if (is == null) {
+            throw new IllegalStateException(
+                "Test resource not found. Run 'mvn generate-test-resources' first.");
+        }
+        encodedBytes = toByteArray(is);
+        is.close();
+        expectedSymbolCount = -1;
+    }
+
+    @Setup(Level.Invocation)
+    public void setup() throws IOException {
+        // MemoryCacheImageInputStream — pure in-memory, eliminates the
+        // FileCacheImageInputStream temp-file backed native seek() calls
+        // that were consuming 32.7% of CPU time per JFR profiling.
+        ImageInputStream iis = new MemoryCacheImageInputStream(
+                new ByteArrayInputStream(encodedBytes));
+        decoder = new ArithmeticDecoder(iis);
+        symbolsDecoded = 0;
+    }
+
+    @TearDown(Level.Invocation)
+    public void verifySymbolCount() {
+        if (expectedSymbolCount == -1) {
+            expectedSymbolCount = symbolsDecoded;
+            System.out.printf(
+                "[ArithmeticDecoderBenchmark] baseline symbol count: %d%n", expectedSymbolCount);
+        } else if (symbolsDecoded != expectedSymbolCount) {
+            throw new IllegalStateException(String.format(
+                "Symbol count mismatch: expected %d but decoded %d. " +
+                "Check byteIn() for early termination or over-read bugs.",
+                expectedSymbolCount, symbolsDecoded));
+        }
+    }
+
+    // -----------------------------------------------------------------------
+    // Benchmark
+    // -----------------------------------------------------------------------
+
+    @Benchmark
+    public void decodeFullStream(Blackhole bh) throws IOException {
+        CX cx = new CX(1, 0);
+        for (int i = 0; i < 257; i++) {       // fixed count matching the test
+            bh.consume(decoder.decode(cx));
+            symbolsDecoded++;
+        }
+    }
+    // -----------------------------------------------------------------------
+    // Utility
+    // -----------------------------------------------------------------------
+
+    /**
+     * Heuristic to distinguish normal end-of-stream termination from a
+     * genuine decode error. ImageInputStream implementations typically
+     * produce a null or empty message on EOF.
+     */
+    private static boolean isEndOfStream(IOException e) {
+        String msg = e.getMessage();
+        return msg == null || msg.isEmpty();
+    }
+
+    /** Java-8-compatible equivalent of InputStream.readAllBytes(). */
+    private static byte[] toByteArray(InputStream is) throws IOException {
+        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        byte[] chunk = new byte[4096];
+        int bytesRead;
+        while ((bytesRead = is.read(chunk)) != -1) {
+            buffer.write(chunk, 0, bytesRead);
+        }
+        return buffer.toByteArray();
+    }
+}
\ No newline at end of file