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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> +// Copyright (C) 2009 Albert Astals Cid <[email protected]> +// +//======================================================================== + +#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 <[email protected]> +// Copyright (C) 2009 Albert Astals Cid <[email protected]> +// +//======================================================================== + +#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 _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
