~ubuntu-branches/ubuntu/hoary/libextractor/hoary

« back to all changes in this revision

Viewing changes to src/plugins/pdf/Catalog.cc

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2004-10-30 23:50:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041030235000-poix4e5mzhmzkpbk
Tags: 0.3.10-2
* Added fix from cvs for various Sparc64 problems (Closes #278905).
* Added workaround from cvs for re-load glib problem of OLE2 extractor.
* debian/watch added.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
//
3
3
// Catalog.cc
4
4
//
5
 
// Copyright 1996 Derek B. Noonburg
 
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
6
//
7
7
//========================================================================
8
8
 
9
 
#ifdef __GNUC__
 
9
#include <aconf.h>
 
10
 
 
11
#ifdef USE_GCC_PRAGMAS
10
12
#pragma implementation
11
13
#endif
12
14
 
13
15
#include <stddef.h>
14
16
#include "gmem.h"
15
17
#include "Object.h"
 
18
#include "XRef.h"
16
19
#include "Array.h"
17
20
#include "Dict.h"
18
21
#include "Page.h"
24
27
// Catalog
25
28
//------------------------------------------------------------------------
26
29
 
27
 
Catalog::Catalog(Object *catDict) {
28
 
  Object pagesDict;
 
30
Catalog::Catalog(XRef *xrefA) {
 
31
  Object catDict, pagesDict;
29
32
  Object obj, obj2;
30
33
  int numPages0;
31
34
  int i;
32
35
 
33
36
  ok = gTrue;
 
37
  xref = xrefA;
34
38
  pages = NULL;
35
39
  pageRefs = NULL;
36
40
  numPages = pagesSize = 0;
37
41
  baseURI = NULL;
38
42
 
39
 
  if (!catDict->isDict()) {
40
 
    error(-1, "Catalog object is wrong type (%s)", catDict->getTypeName());
 
43
  xref->getCatalog(&catDict);
 
44
  if (!catDict.isDict()) {
 
45
    error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
41
46
    goto err1;
42
47
  }
43
48
 
44
49
  // read page tree
45
 
  catDict->dictLookup("Pages", &pagesDict);
 
50
  catDict.dictLookup("Pages", &pagesDict);
46
51
  // This should really be isDict("Pages"), but I've seen at least one
47
52
  // PDF file where the /Type entry is missing.
48
53
  if (!pagesDict.isDict()) {
51
56
    goto err2;
52
57
  }
53
58
  pagesDict.dictLookup("Count", &obj);
54
 
  if (!obj.isInt()) {
 
59
  // some PDF files actually use real numbers here ("/Count 9.0")
 
60
  if (!obj.isNum()) {
55
61
    error(-1, "Page count in top-level pages object is wrong type (%s)",
56
62
          obj.getTypeName());
57
63
    goto err3;
58
64
  }
59
 
  pagesSize = numPages0 = obj.getInt();
 
65
  pagesSize = numPages0 = (int)obj.getNum();
60
66
  obj.free();
61
67
  pages = (Page **)gmalloc(pagesSize * sizeof(Page *));
62
68
  pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref));
72
78
  pagesDict.free();
73
79
 
74
80
  // read named destination dictionary
75
 
  catDict->dictLookup("Dests", &dests);
 
81
  catDict.dictLookup("Dests", &dests);
76
82
 
77
83
  // read root of named destination tree
78
 
  if (catDict->dictLookup("Names", &obj)->isDict())
 
84
  if (catDict.dictLookup("Names", &obj)->isDict())
79
85
    obj.dictLookup("Dests", &nameTree);
80
86
  else
81
87
    nameTree.initNull();
82
88
  obj.free();
83
89
 
84
90
  // read base URI
85
 
  if (catDict->dictLookup("URI", &obj)->isDict()) {
 
91
  if (catDict.dictLookup("URI", &obj)->isDict()) {
86
92
    if (obj.dictLookup("Base", &obj2)->isString()) {
87
93
      baseURI = obj2.getString()->copy();
88
94
    }
90
96
  }
91
97
  obj.free();
92
98
 
 
99
  // get the metadata stream
 
100
  catDict.dictLookup("Metadata", &metadata);
 
101
 
 
102
  // get the structure tree root
 
103
  catDict.dictLookup("StructTreeRoot", &structTreeRoot);
 
104
 
 
105
  // get the outline dictionary
 
106
  catDict.dictLookup("Outlines", &outline);
 
107
 
 
108
  catDict.free();
93
109
  return;
94
110
 
95
111
 err3:
97
113
 err2:
98
114
  pagesDict.free();
99
115
 err1:
 
116
  catDict.free();
100
117
  dests.initNull();
101
118
  nameTree.initNull();
102
119
  ok = gFalse;
119
136
  if (baseURI) {
120
137
    delete baseURI;
121
138
  }
 
139
  metadata.free();
 
140
  structTreeRoot.free();
 
141
  outline.free();
 
142
}
 
143
 
 
144
GString *Catalog::readMetadata() {
 
145
  GString *s;
 
146
  Dict *dict;
 
147
  Object obj;
 
148
  int c;
 
149
 
 
150
  if (!metadata.isStream()) {
 
151
    return NULL;
 
152
  }
 
153
  dict = metadata.streamGetDict();
 
154
  if (!dict->lookup("Subtype", &obj)->isName("XML")) {
 
155
    error(-1, "Unknown Metadata type: '%s'",
 
156
          obj.isName() ? obj.getName() : "???");
 
157
  }
 
158
  obj.free();
 
159
  s = new GString();
 
160
  metadata.streamReset();
 
161
  while ((c = metadata.streamGetChar()) != EOF) {
 
162
    s->append(c);
 
163
  }
 
164
  metadata.streamClose();
 
165
  return s;
122
166
}
123
167
 
124
168
int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) {
140
184
    kids.arrayGet(i, &kid);
141
185
    if (kid.isDict("Page")) {
142
186
      attrs2 = new PageAttrs(attrs1, kid.getDict());
143
 
      page = new Page(start+1, kid.getDict(), attrs2);
 
187
      page = new Page(xref, start+1, kid.getDict(), attrs2);
144
188
      if (!page->isOk()) {
145
189
        ++start;
146
190
        goto err3;
166
210
    // This should really be isDict("Pages"), but I've seen at least one
167
211
    // PDF file where the /Type entry is missing.
168
212
    } else if (kid.isDict()) {
169
 
      if ((start = readPageTree(kid.getDict(), attrs1, start)) < 0)
 
213
      if ((start = readPageTree(kid.getDict(), attrs1, start))
 
214
          < 0)
170
215
        goto err2;
171
216
    } else {
172
217
      error(-1, "Kid object (page %d) is wrong type (%s)",
225
270
  // construct LinkDest
226
271
  dest = NULL;
227
272
  if (obj1.isArray()) {
228
 
    dest = new LinkDest(obj1.getArray(), gTrue);
 
273
    dest = new LinkDest(obj1.getArray());
229
274
  } else if (obj1.isDict()) {
230
275
    if (obj1.dictLookup("D", &obj2)->isArray())
231
 
      dest = new LinkDest(obj2.getArray(), gTrue);
 
276
      dest = new LinkDest(obj2.getArray());
232
277
    else
233
278
      error(-1, "Bad named destination value");
234
279
    obj2.free();
236
281
    error(-1, "Bad named destination value");
237
282
  }
238
283
  obj1.free();
 
284
  if (dest && !dest->isOk()) {
 
285
    delete dest;
 
286
    dest = NULL;
 
287
  }
239
288
 
240
289
  return dest;
241
290
}
259
308
        } else if (cmp < 0) {
260
309
          done = gTrue;
261
310
        }
262
 
        name1.free();
263
311
      }
 
312
      name1.free();
264
313
    }
265
314
    names.free();
266
315
    if (!found)