You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A form XObject with INCOMPLETE /Resources shadows the page's: four of six images are not drawn #102
qpdf's own fixture form-xobjects-some-resources2.pdf — the name is the whole
story — draws six 15×15 images on page 1 through form XObjects, some of which
carry their own /Resources and some of which carry only part of what they use.
page 1
images pdfimages -list takes out
6 (objects 10, 12, 14, 16, 18, 20)
images render.Images returns
2 (objects 10, 12)
It is not only the extraction API. Through go-pdfkit/conformance's compare
against pdftoppm at 72 dpi, on a corpus of these files alone:
pixels differing
8.54%
mean abs difference
10.936 levels
worst square mean
130.27 levels
worst pixel
254
A worst square mean of 130 is not resampling. Four of the six stamps are
missing from the page we draw. Both form-xobjects-some-resources2.pdf and
its -out.pdf sibling are affected; a third fixture, nested-form-xobjects-inline-images-ii-some.pdf, differs by 0.03%.
Where
Both the drawing path and the extraction path handle an absent /Resources and neither handles an incomplete one.
The comment beside the second one says "A form with no resources of its own
draws against the ones in force where it was drawn" — which is exactly right
and exactly half the rule. A form that has /Resources but whose /XObject
(or /Font, /ColorSpace, /Pattern, /Shading, /ExtGState) does not hold
the name being used replaces the parent dictionary wholesale, so the name
resolves to nothing and drawXObject returns early.
A form XObject's resource dictionary is not required to be complete, and a name
it does not provide is resolved in the resources in force where the form was
painted. poppler does that — hence six images against our two — and qpdf ships
this fixture precisely to exercise it.
What a fix looks like
A name is looked up in the form's own category first and then in the enclosing
one, per category rather than per dictionary. The chain has to be the enclosing
dictionaries, not the page's alone, since forms nest; maxFormDepth already
bounds how deep that goes.
against render.Images(d, 1) returning 2. In the conformance corpus the file is pdfforms/gh-qpdf/qpdf_qtest_qpdf_form-xobjects-some-resources2.pdf; upstream it
is qpdf/qtest/qpdf/form-xobjects-some-resources2.pdf.
Found by a counter added in conformance#92 for the
pictures the reference extracts and we do not: of gh-qpdf's 13 such rows,
three are inline images and ten are this.
Activity
Images returns the inline ones, so 4 147 pictures of one population c…