From 10d6eaa73164b58c91ae8a4537b8a8589038a01d Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 8 Jul 2016 12:04:35 +0200 Subject: Separate close and drop functionality for devices and writers. Closing a device or writer may throw exceptions, but much of the foreign language bindings (JNI and JS) depend on drop to never throw an exception (exceptions in finalizers are bad). --- docs/multi-threaded.c | 2 ++ include/mupdf/fitz/device.h | 9 ++++---- include/mupdf/fitz/document.h | 12 +++++------ include/mupdf/fitz/unzip.h | 1 + include/mupdf/fitz/writer.h | 3 ++- include/mupdf/pdf/interpret.h | 4 +++- include/mupdf/xps.h | 4 ++-- platform/java/mupdf_native.c | 4 ++-- source/cbz/mucbz.c | 12 +++++------ source/cbz/muimg.c | 8 ++++---- source/cbz/mutiff.c | 10 ++++----- source/fitz/bbox-device.c | 4 ++-- source/fitz/device.c | 12 ++++++----- source/fitz/document.c | 12 +++++------ source/fitz/draw-device.c | 4 ++-- source/fitz/font.c | 3 +++ source/fitz/image.c | 1 + source/fitz/list-device.c | 4 ++-- source/fitz/output-cbz.c | 23 +++++++++++++-------- source/fitz/output-png.c | 7 +++++-- source/fitz/stext-device.c | 16 +++++++++++---- source/fitz/svg-device.c | 13 ++++++++---- source/fitz/util.c | 9 ++++++++ source/fitz/writer.c | 12 ++++++----- source/fitz/zip.c | 48 ++++++++++++++++++++++--------------------- source/html/epub-doc.c | 10 ++++----- source/html/html-doc.c | 10 ++++----- source/pdf/pdf-annot.c | 2 +- source/pdf/pdf-appearance.c | 16 +++++++++++---- source/pdf/pdf-device.c | 14 +++++++++---- source/pdf/pdf-interpret.c | 19 +++++++++++++++-- source/pdf/pdf-op-buffer.c | 4 ++-- source/pdf/pdf-op-filter.c | 4 ++-- source/pdf/pdf-op-run.c | 4 ++-- source/pdf/pdf-page.c | 2 +- source/pdf/pdf-write.c | 27 ++++++++++++------------ source/pdf/pdf-xref.c | 8 ++++---- source/svg/svg-doc.c | 8 ++++---- source/tools/muconvert.c | 2 ++ source/tools/mudraw.c | 11 ++++++---- source/tools/muraster.c | 9 ++++---- source/tools/murun.c | 18 +++++++++++----- source/xps/xps-doc.c | 4 ++-- source/xps/xps-zip.c | 8 ++++---- 44 files changed, 254 insertions(+), 163 deletions(-) diff --git a/docs/multi-threaded.c b/docs/multi-threaded.c index 6f07b543..15fdcba2 100644 --- a/docs/multi-threaded.c +++ b/docs/multi-threaded.c @@ -96,6 +96,7 @@ renderer(void *data) fprintf(stderr, "thread at page %d rendering!\n", pagenumber); dev = fz_new_draw_device(ctx, &fz_identity, pix); fz_run_display_list(ctx, list, dev, &fz_identity, &bbox, NULL); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); // This threads context is freed. @@ -212,6 +213,7 @@ int main(int argc, char **argv) dev = fz_new_list_device(ctx, list); fz_run_page(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); // The page is no longer needed, all drawing commands diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h index 172081fe..57e61ad0 100644 --- a/include/mupdf/fitz/device.h +++ b/include/mupdf/fitz/device.h @@ -102,7 +102,8 @@ struct fz_device_s int hints; int flags; - void (*close)(fz_context *, fz_device *); + void (*close_device)(fz_context *, fz_device *); + void (*drop_device)(fz_context *, fz_device *); void (*fill_path)(fz_context *, fz_device *, const fz_path *, int even_odd, const fz_matrix *, fz_colorspace *, const float *color, float alpha); void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, const fz_matrix *, fz_colorspace *, const float *color, float alpha); @@ -168,14 +169,14 @@ void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear); void *fz_new_device(fz_context *ctx, int size); /* - fz_close_device: Flush any pending output and free internal memory. - This is called implicitly on fz_drop_device, so it's only useful for - garbage collected language bindings. + fz_close_device: Signal the end of input, and flush any buffered output. + This is NOT called implicitly on fz_drop_device. */ void fz_close_device(fz_context *ctx, fz_device *dev); /* fz_drop_device: Free a devices of any type and its resources. + Don't forget to call fz_close_device before dropping the device, or you may get incomplete output! */ void fz_drop_device(fz_context *ctx, fz_device *dev); diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h index 889b66b1..f1a4a74f 100644 --- a/include/mupdf/fitz/document.h +++ b/include/mupdf/fitz/document.h @@ -26,7 +26,7 @@ typedef enum } fz_permission; -typedef void (fz_document_close_fn)(fz_context *ctx, fz_document *doc); +typedef void (fz_document_drop_fn)(fz_context *ctx, fz_document *doc); typedef int (fz_document_needs_password_fn)(fz_context *ctx, fz_document *doc); typedef int (fz_document_authenticate_password_fn)(fz_context *ctx, fz_document *doc, const char *password); typedef int (fz_document_has_permission_fn)(fz_context *ctx, fz_document *doc, fz_permission permission); @@ -39,7 +39,7 @@ typedef int (fz_document_lookup_metadata_fn)(fz_context *ctx, fz_document *doc, typedef fz_link *(fz_page_load_links_fn)(fz_context *ctx, fz_page *page); typedef fz_rect *(fz_page_bound_page_fn)(fz_context *ctx, fz_page *page, fz_rect *); typedef void (fz_page_run_page_contents_fn)(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie); -typedef void (fz_page_drop_page_imp_fn)(fz_context *ctx, fz_page *page); +typedef void (fz_page_drop_page_fn)(fz_context *ctx, fz_page *page); typedef fz_transition *(fz_page_page_presentation_fn)(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration); typedef fz_annot *(fz_page_first_annot_fn)(fz_context *ctx, fz_page *page); @@ -49,7 +49,7 @@ typedef int (fz_page_separation_disabled_fn)(fz_context *ctx, fz_page *page, int typedef int (fz_page_count_separations_fn)(fz_context *ctx, fz_page *page); typedef const char *(fz_page_get_separation_fn)(fz_context *ctx, fz_page *page, int separation, uint32_t *rgb, uint32_t *cmyk); -typedef void (fz_annot_drop_imp_fn)(fz_context *ctx, fz_annot *annot); +typedef void (fz_annot_drop_fn)(fz_context *ctx, fz_annot *annot); typedef fz_annot *(fz_annot_next_fn)(fz_context *ctx, fz_annot *annot); typedef fz_rect *(fz_annot_bound_fn)(fz_context *ctx, fz_annot *annot, fz_rect *rect); typedef void (fz_annot_run_fn)(fz_context *ctx, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie); @@ -57,7 +57,7 @@ typedef void (fz_annot_run_fn)(fz_context *ctx, fz_annot *annot, fz_device *dev, struct fz_annot_s { int refs; - fz_annot_drop_imp_fn *drop_annot_imp; + fz_annot_drop_fn *drop_annot; fz_annot_bound_fn *bound_annot; fz_annot_run_fn *run_annot; fz_annot_next_fn *next_annot; @@ -66,7 +66,7 @@ struct fz_annot_s struct fz_page_s { int refs; - fz_page_drop_page_imp_fn *drop_page_imp; + fz_page_drop_page_fn *drop_page; fz_page_bound_page_fn *bound_page; fz_page_run_page_contents_fn *run_page_contents; fz_page_load_links_fn *load_links; @@ -81,7 +81,7 @@ struct fz_page_s struct fz_document_s { int refs; - fz_document_close_fn *close; + fz_document_drop_fn *drop_document; fz_document_needs_password_fn *needs_password; fz_document_authenticate_password_fn *authenticate_password; fz_document_has_permission_fn *has_permission; diff --git a/include/mupdf/fitz/unzip.h b/include/mupdf/fitz/unzip.h index 64b2b94b..c6295b90 100644 --- a/include/mupdf/fitz/unzip.h +++ b/include/mupdf/fitz/unzip.h @@ -23,6 +23,7 @@ typedef struct fz_zip_writer_s fz_zip_writer; fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename); void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress); +void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip); void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip); #endif diff --git a/include/mupdf/fitz/writer.h b/include/mupdf/fitz/writer.h index 6f0f47be..069cc7a5 100644 --- a/include/mupdf/fitz/writer.h +++ b/include/mupdf/fitz/writer.h @@ -13,7 +13,8 @@ struct fz_document_writer_s { fz_device *(*begin_page)(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox); void (*end_page)(fz_context *ctx, fz_document_writer *wri, fz_device *dev); - void (*close)(fz_context *ctx, fz_document_writer *wri); + void (*close_writer)(fz_context *ctx, fz_document_writer *wri); + void (*drop_writer)(fz_context *ctx, fz_document_writer *wri); }; int fz_has_option(fz_context *ctx, const char *opts, const char *key, const char **val); diff --git a/include/mupdf/pdf/interpret.h b/include/mupdf/pdf/interpret.h index da89e573..07460221 100644 --- a/include/mupdf/pdf/interpret.h +++ b/include/mupdf/pdf/interpret.h @@ -6,11 +6,13 @@ typedef struct pdf_gstate_s pdf_gstate; typedef struct pdf_processor_s pdf_processor; void *pdf_new_processor(fz_context *ctx, int size); +void pdf_close_processor(fz_context *ctx, pdf_processor *proc); void pdf_drop_processor(fz_context *ctx, pdf_processor *proc); struct pdf_processor_s { - void (*drop_imp)(fz_context *ctx, pdf_processor *proc); + void (*close_processor)(fz_context *ctx, pdf_processor *proc); + void (*drop_processor)(fz_context *ctx, pdf_processor *proc); /* general graphics state */ void (*op_w)(fz_context *ctx, pdf_processor *proc, float linewidth); diff --git a/include/mupdf/xps.h b/include/mupdf/xps.h index 1091faa6..e0f49b3d 100644 --- a/include/mupdf/xps.h +++ b/include/mupdf/xps.h @@ -33,14 +33,14 @@ xps_document *xps_open_document(fz_context *ctx, const char *filename); xps_document *xps_open_document_with_stream(fz_context *ctx, fz_stream *file); /* - xps_close_document: Closes and frees an opened document. + xps_drop_document: Closes and frees an opened document. The resource store in the context associated with xps_document is emptied. Does not throw exceptions. */ -void xps_close_document(fz_context *ctx, xps_document *doc); +void xps_drop_document(fz_context *ctx, xps_document *doc); int xps_count_pages(fz_context *ctx, xps_document *doc); xps_page *xps_load_page(fz_context *ctx, xps_document *doc, int number); diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c index 5cef1e70..2a52e028 100644 --- a/platform/java/mupdf_native.c +++ b/platform/java/mupdf_native.c @@ -1284,7 +1284,7 @@ fz_java_device_end_tile(fz_context *ctx, fz_device *dev) } static void -fz_java_device_close(fz_context *ctx, fz_device *dev) +fz_java_device_drop(fz_context *ctx, fz_device *dev) { fz_java_device *jdev = (fz_java_device *)dev; JNIEnv *env = jdev->env; @@ -1303,7 +1303,7 @@ static fz_device *fz_new_java_device(fz_context *ctx, JNIEnv *env, jobject self) dev->self = (*env)->NewGlobalRef(env, self); - dev->super.close = fz_java_device_close; + dev->super.drop_device = fz_java_device_drop; dev->super.fill_path = fz_java_device_fill_path; dev->super.stroke_path = fz_java_device_stroke_path; diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c index 5a83adc0..0b5de93e 100644 --- a/source/cbz/mucbz.c +++ b/source/cbz/mucbz.c @@ -101,7 +101,7 @@ cbz_create_page_list(fz_context *ctx, cbz_document *doc) } static void -cbz_close_document(fz_context *ctx, cbz_document *doc) +cbz_drop_document(fz_context *ctx, cbz_document *doc) { fz_drop_archive(ctx, doc->zip); fz_free(ctx, (char **)doc->page); @@ -143,7 +143,7 @@ cbz_run_page(fz_context *ctx, cbz_page *page, fz_device *dev, const fz_matrix *c } static void -cbz_drop_page_imp(fz_context *ctx, cbz_page *page) +cbz_drop_page(fz_context *ctx, cbz_page *page) { if (!page) return; @@ -169,7 +169,7 @@ cbz_load_page(fz_context *ctx, cbz_document *doc, int number) page = fz_new_page(ctx, sizeof *page); page->super.bound_page = (fz_page_bound_page_fn *)cbz_bound_page; page->super.run_page_contents = (fz_page_run_page_contents_fn *)cbz_run_page; - page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)cbz_drop_page_imp; + page->super.drop_page = (fz_page_drop_page_fn *)cbz_drop_page; page->image = fz_new_image_from_buffer(ctx, buf); } fz_always(ctx) @@ -179,7 +179,7 @@ cbz_load_page(fz_context *ctx, cbz_document *doc, int number) fz_catch(ctx) { fz_free(ctx, data); - cbz_drop_page_imp(ctx, page); + cbz_drop_page(ctx, page); fz_rethrow(ctx); } @@ -199,7 +199,7 @@ cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) { cbz_document *doc = fz_new_document(ctx, cbz_document); - doc->super.close = (fz_document_close_fn *)cbz_close_document; + doc->super.drop_document = (fz_document_drop_fn *)cbz_drop_document; doc->super.count_pages = (fz_document_count_pages_fn *)cbz_count_pages; doc->super.load_page = (fz_document_load_page_fn *)cbz_load_page; doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)cbz_lookup_metadata; @@ -211,7 +211,7 @@ cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) } fz_catch(ctx) { - cbz_close_document(ctx, doc); + cbz_drop_document(ctx, doc); fz_rethrow(ctx); } return doc; diff --git a/source/cbz/muimg.c b/source/cbz/muimg.c index de99679f..5292c365 100644 --- a/source/cbz/muimg.c +++ b/source/cbz/muimg.c @@ -18,7 +18,7 @@ struct img_document_s }; static void -img_close_document(fz_context *ctx, img_document *doc) +img_drop_document(fz_context *ctx, img_document *doc) { fz_drop_image(ctx, doc->image); fz_free(ctx, doc); @@ -57,7 +57,7 @@ img_run_page(fz_context *ctx, img_page *page, fz_device *dev, const fz_matrix *c } static void -img_drop_page_imp(fz_context *ctx, img_page *page) +img_drop_page(fz_context *ctx, img_page *page) { fz_drop_image(ctx, page->image); } @@ -74,7 +74,7 @@ img_load_page(fz_context *ctx, img_document *doc, int number) page->super.bound_page = (fz_page_bound_page_fn *)img_bound_page; page->super.run_page_contents = (fz_page_run_page_contents_fn *)img_run_page; - page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)img_drop_page_imp; + page->super.drop_page = (fz_page_drop_page_fn *)img_drop_page; page->image = fz_keep_image(ctx, doc->image); @@ -94,7 +94,7 @@ img_new_document(fz_context *ctx, fz_image *image) { img_document *doc = fz_new_document(ctx, img_document); - doc->super.close = (fz_document_close_fn *)img_close_document; + doc->super.drop_document = (fz_document_drop_fn *)img_drop_document; doc->super.count_pages = (fz_document_count_pages_fn *)img_count_pages; doc->super.load_page = (fz_document_load_page_fn *)img_load_page; doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)img_lookup_metadata; diff --git a/source/cbz/mutiff.c b/source/cbz/mutiff.c index ad859987..64da4c5a 100644 --- a/source/cbz/mutiff.c +++ b/source/cbz/mutiff.c @@ -47,7 +47,7 @@ tiff_run_page(fz_context *ctx, tiff_page *page, fz_device *dev, const fz_matrix } static void -tiff_drop_page_imp(fz_context *ctx, tiff_page *page) +tiff_drop_page(fz_context *ctx, tiff_page *page) { if (!page) return; @@ -76,7 +76,7 @@ tiff_load_page(fz_context *ctx, tiff_document *doc, int number) page = fz_new_page(ctx, sizeof *page); page->super.bound_page = (fz_page_bound_page_fn *)tiff_bound_page; page->super.run_page_contents = (fz_page_run_page_contents_fn *)tiff_run_page; - page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)tiff_drop_page_imp; + page->super.drop_page = (fz_page_drop_page_fn *)tiff_drop_page; page->image = fz_keep_image(ctx, image); } fz_always(ctx) @@ -108,7 +108,7 @@ tiff_lookup_metadata(fz_context *ctx, tiff_document *doc, const char *key, char } static void -tiff_close_document(fz_context *ctx, tiff_document *doc) +tiff_drop_document(fz_context *ctx, tiff_document *doc) { fz_drop_buffer(ctx, doc->buffer); fz_free(ctx, doc); @@ -121,7 +121,7 @@ tiff_open_document_with_stream(fz_context *ctx, fz_stream *file) doc = fz_new_document(ctx, tiff_document); - doc->super.close = (fz_document_close_fn *)tiff_close_document; + doc->super.drop_document = (fz_document_drop_fn *)tiff_drop_document; doc->super.count_pages = (fz_document_count_pages_fn *)tiff_count_pages; doc->super.load_page = (fz_document_load_page_fn *)tiff_load_page; doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)tiff_lookup_metadata; @@ -133,7 +133,7 @@ tiff_open_document_with_stream(fz_context *ctx, fz_stream *file) } fz_catch(ctx) { - tiff_close_document(ctx, doc); + tiff_drop_document(ctx, doc); fz_rethrow(ctx); } diff --git a/source/fitz/bbox-device.c b/source/fitz/bbox-device.c index 42ca57ad..340eef3c 100644 --- a/source/fitz/bbox-device.c +++ b/source/fitz/bbox-device.c @@ -179,7 +179,7 @@ fz_bbox_end_tile(fz_context *ctx, fz_device *dev) } static void -fz_bbox_close(fz_context *ctx, fz_device *dev) +fz_bbox_drop_device(fz_context *ctx, fz_device *dev) { fz_bbox_device *bdev = (fz_bbox_device*)dev; if (bdev->top > 0) @@ -191,7 +191,7 @@ fz_new_bbox_device(fz_context *ctx, fz_rect *result) { fz_bbox_device *dev = fz_new_device(ctx, sizeof *dev); - dev->super.close = fz_bbox_close; + dev->super.drop_device = fz_bbox_drop_device; dev->super.fill_path = fz_bbox_fill_path; dev->super.stroke_path = fz_bbox_stroke_path; diff --git a/source/fitz/device.c b/source/fitz/device.c index 4379bb21..88b658a3 100644 --- a/source/fitz/device.c +++ b/source/fitz/device.c @@ -13,11 +13,11 @@ fz_close_device(fz_context *ctx, fz_device *dev) { if (dev == NULL) return; - if (dev->close) - dev->close(ctx, dev); + if (dev->close_device) + dev->close_device(ctx, dev); /* Don't call more than once! */ - dev->close = NULL; + dev->close_device = NULL; /* And disable all further device calls. */ dev->fill_path = NULL; @@ -53,8 +53,10 @@ fz_drop_device(fz_context *ctx, fz_device *dev) { if (fz_drop_imp(ctx, dev, &dev->refs)) { - if (dev->close) - dev->close(ctx, dev); + if (dev->close_device) + fz_warn(ctx, "dropping unclosed device"); + if (dev->drop_device) + dev->drop_device(ctx, dev); fz_free(ctx, dev->container); fz_free(ctx, dev); } diff --git a/source/fitz/document.c b/source/fitz/document.c index 02c30459..ad602bc2 100644 --- a/source/fitz/document.c +++ b/source/fitz/document.c @@ -150,8 +150,8 @@ fz_keep_document(fz_context *ctx, fz_document *doc) void fz_drop_document(fz_context *ctx, fz_document *doc) { - if (doc && --doc->refs == 0 && doc->close) - doc->close(ctx, doc); + if (doc && --doc->refs == 0 && doc->drop_document) + doc->drop_document(ctx, doc); } static void @@ -362,8 +362,8 @@ fz_drop_annot(fz_context *ctx, fz_annot *annot) { if (annot && --annot->refs == 0) { - if (annot->drop_annot_imp) - annot->drop_annot_imp(ctx, annot); + if (annot->drop_annot) + annot->drop_annot(ctx, annot); fz_free(ctx, annot); } } @@ -389,9 +389,9 @@ fz_drop_page(fz_context *ctx, fz_page *page) { if (page) { - if (--page->refs == 0 && page->drop_page_imp) + if (--page->refs == 0 && page->drop_page) { - page->drop_page_imp(ctx, page); + page->drop_page(ctx, page); fz_free(ctx, page); } } diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 9a2cb507..ff746e29 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -2357,7 +2357,7 @@ fz_draw_end_tile(fz_context *ctx, fz_device *devp) } static void -fz_draw_close(fz_context *ctx, fz_device *devp) +fz_draw_drop_device(fz_context *ctx, fz_device *devp) { fz_draw_device *dev = (fz_draw_device*)devp; fz_gel *gel = dev->gel; @@ -2400,7 +2400,7 @@ fz_new_draw_device(fz_context *ctx, const fz_matrix *transform, fz_pixmap *dest) { fz_draw_device *dev = fz_new_device(ctx, sizeof *dev); - dev->super.close = fz_draw_close; + dev->super.drop_device = fz_draw_drop_device; dev->super.fill_path = fz_draw_fill_path; dev->super.stroke_path = fz_draw_stroke_path; diff --git a/source/fitz/font.c b/source/fitz/font.c index b0248bd7..79cd050a 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -1169,6 +1169,7 @@ fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nested_depth) font->bbox_table[gid] = dev->d1_rect; fz_transform_rect(&font->bbox_table[gid], &font->t3matrix); } + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); } @@ -1191,6 +1192,7 @@ fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_rect *bounds) fz_try(ctx) { fz_run_display_list(ctx, list, dev, &font->t3matrix, &fz_infinite_rect, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -1270,6 +1272,7 @@ fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matr fz_try(ctx) { fz_run_t3_glyph(ctx, font, gid, trm, dev); + fz_close_device(ctx, dev); } fz_always(ctx) { diff --git a/source/fitz/image.c b/source/fitz/image.c index 064b03c7..330b65cf 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -1085,6 +1085,7 @@ display_list_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subar fz_clear_pixmap(ctx, pix); /* clear to transparent */ dev = fz_new_draw_device(ctx, &ctm, pix); fz_run_display_list(ctx, image->list, dev, &fz_identity, NULL, NULL); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); /* Never do more subsampling, cos we've already given them the right size */ diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c index 18af0e20..d5e13375 100644 --- a/source/fitz/list-device.c +++ b/source/fitz/list-device.c @@ -1199,7 +1199,7 @@ fz_list_render_flags(fz_context *ctx, fz_device *dev, int set, int clear) } static void -drop_writer(fz_context *ctx, fz_device *dev) +fz_list_drop_device(fz_context *ctx, fz_device *dev) { fz_list_device *writer = (fz_list_device *)dev; @@ -1243,7 +1243,7 @@ fz_new_list_device(fz_context *ctx, fz_display_list *list) dev->super.render_flags = fz_list_render_flags; - dev->super.close = drop_writer; + dev->super.drop_device = fz_list_drop_device; dev->list = list; dev->path = NULL; diff --git a/source/fitz/output-cbz.c b/source/fitz/output-cbz.c index 80ef287c..43be16cb 100644 --- a/source/fitz/output-cbz.c +++ b/source/fitz/output-cbz.c @@ -29,6 +29,9 @@ cbz_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) fz_buffer *buffer; char name[40]; + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + wri->count += 1; fz_snprintf(name, sizeof name, "p%04d.png", wri->count); @@ -43,20 +46,21 @@ cbz_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) fz_drop_pixmap(ctx, wri->pixmap); wri->pixmap = NULL; +} - fz_drop_device(ctx, dev); +static void +cbz_close_writer(fz_context *ctx, fz_document_writer *wri_) +{ + fz_cbz_writer *wri = (fz_cbz_writer*)wri_; + fz_close_zip_writer(ctx, wri->zip); } static void -cbz_close(fz_context *ctx, fz_document_writer *wri_) +cbz_drop_writer(fz_context *ctx, fz_document_writer *wri_) { fz_cbz_writer *wri = (fz_cbz_writer*)wri_; - fz_try(ctx) - fz_drop_zip_writer(ctx, wri->zip); - fz_always(ctx) - fz_drop_pixmap(ctx, wri->pixmap); - fz_catch(ctx) - fz_rethrow(ctx); + fz_drop_zip_writer(ctx, wri->zip); + fz_drop_pixmap(ctx, wri->pixmap); } fz_document_writer * @@ -67,7 +71,8 @@ fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options) wri = fz_malloc_struct(ctx, fz_cbz_writer); wri->super.begin_page = cbz_begin_page; wri->super.end_page = cbz_end_page; - wri->super.close = cbz_close; + wri->super.close_writer = cbz_close_writer; + wri->super.drop_writer = cbz_drop_writer; fz_try(ctx) { diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c index 5bd0737e..d710a0cd 100644 --- a/source/fitz/output-png.c +++ b/source/fitz/output-png.c @@ -324,6 +324,9 @@ png_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) fz_png_writer *wri = (fz_png_writer*)wri_; char path[PATH_MAX]; + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + wri->count += 1; fz_format_output_path(ctx, path, sizeof path, wri->path, wri->count); @@ -333,7 +336,7 @@ png_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) } static void -png_close(fz_context *ctx, fz_document_writer *wri_) +png_drop_writer(fz_context *ctx, fz_document_writer *wri_) { fz_png_writer *wri = (fz_png_writer*)wri_; fz_drop_pixmap(ctx, wri->pixmap); @@ -348,7 +351,7 @@ fz_new_png_writer(fz_context *ctx, const char *path, const char *options) wri = fz_malloc_struct(ctx, fz_png_writer); wri->super.begin_page = png_begin_page; wri->super.end_page = png_end_page; - wri->super.close = png_close; + wri->super.drop_writer = png_drop_writer; fz_try(ctx) { diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c index f50bbf82..55f2033b 100644 --- a/source/fitz/stext-device.c +++ b/source/fitz/stext-device.c @@ -1015,7 +1015,7 @@ fz_bidi_reorder_stext_page(fz_context *ctx, fz_stext_page *page) } static void -fz_stext_close(fz_context *ctx, fz_device *dev) +fz_stext_close_device(fz_context *ctx, fz_device *dev) { fz_stext_device *tdev = (fz_stext_device*)dev; @@ -1023,8 +1023,6 @@ fz_stext_close(fz_context *ctx, fz_device *dev) tdev->cur_span = NULL; strain_soup(ctx, tdev); - free_span_soup(ctx, tdev->spans); - tdev->spans = NULL; /* TODO: smart sorting of blocks in reading order */ /* TODO: unicode NFC normalization */ @@ -1032,6 +1030,14 @@ fz_stext_close(fz_context *ctx, fz_device *dev) fz_bidi_reorder_stext_page(ctx, tdev->page); } +static void +fz_stext_drop_device(fz_context *ctx, fz_device *dev) +{ + fz_stext_device *tdev = (fz_stext_device*)dev; + free_span_soup(ctx, tdev->spans); + tdev->spans = NULL; +} + fz_device * fz_new_stext_device(fz_context *ctx, fz_stext_sheet *sheet, fz_stext_page *page) { @@ -1039,7 +1045,9 @@ fz_new_stext_device(fz_context *ctx, fz_stext_sheet *sheet, fz_stext_page *page) dev->super.hints = FZ_IGNORE_IMAGE | FZ_IGNORE_SHADE; - dev->super.close = fz_stext_close; + dev->super.close_device = fz_stext_close_device; + dev->super.drop_device = fz_stext_drop_device; + dev->super.fill_text = fz_stext_fill_text; dev->super.stroke_text = fz_stext_stroke_text; dev->super.clip_text = fz_stext_clip_text; diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c index 1a486545..8a7f4bf9 100644 --- a/source/fitz/svg-device.c +++ b/source/fitz/svg-device.c @@ -1063,23 +1063,28 @@ svg_dev_end_tile(fz_context *ctx, fz_device *dev) } static void -svg_dev_close(fz_context *ctx, fz_device *dev) +svg_dev_close_device(fz_context *ctx, fz_device *dev) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; + fz_printf(ctx, out, "\n"); +} +static void +svg_dev_drop_device(fz_context *ctx, fz_device *dev) +{ + svg_device *sdev = (svg_device*)dev; fz_free(ctx, sdev->tiles); fz_drop_buffer(ctx, sdev->defs_buffer); fz_drop_output(ctx, sdev->defs); - - fz_printf(ctx, out, "\n"); } fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height) { svg_device *dev = fz_new_device(ctx, sizeof *dev); - dev->super.close = svg_dev_close; + dev->super.close_device = svg_dev_close_device; + dev->super.drop_device = svg_dev_drop_device; dev->super.fill_path = svg_dev_fill_path; dev->super.stroke_path = svg_dev_stroke_path; diff --git a/source/fitz/util.c b/source/fitz/util.c index f76e496a..cefac962 100644 --- a/source/fitz/util.c +++ b/source/fitz/util.c @@ -13,6 +13,7 @@ fz_new_display_list_from_page(fz_context *ctx, fz_page *page) { dev = fz_new_list_device(ctx, list); fz_run_page(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -56,6 +57,7 @@ fz_new_display_list_from_page_contents(fz_context *ctx, fz_page *page) { dev = fz_new_list_device(ctx, list); fz_run_page_contents(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -83,6 +85,7 @@ fz_new_display_list_from_annot(fz_context *ctx, fz_annot *annot) { dev = fz_new_list_device(ctx, list); fz_run_annot(ctx, annot, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -119,6 +122,7 @@ fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, const fz { dev = fz_new_draw_device(ctx, ctm, pix); fz_run_display_list(ctx, list, dev, &fz_identity, NULL, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -155,6 +159,7 @@ fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, const fz_matrix { dev = fz_new_draw_device(ctx, ctm, pix); fz_run_page_contents(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -191,6 +196,7 @@ fz_new_pixmap_from_annot(fz_context *ctx, fz_annot *annot, const fz_matrix *ctm, { dev = fz_new_draw_device(ctx, ctm, pix); fz_run_annot(ctx, annot, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -227,6 +233,7 @@ fz_new_pixmap_from_page(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz { dev = fz_new_draw_device(ctx, ctm, pix); fz_run_page(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -268,6 +275,7 @@ fz_new_stext_page_from_display_list(fz_context *ctx, fz_display_list *list, fz_s { dev = fz_new_stext_device(ctx, sheet, text); fz_run_display_list(ctx, list, dev, &fz_identity, NULL, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -293,6 +301,7 @@ fz_new_stext_page_from_page(fz_context *ctx, fz_page *page, fz_stext_sheet *shee { dev = fz_new_stext_device(ctx, sheet, text); fz_run_page(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); } fz_always(ctx) { diff --git a/source/fitz/writer.c b/source/fitz/writer.c index 556e01a8..c4e95e2a 100644 --- a/source/fitz/writer.c +++ b/source/fitz/writer.c @@ -67,16 +67,18 @@ fz_new_document_writer(fz_context *ctx, const char *path, const char *format, co void fz_close_document_writer(fz_context *ctx, fz_document_writer *wri) { - if (wri->close) - wri->close(ctx, wri); - wri->close = NULL; + if (wri->close_writer) + wri->close_writer(ctx, wri); + wri->close_writer = NULL; } void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri) { - if (wri->close) - wri->close(ctx, wri); + if (wri->close_writer) + fz_warn(ctx, "dropping unclosed document writer"); + if (wri->drop_writer) + wri->drop_writer(ctx, wri); fz_free(ctx, wri); } diff --git a/source/fitz/zip.c b/source/fitz/zip.c index dd67e5ac..599d2954 100644 --- a/source/fitz/zip.c +++ b/source/fitz/zip.c @@ -15,6 +15,7 @@ struct fz_zip_writer_s fz_output *output; fz_buffer *central; int count; + int closed; }; void @@ -63,33 +64,34 @@ fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buf } void -fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip) +fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip) { - fz_try(ctx) - { - fz_off_t offset = fz_tell_output(ctx, zip->output); + fz_off_t offset = fz_tell_output(ctx, zip->output); - fz_write(ctx, zip->output, zip->central->data, zip->central->len); + fz_write(ctx, zip->output, zip->central->data, zip->central->len); - fz_write_int32_le(ctx, zip->output, ZIP_END_OF_CENTRAL_DIRECTORY_SIG); - fz_write_int16_le(ctx, zip->output, 0); /* number of this disk */ - fz_write_int16_le(ctx, zip->output, 0); /* number of disk where central directory starts */ - fz_write_int16_le(ctx, zip->output, zip->count); /* entries in central directory in this disk */ - fz_write_int16_le(ctx, zip->output, zip->count); /* entries in central directory in total */ - fz_write_int32_le(ctx, zip->output, (int)zip->central->len); /* size of the central directory */ - fz_write_int32_le(ctx, zip->output, (int)offset); /* offset of the central directory */ - fz_write_int16_le(ctx, zip->output, 5); /* zip file comment length */ + fz_write_int32_le(ctx, zip->output, ZIP_END_OF_CENTRAL_DIRECTORY_SIG); + fz_write_int16_le(ctx, zip->output, 0); /* number of this disk */ + fz_write_int16_le(ctx, zip->output, 0); /* number of disk where central directory starts */ + fz_write_int16_le(ctx, zip->output, zip->count); /* entries in central directory in this disk */ + fz_write_int16_le(ctx, zip->output, zip->count); /* entries in central directory in total */ + fz_write_int32_le(ctx, zip->output, (int)zip->central->len); /* size of the central directory */ + fz_write_int32_le(ctx, zip->output, (int)offset); /* offset of the central directory */ + fz_write_int16_le(ctx, zip->output, 5); /* zip file comment length */ - fz_write(ctx, zip->output, "MuPDF", 5); - } - fz_always(ctx) - { - fz_drop_output(ctx, zip->output); - fz_drop_buffer(ctx, zip->central); - fz_free(ctx, zip); - } - fz_catch(ctx) - fz_rethrow(ctx); + fz_write(ctx, zip->output, "MuPDF", 5); + + zip->closed = 1; +} + +void +fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip) +{ + if (!zip->closed) + fz_warn(ctx, "dropping unclosed zip writer"); + fz_drop_output(ctx, zip->output); + fz_drop_buffer(ctx, zip->central); + fz_free(ctx, zip); } fz_zip_writer * diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c index 408c3345..541fb7eb 100644 --- a/source/html/epub-doc.c +++ b/source/html/epub-doc.c @@ -93,7 +93,7 @@ epub_count_pages(fz_context *ctx, fz_document *doc_) } static void -epub_drop_page_imp(fz_context *ctx, fz_page *page_) +epub_drop_page(fz_context *ctx, fz_page *page_) { } @@ -154,14 +154,14 @@ epub_load_page(fz_context *ctx, fz_document *doc_, int number) epub_page *page = fz_new_page(ctx, sizeof *page); page->super.bound_page = epub_bound_page; page->super.run_page_contents = epub_run_page; - page->super.drop_page_imp = epub_drop_page_imp; + page->super.drop_page = epub_drop_page; page->doc = doc; page->number = number; return (fz_page*)page; } static void -epub_close_document(fz_context *ctx, fz_document *doc_) +epub_drop_document(fz_context *ctx, fz_document *doc_) { epub_document *doc = (epub_document*)doc_; epub_chapter *ch, *next; @@ -419,7 +419,7 @@ epub_init(fz_context *ctx, fz_archive *zip) doc->zip = zip; doc->set = fz_new_html_font_set(ctx); - doc->super.close = epub_close_document; + doc->super.drop_document = epub_drop_document; doc->super.layout = epub_layout; doc->super.load_outline = epub_load_outline; doc->super.count_pages = epub_count_pages; @@ -432,7 +432,7 @@ epub_init(fz_context *ctx, fz_archive *zip) } fz_catch(ctx) { - epub_close_document(ctx, (fz_document*)doc); + epub_drop_document(ctx, (fz_document*)doc); fz_rethrow(ctx); } diff --git a/source/html/html-doc.c b/source/html/html-doc.c index 94ceddb4..2e8b8ec4 100644 --- a/source/html/html-doc.c +++ b/source/html/html-doc.c @@ -23,7 +23,7 @@ struct html_page_s }; static void -htdoc_close_document(fz_context *ctx, fz_document *doc_) +htdoc_drop_document(fz_context *ctx, fz_document *doc_) { html_document *doc = (html_document*)doc_; fz_drop_archive(ctx, doc->zip); @@ -61,7 +61,7 @@ htdoc_layout(fz_context *ctx, fz_document *doc_, float w, float h, float em) } static void -htdoc_drop_page_imp(fz_context *ctx, fz_page *page_) +htdoc_drop_page(fz_context *ctx, fz_page *page_) { } @@ -97,7 +97,7 @@ htdoc_load_page(fz_context *ctx, fz_document *doc_, int number) html_page *page = fz_new_page(ctx, sizeof *page); page->super.bound_page = htdoc_bound_page; page->super.run_page_contents = htdoc_run_page; - page->super.drop_page_imp = htdoc_drop_page_imp; + page->super.drop_page = htdoc_drop_page; page->doc = doc; page->number = number; return (fz_page*)page; @@ -119,7 +119,7 @@ htdoc_open_document_with_stream(fz_context *ctx, fz_stream *file) doc = fz_new_document(ctx, html_document); - doc->super.close = htdoc_close_document; + doc->super.drop_document = htdoc_drop_document; doc->super.layout = htdoc_layout; doc->super.count_pages = htdoc_count_pages; doc->super.load_page = htdoc_load_page; @@ -145,7 +145,7 @@ htdoc_open_document(fz_context *ctx, const char *filename) fz_dirname(dirname, filename, sizeof dirname); doc = fz_new_document(ctx, html_document); - doc->super.close = htdoc_close_document; + doc->super.drop_document = htdoc_drop_document; doc->super.layout = htdoc_layout; doc->super.count_pages = htdoc_count_pages; doc->super.load_page = htdoc_load_page; diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c index 4a34e945..acf81961 100644 --- a/source/pdf/pdf-annot.c +++ b/source/pdf/pdf-annot.c @@ -491,7 +491,7 @@ pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page) { pdf_annot *annot = fz_new_annot(ctx, sizeof(pdf_annot)); - annot->super.drop_annot_imp = (fz_annot_drop_imp_fn*)pdf_drop_annot_imp; + annot->super.drop_annot = (fz_annot_drop_fn*)pdf_drop_annot_imp; annot->super.bound_annot = (fz_annot_bound_fn*)pdf_bound_annot; annot->super.run_annot = (fz_annot_run_fn*)pdf_run_annot; annot->super.next_annot = (fz_annot_next_fn*)pdf_next_annot; diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c index e275ca56..ed8a6f4a 100644 --- a/source/pdf/pdf-appearance.c +++ b/source/pdf/pdf-appearance.c @@ -1612,7 +1612,7 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann dev = pdf_new_pdf_device(ctx, doc, &fz_identity, &trect, resources, contents); fz_run_display_list(ctx, disp_list, dev, &inv_page_ctm, &fz_infinite_rect, NULL); - fz_drop_device(ctx, dev); + fz_close_device(ctx, dev); pdf_update_stream(ctx, doc, ap_obj, contents, 0); fz_drop_buffer(ctx, contents); @@ -1627,11 +1627,10 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann doc->dirty = 1; } - fz_catch(ctx) - { + fz_always(ctx) fz_drop_device(ctx, dev); + fz_catch(ctx) fz_rethrow(ctx); - } } static fz_point * @@ -1745,6 +1744,8 @@ void pdf_set_markup_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *an fz_stroke_path(ctx, dev, path, stroke, &page_ctm, fz_device_rgb(ctx), color, alpha); } + fz_close_device(ctx, dev); + fz_transform_rect(&rect, &page_ctm); pdf_set_annot_appearance(ctx, doc, annot, &rect, strike_list); } @@ -1879,6 +1880,8 @@ void pdf_update_ink_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *an rect.y1 += width; } + fz_close_device(ctx, dev); + fz_transform_rect(&rect, &page_ctm); pdf_set_annot_appearance(ctx, doc, annot, &rect, strike_list); } @@ -2126,6 +2129,8 @@ void pdf_update_text_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_an fz_fill_path(ctx, dev, path, 0, &tm, cs, white, 1.0f); fz_stroke_path(ctx, dev, path, stroke, &tm, cs, black, 1.0f); + fz_close_device(ctx, dev); + fz_transform_rect(&rect, &page_ctm); pdf_set_annot_appearance(ctx, doc, annot, &rect, dlist); @@ -2198,6 +2203,7 @@ void pdf_update_free_text_annot_appearance(fz_context *ctx, pdf_document *doc, p dlist = fz_new_display_list(ctx, NULL); dev = fz_new_list_device(ctx, dlist); fz_fill_text(ctx, dev, text, &page_ctm, cs, font_rec.da_rec.col, 1.0f); + fz_close_device(ctx, dev); fz_transform_rect(&rect, &page_ctm); pdf_set_annot_appearance(ctx, doc, annot, &rect, dlist); @@ -2415,6 +2421,8 @@ void pdf_set_signature_appearance(fz_context *ctx, pdf_document *doc, pdf_annot text = fit_text(ctx, &font_rec, (char *)bufstr, &rect); fz_fill_text(ctx, dev, text, &page_ctm, cs, font_rec.da_rec.col, 1.0f); + fz_close_device(ctx, dev); + rect = annot_rect; fz_transform_rect(&rect, &page_ctm); pdf_set_annot_appearance(ctx, doc, annot, &rect, dlist); diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c index 5c243e8f..4af09b0e 100644 --- a/source/pdf/pdf-device.c +++ b/source/pdf/pdf-device.c @@ -1037,12 +1037,17 @@ pdf_dev_end_tile(fz_context *ctx, fz_device *dev) } static void -pdf_dev_close(fz_context *ctx, fz_device *dev) +pdf_dev_close_device(fz_context *ctx, fz_device *dev) { pdf_device *pdev = (pdf_device*)dev; - int i; - pdf_dev_end_text(ctx, pdev); +} + +static void +pdf_dev_drop_device(fz_context *ctx, fz_device *dev) +{ + pdf_device *pdev = (pdf_device*)dev; + int i; for (i = pdev->num_gstates-1; i >= 0; i--) fz_drop_stroke_state(ctx, pdev->gstates[i].stroke_state); @@ -1066,7 +1071,8 @@ fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, const fz_matri { pdf_device *dev = fz_new_device(ctx, sizeof *dev); - dev->super.close = pdf_dev_close; + dev->super.close_device = pdf_dev_close_device; + dev->super.drop_device = pdf_dev_drop_device; dev->super.fill_path = pdf_dev_fill_path; dev->super.stroke_path = pdf_dev_stroke_path; diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c index c895478f..f3840794 100644 --- a/source/pdf/pdf-interpret.c +++ b/source/pdf/pdf-interpret.c @@ -6,11 +6,26 @@ pdf_new_processor(fz_context *ctx, int size) return Memento_label(fz_calloc(ctx, 1, size), "pdf_processor"); } +void +pdf_close_processor(fz_context *ctx, pdf_processor *proc) +{ + if (proc && proc->close_processor) + { + proc->close_processor(ctx, proc); + proc->close_processor = NULL; + } +} + void pdf_drop_processor(fz_context *ctx, pdf_processor *proc) { - if (proc && proc->drop_imp) - proc->drop_imp(ctx, proc); + if (proc) + { + if (proc->close_processor) + fz_warn(ctx, "dropping unclosed PDF processor"); + if (proc->drop_processor) + proc->drop_processor(ctx, proc); + } fz_free(ctx, proc); } diff --git a/source/pdf/pdf-op-buffer.c b/source/pdf/pdf-op-buffer.c index 5b37e6a5..2eb4323a 100644 --- a/source/pdf/pdf-op-buffer.c +++ b/source/pdf/pdf-op-buffer.c @@ -761,7 +761,7 @@ pdf_out_EX(fz_context *ctx, pdf_processor *proc) } static void -pdf_drop_imp_output_processor(fz_context *ctx, pdf_processor *proc) +pdf_drop_output_processor(fz_context *ctx, pdf_processor *proc) { fz_output *out = ((pdf_output_processor*)proc)->out; fz_drop_output(ctx, out); @@ -772,7 +772,7 @@ pdf_new_output_processor(fz_context *ctx, fz_output *out, int ahxencode) { pdf_output_processor *proc = pdf_new_processor(ctx, sizeof *proc); { - proc->super.drop_imp = pdf_drop_imp_output_processor; + proc->super.drop_processor = pdf_drop_output_processor; /* general graphics state */ proc->super.op_w = pdf_out_w; diff --git a/source/pdf/pdf-op-filter.c b/source/pdf/pdf-op-filter.c index 8eebe5cd..f5a0958d 100644 --- a/source/pdf/pdf-op-filter.c +++ b/source/pdf/pdf-op-filter.c @@ -1113,7 +1113,7 @@ pdf_filter_END(fz_context *ctx, pdf_processor *proc) } static void -pdf_drop_imp_filter_processor(fz_context *ctx, pdf_processor *proc) +pdf_drop_filter_processor(fz_context *ctx, pdf_processor *proc) { pdf_filter_processor *p = (pdf_filter_processor*)proc; fz_free(ctx, p->gstate); @@ -1125,7 +1125,7 @@ pdf_new_filter_processor(fz_context *ctx, pdf_processor *chain, pdf_document *do pdf_filter_processor *proc = pdf_new_processor(ctx, sizeof *proc); { - proc->super.drop_imp = pdf_drop_imp_filter_processor; + proc->super.drop_processor = pdf_drop_filter_processor; /* general graphics state */ proc->super.op_w = pdf_filter_w; diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index a0f28008..96084cdf 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -1999,7 +1999,7 @@ static void pdf_run_END(fz_context *ctx, pdf_processor *proc) } static void -pdf_run_drop_imp(fz_context *ctx, pdf_processor *proc) +pdf_drop_run_processor(fz_context *ctx, pdf_processor *proc) { pdf_run_processor *pr = (pdf_run_processor *)proc; @@ -2030,7 +2030,7 @@ pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, con { proc->super.event = event; - proc->super.drop_imp = pdf_run_drop_imp; + proc->super.drop_processor = pdf_drop_run_processor; /* general graphics state */ proc->super.op_w = pdf_run_w; diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c index e3b68378..dae0d49d 100644 --- a/source/pdf/pdf-page.c +++ b/source/pdf/pdf-page.c @@ -538,7 +538,7 @@ pdf_new_page(fz_context *ctx, pdf_document *doc) page->doc = (pdf_document*) fz_keep_document(ctx, &doc->super); - page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)pdf_drop_page_imp; + page->super.drop_page = (fz_page_drop_page_fn *)pdf_drop_page_imp; page->super.load_links = (fz_page_load_links_fn *)pdf_load_links; page->super.bound_page = (fz_page_bound_page_fn *)pdf_bound_page; page->super.first_annot = (fz_page_first_annot_fn *)pdf_first_annot; diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index 0a7a0f2f..3f2c2cda 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -3221,20 +3221,20 @@ pdf_writer_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) } static void -pdf_writer_close(fz_context *ctx, fz_document_writer *wri_) +pdf_writer_close_writer(fz_context *ctx, fz_document_writer *wri_) { pdf_writer *wri = (pdf_writer*)wri_; - fz_try(ctx) - pdf_save_document(ctx, wri->pdf, wri->filename, &wri->opts); - fz_always(ctx) - { - fz_drop_buffer(ctx, wri->contents); - pdf_drop_obj(ctx, wri->resources); - pdf_drop_document(ctx, wri->pdf); - fz_free(ctx, wri->filename); - } - fz_catch(ctx) - fz_rethrow(ctx); + pdf_save_document(ctx, wri->pdf, wri->filename, &wri->opts); +} + +static void +pdf_writer_drop_writer(fz_context *ctx, fz_document_writer *wri_) +{ + pdf_writer *wri = (pdf_writer*)wri_; + fz_drop_buffer(ctx, wri->contents); + pdf_drop_obj(ctx, wri->resources); + pdf_drop_document(ctx, wri->pdf); + fz_free(ctx, wri->filename); } fz_document_writer * @@ -3245,7 +3245,8 @@ fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options) wri = fz_malloc_struct(ctx, pdf_writer); wri->super.begin_page = pdf_writer_begin_page; wri->super.end_page = pdf_writer_end_page; - wri->super.close = pdf_writer_close; + wri->super.close_writer = pdf_writer_close_writer; + wri->super.drop_writer = pdf_writer_drop_writer; fz_try(ctx) { diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 48a5d316..f9f2f576 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -1556,7 +1556,7 @@ pdf_init_document(fz_context *ctx, pdf_document *doc) } static void -pdf_close_document(fz_context *ctx, pdf_document *doc) +pdf_drop_document_imp(fz_context *ctx, pdf_document *doc) { int i; @@ -2299,7 +2299,7 @@ pdf_new_document(fz_context *ctx, fz_stream *file) { pdf_document *doc = fz_new_document(ctx, pdf_document); - doc->super.close = (fz_document_close_fn *)pdf_close_document; + doc->super.drop_document = (fz_document_drop_fn *)pdf_drop_document_imp; doc->super.needs_password = (fz_document_needs_password_fn *)pdf_needs_password; doc->super.authenticate_password = (fz_document_authenticate_password_fn *)pdf_authenticate_password; doc->super.has_permission = (fz_document_has_permission_fn *)pdf_has_permission; @@ -2325,7 +2325,7 @@ pdf_open_document_with_stream(fz_context *ctx, fz_stream *file) } fz_catch(ctx) { - pdf_close_document(ctx, doc); + pdf_drop_document_imp(ctx, doc); fz_rethrow(ctx); } return doc; @@ -2352,7 +2352,7 @@ pdf_open_document(fz_context *ctx, const char *filename) } fz_catch(ctx) { - pdf_close_document(ctx, doc); + pdf_drop_document_imp(ctx, doc); fz_rethrow(ctx); } return doc; diff --git a/source/svg/svg-doc.c b/source/svg/svg-doc.c index 25f00e62..5404eefa 100644 --- a/source/svg/svg-doc.c +++ b/source/svg/svg-doc.c @@ -9,7 +9,7 @@ struct svg_page_s }; static void -svg_close_document(fz_context *ctx, fz_document *doc_) +svg_drop_document(fz_context *ctx, fz_document *doc_) { svg_document *doc = (svg_document*)doc_; fz_drop_tree(ctx, doc->idmap, NULL); @@ -47,7 +47,7 @@ svg_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix *c } static void -svg_drop_page_imp(fz_context *ctx, fz_page *page_) +svg_drop_page(fz_context *ctx, fz_page *page_) { /* nothing */ } @@ -64,7 +64,7 @@ svg_load_page(fz_context *ctx, fz_document *doc_, int number) page = fz_new_page(ctx, sizeof *page); page->super.bound_page = svg_bound_page; page->super.run_page_contents = svg_run_page; - page->super.drop_page_imp = svg_drop_page_imp; + page->super.drop_page = svg_drop_page; page->doc = doc; return (fz_page*)page; @@ -92,7 +92,7 @@ svg_open_document_with_buffer(fz_context *ctx, fz_buffer *buf) root = fz_parse_xml(ctx, buf->data, buf->len, 0); doc = fz_new_document(ctx, svg_document); - doc->super.close = svg_close_document; + doc->super.drop_document = svg_drop_document; doc->super.count_pages = svg_count_pages; doc->super.load_page = svg_load_page; diff --git a/source/tools/muconvert.c b/source/tools/muconvert.c index 95f01c4a..4fb3b071 100644 --- a/source/tools/muconvert.c +++ b/source/tools/muconvert.c @@ -162,6 +162,8 @@ int muconvert_main(int argc, char **argv) fz_drop_document(ctx, doc); } + fz_close_document_writer(ctx, out); + fz_drop_document_writer(ctx, out); fz_drop_context(ctx); return EXIT_SUCCESS; diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 0521a9b0..16e12b6b 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -554,6 +554,7 @@ static void drawband(fz_context *ctx, fz_page *page, fz_display_list *list, cons fz_run_display_list(ctx, list, dev, ctm, tbounds, cookie); else fz_run_page(ctx, page, dev, ctm, cookie); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); dev = NULL; @@ -596,6 +597,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in else fz_run_page(ctx, page, dev, &fz_identity, cookie); fz_printf(ctx, out, "\n"); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -628,6 +630,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in fz_run_display_list(ctx, list, dev, &fz_identity, &fz_infinite_rect, cookie); else fz_run_page(ctx, page, dev, &fz_identity, cookie); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); dev = NULL; if (output_format == OUT_STEXT) @@ -674,6 +677,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in fz_run_display_list(ctx, list, dev, &fz_identity, NULL, cookie); else fz_run_page(ctx, page, dev, &fz_identity, cookie); + fz_close_device(ctx, dev); page_obj = pdf_add_page(ctx, pdfout, &mediabox, rotation, resources, contents); pdf_insert_page(ctx, pdfout, -1, page_obj); @@ -726,6 +730,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in fz_run_display_list(ctx, list, dev, &ctm, &tbounds, cookie); else fz_run_page(ctx, page, dev, &ctm, cookie); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); dev = NULL; } @@ -754,10 +759,8 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in fz_ps_output_context *psoc = NULL; fz_mono_pcl_output_context *pmcoc = NULL; fz_color_pcl_output_context *pccoc = NULL; - fz_device *dev = NULL; fz_bitmap *bit = NULL; - fz_var(dev); fz_var(pix); fz_var(poc); fz_var(psoc); @@ -991,8 +994,6 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in { fz_drop_bitmap(ctx, bit); bit = NULL; - fz_drop_device(ctx, dev); - dev = NULL; if (num_workers > 0) { int band; @@ -1121,6 +1122,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) if (lowmemory) fz_enable_device_hints(ctx, dev, FZ_NO_CACHE); fz_run_page(ctx, page, dev, &fz_identity, &cookie); + fz_close_device(ctx, dev); } fz_always(ctx) { @@ -1153,6 +1155,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_run_display_list(ctx, list, dev, &fz_identity, &fz_infinite_rect, NULL); else fz_run_page(ctx, page, dev, &fz_identity, &cookie); + fz_close_device(ctx, dev); } fz_always(ctx) { diff --git a/source/tools/muraster.c b/source/tools/muraster.c index e5d886f4..6a2cf87e 100644 --- a/source/tools/muraster.c +++ b/source/tools/muraster.c @@ -710,6 +710,7 @@ static int drawband(fz_context *ctx, fz_page *page, fz_display_list *list, const fz_run_display_list(ctx, list, dev, ctm, tbounds, cookie); else fz_run_page(ctx, page, dev, ctm, cookie); + fz_close_device(ctx, dev); fz_drop_device(ctx, dev); dev = NULL; @@ -726,12 +727,10 @@ static int drawband(fz_context *ctx, fz_page *page, fz_display_list *list, const static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_details *render) { - fz_device *dev = NULL; fz_pixmap *pix = NULL; fz_bitmap *bit = NULL; int errors_are_fatal = 0; - fz_var(dev); fz_var(pix); fz_var(bit); fz_var(errors_are_fatal); @@ -852,8 +851,6 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de { fz_drop_bitmap(ctx, bit); bit = NULL; - fz_drop_device(ctx, dev); - dev = NULL; if (render->num_workers > 0) { int band; @@ -1198,9 +1195,11 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) #if GREY_FALLBACK != 0 test_dev = fz_new_test_device(ctx, &is_color, 0.01f, 0, list_dev); fz_run_page(ctx, page, test_dev, &fz_identity, &cookie); + fz_close_device(ctx, test_dev); #else fz_run_page(ctx, page, list_dev, &fz_identity, &cookie); #endif + fz_close_device(ctx, list_dev); } fz_always(ctx) { @@ -1229,6 +1228,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) { test_dev = fz_new_test_device(ctx, &is_color, 0.01f, 0, test_dev); fz_run_page(ctx, page, test_dev, &fz_identity, &cookie); + fz_close_device(ctx, test_dev); } fz_always(ctx) { @@ -1258,6 +1258,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_run_display_list(ctx, list, test_dev, &fz_identity, &fz_infinite_rect, &cookie); else fz_run_page(ctx, page, test_dev, &fz_identity, &cookie); + fz_close_device(ctx, test_dev); } fz_always(ctx) { diff --git a/source/tools/murun.c b/source/tools/murun.c index a3eacaa8..fb35f0a0 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -178,7 +178,10 @@ static const char *require_js = static void ffi_gc_fz_buffer(js_State *J, void *buf) { fz_context *ctx = js_getcontext(J); - fz_drop_buffer(ctx, buf); + fz_try(ctx) + fz_drop_buffer(ctx, buf); + fz_catch(ctx) + rethrow(J); } static void ffi_gc_fz_document(js_State *J, void *doc) @@ -1497,11 +1500,13 @@ static void ffi_Page_run(js_State *J) } else { device = new_js_device(ctx, J); js_copy(J, 1); /* put the js device on the top so the callbacks know where to get it */ - fz_try(ctx) + fz_try(ctx) { if (no_annots) fz_run_page_contents(ctx, page, device, &ctm, NULL); else fz_run_page(ctx, page, device, &ctm, NULL); + fz_close_device(ctx, device); + } fz_always(ctx) fz_drop_device(ctx, device); fz_catch(ctx) @@ -1650,8 +1655,10 @@ static void ffi_Annotation_run(js_State *J) } else { device = new_js_device(ctx, J); js_copy(J, 1); /* put the js device on the top so the callbacks know where to get it */ - fz_try(ctx) + fz_try(ctx) { fz_run_annot(ctx, annot, device, &ctm, NULL); + fz_close_device(ctx, device); + } fz_always(ctx) fz_drop_device(ctx, device); fz_catch(ctx) @@ -2213,8 +2220,10 @@ static void ffi_DisplayList_run(js_State *J) } else { device = new_js_device(ctx, J); js_copy(J, 1); - fz_try(ctx) + fz_try(ctx) { fz_run_display_list(ctx, list, device, &ctm, NULL, NULL); + fz_close_device(ctx, device); + } fz_always(ctx) fz_drop_device(ctx, device); fz_catch(ctx) @@ -2418,7 +2427,6 @@ static void ffi_DocumentWriter_endPage(js_State *J) rethrow(J); } - static void ffi_DocumentWriter_close(js_State *J) { fz_context *ctx = js_getcontext(J); diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c index 95008e72..fb4511f4 100644 --- a/source/xps/xps-doc.c +++ b/source/xps/xps-doc.c @@ -414,7 +414,7 @@ xps_bound_page(fz_context *ctx, xps_page *page, fz_rect *bounds) return bounds; } -void +static void xps_drop_page_imp(fz_context *ctx, xps_page *page) { if (page == NULL) @@ -444,7 +444,7 @@ xps_load_page(fz_context *ctx, xps_document *doc, int number) page->super.load_links = (fz_page_load_links_fn *)xps_load_links; page->super.bound_page = (fz_page_bound_page_fn *)xps_bound_page; page->super.run_page_contents = (fz_page_run_page_contents_fn *)xps_run_page; - page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)xps_drop_page_imp; + page->super.drop_page = (fz_page_drop_page_fn *)xps_drop_page_imp; page->doc = (xps_document*) fz_keep_document(ctx, &doc->super); page->fix = fix; diff --git a/source/xps/xps-zip.c b/source/xps/xps-zip.c index b0c4403a..2bf0391f 100644 --- a/source/xps/xps-zip.c +++ b/source/xps/xps-zip.c @@ -134,7 +134,7 @@ xps_open_document_with_directory(fz_context *ctx, const char *directory) } fz_catch(ctx) { - xps_close_document(ctx, doc); + xps_drop_document(ctx, doc); fz_rethrow(ctx); } @@ -156,7 +156,7 @@ xps_open_document_with_stream(fz_context *ctx, fz_stream *file) } fz_catch(ctx) { - xps_close_document(ctx, doc); + xps_drop_document(ctx, doc); fz_rethrow(ctx); } @@ -194,7 +194,7 @@ xps_open_document(fz_context *ctx, const char *filename) } void -xps_close_document(fz_context *ctx, xps_document *doc) +xps_drop_document(fz_context *ctx, xps_document *doc) { xps_font_cache *font, *next; @@ -232,7 +232,7 @@ static void xps_init_document(fz_context *ctx, xps_document *doc) { doc->super.refs = 1; - doc->super.close = (fz_document_close_fn *)xps_close_document; + doc->super.drop_document = (fz_document_drop_fn *)xps_drop_document; doc->super.load_outline = (fz_document_load_outline_fn *)xps_load_outline; doc->super.count_pages = (fz_document_count_pages_fn *)xps_count_pages; doc->super.load_page = (fz_document_load_page_fn *)xps_load_page; -- cgit v1.2.3