summaryrefslogtreecommitdiff
path: root/src/page.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2018-01-05 15:40:09 +0000
committerVincent Sanders <vince@kyllikki.org>2018-01-05 15:40:09 +0000
commitad6da4a71f2b837a791401e658a16bf6903fd3b5 (patch)
tree761f5e5a80a907721ff596f7f82cec85a160edad /src/page.c
parenta65babe2fbd341f9d12a50a9530682ef1e015b58 (diff)
downloadlibnspdf-ad6da4a71f2b837a791401e658a16bf6903fd3b5.tar.gz
libnspdf-ad6da4a71f2b837a791401e658a16bf6903fd3b5.tar.bz2
split out page handling into new module
Diffstat (limited to 'src/page.c')
-rw-r--r--src/page.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/page.c b/src/page.c
new file mode 100644
index 0000000..bca6dbc
--- /dev/null
+++ b/src/page.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2018 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of libnspdf.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <nspdf/page.h>
+
+#include "cos_object.h"
+#include "pdf_doc.h"
+
+/**
+ * recursively decodes a page tree
+ */
+nspdferror
+nspdf__decode_page_tree(struct nspdf_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 = nspdf__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;
+}
+
+/* exported interface documented in nspdf/page.h */
+nspdferror
+nspdf_count_pages(struct nspdf_doc *doc, unsigned int *pages_out)
+{
+ *pages_out = doc->page_table_size;
+ return NSPDFERROR_OK;
+}