From a638d6d24069943fbc950587db2e03f18cfea581 Mon Sep 17 00:00:00 2001 From: Paul Gardiner Date: Thu, 27 Aug 2015 14:07:23 +0100 Subject: 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. --- include/mupdf/pdf/object.h | 1 + source/pdf/pdf-object.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h index fa976be5..84dbc4fe 100644 --- a/include/mupdf/pdf/object.h +++ b/include/mupdf/pdf/object.h @@ -25,6 +25,7 @@ pdf_obj *pdf_new_rect(fz_context *ctx, pdf_document *doc, const fz_rect *rect); pdf_obj *pdf_new_matrix(fz_context *ctx, pdf_document *doc, const fz_matrix *mtx); pdf_obj *pdf_copy_array(fz_context *ctx, pdf_obj *array); pdf_obj *pdf_copy_dict(fz_context *ctx, pdf_obj *dict); +pdf_obj *pdf_deep_copy_obj(fz_context *ctx, pdf_obj *obj); pdf_obj *pdf_new_obj_from_str(fz_context *ctx, pdf_document *doc, const char *src); 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) { -- cgit v1.2.3