summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-08-29 16:28:23 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-09-01 15:39:56 +0200
commitf86e9738deb6c6887fb51f2d11e8294cfc1b51cb (patch)
tree90604c5c291f3ff3334720fd1faefcdfd3906858
parent1000326aaaeab4ae17a8f93ef6d28e287fb120cc (diff)
downloadmupdf-f86e9738deb6c6887fb51f2d11e8294cfc1b51cb.tar.xz
Simplify PDF resource caching table handling.
-rw-r--r--include/mupdf/fitz/buffer.h5
-rw-r--r--include/mupdf/pdf/document.h6
-rw-r--r--include/mupdf/pdf/resource.h26
-rw-r--r--scripts/cmapdump.c1
-rw-r--r--source/fitz/buffer.c8
-rw-r--r--source/pdf/pdf-device.c5
-rw-r--r--source/pdf/pdf-font.c8
-rw-r--r--source/pdf/pdf-image.c4
-rw-r--r--source/pdf/pdf-resources.c164
9 files changed, 78 insertions, 149 deletions
diff --git a/include/mupdf/fitz/buffer.h b/include/mupdf/fitz/buffer.h
index a616fa86..40e46e73 100644
--- a/include/mupdf/fitz/buffer.h
+++ b/include/mupdf/fitz/buffer.h
@@ -138,4 +138,9 @@ size_t fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...
size_t fz_buffer_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
void fz_buffer_print_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text);
+/*
+ fz_md5_buffer: create MD5 digest of buffer contents.
+*/
+void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]);
+
#endif
diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h
index 8a8fdd40..aabf05f9 100644
--- a/include/mupdf/pdf/document.h
+++ b/include/mupdf/pdf/document.h
@@ -12,7 +12,6 @@ typedef struct pdf_annot_s pdf_annot;
typedef struct pdf_widget_s pdf_widget;
typedef struct pdf_hotspot_s pdf_hotspot;
typedef struct pdf_js_s pdf_js;
-typedef struct pdf_resource_tables_s pdf_resource_tables;
enum
{
@@ -266,7 +265,10 @@ struct pdf_document_s
int max_type3_fonts;
fz_font **type3_fonts;
- pdf_resource_tables *resources;
+ struct {
+ fz_hash_table *images;
+ fz_hash_table *fonts;
+ } resources;
};
/*
diff --git a/include/mupdf/pdf/resource.h b/include/mupdf/pdf/resource.h
index e0290247..f9f99da6 100644
--- a/include/mupdf/pdf/resource.h
+++ b/include/mupdf/pdf/resource.h
@@ -16,29 +16,11 @@ void pdf_remove_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key);
* the data, enabling rapid lookup.
*/
-typedef struct pdf_res_table_s pdf_res_table;
-typedef pdf_obj *(pdf_res_search_fn)(fz_context *ctx, pdf_document *doc, pdf_res_table *list,
- void *item, unsigned char md5[16]);
-
-struct pdf_res_table_s
-{
- fz_hash_table *hash;
- pdf_res_search_fn *search;
-};
-
-struct pdf_resource_tables_s
-{
- pdf_res_table *image;
- pdf_res_table *font;
- pdf_res_table *color;
- pdf_res_table *pattern;
- pdf_res_table *shading;
-};
-
-pdf_obj *pdf_find_resource(fz_context *ctx, pdf_document *doc, pdf_res_table *table, void *item, unsigned char md5[16]);
-void pdf_init_resource_tables(fz_context *ctx, pdf_document *doc);
+pdf_obj *pdf_find_font_resource(fz_context *ctx, pdf_document *doc, fz_buffer *item, unsigned char md5[16]);
+pdf_obj *pdf_insert_font_resource(fz_context *ctx, pdf_document *doc, unsigned char md5[16], pdf_obj *obj);
+pdf_obj *pdf_find_image_resource(fz_context *ctx, pdf_document *doc, fz_image *item, unsigned char md5[16]);
+pdf_obj *pdf_insert_image_resource(fz_context *ctx, pdf_document *doc, unsigned char md5[16], pdf_obj *obj);
void pdf_drop_resource_tables(fz_context *ctx, pdf_document *doc);
-pdf_obj *pdf_insert_resource(fz_context *ctx, pdf_res_table *table, void *key, pdf_obj *obj);
/*
* Functions, Colorspaces, Shadings and Images
diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c
index 2f3493d7..4da2e329 100644
--- a/scripts/cmapdump.c
+++ b/scripts/cmapdump.c
@@ -17,6 +17,7 @@
#include "../source/fitz/output.c"
#include "../source/fitz/string.c"
#include "../source/fitz/buffer.c"
+#include "../source/fitz/crypt-md5.c"
#include "../source/fitz/stream-open.c"
#include "../source/fitz/stream-read.c"
#include "../source/fitz/strtod.c"
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);
}