[poppler] 2 commits - poppler/Gfx.cc poppler/Gfx.h poppler/PopplerCache.cc poppler/PopplerCache.h

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Sun Jan 24 09:00:12 PST 2010


 poppler/Gfx.cc          |   19 +++++++++++++--
 poppler/Gfx.h           |    2 +
 poppler/PopplerCache.cc |   60 ++++++++++++++++++++++++++++++++++++++++++++++++
 poppler/PopplerCache.h  |   16 ++++++++++++
 4 files changed, 95 insertions(+), 2 deletions(-)

New commits:
commit 59ff9d66fc3b0c9612b1c12fc1ae4dbb8dc85b39
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Sun Jan 24 17:57:48 2010 +0100

    Use a small object cache in GfxResources to cache GState objects
    
    It drastically improves performance with some documents like page 742 of
    PDF32000_2008.pdf

diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index d8e144f..f0241c7 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -307,7 +307,8 @@ static inline GBool isSameGfxColor(const GfxColor &colorA, const GfxColor &color
 // GfxResources
 //------------------------------------------------------------------------
 
-GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) {
+GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) :
+    gStateCache(2, xref) {
   Object obj1, obj2;
   Ref r;
 
@@ -480,11 +481,25 @@ GfxShading *GfxResources::lookupShading(char *name, Gfx *gfx) {
 }
 
 GBool GfxResources::lookupGState(char *name, Object *obj) {
+  Object objRef;
+
+  if (!lookupGStateNF(name, &objRef))
+    return gFalse;
+
+  if (!gStateCache.lookup(&objRef, obj)->isNull())
+    return gTrue;
+  obj->free();
+
+  gStateCache.put(&objRef)->copy(obj);
+  return gTrue;
+}
+
+GBool GfxResources::lookupGStateNF(char *name, Object *obj) {
   GfxResources *resPtr;
 
   for (resPtr = this; resPtr; resPtr = resPtr->next) {
     if (resPtr->gStateDict.isDict()) {
-      if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) {
+      if (!resPtr->gStateDict.dictLookupNF(name, obj)->isNull()) {
 	return gTrue;
       }
       obj->free();
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index ef1977a..fd4fc6c 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -113,6 +113,7 @@ public:
   GfxPattern *lookupPattern(char *name, Gfx *gfx);
   GfxShading *lookupShading(char *name, Gfx *gfx);
   GBool lookupGState(char *name, Object *obj);
+  GBool lookupGStateNF(char *name, Object *obj);
 
   GfxResources *getNext() { return next; }
 
@@ -124,6 +125,7 @@ private:
   Object patternDict;
   Object shadingDict;
   Object gStateDict;
+  PopplerObjectCache gStateCache;
   Object propertiesDict;
   GfxResources *next;
 };
commit 880a4a9a60a10f7aa7d3dc7c2802b31b7ef01e06
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Sun Jan 24 17:56:35 2010 +0100

    Add a generic cache to store objects by its reference

diff --git a/poppler/PopplerCache.cc b/poppler/PopplerCache.cc
index b0859aa..bb7f850 100644
--- a/poppler/PopplerCache.cc
+++ b/poppler/PopplerCache.cc
@@ -100,3 +100,63 @@ PopplerCacheKey *PopplerCache::key(int index)
 {
   return keys[index];
 }
+
+class ObjectKey : public PopplerCacheKey {
+  public:
+    ObjectKey(int numA, int genA) : num(numA), gen(genA)
+    {
+    }
+
+    bool operator==(const PopplerCacheKey &key) const
+    {
+      const ObjectKey *k = static_cast<const ObjectKey*>(&key);
+      return k->num == num && k->gen == gen;
+    }
+
+    int num, gen;
+};
+
+class ObjectItem : public PopplerCacheItem {
+  public:
+    ObjectItem(Object *obj)
+    {
+      obj->copy(&item);
+    }
+
+    ~ObjectItem()
+    {
+      item.free();
+    }
+
+    Object item;
+};
+
+PopplerObjectCache::PopplerObjectCache(int cacheSize, XRef *xrefA) {
+  cache = new PopplerCache (cacheSize);
+  xref = xrefA;
+}
+
+PopplerObjectCache::~PopplerObjectCache() {
+  delete cache;
+}
+
+Object *PopplerObjectCache::put(Object *objRef) {
+  Ref ref = objRef->getRef();
+  Object obj;
+  objRef->fetch(xref, &obj);
+
+  ObjectKey *key = new ObjectKey(ref.num, ref.gen);
+  ObjectItem *item = new ObjectItem(&obj);
+  cache->put(key, item);
+  obj.free();
+
+  return &item->item;
+}
+
+Object *PopplerObjectCache::lookup(Object *objRef, Object *obj) {
+  Ref ref = objRef->getRef();
+  ObjectKey key(ref.num, ref.gen);
+  ObjectItem *item = static_cast<ObjectItem *>(cache->lookup(key));
+
+  return item ? item->item.copy(obj) : obj->initNull();
+}
diff --git a/poppler/PopplerCache.h b/poppler/PopplerCache.h
index 5f22409..79c7ce2 100644
--- a/poppler/PopplerCache.h
+++ b/poppler/PopplerCache.h
@@ -12,6 +12,8 @@
 #ifndef POPPLER_CACHE_H
 #define POPPLER_CACHE_H
 
+#include "Object.h"
+
 class PopplerCacheItem
 {
   public:
@@ -58,4 +60,18 @@ class PopplerCache
     int cacheSize;
 };
 
+class PopplerObjectCache
+{
+  public:
+    PopplerObjectCache (int cacheSizeA, XRef *xrefA);
+    ~PopplerObjectCache();
+
+    Object *put(Object *objRef);
+    Object *lookup(Object *objRef, Object *obj);
+
+  private:
+    XRef *xref;
+    PopplerCache *cache;
+};
+
 #endif


More information about the poppler mailing list