diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-12-08 21:06:20 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-12-08 21:46:56 +0100 |
commit | 6796e89abefe67ea1e35e5f40f6a77620b6de9d8 (patch) | |
tree | 77635bafb33e939501de66e27cd393aafbc75b0b | |
parent | 787c07bc94c3aa163981cb0321e92ce465d33d5f (diff) | |
download | mupdf-6796e89abefe67ea1e35e5f40f6a77620b6de9d8.tar.xz |
Throw exceptions in xps code.
-rw-r--r-- | xps/muxps.h | 5 | ||||
-rw-r--r-- | xps/xps_doc.c | 85 | ||||
-rw-r--r-- | xps/xps_glyphs.c | 10 | ||||
-rw-r--r-- | xps/xps_image.c | 27 | ||||
-rw-r--r-- | xps/xps_outline.c | 40 | ||||
-rw-r--r-- | xps/xps_png.c | 117 | ||||
-rw-r--r-- | xps/xps_resource.c | 50 | ||||
-rw-r--r-- | xps/xps_tiff.c | 122 | ||||
-rw-r--r-- | xps/xps_tile.c | 21 | ||||
-rw-r--r-- | xps/xps_xml.c | 4 | ||||
-rw-r--r-- | xps/xps_zip.c | 112 |
11 files changed, 243 insertions, 350 deletions
diff --git a/xps/muxps.h b/xps/muxps.h index 18ca528e..188935c8 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -63,6 +63,7 @@ struct xps_part_s }; xps_part *xps_new_part(xps_document *doc, char *name, int size); +int xps_has_part(xps_document *doc, char *partname); xps_part *xps_read_part(xps_document *doc, char *partname); void xps_free_part(xps_document *doc, xps_part *part); @@ -98,7 +99,7 @@ struct xps_target_s xps_target *next; }; -int xps_read_page_list(xps_document *doc); +void xps_read_page_list(xps_document *doc); void xps_debug_page_list(xps_document *doc); void xps_free_page_list(xps_document *doc); @@ -162,7 +163,7 @@ struct xps_resource_s xps_resource *parent; /* up to the previous dict in the stack */ }; -int xps_parse_resource_dictionary(xps_document *doc, xps_resource **dictp, char *base_uri, xml_element *root); +xps_resource * xps_parse_resource_dictionary(xps_document *doc, char *base_uri, xml_element *root); void xps_free_resource_dictionary(xps_document *doc, xps_resource *dict); void xps_resolve_resource_reference(xps_document *doc, xps_resource *dict, char **attp, xml_element **tagp, char **urip); diff --git a/xps/xps_doc.c b/xps/xps_doc.c index 6b6c0c08..3304e1b9 100644 --- a/xps/xps_doc.c +++ b/xps/xps_doc.c @@ -237,7 +237,7 @@ xps_parse_metadata_imp(xps_document *doc, xml_element *item, xps_fixdoc *fixdoc) } } -static int +static void xps_parse_metadata(xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) { xml_element *root; @@ -262,70 +262,50 @@ xps_parse_metadata(xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) doc->part_uri = part->name; root = xml_parse_document(doc->ctx, part->data, part->size); - if (!root) - return fz_error_note(-1, "cannot parse metadata part '%s'", part->name); - xps_parse_metadata_imp(doc, root, fixdoc); - xml_free_element(doc->ctx, root); doc->base_uri = NULL; doc->part_uri = NULL; - - return fz_okay; } -static int +static void xps_read_and_process_metadata_part(xps_document *doc, char *name, xps_fixdoc *fixdoc) { - xps_part *part; - int code; - - part = xps_read_part(doc, name); - if (!part) - return fz_error_note(-1, "cannot read zip part '%s'", name); - - code = xps_parse_metadata(doc, part, fixdoc); - if (code) - return fz_error_note(code, "cannot process metadata part '%s'", name); - - xps_free_part(doc, part); - - return fz_okay; + if (xps_has_part(doc, name)) + { + xps_part *part = xps_read_part(doc, name); + xps_parse_metadata(doc, part, fixdoc); + xps_free_part(doc, part); + } } -int +void xps_read_page_list(xps_document *doc) { xps_fixdoc *fixdoc; - int code; - code = xps_read_and_process_metadata_part(doc, "/_rels/.rels", NULL); - if (code) - return fz_error_note(code, "cannot process root relationship part"); + xps_read_and_process_metadata_part(doc, "/_rels/.rels", NULL); if (!doc->start_part) - return fz_error_make("cannot find fixed document sequence start part"); + fz_throw(doc->ctx, "cannot find fixed document sequence start part"); - code = xps_read_and_process_metadata_part(doc, doc->start_part, NULL); - if (code) - return fz_error_note(code, "cannot process FixedDocumentSequence part"); + xps_read_and_process_metadata_part(doc, doc->start_part, NULL); for (fixdoc = doc->first_fixdoc; fixdoc; fixdoc = fixdoc->next) { char relbuf[1024]; - xps_rels_for_part(relbuf, fixdoc->name, sizeof relbuf); - - code = xps_read_and_process_metadata_part(doc, relbuf, fixdoc); - if (code) - fz_error_handle(code, "cannot process FixedDocument rels part"); - - code = xps_read_and_process_metadata_part(doc, fixdoc->name, fixdoc); - if (code) - return fz_error_note(code, "cannot process FixedDocument part"); + fz_try(doc->ctx) + { + xps_rels_for_part(relbuf, fixdoc->name, sizeof relbuf); + xps_read_and_process_metadata_part(doc, relbuf, fixdoc); + } + fz_catch(doc->ctx) + { + fz_warn(doc->ctx, "cannot process FixedDocument rels part"); + } + xps_read_and_process_metadata_part(doc, fixdoc->name, fixdoc); } - - return fz_okay; } int @@ -334,7 +314,7 @@ xps_count_pages(xps_document *doc) return doc->page_count; } -static int +static void xps_load_fixed_page(xps_document *doc, xps_page *page) { xps_part *part; @@ -343,31 +323,23 @@ xps_load_fixed_page(xps_document *doc, xps_page *page) char *height_att; part = xps_read_part(doc, page->name); - if (!part) - return fz_error_note(-1, "cannot read zip part '%s'", page->name); - root = xml_parse_document(doc->ctx, part->data, part->size); - if (!root) - return fz_error_note(-1, "cannot parse xml part '%s'", page->name); - xps_free_part(doc, part); if (strcmp(xml_tag(root), "FixedPage")) - return fz_error_make("expected FixedPage element (found %s)", xml_tag(root)); + fz_throw(doc->ctx, "expected FixedPage element (found %s)", xml_tag(root)); width_att = xml_att(root, "Width"); if (!width_att) - return fz_error_make("FixedPage missing required attribute: Width"); + fz_throw(doc->ctx, "FixedPage missing required attribute: Width"); height_att = xml_att(root, "Height"); if (!height_att) - return fz_error_make("FixedPage missing required attribute: Height"); + fz_throw(doc->ctx, "FixedPage missing required attribute: Height"); page->width = atoi(width_att); page->height = atoi(height_att); page->root = root; - - return 0; } xps_page * @@ -381,17 +353,14 @@ xps_load_page(xps_document *doc, int number) if (n == number) { if (!page->root) - { xps_load_fixed_page(doc, page); - /* RJW: "cannot load page %d", number + 1 */ - } return page; } n ++; } fz_throw(doc->ctx, "cannot find page %d", number + 1); - return NULL; /* Stupid MSVC */ + return NULL; } void diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c index 56e6e4c6..9731a448 100644 --- a/xps/xps_glyphs.c +++ b/xps/xps_glyphs.c @@ -483,8 +483,12 @@ xps_parse_glyphs(xps_document *doc, fz_matrix ctm, font = xps_lookup_font(doc, partname); if (!font) { - part = xps_read_part(doc, partname); - if (!part) { + fz_try(doc->ctx) + { + part = xps_read_part(doc, partname); + } + fz_catch(doc->ctx) + { fz_warn(doc->ctx, "cannot find font resource part '%s'", partname); return; } @@ -501,7 +505,7 @@ xps_parse_glyphs(xps_document *doc, fz_matrix ctm, } fz_catch(doc->ctx) { - fz_error_handle(1, "cannot load font resource '%s'", partname); + fz_warn(doc->ctx, "cannot load font resource '%s'", partname); xps_free_part(doc, part); return; } diff --git a/xps/xps_image.c b/xps/xps_image.c index 129637d9..6ba017da 100644 --- a/xps/xps_image.c +++ b/xps/xps_image.c @@ -10,24 +10,13 @@ xps_decode_image(fz_context *ctx, byte *buf, int len) fz_throw(ctx, "unknown image file format"); if (buf[0] == 0xff && buf[1] == 0xd8) - { image = xps_decode_jpeg(ctx, buf, len); - /* RJW: "cannot decode jpeg image" */ - } else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0) - { image = xps_decode_png(ctx, buf, len); - /* RJW: "cannot decode png image" */ - } else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC) - { fz_throw(ctx, "JPEG-XR codec is not available"); - } else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0) - { image = xps_decode_tiff(ctx, buf, len); - /* RJW: "cannot decode TIFF image" */ - } else fz_throw(ctx, "unknown image file format"); @@ -59,7 +48,7 @@ xps_find_image_brush_source_part(xps_document *doc, char *base_uri, xml_element image_source_att = xml_att(root, "ImageSource"); if (!image_source_att) - return NULL; + fz_throw(doc->ctx, "cannot find image source attribute"); /* "{ColorConvertedBitmap /Resources/Image.tiff /Resources/Profile.icc}" */ if (strstr(image_source_att, "{ColorConvertedBitmap") == image_source_att) @@ -90,7 +79,7 @@ xps_find_image_brush_source_part(xps_document *doc, char *base_uri, xml_element } if (!image_name) - return NULL; + fz_throw(doc->ctx, "cannot find image source"); xps_absolute_path(partname, base_uri, image_name, sizeof partname); @@ -104,8 +93,12 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, xps_part *part; fz_pixmap *image; - part = xps_find_image_brush_source_part(doc, base_uri, root); - if (!part) { + fz_try(doc->ctx) + { + part = xps_find_image_brush_source_part(doc, base_uri, root); + } + fz_catch(doc->ctx) + { fz_warn(doc->ctx, "cannot find image source"); return; } @@ -116,13 +109,13 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, } fz_catch(doc->ctx) { + fz_warn(doc->ctx, "cannot decode image resource"); xps_free_part(doc, part); - fz_error_handle(-1, "cannot decode image resource"); return; } + xps_free_part(doc, part); xps_parse_tiling_brush(doc, ctm, area, base_uri, dict, root, xps_paint_image_brush, image); fz_drop_pixmap(doc->ctx, image); - xps_free_part(doc, part); } diff --git a/xps/xps_outline.c b/xps/xps_outline.c index 48eb100b..ae43a4e8 100644 --- a/xps/xps_outline.c +++ b/xps/xps_outline.c @@ -83,23 +83,29 @@ xps_load_document_structure(xps_document *doc, xps_fixdoc *fixdoc) fz_outline *outline; part = xps_read_part(doc, fixdoc->outline); - if (!part) - return NULL; - - root = xml_parse_document(doc->ctx, part->data, part->size); - if (!root) { - fz_error_handle(-1, "cannot parse document structure part '%s'", part->name); + fz_try(doc->ctx) + { + root = xml_parse_document(doc->ctx, part->data, part->size); + } + fz_catch(doc->ctx) + { xps_free_part(doc, part); - return NULL; + fz_rethrow(doc->ctx); } + xps_free_part(doc, part); - outline = xps_parse_document_structure(doc, root); - + fz_try(doc->ctx) + { + outline = xps_parse_document_structure(doc, root); + } + fz_catch(doc->ctx) + { + xml_free_element(doc->ctx, root); + fz_rethrow(doc->ctx); + } xml_free_element(doc->ctx, root); - xps_free_part(doc, part); return outline; - } fz_outline * @@ -111,13 +117,11 @@ xps_load_outline(xps_document *doc) for (fixdoc = doc->first_fixdoc; fixdoc; fixdoc = fixdoc->next) { if (fixdoc->outline) { outline = xps_load_document_structure(doc, fixdoc); - if (outline) { - if (!head) - head = outline; - else - tail->next = outline; - tail = outline; - } + if (!head) + head = outline; + else + tail->next = outline; + tail = outline; } } return head; diff --git a/xps/xps_png.c b/xps/xps_png.c index d9e952a7..a396b433 100644 --- a/xps/xps_png.c +++ b/xps/xps_png.c @@ -219,13 +219,13 @@ png_deinterlace(struct info *info, int *passw, int *passh, int *passofs) info->samples = output; } -static int +static void png_read_ihdr(struct info *info, unsigned char *p, int size) { int color, compression, filter; if (size != 13) - return fz_error_make("IHDR chunk is the wrong size"); + fz_throw(info->ctx, "IHDR chunk is the wrong size"); info->width = getint(p + 0); info->height = getint(p + 4); @@ -237,21 +237,21 @@ png_read_ihdr(struct info *info, unsigned char *p, int size) info->interlace = p[12]; if (info->width <= 0) - return fz_error_make("image width must be > 0"); + fz_throw(info->ctx, "image width must be > 0"); if (info->height <= 0) - return fz_error_make("image height must be > 0"); + fz_throw(info->ctx, "image height must be > 0"); if (info->depth != 1 && info->depth != 2 && info->depth != 4 && info->depth != 8 && info->depth != 16) - return fz_error_make("image bit depth must be one of 1, 2, 4, 8, 16"); + fz_throw(info->ctx, "image bit depth must be one of 1, 2, 4, 8, 16"); if (color == 2 && info->depth < 8) - return fz_error_make("illegal bit depth for truecolor"); + fz_throw(info->ctx, "illegal bit depth for truecolor"); if (color == 3 && info->depth > 8) - return fz_error_make("illegal bit depth for indexed"); + fz_throw(info->ctx, "illegal bit depth for indexed"); if (color == 4 && info->depth < 8) - return fz_error_make("illegal bit depth for grayscale with alpha"); + fz_throw(info->ctx, "illegal bit depth for grayscale with alpha"); if (color == 6 && info->depth < 8) - return fz_error_make("illegal bit depth for truecolor with alpha"); + fz_throw(info->ctx, "illegal bit depth for truecolor with alpha"); info->indexed = 0; if (color == 0) /* gray */ @@ -268,26 +268,24 @@ png_read_ihdr(struct info *info, unsigned char *p, int size) info->n = 1; } else - return fz_error_make("unknown color type"); + fz_throw(info->ctx, "unknown color type"); if (compression != 0) - return fz_error_make("unknown compression method"); + fz_throw(info->ctx, "unknown compression method"); if (filter != 0) - return fz_error_make("unknown filter method"); + fz_throw(info->ctx, "unknown filter method"); if (info->interlace != 0 && info->interlace != 1) - return fz_error_make("interlace method not supported"); - - return fz_okay; + fz_throw(info->ctx, "interlace method not supported"); } -static int +static void png_read_plte(struct info *info, unsigned char *p, int size) { int n = size / 3; int i; if (n > 256 || n > (1 << info->depth)) - return fz_error_make("too many samples in palette"); + fz_throw(info->ctx, "too many samples in palette"); for (i = 0; i < n; i++) { @@ -295,11 +293,9 @@ png_read_plte(struct info *info, unsigned char *p, int size) info->palette[i * 4 + 1] = p[i * 3 + 1]; info->palette[i * 4 + 2] = p[i * 3 + 2]; } - - return fz_okay; } -static int +static void png_read_trns(struct info *info, unsigned char *p, int size) { int i; @@ -309,22 +305,20 @@ png_read_trns(struct info *info, unsigned char *p, int size) if (info->indexed) { if (size > 256 || size > (1 << info->depth)) - return fz_error_make("too many samples in transparency table"); + fz_throw(info->ctx, "too many samples in transparency table"); for (i = 0; i < size; i++) info->palette[i * 4 + 3] = p[i]; } else { if (size != info->n * 2) - return fz_error_make("tRNS chunk is the wrong size"); + fz_throw(info->ctx, "tRNS chunk is the wrong size"); for (i = 0; i < info->n; i++) info->trns[i] = (p[i * 2] << 8 | p[i * 2 + 1]) & ((1 << info->depth) - 1); } - - return fz_okay; } -static int +static void png_read_idat(struct info *info, unsigned char *p, int size, z_stream *stm) { int code; @@ -334,31 +328,28 @@ png_read_idat(struct info *info, unsigned char *p, int size, z_stream *stm) code = inflate(stm, Z_SYNC_FLUSH); if (code != Z_OK && code != Z_STREAM_END) - return fz_error_make("zlib error: %s", stm->msg); + fz_throw(info->ctx, "zlib error: %s", stm->msg); if (stm->avail_in != 0) { if (stm->avail_out == 0) - return fz_error_make("ran out of output before input"); - return fz_error_make("inflate did not consume buffer (%d remaining)", stm->avail_in); + fz_throw(info->ctx, "ran out of output before input"); + fz_throw(info->ctx, "inflate did not consume buffer (%d remaining)", stm->avail_in); } - - return fz_okay; } -static int +static void png_read_phys(struct info *info, unsigned char *p, int size) { if (size != 9) - return fz_error_make("pHYs chunk is the wrong size"); + fz_throw(info->ctx, "pHYs chunk is the wrong size"); if (p[8] == 1) { info->xres = getint(p) * 254 / 10000; info->yres = getint(p + 4) * 254 / 10000; } - return fz_okay; } -static int +static void png_read_image(struct info *info, unsigned char *p, int total) { int passw[7], passh[7], passofs[8]; @@ -373,7 +364,7 @@ png_read_image(struct info *info, unsigned char *p, int total) /* Read signature */ if (total < 8 + 12 || memcmp(p, png_signature, 8)) - return fz_error_make("not a png image (wrong signature)"); + fz_throw(info->ctx, "not a png image (wrong signature)"); p += 8; total -= 8; @@ -383,16 +374,12 @@ png_read_image(struct info *info, unsigned char *p, int total) size = getint(p); if (size + 12 > total) - return fz_error_make("premature end of data in png image"); + fz_throw(info->ctx, "premature end of data in png image"); if (!memcmp(p + 4, "IHDR", 4)) - { - code = png_read_ihdr(info, p + 8, size); - if (code) - return fz_error_note(code, "cannot read png header"); - } + png_read_ihdr(info, p + 8, size); else - return fz_error_make("png file must start with IHDR chunk"); + fz_throw(info->ctx, "png file must start with IHDR chunk"); p += size + 12; total -= size + 12; @@ -420,7 +407,7 @@ png_read_image(struct info *info, unsigned char *p, int total) code = inflateInit(&stm); if (code != Z_OK) - return fz_error_make("zlib error: %s", stm.msg); + fz_throw(info->ctx, "zlib error: %s", stm.msg); /* Read remaining chunks until IEND */ @@ -429,36 +416,16 @@ png_read_image(struct info *info, unsigned char *p, int total) size = getint(p); if (size + 12 > total) - return fz_error_make("premature end of data in png image"); + fz_throw(info->ctx, "premature end of data in png image"); if (!memcmp(p + 4, "PLTE", 4)) - { - code = png_read_plte(info, p + 8, size); - if (code) - return fz_error_note(code, "cannot read png palette"); - } - + png_read_plte(info, p + 8, size); if (!memcmp(p + 4, "tRNS", 4)) - { - code = png_read_trns(info, p + 8, size); - if (code) - return fz_error_note(code, "cannot read png transparency"); - } - + png_read_trns(info, p + 8, size); if (!memcmp(p + 4, "pHYs", 4)) - { - code = png_read_phys(info, p + 8, size); - if (code) - return fz_error_note(code, "cannot read png resolution"); - } - + png_read_phys(info, p + 8, size); if (!memcmp(p + 4, "IDAT", 4)) - { - code = png_read_idat(info, p + 8, size, &stm); - if (code) - return fz_error_note(code, "cannot read png image data"); - } - + png_read_idat(info, p + 8, size, &stm); if (!memcmp(p + 4, "IEND", 4)) break; @@ -468,7 +435,7 @@ png_read_image(struct info *info, unsigned char *p, int total) code = inflateEnd(&stm); if (code != Z_OK) - return fz_error_make("zlib error: %s", stm.msg); + fz_throw(info->ctx, "zlib error: %s", stm.msg); /* Apply prediction filter and deinterlacing */ @@ -476,8 +443,6 @@ png_read_image(struct info *info, unsigned char *p, int total) png_predict(info->samples, info->width, info->height, info->n, info->depth); else png_deinterlace(info, passw, passh, passofs); - - return fz_okay; } static fz_pixmap * @@ -541,14 +506,8 @@ xps_decode_png(fz_context *ctx, byte *p, int total) int stride; png.ctx = ctx; - fz_try(ctx) - { - png_read_image(&png, p, total); - } - fz_catch(ctx) - { - fz_throw(ctx, "cannot read png image"); - } + + png_read_image(&png, p, total); if (png.n == 3 || png.n == 4) colorspace = fz_device_rgb; diff --git a/xps/xps_resource.c b/xps/xps_resource.c index 4a084b29..3701f079 100644 --- a/xps/xps_resource.c +++ b/xps/xps_resource.c @@ -52,8 +52,8 @@ xps_resolve_resource_reference(xps_document *doc, xps_resource *dict, } } -static int -xps_parse_remote_resource_dictionary(xps_document *doc, xps_resource **dictp, char *base_uri, char *source_att) +static xps_resource * +xps_parse_remote_resource_dictionary(xps_document *doc, char *base_uri, char *source_att) { char part_name[1024]; char part_uri[1024]; @@ -61,28 +61,17 @@ xps_parse_remote_resource_dictionary(xps_document *doc, xps_resource **dictp, ch xps_part *part; xml_element *xml; char *s; - int code; /* External resource dictionaries MUST NOT reference other resource dictionaries */ xps_absolute_path(part_name, base_uri, source_att, sizeof part_name); part = xps_read_part(doc, part_name); - if (!part) - { - return fz_error_make("cannot find remote resource part '%s'", part_name); - } - xml = xml_parse_document(doc->ctx, part->data, part->size); - if (!xml) - { - xps_free_part(doc, part); - return fz_error_note(-1, "cannot parse xml"); - } + xps_free_part(doc, part); if (strcmp(xml_tag(xml), "ResourceDictionary")) { xml_free_element(doc->ctx, xml); - xps_free_part(doc, part); - return fz_error_make("expected ResourceDictionary element (found %s)", xml_tag(xml)); + fz_throw(doc->ctx, "expected ResourceDictionary element (found %s)", xml_tag(xml)); } fz_strlcpy(part_uri, part_name, sizeof part_uri); @@ -90,40 +79,24 @@ xps_parse_remote_resource_dictionary(xps_document *doc, xps_resource **dictp, ch if (s) s[1] = 0; - code = xps_parse_resource_dictionary(doc, &dict, part_uri, xml); - if (code) - { - xml_free_element(doc->ctx, xml); - xps_free_part(doc, part); - return fz_error_note(code, "cannot parse remote resource dictionary: %s", part_uri); - } - + dict = xps_parse_resource_dictionary(doc, part_uri, xml); dict->base_xml = xml; /* pass on ownership */ - xps_free_part(doc, part); - - *dictp = dict; - return fz_okay; + return dict; } -int -xps_parse_resource_dictionary(xps_document *doc, xps_resource **dictp, char *base_uri, xml_element *root) +xps_resource * +xps_parse_resource_dictionary(xps_document *doc, char *base_uri, xml_element *root) { xps_resource *head; xps_resource *entry; xml_element *node; char *source; char *key; - int code; source = xml_att(root, "Source"); if (source) - { - code = xps_parse_remote_resource_dictionary(doc, dictp, base_uri, source); - if (code) - return fz_error_note(code, "cannot parse remote resource dictionary"); - return fz_okay; - } + return xps_parse_remote_resource_dictionary(doc, base_uri, source); head = NULL; @@ -146,10 +119,9 @@ xps_parse_resource_dictionary(xps_document *doc, xps_resource **dictp, char *bas if (head) head->base_uri = fz_strdup(doc->ctx, base_uri); else - return fz_error_make("empty resource dictionary"); + fz_throw(doc->ctx, "empty resource dictionary"); - *dictp = head; - return fz_okay; + return head; } void diff --git a/xps/xps_tiff.c b/xps/xps_tiff.c index b9571465..38430710 100644 --- a/xps/xps_tiff.c +++ b/xps/xps_tiff.c @@ -12,6 +12,8 @@ struct tiff { + fz_context *ctx; + /* "file" */ byte *bp, *rp, *ep; @@ -56,7 +58,6 @@ struct tiff fz_colorspace *colorspace; byte *samples; int stride; - fz_context *ctx; }; enum @@ -134,56 +135,44 @@ static const byte bitrev[256] = 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; -static int +static void xps_decode_tiff_uncompressed(struct tiff *tiff, fz_stream *stm, byte *wp, int wlen) { - int n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); - if (n < 0) - return fz_error_note(n, "cannot read uncompressed strip"); - return fz_okay; } -static int +static void xps_decode_tiff_packbits(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_rld(chain); - int n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); - if (n < 0) - return fz_error_note(n, "cannot read packbits strip"); - return fz_okay; } -static int +static void xps_decode_tiff_lzw(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_lzwd(chain, NULL); - int n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); - if (n < 0) - return fz_error_note(n, "cannot read lzw strip"); - return fz_okay; } -static int + +static void xps_decode_tiff_flate(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_flated(chain); - int n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); - if (n < 0) - return fz_error_note(n, "cannot read flate strip"); - return fz_okay; } -static int +static void xps_decode_tiff_fax(struct tiff *tiff, int comp, fz_stream *chain, byte *wp, int wlen) { + fz_context *ctx = tiff->ctx; fz_stream *stm; fz_obj *params; fz_obj *columns, *rows, *black_is_1, *k, *encoded_byte_align; - int n; - fz_context *ctx = tiff->ctx; columns = fz_new_int(ctx, tiff->imagewidth); rows = fz_new_int(ctx, tiff->imagelength); @@ -205,24 +194,17 @@ xps_decode_tiff_fax(struct tiff *tiff, int comp, fz_stream *chain, byte *wp, int fz_drop_obj(encoded_byte_align); stm = fz_open_faxd(chain, params); - n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); fz_drop_obj(params); - - if (n < 0) - return fz_error_note(n, "cannot read fax strip"); - return fz_okay; } -static int +static void xps_decode_tiff_jpeg(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_dctd(chain, NULL); - int n = fz_read(stm, wp, wlen); + fz_read(stm, wp, wlen); fz_close(stm); - if (n < 0) - return fz_error_note(n, "cannot read jpeg strip"); - return fz_okay; } static inline int getcomp(byte *line, int x, int bpc) @@ -299,7 +281,7 @@ xps_invert_tiff(byte *line, int width, int comps, int bits, int alpha) } } -static int +static void xps_expand_tiff_colormap(struct tiff *tiff) { int maxval = 1 << tiff->bitspersample; @@ -313,10 +295,10 @@ xps_expand_tiff_colormap(struct tiff *tiff) /* image can be with or without extrasamples: comps is 1 or 2 */ if (tiff->samplesperpixel != 1 && tiff->samplesperpixel != 2) - return fz_error_make("invalid number of samples for RGBPal"); + fz_throw(tiff->ctx, "invalid number of samples for RGBPal"); if (tiff->bitspersample != 4 && tiff->bitspersample != 8) - return fz_error_make("invalid number of bits for RGBPal"); + fz_throw(tiff->ctx, "invalid number of bits for RGBPal"); stride = tiff->imagewidth * (tiff->samplesperpixel + 2); @@ -352,14 +334,12 @@ xps_expand_tiff_colormap(struct tiff *tiff) tiff->bitspersample = 8; tiff->stride = stride; tiff->samples = samples; - return fz_okay; } -static int +static void xps_decode_tiff_strips(struct tiff *tiff) { fz_stream *stm; - int error; /* switch on compression to create a filter */ /* feed each strip to the filter */ @@ -376,10 +356,10 @@ xps_decode_tiff_strips(struct tiff *tiff) unsigned i; if (!tiff->rowsperstrip || !tiff->stripoffsets || !tiff->rowsperstrip) - return fz_error_make("no image data in tiff; maybe it is tiled"); + fz_throw(tiff->ctx, "no image data in tiff; maybe it is tiled"); if (tiff->planar != 1) - return fz_error_make("image data is not in chunky format"); + fz_throw(tiff->ctx, "image data is not in chunky format"); tiff->stride = (tiff->imagewidth * tiff->samplesperpixel * tiff->bitspersample + 7) / 8; @@ -405,7 +385,7 @@ xps_decode_tiff_strips(struct tiff *tiff) tiff->colorspace = fz_device_rgb; break; default: - return fz_error_make("unknown photometric: %d", tiff->photometric); + fz_throw(tiff->ctx, "unknown photometric: %d", tiff->photometric); } switch (tiff->resolutionunit) @@ -446,7 +426,7 @@ xps_decode_tiff_strips(struct tiff *tiff) wlen = tiff->samples + tiff->stride * tiff->imagelength - wp; if (rp + rlen > tiff->ep) - return fz_error_make("strip extends beyond the end of the file"); + fz_throw(tiff->ctx, "strip extends beyond the end of the file"); /* the bits are in un-natural order */ if (tiff->fillorder == 2) @@ -459,39 +439,36 @@ xps_decode_tiff_strips(struct tiff *tiff) switch (tiff->compression) { case 1: - error = xps_decode_tiff_uncompressed(tiff, stm, wp, wlen); + xps_decode_tiff_uncompressed(tiff, stm, wp, wlen); break; case 2: - error = xps_decode_tiff_fax(tiff, 2, stm, wp, wlen); + xps_decode_tiff_fax(tiff, 2, stm, wp, wlen); break; case 3: - error = xps_decode_tiff_fax(tiff, 3, stm, wp, wlen); + xps_decode_tiff_fax(tiff, 3, stm, wp, wlen); break; case 4: - error = xps_decode_tiff_fax(tiff, 4, stm, wp, wlen); + xps_decode_tiff_fax(tiff, 4, stm, wp, wlen); break; case 5: - error = xps_decode_tiff_lzw(tiff, stm, wp, wlen); + xps_decode_tiff_lzw(tiff, stm, wp, wlen); break; case 6: - error = fz_error_make("deprecated JPEG in TIFF compression not supported"); + fz_throw(tiff->ctx, "deprecated JPEG in TIFF compression not supported"); break; case 7: - error = xps_decode_tiff_jpeg(tiff, stm, wp, wlen); + xps_decode_tiff_jpeg(tiff, stm, wp, wlen); break; case 8: - error = xps_decode_tiff_flate(tiff, stm, wp, wlen); + xps_decode_tiff_flate(tiff, stm, wp, wlen); break; case 32773: - error = xps_decode_tiff_packbits(tiff, stm, wp, wlen); + xps_decode_tiff_packbits(tiff, stm, wp, wlen); break; default: - error = fz_error_make("unknown TIFF compression: %d", tiff->compression); + fz_throw(tiff->ctx, "unknown TIFF compression: %d", tiff->compression); } - if (error) - return fz_error_note(error, "cannot decode strip %d", row / tiff->rowsperstrip); - /* scramble the bits back into original order */ if (tiff->fillorder == 2) for (i = 0; i < rlen; i++) @@ -514,11 +491,7 @@ xps_decode_tiff_strips(struct tiff *tiff) /* RGBPal */ if (tiff->photometric == 3 && tiff->colormap) - { - error = xps_expand_tiff_colormap(tiff); - if (error) - return fz_error_note(error, "cannot expand colormap"); - } + xps_expand_tiff_colormap(tiff); /* WhiteIsZero .. invert */ if (tiff->photometric == 0) @@ -530,8 +503,6 @@ xps_decode_tiff_strips(struct tiff *tiff) p += tiff->stride; } } - - return fz_okay; } static inline int readbyte(struct tiff *tiff) @@ -596,7 +567,7 @@ xps_read_tiff_tag_value(unsigned *p, struct tiff *tiff, unsigned type, unsigned } } -static int +static void xps_read_tiff_tag(struct tiff *tiff, unsigned offset) { unsigned tag; @@ -707,14 +678,12 @@ xps_read_tiff_tag(struct tiff *tiff, unsigned offset) case TileLength: case TileOffsets: case TileByteCounts: - return fz_error_make("tiled tiffs not supported"); + fz_throw(tiff->ctx, "tiled tiffs not supported"); default: /* printf("unknown tag: %d t=%d n=%d\n", tag, type, count); */ break; } - - return fz_okay; } static void @@ -729,14 +698,13 @@ xps_swap_byte_order(byte *buf, int n) } } -static int +static void xps_decode_tiff_header(struct tiff *tiff, byte *buf, int len) { unsigned version; unsigned offset; unsigned count; unsigned i; - int error; memset(tiff, 0, sizeof(struct tiff)); @@ -765,12 +733,12 @@ xps_decode_tiff_header(struct tiff *tiff, byte *buf, int len) tiff->order = TII; tiff->order = readshort(tiff); if (tiff->order != TII && tiff->order != TMM) - return fz_error_make("not a TIFF file, wrong magic marker"); + fz_throw(tiff->ctx, "not a TIFF file, wrong magic marker"); /* check version */ version = readshort(tiff); if (version != 42) - return fz_error_make("not a TIFF file, wrong version marker"); + fz_throw(tiff->ctx, "not a TIFF file, wrong version marker"); /* get offset of IFD */ offset = readlong(tiff); @@ -786,13 +754,9 @@ xps_decode_tiff_header(struct tiff *tiff, byte *buf, int len) offset += 2; for (i = 0; i < count; i++) { - error = xps_read_tiff_tag(tiff, offset); - if (error) - return fz_error_note(error, "cannot read TIFF header tag"); + xps_read_tiff_tag(tiff, offset); offset += 12; } - - return fz_okay; } fz_pixmap * @@ -803,7 +767,6 @@ xps_decode_tiff(fz_context *ctx, byte *buf, int len) tiff.ctx = ctx; xps_decode_tiff_header(&tiff, buf, len); - /* RJW: "cannot decode tiff header" */ /* Decode the image strips */ @@ -811,14 +774,11 @@ xps_decode_tiff(fz_context *ctx, byte *buf, int len) tiff.rowsperstrip = tiff.imagelength; xps_decode_tiff_strips(&tiff); - /* RJW: "cannot decode image data" */ /* Byte swap 16-bit images to big endian if necessary */ if (tiff.bitspersample == 16) - { if (tiff.order == TII) xps_swap_byte_order(tiff.samples, tiff.imagewidth * tiff.imagelength * tiff.samplesperpixel); - } /* Expand into fz_pixmap struct */ diff --git a/xps/xps_tile.c b/xps/xps_tile.c index f6a2143f..04c613a4 100644 --- a/xps/xps_tile.c +++ b/xps/xps_tile.c @@ -250,7 +250,6 @@ xps_parse_canvas(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *new_dict = NULL; xml_element *node; char *opacity_mask_uri; - int code; char *transform_att; char *clip_att; @@ -272,14 +271,9 @@ xps_parse_canvas(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, { if (!strcmp(xml_tag(node), "Canvas.Resources") && xml_down(node)) { - code = xps_parse_resource_dictionary(doc, &new_dict, base_uri, xml_down(node)); - if (code) - fz_error_handle(code, "cannot load Canvas.Resources"); - else - { - new_dict->parent = dict; - dict = new_dict; - } + new_dict = xps_parse_resource_dictionary(doc, base_uri, xml_down(node)); + new_dict->parent = dict; + dict = new_dict; } if (!strcmp(xml_tag(node), "Canvas.RenderTransform")) @@ -329,7 +323,6 @@ xps_parse_fixed_page(xps_document *doc, fz_matrix ctm, xps_page *page) char base_uri[1024]; fz_rect area; char *s; - int code; fz_strlcpy(base_uri, page->name, sizeof base_uri); s = strrchr(base_uri, '/'); @@ -349,16 +342,10 @@ xps_parse_fixed_page(xps_document *doc, fz_matrix ctm, xps_page *page) for (node = xml_down(page->root); node; node = xml_next(node)) { if (!strcmp(xml_tag(node), "FixedPage.Resources") && xml_down(node)) - { - code = xps_parse_resource_dictionary(doc, &dict, base_uri, xml_down(node)); - if (code) - fz_error_handle(code, "cannot load FixedPage.Resources"); - } + dict = xps_parse_resource_dictionary(doc, base_uri, xml_down(node)); xps_parse_element(doc, ctm, area, base_uri, dict, node); } if (dict) - { xps_free_resource_dictionary(doc, dict); - } } diff --git a/xps/xps_xml.c b/xps/xps_xml.c index d92804af..b6dc63c3 100644 --- a/xps/xps_xml.c +++ b/xps/xps_xml.c @@ -377,10 +377,8 @@ xml_parse_document(fz_context *ctx, unsigned char *s, int n) p = convert_to_utf8(ctx, s, n); error = xml_parse_document_imp(&parser, p); - if (error) { + if (error) fz_throw(ctx, "%s", error); - return NULL; - } if (p != (char*)s) fz_free(ctx, p); diff --git a/xps/xps_zip.c b/xps/xps_zip.c index f02bf33e..f8099296 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -80,7 +80,7 @@ xps_find_zip_entry(xps_document *doc, char *name) return NULL; } -static int +static void xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) { z_stream stream; @@ -94,7 +94,7 @@ xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) sig = getlong(doc->file); if (sig != ZIP_LOCAL_FILE_SIG) - return fz_error_make("wrong zip local file signature (0x%x)", sig); + fz_throw(doc->ctx, "wrong zip local file signature (0x%x)", sig); version = getshort(doc->file); general = getshort(doc->file); @@ -130,32 +130,30 @@ xps_read_zip_entry(xps_document *doc, xps_entry *ent, unsigned char *outbuf) code = inflateInit2(&stream, -15); if (code != Z_OK) - return fz_error_make("zlib inflateInit2 error: %s", stream.msg); + fz_throw(doc->ctx, "zlib inflateInit2 error: %s", stream.msg); code = inflate(&stream, Z_FINISH); if (code != Z_STREAM_END) { inflateEnd(&stream); - return fz_error_make("zlib inflate error: %s", stream.msg); + fz_throw(doc->ctx, "zlib inflate error: %s", stream.msg); } code = inflateEnd(&stream); if (code != Z_OK) - return fz_error_make("zlib inflateEnd error: %s", stream.msg); + fz_throw(doc->ctx, "zlib inflateEnd error: %s", stream.msg); fz_free(doc->ctx, inbuf); } else { - return fz_error_make("unknown compression method (%d)", method); + fz_throw(doc->ctx, "unknown compression method (%d)", method); } - - return fz_okay; } /* * Read the central directory in a zip file. */ -static int +static void xps_read_zip_dir(xps_document *doc, int start_offset) { int sig; @@ -167,7 +165,7 @@ xps_read_zip_dir(xps_document *doc, int start_offset) sig = getlong(doc->file); if (sig != ZIP_END_OF_CENTRAL_DIRECTORY_SIG) - return fz_error_make("wrong zip end of central directory signature (0x%x)", sig); + fz_throw(doc->ctx, "wrong zip end of central directory signature (0x%x)", sig); (void) getshort(doc->file); /* this disk */ (void) getshort(doc->file); /* start disk */ @@ -185,7 +183,7 @@ xps_read_zip_dir(xps_document *doc, int start_offset) { sig = getlong(doc->file); if (sig != ZIP_CENTRAL_DIRECTORY_SIG) - return fz_error_make("wrong zip central directory signature (0x%x)", sig); + fz_throw(doc->ctx, "wrong zip central directory signature (0x%x)", sig); (void) getshort(doc->file); /* version made by */ (void) getshort(doc->file); /* version to extract */ @@ -213,11 +211,9 @@ xps_read_zip_dir(xps_document *doc, int start_offset) } qsort(doc->zip_table, count, sizeof(xps_entry), xps_compare_entries); - - return fz_okay; } -static int +static void xps_find_and_read_zip_dir(xps_document *doc) { unsigned char buf[512]; @@ -233,19 +229,20 @@ xps_find_and_read_zip_dir(xps_document *doc) while (back < maxback) { fz_seek(doc->file, file_size - back, 0); - n = fz_read(doc->file, buf, sizeof buf); - if (n < 0) - return fz_error_make("cannot read end of central directory"); - for (i = n - 4; i > 0; i--) + { if (!memcmp(buf + i, "PK\5\6", 4)) - return xps_read_zip_dir(doc, file_size - back + i); + { + xps_read_zip_dir(doc, file_size - back + i); + return; + } + } back += sizeof buf - 4; } - return fz_error_make("cannot find end of central directory"); + fz_throw(doc->ctx, "cannot find end of central directory"); } /* @@ -309,9 +306,25 @@ xps_read_zip_part(xps_document *doc, char *partname) return part; } + fz_throw(doc->ctx, "cannot find part '%s'", partname); return NULL; } +static int +xps_has_zip_part(xps_document *doc, char *name) +{ + char buf[2048]; + if (xps_find_zip_entry(doc, name)) + return 1; + sprintf(buf, "%s/[0].piece", name); + if (xps_find_zip_entry(doc, buf)); + return 1; + sprintf(buf, "%s/[0].last.piece", name); + if (xps_find_zip_entry(doc, buf)); + return 1; + return 0; +} + /* * Read and interleave split parts from files in the directory. */ @@ -371,6 +384,8 @@ xps_read_dir_part(xps_document *doc, char *name) else sprintf(buf, "%s%s/[%d].last.piece", doc->directory, name, i); file = fopen(buf, "rb"); + if (!file) + fz_throw(doc->ctx, "cannot open file '%s'", buf); n = fread(part->data + offset, 1, size - offset, file); offset += n; fclose(file); @@ -378,9 +393,41 @@ xps_read_dir_part(xps_document *doc, char *name) return part; } + fz_throw(doc->ctx, "cannot find part '%s'", name); return NULL; } +static int +file_exists(xps_document *doc, char *name) +{ + char buf[2048]; + FILE *file; + fz_strlcpy(buf, doc->directory, sizeof buf); + fz_strlcat(buf, name, sizeof buf); + file = fopen(buf, "rb"); + if (file) + { + fclose(file); + return 1; + } + return 0; +} + +static int +xps_has_dir_part(xps_document *doc, char *name) +{ + char buf[2048]; + if (file_exists(doc, name)) + return 1; + sprintf(buf, "%s/[0].piece", name); + if (file_exists(doc, buf)); + return 1; + sprintf(buf, "%s/[0].last.piece", name); + if (file_exists(doc, buf)); + return 1; + return 0; +} + xps_part * xps_read_part(xps_document *doc, char *partname) { @@ -389,6 +436,14 @@ xps_read_part(xps_document *doc, char *partname) return xps_read_zip_part(doc, partname); } +int +xps_has_part(xps_document *doc, char *partname) +{ + if (doc->directory) + return xps_has_dir_part(doc, partname); + return xps_has_zip_part(doc, partname); +} + static xps_document * xps_open_directory(fz_context *ctx, char *directory) { @@ -397,8 +452,8 @@ xps_open_directory(fz_context *ctx, char *directory) doc = fz_malloc(ctx, sizeof(xps_document)); memset(doc, 0, sizeof *doc); - doc->directory = fz_strdup(ctx, directory); doc->ctx = ctx; + doc->directory = fz_strdup(ctx, directory); fz_try(ctx) { @@ -407,7 +462,7 @@ xps_open_directory(fz_context *ctx, char *directory) fz_catch(ctx) { xps_free_context(doc); - fz_throw(ctx, "cannot read page list"); + fz_rethrow(ctx); } return doc; @@ -416,8 +471,8 @@ xps_open_directory(fz_context *ctx, char *directory) xps_document * xps_open_stream(fz_stream *file) { - xps_document *doc; fz_context *ctx = file->ctx; + xps_document *doc; doc = fz_malloc(ctx, sizeof(xps_document)); memset(doc, 0, sizeof *doc); @@ -428,21 +483,12 @@ xps_open_stream(fz_stream *file) fz_try(ctx) { xps_find_and_read_zip_dir(doc); - } - fz_catch(ctx) - { - xps_free_context(doc); - fz_throw(ctx, "cannot read zip central directory"); - } - - fz_try(ctx) - { xps_read_page_list(doc); } fz_catch(ctx) { xps_free_context(doc); - fz_throw(ctx, "cannot read page list"); + fz_rethrow(ctx); } return doc; |