summaryrefslogtreecommitdiff
path: root/src/xref.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xref.c')
-rw-r--r--src/xref.c117
1 files changed, 112 insertions, 5 deletions
diff --git a/src/xref.c b/src/xref.c
index 8239f45..452aa19 100644
--- a/src/xref.c
+++ b/src/xref.c
@@ -499,12 +499,123 @@ nspdferror decode_trailers(struct pdf_doc *doc)
return decode_xref_trailer(doc, startxref);
}
+/**
+ * recursively decodes a page tree
+ */
+nspdferror
+decode_page_tree(struct pdf_doc *doc,
+ struct cos_object *page_tree_node,
+ unsigned int *page_index)
+{
+ nspdferror res;
+ const char *type;
+
+ // Type = Pages
+ res = cos_get_dictionary_name(doc, page_tree_node, "Type", &type);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ if (strcmp(type, "Pages") == 0) {
+ struct cos_object *kids;
+ unsigned int kids_size;
+ unsigned int kids_index;
+
+ if (doc->page_table == NULL) {
+ /* allocate top level page table */
+ int64_t count;
+
+ res = cos_get_dictionary_int(doc, page_tree_node, "Count", &count);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ doc->page_table = calloc(count, sizeof(struct page_table_entry));
+ if (doc->page_table == NULL) {
+ return NSPDFERROR_NOMEM;
+ }
+ doc->page_table_size = count;
+ }
+
+ res = cos_get_dictionary_array(doc, page_tree_node, "Kids", &kids);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ res = cos_get_array_size(doc, kids, &kids_size);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ for (kids_index = 0; kids_index < kids_size; kids_index++) {
+ struct cos_object *kid;
+
+ res = cos_get_array_dictionary(doc, kids, kids_index, &kid);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ res = decode_page_tree(doc, kid, page_index);
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+ }
+
+ } else if (strcmp(type, "Page") == 0) {
+ struct page_table_entry *page;
+
+ page = doc->page_table + (*page_index);
+
+ /* required heritable resources */
+ res = cos_heritable_dictionary_dictionary(doc,
+ page_tree_node,
+ "Resources",
+ &(page->resources));
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ /* required heritable mediabox */
+ res = cos_heritable_dictionary_array(doc,
+ page_tree_node,
+ "MediaBox",
+ &(page->mediabox));
+ if (res != NSPDFERROR_OK) {
+ return res;
+ }
+
+ /* optional page contents */
+ res = cos_get_dictionary_value(doc,
+ page_tree_node,
+ "Contents",
+ &(page->contents));
+ if ((res != NSPDFERROR_OK) &&
+ (res != NSPDFERROR_NOTFOUND)) {
+ return res;
+ }
+
+ printf("page index:%d page:%p resources:%p mediabox:%p contents:%p\n",
+ *page_index,
+ page,
+ page->resources,
+ page->mediabox,
+ page->contents);
+
+ (*page_index)++;
+ res = NSPDFERROR_OK;
+ } else {
+ res = NSPDFERROR_FORMAT;
+ }
+ return res;
+}
+
nspdferror decode_catalog(struct pdf_doc *doc)
{
nspdferror res;
struct cos_object *catalog;
const char *type;
struct cos_object *pages;
+ unsigned int page_index = 0;
res = cos_get_dictionary(doc, doc->root, &catalog);
if (res != NSPDFERROR_OK) {
@@ -526,14 +637,10 @@ nspdferror decode_catalog(struct pdf_doc *doc)
return res;
}
- // Type = Pages
- res = cos_get_dictionary_name(doc, pages, "Type", &type);
+ res = decode_page_tree(doc, pages, &page_index);
if (res != NSPDFERROR_OK) {
return res;
}
- if (strcmp(type, "Pages") != 0) {
- return NSPDFERROR_FORMAT;
- }
return res;
}