[poppler] Branch 'poppler-0.8' - poppler/XRef.cc poppler/XRef.h

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Jul 25 11:10:23 PDT 2008


 poppler/XRef.cc |   70 ++++++++++++++++++++------------------------------------
 poppler/XRef.h  |    1 
 2 files changed, 25 insertions(+), 46 deletions(-)

New commits:
commit 52e9dd430d126207571e6f6d0a440ee078db89e5
Author: Albert Astals Cid <aacid at kde.org>
Date:   Fri Jul 25 20:05:49 2008 +0200

    Fix XRef::add and XRef::addIndirectObject, also remove num from XRefEntry
    
    Previous code was under some incorrect assumptions:
     * our XRef does not maintain the free link list so if you want to
       find a free entry you have to go though all of them
     * our XRefEntry does not need a num because the index itself is the num

diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index f950232..5c19c09 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1004,12 +1004,12 @@ Guint XRef::strToUnsigned(char *s) {
 }
 
 void XRef::add(int num, int gen, Guint offs, GBool used) {
-  size += 1;
-  entries = (XRefEntry *)greallocn(entries, size, sizeof(XRefEntry));
-  XRefEntry *e = &entries[size-1];
-
+  if (num >= size) {
+    size = num + 1;
+    entries = (XRefEntry *)greallocn(entries, size, sizeof(XRefEntry));
+  }
+  XRefEntry *e = &entries[num];
   e->gen = gen;
-  e->num = num;
   e->obj.initNull ();
   e->updated = false;
   if (used) {
@@ -1031,53 +1031,37 @@ void XRef::setModifiedObject (Object* o, Ref r) {
 }
 
 Ref XRef::addIndirectObject (Object* o) {
-  //Find the next free entry
-  // lastEntry is the last free entry we encountered,
-  // entry 0 is always free
-  int lastEntry = 0;
-  int newEntry = entries[0].offset;
-
-  do {
-    lastEntry = newEntry;
-    newEntry = entries[newEntry].offset;
-    //we are looking for a free entry that we can reuse
-    //(=> gen number != 65535)
-  } while ((newEntry != 0) && (entries[newEntry].gen == 65535));
-
-  //the linked list of free entry is empty => create a new one
-  if (newEntry == 0) {
-    newEntry = size;
+  int entryIndexToUse = -1;
+  for (int i = 1; entryIndexToUse == -1 && i < size; ++i) {
+    if (entries[i].type == xrefEntryFree) entryIndexToUse = i;
+  }
+
+  XRefEntry *e;
+  if (entryIndexToUse == -1) {
+    entryIndexToUse = size;
     size++;
     entries = (XRefEntry *)greallocn(entries, size, sizeof(XRefEntry));
-    entries[newEntry].gen = 0;
-    entries[newEntry].num = newEntry;
-  } else { //reuse a free entry
-    //'remove' the entry we are using from the free entry linked list
-    entries[lastEntry].offset = entries[newEntry].offset;
-    entries[newEntry].num = newEntry;
+    e = &entries[entryIndexToUse];
+    e->gen = 0;
+  } else {
+    //reuse a free entry
+    e = &entries[entryIndexToUse];
     //we don't touch gen number, because it should have been 
     //incremented when the object was deleted
   }
-
-  entries[newEntry].type = xrefEntryUncompressed;
-  o->copy(&entries[newEntry].obj);
-  entries[newEntry].updated = true;
+  e->type = xrefEntryUncompressed;
+  o->copy(&e->obj);
+  e->updated = true;
 
   Ref r;
-  r.num = entries[newEntry].num;
-  r.gen = entries[newEntry].gen;
+  r.num = entryIndexToUse;
+  r.gen = e->gen;
   return r;
 }
 
 
 //used to sort the entries
-int compare (const void* a, const void* b)
-{
-  return (((XRefEntry*)a)->num - ((XRefEntry*)b)->num);
-}
-
 void XRef::writeToFile(OutStream* outStr) {
-  qsort(entries, size, sizeof(XRefEntry), compare);
   //create free entries linked-list
   if (entries[0].gen != 65535) {
     error(-1, "XRef::writeToFile, entry 0 of the XRef is invalid (gen != 65535)\n");
@@ -1085,7 +1069,7 @@ void XRef::writeToFile(OutStream* outStr) {
   int lastFreeEntry = 0; 
   for (int i=0; i<size; i++) {
     if (entries[i].type == xrefEntryFree) {
-      entries[lastFreeEntry].offset = entries[i].num;
+      entries[lastFreeEntry].offset = i;
       lastFreeEntry = i;
     }
   }
@@ -1093,11 +1077,7 @@ void XRef::writeToFile(OutStream* outStr) {
   int j;
   outStr->printf("xref\r\n");
   for (int i=0; i<size; i++) {
-    for(j=i; j<size; j++) { //look for consecutive entries
-      if (j!=i && entries[j].num != entries[j-1].num+1) 
-              break;
-    }
-    outStr->printf("%i %i\r\n", entries[i].num, j-i);
+    outStr->printf("%i %i\r\n", i, i+size);
     for (int k=i; k<j; k++) {
       if(entries[k].gen > 65535) entries[k].gen = 65535; //cap generation number to 65535 (required by PDFReference)
       outStr->printf("%010i %05i %c\r\n", entries[k].offset, entries[k].gen, (entries[k].type==xrefEntryFree)?'f':'n');
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 4a25515..a7e047f 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -34,7 +34,6 @@ enum XRefEntryType {
 struct XRefEntry {
   Guint offset;
   int gen;
-  int num;
   XRefEntryType type;
   bool updated;
   Object obj; //if this entry was updated, obj will contains the updated object


More information about the poppler mailing list