summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2009-06-07 13:37:40 +0200
committerAlbert Astals Cid <aacid@kde.org>2009-06-07 13:37:40 +0200
commit2619e09833f421fb3d8cc68d41d15081ae6824e4 (patch)
tree2d09fbbf1bbfe2ec99ec4c292fb3113dd31058a1
parent588bfe3c14f42be492066c2a98e30482475a6926 (diff)
Implement a cache for PostscriptFunction transforms
Makes time of rendering of bug 21562 go down from 24 to 8 seconds
-rw-r--r--poppler/Function.cc76
-rw-r--r--poppler/Function.h2
2 files changed, 78 insertions, 0 deletions
diff --git a/poppler/Function.cc b/poppler/Function.cc
index b538f5f5..f81f0fdc 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -37,6 +37,7 @@
#include "Stream.h"
#include "Error.h"
#include "Function.h"
+#include "PopplerCache.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -1009,6 +1010,64 @@ void PSStack::roll(int n, int j) {
}
}
+class PostScriptFunctionKey : public PopplerCacheKey
+{
+ public:
+ PostScriptFunctionKey(int sizeA, double *inA, bool copyA)
+ {
+ copied = copyA;
+ size = sizeA;
+ if (copied) {
+ in = new double[size];
+ for (int i = 0; i < size; ++i) in[i] = inA[i];
+ } else {
+ in = inA;
+ }
+ }
+
+ ~PostScriptFunctionKey()
+ {
+ if (copied) delete[] in;
+ }
+
+ bool operator==(const PopplerCacheKey &key) const
+ {
+ const PostScriptFunctionKey *k = static_cast<const PostScriptFunctionKey*>(&key);
+ if (size == k->size) {
+ bool equal = true;
+ for (int i = 0; equal && i < size; ++i) {
+ equal = in[i] == k->in[i];
+ }
+ return equal;
+ } else {
+ return false;
+ }
+ }
+
+ bool copied;
+ int size;
+ double *in;
+};
+
+class PostScriptFunctionItem : public PopplerCacheItem
+{
+ public:
+ PostScriptFunctionItem(int sizeA, double *outA)
+ {
+ size = sizeA;
+ out = new double[size];
+ for (int i = 0; i < size; ++i) out[i] = outA[i];
+ }
+
+ ~PostScriptFunctionItem()
+ {
+ delete[] out;
+ }
+
+ int size;
+ double *out;
+};
+
PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
Stream *str;
int codePtr;
@@ -1018,6 +1077,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
codeString = NULL;
codeSize = 0;
ok = gFalse;
+ cache = new PopplerCache(5);
//----- initialize the generic stuff
if (!init(dict)) {
@@ -1075,10 +1135,21 @@ PostScriptFunction::~PostScriptFunction() {
gfree(code);
delete codeString;
delete stack;
+ delete cache;
}
void PostScriptFunction::transform(double *in, double *out) {
int i;
+
+ PostScriptFunctionKey key(m, in, false);
+ PopplerCacheItem *item = cache->lookup(key);
+ if (item) {
+ PostScriptFunctionItem *it = static_cast<PostScriptFunctionItem *>(item);
+ for (int i = 0; i < n; ++i) {
+ out[i] = it->out[i];
+ }
+ return;
+ }
stack->clear();
for (i = 0; i < m; ++i) {
@@ -1094,6 +1165,11 @@ void PostScriptFunction::transform(double *in, double *out) {
out[i] = range[i][1];
}
}
+
+ PostScriptFunctionKey *newKey = new PostScriptFunctionKey(m, in, true);
+ PostScriptFunctionItem *newItem = new PostScriptFunctionItem(n, out);
+ cache->put(newKey, newItem);
+
// if (!stack->empty()) {
// error(-1, "Extra values on stack at end of PostScript function");
// }
diff --git a/poppler/Function.h b/poppler/Function.h
index 4cf6fd0e..2dcccb06 100644
--- a/poppler/Function.h
+++ b/poppler/Function.h
@@ -34,6 +34,7 @@ class Dict;
class Stream;
struct PSObject;
class PSStack;
+class PopplerCache;
//------------------------------------------------------------------------
// Function
@@ -237,6 +238,7 @@ private:
PSStack *stack;
int codeSize;
GBool ok;
+ PopplerCache *cache;
};
#endif