[poppler] poppler/GfxState.cc poppler/GfxState.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Tue Oct 1 13:59:12 PDT 2013
poppler/GfxState.cc | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++
poppler/GfxState.h | 2
2 files changed, 113 insertions(+)
New commits:
commit d80eb4a34c218de34633ee2f1b9dfd65504a0ad9
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date: Tue Oct 1 22:57:55 2013 +0200
cache cms values in getGray(), getRGB() and getCMYK()
Bug #68420
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index d723833..11540ad 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -156,6 +156,8 @@ static const char *gfxColorSpaceModeNames[] = {
#ifdef USE_CMS
+static const int CMSCACHE_LIMIT = 2048;
+
#ifdef USE_LCMS1
#include <lcms.h>
#define cmsColorSpaceSignature icColorSpaceSignature
@@ -1869,8 +1871,28 @@ void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
for (int i = 0;i < nComps;i++) {
in[i] = colToByte(color->c[i]);
}
+ if (nComps <= 4) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
+ if (it != cmsCache.end()) {
+ unsigned int value = it->second;
+ *gray = byteToCol(value & 0xff);
+ return;
+ }
+ }
transform->doTransform(in,out,1);
*gray = byteToCol(out[0]);
+ if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ unsigned int value = out[0];
+ cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
+ }
} else {
GfxRGB rgb;
getRGB(color,&rgb);
@@ -1893,10 +1915,76 @@ void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
for (int i = 0;i < nComps;i++) {
in[i] = colToByte(color->c[i]);
}
+ if (nComps <= 4) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
+ if (it != cmsCache.end()) {
+ unsigned int value = it->second;
+ rgb->r = byteToCol(value >> 16);
+ rgb->g = byteToCol((value >> 8) & 0xff);
+ rgb->b = byteToCol(value & 0xff);
+ return;
+ }
+ }
transform->doTransform(in,out,1);
rgb->r = byteToCol(out[0]);
rgb->g = byteToCol(out[1]);
rgb->b = byteToCol(out[2]);
+ if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ unsigned int value = (out[0] << 16) + (out[1] << 8) + out[2];
+ cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
+ }
+ } else if (transform != 0
+ && (displayProfile == NULL || displayPixelType == PT_CMYK)) {
+ Guchar in[gfxColorMaxComps];
+ Guchar out[gfxColorMaxComps];
+ double c, m, y, k, c1, m1, y1, k1, r, g, b;
+
+ for (int i = 0;i < nComps;i++) {
+ in[i] = colToByte(color->c[i]);
+ }
+ if (nComps <= 4) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
+ if (it != cmsCache.end()) {
+ unsigned int value = it->second;
+ rgb->r = byteToCol(value >> 16);
+ rgb->g = byteToCol((value >> 8) & 0xff);
+ rgb->b = byteToCol(value & 0xff);
+ return;
+ }
+ }
+ transform->doTransform(in,out,1);
+ c = byteToDbl(out[0]);
+ m = byteToDbl(out[1]);
+ y = byteToDbl(out[2]);
+ k = byteToDbl(out[3]);
+ c1 = 1 - c;
+ m1 = 1 - m;
+ y1 = 1 - y;
+ k1 = 1 - k;
+ cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
+ rgb->r = clip01(dblToCol(r));
+ rgb->g = clip01(dblToCol(g));
+ rgb->b = clip01(dblToCol(b));
+ if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ unsigned int value = (dblToByte(r) << 16) + (dblToByte(g) << 8) + dblToByte(b);
+ cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
+ }
} else {
alt->getRGB(color, rgb);
}
@@ -2054,11 +2142,34 @@ void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
for (int i = 0;i < nComps;i++) {
in[i] = colToByte(color->c[i]);
}
+ if (nComps <= 4) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
+ if (it != cmsCache.end()) {
+ unsigned int value = it->second;
+ cmyk->c = byteToCol(value >> 24);
+ cmyk->m = byteToCol((value >> 16) & 0xff);
+ cmyk->y = byteToCol((value >> 8) & 0xff);
+ cmyk->k = byteToCol(value & 0xff);
+ return;
+ }
+ }
transform->doTransform(in,out,1);
cmyk->c = byteToCol(out[0]);
cmyk->m = byteToCol(out[1]);
cmyk->y = byteToCol(out[2]);
cmyk->k = byteToCol(out[3]);
+ if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
+ unsigned int key = 0;
+ for (int j = 0; j < nComps; j++) {
+ key = (key << 8) + in[j];
+ }
+ unsigned int value = (out[0] << 24) + (out[1] << 16) + (out[2] << 8) + out[3];
+ cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
+ }
} else {
GfxRGB rgb;
GfxColorComp c, m, y, k;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 78fdbc0..286008d 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -42,6 +42,7 @@
#include "Function.h"
#include <assert.h>
+#include <map>
class Array;
class Gfx;
@@ -546,6 +547,7 @@ private:
#ifdef USE_CMS
GfxColorTransform *transform;
GfxColorTransform *lineTransform; // color transform for line
+ std::map<unsigned int, unsigned int> cmsCache;
#endif
};
//------------------------------------------------------------------------
More information about the poppler
mailing list