[poppler] 3 commits - CMakeLists.txt poppler/Function.cc poppler/Function.h poppler/GfxState.cc poppler/GfxState.h poppler/Makefile.am poppler/PopplerCache.cc poppler/PopplerCache.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Sun Jun 7 04:39:20 PDT 2009
CMakeLists.txt | 1
poppler/Function.cc | 76 +++++++++++++++++++++++++++++++++++++
poppler/Function.h | 2
poppler/GfxState.cc | 97 ++++++++++++++++++++++--------------------------
poppler/GfxState.h | 19 +--------
poppler/Makefile.am | 1
poppler/PopplerCache.cc | 82 ++++++++++++++++++++++++++++++++++++++++
poppler/PopplerCache.h | 47 +++++++++++++++++++++++
8 files changed, 258 insertions(+), 67 deletions(-)
New commits:
commit 3d40dcad850a2bc0e28845a15722db0c79920135
Author: Albert Astals Cid <aacid at kde.org>
Date: Sun Jun 7 13:38:50 2009 +0200
Move the GfxState cache to the new poppler cache class
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index d75e015..932bfff 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -43,6 +43,7 @@
#include "GfxState_helpers.h"
#include "GfxFont.h"
#include "GlobalParams.h"
+#include "PopplerCache.h"
//------------------------------------------------------------------------
@@ -1351,6 +1352,38 @@ void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
// GfxICCBasedColorSpace
//------------------------------------------------------------------------
+class GfxICCBasedColorSpaceKey : public PopplerCacheKey
+{
+ public:
+ GfxICCBasedColorSpaceKey(int numA, int genA) : num(numA), gen(genA)
+ {
+ }
+
+ bool operator==(const PopplerCacheKey &key) const
+ {
+ const GfxICCBasedColorSpaceKey *k = static_cast<const GfxICCBasedColorSpaceKey*>(&key);
+ return k->num == num && k->gen == gen;
+ }
+
+ int num, gen;
+};
+
+class GfxICCBasedColorSpaceItem : public PopplerCacheItem
+{
+ public:
+ GfxICCBasedColorSpaceItem(GfxICCBasedColorSpace *csA)
+ {
+ cs = static_cast<GfxICCBasedColorSpace*>(csA->copy());
+ }
+
+ ~GfxICCBasedColorSpaceItem()
+ {
+ delete cs;
+ }
+
+ GfxICCBasedColorSpace *cs;
+};
+
GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
Ref *iccProfileStreamA) {
nComps = nCompsA;
@@ -1413,9 +1446,15 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) {
obj1.free();
#ifdef USE_CMS
// check cache
- if (iccProfileStreamA.num > 0
- && (cs = GfxICCBasedCache::lookup(iccProfileStreamA.num,
- iccProfileStreamA.gen)) != NULL) return cs;
+ if (iccProfileStreamA.num > 0) {
+ GfxICCBasedColorSpaceKey k(iccProfileStreamA.num, iccProfileStreamA.gen);
+ GfxICCBasedColorSpaceItem *item = static_cast<GfxICCBasedColorSpaceItem *>(cache->lookup(k));
+ if (item != NULL)
+ {
+ cs = static_cast<GfxICCBasedColorSpace*>(item->cs->copy());
+ return cs;
+ }
+ }
#endif
arr->get(1, &obj1);
if (!obj1.isStream()) {
@@ -1529,7 +1568,9 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) {
obj1.free();
// put this colorSpace into cache
if (iccProfileStreamA.num > 0) {
- GfxICCBasedCache::put(iccProfileStreamA.num,iccProfileStreamA.gen,cs);
+ GfxICCBasedColorSpaceKey *k = new GfxICCBasedColorSpaceKey(iccProfileStreamA.num, iccProfileStreamA.gen);
+ GfxICCBasedColorSpaceItem *item = new GfxICCBasedColorSpaceItem(cs);
+ cache->put(k, item);
}
#endif
return cs;
@@ -1670,53 +1711,7 @@ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
}
#ifdef USE_CMS
-GfxICCBasedCache
- GfxICCBasedCache::cache[GFX_ICCBASED_CACHE_SIZE];
-
-GfxICCBasedCache::GfxICCBasedCache()
-{
- num = 0;
- gen = 0;
- colorSpace = 0;
-}
-
-GfxICCBasedColorSpace *GfxICCBasedCache::lookup(int numA, int genA)
-{
- int i;
-
- if (cache[0].num == numA && cache[0].gen == genA) {
- return (GfxICCBasedColorSpace *)cache[0].colorSpace->copy();
- }
- for (i = 1;i < GFX_ICCBASED_CACHE_SIZE && cache[i].num > 0;i++) {
- if (cache[i].num == numA && cache[i].gen == genA) {
- int j;
- GfxICCBasedCache hit = cache[i];
-
- for (j = i;j > 0;j--) {
- if (cache[j - 1].num > 0) cache[j] = cache[j-1];
- }
- cache[0] = hit;
- return (GfxICCBasedColorSpace *)hit.colorSpace->copy();
- }
- }
- return NULL;
-}
-
-void GfxICCBasedCache::put(int numA, int genA,
- GfxICCBasedColorSpace *cs)
-{
- int i;
-
- if (cache[GFX_ICCBASED_CACHE_SIZE-1].num > 0) {
- delete cache[GFX_ICCBASED_CACHE_SIZE-1].colorSpace;
- }
- for (i = GFX_ICCBASED_CACHE_SIZE-1; i > 0; i--) {
- if (cache[i - 1].num > 0) cache[i] = cache[i - 1];
- }
- cache[0].num = numA;
- cache[0].gen = genA;
- cache[0].colorSpace = (GfxICCBasedColorSpace *)cs->copy();
-}
+PopplerCache *GfxICCBasedColorSpace::cache = new PopplerCache(5);
#endif
//------------------------------------------------------------------------
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 09abc2f..6c8be49 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -38,6 +38,7 @@ class Array;
class GfxFont;
class PDFRectangle;
class GfxShading;
+class PopplerCache;
class Matrix {
public:
@@ -458,24 +459,10 @@ private:
#ifdef USE_CMS
GfxColorTransform *transform;
GfxColorTransform *lineTransform; // color transform for line
-#endif
-};
-#ifdef USE_CMS
-#define GFX_ICCBASED_CACHE_SIZE 5
-class GfxICCBasedCache {
-public:
- static GfxICCBasedColorSpace *lookup(int numA, int genA);
- static void put(int numA, int genA, GfxICCBasedColorSpace *cs);
-private:
- GfxICCBasedCache();
- int num;
- int gen;
- GfxICCBasedColorSpace *colorSpace;
- static GfxICCBasedCache cache[GFX_ICCBASED_CACHE_SIZE];
-};
+ static PopplerCache *cache;
#endif
-
+};
//------------------------------------------------------------------------
// GfxIndexedColorSpace
//------------------------------------------------------------------------
commit 2619e09833f421fb3d8cc68d41d15081ae6824e4
Author: Albert Astals Cid <aacid at kde.org>
Date: Sun Jun 7 13:37:40 2009 +0200
Implement a cache for PostscriptFunction transforms
Makes time of rendering of bug 21562 go down from 24 to 8 seconds
diff --git a/poppler/Function.cc b/poppler/Function.cc
index b538f5f..f81f0fd 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 4cf6fd0..2dcccb0 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
commit 588bfe3c14f42be492066c2a98e30482475a6926
Author: Albert Astals Cid <aacid at kde.org>
Date: Sun Jun 7 13:36:39 2009 +0200
Add a code to a generic cache based on Koji's code for GfxState cache
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0fbc49a..194d46b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -182,6 +182,7 @@ set(poppler_SRCS
poppler/Parser.cc
poppler/PDFDoc.cc
poppler/PDFDocEncoding.cc
+ poppler/PopplerCache.cc
poppler/ProfileData.cc
poppler/PreScanOutputDev.cc
poppler/PSTokenizer.cc
diff --git a/poppler/Makefile.am b/poppler/Makefile.am
index 4f0f410..f43cf4b 100644
--- a/poppler/Makefile.am
+++ b/poppler/Makefile.am
@@ -255,6 +255,7 @@ libpoppler_la_SOURCES = \
Parser.cc \
PDFDoc.cc \
PDFDocEncoding.cc \
+ PopplerCache.cc \
ProfileData.cc \
PreScanOutputDev.cc \
PSTokenizer.cc \
diff --git a/poppler/PopplerCache.cc b/poppler/PopplerCache.cc
new file mode 100644
index 0000000..10c5f99
--- /dev/null
+++ b/poppler/PopplerCache.cc
@@ -0,0 +1,82 @@
+//========================================================================
+//
+// PopplerCache.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2009 Koji Otani <sho at bbr.jp>
+// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
+//
+//========================================================================
+
+#include "PopplerCache.h"
+
+PopplerCacheKey::~PopplerCacheKey()
+{
+}
+
+PopplerCacheItem::~PopplerCacheItem()
+{
+}
+
+PopplerCache::PopplerCache(int cacheSizeA)
+{
+ cacheSize = cacheSizeA;
+ keys = new PopplerCacheKey*[cacheSize];
+ items = new PopplerCacheItem*[cacheSize];
+ lastValidCacheIndex = -1;
+}
+
+PopplerCache::~PopplerCache()
+{
+ for (int i = 0; i <= lastValidCacheIndex; ++i) {
+ delete keys[i];
+ delete items[i];
+ }
+ delete[] keys;
+ delete[] items;
+}
+
+PopplerCacheItem *PopplerCache::lookup(const PopplerCacheKey &key)
+{
+ if (lastValidCacheIndex < 0)
+ return 0;
+
+ if (*keys[0] == key) {
+ return items[0];
+ }
+ for (int i = 1; i <= lastValidCacheIndex; i++) {
+ if (*keys[i] == key) {
+ PopplerCacheKey *keyHit = keys[i];
+ PopplerCacheItem *itemHit = items[i];
+
+ for (int j = i; j > 0; j--) {
+ keys[j] = keys[j - 1];
+ items[j] = items[j - 1];
+ }
+
+ keys[0] = keyHit;
+ items[0] = itemHit;
+ return itemHit;
+ }
+ }
+ return 0;
+}
+
+void PopplerCache::put(PopplerCacheKey *key, PopplerCacheItem *item)
+{
+ int movingStartIndex = lastValidCacheIndex + 1;
+ if (lastValidCacheIndex == cacheSize - 1) {
+ delete keys[lastValidCacheIndex];
+ delete items[lastValidCacheIndex];
+ movingStartIndex = cacheSize - 1;
+ } else {
+ lastValidCacheIndex++;
+ }
+ for (int i = movingStartIndex; i > 0; i--) {
+ keys[i] = keys[i - 1];
+ items[i] = items[i - 1];
+ }
+ keys[0] = key;
+ items[0] = item;
+}
diff --git a/poppler/PopplerCache.h b/poppler/PopplerCache.h
new file mode 100644
index 0000000..7d72d76
--- /dev/null
+++ b/poppler/PopplerCache.h
@@ -0,0 +1,47 @@
+//========================================================================
+//
+// PopplerCache.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2009 Koji Otani <sho at bbr.jp>
+// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
+//
+//========================================================================
+
+#ifndef POPPLER_CACHE_H
+#define POPPLER_CACHE_H
+
+class PopplerCacheItem
+{
+ public:
+ virtual ~PopplerCacheItem();
+};
+
+class PopplerCacheKey
+{
+ public:
+ virtual ~PopplerCacheKey();
+ virtual bool operator==(const PopplerCacheKey &key) const = 0;
+};
+
+class PopplerCache
+{
+ public:
+ PopplerCache(int cacheSizeA);
+ ~PopplerCache();
+
+ /* The item returned is owned by the cache */
+ PopplerCacheItem *lookup(const PopplerCacheKey &key);
+
+ /* The key and item pointers ownership is taken by the cache */
+ void put(PopplerCacheKey *key, PopplerCacheItem *item);
+
+ private:
+ PopplerCacheKey **keys;
+ PopplerCacheItem **items;
+ int lastValidCacheIndex;
+ int cacheSize;
+};
+
+#endif
More information about the poppler
mailing list