[poppler] 2 commits - poppler/Gfx.cc poppler/GfxState.cc poppler/GfxState.h poppler/SplashOutputDev.cc poppler/SplashOutputDev.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Wed Mar 2 08:52:23 UTC 2016
poppler/Gfx.cc | 33 ++++++++++++++++--
poppler/GfxState.cc | 7 ++-
poppler/GfxState.h | 7 +++
poppler/SplashOutputDev.cc | 80 ++++++++++++++++++++++++++++++++++++++++++++-
poppler/SplashOutputDev.h | 3 +
5 files changed, 122 insertions(+), 8 deletions(-)
New commits:
commit 1f7cb78f8b771bae8bfd96a7a7ca3afbaf89c749
Author: Albert Astals Cid <aacid at kde.org>
Date: Wed Mar 2 09:51:46 2016 +0100
Fix memory leak in Matte parsing
Also remove unneeded comment
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 4c10155..471bea6 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Jonathan Blandford <jrb at redhat.com>
-// Copyright (C) 2005-2013, 2015 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005-2013, 2015, 2016 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2006 Thorkild Stray <thorkild at ifi.uio.no>
// Copyright (C) 2006 Kristian Høgsberg <krh at redhat.com>
// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc at gnome.org>
@@ -4570,7 +4570,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
// handle the Matte entry
maskDict->lookup("Matte", &obj1);
- if (obj1.isArray()) { // && maskStr->getKind() != strDCT) {
+ if (obj1.isArray()) {
if (obj1.getArray()->getLength() != colorSpace->getNComps()) {
error(errSyntaxError, -1, "Matte entry should have {0:d} components but has {1:d}",
colorSpace->getNComps(), obj1.getArray()->getLength());
@@ -4595,6 +4595,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
}
}
+ obj1.free();
haveSoftMask = gTrue;
} else if (maskObj.isArray()) {
// color key mask
commit 36c276f1af7e0f1d8a207f6cdcaa80a24e95e044
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date: Wed Mar 2 09:50:01 2016 +0100
Splash: Implementation of matte entries in softmasks of softmasked images
Bug #22473
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index bb5f9b1..4c10155 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -28,7 +28,7 @@
// Copyright (C) 2008 Michael Vrable <mvrable at cs.ucsd.edu>
// Copyright (C) 2008 Hib Eris <hib at hiberis.nl>
// Copyright (C) 2009 M Joonas Pihlaja <jpihlaja at cc.helsinki.fi>
-// Copyright (C) 2009-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2009-2016 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2009 William Bader <williambader at hotmail.com>
// Copyright (C) 2009, 2010 David Benjamin <davidben at mit.edu>
// Copyright (C) 2010 Nils Höglund <nils.hoglund at gmail.com>
@@ -4568,7 +4568,33 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
delete maskColorMap;
goto err1;
}
- //~ handle the Matte entry
+ // handle the Matte entry
+ maskDict->lookup("Matte", &obj1);
+ if (obj1.isArray()) { // && maskStr->getKind() != strDCT) {
+ if (obj1.getArray()->getLength() != colorSpace->getNComps()) {
+ error(errSyntaxError, -1, "Matte entry should have {0:d} components but has {1:d}",
+ colorSpace->getNComps(), obj1.getArray()->getLength());
+ } else if (maskWidth != width || maskHeight != height) {
+ error(errSyntaxError, -1, "Softmask with matte entry {0:d} x {1:d} must have same geometry as the image {2:d} x {3:d}",
+ maskWidth, maskHeight, width, height);
+ } else {
+ GfxColor matteColor;
+ for (i = 0; i < colorSpace->getNComps(); i++) {
+ obj1.getArray()->get(i, &obj2);
+ if (!obj2.isNum()) {
+ obj2.free();
+ error(errSyntaxError, -1, "Matte entry {0:d} should be a number but it's of type {1:d}", i, obj2.getType());
+
+ break;
+ }
+ matteColor.c[i] = dblToCol(obj2.getNum());
+ obj2.free();
+ }
+ if (i == colorSpace->getNComps()) {
+ maskColorMap->setMatteColor(&matteColor);
+ }
+ }
+ }
haveSoftMask = gTrue;
} else if (maskObj.isArray()) {
// color key mask
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index bd3b42d..603bf5b 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -18,7 +18,7 @@
// Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2006-2015 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2009, 2012 Koji Otani <sho at bbr.jp>
-// Copyright (C) 2009, 2011-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2009, 2011-2016 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2009 Christian Persch <chpe at gnome.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha at gmail.com>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
@@ -5821,6 +5821,7 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
GBool useByteLookup;
ok = gTrue;
+ useMatte = gFalse;
// bits per component and color space
bits = bitsA;
@@ -5983,6 +5984,8 @@ GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) {
bits = colorMap->bits;
nComps = colorMap->nComps;
nComps2 = colorMap->nComps2;
+ useMatte = colorMap->useMatte;
+ matteColor = colorMap->matteColor;
colorSpace2 = NULL;
for (k = 0; k < gfxColorMaxComps; ++k) {
lookup[k] = NULL;
@@ -6570,7 +6573,7 @@ void GfxPath::offset(double dx, double dy) {
}
//------------------------------------------------------------------------
-// GfxState
+//
//------------------------------------------------------------------------
GfxState::ReusablePathIterator::ReusablePathIterator(GfxPath *path)
: path(path),
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index c20438b..d359355 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -20,7 +20,7 @@
// Copyright (C) 2009-2011, 2013 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2011 Andrea Canciani <ranma42 at gmail.com>
-// Copyright (C) 2011-2014 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2011-2014, 2016 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2013 Lu Wang <coolwanglu at gmail.com>
// Copyright (C) 2015 Adrian Johnson <ajohnson at redneon.com>
//
@@ -1194,6 +1194,9 @@ public:
void getDeviceN(Guchar *x, GfxColor *deviceN);
void getColor(Guchar *x, GfxColor *color);
+ // Matte color ops
+ void setMatteColor(GfxColor *color) { useMatte = gTrue; matteColor = *color; }
+ GfxColor *getMatteColor() { return (useMatte) ? &matteColor : NULL; }
private:
GfxImageColorMap(GfxImageColorMap *colorMap);
@@ -1212,6 +1215,8 @@ private:
decodeLow[gfxColorMaxComps];
double // max - min value for each component
decodeRange[gfxColorMaxComps];
+ GBool useMatte;
+ GfxColor matteColor;
GBool ok;
};
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 7b11279..cc3199d 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -1760,6 +1760,51 @@ SplashPattern *SplashOutputDev::getColor(GfxColor *deviceN) {
}
#endif
+void SplashOutputDev::getMatteColor(SplashColorMode colorMode, GfxImageColorMap *colorMap, GfxColor *matteColorIn, SplashColor matteColor) {
+ GfxGray gray;
+ GfxRGB rgb;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+ GfxColor deviceN;
+#endif
+
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ colorMap->getColorSpace()->getGray(matteColorIn, &gray);
+ matteColor[0] = colToByte(gray);
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ colorMap->getColorSpace()->getRGB(matteColorIn, &rgb);
+ matteColor[0] = colToByte(rgb.r);
+ matteColor[1] = colToByte(rgb.g);
+ matteColor[2] = colToByte(rgb.b);
+ break;
+ case splashModeXBGR8:
+ colorMap->getColorSpace()->getRGB(matteColorIn, &rgb);
+ matteColor[0] = colToByte(rgb.r);
+ matteColor[1] = colToByte(rgb.g);
+ matteColor[2] = colToByte(rgb.b);
+ matteColor[3] = 255;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ colorMap->getColorSpace()->getCMYK(matteColorIn, &cmyk);
+ matteColor[0] = colToByte(cmyk.c);
+ matteColor[1] = colToByte(cmyk.m);
+ matteColor[2] = colToByte(cmyk.y);
+ matteColor[3] = colToByte(cmyk.k);
+ break;
+ case splashModeDeviceN8:
+ colorMap->getColorSpace()->getDeviceN(matteColorIn, &deviceN);
+ for (int cp = 0; cp < SPOT_NCOMPS+4; cp++)
+ matteColor[cp] = colToByte(deviceN.c[cp]);
+ break;
+#endif
+ }
+}
+
void SplashOutputDev::setOverprintMask(GfxColorSpace *colorSpace,
GBool overprintFlag,
int overprintMode,
@@ -2899,6 +2944,9 @@ struct SplashOutImageData {
int *maskColors;
SplashColorMode colorMode;
int width, height, y;
+ ImageStream *maskStr;
+ GfxImageColorMap *maskColorMap;
+ SplashColor matteColor;
};
#ifdef USE_CMS
@@ -2932,6 +2980,11 @@ GBool SplashOutputDev::useIccImageSrc(void *data) {
}
#endif
+// Clip x to lie in [0, 255].
+static inline Guchar clip255(int x) {
+ return x < 0 ? 0 : x > 255 ? 255 : x;
+}
+
GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
Guchar * /*alphaLine*/) {
SplashOutImageData *imgData = (SplashOutImageData *)data;
@@ -3075,6 +3128,16 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
}
}
+ if (imgData->maskStr != NULL && (p = imgData->maskStr->getLine()) != NULL) {
+ int destComps = splashColorModeNComps[imgData->colorMode];
+ int convComps = (imgData->colorMode == splashModeXBGR8) ? 3 : destComps;
+ imgData->maskColorMap->getGrayLine(p, p, imgData->width);
+ for (x = 0, q = colorLine; x < imgData->width; ++x, p++, q += destComps) {
+ for (int cp = 0; cp < convComps; cp++) {
+ q[cp] = (*p) ? clip255(imgData->matteColor[cp] + (int) (q[cp] - imgData->matteColor[cp]) * 255 / *p) : imgData->matteColor[cp];
+ }
+ }
+ }
++imgData->y;
return gTrue;
}
@@ -3415,6 +3478,8 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
imgData.colorMode = colorMode;
imgData.width = width;
imgData.height = height;
+ imgData.maskStr = NULL;
+ imgData.maskColorMap = NULL;
imgData.y = 0;
// special case for one-channel (monochrome/gray/separation) images:
@@ -3879,6 +3944,8 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
imgMaskData.width = maskWidth;
imgMaskData.height = maskHeight;
imgMaskData.y = 0;
+ imgMaskData.maskStr = NULL;
+ imgMaskData.maskColorMap = NULL;
n = 1 << maskColorMap->getBits();
imgMaskData.lookup = (SplashColorPtr)gmalloc(n);
for (i = 0; i < n; ++i) {
@@ -3894,7 +3961,6 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
maskSplash->drawImage(&imageSrc, NULL, &imgMaskData, splashModeMono8, gFalse,
maskWidth, maskHeight, mat, maskInterpolate);
delete imgMaskData.imgStr;
- maskStr->close();
gfree(imgMaskData.lookup);
delete maskSplash;
splash->setSoftMask(maskBitmap);
@@ -3910,6 +3976,16 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
imgData.colorMode = colorMode;
imgData.width = width;
imgData.height = height;
+ imgData.maskStr = NULL;
+ imgData.maskColorMap = NULL;
+ if (maskColorMap->getMatteColor() != NULL) {
+ getMatteColor(colorMode, colorMap, maskColorMap->getMatteColor(), imgData.matteColor);
+ imgData.maskColorMap = maskColorMap;
+ imgData.maskStr = new ImageStream(maskStr, maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+ imgData.maskStr->reset();
+ }
imgData.y = 0;
// special case for one-channel (monochrome/gray/separation) images:
@@ -3982,7 +4058,9 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
splash->drawImage(&imageSrc, NULL, &imgData, srcMode, gFalse, width, height, mat, interpolate);
splash->setSoftMask(NULL);
gfree(imgData.lookup);
+ delete imgData.maskStr;
delete imgData.imgStr;
+ maskStr->close();
str->close();
}
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index ce4082f..16a6e81 100644
--- a/poppler/SplashOutputDev.h
+++ b/poppler/SplashOutputDev.h
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Takashi Iwai <tiwai at suse.de>
-// Copyright (C) 2009-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2009-2016 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
@@ -379,6 +379,7 @@ private:
SplashPattern *getColor(GfxCMYK *cmyk);
SplashPattern *getColor(GfxColor *deviceN);
#endif
+ void getMatteColor( SplashColorMode colorMode, GfxImageColorMap *colorMap, GfxColor * matteColor, SplashColor splashMatteColor);
void setOverprintMask(GfxColorSpace *colorSpace, GBool overprintFlag,
int overprintMode, GfxColor *singleColor, GBool grayIndexed = gFalse);
SplashPath *convertPath(GfxState *state, GfxPath *path,
More information about the poppler
mailing list