summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cos_object.c47
-rw-r--r--src/cos_object.h7
-rw-r--r--src/document.c22
-rw-r--r--src/page.c2
4 files changed, 52 insertions, 26 deletions
diff --git a/src/cos_object.c b/src/cos_object.c
index 12adcc9..ad7a17f 100644
--- a/src/cos_object.c
+++ b/src/cos_object.c
@@ -178,31 +178,42 @@ nspdferror cos_free_object(struct cos_object *cos_obj)
* this finds and returns a value for a given key removing it from a dictionary
*/
nspdferror
-cos_extract_dictionary_value(struct cos_object *dict,
+cos_extract_dictionary_value(struct nspdf_doc *doc,
+ struct cos_object *dict,
const char *key,
struct cos_object **value_out)
{
- struct cos_dictionary_entry *entry;
- struct cos_dictionary_entry **prev;
+ nspdferror res;
- if (dict->type != COS_TYPE_DICTIONARY) {
- return NSPDFERROR_TYPE;
- }
+ res = nspdf__xref_get_referenced(doc, &dict);
+ if (res == NSPDFERROR_OK) {
+ if (dict->type != COS_TYPE_DICTIONARY) {
+ res = NSPDFERROR_TYPE;
- prev = &dict->u.dictionary;
- entry = *prev;
- while (entry != NULL) {
- if (strcmp(entry->key->u.name, key) == 0) {
- *value_out = entry->value;
- *prev = entry->next;
- cos_free_object(entry->key);
- free(entry);
- return NSPDFERROR_OK;
+ } else {
+ struct cos_dictionary_entry **prev;
+ struct cos_dictionary_entry *entry;
+
+ res = NSPDFERROR_NOTFOUND;
+
+ prev = &dict->u.dictionary;
+ entry = *prev;
+ while (entry != NULL) {
+ if (strcmp(entry->key->u.name, key) == 0) {
+ *value_out = entry->value;
+ *prev = entry->next;
+ cos_free_object(entry->key);
+ free(entry);
+ res = NSPDFERROR_OK;
+ break;
+ }
+ prev = &entry->next;
+ entry = *prev;
+ }
}
- prev = &entry->next;
- entry = *prev;
}
- return NSPDFERROR_NOTFOUND;
+ return res;
+
}
diff --git a/src/cos_object.h b/src/cos_object.h
index a1a70ee..1214a65 100644
--- a/src/cos_object.h
+++ b/src/cos_object.h
@@ -149,6 +149,11 @@ nspdferror cos_free_object(struct cos_object *cos_obj);
* the entry from the dictionary. Once extracted the caller owns the returned
* object and must free it.
*
+ * Get the value for a key from a dictionary, If the dictionary is an object
+ * reference it will be dereferenced first which will parse any previously
+ * unreferenced indirect objects.
+ *
+ * \param doc The document the cos object belongs to or NULL to supress dereferencing.
* \param dict The dictionary
* \param key The key to lookup
* \param value_out The value object associated with the key
@@ -156,7 +161,7 @@ nspdferror cos_free_object(struct cos_object *cos_obj);
* NSPDFERROR_TYPE if the object passed in \p dict is not a dictionary.
* NSPDFERROR_NOTFOUND if the key is not present in the dictionary.
*/
-nspdferror cos_extract_dictionary_value(struct cos_object *dict, const char *key, struct cos_object **value_out);
+nspdferror cos_extract_dictionary_value(struct nspdf_doc *doc, struct cos_object *dict, const char *key, struct cos_object **value_out);
/**
diff --git a/src/document.c b/src/document.c
index dcf8395..bd3d314 100644
--- a/src/document.c
+++ b/src/document.c
@@ -240,7 +240,7 @@ decode_xref_trailer(struct nspdf_doc *doc, unsigned int xref_offset)
goto decode_xref_trailer_failed;
}
- res = cos_extract_dictionary_value(trailer, "Root", &doc->root);
+ res = cos_extract_dictionary_value(NULL, trailer, "Root", &doc->root);
if (res != NSPDFERROR_OK) {
printf("no Root!\n");
goto decode_xref_trailer_failed;
@@ -251,17 +251,17 @@ decode_xref_trailer(struct nspdf_doc *doc, unsigned int xref_offset)
goto decode_xref_trailer_failed;
}
- res = cos_extract_dictionary_value(trailer, "Encrypt", &doc->encrypt);
+ res = cos_extract_dictionary_value(NULL, trailer, "Encrypt", &doc->encrypt);
if ((res != NSPDFERROR_OK) && (res != NSPDFERROR_NOTFOUND)) {
goto decode_xref_trailer_failed;
}
- res = cos_extract_dictionary_value(trailer, "Info", &doc->info);
+ res = cos_extract_dictionary_value(NULL, trailer, "Info", &doc->info);
if ((res != NSPDFERROR_OK) && (res != NSPDFERROR_NOTFOUND)) {
goto decode_xref_trailer_failed;
}
- res = cos_extract_dictionary_value(trailer, "ID", &doc->id);
+ res = cos_extract_dictionary_value(NULL, trailer, "ID", &doc->id);
if ((res != NSPDFERROR_OK) && (res != NSPDFERROR_NOTFOUND)) {
goto decode_xref_trailer_failed;
}
@@ -353,7 +353,7 @@ static nspdferror decode_catalog(struct nspdf_doc *doc)
return res;
}
- // Type = Catalog
+ /* Type = Catalog */
res = cos_get_dictionary_name(doc, catalog, "Type", &type);
if (res != NSPDFERROR_OK) {
return res;
@@ -362,7 +362,13 @@ static nspdferror decode_catalog(struct nspdf_doc *doc)
return NSPDFERROR_FORMAT;
}
- // Pages
+ /* Pages */
+
+ /** todo this should get the dictionary Pages object and check it is an
+ * indirect reference (spec says it *must* be) then below has the reference
+ * to free in xref table
+ */
+
res = cos_get_dictionary_dictionary(doc, catalog, "Pages", &pages);
if (res != NSPDFERROR_OK) {
return res;
@@ -373,6 +379,10 @@ static nspdferror decode_catalog(struct nspdf_doc *doc)
return res;
}
+ /** \todo need to free referenced object when page resources tree is copied
+ * instead of being owned by the reference. Right now we leak like a seive
+ */
+
return res;
}
diff --git a/src/page.c b/src/page.c
index d55a92f..0d12fc2 100644
--- a/src/page.c
+++ b/src/page.c
@@ -175,7 +175,7 @@ nspdf__decode_page_tree(struct nspdf_doc *doc,
}
/* optional page contents */
- res = cos_get_dictionary_value(doc,
+ res = cos_extract_dictionary_value(doc,
page_tree_node,
"Contents",
&(page->contents));