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)

Reply via email to