Martin Leitner created FOP-3358:
-----------------------------------
Summary: PDF Images: PatternUtil.promotePatterns writes pattern
objects of an embedded PDF page more than once
Key: FOP-3358
URL: https://issues.apache.org/jira/browse/FOP-3358
Project: FOP
Issue Type: Bug
Components: renderer/pdf
Affects Versions: main, 2.11, 2.10
Reporter: Martin Leitner
When a PDF page that uses patterns is embedded with fop-pdf-images and form
XObjects are *not* enabled (the default), each pattern object is written into
the output PDF more than once under the same object number.
h3. Steps to reproduce
Attached {{test.fo}} places {{shading.pdf}} (the file from fop-pdf-images' own
{{test/resources}}) twice on one page:
{code}
fop -fo test.fo -pdf out.pdf
{code}
Then count the object headers in {{out.pdf}}, e.g. {{grep -a -c "^22 0 obj"
out.pdf}}.
h3. Actual result (FOP 2.11 + fop-pdf-images 2.11 from Maven Central, PDFBox
3.0.3)
* Two {{external-graphic}}s of {{shading.pdf}}: objects 22 and 23 (the two
patterns) are each written *4 times*.
* With only one {{external-graphic}}: objects 22 and 23 are each written
*twice*.
The same happens with 2.10 and on current {{main}} (7dc1190).
h3. Expected result
Each indirect object is written exactly once. An object number/generation pair
identifies one indirect object (ISO 32000-1, 7.3.10); repeating it makes the
file body inconsistent with the cross-reference table.
h3. Cause
{{PDFCloner.cacheClonedObject}} already registers every cloned indirect object,
patterns included, via {{PDFDocument.registerObject}} (object number + output
queue). {{PatternUtil.promotePatterns()}} then calls {{setObjectNumber}} +
{{addObject}} on *every* entry of the target page's {{/Pattern}} dictionary, so
those patterns go into the output queue a second time.
That dictionary also accumulates across {{createStreamFromPDFBoxPage}} calls
for the same target page, so every further embedded image re-queues the
patterns of all earlier ones as well. This is why the count grows with the
number of images on a page.
With form XObjects enabled, {{PatternUtil}} is constructed disabled and the
problem does not occur.
We noticed it because our FOP build refuses to write a stream that has already
been written, which turns this into "java.io.IOException: Stream is closed".
Stock FOP silently writes the duplicates.
h3. Fix
Attached {{FOP-pdf-images-promotePatterns.patch}} (against {{main}} 7dc1190):
{{promotePatterns()}} skips patterns that already have an object number,
because they are already in the output queue, either from the cloner or from an
earlier call for the same page. Direct (unnumbered) pattern dictionaries are
promoted as before.
The patch adds two tests to {{PDFBoxAdapterTestCase}}:
* {{testPatternsAreWrittenOnce}} - one embedded page, with and without form
XObjects
* {{testPatternsOfTwoImagesOnOnePageAreWrittenOnce}} - two embedded pages on
one target page
Both tests fail on {{main}} without the change (objects written 2x, and 3x/2x
in the two-image case) and pass with it. The full fop-pdf-images test suite
passes: 117 tests.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)