summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/splash
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/splash')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc407
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.h11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc74
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.h19
5 files changed, 443 insertions, 70 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
index f84968cfb2a..4ac14edc459 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
@@ -40,6 +40,8 @@ if (HAVE_SPLASH)
SplashXPathScanner.cc
${DTYPE_SRCS}
)
+ set_property(TARGET splash_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
add_library(splash
$<TARGET_OBJECTS:splash_objs>
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index 343db796fb2..4afe21b4a25 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -469,6 +469,12 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
if (pipe->noTransparency && !state->blendFunc) {
+ //----- handle overprint
+
+ if (overprintMaskPtr) {
+ *overprintMaskPtr++ = 0xffffffff;
+ }
+
//----- result color
switch (bitmap->mode) {
@@ -650,7 +656,19 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
// This path is only used when Splash::composite() is called to
// composite a non-isolated group onto the backdrop. In this
// case, shape is the source (group) alpha.
- t = (aDest * 255) / shape - aDest;
+ //
+ // In a nested non-isolated group, i.e., if the destination is
+ // also a non-isolated group (state->inNonIsolatedGroup), we
+ // need to compute the corrected alpha, because the
+ // destination is is storing group alpha (same computation as
+ // blitCorrectedAlpha).
+ if (alpha0Ptr) {
+ t = *alpha0Ptr;
+ t = (Guchar)(aDest + t - div255(aDest * t));
+ } else {
+ t = aDest;
+ }
+ t = (t * 255) / shape - t;
switch (bitmap->mode) {
#if SPLASH_CMYK
case splashModeCMYK8:
@@ -3916,10 +3934,13 @@ class ImageMaskScaler {
public:
// Set up a MaskScaler to scale from [srcWidth]x[srcHeight] to
- // [scaledWidth]x[scaledHeight].
+ // [scaledWidth]x[scaledHeight]. The [interpolate] flag controls
+ // filtering on upsampling, and the [antialias] flag controls
+ // filtering on downsampling.
ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
int aSrcWidth, int aSrcHeight,
- int aScaledWidth, int aScaledHeight, GBool aInterpolate);
+ int aScaledWidth, int aScaledHeight,
+ GBool aInterpolate, GBool aAntialias);
~ImageMaskScaler();
@@ -3934,10 +3955,13 @@ public:
private:
void vertDownscaleHorizDownscale();
+ void vertDownscaleHorizDownscaleThresh();
void vertDownscaleHorizUpscaleNoInterp();
void vertDownscaleHorizUpscaleInterp();
+ void vertDownscaleHorizUpscaleThresh();
void vertUpscaleHorizDownscaleNoInterp();
void vertUpscaleHorizDownscaleInterp();
+ void vertUpscaleHorizDownscaleThresh();
void vertUpscaleHorizUpscaleNoInterp();
void vertUpscaleHorizUpscaleInterp();
@@ -3979,7 +4003,7 @@ private:
ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
int aSrcWidth, int aSrcHeight,
int aScaledWidth, int aScaledHeight,
- GBool aInterpolate) {
+ GBool aInterpolate, GBool aAntialias) {
tmpBuf0 = NULL;
tmpBuf1 = NULL;
tmpBuf2 = NULL;
@@ -4002,9 +4026,15 @@ ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
tmpBuf0 = (Guchar *)gmalloc(srcWidth);
accBuf = (Guint *)gmallocn(srcWidth, sizeof(Guint));
if (scaledWidth <= srcWidth) {
- scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscale;
+ if (!aAntialias) {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscaleThresh;
+ } else {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscale;
+ }
} else {
- if (aInterpolate) {
+ if (!aAntialias) {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleThresh;
+ } else if (aInterpolate) {
scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleInterp;
} else {
scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp;
@@ -4016,7 +4046,14 @@ ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
yq = scaledHeight % srcHeight;
yt = 0;
yn = 0;
- if (aInterpolate) {
+ if (!aAntialias) {
+ tmpBuf0 = (Guchar *)gmalloc(srcWidth);
+ if (scaledWidth <= srcWidth) {
+ scalingFunc = &ImageMaskScaler::vertUpscaleHorizDownscaleThresh;
+ } else {
+ scalingFunc = &ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp;
+ }
+ } else if (aInterpolate) {
yInvScale = (SplashCoord)srcHeight / (SplashCoord)scaledHeight;
tmpBuf0 = (Guchar *)gmalloc(srcWidth);
tmpBuf1 = (Guchar *)gmalloc(srcWidth);
@@ -4099,6 +4136,43 @@ void ImageMaskScaler::vertDownscaleHorizDownscale() {
}
}
+void ImageMaskScaler::vertDownscaleHorizDownscaleThresh() {
+ //--- vert downscale
+ int yStep = yp;
+ yt += yq;
+ if (yt >= scaledHeight) {
+ yt -= scaledHeight;
+ ++yStep;
+ }
+ memset(accBuf, 0, srcWidth * sizeof(Guint));
+ for (int i = 0; i < yStep; ++i) {
+ (*src)(srcData, tmpBuf0);
+ for (int j = 0; j < srcWidth; ++j) {
+ accBuf[j] += tmpBuf0[j];
+ }
+ }
+
+ //--- horiz downscale
+ int acc;
+ int xt = 0;
+ int unscaledIdx = 0;
+ for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= scaledWidth) {
+ xt -= scaledWidth;
+ ++xStep;
+ }
+
+ acc = 0;
+ for (int i = 0; i < xStep; ++i) {
+ acc += accBuf[unscaledIdx];
+ ++unscaledIdx;
+ }
+ line[scaledIdx] = acc > ((xStep * yStep) >> 1) ? (Guchar)255 : (Guchar)0;
+ }
+}
+
void ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp() {
//--- vert downscale
int yStep = yp;
@@ -4169,6 +4243,40 @@ void ImageMaskScaler::vertDownscaleHorizUpscaleInterp() {
}
}
+void ImageMaskScaler::vertDownscaleHorizUpscaleThresh() {
+ //--- vert downscale
+ int yStep = yp;
+ yt += yq;
+ if (yt >= scaledHeight) {
+ yt -= scaledHeight;
+ ++yStep;
+ }
+ memset(accBuf, 0, srcWidth * sizeof(Guint));
+ for (int i = 0; i < yStep; ++i) {
+ (*src)(srcData, tmpBuf0);
+ for (int j = 0; j < srcWidth; ++j) {
+ accBuf[j] += tmpBuf0[j];
+ }
+ }
+
+ //--- horiz upscale
+ int xt = 0;
+ int scaledIdx = 0;
+ for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= srcWidth) {
+ xt -= srcWidth;
+ ++xStep;
+ }
+ Guchar buf = accBuf[srcIdx] > (Guint)(yStep >> 1) ? (Guchar)255 : (Guchar)0;
+ for (int i = 0; i < xStep; ++i) {
+ line[scaledIdx] = buf;
+ ++scaledIdx;
+ }
+ }
+}
+
void ImageMaskScaler::vertUpscaleHorizDownscaleNoInterp() {
//--- vert upscale
if (yn == 0) {
@@ -4256,6 +4364,40 @@ void ImageMaskScaler::vertUpscaleHorizDownscaleInterp() {
}
}
+void ImageMaskScaler::vertUpscaleHorizDownscaleThresh() {
+ //--- vert upscale
+ if (yn == 0) {
+ yn = yp;
+ yt += yq;
+ if (yt >= srcHeight) {
+ yt -= srcHeight;
+ ++yn;
+ }
+ (*src)(srcData, tmpBuf0);
+ }
+ --yn;
+
+ //--- horiz downscale
+ int acc;
+ int xt = 0;
+ int unscaledIdx = 0;
+ for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= scaledWidth) {
+ xt -= scaledWidth;
+ ++xStep;
+ }
+
+ acc = 0;
+ for (int i = 0; i < xStep; ++i) {
+ acc += tmpBuf0[unscaledIdx];
+ ++unscaledIdx;
+ }
+ line[scaledIdx] = acc > (xStep >> 1) ? (Guchar)255 : (Guchar)0;
+ }
+}
+
void ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp() {
//--- vert upscale
if (yn == 0) {
@@ -4585,8 +4727,8 @@ SplashError Splash::clipToPath(SplashPath *path, GBool eo) {
return state->clipToPath(path, eo);
}
-void Splash::setSoftMask(SplashBitmap *softMask) {
- state->setSoftMask(softMask);
+void Splash::setSoftMask(SplashBitmap *softMask, GBool deleteBitmap) {
+ state->setSoftMask(softMask, deleteBitmap);
}
void Splash::setInTransparencyGroup(SplashBitmap *groupBackBitmapA,
@@ -4608,6 +4750,41 @@ void Splash::forceDeferredInit(int y, int h) {
useDestRow(y + h - 1);
}
+// Check that alpha is 0 in the specified rectangle.
+// NB: This doesn't work correctly in a non-isolated group, because
+// the rasterizer temporarily stores alpha_g instead of alpha.
+GBool Splash::checkTransparentRect(int x, int y, int w, int h) {
+ if (state->inNonIsolatedGroup) {
+ return gFalse;
+ }
+
+
+ if (!bitmap->alpha) {
+ return gFalse;
+ }
+ int yy0, yy1;
+ if (groupDestInitMode == splashGroupDestPreInit) {
+ yy0 = y;
+ yy1 = y + h - 1;
+ } else {
+ // both splashGroupDestInitZero and splashGroupDestInitCopy set
+ // alpha to zero, so anything outside of groupDestInit[YMin,YMax]
+ // will have alpha=0
+ yy0 = (y > groupDestInitYMin) ? y : groupDestInitYMin;
+ yy1 = (y + h - 1 < groupDestInitYMax) ? y + h - 1 : groupDestInitYMax;
+ }
+ Guchar *alphaP = &bitmap->alpha[yy0 * bitmap->alphaRowSize + x];
+ for (int yy = yy0; yy <= yy1; ++yy) {
+ for (int xx = 0; xx < w; ++xx) {
+ if (alphaP[xx] != 0) {
+ return gFalse;
+ }
+ }
+ alphaP += bitmap->getAlphaRowSize();
+ }
+ return gTrue;
+}
+
void Splash::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
Guchar *gray) {
state->setTransfer(red, green, blue, gray);
@@ -5749,7 +5926,8 @@ struct SplashDrawImageMaskRowData {
SplashError Splash::fillImageMask(GString *imageTag,
SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
- GBool glyphMode, GBool interpolate) {
+ GBool glyphMode, GBool interpolate,
+ GBool antialias) {
if (debugMode) {
printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
w, h, (double)mat[0], (double)mat[1], (double)mat[2],
@@ -5763,28 +5941,35 @@ SplashError Splash::fillImageMask(GString *imageTag,
//--- compute image bbox, check clipping
GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001;
+ GBool rot90Only = splashAbs(mat[0]) <= 0.0001 && splashAbs(mat[3]) <= 0.0001;
GBool horizFlip = gFalse;
GBool vertFlip = gFalse;
int xMin, yMin, xMax, yMax;
if (flipsOnly) {
horizFlip = mat[0] < 0;
vertFlip = mat[3] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
+ }
if (vertFlip) {
- if (horizFlip) { // bottom-up, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- } else { // bottom-up
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
} else {
- if (horizFlip) { // top-down, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- } else { // top-down
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
+ }
+ } else if (rot90Only) {
+ horizFlip = mat[2] < 0;
+ vertFlip = mat[1] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[2] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[2] + mat[4], &xMin, &xMax);
+ }
+ if (vertFlip) {
+ getImageBounds(mat[1] + mat[5], mat[5], &yMin, &yMax);
+ } else {
+ getImageBounds(mat[5], mat[1] + mat[5], &yMin, &yMax);
}
} else {
int xx = splashRound(mat[4]); // (0,0)
@@ -5860,7 +6045,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
if (clipRes == splashClipAllInside) {
drawRowFunc = &Splash::drawImageMaskRowNoClip;
} else {
- if (vectorAntialias) {
+ if (antialias) {
drawRowFunc = &Splash::drawImageMaskRowClipAA;
} else {
drawRowFunc = &Splash::drawImageMaskRowClipNoAA;
@@ -5873,7 +6058,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
int scaledWidth = xMax - xMin;
int scaledHeight = yMax - yMin;
ImageMaskScaler scaler(src, srcData, w, h,
- scaledWidth, scaledHeight, interpolate);
+ scaledWidth, scaledHeight, interpolate, antialias);
Guchar *tmpLine = NULL;
if (horizFlip) {
tmpLine = (Guchar *)gmalloc(scaledWidth);
@@ -5912,6 +6097,50 @@ SplashError Splash::fillImageMask(GString *imageTag,
gfree(tmpLine);
}
+ //--- 90/270 rotation
+ } else if (rot90Only && !veryLarge) {
+ if (clipRes != splashClipAllOutside) {
+
+ // scale the mask
+ int scaledWidth = yMax - yMin;
+ int scaledHeight = xMax - xMin;
+ ImageMaskScaler scaler(src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate, antialias);
+ Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+ Guchar *ptr = scaledMask;
+ for (int y = 0; y < scaledHeight; ++y) {
+ scaler.nextLine();
+ memcpy(ptr, scaler.data(), scaledWidth);
+ ptr += scaledWidth;
+ }
+
+ // draw it
+ Guchar *tmpLine = (Guchar *)gmalloc(scaledHeight);
+ for (int y = 0; y < scaledWidth; ++y) {
+ if (vertFlip) {
+ ptr = scaledMask + (scaledWidth - 1 - y);
+ } else {
+ ptr = scaledMask + y;
+ }
+ if (horizFlip) {
+ ptr += (scaledHeight - 1) * scaledWidth;
+ for (int x = 0; x < scaledHeight; ++x) {
+ tmpLine[x] = *ptr;
+ ptr -= scaledWidth;
+ }
+ } else {
+ for (int x = 0; x < scaledHeight; ++x) {
+ tmpLine[x] = *ptr;
+ ptr += scaledWidth;
+ }
+ }
+ (this->*drawRowFunc)(&dd, tmpLine, xMin, yMin + y, scaledHeight);
+ }
+
+ gfree(tmpLine);
+ gfree(scaledMask);
+ }
+
//--- arbitrary transform
} else {
// estimate of size of scaled image
@@ -5963,7 +6192,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
if (downscaling) {
ImageMaskScaler scaler(src, srcData, w, h,
- scaledWidth, scaledHeight, interpolate);
+ scaledWidth, scaledHeight, interpolate, antialias);
Guchar *ptr = scaledMask;
for (int y = 0; y < scaledHeight; ++y) {
scaler.nextLine();
@@ -5982,7 +6211,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
}
// draw it
- if (interpolate) {
+ if (interpolate && antialias) {
drawImageMaskArbitraryInterp(scaledMask,
&dd, drawRowFunc, invMat,
scaledWidth, scaledHeight,
@@ -6259,28 +6488,35 @@ SplashError Splash::drawImage(GString *imageTag,
//--- compute image bbox, check clipping
GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001;
+ GBool rot90Only = splashAbs(mat[0]) <= 0.0001 && splashAbs(mat[3]) <= 0.0001;
GBool horizFlip = gFalse;
GBool vertFlip = gFalse;
int xMin, yMin, xMax, yMax;
if (flipsOnly) {
horizFlip = mat[0] < 0;
vertFlip = mat[3] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
+ }
if (vertFlip) {
- if (horizFlip) { // bottom-up, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- } else { // bottom-up
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
} else {
- if (horizFlip) { // top-down, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- } else { // top-down
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
+ }
+ } else if (rot90Only) {
+ horizFlip = mat[2] < 0;
+ vertFlip = mat[1] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[2] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[2] + mat[4], &xMin, &xMax);
+ }
+ if (vertFlip) {
+ getImageBounds(mat[1] + mat[5], mat[5], &yMin, &yMax);
+ } else {
+ getImageBounds(mat[5], mat[1] + mat[5], &yMin, &yMax);
}
} else {
int xx = splashRound(mat[4]); // (0,0)
@@ -6435,6 +6671,83 @@ SplashError Splash::drawImage(GString *imageTag,
delete scaler;
}
+ //--- 90/270 rotation
+ } else if (rot90Only && !veryLarge) {
+ if (clipRes != splashClipAllOutside) {
+
+ // scale the image
+ int scaledWidth = yMax - yMin;
+ int scaledHeight = xMax - xMin;
+ Guchar *scaledColor, *scaledAlpha;
+ GBool freeScaledImage;
+ getScaledImage(imageTag, src, srcData, w, h, nComps,
+ scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate,
+ &scaledColor, &scaledAlpha, &freeScaledImage);
+
+ // draw it
+ Guchar *tmpLine = (Guchar *)gmallocn(scaledHeight, nComps);
+ Guchar *tmpAlphaLine = NULL;
+ if (srcAlpha) {
+ tmpAlphaLine = (Guchar *)gmalloc(scaledHeight);
+ }
+ for (int y = 0; y < scaledWidth; ++y) {
+ Guchar *ptr, *alphaPtr;
+ if (vertFlip) {
+ ptr = scaledColor + (scaledWidth - 1 - y) * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
+ }
+ } else {
+ ptr = scaledColor + y * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + y;
+ }
+ }
+ if (horizFlip) {
+ ptr += (scaledHeight - 1) * scaledWidth * nComps;
+ Guchar *q = tmpLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ for (int i = 0; i < nComps; ++i) {
+ *q++ = ptr[i];
+ }
+ ptr -= scaledWidth * nComps;
+ }
+ if (srcAlpha) {
+ alphaPtr += (scaledHeight - 1) * scaledWidth;
+ q = tmpAlphaLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ *q++ = *alphaPtr;
+ alphaPtr -= scaledWidth;
+ }
+ }
+ } else {
+ Guchar *q = tmpLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ for (int i = 0; i < nComps; ++i) {
+ *q++ = ptr[i];
+ }
+ ptr += scaledWidth * nComps;
+ }
+ if (srcAlpha) {
+ q = tmpAlphaLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ *q++ = *alphaPtr;
+ alphaPtr += scaledWidth;
+ }
+ }
+ }
+ (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+ xMin, yMin + y, scaledHeight);
+ }
+
+ gfree(tmpLine);
+ gfree(tmpAlphaLine);
+ if (freeScaledImage) {
+ gfree(scaledColor);
+ gfree(scaledAlpha);
+ }
+ }
+
//--- arbitrary transform
} else {
// estimate of size of scaled image
@@ -6518,14 +6831,13 @@ ImageScaler *Splash::getImageScaler(GString *imageTag,
GBool srcAlpha, GBool interpolate) {
// Notes:
//
- // * If the scaled image width or height is greater than 2000, we
- // don't cache it.
+ // * If the scaled image is more than 8 Mpixels, we don't cache it.
//
// * Caching is done on the third consecutive use (second
// consecutive reuse) of an image; this avoids overhead on the
// common case of single-use images.
- if (scaledWidth < 2000 && scaledHeight < 2000 &&
+ if (scaledWidth < 8000000 / scaledHeight &&
imageCache->match(imageTag, scaledWidth, scaledHeight,
srcMode, srcAlpha, interpolate)) {
if (imageCache->colorData) {
@@ -6570,13 +6882,12 @@ void Splash::getScaledImage(GString *imageTag,
GBool *freeScaledImage) {
// Notes:
//
- // * If the scaled image width or height is greater than 2000, we
- // don't cache it.
+ // * If the scaled image is more than 8 Mpixels, we don't cache it.
//
// * This buffers the whole image anyway, so there's no reason to
// skip caching on the first reuse.
- if (scaledWidth >= 2000 || scaledHeight >= 2000) {
+ if (scaledWidth >= 8000000 / scaledHeight) {
int lineSize;
if (scaledWidth < INT_MAX / nComps) {
lineSize = scaledWidth * nComps;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
index d6cc33a5fad..9622b07fc27 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
@@ -182,12 +182,13 @@ public:
SplashCoord x1, SplashCoord y1);
// NB: uses untransformed coordinates.
SplashError clipToPath(SplashPath *path, GBool eo);
- void setSoftMask(SplashBitmap *softMask);
+ void setSoftMask(SplashBitmap *softMask, GBool deleteBitmap = gTrue);
void setInTransparencyGroup(SplashBitmap *groupBackBitmapA,
int groupBackXA, int groupBackYA,
SplashGroupDestInitMode groupDestInitModeA,
GBool nonIsolated, GBool knockout);
void forceDeferredInit(int y, int h);
+ GBool checkTransparentRect(int x, int y, int w, int h);
void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
void setOverprintMask(Guint overprintMask);
void setEnablePathSimplification(GBool en);
@@ -228,11 +229,15 @@ public:
// [x' y' 1] = [x y 1] * mat
// Note that the Splash y axis points downward, and the image source
// is assumed to produce pixels in raster order, starting from the
- // top line.
+ // top line. If [interpolate] is false, no filtering is done when
+ // upsampling. If [antialias] is false, no filtering is done when
+ // upsampling (overriding the [interpolate] flag), and threshold
+ // filtering is done when downsampling.
SplashError fillImageMask(GString *imageTag,
SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
- GBool glyphMode, GBool interpolate);
+ GBool glyphMode, GBool interpolate,
+ GBool antialias);
// Draw an image. This will read <h> lines of <w> pixels from
// <src>, starting with the top line. These pixels are assumed to
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
index 74421c48a4a..7fc510439b1 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
@@ -63,6 +63,21 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
deleteSoftMask = gFalse;
inNonIsolatedGroup = gFalse;
inKnockoutGroup = gFalse;
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
for (i = 0; i < 256; ++i) {
rgbTransferR[i] = (Guchar)i;
rgbTransferG[i] = (Guchar)i;
@@ -75,6 +90,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
cmykTransferK[i] = (Guchar)i;
#endif
}
+ transferIsShared = gFalse;
overprintMask = 0xffffffff;
enablePathSimplification = gFalse;
next = NULL;
@@ -110,6 +126,21 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
deleteSoftMask = gFalse;
inNonIsolatedGroup = gFalse;
inKnockoutGroup = gFalse;
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
for (i = 0; i < 256; ++i) {
rgbTransferR[i] = (Guchar)i;
rgbTransferG[i] = (Guchar)i;
@@ -122,6 +153,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
cmykTransferK[i] = (Guchar)i;
#endif
}
+ transferIsShared = gFalse;
overprintMask = 0xffffffff;
enablePathSimplification = gFalse;
next = NULL;
@@ -156,16 +188,17 @@ SplashState::SplashState(SplashState *state) {
deleteSoftMask = gFalse;
inNonIsolatedGroup = state->inNonIsolatedGroup;
inKnockoutGroup = state->inKnockoutGroup;
- memcpy(rgbTransferR, state->rgbTransferR, 256);
- memcpy(rgbTransferG, state->rgbTransferG, 256);
- memcpy(rgbTransferB, state->rgbTransferB, 256);
- memcpy(grayTransfer, state->grayTransfer, 256);
+ rgbTransferR = state->rgbTransferR;
+ rgbTransferG = state->rgbTransferG;
+ rgbTransferB = state->rgbTransferB;
+ grayTransfer = state->grayTransfer;
#if SPLASH_CMYK
- memcpy(cmykTransferC, state->cmykTransferC, 256);
- memcpy(cmykTransferM, state->cmykTransferM, 256);
- memcpy(cmykTransferY, state->cmykTransferY, 256);
- memcpy(cmykTransferK, state->cmykTransferK, 256);
+ cmykTransferC = state->cmykTransferC;
+ cmykTransferM = state->cmykTransferM;
+ cmykTransferY = state->cmykTransferY;
+ cmykTransferK = state->cmykTransferK;
#endif
+ transferIsShared = gTrue;
overprintMask = state->overprintMask;
enablePathSimplification = state->enablePathSimplification;
next = NULL;
@@ -179,6 +212,9 @@ SplashState::~SplashState() {
if (!clipIsShared) {
delete clip;
}
+ if (!transferIsShared) {
+ gfree(rgbTransferR);
+ }
if (deleteSoftMask && softMask) {
delete softMask;
}
@@ -265,12 +301,12 @@ SplashError SplashState::clipToPath(SplashPath *path, GBool eo) {
enablePathSimplification, strokeAdjust);
}
-void SplashState::setSoftMask(SplashBitmap *softMaskA) {
+void SplashState::setSoftMask(SplashBitmap *softMaskA, GBool deleteBitmap) {
if (deleteSoftMask) {
delete softMask;
}
softMask = softMaskA;
- deleteSoftMask = gTrue;
+ deleteSoftMask = deleteBitmap;
}
void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
@@ -279,6 +315,24 @@ void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
int i;
#endif
+ if (transferIsShared) {
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
+ transferIsShared = gFalse;
+ }
memcpy(rgbTransferR, red, 256);
memcpy(rgbTransferG, green, 256);
memcpy(rgbTransferB, blue, 256);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
index 38cb1188e94..be64b472333 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
@@ -81,7 +81,7 @@ public:
SplashError clipToPath(SplashPath *path, GBool eo);
// Set the soft mask bitmap.
- void setSoftMask(SplashBitmap *softMaskA);
+ void setSoftMask(SplashBitmap *softMaskA, GBool deleteBitmap = gTrue);
// Set the transfer function.
void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
@@ -113,16 +113,17 @@ private:
GBool deleteSoftMask;
GBool inNonIsolatedGroup;
GBool inKnockoutGroup;
- Guchar rgbTransferR[256],
- rgbTransferG[256],
- rgbTransferB[256];
- Guchar grayTransfer[256];
+ Guchar *rgbTransferR;
+ Guchar *rgbTransferG;
+ Guchar *rgbTransferB;
+ Guchar *grayTransfer;
#if SPLASH_CMYK
- Guchar cmykTransferC[256],
- cmykTransferM[256],
- cmykTransferY[256],
- cmykTransferK[256];
+ Guchar *cmykTransferC;
+ Guchar *cmykTransferM;
+ Guchar *cmykTransferY;
+ Guchar *cmykTransferK;
#endif
+ GBool transferIsShared;
Guint overprintMask;
GBool enablePathSimplification;