In GfxColorSpace we have
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
That gets a color line for the given input and saves it in out as a 32 bit
integer with each color packed to fit in 8 bits of that 32.
This works very well for cairo as it can pass a pointer to the cairo image
data directly but for Splash is not so good as we have to unpack the 32 bit
integer to 3 (or 4 if XRGB8 format) different Guchar.
So i'm proposing the addition of
virtual void getRGBLine(Guchar *in, Guchar *out, int length);
that does basically the same but instead of packing the color just saves it in
output directly.
In my tests this gives us around a 5% free speedup.
The catch is that in some cases we need to "duplicate" the conversion code
since it is not really easy to generalize the code.
I'm attaching a work-in-progress patch.
Comments?
Albert
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 8db57b2..8afafe0 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -528,6 +528,18 @@ void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out,
out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);
}
+void GfxDeviceGrayColorSpace::getRGBLine2(Guchar *in, Guchar *out,
+ int length, GBool addFourthComponent) {
+ // TODOO
+ for (int i = 0; i < length; i++) {
+ *out++ = in[i];
+ *out++ = in[i];
+ *out++ = in[i];
+ if (addFourthComponent)
+ *out++ = 255;
+ }
+}
+
void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
cmyk->c = cmyk->m = cmyk->y = 0;
cmyk->k = clip01(gfxColorComp1 - color->c[0]);
@@ -1086,26 +1098,44 @@ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
rgb->b = clip01(dblToCol(b));
}
-void GfxDeviceCMYKColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length)
+static inline void GfxDeviceCMYKColorSpacegetRGBLineHelper(Guchar *&in, double &r, double &g, double &b)
{
- double c, m, y, k, c1, m1, y1, k1, r, g, b;
+ double c, m, y, k, c1, m1, y1, k1;
- Guchar *inp = in;
+ c = byteToDbl(*in++);
+ m = byteToDbl(*in++);
+ y = byteToDbl(*in++);
+ k = byteToDbl(*in++);
+ c1 = 1 - c;
+ m1 = 1 - m;
+ y1 = 1 - y;
+ k1 = 1 - k;
+ cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
+}
+
+void GfxDeviceCMYKColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length)
+{
+ double r, g, b;
for (int i = 0; i < length; i++) {
- c = byteToDbl(*inp++);
- m = byteToDbl(*inp++);
- y = byteToDbl(*inp++);
- k = byteToDbl(*inp++);
- c1 = 1 - c;
- m1 = 1 - m;
- y1 = 1 - y;
- k1 = 1 - k;
- cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
-
+ GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
*out++ = (dblToByte(clip01(r)) << 16) | (dblToByte(clip01(g)) << 8) | dblToByte(clip01(b));
}
}
+void GfxDeviceCMYKColorSpace::getRGBLine2(Guchar *in, Guchar *out, int length, GBool addFourthComponent)
+{
+ double r, g, b;
+
+ for (int i = 0; i < length; i++) {
+ GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
+ *out++ = dblToByte(clip01(r));
+ *out++ = dblToByte(clip01(g));
+ *out++ = dblToByte(clip01(b));
+ if (addFourthComponent)
+ *out++ = 255;
+ }
+}
+
void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
cmyk->c = clip01(color->c[0]);
cmyk->m = clip01(color->c[1]);
@@ -1651,6 +1681,29 @@ void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out,
#endif
}
+void GfxICCBasedColorSpace::getRGBLine2(Guchar *in, Guchar *out,
+ int length, GBool addFourthComponent) {
+#ifdef USE_CMS
+ if (lineTransform != 0) {
+ Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
+ lineTransform->doTransform(in, tmp, length);
+ Guchar *current = tmp;
+ for (int i = 0; i < length; ++i) {
+ *out++ = *current++;
+ *out++ = *current++;
+ *out++ = *current++;
+ if (addFourthComponent)
+ *out++ = 255;
+ }
+ gfree(tmp);
+ } else {
+ alt->getRGBLine2(in, out, length, addFourthComponent);
+ }
+#else
+ alt->getRGBLine2(in, out, length, addFourthComponent);
+#endif
+}
+
void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
#ifdef USE_CMS
if (transform != NULL && displayPixelType == PT_CMYK) {
@@ -1690,7 +1743,8 @@ void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
#endif
}
-GBool GfxICCBasedColorSpace::useGetRGBLine() {
+static inline GBool GfxICCBasedColorSpaceUseGetRGBLineHelper(GfxColorTransform *lineTransform, GfxColorSpace *alt)
+{
#ifdef USE_CMS
return lineTransform != NULL || alt->useGetRGBLine();
#else
@@ -1698,6 +1752,15 @@ GBool GfxICCBasedColorSpace::useGetRGBLine() {
#endif
}
+GBool GfxICCBasedColorSpace::useGetRGBLine() {
+ return GfxICCBasedColorSpaceUseGetRGBLineHelper(lineTransform, alt);
+}
+
+GBool GfxICCBasedColorSpace::useGetRGBLine2()
+{
+ return GfxICCBasedColorSpaceUseGetRGBLineHelper(lineTransform, alt);
+}
+
void GfxICCBasedColorSpace::getDefaultColor(GfxColor *color) {
int i;
@@ -4887,6 +4950,56 @@ void GfxImageColorMap::getRGBLine(Guchar *in, unsigned int *out, int length) {
}
}
+#include <typeinfo>
+void GfxImageColorMap::getRGBLine2(Guchar *in, Guchar *out, int length, GBool addFourthComponent) {
+ int i, j;
+ Guchar *inp, *tmp_line;
+
+ if (!useRGBLine2()) {
+// if (colorSpace2)
+// printf("%s\n", typeid(*colorSpace2).name());
+// if (!colorSpace2)
+// printf("%s\n", typeid(*colorSpace).name());
+ GfxRGB rgb;
+
+ inp = in;
+ for (i = 0; i < length; i++) {
+ getRGB (inp, &rgb);
+ *out++ = colToByte(rgb.r);
+ *out++ = colToByte(rgb.b);
+ *out++ = colToByte(rgb.g);
+ if (addFourthComponent)
+ *out++ = 255;
+ inp += nComps;
+ }
+ return;
+ }
+
+ switch (colorSpace->getMode()) {
+ case csIndexed:
+ case csSeparation:
+ tmp_line = (Guchar *) gmallocn (length, nComps2);
+ for (i = 0; i < length; i++) {
+ for (j = 0; j < nComps2; j++) {
+ tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
+ }
+ }
+ colorSpace2->getRGBLine2(tmp_line, out, length, addFourthComponent);
+ gfree (tmp_line);
+ break;
+
+ default:
+ inp = in;
+ for (j = 0; j < length; j++)
+ for (i = 0; i < nComps; i++) {
+ *inp = byte_lookup[*inp * nComps + i];
+ inp++;
+ }
+ colorSpace->getRGBLine2(in, out, length, addFourthComponent);
+ break;
+ }
+
+}
void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
GfxColor color;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 19594ed..798276d 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -201,10 +201,13 @@ public:
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {}
virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) {}
+ virtual void getRGBLine2(Guchar * /*in*/, Guchar * /*out*/, int /*length*/, GBool /*addFourthComponent*/) {}
- // Does this ColorSpace use getRGBLine?
+ // Does this ColorSpace support getRGBLine?
virtual GBool useGetRGBLine() { return gFalse; }
- // Does this ColorSpace use getGrayLine?
+ // Does this ColorSpace support getRGBLine2?
+ virtual GBool useGetRGBLine2() { return gFalse; }
+ // Does this ColorSpace support getGrayLine?
virtual GBool useGetGrayLine() { return gFalse; }
// Return the number of color components.
@@ -257,8 +260,10 @@ public:
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual void getGrayLine(Guchar *in, Guchar *out, int length);
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+ virtual void getRGBLine2(Guchar *in, Guchar *out, int length, GBool addFourthComponent);
virtual GBool useGetRGBLine() { return gTrue; }
+ virtual GBool useGetRGBLine2() { return gTrue; }
virtual GBool useGetGrayLine() { return gTrue; }
virtual int getNComps() { return 1; }
@@ -394,7 +399,9 @@ public:
virtual void getRGB(GfxColor *color, GfxRGB *rgb);
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+ virtual void getRGBLine2(Guchar *, Guchar *out, int length, GBool addFourthComponent);
virtual GBool useGetRGBLine() { return gTrue; }
+ virtual GBool useGetRGBLine2() { return gTrue; }
virtual int getNComps() { return 4; }
virtual void getDefaultColor(GfxColor *color);
@@ -468,8 +475,10 @@ public:
virtual void getRGB(GfxColor *color, GfxRGB *rgb);
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+ virtual void getRGBLine2(Guchar *in, Guchar *out, int length, GBool addFourthComponent);
virtual GBool useGetRGBLine();
+ virtual GBool useGetRGBLine2();
virtual int getNComps() { return nComps; }
virtual void getDefaultColor(GfxColor *color);
@@ -1068,11 +1077,13 @@ public:
double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
bool useRGBLine() { return (colorSpace2 && colorSpace2->useGetRGBLine ()) || (!colorSpace2 && colorSpace->useGetRGBLine ()); }
+ bool useRGBLine2() { return (colorSpace2 && colorSpace2->useGetRGBLine2 ()) || (!colorSpace2 && colorSpace->useGetRGBLine2 ()); }
// Convert an image pixel to a color.
void getGray(Guchar *x, GfxGray *gray);
void getRGB(Guchar *x, GfxRGB *rgb);
void getRGBLine(Guchar *in, unsigned int *out, int length);
+ void getRGBLine2(Guchar *in, Guchar *out, int length, GBool addFourthComponent);
void getGrayLine(Guchar *in, Guchar *out, int length);
void getCMYK(Guchar *x, GfxCMYK *cmyk);
void getColor(Guchar *x, GfxColor *color);
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index fc838d3..d7955ac 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -2428,39 +2428,13 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
*q++ = colToByte(gray);
}
break;
- case splashModeXBGR8:
+ case splashModeXBGR8:
case splashModeRGB8:
case splashModeBGR8:
- if (!imgData->colorMap->useRGBLine())
- {
- GfxRGB rgb;
- for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
- x < imgData->width;
- ++x, p += nComps) {
- imgData->colorMap->getRGB(p, &rgb);
- *q++ = colToByte(rgb.r);
- *q++ = colToByte(rgb.g);
- *q++ = colToByte(rgb.b);
- if (imgData->colorMode == splashModeXBGR8) *q++ = 255;
- }
- }
- else
- {
- p = imgData->imgStr->getLine();
- q = colorLine;
- unsigned int* line = (unsigned int *)gmallocn(imgData->width, sizeof(unsigned int));
-
- imgData->colorMap->getRGBLine(p, line, imgData->width);
- for (x = 0; x < imgData->width; ++x) {
- *q++ = (line[x] >> 16) & 255;
- *q++ = (line[x] >> 8) & 255;
- *q++ = (line[x]) & 255;
- if (imgData->colorMode == splashModeXBGR8) {
- *q++ = 255;
- }
- }
- gfree(line);
- }
+ p = imgData->imgStr->getLine();
+ q = colorLine;
+
+ imgData->colorMap->getRGBLine2(p, colorLine, imgData->width, imgData->colorMode == splashModeXBGR8);
break;
#if SPLASH_CMYK
case splashModeCMYK8:
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler