summaryrefslogtreecommitdiffstats
path: root/kpdf/xpdf/xpdf/Catalog.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kpdf/xpdf/xpdf/Catalog.cc')
-rw-r--r--kpdf/xpdf/xpdf/Catalog.cc443
1 files changed, 0 insertions, 443 deletions
diff --git a/kpdf/xpdf/xpdf/Catalog.cc b/kpdf/xpdf/xpdf/Catalog.cc
deleted file mode 100644
index 198703a4..00000000
--- a/kpdf/xpdf/xpdf/Catalog.cc
+++ /dev/null
@@ -1,443 +0,0 @@
-//========================================================================
-//
-// Catalog.cc
-//
-// Copyright 1996-2007 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include "gmem.h"
-#include "Object.h"
-#include "XRef.h"
-#include "Array.h"
-#include "Dict.h"
-#include "Page.h"
-#include "Error.h"
-#include "Link.h"
-#include "Catalog.h"
-
-//------------------------------------------------------------------------
-// Catalog
-//------------------------------------------------------------------------
-
-Catalog::Catalog(XRef *xrefA) {
- Object catDict, pagesDict, pagesDictRef;
- Object obj, obj2;
- char *alreadyRead;
- int numPages0;
- int i;
-
- ok = gTrue;
- xref = xrefA;
- pages = NULL;
- pageRefs = NULL;
- numPages = pagesSize = 0;
- baseURI = NULL;
-
- xref->getCatalog(&catDict);
- if (!catDict.isDict()) {
- error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
- goto err1;
- }
-
- // read page tree
- catDict.dictLookup("Pages", &pagesDict);
- // This should really be isDict("Pages"), but I've seen at least one
- // PDF file where the /Type entry is missing.
- if (!pagesDict.isDict()) {
- error(-1, "Top-level pages object is wrong type (%s)",
- pagesDict.getTypeName());
- goto err2;
- }
- pagesDict.dictLookup("Count", &obj);
- // some PDF files actually use real numbers here ("/Count 9.0")
- if (!obj.isNum()) {
- error(-1, "Page count in top-level pages object is wrong type (%s)",
- obj.getTypeName());
- goto err3;
- }
- pagesSize = numPages0 = (int)obj.getNum();
- obj.free();
- pages = (Page **)gmallocn(pagesSize, sizeof(Page *));
- pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref));
- for (i = 0; i < pagesSize; ++i) {
- pages[i] = NULL;
- pageRefs[i].num = -1;
- pageRefs[i].gen = -1;
- }
- alreadyRead = (char *)gmalloc(xref->getNumObjects());
- memset(alreadyRead, 0, xref->getNumObjects());
- if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() &&
- pagesDictRef.getRefNum() >= 0 &&
- pagesDictRef.getRefNum() < xref->getNumObjects()) {
- alreadyRead[pagesDictRef.getRefNum()] = 1;
- }
- pagesDictRef.free();
- numPages = readPageTree(pagesDict.getDict(), NULL, 0, alreadyRead);
- gfree(alreadyRead);
- if (numPages != numPages0) {
- error(-1, "Page count in top-level pages object is incorrect");
- }
- pagesDict.free();
-
- // read named destination dictionary
- catDict.dictLookup("Dests", &dests);
-
- // read root of named destination tree
- if (catDict.dictLookup("Names", &obj)->isDict()) {
- obj.dictLookup("Dests", &obj2);
- destNameTree.init(xref, &obj2);
- obj2.free();
- }
- obj.free();
-
- // read base URI
- if (catDict.dictLookup("URI", &obj)->isDict()) {
- if (obj.dictLookup("Base", &obj2)->isString()) {
- baseURI = obj2.getString()->copy();
- }
- obj2.free();
- }
- obj.free();
-
- // read page mode
- if (catDict.dictLookup("PageMode", &obj)->isName()) {
- if (strcmp(obj.getName(), "UseNone") == 0)
- pageMode = UseNone;
- else if (strcmp(obj.getName(), "UseOutlines") == 0)
- pageMode = UseOutlines;
- else if (strcmp(obj.getName(), "UseThumbs") == 0)
- pageMode = UseThumbs;
- else if (strcmp(obj.getName(), "FullScreen") == 0)
- pageMode = FullScreen;
- else if (strcmp(obj.getName(), "UseOC") == 0)
- pageMode = UseOC;
- else
- pageMode = UseNone;
- } else {
- pageMode = UseNone;
- }
- obj.free();
-
- // get the metadata stream
- catDict.dictLookup("Metadata", &metadata);
-
- // get the structure tree root
- catDict.dictLookup("StructTreeRoot", &structTreeRoot);
-
- // get the outline dictionary
- catDict.dictLookup("Outlines", &outline);
-
- // get the AcroForm dictionary
- catDict.dictLookup("AcroForm", &acroForm);
-
- catDict.free();
- return;
-
- err3:
- obj.free();
- err2:
- pagesDict.free();
- err1:
- catDict.free();
- dests.initNull();
- ok = gFalse;
-}
-
-Catalog::~Catalog() {
- int i;
-
- if (pages) {
- for (i = 0; i < pagesSize; ++i) {
- if (pages[i]) {
- delete pages[i];
- }
- }
- gfree(pages);
- gfree(pageRefs);
- }
- dests.free();
- destNameTree.free();
- if (baseURI) {
- delete baseURI;
- }
- metadata.free();
- structTreeRoot.free();
- outline.free();
- acroForm.free();
-}
-
-GString *Catalog::readMetadata() {
- GString *s;
- Dict *dict;
- Object obj;
- int c;
-
- if (!metadata.isStream()) {
- return NULL;
- }
- dict = metadata.streamGetDict();
- if (!dict->lookup("Subtype", &obj)->isName("XML")) {
- error(-1, "Unknown Metadata type: '%s'",
- obj.isName() ? obj.getName() : "???");
- }
- obj.free();
- s = new GString();
- metadata.streamReset();
- while ((c = metadata.streamGetChar()) != EOF) {
- s->append(c);
- }
- metadata.streamClose();
- return s;
-}
-
-int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start,
- char *alreadyRead) {
- Object kids;
- Object kid;
- Object kidRef;
- PageAttrs *attrs1, *attrs2;
- Page *page;
- int i, j;
-
- attrs1 = new PageAttrs(attrs, pagesDict);
- pagesDict->lookup("Kids", &kids);
- if (!kids.isArray()) {
- error(-1, "Kids object (page %d) is wrong type (%s)",
- start+1, kids.getTypeName());
- goto err1;
- }
- for (i = 0; i < kids.arrayGetLength(); ++i) {
- kids.arrayGetNF(i, &kidRef);
- if (kidRef.isRef() &&
- kidRef.getRefNum() >= 0 &&
- kidRef.getRefNum() < xref->getNumObjects()) {
- if (alreadyRead[kidRef.getRefNum()]) {
- error(-1, "Loop in Pages tree");
- kidRef.free();
- continue;
- }
- alreadyRead[kidRef.getRefNum()] = 1;
- }
- kids.arrayGet(i, &kid);
- if (kid.isDict("Page")) {
- attrs2 = new PageAttrs(attrs1, kid.getDict());
- page = new Page(xref, start+1, kid.getDict(), attrs2);
- if (!page->isOk()) {
- ++start;
- goto err3;
- }
- if (start >= pagesSize) {
- pagesSize += 32;
- pages = (Page **)greallocn(pages, pagesSize, sizeof(Page *));
- pageRefs = (Ref *)greallocn(pageRefs, pagesSize, sizeof(Ref));
- for (j = pagesSize - 32; j < pagesSize; ++j) {
- pages[j] = NULL;
- pageRefs[j].num = -1;
- pageRefs[j].gen = -1;
- }
- }
- pages[start] = page;
- if (kidRef.isRef()) {
- pageRefs[start].num = kidRef.getRefNum();
- pageRefs[start].gen = kidRef.getRefGen();
- }
- ++start;
- // This should really be isDict("Pages"), but I've seen at least one
- // PDF file where the /Type entry is missing.
- } else if (kid.isDict()) {
- if ((start = readPageTree(kid.getDict(), attrs1, start, alreadyRead))
- < 0)
- goto err2;
- } else {
- error(-1, "Kid object (page %d) is wrong type (%s)",
- start+1, kid.getTypeName());
- }
- kid.free();
- kidRef.free();
- }
- delete attrs1;
- kids.free();
- return start;
-
- err3:
- delete page;
- err2:
- kid.free();
- err1:
- kids.free();
- delete attrs1;
- ok = gFalse;
- return -1;
-}
-
-int Catalog::findPage(int num, int gen) {
- int i;
-
- for (i = 0; i < numPages; ++i) {
- if (pageRefs[i].num == num && pageRefs[i].gen == gen)
- return i + 1;
- }
- return 0;
-}
-
-LinkDest *Catalog::findDest(GString *name) {
- LinkDest *dest;
- Object obj1, obj2;
- GBool found;
-
- // try named destination dictionary then name tree
- found = gFalse;
- if (dests.isDict()) {
- if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
- found = gTrue;
- else
- obj1.free();
- }
- if (!found) {
- if (destNameTree.lookup(name, &obj1))
- found = gTrue;
- else
- obj1.free();
- }
- if (!found)
- return NULL;
-
- // construct LinkDest
- dest = NULL;
- if (obj1.isArray()) {
- dest = new LinkDest(obj1.getArray());
- } else if (obj1.isDict()) {
- if (obj1.dictLookup("D", &obj2)->isArray())
- dest = new LinkDest(obj2.getArray());
- else
- error(-1, "Bad named destination value");
- obj2.free();
- } else {
- error(-1, "Bad named destination value");
- }
- obj1.free();
- if (dest && !dest->isOk()) {
- delete dest;
- dest = NULL;
- }
-
- return dest;
-}
-
-NameTree::NameTree()
-{
- size = 0;
- length = 0;
- entries = NULL;
-}
-
-NameTree::Entry::Entry(Array *array, int index) {
- if (!array->getString(index, &name) || !array->getNF(index + 1, &value))
- error(-1, "Invalid page tree");
-}
-
-NameTree::Entry::~Entry() {
- value.free();
-}
-
-void NameTree::addEntry(Entry *entry)
-{
- if (length == size) {
- if (length == 0) {
- size = 8;
- } else {
- size *= 2;
- }
- entries = (Entry **) grealloc (entries, sizeof (Entry *) * size);
- }
-
- entries[length] = entry;
- ++length;
-}
-
-void NameTree::init(XRef *xrefA, Object *tree) {
- xref = xrefA;
- parse(tree);
-}
-
-void NameTree::parse(Object *tree) {
- Object names;
- Object kids, kid;
- int i;
-
- if (!tree->isDict())
- return;
-
- // leaf node
- if (tree->dictLookup("Names", &names)->isArray()) {
- for (i = 0; i < names.arrayGetLength(); i += 2) {
- NameTree::Entry *entry;
-
- entry = new Entry(names.getArray(), i);
- addEntry(entry);
- }
- }
- names.free();
-
- // root or intermediate node
- if (tree->dictLookup("Kids", &kids)->isArray()) {
- for (i = 0; i < kids.arrayGetLength(); ++i) {
- if (kids.arrayGet(i, &kid)->isDict())
- parse(&kid);
- kid.free();
- }
- }
- kids.free();
-}
-
-int NameTree::Entry::cmp(const void *voidKey, const void *voidEntry)
-{
- GString *key = (GString *) voidKey;
- Entry *entry = *(NameTree::Entry **) voidEntry;
-
- return key->cmp(&entry->name);
-}
-
-GBool NameTree::lookup(GString *name, Object *obj)
-{
- Entry *entry;
-
- Entry **e = (Entry **) bsearch(name, entries,
- length, sizeof(Entry *), Entry::cmp);
- if (e) entry = *e;
- else
- {
- error(-1, "failed to look up %s\n", name->getCString());
- obj->initNull();
- return gFalse;
- }
- if (entry != NULL) {
- entry->value.fetch(xref, obj);
- return gTrue;
- } else {
- error(-1, "failed to look up %s\n", name->getCString());
-
- obj->initNull();
-
- return gFalse;
- }
-}
-
-void NameTree::free()
-{
- int i;
-
- for (i = 0; i < length; i++)
- delete entries[i];
-
- gfree(entries);
-}