[poppler] poppler/SplashOutputDev.cc poppler/SplashOutputDev.h splash/Splash.cc splash/Splash.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Sun May 24 09:42:15 PDT 2015
poppler/SplashOutputDev.cc | 142 +++++++++++++++++++++++++++++++++++++++++++--
poppler/SplashOutputDev.h | 8 ++
splash/Splash.cc | 17 ++++-
splash/Splash.h | 9 +-
4 files changed, 163 insertions(+), 13 deletions(-)
New commits:
commit 3db4cb6f07229e26405bfb512c626a272f6351f5
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date: Sun May 24 18:41:30 2015 +0200
Splash: Speed up of rendering icc based images
Bug #90171
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index a7cc6bc..5a9832d 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -2818,6 +2818,37 @@ struct SplashOutImageData {
int width, height, y;
};
+#ifdef USE_CMS
+GBool SplashOutputDev::useIccImageSrc(void *data) {
+ SplashOutImageData *imgData = (SplashOutImageData *)data;
+
+ if (!imgData->lookup && imgData->colorMap->getColorSpace()->getMode() == csICCBased) {
+ GfxICCBasedColorSpace *colorSpace = (GfxICCBasedColorSpace *) imgData->colorMap->getColorSpace();
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ if (colorSpace->getAlt() != NULL && colorSpace->getAlt()->getMode() == csDeviceGray)
+ return gTrue;
+ break;
+ case splashModeXBGR8:
+ case splashModeRGB8:
+ case splashModeBGR8:
+ if (colorSpace->getAlt() != NULL && colorSpace->getAlt()->getMode() == csDeviceRGB)
+ return gTrue;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ if (colorSpace->getAlt() != NULL && colorSpace->getAlt()->getMode() == csDeviceCMYK)
+ return gTrue;
+ break;
+#endif
+ }
+ }
+
+ return gFalse;
+}
+#endif
+
GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
Guchar * /*alphaLine*/) {
SplashOutImageData *imgData = (SplashOutImageData *)data;
@@ -2965,6 +2996,100 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
return gTrue;
}
+#ifdef USE_CMS
+GBool SplashOutputDev::iccImageSrc(void *data, SplashColorPtr colorLine,
+ Guchar * /*alphaLine*/) {
+ SplashOutImageData *imgData = (SplashOutImageData *)data;
+ Guchar *p;
+ int nComps;
+
+ if (imgData->y == imgData->height) {
+ return gFalse;
+ }
+ if (!(p = imgData->imgStr->getLine())) {
+ int destComps = 1;
+ if (imgData->colorMode == splashModeRGB8 || imgData->colorMode == splashModeBGR8)
+ destComps = 3;
+ else if (imgData->colorMode == splashModeXBGR8)
+ destComps = 4;
+#if SPLASH_CMYK
+ else if (imgData->colorMode == splashModeCMYK8)
+ destComps = 4;
+ else if (imgData->colorMode == splashModeDeviceN8)
+ destComps = SPOT_NCOMPS + 4;
+#endif
+ memset(colorLine, 0, imgData->width * destComps);
+ return gFalse;
+ }
+
+ if (imgData->colorMode == splashModeXBGR8) {
+ SplashColorPtr q;
+ int x;
+ for (x = 0, q = colorLine; x < imgData->width; ++x) {
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = 255;
+ }
+ } else {
+ nComps = imgData->colorMap->getNumPixelComps();
+ memcpy(colorLine, p, imgData->width * nComps);
+ }
+
+ ++imgData->y;
+ return gTrue;
+}
+
+void SplashOutputDev::iccTransform(void *data, SplashBitmap *bitmap) {
+ SplashOutImageData *imgData = (SplashOutImageData *)data;
+ int nComps = imgData->colorMap->getNumPixelComps();
+
+ Guchar *colorLine = (Guchar *) gmalloc(nComps * bitmap->getWidth());
+ Guchar *rgbxLine = (imgData->colorMode == splashModeXBGR8) ? (Guchar *) gmalloc(3 * bitmap->getWidth()) : NULL;
+ for (int i = 0; i < bitmap->getHeight(); i++) {
+ Guchar *p = bitmap->getDataPtr() + i * bitmap->getRowSize();
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData->colorMap->getGrayLine(p, colorLine, bitmap->getWidth());
+ memcpy(p, colorLine, nComps * bitmap->getWidth());
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ imgData->colorMap->getRGBLine(p, colorLine, bitmap->getWidth());
+ memcpy(p, colorLine, nComps * bitmap->getWidth());
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData->colorMap->getCMYKLine(p, colorLine, bitmap->getWidth());
+ memcpy(p, colorLine, nComps * bitmap->getWidth());
+ break;
+#endif
+ case splashModeXBGR8:
+ Guchar *q;
+ Guchar *b = p;
+ int x;
+ for (x = 0, q = rgbxLine; x < bitmap->getWidth(); ++x, ++b) {
+ *q++ = *b++;
+ *q++ = *b++;
+ *q++ = *b++;
+ }
+ imgData->colorMap->getRGBLine(rgbxLine, colorLine, bitmap->getWidth());
+ b = p;
+ for (x = 0, q = colorLine; x < bitmap->getWidth(); ++x, ++b) {
+ *b++ = *q++;
+ *b++ = *q++;
+ *b++ = *q++;
+ }
+ break;
+ }
+ }
+ gfree(colorLine);
+ if (rgbxLine != NULL)
+ gfree(rgbxLine);
+}
+#endif
+
GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine,
Guchar *alphaLine) {
SplashOutImageData *imgData = (SplashOutImageData *)data;
@@ -3176,6 +3301,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
SplashOutImageData imgData;
SplashColorMode srcMode;
SplashImageSource src;
+ SplashICCTransform tf;
GfxGray gray;
GfxRGB rgb;
#if SPLASH_CMYK
@@ -3293,8 +3419,14 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
} else {
srcMode = colorMode;
}
+#ifdef USE_CMS
+ src = maskColors ? &alphaImageSrc : useIccImageSrc(&imgData) ? &iccImageSrc : &imageSrc;
+ tf = maskColors == NULL && useIccImageSrc(&imgData) ? &iccTransform : NULL;
+#else
src = maskColors ? &alphaImageSrc : &imageSrc;
- splash->drawImage(src, &imgData, srcMode, maskColors ? gTrue : gFalse,
+ tf = NULL;
+#endif
+ splash->drawImage(src, tf, &imgData, srcMode, maskColors ? gTrue : gFalse,
width, height, mat, interpolate);
if (inlineImg) {
while (imgData.y < height) {
@@ -3596,7 +3728,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
} else {
srcMode = colorMode;
}
- splash->drawImage(&maskedImageSrc, &imgData, srcMode, gTrue,
+ splash->drawImage(&maskedImageSrc, NULL, &imgData, srcMode, gTrue,
width, height, mat, interpolate);
delete maskBitmap;
gfree(imgData.lookup);
@@ -3671,7 +3803,7 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
maskSplash = new Splash(maskBitmap, vectorAntialias);
maskColor[0] = 0;
maskSplash->clear(maskColor);
- maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
+ maskSplash->drawImage(&imageSrc, NULL, &imgMaskData, splashModeMono8, gFalse,
maskWidth, maskHeight, mat, maskInterpolate);
delete imgMaskData.imgStr;
maskStr->close();
@@ -3759,7 +3891,7 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
} else {
srcMode = colorMode;
}
- splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat, interpolate);
+ splash->drawImage(&imageSrc, NULL, &imgData, srcMode, gFalse, width, height, mat, interpolate);
splash->setSoftMask(NULL);
gfree(imgData.lookup);
delete imgData.imgStr;
@@ -4358,7 +4490,7 @@ GBool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *ca
}
retValue = gTrue;
} else {
- retValue = splash->drawImage(&tilingBitmapSrc, &imgData, colorMode, gTrue, result_width, result_height, matc, gFalse, gTrue) == splashOk;
+ retValue = splash->drawImage(&tilingBitmapSrc, NULL, &imgData, colorMode, gTrue, result_width, result_height, matc, gFalse, gTrue) == splashOk;
}
delete tBitmap;
delete gfx;
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index ae20fac..d34426c 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-2014 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2009-2015 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>
@@ -383,6 +383,12 @@ private:
GBool dropEmptySubpaths);
void drawType3Glyph(GfxState *state, T3FontCache *t3Font,
T3FontCacheTag *tag, Guchar *data);
+#ifdef USE_CMS
+ GBool useIccImageSrc(void *data);
+ static void iccTransform(void *data, SplashBitmap *bitmap);
+ static GBool iccImageSrc(void *data, SplashColorPtr colorLine,
+ Guchar *alphaLine);
+#endif
static GBool imageMaskSrc(void *data, SplashColorPtr line);
static GBool imageSrc(void *data, SplashColorPtr colorLine,
Guchar *alphaLine);
diff --git a/splash/Splash.cc b/splash/Splash.cc
index d8ee640..276cc8f 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -13,7 +13,7 @@
//
// Copyright (C) 2005-2015 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2005 Marco Pesenti Gritti <mpg at redhat.com>
-// Copyright (C) 2010-2014 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2010-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2011-2013, 2015 William Bader <williambader at hotmail.com>
// Copyright (C) 2012 Markus Trippelsdorf <markus at trippelsdorf.de>
@@ -3659,7 +3659,7 @@ void Splash::blitMask(SplashBitmap *src, int xDest, int yDest,
}
}
-SplashError Splash::drawImage(SplashImageSource src, void *srcData,
+SplashError Splash::drawImage(SplashImageSource src, SplashICCTransform tf, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat, GBool interpolate,
GBool tilingPattern) {
@@ -3750,6 +3750,9 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (scaledImg == NULL) {
return splashErrBadArg;
}
+ if (tf != NULL) {
+ (*tf)(srcData, scaledImg);
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
delete scaledImg;
}
@@ -3788,6 +3791,9 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (scaledImg == NULL) {
return splashErrBadArg;
}
+ if (tf != NULL) {
+ (*tf)(srcData, scaledImg);
+ }
vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
delete scaledImg;
@@ -3795,14 +3801,14 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
// all other cases
} else {
- return arbitraryTransformImage(src, srcData, srcMode, nComps, srcAlpha,
+ return arbitraryTransformImage(src, tf, srcData, srcMode, nComps, srcAlpha,
w, h, mat, interpolate, tilingPattern);
}
return splashOk;
}
-SplashError Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
+SplashError Splash::arbitraryTransformImage(SplashImageSource src, SplashICCTransform tf, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
@@ -3937,6 +3943,9 @@ SplashError Splash::arbitraryTransformImage(SplashImageSource src, void *srcData
return splashErrBadArg;
}
+ if (tf != NULL) {
+ (*tf)(srcData, scaledImg);
+ }
// construct the three sections
i = 0;
if (vy[1] < vy[i]) {
diff --git a/splash/Splash.h b/splash/Splash.h
index cf98e6c..7576454 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -13,7 +13,7 @@
//
// Copyright (C) 2005 Marco Pesenti Gritti <mpg at redhat.com>
// Copyright (C) 2007, 2011 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2010-2013, 2015 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2012 Adrian Johnson <ajohnson at redneon.com>
//
@@ -56,6 +56,9 @@ typedef GBool (*SplashImageMaskSource)(void *data, SplashColorPtr pixel);
typedef GBool (*SplashImageSource)(void *data, SplashColorPtr colorLine,
Guchar *alphaLine);
+// Use ICCColorSpace to transform a bitmap
+typedef void (*SplashICCTransform)(void *data, SplashBitmap *bitmap);
+
//------------------------------------------------------------------------
enum SplashPipeResultColorCtrl {
@@ -211,7 +214,7 @@ public:
// BGR8 BGR8
// CMYK8 CMYK8
// The matrix behaves as for fillImageMask.
- SplashError drawImage(SplashImageSource src, void *srcData,
+ SplashError drawImage(SplashImageSource src, SplashICCTransform tf, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat, GBool interpolate,
GBool tilingPattern = gFalse);
@@ -357,7 +360,7 @@ private:
SplashBitmap *dest);
void blitMask(SplashBitmap *src, int xDest, int yDest,
SplashClipResult clipRes);
- SplashError arbitraryTransformImage(SplashImageSource src, void *srcData,
+ SplashError arbitraryTransformImage(SplashImageSource src, SplashICCTransform tf, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
More information about the poppler
mailing list