summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-object.c
diff options
context:
space:
mode:
authorPaul Gardiner <paul.gardiner@artifex.com>2015-08-27 14:07:23 +0100
committerPaul Gardiner <paul.gardiner@artifex.com>2015-08-27 15:16:52 +0100
commita638d6d24069943fbc950587db2e03f18cfea581 (patch)
treeca20a275d12da543c3a672f43e41806067693f87 /source/pdf/pdf-object.c
parente5e3cb777043d6ec4759e9e24950123b70a377e5 (diff)
downloadmupdf-a638d6d24069943fbc950587db2e03f18cfea581.tar.xz
Add a deep-copy function for pdf objects
This is work towards supporting several levels of incremental xref, which in turn, is work towards bug #696123. When several levels of incremental xref are present there can be objects that appear at multiple levels and differ between those levels. This deep-copy function will be used to create new copies before the new version is altered.
Diffstat (limited to 'source/pdf/pdf-object.c')
-rw-r--r--source/pdf/pdf-object.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
index 1b77292f..65ad3127 100644
--- a/source/pdf/pdf-object.c
+++ b/source/pdf/pdf-object.c
@@ -1549,6 +1549,51 @@ pdf_sort_dict(fz_context *ctx, pdf_obj *obj)
}
}
+pdf_obj *
+pdf_deep_copy_obj(fz_context *ctx, pdf_obj *obj)
+{
+ if (obj < PDF_OBJ__LIMIT)
+ {
+ return pdf_keep_obj(ctx, obj);
+ }
+ if (obj->kind == PDF_DICT)
+ {
+ pdf_document *doc = DICT(obj)->doc;
+ int n = pdf_dict_len(ctx, obj);
+ pdf_obj *dict = pdf_new_dict(ctx, doc, n);
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ pdf_obj *obj_copy = pdf_deep_copy_obj(ctx, pdf_dict_get_val(ctx, obj, i));
+ pdf_dict_put(ctx, dict, pdf_dict_get_key(ctx, obj, i), obj_copy);
+ pdf_drop_obj(ctx, obj_copy);
+ }
+
+ return dict;
+ }
+ else if (obj->kind == PDF_ARRAY)
+ {
+ pdf_document *doc = ARRAY(obj)->doc;
+ int n = pdf_array_len(ctx, obj);
+ pdf_obj *arr = pdf_new_array(ctx, doc, n);
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ pdf_obj *obj_copy = pdf_deep_copy_obj(ctx, pdf_array_get(ctx, obj, i));
+ pdf_array_push(ctx, arr, obj_copy);
+ pdf_drop_obj(ctx, obj_copy);
+ }
+
+ return arr;
+ }
+ else
+ {
+ return pdf_keep_obj(ctx, obj);
+ }
+}
+
int
pdf_obj_marked(fz_context *ctx, pdf_obj *obj)
{