diff options
author | Nelson Benítez León <nbenitezl@gmail.com> | 2024-02-13 10:28:22 +0000 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2024-02-13 10:28:22 +0000 |
commit | a4da948c19990e299dd336a30d32760ce90b0136 (patch) | |
tree | be87e6e819378df1f559b8a904cbbc11d6a41d74 | |
parent | 0672a083a5f8e0c5ca53f7cf0dd967ce78b26fd1 (diff) |
Gfx::doImage: skip drawing image when it has singular matrix
otherwise it will result in broken output in Cairo backend.
Splash backend already works fine for this case because
it checks for singular matrix in Splash::drawImage().
This commit adds that check early in Gfx::doImage()
which fixes the Cairo backend and for Splash backend
means a perf improvement by avoiding lot of color
computation and image preparation done in
SplashOutputDev::draw{Image,ImageMask,MaskedImage,softMaskedImage}
prior to calling Splash::drawImage which is the one
that checks singular matrix and skips.
Note: singular matrix case is not mentioned in PDF spec
but Xpdf and other pdf readers de-facto do as in here
i.e. skip drawing an image when it has a singular (non
invertible) matrix.
Fixes issue #1114
-rw-r--r-- | poppler/Gfx.cc | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index edead0be..9cb2be2e 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -4192,6 +4192,11 @@ void Gfx::doImage(Object *ref, Stream *str, bool inlineImg) } } + const double *ctm = state->getCTM(); + const double det = ctm[0] * ctm[3] - ctm[1] * ctm[2]; + // Detect singular matrix (non invertible) to avoid drawing Image in such case + const bool singular_matrix = fabs(det) < 0.000001; + // get size Object obj1 = dict->lookup("Width"); if (obj1.isNull()) { @@ -4572,7 +4577,7 @@ void Gfx::doImage(Object *ref, Stream *str, bool inlineImg) } // if drawing is disabled, skip over inline image data - if (!ocState || !out->needNonText()) { + if (!ocState || !out->needNonText() || singular_matrix) { str->reset(); n = height * ((width * colorMap.getNumPixelComps() * colorMap.getBits() + 7) / 8); for (i = 0; i < n; ++i) { |