diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-06-11 15:50:30 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-06-11 19:55:53 +0100 |
commit | 120dabdf30be66b5d17f4c59862907bb5d176e27 (patch) | |
tree | 509ac66222e21248e98fd55eaf0408e098222878 /fitz | |
parent | b42125b79edc28af6508145a24308674403a8460 (diff) | |
download | mupdf-120dabdf30be66b5d17f4c59862907bb5d176e27.tar.xz |
Fix Bug 693099: Render failure due to corrupt jpeg data.
The file supplied with the bug contains corrupt jpeg data on page
61. This causes an error to be thrown which results in mudraw
exiting.
Previously, when image decode was done at loading time, the error
would have been thrown under the pdf interpreter rather than under
the display list renderer. This error would have been caught, a
warning given, and the program would have continued. This is not
ideal behaviour, as there is no way for a caller to know that there
was a problem, and that the image is potentially incomplete.
The solution adopted here, solves both these problems. The fz_cookie
structure is expanded to include a 'errors' count. Whenever we meet
an error during rendering, we increment the 'errors' count, and
continue.
This enables applications to spot the errors count being non-zero on
exit and to display a warning.
mupdf is updated here to pass a cookie in and to check the error count
at the end; if it is found to be non zero, then a warning is given (just
once per visit to each page) to say that the page may have errors on it.
Diffstat (limited to 'fitz')
-rw-r--r-- | fitz/dev_list.c | 179 | ||||
-rw-r--r-- | fitz/fitz.h | 3 |
2 files changed, 98 insertions, 84 deletions
diff --git a/fitz/dev_list.c b/fitz/dev_list.c index 1ca8bf98..d84fb15b 100644 --- a/fitz/dev_list.c +++ b/fitz/dev_list.c @@ -593,6 +593,7 @@ fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix top_ctm, fz int tiled = 0; int empty; int progress = 0; + fz_context *ctx = dev->ctx; if (cookie) { @@ -658,93 +659,103 @@ fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix top_ctm, fz visible: ctm = fz_concat(node->ctm, top_ctm); - switch (node->cmd) - { - case FZ_CMD_FILL_PATH: - fz_fill_path(dev, node->item.path, node->flag, ctm, - node->colorspace, node->color, node->alpha); - break; - case FZ_CMD_STROKE_PATH: - fz_stroke_path(dev, node->item.path, node->stroke, ctm, - node->colorspace, node->color, node->alpha); - break; - case FZ_CMD_CLIP_PATH: - { - fz_rect trect = fz_transform_rect(top_ctm, node->rect); - fz_clip_path(dev, node->item.path, &trect, node->flag, ctm); - break; - } - case FZ_CMD_CLIP_STROKE_PATH: + fz_try(ctx) { - fz_rect trect = fz_transform_rect(top_ctm, node->rect); - fz_clip_stroke_path(dev, node->item.path, &trect, node->stroke, ctm); - break; + switch (node->cmd) + { + case FZ_CMD_FILL_PATH: + fz_fill_path(dev, node->item.path, node->flag, ctm, + node->colorspace, node->color, node->alpha); + break; + case FZ_CMD_STROKE_PATH: + fz_stroke_path(dev, node->item.path, node->stroke, ctm, + node->colorspace, node->color, node->alpha); + break; + case FZ_CMD_CLIP_PATH: + { + fz_rect trect = fz_transform_rect(top_ctm, node->rect); + fz_clip_path(dev, node->item.path, &trect, node->flag, ctm); + break; + } + case FZ_CMD_CLIP_STROKE_PATH: + { + fz_rect trect = fz_transform_rect(top_ctm, node->rect); + fz_clip_stroke_path(dev, node->item.path, &trect, node->stroke, ctm); + break; + } + case FZ_CMD_FILL_TEXT: + fz_fill_text(dev, node->item.text, ctm, + node->colorspace, node->color, node->alpha); + break; + case FZ_CMD_STROKE_TEXT: + fz_stroke_text(dev, node->item.text, node->stroke, ctm, + node->colorspace, node->color, node->alpha); + break; + case FZ_CMD_CLIP_TEXT: + fz_clip_text(dev, node->item.text, ctm, node->flag); + break; + case FZ_CMD_CLIP_STROKE_TEXT: + fz_clip_stroke_text(dev, node->item.text, node->stroke, ctm); + break; + case FZ_CMD_IGNORE_TEXT: + fz_ignore_text(dev, node->item.text, ctm); + break; + case FZ_CMD_FILL_SHADE: + fz_fill_shade(dev, node->item.shade, ctm, node->alpha); + break; + case FZ_CMD_FILL_IMAGE: + fz_fill_image(dev, node->item.image, ctm, node->alpha); + break; + case FZ_CMD_FILL_IMAGE_MASK: + fz_fill_image_mask(dev, node->item.image, ctm, + node->colorspace, node->color, node->alpha); + break; + case FZ_CMD_CLIP_IMAGE_MASK: + { + fz_rect trect = fz_transform_rect(top_ctm, node->rect); + fz_clip_image_mask(dev, node->item.image, &trect, ctm); + break; + } + case FZ_CMD_POP_CLIP: + fz_pop_clip(dev); + break; + case FZ_CMD_BEGIN_MASK: + rect = fz_transform_rect(top_ctm, node->rect); + fz_begin_mask(dev, rect, node->flag, node->colorspace, node->color); + break; + case FZ_CMD_END_MASK: + fz_end_mask(dev); + break; + case FZ_CMD_BEGIN_GROUP: + rect = fz_transform_rect(top_ctm, node->rect); + fz_begin_group(dev, rect, + (node->flag & ISOLATED) != 0, (node->flag & KNOCKOUT) != 0, + node->item.blendmode, node->alpha); + break; + case FZ_CMD_END_GROUP: + fz_end_group(dev); + break; + case FZ_CMD_BEGIN_TILE: + tiled++; + rect.x0 = node->color[2]; + rect.y0 = node->color[3]; + rect.x1 = node->color[4]; + rect.y1 = node->color[5]; + fz_begin_tile(dev, node->rect, rect, + node->color[0], node->color[1], ctm); + break; + case FZ_CMD_END_TILE: + tiled--; + fz_end_tile(dev); + break; + } } - case FZ_CMD_FILL_TEXT: - fz_fill_text(dev, node->item.text, ctm, - node->colorspace, node->color, node->alpha); - break; - case FZ_CMD_STROKE_TEXT: - fz_stroke_text(dev, node->item.text, node->stroke, ctm, - node->colorspace, node->color, node->alpha); - break; - case FZ_CMD_CLIP_TEXT: - fz_clip_text(dev, node->item.text, ctm, node->flag); - break; - case FZ_CMD_CLIP_STROKE_TEXT: - fz_clip_stroke_text(dev, node->item.text, node->stroke, ctm); - break; - case FZ_CMD_IGNORE_TEXT: - fz_ignore_text(dev, node->item.text, ctm); - break; - case FZ_CMD_FILL_SHADE: - fz_fill_shade(dev, node->item.shade, ctm, node->alpha); - break; - case FZ_CMD_FILL_IMAGE: - fz_fill_image(dev, node->item.image, ctm, node->alpha); - break; - case FZ_CMD_FILL_IMAGE_MASK: - fz_fill_image_mask(dev, node->item.image, ctm, - node->colorspace, node->color, node->alpha); - break; - case FZ_CMD_CLIP_IMAGE_MASK: + fz_catch(ctx) { - fz_rect trect = fz_transform_rect(top_ctm, node->rect); - fz_clip_image_mask(dev, node->item.image, &trect, ctm); - break; - } - case FZ_CMD_POP_CLIP: - fz_pop_clip(dev); - break; - case FZ_CMD_BEGIN_MASK: - rect = fz_transform_rect(top_ctm, node->rect); - fz_begin_mask(dev, rect, node->flag, node->colorspace, node->color); - break; - case FZ_CMD_END_MASK: - fz_end_mask(dev); - break; - case FZ_CMD_BEGIN_GROUP: - rect = fz_transform_rect(top_ctm, node->rect); - fz_begin_group(dev, rect, - (node->flag & ISOLATED) != 0, (node->flag & KNOCKOUT) != 0, - node->item.blendmode, node->alpha); - break; - case FZ_CMD_END_GROUP: - fz_end_group(dev); - break; - case FZ_CMD_BEGIN_TILE: - tiled++; - rect.x0 = node->color[2]; - rect.y0 = node->color[3]; - rect.x1 = node->color[4]; - rect.y1 = node->color[5]; - fz_begin_tile(dev, node->rect, rect, - node->color[0], node->color[1], ctm); - break; - case FZ_CMD_END_TILE: - tiled--; - fz_end_tile(dev); - break; + /* Swallow the error */ + if (cookie) + cookie->errors++; + fz_warn(ctx, "Ignoring error during interpretation"); } } } diff --git a/fitz/fitz.h b/fitz/fitz.h index a10fd4dc..1892bc5e 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1750,12 +1750,15 @@ typedef struct fz_cookie_s fz_cookie; may change from -1 to a positive value once an upper bound is known, so take this into consideration when comparing the value of progress to that of progress_max. + + errors: count of errors during current rendering. */ struct fz_cookie_s { int abort; int progress; int progress_max; /* -1 for unknown */ + int errors; }; /* |