From f86e9738deb6c6887fb51f2d11e8294cfc1b51cb Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 29 Aug 2016 16:28:23 +0200 Subject: Simplify PDF resource caching table handling. --- source/fitz/buffer.c | 8 +++ source/pdf/pdf-device.c | 5 -- source/pdf/pdf-font.c | 8 +-- source/pdf/pdf-image.c | 4 +- source/pdf/pdf-resources.c | 164 ++++++++++++++------------------------------- 5 files changed, 64 insertions(+), 125 deletions(-) (limited to 'source') diff --git a/source/fitz/buffer.c b/source/fitz/buffer.c index ba3451bf..10c0c055 100644 --- a/source/fitz/buffer.c +++ b/source/fitz/buffer.c @@ -390,6 +390,14 @@ fz_buffer_print_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text) buffer->len += len; } +void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]) +{ + fz_md5 state; + fz_md5_init(&state); + fz_md5_update(&state, buffer->data, buffer->len); + fz_md5_final(&state, digest); +} + #ifdef TEST_BUFFER_WRITE #define TEST_LEN 1024 diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c index 2324dbd7..3b974efe 100644 --- a/source/pdf/pdf-device.c +++ b/source/pdf/pdf-device.c @@ -1127,11 +1127,6 @@ fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, const fz_matri if (topctm != &fz_identity) fz_buffer_printf(ctx, buf, "%M cm\n", topctm); - - /* Initialise the resource tables if we have not done so - * already. */ - if (doc->resources == NULL) - pdf_init_resource_tables(ctx, doc); } fz_catch(ctx) { diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c index cc6c68ed..a0bdc5f9 100644 --- a/source/pdf/pdf-font.c +++ b/source/pdf/pdf-font.c @@ -2002,7 +2002,7 @@ pdf_add_cid_font(fz_context *ctx, pdf_document *doc, fz_font *font) /* Before we add this font as a resource check if the same font * already exists in our resources for this doc. If yes, then * hand back that reference */ - fref = pdf_find_resource(ctx, doc, doc->resources->font, font->buffer, digest); + fref = pdf_find_font_resource(ctx, doc, font->buffer, digest); if (fref == NULL) { /* Set up desc, width, and font file */ @@ -2031,7 +2031,7 @@ pdf_add_cid_font(fz_context *ctx, pdf_document *doc, fz_font *font) fref = pdf_add_object(ctx, doc, fobj); /* Add ref to our font resource hash table. */ - fref = pdf_insert_resource(ctx, doc->resources->font, digest, fref); + fref = pdf_insert_font_resource(ctx, doc, digest, fref); } } fz_always(ctx) @@ -2077,7 +2077,7 @@ pdf_add_simple_font(fz_context *ctx, pdf_document *doc, fz_font *font) /* Before we add this font as a resource check if the same font * already exists in our resources for this doc. If yes, then * hand back that reference */ - fref = pdf_find_resource(ctx, doc, doc->resources->font, font->buffer, digest); + fref = pdf_find_font_resource(ctx, doc, font->buffer, digest); if (fref == NULL) { fobj = pdf_new_dict(ctx, doc, 10); @@ -2119,7 +2119,7 @@ pdf_add_simple_font(fz_context *ctx, pdf_document *doc, fz_font *font) fref = pdf_add_object(ctx, doc, fobj); /* Add ref to our font resource hash table. */ - fref = pdf_insert_resource(ctx, doc->resources->font, digest, fref); + fref = pdf_insert_font_resource(ctx, doc, digest, fref); } } fz_always(ctx) diff --git a/source/pdf/pdf-image.c b/source/pdf/pdf-image.c index 0b8bd6b1..c9c1fdda 100644 --- a/source/pdf/pdf-image.c +++ b/source/pdf/pdf-image.c @@ -310,7 +310,7 @@ pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image, int mask) /* Before we add this image as a resource check if the same image * already exists in our resources for this doc. If yes, then * hand back that reference */ - imref = pdf_find_resource(ctx, doc, doc->resources->image, image, digest); + imref = pdf_find_image_resource(ctx, doc, image, digest); if (imref == NULL) { if (cbuffer != NULL && cbuffer->params.type != FZ_IMAGE_PNG && cbuffer->params.type != FZ_IMAGE_TIFF) @@ -457,7 +457,7 @@ pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image, int mask) pdf_update_stream(ctx, doc, imref, buffer, 1); /* Add ref to our image resource hash table. */ - imref = pdf_insert_resource(ctx, doc->resources->image, digest, imref); + imref = pdf_insert_image_resource(ctx, doc, digest, imref); } } fz_always(ctx) diff --git a/source/pdf/pdf-resources.c b/source/pdf/pdf-resources.c index 9b539fa9..0772d3a4 100644 --- a/source/pdf/pdf-resources.c +++ b/source/pdf/pdf-resources.c @@ -1,29 +1,7 @@ #include "mupdf/pdf.h" static void -res_table_free(fz_context *ctx, pdf_res_table *table) -{ - int i, n; - pdf_obj *res; - - if (table == NULL) - return; - if (table->hash != NULL) - { - n = fz_hash_len(ctx, table->hash); - for (i = 0; i < n; i++) - { - res = fz_hash_get_val(ctx, table->hash, i); - if (res) - pdf_drop_obj(ctx, res); - } - fz_drop_hash(ctx, table->hash); - } - fz_free(ctx, table); -} - -static void -res_image_get_md5(fz_context *ctx, fz_image *image, unsigned char *digest) +fz_md5_image(fz_context *ctx, fz_image *image, unsigned char digest[16]) { fz_pixmap *pixmap; fz_md5 state; @@ -45,7 +23,7 @@ res_image_get_md5(fz_context *ctx, fz_image *image, unsigned char *digest) /* Image specific methods */ static void -res_image_init(fz_context *ctx, pdf_document *doc, pdf_res_table *table) +pdf_preload_image_resources(fz_context *ctx, pdf_document *doc) { int len, k; pdf_obj *obj; @@ -60,7 +38,6 @@ res_image_init(fz_context *ctx, pdf_document *doc, pdf_res_table *table) fz_try(ctx) { - table->hash = fz_new_hash_table(ctx, 4096, 16, -1); len = pdf_count_objects(ctx, doc); for (k = 1; k < len; k++) { @@ -69,18 +46,15 @@ res_image_init(fz_context *ctx, pdf_document *doc, pdf_res_table *table) if (pdf_name_eq(ctx, type, PDF_NAME_Image)) { image = pdf_load_image(ctx, doc, obj); - res_image_get_md5(ctx, image, digest); + fz_md5_image(ctx, image, digest); fz_drop_image(ctx, image); image = NULL; /* Don't allow overwrites. */ - if (fz_hash_find(ctx, table->hash, digest) == NULL) - fz_hash_insert(ctx, table->hash, digest, obj); - } - else - { - pdf_drop_obj(ctx, obj); + if (!fz_hash_find(ctx, doc->resources.images, digest)) + fz_hash_insert(ctx, doc->resources.images, digest, pdf_keep_obj(ctx, obj)); } + pdf_drop_obj(ctx, obj); obj = NULL; } } @@ -91,126 +65,88 @@ res_image_init(fz_context *ctx, pdf_document *doc, pdf_res_table *table) } fz_catch(ctx) { - res_table_free(ctx, table); fz_rethrow(ctx); } } -static pdf_obj * -res_image_search(fz_context *ctx, pdf_document *doc, pdf_res_table *table, void *item, unsigned char *digest) +pdf_obj * +pdf_find_image_resource(fz_context *ctx, pdf_document *doc, fz_image *item, unsigned char digest[16]) { - fz_image *image = item; - fz_hash_table *hash = table->hash; pdf_obj *res; - if (hash == NULL) - res_image_init(ctx, doc, doc->resources->image); - hash = doc->resources->image->hash; + if (!doc->resources.images) + { + doc->resources.images = fz_new_hash_table(ctx, 4096, 16, -1); + pdf_preload_image_resources(ctx, doc); + } /* Create md5 and see if we have the item in our table */ - res_image_get_md5(ctx, image, digest); - res = fz_hash_find(ctx, hash, digest); + fz_md5_image(ctx, item, digest); + res = fz_hash_find(ctx, doc->resources.images, digest); if (res) pdf_keep_obj(ctx, res); return res; } -/* Font specific methods */ - -/* We do need to come up with an effective way to see what is already in the - * file to avoid adding to what is already there. This is avoided for pdfwrite - * as we check as we add each font. For adding text to an existing file though - * it may be more problematic */ -static void -res_font_init(fz_context *ctx, pdf_document *doc, pdf_res_table *table) +pdf_obj * +pdf_insert_image_resource(fz_context *ctx, pdf_document *doc, unsigned char digest[15], pdf_obj *obj) { - table->hash = fz_new_hash_table(ctx, 4096, 16, -1); + pdf_obj *res = fz_hash_insert(ctx, doc->resources.images, digest, obj); + if (res) + fz_warn(ctx, "warning: image resource already present"); + else + res = pdf_keep_obj(ctx, obj); + return res; } -static void -res_font_get_md5(fz_context *ctx, fz_buffer *buffer, unsigned char *digest) -{ - fz_md5 state; - - fz_md5_init(&state); - fz_md5_update(&state, buffer->data, buffer->len); - fz_md5_final(&state, digest); -} +/* We do need to come up with an effective way to see what is already in the + * file to avoid adding to what is already there. This is avoided for pdfwrite + * as we check as we add each font. For adding text to an existing file though + * it may be more problematic. */ -static pdf_obj * -res_font_search(fz_context *ctx, pdf_document *doc, pdf_res_table *table, void *item, unsigned char digest[16]) +pdf_obj * +pdf_find_font_resource(fz_context *ctx, pdf_document *doc, fz_buffer *item, unsigned char digest[16]) { - fz_buffer *buffer = item; - fz_hash_table *hash = table->hash; pdf_obj *res; - if (hash == NULL) - res_font_init(ctx, doc, doc->resources->font); - hash = doc->resources->font->hash; + if (!doc->resources.fonts) + doc->resources.fonts = fz_new_hash_table(ctx, 4096, 16, -1); /* Create md5 and see if we have the item in our table */ - res_font_get_md5(ctx, buffer, digest); - res = fz_hash_find(ctx, hash, digest); + fz_md5_buffer(ctx, item, digest); + res = fz_hash_find(ctx, doc->resources.fonts, digest); if (res) pdf_keep_obj(ctx, res); return res; } -/* Accessible methods */ pdf_obj * -pdf_find_resource(fz_context *ctx, pdf_document *doc, pdf_res_table *table, void *item, unsigned char md5[16]) +pdf_insert_font_resource(fz_context *ctx, pdf_document *doc, unsigned char digest[15], pdf_obj *obj) { - return table->search(ctx, doc, table, item, md5); + pdf_obj *res = fz_hash_insert(ctx, doc->resources.fonts, digest, obj); + if (res) + fz_warn(ctx, "warning: font resource already present"); + else + res = pdf_keep_obj(ctx, obj); + return res; } -pdf_obj * -pdf_insert_resource(fz_context *ctx, pdf_res_table *table, void *key, pdf_obj *obj) +static void +res_table_free(fz_context *ctx, fz_hash_table *hash) { - pdf_obj *res; - - fz_try(ctx) - { - res = fz_hash_insert(ctx, table->hash, key, obj); - if (res != NULL) - fz_warn(ctx, "warning: resource already present"); - else - res = pdf_keep_obj(ctx, obj); - } - fz_catch(ctx) + int i, n; + if (hash) { - fz_rethrow(ctx); + n = fz_hash_len(ctx, hash); + for (i = 0; i < n; i++) + pdf_drop_obj(ctx, fz_hash_get_val(ctx, hash, i)); + fz_drop_hash(ctx, hash); } - return res; } void pdf_drop_resource_tables(fz_context *ctx, pdf_document *doc) { - if (doc->resources == NULL) - return; - res_table_free(ctx, doc->resources->color); - res_table_free(ctx, doc->resources->font); - res_table_free(ctx, doc->resources->image); - res_table_free(ctx, doc->resources->pattern); - res_table_free(ctx, doc->resources->shading); - fz_free(ctx, doc->resources); - doc->resources = NULL; -} - -void -pdf_init_resource_tables(fz_context *ctx, pdf_document *doc) -{ - fz_try(ctx) - { - doc->resources = fz_malloc_struct(ctx, pdf_resource_tables); - doc->resources->image = fz_malloc_struct(ctx, pdf_res_table); - doc->resources->image->search = res_image_search; - doc->resources->font = fz_malloc_struct(ctx, pdf_res_table); - doc->resources->font->search = res_font_search; - } - fz_catch(ctx) - { - pdf_drop_resource_tables(ctx, doc); - fz_rethrow(ctx); - } + res_table_free(ctx, doc->resources.fonts); + res_table_free(ctx, doc->resources.images); } -- cgit v1.2.3