[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