diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-08 15:48:09 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-08 15:48:09 +0200 |
commit | 649c79c91175dd1d116772d24e76554c440d90a8 (patch) | |
tree | 3372739743a5b67dfde051e02708bd080960f921 | |
parent | 9915a386ea1dab21c5bbd4a0c8012dd13dbda301 (diff) | |
download | mupdf-649c79c91175dd1d116772d24e76554c440d90a8.tar.xz |
Recover from error when only parts of the page content array are broken.
-rw-r--r-- | pdf/pdf_page.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c index 24f63d51..b73bc150 100644 --- a/pdf/pdf_page.c +++ b/pdf/pdf_page.c @@ -129,12 +129,9 @@ static int pdf_resources_use_blending(fz_obj *rdb); static int pdf_extgstate_uses_blending(fz_obj *dict) { - fz_obj *obj; - - obj = fz_dict_gets(dict, "BM"); + fz_obj *obj = fz_dict_gets(dict, "BM"); if (fz_is_name(obj) && strcmp(fz_to_name(obj), "Normal")) return 1; - return 0; } @@ -142,27 +139,21 @@ static int pdf_pattern_uses_blending(fz_obj *dict) { fz_obj *obj; - obj = fz_dict_gets(dict, "Resources"); - if (fz_is_dict(obj) && pdf_resources_use_blending(obj)) + if (pdf_resources_use_blending(obj)) return 1; - obj = fz_dict_gets(dict, "ExtGState"); - if (fz_is_dict(obj) && pdf_extgstate_uses_blending(obj)) + if (pdf_extgstate_uses_blending(obj)) return 1; - return 0; } static int pdf_xobject_uses_blending(fz_obj *dict) { - fz_obj *obj; - - obj = fz_dict_gets(dict, "Resources"); - if (fz_is_dict(obj) && pdf_resources_use_blending(obj)) + fz_obj *obj = fz_dict_gets(dict, "Resources"); + if (pdf_resources_use_blending(obj)) return 1; - return 0; } @@ -173,6 +164,9 @@ pdf_resources_use_blending(fz_obj *rdb) fz_obj *tmp; int i; + if (!rdb) + return 0; + /* stop on cyclic resource dependencies */ if (fz_dict_gets(rdb, ".useBM")) return fz_to_bool(fz_dict_gets(rdb, ".useBM")); @@ -213,21 +207,29 @@ pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list) fz_error error; fz_buffer *big; fz_buffer *one; - int i; + int i, n; /* TODO: openstream, read, close into big buffer at once */ big = fz_new_buffer(32 * 1024); - for (i = 0; i < fz_array_len(list); i++) + n = fz_array_len(list); + for (i = 0; i < n; i++) { fz_obj *stm = fz_array_get(list, i); error = pdf_load_stream(&one, xref, fz_to_num(stm), fz_to_gen(stm)); if (error) { - fz_drop_buffer(big); - return fz_rethrow(error, "cannot load content stream part %d/%d (%d 0 R)", - i + 1, fz_array_len(list), fz_to_num(stm)); + if (i == 0) + { + fz_drop_buffer(big); + return fz_rethrow(error, "cannot load content stream part %d/%d", i + 1, n); + } + else + { + fz_catch(error, "cannot load content stream part %d/%d", i + 1, n); + break; + } } if (big->len + one->len + 1 > big->cap) @@ -252,7 +254,7 @@ pdf_load_page_contents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj) { error = pdf_load_page_contents_array(bufp, xref, obj); if (error) - return fz_rethrow(error, "cannot load content stream array (%d 0 R)", fz_to_num(obj)); + return fz_rethrow(error, "cannot load content stream array"); } else if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj))) { @@ -274,7 +276,8 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) { fz_error error; pdf_page *page; - fz_obj *dict; + pdf_annot *annot; + fz_obj *pageobj, *pageref; fz_obj *obj; fz_bbox bbox; @@ -285,7 +288,8 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) if (!xref->store) xref->store = pdf_new_store(); - dict = xref->page_objs[number]; + pageobj = xref->page_objs[number]; + pageref = xref->page_refs[number]; page = fz_malloc(sizeof(pdf_page)); page->resources = NULL; @@ -294,7 +298,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) page->links = NULL; page->annots = NULL; - obj = fz_dict_gets(dict, "MediaBox"); + obj = fz_dict_gets(pageobj, "MediaBox"); bbox = fz_round_rect(pdf_to_rect(obj)); if (fz_is_empty_rect(pdf_to_rect(obj))) { @@ -305,7 +309,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) bbox.y1 = 792; } - obj = fz_dict_gets(dict, "CropBox"); + obj = fz_dict_gets(pageobj, "CropBox"); if (fz_is_array(obj)) { fz_bbox cropbox = fz_round_rect(pdf_to_rect(obj)); @@ -323,30 +327,34 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) page->mediabox = fz_unit_rect; } - page->rotate = fz_to_int(fz_dict_gets(dict, "Rotate")); + page->rotate = fz_to_int(fz_dict_gets(pageobj, "Rotate")); - obj = fz_dict_gets(dict, "Annots"); + obj = fz_dict_gets(pageobj, "Annots"); if (obj) { pdf_load_links(&page->links, xref, obj); pdf_load_annots(&page->annots, xref, obj); } - page->resources = fz_dict_gets(dict, "Resources"); + page->resources = fz_dict_gets(pageobj, "Resources"); if (page->resources) fz_keep_obj(page->resources); - obj = fz_dict_gets(dict, "Contents"); + obj = fz_dict_gets(pageobj, "Contents"); error = pdf_load_page_contents(&page->contents, xref, obj); if (error) { pdf_free_page(page); - return fz_rethrow(error, "cannot load page contents for page %d (%d 0 R)", number + 1, fz_to_num(obj)); + return fz_rethrow(error, "cannot load page %d contents (%d 0 R)", number + 1, fz_to_num(pageref)); } - if (page->resources && pdf_resources_use_blending(page->resources)) + if (pdf_resources_use_blending(page->resources)) page->transparency = 1; + for (annot = page->annots; annot && !page->transparency; annot = annot->next) + if (pdf_resources_use_blending(annot->ap->resources)) + page->transparency = 1; + *pagep = page; return fz_okay; } |