optimize JPEGFactory methods - #497
Open
valerybokov wants to merge 1 commit into
Open
Conversation
THausherr
reviewed
Aug 17, 2026
| { | ||
| // copy stream | ||
| ByteArrayInputStream byteStream = new ByteArrayInputStream(byteArray); | ||
| if (!(stream instanceof ByteArrayInputStream) && !(stream instanceof BufferedInputStream)) |
Contributor
There was a problem hiding this comment.
Suggested change
| if (!(stream instanceof ByteArrayInputStream) && !(stream instanceof BufferedInputStream)) | |
| if (!stream.markSupported()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The current version of the JPEGFactory.createFromByteArray method always creates a ByteArrayInputStream instance to read the image dimensions, and then creates a PDImageXObject instance. If we use the JPEGFactory.createFromStream method, we have a stream instance and create a new array. This is inefficient. We can work with streams and avoid duplicating memory (the InputStream from createFromStream can also be a ByteArrayInputStream).
I thought the InputStream.markSupported method should be used, and I found this information. The BufferedInputStream.reset() method can throw an exception only in a pathological extreme case: if, after mark(), more bytes were read than fit in the Java array (~2 GB). This isn't a drawback specific to BufferedInputStream—it's a fundamental limitation on storing arbitrary, rewindable data in memory, and it affects all approaches, including the original code before the refactoring (stream.readAllBytes()), which also resulted in an error (out of memory or exceeding array size limits) when handling multi-gigabyte input data. Therefore, BufferedInputStream is no worse than the alternative—it's just as good for realistic input data, with the same theoretical limit as everything else.
If this isn't acceptable, I can rewrite it using the markSupported method.
An additional benefit: the PDImageXObject.createFromFileByContent method now uses BufferedInputStream via the JPEGFactory.createFromStream method.