summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-11-15 19:05:59 +0000
committerRobin Watts <robin.watts@artifex.com>2011-11-17 18:32:06 +0000
commit2be04fd23c9650820fa5abd1196647ccf1b73921 (patch)
tree0828c91a4154cc8a3d4041db4f64611c43a93a2d /apps
parent9b56c6c88522b7ff6c592c93ff8ec33ee158747a (diff)
downloadmupdf-2be04fd23c9650820fa5abd1196647ccf1b73921.tar.xz
Bug 692487: Make pdfclean keep internal links where possible.
Take on a (cosmetically tweaked) version of Zenikos patch to allow pdfclean to keep link destinations that are in preserved pages.
Diffstat (limited to 'apps')
-rw-r--r--apps/pdfclean.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/apps/pdfclean.c b/apps/pdfclean.c
index f46c4b76..b436a9cb 100644
--- a/apps/pdfclean.c
+++ b/apps/pdfclean.c
@@ -278,16 +278,18 @@ static void renumberobjs(void)
static void retainpages(int argc, char **argv)
{
fz_error error;
- fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent;
+ fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;
/* Load the old page tree */
error = pdf_load_page_tree(xref);
if (error)
die(fz_rethrow(error, "cannot load page tree"));
- /* Keep only pages/type entry to avoid references to unretained pages */
+ /* Keep only pages/type and (reduced) dest entries to avoid
+ * references to unretained pages */
oldroot = fz_dict_gets(xref->trailer, "Root");
pages = fz_dict_gets(oldroot, "Pages");
+ olddests = pdf_load_name_tree(xref, "Dests");
root = fz_new_dict(2);
fz_dict_puts(root, "Type", fz_dict_gets(oldroot, "Type"));
@@ -359,6 +361,41 @@ static void retainpages(int argc, char **argv)
fz_drop_obj(countobj);
fz_dict_puts(pages, "Kids", kids);
fz_drop_obj(kids);
+
+ /* Also preserve the (partial) Dests name tree */
+ if (olddests)
+ {
+ int i;
+ fz_obj *names = fz_new_dict(1);
+ fz_obj *dests = fz_new_dict(1);
+ fz_obj *names_list = fz_new_array(32);
+
+ for (i = 0; i < fz_dict_len(olddests); i++)
+ {
+ fz_obj *key = fz_dict_get_key(olddests, i);
+ fz_obj *val = fz_dict_get_val(olddests, i);
+ fz_obj *key_str = fz_new_string(fz_to_name(key), strlen(fz_to_name(key)));
+ fz_obj *dest = fz_dict_gets(val, "D");
+
+ dest = fz_array_get(dest ? dest : val, 0);
+ if (fz_array_contains(fz_dict_gets(pages, "Kids"), dest))
+ {
+ fz_array_push(names_list, key_str);
+ fz_array_push(names_list, val);
+ }
+ fz_drop_obj(key_str);
+ }
+
+ root = fz_dict_gets(xref->trailer, "Root");
+ fz_dict_puts(dests, "Names", names_list);
+ fz_dict_puts(names, "Dests", dests);
+ fz_dict_puts(root, "Names", names);
+
+ fz_drop_obj(names);
+ fz_drop_obj(dests);
+ fz_drop_obj(names_list);
+ fz_drop_obj(olddests);
+ }
}
/*