From 9172100d6d9f2f5aa4594aaa130fbfaef7162afd Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Fri, 5 Sep 2014 20:26:41 +0100 Subject: test-device: Abort interpretation when color found. Add a new class of errors and use them to abort interpretation when the test device detects a color page. --- include/mupdf/fitz/context.h | 1 + source/fitz/document.c | 28 ++++++++++++++++++++++++++-- source/fitz/error.c | 30 ++++++++++++++++++------------ source/fitz/list-device.c | 2 ++ source/fitz/test-device.c | 8 ++++++++ source/pdf/pdf-interpret.c | 12 +++++++++++- source/tools/mudraw.c | 22 ++++++++++++++++------ 7 files changed, 82 insertions(+), 21 deletions(-) diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h index 17eaf704..dc134511 100644 --- a/include/mupdf/fitz/context.h +++ b/include/mupdf/fitz/context.h @@ -80,6 +80,7 @@ enum FZ_ERROR_NONE = 0, FZ_ERROR_GENERIC = 1, FZ_ERROR_TRYLATER = 2, + FZ_ERROR_ABORT = 3, FZ_ERROR_COUNT }; diff --git a/source/fitz/document.c b/source/fitz/document.c index 45da7e90..4bde820c 100644 --- a/source/fitz/document.c +++ b/source/fitz/document.c @@ -244,14 +244,38 @@ void fz_run_page_contents(fz_document *doc, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie) { if (doc && doc->run_page_contents && page) - doc->run_page_contents(doc, page, dev, transform, cookie); + { + fz_context *ctx = dev->ctx; + + fz_try(ctx) + { + doc->run_page_contents(doc, page, dev, transform, cookie); + } + fz_catch(ctx) + { + if (fz_caught(ctx) != FZ_ERROR_ABORT) + fz_rethrow(ctx); + } + } } void fz_run_annot(fz_document *doc, fz_page *page, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie) { if (doc && doc->run_annot && page && annot) - doc->run_annot(doc, page, annot, dev, transform, cookie); + { + fz_context *ctx = dev->ctx; + + fz_try(ctx) + { + doc->run_annot(doc, page, annot, dev, transform, cookie); + } + fz_catch(ctx) + { + if (fz_caught(ctx) != FZ_ERROR_ABORT) + fz_rethrow(ctx); + } + } } void diff --git a/source/fitz/error.c b/source/fitz/error.c index e8225ee3..414b993f 100644 --- a/source/fitz/error.c +++ b/source/fitz/error.c @@ -140,14 +140,17 @@ void fz_throw(fz_context *ctx, int code, const char *fmt, ...) vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args); va_end(args); - fz_flush_warnings(ctx); - fprintf(stderr, "error: %s\n", ctx->error->message); - LOGE("error: %s\n", ctx->error->message); + if (code != FZ_ERROR_ABORT) + { + fz_flush_warnings(ctx); + fprintf(stderr, "error: %s\n", ctx->error->message); + LOGE("error: %s\n", ctx->error->message); #ifdef USE_OUTPUT_DEBUG_STRING - OutputDebugStringA("error: "); - OutputDebugStringA(ctx->error->message); - OutputDebugStringA("\n"); + OutputDebugStringA("error: "); + OutputDebugStringA(ctx->error->message); + OutputDebugStringA("\n"); #endif + } throw(ctx->error); } @@ -168,14 +171,17 @@ void fz_rethrow_message(fz_context *ctx, const char *fmt, ...) vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args); va_end(args); - fz_flush_warnings(ctx); - fprintf(stderr, "error: %s\n", ctx->error->message); - LOGE("error: %s\n", ctx->error->message); + if (ctx->error->errcode != FZ_ERROR_ABORT) + { + fz_flush_warnings(ctx); + fprintf(stderr, "error: %s\n", ctx->error->message); + LOGE("error: %s\n", ctx->error->message); #ifdef USE_OUTPUT_DEBUG_STRING - OutputDebugStringA("error: "); - OutputDebugStringA(ctx->error->message); - OutputDebugStringA("\n"); + OutputDebugStringA("error: "); + OutputDebugStringA(ctx->error->message); + OutputDebugStringA("\n"); #endif + } throw(ctx->error); } diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c index 529e0bbf..2bac3034 100644 --- a/source/fitz/list-device.c +++ b/source/fitz/list-device.c @@ -848,6 +848,8 @@ visible: /* Swallow the error */ if (cookie) cookie->errors++; + if (fz_caught(ctx) == FZ_ERROR_ABORT) + break; fz_warn(ctx, "Ignoring error during interpretation"); } } diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c index 32d3a5f6..9c778ce1 100644 --- a/source/fitz/test-device.c +++ b/source/fitz/test-device.c @@ -38,6 +38,7 @@ fz_test_color(fz_device *dev, fz_colorspace *colorspace, const float *color) { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; + fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); } } else @@ -48,6 +49,7 @@ fz_test_color(fz_device *dev, fz_colorspace *colorspace, const float *color) { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; + fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); } } } @@ -150,6 +152,8 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; + fz_close(stream); + fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } } @@ -199,6 +203,8 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; + fz_drop_pixmap(ctx, pix); + fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } s += 4; @@ -226,6 +232,8 @@ fz_test_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float { *t->is_color = 1; dev->hints |= FZ_IGNORE_IMAGE; + fz_drop_pixmap(ctx, pix); + fz_throw(ctx, FZ_ERROR_ABORT, "Page found as color; stopping interpretation"); break; } } diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c index 507bf0fa..a6b211dd 100644 --- a/source/pdf/pdf-interpret.c +++ b/source/pdf/pdf-interpret.c @@ -252,6 +252,7 @@ pdf_run_keyword(pdf_csi *csi, char *buf) } fz_catch(ctx) { + fz_rethrow_if(ctx, FZ_ERROR_ABORT); switch (op) { case PDF_OP_Do: @@ -452,17 +453,23 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf) } fz_catch(ctx) { + int caught; + if (!csi->cookie) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); } - else if (fz_caught(ctx) == FZ_ERROR_TRYLATER) + else if ((caught = fz_caught(ctx)) == FZ_ERROR_TRYLATER) { if (csi->cookie->incomplete_ok) csi->cookie->incomplete++; else fz_rethrow(ctx); } + else if (caught == FZ_ERROR_ABORT) + { + fz_rethrow(ctx); + } else { csi->cookie->errors++; @@ -524,6 +531,7 @@ pdf_process_contents_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file) fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_rethrow_if(ctx, FZ_ERROR_ABORT); fz_warn(ctx, "Content stream parsing error - rendering truncated"); } } @@ -622,6 +630,7 @@ pdf_process_stream_object(pdf_document *doc, pdf_obj *obj, const pdf_process *pr } fz_catch(ctx) { + fz_rethrow_if(ctx, FZ_ERROR_ABORT); fz_rethrow_message(ctx, "cannot parse content stream"); } } @@ -643,6 +652,7 @@ pdf_process_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, pd } fz_catch(ctx) { + fz_rethrow_if(ctx, FZ_ERROR_ABORT); fz_rethrow_message(ctx, "cannot parse glyph content stream"); } } diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 198e47ce..420ca1dc 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -317,12 +317,22 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) { int iscolor; dev = fz_new_test_device(ctx, &iscolor, 0.02f); - if (list) - fz_run_display_list(list, dev, &fz_identity, &fz_infinite_rect, NULL); - else - fz_run_page(doc, page, dev, &fz_identity, &cookie); - fz_free_device(dev); - dev = NULL; + fz_try(ctx) + { + if (list) + fz_run_display_list(list, dev, &fz_identity, &fz_infinite_rect, NULL); + else + fz_run_page(doc, page, dev, &fz_identity, &cookie); + } + fz_always(ctx) + { + fz_free_device(dev); + dev = NULL; + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } printf(" %s", iscolor ? "color" : "grayscale"); } -- cgit v1.2.3