diff options
47 files changed, 2876 insertions, 3113 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c index c992b504..5e235ddf 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -100,20 +100,25 @@ void pdfapp_invert(pdfapp_t *app, fz_bbox rect) static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd) { - fz_error error; fz_stream *file; char *password = ""; fz_obj *obj; fz_obj *info; + fz_context *ctx = app->ctx; /* * Open PDF and load xref table */ - file = fz_open_fd(app->ctx, fd); - error = pdf_open_xref_with_stream(&app->xref, file, NULL); - if (error) - pdfapp_error(app, fz_error_note(error, "cannot open document '%s'", filename)); + file = fz_open_fd(ctx, fd); + fz_try(ctx) + { + app->xref = pdf_open_xref_with_stream(file, NULL); + } + fz_catch(ctx) + { + pdfapp_error(app, fz_error_note(1, "cannot open document '%s'", filename)); + } fz_close(file); /* @@ -150,29 +155,38 @@ static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd) { obj = fz_dict_gets(info, "Title"); if (obj) - app->doctitle = pdf_to_utf8(app->ctx, obj); + app->doctitle = pdf_to_utf8(ctx, obj); } /* * Start at first page */ - error = pdf_load_page_tree(app->xref); - if (error) - pdfapp_error(app, fz_error_note(error, "cannot load page tree")); + fz_try(ctx) + { + pdf_load_page_tree(app->xref); + } + fz_catch(ctx) + { + pdfapp_error(app, fz_error_note(1, "cannot load page tree")); + } app->pagecount = pdf_count_pages(app->xref); } static void pdfapp_open_xps(pdfapp_t *app, char *filename, int fd) { - fz_error error; fz_stream *file; file = fz_open_fd(app->ctx, fd); - error = xps_open_stream(&app->xps, file); - if (error) - pdfapp_error(app, fz_error_note(error, "cannot open document '%s'", filename)); + fz_try(app->ctx) + { + app->xps = xps_open_stream(file); + } + fz_catch(app->ctx) + { + pdfapp_error(app, fz_error_note(-1, "cannot open document '%s'", filename)); + } fz_close(file); app->doctitle = filename; @@ -282,12 +296,16 @@ static void pdfapp_panview(pdfapp_t *app, int newx, int newy) static void pdfapp_loadpage_pdf(pdfapp_t *app) { pdf_page *page; - fz_error error; fz_device *mdev; - error = pdf_load_page(&page, app->xref, app->pageno - 1); - if (error) - pdfapp_error(app, error); + fz_try(app->ctx) + { + page = pdf_load_page(app->xref, app->pageno - 1); + } + fz_catch(app->ctx) + { + pdfapp_error(app, 1); + } app->page_bbox = page->mediabox; app->page_rotate = page->rotate; @@ -297,11 +315,13 @@ static void pdfapp_loadpage_pdf(pdfapp_t *app) /* Create display list */ app->page_list = fz_new_display_list(app->ctx); mdev = fz_new_list_device(app->ctx, app->page_list); - error = pdf_run_page(app->xref, page, mdev, fz_identity); - if (error) + fz_try(app->ctx) { - error = fz_error_note(error, "cannot draw page %d in '%s'", app->pageno, app->doctitle); - pdfapp_error(app, error); + pdf_run_page(app->xref, page, mdev, fz_identity); + } + fz_catch(app->ctx) + { + pdfapp_error(app, fz_error_note(-1, "cannot draw page %d in '%s'", app->pageno, app->doctitle)); } fz_free_device(mdev); @@ -314,11 +334,15 @@ static void pdfapp_loadpage_xps(pdfapp_t *app) { xps_page *page; fz_device *mdev; - fz_error error; - error = xps_load_page(&page, app->xps, app->pageno - 1); - if (error) - pdfapp_error(app, fz_error_note(error, "cannot load page %d in file '%s'", app->pageno, app->doctitle)); + fz_try(app->ctx) + { + page = xps_load_page(app->xps, app->pageno - 1); + } + fz_catch(app->ctx) + { + pdfapp_error(app, fz_error_note(1, "cannot load page %d in file '%s'", app->pageno, app->doctitle)); + } app->page_bbox.x0 = 0; app->page_bbox.y0 = 0; diff --git a/apps/pdfclean.c b/apps/pdfclean.c index 4b5fa139..4b76afa2 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -287,13 +287,17 @@ static void renumberobjs(void) static void retainpages(int argc, char **argv) { - fz_error error; fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent; /* Load the old page tree */ - error = pdf_load_page_tree(xref); - if (error) - die(fz_error_note(error, "cannot load page tree")); + fz_try(xref->ctx) + { + pdf_load_page_tree(xref); + } + fz_catch(xref->ctx) + { + die(fz_error_note(1, "cannot load page tree")); + } /* Keep only pages/type entry to avoid references to unretained pages */ oldroot = fz_dict_gets(xref->trailer, "Root"); @@ -377,7 +381,6 @@ static void retainpages(int argc, char **argv) static void preloadobjstms(void) { - fz_error error; fz_obj *obj; int num; @@ -385,9 +388,14 @@ static void preloadobjstms(void) { if (xref->table[num].type == 'o') { - error = pdf_load_object(&obj, xref, num, 0); - if (error) - die(error); + fz_try(ctx) + { + obj = pdf_load_object(xref, num, 0); + } + fz_catch(ctx) + { + die(1); + } fz_drop_obj(obj); } } @@ -488,13 +496,17 @@ static void addhexfilter(fz_obj *dict) static void copystream(fz_obj *obj, int num, int gen) { - fz_error error; fz_buffer *buf, *tmp; fz_obj *newlen; - error = pdf_load_raw_stream(&buf, xref, num, gen); - if (error) - die(error); + fz_try(ctx) + { + buf = pdf_load_raw_stream(xref, num, gen); + } + fz_catch(ctx) + { + die(1); + } if (doascii && isbinarystream(buf)) { @@ -520,13 +532,17 @@ static void copystream(fz_obj *obj, int num, int gen) static void expandstream(fz_obj *obj, int num, int gen) { - fz_error error; fz_buffer *buf, *tmp; fz_obj *newlen; - error = pdf_load_stream(&buf, xref, num, gen); - if (error) - die(error); + fz_try(ctx) + { + buf = pdf_load_stream(xref, num, gen); + } + fz_catch(ctx) + { + die(1); + } fz_dict_dels(obj, "Filter"); fz_dict_dels(obj, "DecodeParms"); @@ -555,13 +571,17 @@ static void expandstream(fz_obj *obj, int num, int gen) static void writeobject(int num, int gen) { - fz_error error; fz_obj *obj; fz_obj *type; - error = pdf_load_object(&obj, xref, num, gen); - if (error) - die(error); + fz_try(ctx) + { + obj = pdf_load_object(xref, num, gen); + } + fz_catch(ctx) + { + die(1); + } /* skip ObjStm and XRef objects */ if (fz_is_dict(obj)) @@ -686,7 +706,6 @@ static void writepdf(void) int main(int argc, char **argv) { - fz_error error; char *infile; char *outfile = "out.pdf"; char *password = ""; @@ -724,9 +743,14 @@ int main(int argc, char **argv) if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); - error = pdf_open_xref(ctx, &xref, infile, password); - if (error) - die(fz_error_note(error, "cannot open input file '%s'", infile)); + fz_try(ctx) + { + xref = pdf_open_xref(ctx, infile, password); + } + fz_catch(ctx) + { + die(fz_error_note(1, "cannot open input file '%s'", infile)); + } out = fopen(outfile, "wb"); if (!out) diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c index c65ef059..af21b9ea 100644 --- a/apps/pdfdraw.c +++ b/apps/pdfdraw.c @@ -92,7 +92,6 @@ static int isrange(char *s) static void drawpage(pdf_xref *xref, int pagenum) { - fz_error error; pdf_page *page; fz_display_list *list; fz_device *dev; @@ -104,9 +103,14 @@ static void drawpage(pdf_xref *xref, int pagenum) start = gettime(); } - error = pdf_load_page(&page, xref, pagenum - 1); - if (error) - die(fz_error_note(error, "cannot load page %d in file '%s'", pagenum, filename)); + fz_try(ctx) + { + page = pdf_load_page(xref, pagenum - 1); + } + fz_catch(ctx) + { + die(fz_error_note(1, "cannot load page %d in file '%s'", pagenum, filename)); + } list = NULL; @@ -114,9 +118,14 @@ static void drawpage(pdf_xref *xref, int pagenum) { list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, list); - error = pdf_run_page(xref, page, dev, fz_identity); - if (error) - die(fz_error_note(error, "cannot draw page %d in file '%s'", pagenum, filename)); + fz_try(ctx) + { + pdf_run_page(xref, page, dev, fz_identity); + } + fz_catch(ctx) + { + die(fz_error_note(1, "cannot draw page %d in file '%s'", pagenum, filename)); + } fz_free_device(dev); } @@ -193,15 +202,15 @@ static void drawpage(pdf_xref *xref, int pagenum) char buf[512]; sprintf(buf, output, pagenum); if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm")) - fz_write_pnm(pix, buf); + fz_write_pnm(ctx, pix, buf); else if (strstr(output, ".pam")) - fz_write_pam(pix, buf, savealpha); + fz_write_pam(ctx, pix, buf, savealpha); else if (strstr(output, ".png")) fz_write_png(ctx, pix, buf, savealpha); else if (strstr(output, ".pbm")) { fz_halftone *ht = fz_get_default_halftone(ctx, 1); fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, ht); - fz_write_pbm(bit, buf); + fz_write_pbm(ctx, bit, buf); fz_drop_bitmap(ctx, bit); fz_drop_halftone(ctx, ht); } @@ -376,13 +385,23 @@ int main(int argc, char **argv) { filename = argv[fz_optind++]; - error = pdf_open_xref(ctx, &xref, filename, password); - if (error) + fz_try(ctx) + { + xref = pdf_open_xref(ctx, filename, password); + } + fz_catch(ctx) + { die(fz_error_note(error, "cannot open document: %s", filename)); + } - error = pdf_load_page_tree(xref); - if (error) + fz_try(ctx) + { + pdf_load_page_tree(xref); + } + fz_catch(ctx) + { die(fz_error_note(error, "cannot load page tree: %s", filename)); + } if (showxml) printf("<document name=\"%s\">\n", filename); diff --git a/apps/pdfextract.c b/apps/pdfextract.c index 7e09226e..5aa5fa09 100644 --- a/apps/pdfextract.c +++ b/apps/pdfextract.c @@ -39,7 +39,6 @@ static int isfontdesc(fz_obj *obj) static void saveimage(int num) { - fz_error error; fz_pixmap *img; fz_obj *ref; char name[1024]; @@ -48,9 +47,14 @@ static void saveimage(int num) /* TODO: detect DCTD and save as jpeg */ - error = pdf_load_image(&img, xref, ref); - if (error) - die(error); + fz_try(ctx) + { + img = pdf_load_image(xref, ref); + } + fz_catch(ctx) + { + die(1); + } if (dorgb && img->colorspace && img->colorspace != fz_device_rgb) { @@ -71,7 +75,7 @@ static void saveimage(int num) { sprintf(name, "img-%04d.pam", num); printf("extracting image %s\n", name); - fz_write_pam(img, name, 0); + fz_write_pam(ctx, img, name, 0); } fz_drop_pixmap(ctx, img); @@ -80,7 +84,6 @@ static void saveimage(int num) static void savefont(fz_obj *dict, int num) { - fz_error error; char name[1024]; char *subtype; fz_buffer *buf; @@ -133,11 +136,14 @@ static void savefont(fz_obj *dict, int num) return; } - buf = fz_new_buffer(ctx, 0); - - error = pdf_load_stream(&buf, xref, fz_to_num(stream), fz_to_gen(stream)); - if (error) - die(error); + fz_try(ctx) + { + buf = pdf_load_stream(xref, fz_to_num(stream), fz_to_gen(stream)); + } + fz_catch(ctx) + { + die(1); + } sprintf(name, "%s-%04d.%s", fontname, num, ext); printf("extracting font %s\n", name); @@ -158,15 +164,19 @@ static void savefont(fz_obj *dict, int num) static void showobject(int num) { - fz_error error; fz_obj *obj; if (!xref) die(fz_error_make("no file specified")); - error = pdf_load_object(&obj, xref, num, 0); - if (error) - die(error); + fz_try(ctx) + { + obj = pdf_load_object(xref, num, 0); + } + fz_catch(ctx) + { + die(1); + } if (isimage(obj)) saveimage(num); @@ -178,7 +188,6 @@ static void showobject(int num) int main(int argc, char **argv) { - fz_error error; char *infile; char *password = ""; int c, o; @@ -202,9 +211,14 @@ int main(int argc, char **argv) if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); - error = pdf_open_xref(ctx, &xref, infile, password); - if (error) - die(fz_error_note(error, "cannot open input file '%s'", infile)); + fz_try(ctx) + { + xref = pdf_open_xref(ctx, infile, password); + } + fz_catch(ctx) + { + die(fz_error_note(1, "cannot open input file '%s'", infile)); + } if (fz_optind == argc) { diff --git a/apps/pdfshow.c b/apps/pdfshow.c index fb4bebd1..21c3a8e1 100644 --- a/apps/pdfshow.c +++ b/apps/pdfshow.c @@ -47,7 +47,6 @@ static void showxref(void) static void showpagetree(void) { - fz_error error; fz_obj *ref; int count; int i; @@ -57,9 +56,14 @@ static void showpagetree(void) if (!xref->page_len) { - error = pdf_load_page_tree(xref); - if (error) - die(fz_error_note(error, "cannot load page tree")); + fz_try(xref->ctx) + { + pdf_load_page_tree(xref); + } + fz_catch(xref->ctx) + { + die(fz_error_note(1, "cannot load page tree")); + } } count = pdf_count_pages(xref); @@ -96,19 +100,23 @@ static void showsafe(unsigned char *buf, int n) static void showstream(int num, int gen) { - fz_error error; fz_stream *stm; unsigned char buf[2048]; int n; showcolumn = 0; - if (showdecode) - error = pdf_open_stream(&stm, xref, num, gen); - else - error = pdf_open_raw_stream(&stm, xref, num, gen); - if (error) - die(error); + fz_try(xref->ctx) + { + if (showdecode) + stm = pdf_open_stream(xref, num, gen); + else + stm = pdf_open_raw_stream(xref, num, gen); + } + fz_catch(xref->ctx) + { + die(1); + } while (1) { @@ -128,15 +136,19 @@ static void showstream(int num, int gen) static void showobject(int num, int gen) { - fz_error error; fz_obj *obj; if (!xref) die(fz_error_make("no file specified")); - error = pdf_load_object(&obj, xref, num, gen); - if (error) - die(error); + fz_try(ctx) + { + obj = pdf_load_object(xref, num, gen); + } + fz_catch(ctx) + { + die(1); + } if (pdf_is_stream(xref, num, gen)) { @@ -166,7 +178,6 @@ static void showobject(int num, int gen) static void showgrep(char *filename) { - fz_error error; fz_obj *obj; int i; @@ -174,9 +185,14 @@ static void showgrep(char *filename) { if (xref->table[i].type == 'n' || xref->table[i].type == 'o') { - error = pdf_load_object(&obj, xref, i, 0); - if (error) - die(error); + fz_try(ctx) + { + obj = pdf_load_object(xref, i, 0); + } + fz_catch(ctx) + { + die(1); + } fz_sort_dict(obj); @@ -195,7 +211,6 @@ int main(int argc, char **argv) { char *password = NULL; /* don't throw errors if encrypted */ char *filename; - fz_error error; int c; while ((c = fz_getopt(argc, argv, "p:be")) != -1) @@ -218,9 +233,14 @@ int main(int argc, char **argv) if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); - error = pdf_open_xref(ctx, &xref, filename, password); - if (error) - die(fz_error_note(error, "cannot open document: %s", filename)); + fz_try(ctx) + { + xref = pdf_open_xref(ctx, filename, password); + } + fz_catch(ctx) + { + die(fz_error_note(1, "cannot open document: %s", filename)); + } if (fz_optind == argc) showtrailer(); diff --git a/apps/win_main.c b/apps/win_main.c index 24279e1d..a77347e4 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -241,7 +241,7 @@ dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetDlgItemTextA(hwnd, 0x13, "n/a"); } - info = fz_dict_gets(xref->ctx, xref->trailer, "Info"); + info = fz_dict_gets(xref->trailer, "Info"); if (!info) return TRUE; @@ -253,21 +253,21 @@ dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) fz_free(context, ucs); \ } - if ((obj = fz_dict_gets(xref->ctx, info, "Title"))) + if ((obj = fz_dict_gets(info, "Title"))) SETUCS(0x20); - if ((obj = fz_dict_gets(xref->ctx, info, "Author"))) + if ((obj = fz_dict_gets(info, "Author"))) SETUCS(0x21); - if ((obj = fz_dict_gets(xref->ctx, info, "Subject"))) + if ((obj = fz_dict_gets(info, "Subject"))) SETUCS(0x22); - if ((obj = fz_dict_gets(xref->ctx, info, "Keywords"))) + if ((obj = fz_dict_gets(info, "Keywords"))) SETUCS(0x23); - if ((obj = fz_dict_gets(xref->ctx, info, "Creator"))) + if ((obj = fz_dict_gets(info, "Creator"))) SETUCS(0x24); - if ((obj = fz_dict_gets(xref->ctx, info, "Producer"))) + if ((obj = fz_dict_gets(info, "Producer"))) SETUCS(0x25); - if ((obj = fz_dict_gets(xref->ctx, info, "CreationDate"))) + if ((obj = fz_dict_gets(info, "CreationDate"))) SETUCS(0x26); - if ((obj = fz_dict_gets(xref->ctx, info, "ModDate"))) + if ((obj = fz_dict_gets(info, "ModDate"))) SETUCS(0x27); return TRUE; @@ -858,7 +858,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShow fz_accelerate(); - ctx = fz_context_init(&fz_alloc_default); + ctx = fz_new_context(/*&fz_alloc_default*/); if (ctx == NULL) { fprintf(stderr, "Failed to init context"); diff --git a/apps/xpsdraw.c b/apps/xpsdraw.c index 4544d09c..19cf600a 100644 --- a/apps/xpsdraw.c +++ b/apps/xpsdraw.c @@ -20,7 +20,7 @@ int uselist = 1; fz_colorspace *colorspace; fz_glyph_cache *glyphcache; char *filename; -fz_context *fzctx; +fz_context *ctx; struct { int count, total; @@ -91,16 +91,20 @@ static void drawpage(xps_document *doc, int pagenum) fz_display_list *list; fz_device *dev; int start; - int code; if (showtime) { start = gettime(); } - code = xps_load_page(&page, doc, pagenum - 1); - if (code) - die(fz_error_note(code, "cannot load page %d in file '%s'", pagenum, filename)); + fz_try(doc->ctx) + { + page = xps_load_page(doc, pagenum - 1); + } + fz_catch(doc->ctx) + { + die(fz_error_note(1, "cannot load page %d in file '%s'", pagenum, filename)); + } list = NULL; @@ -183,9 +187,9 @@ static void drawpage(xps_document *doc, int pagenum) char buf[512]; sprintf(buf, output, pagenum); if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm")) - fz_write_pnm(pix, buf); + fz_write_pnm(doc->ctx, pix, buf); else if (strstr(output, ".pam")) - fz_write_pam(pix, buf, savealpha); + fz_write_pam(doc->ctx, pix, buf, savealpha); else if (strstr(output, ".png")) fz_write_png(doc->ctx, pix, buf, savealpha); } @@ -278,7 +282,6 @@ int main(int argc, char **argv) int grayscale = 0; int accelerate = 1; xps_document *doc; - int code; int c; while ((c = fz_getopt(argc, argv, "o:p:r:Aadgmtx5")) != -1) @@ -311,14 +314,14 @@ int main(int argc, char **argv) if (accelerate) fz_accelerate(); - fzctx = fz_new_context(); - if (fzctx == NULL) + ctx = fz_new_context(); + if (ctx == NULL) { fprintf(stderr, "failed to initialise context"); exit(1); } - glyphcache = fz_new_glyph_cache(fzctx); + glyphcache = fz_new_glyph_cache(ctx); colorspace = fz_device_rgb; if (grayscale) @@ -342,9 +345,14 @@ int main(int argc, char **argv) { filename = argv[fz_optind++]; - code = xps_open_file(fzctx, &doc, filename); - if (code) - die(fz_error_note(code, "cannot open document: %s", filename)); + fz_try(ctx) + { + doc = xps_open_file(ctx, filename); + } + fz_catch(ctx) + { + die(fz_error_note(-1, "cannot open document: %s", filename)); + } if (showxml) printf("<document name=\"%s\">\n", filename); @@ -368,8 +376,8 @@ int main(int argc, char **argv) printf("slowest page %d: %dms\n", timing.maxpage, timing.max); } - fz_free_glyph_cache(fzctx, glyphcache); - fz_free_context(fzctx); + fz_free_glyph_cache(ctx, glyphcache); + fz_free_context(ctx); return 0; } diff --git a/fitz/base_memory.c b/fitz/base_memory.c index 27474cc3..cf972542 100644 --- a/fitz/base_memory.c +++ b/fitz/base_memory.c @@ -36,6 +36,29 @@ fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size) } void * +fz_calloc(fz_context *ctx, unsigned int count, unsigned int size) +{ + void *p; + + if (count == 0 || size == 0) + return 0; + + if (count > UINT_MAX / size) + { + fprintf(stderr, "fatal error: out of memory (integer overflow)\n"); + abort(); + } + + p = calloc(count, size); + if (!p) + { + fprintf(stderr, "fatal error: out of memory\n"); + abort(); + } + return p; +} + +void * fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size) { void *np; diff --git a/fitz/base_object.c b/fitz/base_object.c index fae4b1b4..6307e5e0 100644 --- a/fitz/base_object.c +++ b/fitz/base_object.c @@ -795,16 +795,16 @@ fz_free_dict(fz_obj *obj) void fz_drop_obj(fz_obj *obj) { - assert(obj != NULL); - if (--obj->refs == 0) - { - if (obj->kind == FZ_ARRAY) - fz_free_array(obj); - else if (obj->kind == FZ_DICT) - fz_free_dict(obj); - else - fz_free(obj->ctx, obj); - } + if (obj == NULL) + return; + if (--obj->refs) + return; + if (obj->kind == FZ_ARRAY) + fz_free_array(obj); + else if (obj->kind == FZ_DICT) + fz_free_dict(obj); + else + fz_free(obj->ctx, obj); } /* Pretty printing objects */ diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c index d0d6cdef..5700a664 100644 --- a/fitz/filt_jpxd.c +++ b/fitz/filt_jpxd.c @@ -18,8 +18,8 @@ static void fz_opj_info_callback(const char *msg, void *client_data) /* fprintf(stderr, "openjpeg info: %s", msg); */ } -fz_error -fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *defcs) +fz_pixmap * +fz_load_jpx_image(fz_context *ctx, unsigned char *data, int size, fz_colorspace *defcs) { fz_pixmap *img; opj_event_mgr_t evtmgr; @@ -34,7 +34,7 @@ fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int si int x, y, k, v; if (size < 2) - return fz_error_make("not enough data to determine image format"); + fz_throw(ctx, "not enough data to determine image format"); /* Check for SOC marker -- if found we have a bare J2K stream */ if (data[0] == 0xFF && data[1] == 0x4F) @@ -61,16 +61,16 @@ fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int si opj_destroy_decompress(info); if (!jpx) - return fz_error_make("opj_decode failed"); + fz_throw(ctx, "opj_decode failed"); for (k = 1; k < jpx->numcomps; k++) { if (jpx->comps[k].w != jpx->comps[0].w) - return fz_error_make("image components have different width"); + fz_throw(ctx, "image components have different width"); if (jpx->comps[k].h != jpx->comps[0].h) - return fz_error_make("image components have different height"); + fz_throw(ctx, "image components have different height"); if (jpx->comps[k].prec != jpx->comps[0].prec) - return fz_error_make("image components have different precision"); + fz_throw(ctx, "image components have different precision"); } n = jpx->numcomps; @@ -112,7 +112,7 @@ fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int si if (!img) { opj_image_destroy(jpx); - return fz_error_make("out of memory"); + fz_throw(ctx, "out of memory"); } p = img->samples; @@ -148,6 +148,5 @@ fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int si opj_image_destroy(jpx); - *imgp = img; - return fz_okay; + return img; } diff --git a/fitz/fitz.h b/fitz/fitz.h index 048e1c35..aa9ff222 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -202,6 +202,7 @@ void fz_free_context(fz_context *ctx); /* The following throw exceptions on failure to allocate */ void *fz_malloc(fz_context *ctx, unsigned int size); void *fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size); +void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); void *fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size); char *fz_strdup(fz_context *ctx, char *s); @@ -545,7 +546,7 @@ void fz_seek(fz_stream *stm, int offset, int whence); int fz_read(fz_stream *stm, unsigned char *buf, int len); void fz_read_line(fz_stream *stm, char *buf, int max); -fz_error fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial); +fz_buffer *fz_read_all(fz_stream *stm, int initial); static inline int fz_read_byte(fz_stream *stm) { @@ -696,11 +697,11 @@ void fz_gamma_pixmap(fz_pixmap *pix, float gamma); fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h); fz_pixmap *fz_scale_pixmap_gridfit(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, int gridfit); -fz_error fz_write_pnm(fz_pixmap *pixmap, char *filename); -fz_error fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha); -fz_error fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); +void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); +void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); +void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); -fz_error fz_load_jpx_image(fz_context *ctx, fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *dcs); +fz_pixmap *fz_load_jpx_image(fz_context *ctx, unsigned char *data, int size, fz_colorspace *dcs); /* * Bitmaps have 1 component per bit. Only used for creating halftoned versions @@ -722,7 +723,7 @@ fz_bitmap *fz_keep_bitmap(fz_bitmap *bit); void fz_clear_bitmap(fz_bitmap *bit); void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); -fz_error fz_write_pbm(fz_bitmap *bitmap, char *filename); +void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename); /* * A halftone is a set of threshold tiles, one per component. Each threshold @@ -806,7 +807,7 @@ struct fz_font_s fz_buffer **t3procs; /* has 256 entries if used */ float *t3widths; /* has 256 entries if used */ void *t3xref; /* a pdf_xref for the callback */ - fz_error (*t3run)(void *xref, fz_obj *resources, fz_buffer *contents, + void (*t3run)(void *xref, fz_obj *resources, fz_buffer *contents, struct fz_device_s *dev, fz_matrix ctm); fz_rect bbox; @@ -818,8 +819,8 @@ struct fz_font_s fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix); -fz_error fz_new_font_from_memory(fz_context *ctx, fz_font **fontp, unsigned char *data, int len, int index); -fz_error fz_new_font_from_file(fz_context *ctx, fz_font **fontp, char *path, int index); +fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index); +fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index); fz_font *fz_keep_font(fz_font *font); void fz_drop_font(fz_context *ctx, fz_font *font); diff --git a/fitz/memento.c b/fitz/memento.c index a9885072..24e19e3a 100644 --- a/fitz/memento.c +++ b/fitz/memento.c @@ -487,8 +487,10 @@ static void Memento_event(void) globals.countdown = globals.paranoia; } - if (globals.sequence == globals.breakAt) + if (globals.sequence == globals.breakAt) { + fprintf(stderr, "Breaking at event %d\n", globals.breakAt); Memento_breakpoint(); + } } int Memento_breakAt(int event) diff --git a/fitz/res_bitmap.c b/fitz/res_bitmap.c index 3b13883b..02bb6f44 100644 --- a/fitz/res_bitmap.c +++ b/fitz/res_bitmap.c @@ -46,8 +46,8 @@ fz_clear_bitmap(fz_bitmap *bit) * Write bitmap to PBM file */ -fz_error -fz_write_pbm(fz_bitmap *bitmap, char *filename) +void +fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename) { FILE *fp; unsigned char *p; @@ -55,7 +55,7 @@ fz_write_pbm(fz_bitmap *bitmap, char *filename) fp = fopen(filename, "wb"); if (!fp) - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); assert(bitmap->n == 1); @@ -72,5 +72,4 @@ fz_write_pbm(fz_bitmap *bitmap, char *filename) } fclose(fp); - return fz_okay; } diff --git a/fitz/res_font.c b/fitz/res_font.c index 47e22ff1..a9a1fdf4 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -179,8 +179,8 @@ fz_finalize_freetype(fz_context *ctx) } } -fz_error -fz_new_font_from_file(fz_context *ctx, fz_font **fontp, char *path, int index) +fz_font * +fz_new_font_from_file(fz_context *ctx, char *path, int index) { FT_Face face; fz_error error; @@ -189,11 +189,11 @@ fz_new_font_from_file(fz_context *ctx, fz_font **fontp, char *path, int index) error = fz_init_freetype(ctx); if (error) - return fz_error_note(error, "cannot init freetype library"); + fz_throw(ctx, "cannot init freetype library"); fterr = FT_New_Face(fz_ftlib, path, index, &face); if (fterr) - return fz_error_make("freetype: cannot load font: %s", ft_error_string(fterr)); + fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr)); font = fz_new_font(ctx, face->family_name); font->ft_face = face; @@ -202,12 +202,11 @@ fz_new_font_from_file(fz_context *ctx, fz_font **fontp, char *path, int index) font->bbox.x1 = face->bbox.xMax * 1000 / face->units_per_EM; font->bbox.y1 = face->bbox.yMax * 1000 / face->units_per_EM; - *fontp = font; - return fz_okay; + return font; } -fz_error -fz_new_font_from_memory(fz_context *ctx, fz_font **fontp, unsigned char *data, int len, int index) +fz_font * +fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index) { FT_Face face; fz_error error; @@ -216,11 +215,11 @@ fz_new_font_from_memory(fz_context *ctx, fz_font **fontp, unsigned char *data, i error = fz_init_freetype(ctx); if (error) - return fz_error_note(error, "cannot init freetype library"); + fz_throw(ctx, "cannot init freetype library"); fterr = FT_New_Memory_Face(fz_ftlib, data, len, index, &face); if (fterr) - return fz_error_make("freetype: cannot load font: %s", ft_error_string(fterr)); + fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr)); font = fz_new_font(ctx, face->family_name); font->ft_face = face; @@ -229,8 +228,7 @@ fz_new_font_from_memory(fz_context *ctx, fz_font **fontp, unsigned char *data, i font->bbox.x1 = face->bbox.xMax * 1000 / face->units_per_EM; font->bbox.y1 = face->bbox.yMax * 1000 / face->units_per_EM; - *fontp = font; - return fz_okay; + return font; } static fz_matrix @@ -514,7 +512,6 @@ fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix) fz_pixmap * fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model) { - fz_error error; fz_matrix ctm; fz_buffer *contents; fz_bbox bbox; @@ -532,9 +529,8 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co ctm = fz_concat(font->t3matrix, trm); dev = fz_new_bbox_device(ctx, &bbox); - error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); - if (error) - fz_error_handle(error, "cannot draw type3 glyph"); + font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); + /* RJW: "cannot draw type3 glyph" */ if (dev->flags & FZ_CHARPROC_MASK) { @@ -565,9 +561,8 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co cache = fz_new_glyph_cache(ctx); dev = fz_new_draw_device_type3(ctx, cache, glyph); - error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); - if (error) - fz_error_handle(error, "cannot draw type3 glyph"); + font->t3run(font->t3xref, font->t3resources, contents, dev, ctm); + /* RJW: "cannot draw type3 glyph" */ fz_free_device(dev); fz_free_glyph_cache(ctx, cache); diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c index a34933f5..471dcc72 100644 --- a/fitz/res_pixmap.c +++ b/fitz/res_pixmap.c @@ -293,19 +293,19 @@ fz_gamma_pixmap(fz_pixmap *pix, float gamma) * Write pixmap to PNM file (without alpha channel) */ -fz_error -fz_write_pnm(fz_pixmap *pixmap, char *filename) +void +fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) { FILE *fp; unsigned char *p; int len; if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4) - return fz_error_make("pixmap must be grayscale or rgb to write as pnm"); + fz_throw(ctx, "pixmap must be grayscale or rgb to write as pnm"); fp = fopen(filename, "wb"); if (!fp) - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); if (pixmap->n == 1 || pixmap->n == 2) fprintf(fp, "P5\n"); @@ -340,15 +340,14 @@ fz_write_pnm(fz_pixmap *pixmap, char *filename) } fclose(fp); - return fz_okay; } /* * Write pixmap to PAM file (with or without alpha channel) */ -fz_error -fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha) +void +fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) { unsigned char *sp; int y, w, k; @@ -361,7 +360,7 @@ fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha) fp = fopen(filename, "wb"); if (!fp) - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); fprintf(fp, "P7\n"); fprintf(fp, "WIDTH %d\n", pixmap->w); @@ -392,8 +391,6 @@ fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha) } fclose(fp); - - return fz_okay; } /* @@ -430,7 +427,7 @@ static void putchunk(char *tag, unsigned char *data, int size, FILE *fp) put32(sum, fp); } -fz_error +void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) { static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; @@ -443,7 +440,7 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) int err; if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4) - return fz_error_make("pixmap must be grayscale or rgb to write as png"); + fz_throw(ctx, "pixmap must be grayscale or rgb to write as png"); sn = pixmap->n; dn = pixmap->n; @@ -488,7 +485,7 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) { fz_free(ctx, udata); fz_free(ctx, cdata); - return fz_error_make("cannot compress image data"); + fz_throw(ctx, "cannot compress image data"); } fp = fopen(filename, "wb"); @@ -496,7 +493,7 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) { fz_free(ctx, udata); fz_free(ctx, cdata); - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); } big32(head+0, pixmap->w); @@ -515,5 +512,4 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) fz_free(ctx, udata); fz_free(ctx, cdata); - return fz_okay; } diff --git a/fitz/stm_read.c b/fitz/stm_read.c index 23f758eb..58379887 100644 --- a/fitz/stm_read.c +++ b/fitz/stm_read.c @@ -94,8 +94,8 @@ fz_fill_buffer(fz_stream *stm) } } -fz_error -fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial) +fz_buffer * +fz_read_all(fz_stream *stm, int initial) { fz_buffer *buf; int n; @@ -114,14 +114,14 @@ fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial) if (buf->len / 200 > initial) { fz_drop_buffer(ctx, buf); - return fz_error_make("compression bomb detected"); + fz_throw(ctx, "compression bomb detected"); } n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len); if (n < 0) { fz_drop_buffer(ctx, buf); - return fz_error_note(n, "read error"); + fz_throw(ctx, "read error"); } if (n == 0) break; @@ -129,8 +129,7 @@ fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial) buf->len += n; } - *bufp = buf; - return fz_okay; + return buf; } void diff --git a/pdf/mupdf.h b/pdf/mupdf.h index 779fb976..727d28e2 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -25,12 +25,12 @@ enum PDF_NUM_TOKENS }; -fz_error pdf_lex(int *tok, fz_stream *f, char *buf, int n, int *len); +int pdf_lex(fz_stream *f, char *buf, int n, int *len); -fz_error pdf_parse_array(fz_obj **op, pdf_xref *xref, fz_stream *f, char *buf, int cap); -fz_error pdf_parse_dict(fz_obj **op, pdf_xref *xref, fz_stream *f, char *buf, int cap); -fz_error pdf_parse_stm_obj(fz_obj **op, pdf_xref *xref, fz_stream *f, char *buf, int cap); -fz_error pdf_parse_ind_obj(fz_obj **op, pdf_xref *xref, fz_stream *f, char *buf, int cap, int *num, int *gen, int *stm_ofs); +fz_obj *pdf_parse_array(pdf_xref *xref, fz_stream *f, char *buf, int cap); +fz_obj *pdf_parse_dict(pdf_xref *xref, fz_stream *f, char *buf, int cap); +fz_obj *pdf_parse_stm_obj(pdf_xref *xref, fz_stream *f, char *buf, int cap); +fz_obj * pdf_parse_ind_obj(pdf_xref *xref, fz_stream *f, char *buf, int cap, int *num, int *gen, int *stm_ofs); fz_rect pdf_to_rect(fz_context *ctx, fz_obj *array); fz_matrix pdf_to_matrix(fz_context *ctx, fz_obj *array); @@ -79,25 +79,25 @@ struct pdf_xref_s }; fz_obj *pdf_resolve_indirect(fz_obj *ref); -fz_error pdf_cache_object(pdf_xref *, int num, int gen); -fz_error pdf_load_object(fz_obj **objp, pdf_xref *, int num, int gen); +void pdf_cache_object(pdf_xref *, int num, int gen); +fz_obj *pdf_load_object(pdf_xref *, int num, int gen); void pdf_update_object( pdf_xref *xref, int num, int gen, fz_obj *newobj); int pdf_is_stream(pdf_xref *xref, int num, int gen); fz_stream *pdf_open_inline_stream(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int length); -fz_error pdf_load_raw_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen); -fz_error pdf_load_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen); -fz_error pdf_open_raw_stream(fz_stream **stmp, pdf_xref *, int num, int gen); -fz_error pdf_open_stream(fz_stream **stmp, pdf_xref *, int num, int gen); -fz_error pdf_open_stream_at(fz_stream **stmp, pdf_xref *xref, int num, int gen, fz_obj *dict, int stm_ofs); - -fz_error pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password); -fz_error pdf_open_xref(fz_context *ctx, pdf_xref **xrefp, const char *filename, char *password); +fz_buffer *pdf_load_raw_stream(pdf_xref *xref, int num, int gen); +fz_buffer *pdf_load_stream(pdf_xref *xref, int num, int gen); +fz_stream *pdf_open_raw_stream(pdf_xref *, int num, int gen); +fz_stream *pdf_open_stream(pdf_xref *, int num, int gen); +fz_stream *pdf_open_stream_at(pdf_xref *xref, int num, int gen, fz_obj *dict, int stm_ofs); + +pdf_xref *pdf_open_xref_with_stream(fz_stream *file, char *password); +pdf_xref *pdf_open_xref(fz_context *ctx, const char *filename, char *password); void pdf_free_xref(pdf_xref *); /* private */ -fz_error pdf_repair_xref(pdf_xref *xref, char *buf, int bufsize); -fz_error pdf_repair_obj_stms(pdf_xref *xref); +void pdf_repair_xref(pdf_xref *xref, char *buf, int bufsize); +void pdf_repair_obj_stms(pdf_xref *xref); void pdf_debug_xref(pdf_xref *); void pdf_resize_xref(pdf_xref *xref, int newcap); @@ -118,7 +118,7 @@ enum PDF_DEFAULT_PERM_FLAGS = 0xfffc }; -fz_error pdf_new_crypt(fz_context *ctx, pdf_crypt **cp, fz_obj *enc, fz_obj *id); +pdf_crypt *pdf_new_crypt(fz_context *ctx, fz_obj *enc, fz_obj *id); void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt); void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, fz_obj *obj, int num, int gen); @@ -160,18 +160,18 @@ void pdf_age_store(fz_context *ctx, pdf_store *store, int maxage); typedef struct pdf_function_s pdf_function; -fz_error pdf_load_function(pdf_function **func, pdf_xref *xref, fz_obj *ref); +pdf_function *pdf_load_function(pdf_xref *xref, fz_obj *ref); void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in, int inlen, float *out, int outlen); pdf_function *pdf_keep_function(pdf_function *func); void pdf_drop_function(fz_context *ctx, pdf_function *func); -fz_error pdf_load_colorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj); +fz_colorspace *pdf_load_colorspace(pdf_xref *xref, fz_obj *obj); fz_pixmap *pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src); -fz_error pdf_load_shading(fz_shade **shadep, pdf_xref *xref, fz_obj *obj); +fz_shade *pdf_load_shading(pdf_xref *xref, fz_obj *obj); -fz_error pdf_load_inline_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); -fz_error pdf_load_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *obj); +fz_pixmap *pdf_load_inline_image(pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); +fz_pixmap *pdf_load_image(pdf_xref *xref, fz_obj *obj); int pdf_is_jpx_image(fz_context *ctx, fz_obj *dict); /* @@ -192,7 +192,7 @@ struct pdf_pattern_s fz_buffer *contents; }; -fz_error pdf_load_pattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *obj); +pdf_pattern *pdf_load_pattern(pdf_xref *xref, fz_obj *obj); pdf_pattern *pdf_keep_pattern(pdf_pattern *pat); void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat); @@ -215,7 +215,7 @@ struct pdf_xobject_s fz_buffer *contents; }; -fz_error pdf_load_xobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj); +pdf_xobject *pdf_load_xobject(pdf_xref *xref, fz_obj *obj); pdf_xobject *pdf_keep_xobject(pdf_xobject *xobj); void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj); @@ -283,9 +283,9 @@ int pdf_lookup_cmap_full(pdf_cmap *cmap, int cpt, int *out); unsigned char *pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, int *cpt); pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes); -fz_error pdf_parse_cmap(pdf_cmap **cmapp, fz_stream *file); -fz_error pdf_load_embedded_cmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *ref); -fz_error pdf_load_system_cmap(fz_context *ctx, pdf_cmap **cmapp, char *name); +pdf_cmap *pdf_parse_cmap(fz_stream *file); +pdf_cmap *pdf_load_embedded_cmap(pdf_xref *xref, fz_obj *ref); +pdf_cmap *pdf_load_system_cmap(fz_context *ctx, char *name); pdf_cmap *pdf_find_builtin_cmap(char *cmap_name); /* @@ -387,7 +387,7 @@ void pdf_end_vmtx(pdf_font_desc *font); pdf_hmtx pdf_get_hmtx(pdf_font_desc *font, int cid); pdf_vmtx pdf_get_vmtx(pdf_font_desc *font, int cid); -fz_error pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm); +void pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm); int pdf_font_cid_to_gid(pdf_font_desc *fontdesc, int cid); @@ -395,8 +395,8 @@ unsigned char *pdf_find_builtin_font(char *name, unsigned int *len); unsigned char *pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len); unsigned char *pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len); -fz_error pdf_load_type3_font(pdf_font_desc **fontp, pdf_xref *xref, fz_obj *rdb, fz_obj *obj); -fz_error pdf_load_font(pdf_font_desc **fontp, pdf_xref *xref, fz_obj *rdb, fz_obj *obj); +pdf_font_desc *pdf_load_type3_font(pdf_xref *xref, fz_obj *rdb, fz_obj *obj); +pdf_font_desc *pdf_load_font(pdf_xref *xref, fz_obj *rdb, fz_obj *obj); pdf_font_desc *pdf_new_font_desc(fz_context *ctx); pdf_font_desc *pdf_keep_font(pdf_font_desc *fontdesc); @@ -479,19 +479,19 @@ struct pdf_page_s pdf_annot *annots; }; -fz_error pdf_load_page_tree(pdf_xref *xref); +void pdf_load_page_tree(pdf_xref *xref); int pdf_find_page_number(pdf_xref *xref, fz_obj *pageobj); int pdf_count_pages(pdf_xref *xref); -fz_error pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number); +pdf_page *pdf_load_page(pdf_xref *xref, int number); void pdf_free_page(fz_context *ctx, pdf_page *page); /* * Content stream parsing */ -fz_error pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *target); -fz_error pdf_run_page(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm); -fz_error pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm); +void pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *target); +void pdf_run_page(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm); +void pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm); #endif diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index aa640610..2a569e5c 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -192,7 +192,6 @@ pdf_load_annots(pdf_annot **annotp, pdf_xref *xref, fz_obj *annots) pdf_annot *annot, *head, *tail; fz_obj *obj, *ap, *as, *n, *rect; pdf_xobject *form; - fz_error error; int i, len; fz_context *ctx = xref->ctx; @@ -217,10 +216,13 @@ pdf_load_annots(pdf_annot **annotp, pdf_xref *xref, fz_obj *annots) if (pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n))) { - error = pdf_load_xobject(&form, xref, n); - if (error) + fz_try(ctx) { - fz_error_handle(error, "ignoring broken annotation"); + form = pdf_load_xobject(xref, n); + } + fz_catch(ctx) + { + fz_warn(ctx, "ignoring broken annotation"); continue; } diff --git a/pdf/pdf_cmap_load.c b/pdf/pdf_cmap_load.c index c962c6ca..15bd8406 100644 --- a/pdf/pdf_cmap_load.c +++ b/pdf/pdf_cmap_load.c @@ -4,8 +4,8 @@ /* * Load CMap stream in PDF file */ -fz_error -pdf_load_embedded_cmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmobj) +pdf_cmap * +pdf_load_embedded_cmap(pdf_xref *xref, fz_obj *stmobj) { fz_error error = fz_okay; fz_stream *file = NULL; @@ -14,68 +14,61 @@ pdf_load_embedded_cmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmobj) fz_obj *wmode; fz_obj *obj; fz_context *ctx = xref->ctx; + volatile int phase = 0; - if ((*cmapp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_cmap, stmobj))) - { - pdf_keep_cmap(*cmapp); - return fz_okay; - } - - error = pdf_open_stream(&file, xref, fz_to_num(stmobj), fz_to_gen(stmobj)); - if (error) + if ((cmap = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_cmap, stmobj))) { - error = fz_error_note(error, "cannot open cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); - goto cleanup; + pdf_keep_cmap(cmap); + return cmap; } - error = pdf_parse_cmap(&cmap, file); - if (error) + fz_try(ctx) { - error = fz_error_note(error, "cannot parse cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); - goto cleanup; - } - - fz_close(file); - wmode = fz_dict_gets(stmobj, "WMode"); - if (fz_is_int(wmode)) - pdf_set_wmode(cmap, fz_to_int(wmode)); + file = pdf_open_stream(xref, fz_to_num(stmobj), fz_to_gen(stmobj)); + phase = 1; + cmap = pdf_parse_cmap(file); + phase = 2; + fz_close(file); + file = NULL; - obj = fz_dict_gets(stmobj, "UseCMap"); - if (fz_is_name(obj)) - { - error = pdf_load_system_cmap(ctx, &usecmap, fz_to_name(obj)); - if (error) + wmode = fz_dict_gets(stmobj, "WMode"); + if (fz_is_int(wmode)) + pdf_set_wmode(cmap, fz_to_int(wmode)); + obj = fz_dict_gets(stmobj, "UseCMap"); + if (fz_is_name(obj)) { - error = fz_error_note(error, "cannot load system usecmap '%s'", fz_to_name(obj)); - goto cleanup; + usecmap = pdf_load_system_cmap(ctx, fz_to_name(obj)); + pdf_set_usecmap(ctx, cmap, usecmap); + pdf_drop_cmap(ctx, usecmap); } - pdf_set_usecmap(ctx, cmap, usecmap); - pdf_drop_cmap(ctx, usecmap); - } - else if (fz_is_indirect(obj)) - { - error = pdf_load_embedded_cmap(&usecmap, xref, obj); - if (error) + else if (fz_is_indirect(obj)) { - error = fz_error_note(error, "cannot load embedded usecmap (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - goto cleanup; + phase = 3; + usecmap = pdf_load_embedded_cmap(xref, obj); + pdf_set_usecmap(ctx, cmap, usecmap); + pdf_drop_cmap(ctx, usecmap); } - pdf_set_usecmap(ctx, cmap, usecmap); - pdf_drop_cmap(ctx, usecmap); - } - - pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)pdf_keep_cmap, (pdf_store_drop_fn *)pdf_drop_cmap, stmobj, cmap); - *cmapp = cmap; - return fz_okay; + pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)pdf_keep_cmap, (pdf_store_drop_fn *)pdf_drop_cmap, stmobj, cmap); + } + fz_catch(ctx) + { + if (file) + fz_close(file); + if (cmap) + pdf_drop_cmap(ctx, cmap); + if (phase < 1) + fz_throw(ctx, "cannot open cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); + else if (phase < 2) + fz_throw(ctx, "cannot parse cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); + else if (phase < 3) + fz_throw(ctx, "cannot load system usecmap '%s'", fz_to_name(obj)); + else + fz_throw(ctx, "cannot load embedded usecmap (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + } -cleanup: - if (file) - fz_close(file); - if (cmap) - pdf_drop_cmap(ctx, cmap); - return error; /* already rethrown */ + return cmap; } /* @@ -96,24 +89,23 @@ pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes) /* * Load predefined CMap from system. */ -fz_error -pdf_load_system_cmap(fz_context *ctx, pdf_cmap **cmapp, char *cmap_name) +pdf_cmap * +pdf_load_system_cmap(fz_context *ctx, char *cmap_name) { pdf_cmap *usecmap; pdf_cmap *cmap; cmap = pdf_find_builtin_cmap(cmap_name); if (!cmap) - return fz_error_make("no builtin cmap file: %s", cmap_name); + fz_throw(ctx, "no builtin cmap file: %s", cmap_name); if (cmap->usecmap_name[0] && !cmap->usecmap) { usecmap = pdf_find_builtin_cmap(cmap->usecmap_name); if (!usecmap) - return fz_error_make("nu builtin cmap file: %s", cmap->usecmap_name); + fz_throw(ctx, "nu builtin cmap file: %s", cmap->usecmap_name); pdf_set_usecmap(ctx, cmap, usecmap); } - *cmapp = cmap; - return fz_okay; + return cmap; } diff --git a/pdf/pdf_cmap_parse.c b/pdf/pdf_cmap_parse.c index d048271f..4dcc76c5 100644 --- a/pdf/pdf_cmap_parse.c +++ b/pdf/pdf_cmap_parse.c @@ -48,65 +48,54 @@ pdf_code_from_string(char *buf, int len) return a; } -static fz_error -pdf_lex_cmap(int *tok, fz_stream *file, char *buf, int n, int *sl) +static int +pdf_lex_cmap(fz_stream *file, char *buf, int n, int *sl) { - fz_error error; + int tok = pdf_lex(file, buf, n, sl); - error = pdf_lex(tok, file, buf, n, sl); - if (error) - return fz_error_note(error, "cannot parse cmap token"); + /* RJW: Lost debugging here: "cannot parse cmap token" */ - if (*tok == PDF_TOK_KEYWORD) - *tok = pdf_cmap_token_from_keyword(buf); + if (tok == PDF_TOK_KEYWORD) + tok = pdf_cmap_token_from_keyword(buf); - return fz_okay; + return tok; } -static fz_error +static void pdf_parse_cmap_name(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_NAME) fz_strlcpy(cmap->cmap_name, buf, sizeof(cmap->cmap_name)); else fz_warn(file->ctx, "expected name after CMapName in cmap"); - - return fz_okay; } -static fz_error +static void pdf_parse_wmode(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_INT) pdf_set_wmode(cmap, atoi(buf)); else fz_warn(file->ctx, "expected integer after WMode in cmap"); - - return fz_okay; } -static fz_error +static void pdf_parse_codespace_range(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; @@ -114,19 +103,17 @@ pdf_parse_codespace_range(pdf_cmap *cmap, fz_stream *file) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == TOK_END_CODESPACE_RANGE) - return fz_okay; + return; else if (tok == PDF_TOK_STRING) { lo = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_STRING) { hi = pdf_code_from_string(buf, len); @@ -138,13 +125,12 @@ pdf_parse_codespace_range(pdf_cmap *cmap, fz_stream *file) else break; } - return fz_error_make("expected string or endcodespacerange"); + fz_throw(file->ctx, "expected string or endcodespacerange"); } -static fz_error +static void pdf_parse_cid_range(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; @@ -152,31 +138,28 @@ pdf_parse_cid_range(pdf_cmap *cmap, fz_stream *file) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == TOK_END_CID_RANGE) - return fz_okay; + return; else if (tok != PDF_TOK_STRING) - return fz_error_make("expected string or endcidrange"); + fz_throw(file->ctx, "expected string or endcidrange"); lo = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok != PDF_TOK_STRING) - return fz_error_make("expected string"); + fz_throw(file->ctx, "expected string"); hi = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok != PDF_TOK_INT) - return fz_error_make("expected integer"); + fz_throw(file->ctx, "expected integer"); dst = atoi(buf); @@ -184,10 +167,9 @@ pdf_parse_cid_range(pdf_cmap *cmap, fz_stream *file) } } -static fz_error +static void pdf_parse_cid_char(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; @@ -195,23 +177,22 @@ pdf_parse_cid_char(pdf_cmap *cmap, fz_stream *file) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_CID_CHAR) - return fz_okay; + return; else if (tok != PDF_TOK_STRING) - return fz_error_make("expected string or endcidchar"); + fz_throw(file->ctx, "expected string or endcidchar"); src = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ + if (tok != PDF_TOK_INT) - return fz_error_make("expected integer"); + fz_throw(file->ctx, "expected integer"); dst = atoi(buf); @@ -219,10 +200,9 @@ pdf_parse_cid_char(pdf_cmap *cmap, fz_stream *file) } } -static fz_error +static void pdf_parse_bf_range_array(pdf_cmap *cmap, fz_stream *file, int lo, int hi) { - fz_error error; char buf[256]; int tok; int len; @@ -231,16 +211,15 @@ pdf_parse_bf_range_array(pdf_cmap *cmap, fz_stream *file, int lo, int hi) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok == PDF_TOK_CLOSE_ARRAY) - return fz_okay; + return; /* Note: does not handle [ /Name /Name ... ] */ else if (tok != PDF_TOK_STRING) - return fz_error_make("expected string or ]"); + fz_throw(file->ctx, "expected string or ]"); if (len / 2) { @@ -254,10 +233,9 @@ pdf_parse_bf_range_array(pdf_cmap *cmap, fz_stream *file, int lo, int hi) } } -static fz_error +static void pdf_parse_bf_range(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; @@ -265,29 +243,26 @@ pdf_parse_bf_range(pdf_cmap *cmap, fz_stream *file) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_BF_RANGE) - return fz_okay; + return; else if (tok != PDF_TOK_STRING) - return fz_error_make("expected string or endbfrange"); + fz_throw(file->ctx, "expected string or endbfrange"); lo = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok != PDF_TOK_STRING) - return fz_error_make("expected string"); + fz_throw(file->ctx, "expected string"); hi = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok == PDF_TOK_STRING) { @@ -318,22 +293,20 @@ pdf_parse_bf_range(pdf_cmap *cmap, fz_stream *file) else if (tok == PDF_TOK_OPEN_ARRAY) { - error = pdf_parse_bf_range_array(cmap, file, lo, hi); - if (error) - return fz_error_note(error, "cannot map bfrange"); + pdf_parse_bf_range_array(cmap, file, lo, hi); + /* RJW: "cannot map bfrange" */ } else { - return fz_error_make("expected string or array or endbfrange"); + fz_throw(file->ctx, "expected string or array or endbfrange"); } } } -static fz_error +static void pdf_parse_bf_char(pdf_cmap *cmap, fz_stream *file) { - fz_error error; char buf[256]; int tok; int len; @@ -343,24 +316,22 @@ pdf_parse_bf_char(pdf_cmap *cmap, fz_stream *file) while (1) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_BF_CHAR) - return fz_okay; + return; else if (tok != PDF_TOK_STRING) - return fz_error_make("expected string or endbfchar"); + fz_throw(file->ctx, "expected string or endbfchar"); src = pdf_code_from_string(buf, len); - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "syntaxerror in cmap"); + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); + /* RJW: "syntaxerror in cmap" */ /* Note: does not handle /dstName */ if (tok != PDF_TOK_STRING) - return fz_error_make("expected string"); + fz_throw(file->ctx, "expected string"); if (len / 2) { @@ -371,120 +342,92 @@ pdf_parse_bf_char(pdf_cmap *cmap, fz_stream *file) } } -fz_error -pdf_parse_cmap(pdf_cmap **cmapp, fz_stream *file) +pdf_cmap * +pdf_parse_cmap(fz_stream *file) { - fz_error error; pdf_cmap *cmap; char key[64]; char buf[256]; int tok; int len; + const char *where; + fz_context *ctx = file->ctx; - cmap = pdf_new_cmap(file->ctx); + cmap = pdf_new_cmap(ctx); strcpy(key, ".notdef"); - while (1) + fz_try(ctx) { - error = pdf_lex_cmap(&tok, file, buf, sizeof buf, &len); - if (error) + while (1) { - error = fz_error_note(error, "syntaxerror in cmap"); - goto cleanup; - } + where = ""; + tok = pdf_lex_cmap(file, buf, sizeof buf, &len); - if (tok == PDF_TOK_EOF || tok == TOK_END_CMAP) - break; + if (tok == PDF_TOK_EOF || tok == TOK_END_CMAP) + break; - else if (tok == PDF_TOK_NAME) - { - if (!strcmp(buf, "CMapName")) + else if (tok == PDF_TOK_NAME) { - error = pdf_parse_cmap_name(cmap, file); - if (error) + if (!strcmp(buf, "CMapName")) { - error = fz_error_note(error, "syntaxerror in cmap after CMapName"); - goto cleanup; + where = " after CMapName"; + pdf_parse_cmap_name(cmap, file); } - } - else if (!strcmp(buf, "WMode")) - { - error = pdf_parse_wmode(cmap, file); - if (error) + else if (!strcmp(buf, "WMode")) { - error = fz_error_note(error, "syntaxerror in cmap after WMode"); - goto cleanup; + where = " after WMode"; + pdf_parse_wmode(cmap, file); } + else + fz_strlcpy(key, buf, sizeof key); } - else - fz_strlcpy(key, buf, sizeof key); - } - else if (tok == TOK_USECMAP) - { - fz_strlcpy(cmap->usecmap_name, key, sizeof(cmap->usecmap_name)); - } + else if (tok == TOK_USECMAP) + { + fz_strlcpy(cmap->usecmap_name, key, sizeof(cmap->usecmap_name)); + } - else if (tok == TOK_BEGIN_CODESPACE_RANGE) - { - error = pdf_parse_codespace_range(cmap, file); - if (error) + else if (tok == TOK_BEGIN_CODESPACE_RANGE) { - error = fz_error_note(error, "syntaxerror in cmap codespacerange"); - goto cleanup; + where = " codespacerange"; + pdf_parse_codespace_range(cmap, file); } - } - else if (tok == TOK_BEGIN_BF_CHAR) - { - error = pdf_parse_bf_char(cmap, file); - if (error) + else if (tok == TOK_BEGIN_BF_CHAR) { - error = fz_error_note(error, "syntaxerror in cmap bfchar"); - goto cleanup; + where = " bfchar"; + pdf_parse_bf_char(cmap, file); } - } - else if (tok == TOK_BEGIN_CID_CHAR) - { - error = pdf_parse_cid_char(cmap, file); - if (error) + else if (tok == TOK_BEGIN_CID_CHAR) { - error = fz_error_note(error, "syntaxerror in cmap cidchar"); - goto cleanup; + where = " cidchar"; + pdf_parse_cid_char(cmap, file); } - } - else if (tok == TOK_BEGIN_BF_RANGE) - { - error = pdf_parse_bf_range(cmap, file); - if (error) + else if (tok == TOK_BEGIN_BF_RANGE) { - error = fz_error_note(error, "syntaxerror in cmap bfrange"); - goto cleanup; + where = " bfrange"; + pdf_parse_bf_range(cmap, file); } - } - else if (tok == TOK_BEGIN_CID_RANGE) - { - error = pdf_parse_cid_range(cmap, file); - if (error) + else if (tok == TOK_BEGIN_CID_RANGE) { - error = fz_error_note(error, "syntaxerror in cmap cidrange"); - goto cleanup; + where = "cidrange"; + pdf_parse_cid_range(cmap, file); } + + /* ignore everything else */ } - /* ignore everything else */ + pdf_sort_cmap(file->ctx, cmap); + } + fz_catch(ctx) + { + pdf_drop_cmap(file->ctx, cmap); + fz_throw(ctx, "syntaxerror in cmap%s", where); } - pdf_sort_cmap(file->ctx, cmap); - - *cmapp = cmap; - return fz_okay; - -cleanup: - pdf_drop_cmap(file->ctx, cmap); - return error; /* already rethrown */ + return cmap; } diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c index 4c4368cc..c386b34c 100644 --- a/pdf/pdf_colorspace.c +++ b/pdf/pdf_colorspace.c @@ -3,8 +3,8 @@ /* ICCBased */ -static fz_error -load_icc_based(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict) +static fz_colorspace * +load_icc_based(pdf_xref *xref, fz_obj *dict) { int n; @@ -12,12 +12,13 @@ load_icc_based(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict) switch (n) { - case 1: *csp = fz_device_gray; return fz_okay; - case 3: *csp = fz_device_rgb; return fz_okay; - case 4: *csp = fz_device_cmyk; return fz_okay; + case 1: return fz_device_gray; + case 3: return fz_device_rgb; + case 4: return fz_device_cmyk; } - return fz_error_make("syntaxerror: ICCBased must have 1, 3 or 4 components"); + fz_throw(xref->ctx, "syntaxerror: ICCBased must have 1, 3 or 4 components"); + return NULL; /* Stupid MSVC */ } /* Lab */ @@ -89,10 +90,9 @@ free_separation(fz_context *ctx, fz_colorspace *cs) fz_free(ctx, sep); } -static fz_error -load_separation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) +static fz_colorspace * +load_separation(pdf_xref *xref, fz_obj *array) { - fz_error error; fz_colorspace *cs; struct separation *sep; fz_context *ctx = xref->ctx; @@ -109,18 +109,14 @@ load_separation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) n = 1; if (n > FZ_MAX_COLORS) - return fz_error_make("too many components in colorspace"); + fz_throw(ctx, "too many components in colorspace"); - error = pdf_load_colorspace(&base, xref, baseobj); - if (error) - return fz_error_note(error, "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj)); + base = pdf_load_colorspace(xref, baseobj); + /* RJW: "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */ - error = pdf_load_function(&tint, xref, tintobj); - if (error) - { - fz_drop_colorspace(ctx, base); - return fz_error_note(error, "cannot load tint function (%d %d R)", fz_to_num(tintobj), fz_to_gen(tintobj)); - } + tint = pdf_load_function(xref, tintobj); + /* RJW: fz_drop_colorspace(ctx, base); + * "cannot load tint function (%d %d R)", fz_to_num(tintobj), fz_to_gen(tintobj) */ sep = fz_malloc(ctx, sizeof(struct separation)); sep->base = base; @@ -131,8 +127,7 @@ load_separation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) cs->free_data = free_separation; cs->data = sep; - *csp = cs; - return fz_okay; + return cs; } /* Indexed */ @@ -208,22 +203,19 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src) return dst; } -static fz_error -load_indexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) +static fz_colorspace * +load_indexed(pdf_xref *xref, fz_obj *array) { - fz_error error; - fz_colorspace *cs; struct indexed *idx; fz_context *ctx = xref->ctx; fz_obj *baseobj = fz_array_get(array, 1); fz_obj *highobj = fz_array_get(array, 2); fz_obj *lookup = fz_array_get(array, 3); - fz_colorspace *base; + fz_colorspace *base, *cs; int i, n; - error = pdf_load_colorspace(&base, xref, baseobj); - if (error) - return fz_error_note(error, "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj)); + base = pdf_load_colorspace(xref, baseobj); + /* "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */ idx = fz_malloc(ctx, sizeof(struct indexed)); idx->base = base; @@ -247,18 +239,21 @@ load_indexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) { fz_stream *file; - error = pdf_open_stream(&file, xref, fz_to_num(lookup), fz_to_gen(lookup)); - if (error) + fz_try(ctx) + { + file = pdf_open_stream(xref, fz_to_num(lookup), fz_to_gen(lookup)); + } + fz_catch(ctx) { fz_drop_colorspace(ctx, cs); - return fz_error_note(error, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup)); + fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup)); } i = fz_read(file, idx->lookup, n); if (i < 0) { fz_drop_colorspace(ctx, cs); - return fz_error_make("cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup)); + fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup)); } fz_close(file); @@ -266,37 +261,35 @@ load_indexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array) else { fz_drop_colorspace(ctx, cs); - return fz_error_make("cannot parse colorspace lookup table"); + fz_throw(ctx, "cannot parse colorspace lookup table"); } - *csp = cs; - return fz_okay; + return cs; } /* Parse and create colorspace from PDF object */ -static fz_error -pdf_load_colorspace_imp(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) +static fz_colorspace * +pdf_load_colorspace_imp(pdf_xref *xref, fz_obj *obj) { if (fz_is_name(obj)) { if (!strcmp(fz_to_name(obj), "Pattern")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(obj), "G")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(obj), "RGB")) - *csp = fz_device_rgb; + return fz_device_rgb; else if (!strcmp(fz_to_name(obj), "CMYK")) - *csp = fz_device_cmyk; + return fz_device_cmyk; else if (!strcmp(fz_to_name(obj), "DeviceGray")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(obj), "DeviceRGB")) - *csp = fz_device_rgb; + return fz_device_rgb; else if (!strcmp(fz_to_name(obj), "DeviceCMYK")) - *csp = fz_device_cmyk; + return fz_device_cmyk; else - return fz_error_make("unknown colorspace: %s", fz_to_name(obj)); - return fz_okay; + fz_throw(xref->ctx, "unknown colorspace: %s", fz_to_name(obj)); } else if (fz_is_array(obj)) @@ -308,82 +301,75 @@ pdf_load_colorspace_imp(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) /* load base colorspace instead */ if (!strcmp(fz_to_name(name), "Pattern")) { - fz_error error; - obj = fz_array_get(obj, 1); if (!obj) { - *csp = fz_device_gray; - return fz_okay; + return fz_device_gray; } - error = pdf_load_colorspace(csp, xref, obj); - if (error) - return fz_error_note(error, "cannot load pattern (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + return pdf_load_colorspace(xref, obj); + /* RJW: "cannot load pattern (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ } else if (!strcmp(fz_to_name(name), "G")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(name), "RGB")) - *csp = fz_device_rgb; + return fz_device_rgb; else if (!strcmp(fz_to_name(name), "CMYK")) - *csp = fz_device_cmyk; + return fz_device_cmyk; else if (!strcmp(fz_to_name(name), "DeviceGray")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(name), "DeviceRGB")) - *csp = fz_device_rgb; + return fz_device_rgb; else if (!strcmp(fz_to_name(name), "DeviceCMYK")) - *csp = fz_device_cmyk; + return fz_device_cmyk; else if (!strcmp(fz_to_name(name), "CalGray")) - *csp = fz_device_gray; + return fz_device_gray; else if (!strcmp(fz_to_name(name), "CalRGB")) - *csp = fz_device_rgb; + return fz_device_rgb; else if (!strcmp(fz_to_name(name), "CalCMYK")) - *csp = fz_device_cmyk; + return fz_device_cmyk; else if (!strcmp(fz_to_name(name), "Lab")) - *csp = fz_device_lab; + return fz_device_lab; else if (!strcmp(fz_to_name(name), "ICCBased")) - return load_icc_based(csp, xref, fz_array_get(obj, 1)); + return load_icc_based(xref, fz_array_get(obj, 1)); else if (!strcmp(fz_to_name(name), "Indexed")) - return load_indexed(csp, xref, obj); + return load_indexed(xref, obj); else if (!strcmp(fz_to_name(name), "I")) - return load_indexed(csp, xref, obj); + return load_indexed(xref, obj); else if (!strcmp(fz_to_name(name), "Separation")) - return load_separation(csp, xref, obj); + return load_separation(xref, obj); else if (!strcmp(fz_to_name(name), "DeviceN")) - return load_separation(csp, xref, obj); + return load_separation(xref, obj); else - return fz_error_make("syntaxerror: unknown colorspace %s", fz_to_name(name)); - - return fz_okay; + fz_throw(xref->ctx, "syntaxerror: unknown colorspace %s", fz_to_name(name)); } } - return fz_error_make("syntaxerror: could not parse color space (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + fz_throw(xref->ctx, "syntaxerror: could not parse color space (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + return NULL; /* Stupid MSVC */ } -fz_error -pdf_load_colorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) +fz_colorspace * +pdf_load_colorspace(pdf_xref *xref, fz_obj *obj) { - fz_error error; fz_context *ctx = xref->ctx; + fz_colorspace *cs; - if ((*csp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_colorspace, obj))) + if ((cs = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_colorspace, obj))) { - fz_keep_colorspace(*csp); - return fz_okay; + return fz_keep_colorspace(cs); } - error = pdf_load_colorspace_imp(csp, xref, obj); - if (error) - return fz_error_note(error, "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + cs = pdf_load_colorspace_imp(xref, obj); + /* RJW: "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ - pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_colorspace, (pdf_store_drop_fn *)fz_drop_colorspace, obj, *csp); + pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_colorspace, (pdf_store_drop_fn *)fz_drop_colorspace, obj, cs); - return fz_okay; + return cs; } diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c index 523fabc1..1ae16b37 100644 --- a/pdf/pdf_crypt.c +++ b/pdf/pdf_crypt.c @@ -47,11 +47,10 @@ static fz_error pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, fz * given the Encryption and ID objects. */ -fz_error -pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) +pdf_crypt * +pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id) { pdf_crypt *crypt; - fz_error error; fz_obj *obj; crypt = fz_malloc(ctx, sizeof(pdf_crypt)); @@ -63,12 +62,12 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) if (!fz_is_name(obj)) { pdf_free_crypt(ctx, crypt); - return fz_error_make("unspecified encryption handler"); + fz_throw(ctx, "unspecified encryption handler"); } if (strcmp(fz_to_name(obj), "Standard") != 0) { pdf_free_crypt(ctx, crypt); - return fz_error_make("unknown encryption handler: '%s'", fz_to_name(obj)); + fz_throw(ctx, "unknown encryption handler: '%s'", fz_to_name(obj)); } crypt->v = 0; @@ -78,7 +77,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) if (crypt->v != 1 && crypt->v != 2 && crypt->v != 4 && crypt->v != 5) { pdf_free_crypt(ctx, crypt); - return fz_error_make("unknown encryption version"); + fz_throw(ctx, "unknown encryption version"); } crypt->length = 40; @@ -95,12 +94,12 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) if (crypt->length % 8 != 0) { pdf_free_crypt(ctx, crypt); - return fz_error_make("invalid encryption key length"); + fz_throw(ctx, "invalid encryption key length"); } if (crypt->length > 256) { pdf_free_crypt(ctx, crypt); - return fz_error_make("invalid encryption key length"); + fz_throw(ctx, "invalid encryption key length"); } } @@ -134,26 +133,20 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) crypt->cf = NULL; } - obj = fz_dict_gets(dict, "StmF"); - if (fz_is_name(obj)) + fz_try(ctx) { - error = pdf_parse_crypt_filter(ctx, &crypt->stmf, crypt->cf, fz_to_name(obj), crypt->length); - if (error) - { - pdf_free_crypt(ctx, crypt); - return fz_error_note(error, "cannot parse stream crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - } - } + obj = fz_dict_gets(dict, "StmF"); + if (fz_is_name(obj)) + pdf_parse_crypt_filter(ctx, &crypt->stmf, crypt->cf, fz_to_name(obj), crypt->length); - obj = fz_dict_gets(dict, "StrF"); - if (fz_is_name(obj)) + obj = fz_dict_gets(dict, "StrF"); + if (fz_is_name(obj)) + pdf_parse_crypt_filter(ctx, &crypt->strf, crypt->cf, fz_to_name(obj), crypt->length); + } + fz_catch(ctx) { - error = pdf_parse_crypt_filter(ctx, &crypt->strf, crypt->cf, fz_to_name(obj), crypt->length); - if (error) - { - pdf_free_crypt(ctx, crypt); - return fz_error_note(error, "cannot parse string crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - } + pdf_free_crypt(ctx, crypt); + fz_throw(ctx, "cannot parse string crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); } /* in crypt revision 4, the crypt filter determines the key length */ @@ -169,7 +162,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) else { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing revision value"); + fz_throw(ctx, "encryption dictionary missing revision value"); } obj = fz_dict_gets(dict, "O"); @@ -181,7 +174,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) else { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing owner password"); + fz_throw(ctx, "encryption dictionary missing owner password"); } obj = fz_dict_gets(dict, "U"); @@ -197,7 +190,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) else { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing user password"); + fz_throw(ctx, "encryption dictionary missing user password"); } obj = fz_dict_gets(dict, "P"); @@ -206,7 +199,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) else { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing permissions value"); + fz_throw(ctx, "encryption dictionary missing permissions value"); } if (crypt->r == 5) @@ -215,7 +208,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) if (!fz_is_string(obj) || fz_to_str_len(obj) != 32) { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing owner encryption key"); + fz_throw(ctx, "encryption dictionary missing owner encryption key"); } memcpy(crypt->oe, fz_to_str_buf(obj), 32); @@ -223,7 +216,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) if (!fz_is_string(obj) || fz_to_str_len(obj) != 32) { pdf_free_crypt(ctx, crypt); - return fz_error_make("encryption dictionary missing user encryption key"); + fz_throw(ctx, "encryption dictionary missing user encryption key"); } memcpy(crypt->ue, fz_to_str_buf(obj), 32); } @@ -244,8 +237,7 @@ pdf_new_crypt(fz_context *ctx, pdf_crypt **cryptp, fz_obj *dict, fz_obj *id) else fz_warn(ctx, "missing file identifier, may not be able to do decryption"); - *cryptp = crypt; - return fz_okay; + return crypt; } void diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c index 2bb69528..3a94527b 100644 --- a/pdf/pdf_font.c +++ b/pdf/pdf_font.c @@ -5,7 +5,7 @@ #include FT_FREETYPE_H #include FT_XFREE86_H -static fz_error pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection, char *basefont); +static void pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection, char *basefont); static char *base_font_names[14][7] = { @@ -170,71 +170,60 @@ static int lookup_mre_code(char *name) * Load font files. */ -static fz_error +static void pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname) { - fz_error error; unsigned char *data; unsigned int len; data = pdf_find_builtin_font(fontname, &len); if (!data) - return fz_error_make("cannot find builtin font: '%s'", fontname); + fz_throw(ctx, "cannot find builtin font: '%s'", fontname); - error = fz_new_font_from_memory(ctx, &fontdesc->font, data, len, 0); - if (error) - return fz_error_note(error, "cannot load freetype font from memory"); + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + /* RJW: "cannot load freetype font from memory" */ if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) fontdesc->flags |= PDF_FD_SYMBOLIC; - - return fz_okay; } -static fz_error +static void pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, int mono, int serif, int bold, int italic) { - fz_error error; unsigned char *data; unsigned int len; data = pdf_find_substitute_font(mono, serif, bold, italic, &len); if (!data) - return fz_error_make("cannot find substitute font"); + fz_throw(ctx, "cannot find substitute font"); - error = fz_new_font_from_memory(ctx, &fontdesc->font, data, len, 0); - if (error) - return fz_error_note(error, "cannot load freetype font from memory"); + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + /* RJW: "cannot load freetype font from memory" */ fontdesc->font->ft_substitute = 1; fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face); fontdesc->font->ft_italic = italic && !ft_is_italic(fontdesc->font->ft_face); - return fz_okay; } -static fz_error +static void pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, int ros, int serif) { - fz_error error; unsigned char *data; unsigned int len; data = pdf_find_substitute_cjk_font(ros, serif, &len); if (!data) - return fz_error_make("cannot find builtin CJK font"); + fz_throw(ctx, "cannot find builtin CJK font"); - error = fz_new_font_from_memory(ctx, &fontdesc->font, data, len, 0); - if (error) - return fz_error_note(error, "cannot load builtin CJK font"); + fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0); + /* RJW: "cannot load builtin CJK font" */ fontdesc->font->ft_substitute = 1; - return fz_okay; } -static fz_error +static void pdf_load_system_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, char *collection) { - fz_error error; int bold = 0; int italic = 0; int serif = 0; @@ -259,39 +248,45 @@ pdf_load_system_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, c if (collection) { if (!strcmp(collection, "Adobe-CNS1")) - return pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_CNS, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_CNS, serif); else if (!strcmp(collection, "Adobe-GB1")) - return pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_GB, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_GB, serif); else if (!strcmp(collection, "Adobe-Japan1")) - return pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_JAPAN, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_JAPAN, serif); else if (!strcmp(collection, "Adobe-Korea1")) - return pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_KOREA, serif); - return fz_error_make("unknown cid collection: %s", collection); + pdf_load_substitute_cjk_font(ctx, fontdesc, PDF_ROS_KOREA, serif); + else + fz_throw(ctx, "unknown cid collection: %s", collection); + return; } - error = pdf_load_substitute_font(ctx, fontdesc, mono, serif, bold, italic); - if (error) - return fz_error_note(error, "cannot load substitute font"); - - return fz_okay; + pdf_load_substitute_font(ctx, fontdesc, mono, serif, bold, italic); + /* RJW: "cannot load substitute font" */ } -static fz_error +static void pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *stmref) { - fz_error error; fz_buffer *buf; fz_context *ctx = xref->ctx; - error = pdf_load_stream(&buf, xref, fz_to_num(stmref), fz_to_gen(stmref)); - if (error) - return fz_error_note(error, "cannot load font stream (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref)); + fz_try(ctx) + { + buf = pdf_load_stream(xref, fz_to_num(stmref), fz_to_gen(stmref)); + } + fz_catch(ctx) + { + fz_throw(ctx, "cannot load font stream (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref)); + } - error = fz_new_font_from_memory(ctx, &fontdesc->font, buf->data, buf->len, 0); - if (error) + fz_try(ctx) + { + fontdesc->font = fz_new_font_from_memory(ctx, buf->data, buf->len, 0); + } + fz_catch(ctx) { fz_drop_buffer(ctx, buf); - return fz_error_note(error, "cannot load embedded font (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref)); + fz_throw(ctx, "cannot load embedded font (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref)); } /* save the buffer so we can free it later */ @@ -300,8 +295,6 @@ pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *stmref) fz_free(ctx, buf); /* only free the fz_buffer struct, not the contained data */ fontdesc->is_embedded = 1; - - return fz_okay; } /* @@ -391,15 +384,14 @@ pdf_new_font_desc(fz_context *ctx) * Simple fonts (Type1 and TrueType) */ -static fz_error -pdf_load_simple_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict) +static pdf_font_desc * +pdf_load_simple_font(pdf_xref *xref, fz_obj *dict) { - fz_error error; fz_obj *descriptor; fz_obj *encoding; fz_obj *widths; unsigned short *etable = NULL; - pdf_font_desc *fontdesc; + pdf_font_desc * volatile fontdesc; FT_Face face; FT_CharMap cmap; int symbolic; @@ -417,298 +409,294 @@ pdf_load_simple_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict) fontname = clean_font_name(basefont); /* Load font file */ + fz_try(ctx) + { + fontdesc = pdf_new_font_desc(ctx); - fontdesc = pdf_new_font_desc(ctx); + descriptor = fz_dict_gets(dict, "FontDescriptor"); + if (descriptor) + pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont); + else + pdf_load_builtin_font(ctx, fontdesc, fontname); - descriptor = fz_dict_gets(dict, "FontDescriptor"); - if (descriptor) - error = pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont); - else - error = pdf_load_builtin_font(ctx, fontdesc, fontname); - if (error) - goto cleanup; - - /* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */ - if (!*fontdesc->font->name && - !fz_dict_gets(dict, "ToUnicode") && - !strcmp(fz_to_name(fz_dict_gets(dict, "Encoding")), "WinAnsiEncoding") && - fz_to_int(fz_dict_gets(descriptor, "Flags")) == 4) - { - /* note: without the comma, pdf_load_font_descriptor would prefer /FontName over /BaseFont */ - char *cp936fonts[] = { - "\xCB\xCE\xCC\xE5", "SimSun,Regular", - "\xBA\xDA\xCC\xE5", "SimHei,Regular", - "\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular", - "\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular", - "\xC1\xA5\xCA\xE9", "SimLi,Regular", - NULL - }; - for (i = 0; cp936fonts[i]; i += 2) - if (!strcmp(basefont, cp936fonts[i])) - break; - if (cp936fonts[i]) + /* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */ + if (!*fontdesc->font->name && + !fz_dict_gets(dict, "ToUnicode") && + !strcmp(fz_to_name(fz_dict_gets(dict, "Encoding")), "WinAnsiEncoding") && + fz_to_int(fz_dict_gets(descriptor, "Flags")) == 4) { - fz_warn(ctx, "workaround for S22PDF lying about chinese font encodings"); - pdf_drop_font(ctx, fontdesc); - fontdesc = pdf_new_font_desc(ctx); - error = pdf_load_font_descriptor(fontdesc, xref, descriptor, "Adobe-GB1", cp936fonts[i+1]); - error |= pdf_load_system_cmap(ctx, &fontdesc->encoding, "GBK-EUC-H"); - error |= pdf_load_system_cmap(ctx, &fontdesc->to_unicode, "Adobe-GB1-UCS2"); - error |= pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-GB1-UCS2"); - if (error) - return fz_error_note(error, "cannot load font"); - - face = fontdesc->font->ft_face; - kind = ft_kind(face); - goto skip_encoding; + /* note: without the comma, pdf_load_font_descriptor would prefer /FontName over /BaseFont */ + char *cp936fonts[] = { + "\xCB\xCE\xCC\xE5", "SimSun,Regular", + "\xBA\xDA\xCC\xE5", "SimHei,Regular", + "\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular", + "\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular", + "\xC1\xA5\xCA\xE9", "SimLi,Regular", + NULL + }; + for (i = 0; cp936fonts[i]; i += 2) + if (!strcmp(basefont, cp936fonts[i])) + break; + if (cp936fonts[i]) + { + fz_warn(ctx, "workaround for S22PDF lying about chinese font encodings"); + pdf_drop_font(ctx, fontdesc); + fontdesc = pdf_new_font_desc(ctx); + pdf_load_font_descriptor(fontdesc, xref, descriptor, "Adobe-GB1", cp936fonts[i+1]); + fontdesc->encoding = pdf_load_system_cmap(ctx, "GBK-EUC-H"); + fontdesc->to_unicode = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); + /* RJW: "cannot load font" */ + + face = fontdesc->font->ft_face; + kind = ft_kind(face); + goto skip_encoding; + } } - } - face = fontdesc->font->ft_face; - kind = ft_kind(face); + face = fontdesc->font->ft_face; + kind = ft_kind(face); - /* Encoding */ + /* Encoding */ - symbolic = fontdesc->flags & 4; + symbolic = fontdesc->flags & 4; - if (face->num_charmaps > 0) - cmap = face->charmaps[0]; - else - cmap = NULL; - - for (i = 0; i < face->num_charmaps; i++) - { - FT_CharMap test = face->charmaps[i]; + if (face->num_charmaps > 0) + cmap = face->charmaps[0]; + else + cmap = NULL; - if (kind == TYPE1) + for (i = 0; i < face->num_charmaps; i++) { - if (test->platform_id == 7) - cmap = test; + FT_CharMap test = face->charmaps[i]; + + if (kind == TYPE1) + { + if (test->platform_id == 7) + cmap = test; + } + + if (kind == TRUETYPE) + { + if (test->platform_id == 1 && test->encoding_id == 0) + cmap = test; + if (test->platform_id == 3 && test->encoding_id == 1) + cmap = test; + } } - if (kind == TRUETYPE) + if (cmap) { - if (test->platform_id == 1 && test->encoding_id == 0) - cmap = test; - if (test->platform_id == 3 && test->encoding_id == 1) - cmap = test; + fterr = FT_Set_Charmap(face, cmap); + if (fterr) + fz_warn(ctx, "freetype could not set cmap: %s", ft_error_string(fterr)); } - } - - if (cmap) - { - fterr = FT_Set_Charmap(face, cmap); - if (fterr) - fz_warn(ctx, "freetype could not set cmap: %s", ft_error_string(fterr)); - } - else - fz_warn(ctx, "freetype could not find any cmaps"); - - etable = fz_malloc_array(ctx, 256, sizeof(unsigned short)); - for (i = 0; i < 256; i++) - { - estrings[i] = NULL; - etable[i] = 0; - } - - encoding = fz_dict_gets(dict, "Encoding"); - if (encoding) - { - if (fz_is_name(encoding)) - pdf_load_encoding(estrings, fz_to_name(encoding)); + else + fz_warn(ctx, "freetype could not find any cmaps"); - if (fz_is_dict(encoding)) + etable = fz_malloc_array(ctx, 256, sizeof(unsigned short)); + for (i = 0; i < 256; i++) { - fz_obj *base, *diff, *item; + estrings[i] = NULL; + etable[i] = 0; + } - base = fz_dict_gets(encoding, "BaseEncoding"); - if (fz_is_name(base)) - pdf_load_encoding(estrings, fz_to_name(base)); - else if (!fontdesc->is_embedded && !symbolic) - pdf_load_encoding(estrings, "StandardEncoding"); + encoding = fz_dict_gets(dict, "Encoding"); + if (encoding) + { + if (fz_is_name(encoding)) + pdf_load_encoding(estrings, fz_to_name(encoding)); - diff = fz_dict_gets(encoding, "Differences"); - if (fz_is_array(diff)) + if (fz_is_dict(encoding)) { - n = fz_array_len(diff); - k = 0; - for (i = 0; i < n; i++) + fz_obj *base, *diff, *item; + + base = fz_dict_gets(encoding, "BaseEncoding"); + if (fz_is_name(base)) + pdf_load_encoding(estrings, fz_to_name(base)); + else if (!fontdesc->is_embedded && !symbolic) + pdf_load_encoding(estrings, "StandardEncoding"); + + diff = fz_dict_gets(encoding, "Differences"); + if (fz_is_array(diff)) { - item = fz_array_get(diff, i); - if (fz_is_int(item)) - k = fz_to_int(item); - if (fz_is_name(item)) - estrings[k++] = fz_to_name(item); - if (k < 0) k = 0; - if (k > 255) k = 255; + n = fz_array_len(diff); + k = 0; + for (i = 0; i < n; i++) + { + item = fz_array_get(diff, i); + if (fz_is_int(item)) + k = fz_to_int(item); + if (fz_is_name(item)) + estrings[k++] = fz_to_name(item); + if (k < 0) k = 0; + if (k > 255) k = 255; + } } } } - } - /* start with the builtin encoding */ - for (i = 0; i < 256; i++) - etable[i] = ft_char_index(face, i); - - /* encode by glyph name where we can */ - if (kind == TYPE1) - { + /* start with the builtin encoding */ for (i = 0; i < 256; i++) + etable[i] = ft_char_index(face, i); + + /* encode by glyph name where we can */ + if (kind == TYPE1) { - if (estrings[i]) + for (i = 0; i < 256; i++) { - etable[i] = FT_Get_Name_Index(face, estrings[i]); - if (etable[i] == 0) + if (estrings[i]) { - int aglcode = pdf_lookup_agl(estrings[i]); - const char **dupnames = pdf_lookup_agl_duplicates(aglcode); - while (*dupnames) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + if (etable[i] == 0) { - etable[i] = FT_Get_Name_Index(face, (char*)*dupnames); - if (etable[i]) - break; - dupnames++; + int aglcode = pdf_lookup_agl(estrings[i]); + const char **dupnames = pdf_lookup_agl_duplicates(aglcode); + while (*dupnames) + { + etable[i] = FT_Get_Name_Index(face, (char*)*dupnames); + if (etable[i]) + break; + dupnames++; + } } } } } - } - /* encode by glyph name where we can */ - if (kind == TRUETYPE) - { - /* Unicode cmap */ - if (!symbolic && face->charmap && face->charmap->platform_id == 3) + /* encode by glyph name where we can */ + if (kind == TRUETYPE) { - for (i = 0; i < 256; i++) + /* Unicode cmap */ + if (!symbolic && face->charmap && face->charmap->platform_id == 3) { - if (estrings[i]) + for (i = 0; i < 256; i++) { - int aglcode = pdf_lookup_agl(estrings[i]); - if (!aglcode) - etable[i] = FT_Get_Name_Index(face, estrings[i]); - else - etable[i] = ft_char_index(face, aglcode); + if (estrings[i]) + { + int aglcode = pdf_lookup_agl(estrings[i]); + if (!aglcode) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + else + etable[i] = ft_char_index(face, aglcode); + } } } - } - /* MacRoman cmap */ - else if (!symbolic && face->charmap && face->charmap->platform_id == 1) - { - for (i = 0; i < 256; i++) + /* MacRoman cmap */ + else if (!symbolic && face->charmap && face->charmap->platform_id == 1) { - if (estrings[i]) + for (i = 0; i < 256; i++) { - k = lookup_mre_code(estrings[i]); - if (k <= 0) - etable[i] = FT_Get_Name_Index(face, estrings[i]); - else - etable[i] = ft_char_index(face, k); + if (estrings[i]) + { + k = lookup_mre_code(estrings[i]); + if (k <= 0) + etable[i] = FT_Get_Name_Index(face, estrings[i]); + else + etable[i] = ft_char_index(face, k); + } } } - } - /* Symbolic cmap */ - else - { - for (i = 0; i < 256; i++) + /* Symbolic cmap */ + else { - if (estrings[i]) + for (i = 0; i < 256; i++) { - etable[i] = FT_Get_Name_Index(face, estrings[i]); - if (etable[i] == 0) - etable[i] = ft_char_index(face, i); + if (estrings[i]) + { + etable[i] = FT_Get_Name_Index(face, estrings[i]); + if (etable[i] == 0) + etable[i] = ft_char_index(face, i); + } } } } - } - /* try to reverse the glyph names from the builtin encoding */ - for (i = 0; i < 256; i++) - { - if (etable[i] && !estrings[i]) + /* try to reverse the glyph names from the builtin encoding */ + for (i = 0; i < 256; i++) { - if (FT_HAS_GLYPH_NAMES(face)) + if (etable[i] && !estrings[i]) { - fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); - if (fterr) - fz_warn(ctx, "freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr)); - if (ebuffer[i][0]) - estrings[i] = ebuffer[i]; - } - else - { - estrings[i] = (char*) pdf_win_ansi[i]; /* discard const */ + if (FT_HAS_GLYPH_NAMES(face)) + { + fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); + if (fterr) + fz_warn(ctx, "freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr)); + if (ebuffer[i][0]) + estrings[i] = ebuffer[i]; + } + else + { + estrings[i] = (char*) pdf_win_ansi[i]; /* discard const */ + } } } - } - fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); - fontdesc->cid_to_gid_len = 256; - fontdesc->cid_to_gid = etable; + fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); + fontdesc->cid_to_gid_len = 256; + fontdesc->cid_to_gid = etable; - error = pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode")); - if (error) - fz_error_handle(error, "cannot load to_unicode"); + pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode")); + /* RJW: "cannot load to_unicode" */ -skip_encoding: + skip_encoding: - /* Widths */ + /* Widths */ - pdf_set_default_hmtx(fontdesc, fontdesc->missing_width); + pdf_set_default_hmtx(fontdesc, fontdesc->missing_width); - widths = fz_dict_gets(dict, "Widths"); - if (widths) - { - int first, last; + widths = fz_dict_gets(dict, "Widths"); + if (widths) + { + int first, last; - first = fz_to_int(fz_dict_gets(dict, "FirstChar")); - last = fz_to_int(fz_dict_gets(dict, "LastChar")); + first = fz_to_int(fz_dict_gets(dict, "FirstChar")); + last = fz_to_int(fz_dict_gets(dict, "LastChar")); - if (first < 0 || last > 255 || first > last) - first = last = 0; + if (first < 0 || last > 255 || first > last) + first = last = 0; - for (i = 0; i < last - first + 1; i++) + for (i = 0; i < last - first + 1; i++) + { + int wid = fz_to_int(fz_array_get(widths, i)); + pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid); + } + } + else { - int wid = fz_to_int(fz_array_get(widths, i)); - pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid); + fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72); + if (fterr) + fz_warn(ctx, "freetype set character size: %s", ft_error_string(fterr)); + for (i = 0; i < 256; i++) + { + pdf_add_hmtx(ctx, fontdesc, i, i, ft_width(ctx, fontdesc, i)); + } } + + pdf_end_hmtx(fontdesc); } - else + fz_catch(ctx) { - fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72); - if (fterr) - fz_warn(ctx, "freetype set character size: %s", ft_error_string(fterr)); - for (i = 0; i < 256; i++) - { - pdf_add_hmtx(ctx, fontdesc, i, i, ft_width(ctx, fontdesc, i)); - } + if (etable != fontdesc->cid_to_gid) + fz_free(ctx, etable); + pdf_drop_font(ctx, fontdesc); + fz_throw(ctx, "cannot load simple font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); } - - pdf_end_hmtx(fontdesc); - - *fontdescp = fontdesc; - return fz_okay; - -cleanup: - if (etable != fontdesc->cid_to_gid) - fz_free(ctx, etable); - pdf_drop_font(ctx, fontdesc); - return fz_error_note(error, "cannot load simple font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + return fontdesc; } /* * CID Fonts */ -static fz_error -load_cid_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_unicode) +static pdf_font_desc * +load_cid_font(pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_unicode) { - fz_error error; fz_obj *widths; fz_obj *descriptor; - pdf_font_desc *fontdesc; + pdf_font_desc * volatile fontdesc; FT_Face face; int kind; char collection[256]; @@ -718,192 +706,129 @@ load_cid_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *e int dw; fz_context *ctx = xref->ctx; - /* Get font name and CID collection */ - - basefont = fz_to_name(fz_dict_gets(dict, "BaseFont")); - + fz_try(ctx) { - fz_obj *cidinfo; - char tmpstr[64]; - int tmplen; - - cidinfo = fz_dict_gets(dict, "CIDSystemInfo"); - if (!cidinfo) - return fz_error_make("cid font is missing info"); - - obj = fz_dict_gets(cidinfo, "Registry"); - tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj)); - memcpy(tmpstr, fz_to_str_buf(obj), tmplen); - tmpstr[tmplen] = '\0'; - fz_strlcpy(collection, tmpstr, sizeof collection); - - fz_strlcat(collection, "-", sizeof collection); - - obj = fz_dict_gets(cidinfo, "Ordering"); - tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj)); - memcpy(tmpstr, fz_to_str_buf(obj), tmplen); - tmpstr[tmplen] = '\0'; - fz_strlcat(collection, tmpstr, sizeof collection); - } - - /* Load font file */ + /* Get font name and CID collection */ - fontdesc = pdf_new_font_desc(ctx); + basefont = fz_to_name(fz_dict_gets(dict, "BaseFont")); - descriptor = fz_dict_gets(dict, "FontDescriptor"); - if (descriptor) - error = pdf_load_font_descriptor(fontdesc, xref, descriptor, collection, basefont); - else - error = fz_error_make("syntaxerror: missing font descriptor"); - if (error) - goto cleanup; + { + fz_obj *cidinfo; + char tmpstr[64]; + int tmplen; + + cidinfo = fz_dict_gets(dict, "CIDSystemInfo"); + if (!cidinfo) + fz_throw(ctx, "cid font is missing info"); + + obj = fz_dict_gets(cidinfo, "Registry"); + tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj)); + memcpy(tmpstr, fz_to_str_buf(obj), tmplen); + tmpstr[tmplen] = '\0'; + fz_strlcpy(collection, tmpstr, sizeof collection); + + fz_strlcat(collection, "-", sizeof collection); + + obj = fz_dict_gets(cidinfo, "Ordering"); + tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj)); + memcpy(tmpstr, fz_to_str_buf(obj), tmplen); + tmpstr[tmplen] = '\0'; + fz_strlcat(collection, tmpstr, sizeof collection); + } - face = fontdesc->font->ft_face; - kind = ft_kind(face); + /* Load font file */ - /* Encoding */ + fontdesc = pdf_new_font_desc(ctx); - error = fz_okay; - if (fz_is_name(encoding)) - { - if (!strcmp(fz_to_name(encoding), "Identity-H")) - fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 2); - else if (!strcmp(fz_to_name(encoding), "Identity-V")) - fontdesc->encoding = pdf_new_identity_cmap(ctx, 1, 2); - else - error = pdf_load_system_cmap(ctx, &fontdesc->encoding, fz_to_name(encoding)); - } - else if (fz_is_indirect(encoding)) - { - error = pdf_load_embedded_cmap(&fontdesc->encoding, xref, encoding); - } - else - { - error = fz_error_make("syntaxerror: font missing encoding"); - } - if (error) - goto cleanup; + descriptor = fz_dict_gets(dict, "FontDescriptor"); + if (descriptor == NULL) + fz_throw(ctx, "syntaxerror: missing font descriptor"); + pdf_load_font_descriptor(fontdesc, xref, descriptor, collection, basefont); - pdf_set_font_wmode(fontdesc, pdf_get_wmode(fontdesc->encoding)); + face = fontdesc->font->ft_face; + kind = ft_kind(face); - if (kind == TRUETYPE) - { - fz_obj *cidtogidmap; + /* Encoding */ - cidtogidmap = fz_dict_gets(dict, "CIDToGIDMap"); - if (fz_is_indirect(cidtogidmap)) + if (fz_is_name(encoding)) { - fz_buffer *buf; - - error = pdf_load_stream(&buf, xref, fz_to_num(cidtogidmap), fz_to_gen(cidtogidmap)); - if (error) - goto cleanup; - - fontdesc->cid_to_gid_len = (buf->len) / 2; - fontdesc->cid_to_gid = fz_malloc_array(ctx, fontdesc->cid_to_gid_len, sizeof(unsigned short)); - for (i = 0; i < fontdesc->cid_to_gid_len; i++) - fontdesc->cid_to_gid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1]; - - fz_drop_buffer(ctx, buf); + if (!strcmp(fz_to_name(encoding), "Identity-H")) + fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 2); + else if (!strcmp(fz_to_name(encoding), "Identity-V")) + fontdesc->encoding = pdf_new_identity_cmap(ctx, 1, 2); + else + fontdesc->encoding = pdf_load_system_cmap(ctx, fz_to_name(encoding)); } - - /* if truetype font is external, cidtogidmap should not be identity */ - /* so we map from cid to unicode and then map that through the (3 1) */ - /* unicode cmap to get a glyph id */ - else if (fontdesc->font->ft_substitute) + else if (fz_is_indirect(encoding)) { - fterr = FT_Select_Charmap(face, ft_encoding_unicode); - if (fterr) - { - error = fz_error_make("fonterror: no unicode cmap when emulating CID font: %s", ft_error_string(fterr)); - goto cleanup; - } + fontdesc->encoding = pdf_load_embedded_cmap(xref, encoding); + } + else + { + fz_throw(ctx, "syntaxerror: font missing encoding"); + } - if (!strcmp(collection, "Adobe-CNS1")) - error = pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-CNS1-UCS2"); - else if (!strcmp(collection, "Adobe-GB1")) - error = pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-GB1-UCS2"); - else if (!strcmp(collection, "Adobe-Japan1")) - error = pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-Japan1-UCS2"); - else if (!strcmp(collection, "Adobe-Japan2")) - error = pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-Japan2-UCS2"); - else if (!strcmp(collection, "Adobe-Korea1")) - error = pdf_load_system_cmap(ctx, &fontdesc->to_ttf_cmap, "Adobe-Korea1-UCS2"); - else - error = fz_okay; + pdf_set_font_wmode(fontdesc, pdf_get_wmode(fontdesc->encoding)); - if (error) - { - error = fz_error_note(error, "cannot load system cmap %s", collection); - goto cleanup; - } - } - } + if (kind == TRUETYPE) + { + fz_obj *cidtogidmap; - error = pdf_load_to_unicode(fontdesc, xref, NULL, collection, to_unicode); - if (error) - fz_error_handle(error, "cannot load to_unicode"); + cidtogidmap = fz_dict_gets(dict, "CIDToGIDMap"); + if (fz_is_indirect(cidtogidmap)) + { + fz_buffer *buf; - /* Horizontal */ + buf = pdf_load_stream(xref, fz_to_num(cidtogidmap), fz_to_gen(cidtogidmap)); - dw = 1000; - obj = fz_dict_gets(dict, "DW"); - if (obj) - dw = fz_to_int(obj); - pdf_set_default_hmtx(fontdesc, dw); + fontdesc->cid_to_gid_len = (buf->len) / 2; + fontdesc->cid_to_gid = fz_malloc_array(ctx, fontdesc->cid_to_gid_len, sizeof(unsigned short)); + for (i = 0; i < fontdesc->cid_to_gid_len; i++) + fontdesc->cid_to_gid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1]; - widths = fz_dict_gets(dict, "W"); - if (widths) - { - int c0, c1, w, n, m; + fz_drop_buffer(ctx, buf); + } - n = fz_array_len(widths); - for (i = 0; i < n; ) - { - c0 = fz_to_int(fz_array_get(widths, i)); - obj = fz_array_get(widths, i + 1); - if (fz_is_array(obj)) + /* if truetype font is external, cidtogidmap should not be identity */ + /* so we map from cid to unicode and then map that through the (3 1) */ + /* unicode cmap to get a glyph id */ + else if (fontdesc->font->ft_substitute) { - m = fz_array_len(obj); - for (k = 0; k < m; k++) + fterr = FT_Select_Charmap(face, ft_encoding_unicode); + if (fterr) { - w = fz_to_int(fz_array_get(obj, k)); - pdf_add_hmtx(ctx, fontdesc, c0 + k, c0 + k, w); + fz_throw(ctx, "fonterror: no unicode cmap when emulating CID font: %s", ft_error_string(fterr)); } - i += 2; - } - else - { - c1 = fz_to_int(obj); - w = fz_to_int(fz_array_get(widths, i + 2)); - pdf_add_hmtx(ctx, fontdesc, c0, c1, w); - i += 3; + + if (!strcmp(collection, "Adobe-CNS1")) + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-CNS1-UCS2"); + else if (!strcmp(collection, "Adobe-GB1")) + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan1")) + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan1-UCS2"); + else if (!strcmp(collection, "Adobe-Japan2")) + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan2-UCS2"); + else if (!strcmp(collection, "Adobe-Korea1")) + fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Korea1-UCS2"); + /* RJW: "cannot load system cmap %s", collection */ } } - } - pdf_end_hmtx(fontdesc); + pdf_load_to_unicode(fontdesc, xref, NULL, collection, to_unicode); + /* RJW: "cannot load to_unicode" */ - /* Vertical */ - - if (pdf_get_wmode(fontdesc->encoding) == 1) - { - int dw2y = 880; - int dw2w = -1000; + /* Horizontal */ - obj = fz_dict_gets(dict, "DW2"); + dw = 1000; + obj = fz_dict_gets(dict, "DW"); if (obj) - { - dw2y = fz_to_int(fz_array_get(obj, 0)); - dw2w = fz_to_int(fz_array_get(obj, 1)); - } - - pdf_set_default_vmtx(fontdesc, dw2y, dw2w); + dw = fz_to_int(obj); + pdf_set_default_hmtx(fontdesc, dw); - widths = fz_dict_gets(dict, "W2"); + widths = fz_dict_gets(dict, "W"); if (widths) { - int c0, c1, w, x, y, n; + int c0, c1, w, n, m; n = fz_array_len(widths); for (i = 0; i < n; ) @@ -912,13 +837,11 @@ load_cid_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *e obj = fz_array_get(widths, i + 1); if (fz_is_array(obj)) { - int m = fz_array_len(obj); - for (k = 0; k * 3 < m; k ++) + m = fz_array_len(obj); + for (k = 0; k < m; k++) { - w = fz_to_int(fz_array_get(obj, k * 3 + 0)); - x = fz_to_int(fz_array_get(obj, k * 3 + 1)); - y = fz_to_int(fz_array_get(obj, k * 3 + 2)); - pdf_add_vmtx(ctx, fontdesc, c0 + k, c0 + k, x, y, w); + w = fz_to_int(fz_array_get(obj, k)); + pdf_add_hmtx(ctx, fontdesc, c0 + k, c0 + k, w); } i += 2; } @@ -926,29 +849,79 @@ load_cid_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *e { c1 = fz_to_int(obj); w = fz_to_int(fz_array_get(widths, i + 2)); - x = fz_to_int(fz_array_get(widths, i + 3)); - y = fz_to_int(fz_array_get(widths, i + 4)); - pdf_add_vmtx(ctx, fontdesc, c0, c1, x, y, w); - i += 5; + pdf_add_hmtx(ctx, fontdesc, c0, c1, w); + i += 3; } } } - pdf_end_vmtx(fontdesc); - } + pdf_end_hmtx(fontdesc); + + /* Vertical */ + + if (pdf_get_wmode(fontdesc->encoding) == 1) + { + int dw2y = 880; + int dw2w = -1000; + + obj = fz_dict_gets(dict, "DW2"); + if (obj) + { + dw2y = fz_to_int(fz_array_get(obj, 0)); + dw2w = fz_to_int(fz_array_get(obj, 1)); + } + + pdf_set_default_vmtx(fontdesc, dw2y, dw2w); + + widths = fz_dict_gets(dict, "W2"); + if (widths) + { + int c0, c1, w, x, y, n; - *fontdescp = fontdesc; - return fz_okay; + n = fz_array_len(widths); + for (i = 0; i < n; ) + { + c0 = fz_to_int(fz_array_get(widths, i)); + obj = fz_array_get(widths, i + 1); + if (fz_is_array(obj)) + { + int m = fz_array_len(obj); + for (k = 0; k * 3 < m; k ++) + { + w = fz_to_int(fz_array_get(obj, k * 3 + 0)); + x = fz_to_int(fz_array_get(obj, k * 3 + 1)); + y = fz_to_int(fz_array_get(obj, k * 3 + 2)); + pdf_add_vmtx(ctx, fontdesc, c0 + k, c0 + k, x, y, w); + } + i += 2; + } + else + { + c1 = fz_to_int(obj); + w = fz_to_int(fz_array_get(widths, i + 2)); + x = fz_to_int(fz_array_get(widths, i + 3)); + y = fz_to_int(fz_array_get(widths, i + 4)); + pdf_add_vmtx(ctx, fontdesc, c0, c1, x, y, w); + i += 5; + } + } + } -cleanup: - pdf_drop_font(ctx, fontdesc); - return fz_error_note(error, "cannot load cid font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + pdf_end_vmtx(fontdesc); + } + } + fz_catch(ctx) + { + pdf_drop_font(ctx, fontdesc); + fz_throw(ctx, "cannot load cid font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + } + + return fontdesc; } -static fz_error -pdf_load_type0_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict) +static pdf_font_desc * +pdf_load_type0_font(pdf_xref *xref, fz_obj *dict) { - fz_error error; fz_obj *dfonts; fz_obj *dfont; fz_obj *subtype; @@ -957,7 +930,7 @@ pdf_load_type0_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict) dfonts = fz_dict_gets(dict, "DescendantFonts"); if (!dfonts) - return fz_error_make("cid font is missing descendant fonts"); + fz_throw(xref->ctx, "cid font is missing descendant fonts"); dfont = fz_array_get(dfonts, 0); @@ -966,25 +939,22 @@ pdf_load_type0_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict) to_unicode = fz_dict_gets(dict, "ToUnicode"); if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType0")) - error = load_cid_font(fontdescp, xref, dfont, encoding, to_unicode); + return load_cid_font(xref, dfont, encoding, to_unicode); else if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType2")) - error = load_cid_font(fontdescp, xref, dfont, encoding, to_unicode); + return load_cid_font(xref, dfont, encoding, to_unicode); else - error = fz_error_make("syntaxerror: unknown cid font type"); - if (error) - return fz_error_note(error, "cannot load descendant font (%d %d R)", fz_to_num(dfont), fz_to_gen(dfont)); - - return fz_okay; + fz_throw(xref->ctx, "syntaxerror: unknown cid font type"); + /* RJW: "cannot load descendant font (%d %d R)", fz_to_num(dfont), fz_to_gen(dfont) */ + return NULL; /* Stupid MSVC */ } /* * FontDescriptor */ -static fz_error +static void pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection, char *basefont) { - fz_error error; fz_obj *obj1, *obj2, *obj3, *obj; char *fontname; char *origname; @@ -1012,26 +982,27 @@ pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, if (fz_is_indirect(obj)) { - error = pdf_load_embedded_font(fontdesc, xref, obj); - if (error) + fz_try(ctx) { - fz_error_handle(error, "ignored error when loading embedded font, attempting to load system font"); + pdf_load_embedded_font(fontdesc, xref, obj); + } + fz_catch(ctx) + { + fz_error_handle(-1, "ignored error when loading embedded font, attempting to load system font"); if (origname != fontname) - error = pdf_load_builtin_font(ctx, fontdesc, fontname); + pdf_load_builtin_font(ctx, fontdesc, fontname); else - error = pdf_load_system_font(ctx, fontdesc, fontname, collection); - if (error) - return fz_error_note(error, "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + pdf_load_system_font(ctx, fontdesc, fontname, collection); + /* RJW: "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */ } } else { if (origname != fontname) - error = pdf_load_builtin_font(ctx, fontdesc, fontname); + pdf_load_builtin_font(ctx, fontdesc, fontname); else - error = pdf_load_system_font(ctx, fontdesc, fontname, collection); - if (error) - return fz_error_note(error, "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + pdf_load_system_font(ctx, fontdesc, fontname, collection); + /* RJW: "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */ } fz_strlcpy(fontdesc->font->name, fontname, sizeof fontdesc->font->name); @@ -1043,9 +1014,6 @@ pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, if (FT_IS_TRICKY(face) || is_dynalab(fontdesc->font->name)) fontdesc->font->ft_hint = 1; } - - return fz_okay; - } static void @@ -1081,19 +1049,19 @@ pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc) } } -fz_error -pdf_load_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) +pdf_font_desc * +pdf_load_font(pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { - fz_error error; char *subtype; fz_obj *dfonts; fz_obj *charprocs; fz_context *ctx = xref->ctx; + pdf_font_desc *fontdesc; - if ((*fontdescp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_font, dict))) + if ((fontdesc = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_font, dict))) { - pdf_keep_font(*fontdescp); - return fz_okay; + pdf_keep_font(fontdesc); + return fontdesc; } subtype = fz_to_name(fz_dict_gets(dict, "Subtype")); @@ -1101,40 +1069,39 @@ pdf_load_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *di charprocs = fz_dict_gets(dict, "CharProcs"); if (subtype && !strcmp(subtype, "Type0")) - error = pdf_load_type0_font(fontdescp, xref, dict); + fontdesc = pdf_load_type0_font(xref, dict); else if (subtype && !strcmp(subtype, "Type1")) - error = pdf_load_simple_font(fontdescp, xref, dict); + fontdesc = pdf_load_simple_font(xref, dict); else if (subtype && !strcmp(subtype, "MMType1")) - error = pdf_load_simple_font(fontdescp, xref, dict); + fontdesc = pdf_load_simple_font(xref, dict); else if (subtype && !strcmp(subtype, "TrueType")) - error = pdf_load_simple_font(fontdescp, xref, dict); + fontdesc = pdf_load_simple_font(xref, dict); else if (subtype && !strcmp(subtype, "Type3")) - error = pdf_load_type3_font(fontdescp, xref, rdb, dict); + fontdesc = pdf_load_type3_font(xref, rdb, dict); else if (charprocs) { fz_warn(ctx, "unknown font format, guessing type3."); - error = pdf_load_type3_font(fontdescp, xref, rdb, dict); + fontdesc = pdf_load_type3_font(xref, rdb, dict); } else if (dfonts) { fz_warn(ctx, "unknown font format, guessing type0."); - error = pdf_load_type0_font(fontdescp, xref, dict); + fontdesc = pdf_load_type0_font(xref, dict); } else { fz_warn(ctx, "unknown font format, guessing type1 or truetype."); - error = pdf_load_simple_font(fontdescp, xref, dict); + fontdesc = pdf_load_simple_font(xref, dict); } - if (error) - return fz_error_note(error, "cannot load font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + /* RJW: "cannot load font (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */ /* Save the widths to stretch non-CJK substitute fonts */ - if ((*fontdescp)->font->ft_substitute && !(*fontdescp)->to_ttf_cmap) - pdf_make_width_table(ctx, *fontdescp); + if (fontdesc->font->ft_substitute && !fontdesc->to_ttf_cmap) + pdf_make_width_table(ctx, fontdesc); - pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)pdf_keep_font, (pdf_store_drop_fn *)pdf_drop_font, dict, *fontdescp); + pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)pdf_keep_font, (pdf_store_drop_fn *)pdf_drop_font, dict, fontdesc); - return fz_okay; + return fontdesc; } void diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index 9078c65a..3ef0d75f 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -681,38 +681,37 @@ resize_code(fz_context *ctx, pdf_function *func, int newsize) } } -static fz_error +static void parse_code(pdf_function *func, fz_stream *stream, int *codeptr) { - fz_error error; char buf[64]; int len; int tok; int opptr, elseptr, ifptr; int a, b, mid, cmp; + fz_context *ctx = stream->ctx; memset(buf, 0, sizeof(buf)); while (1) { - error = pdf_lex(&tok, stream, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "calculator function lexical error"); + tok = pdf_lex(stream, buf, sizeof buf, &len); + /* RJW: "calculator function lexical error" */ switch(tok) { case PDF_TOK_EOF: - return fz_error_make("truncated calculator function"); + fz_throw(ctx, "truncated calculator function"); case PDF_TOK_INT: - resize_code(stream->ctx, func, *codeptr); + resize_code(ctx, func, *codeptr); func->u.p.code[*codeptr].type = PS_INT; func->u.p.code[*codeptr].u.i = atoi(buf); ++*codeptr; break; case PDF_TOK_REAL: - resize_code(stream->ctx, func, *codeptr); + resize_code(ctx, func, *codeptr); func->u.p.code[*codeptr].type = PS_REAL; func->u.p.code[*codeptr].u.f = fz_atof(buf); ++*codeptr; @@ -722,76 +721,68 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr) opptr = *codeptr; *codeptr += 4; - resize_code(stream->ctx, func, *codeptr); + resize_code(ctx, func, *codeptr); ifptr = *codeptr; - error = parse_code(func, stream, codeptr); - if (error) - return fz_error_note(error, "error in 'if' branch"); + parse_code(func, stream, codeptr); + /* RJW: "error in 'if' branch" */ - error = pdf_lex(&tok, stream, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "calculator function syntax error"); + tok = pdf_lex(stream, buf, sizeof buf, &len); + /* RJW: "calculator function syntax error" */ if (tok == PDF_TOK_OPEN_BRACE) { elseptr = *codeptr; - error = parse_code(func, stream, codeptr); - if (error) - return fz_error_note(error, "error in 'else' branch"); + parse_code(func, stream, codeptr); + /* RJW: "error in 'else' branch" */ - error = pdf_lex(&tok, stream, buf, sizeof buf, &len); - if (error) - return fz_error_note(error, "calculator function syntax error"); + tok = pdf_lex(stream, buf, sizeof buf, &len); + /* RJW: "calculator function syntax error" */ } else { elseptr = -1; } - if (tok == PDF_TOK_KEYWORD) + if (tok != PDF_TOK_KEYWORD) + fz_throw(ctx, "missing keyword in 'if-else' context"); + + if (!strcmp(buf, "if")) { - if (!strcmp(buf, "if")) - { - if (elseptr >= 0) - return fz_error_make("too many branches for 'if'"); - func->u.p.code[opptr].type = PS_OPERATOR; - func->u.p.code[opptr].u.op = PS_OP_IF; - func->u.p.code[opptr+2].type = PS_BLOCK; - func->u.p.code[opptr+2].u.block = ifptr; - func->u.p.code[opptr+3].type = PS_BLOCK; - func->u.p.code[opptr+3].u.block = *codeptr; - } - else if (!strcmp(buf, "ifelse")) - { - if (elseptr < 0) - return fz_error_make("not enough branches for 'ifelse'"); - func->u.p.code[opptr].type = PS_OPERATOR; - func->u.p.code[opptr].u.op = PS_OP_IFELSE; - func->u.p.code[opptr+1].type = PS_BLOCK; - func->u.p.code[opptr+1].u.block = elseptr; - func->u.p.code[opptr+2].type = PS_BLOCK; - func->u.p.code[opptr+2].u.block = ifptr; - func->u.p.code[opptr+3].type = PS_BLOCK; - func->u.p.code[opptr+3].u.block = *codeptr; - } - else - { - return fz_error_make("unknown keyword in 'if-else' context: '%s'", buf); - } + if (elseptr >= 0) + fz_throw(ctx, "too many branches for 'if'"); + func->u.p.code[opptr].type = PS_OPERATOR; + func->u.p.code[opptr].u.op = PS_OP_IF; + func->u.p.code[opptr+2].type = PS_BLOCK; + func->u.p.code[opptr+2].u.block = ifptr; + func->u.p.code[opptr+3].type = PS_BLOCK; + func->u.p.code[opptr+3].u.block = *codeptr; + } + else if (!strcmp(buf, "ifelse")) + { + if (elseptr < 0) + fz_throw(ctx, "not enough branches for 'ifelse'"); + func->u.p.code[opptr].type = PS_OPERATOR; + func->u.p.code[opptr].u.op = PS_OP_IFELSE; + func->u.p.code[opptr+1].type = PS_BLOCK; + func->u.p.code[opptr+1].u.block = elseptr; + func->u.p.code[opptr+2].type = PS_BLOCK; + func->u.p.code[opptr+2].u.block = ifptr; + func->u.p.code[opptr+3].type = PS_BLOCK; + func->u.p.code[opptr+3].u.block = *codeptr; } else { - return fz_error_make("missing keyword in 'if-else' context"); + fz_throw(ctx, "unknown keyword in 'if-else' context: '%s'", buf); } break; case PDF_TOK_CLOSE_BRACE: - resize_code(stream->ctx, func, *codeptr); + resize_code(ctx, func, *codeptr); func->u.p.code[*codeptr].type = PS_OPERATOR; func->u.p.code[*codeptr].u.op = PS_OP_RETURN; ++*codeptr; - return fz_okay; + return; case PDF_TOK_KEYWORD: cmp = -1; @@ -809,60 +800,54 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr) a = b = mid; } if (cmp != 0) - return fz_error_make("unknown operator: '%s'", buf); + fz_throw(ctx, "unknown operator: '%s'", buf); - resize_code(stream->ctx, func, *codeptr); + resize_code(ctx, func, *codeptr); func->u.p.code[*codeptr].type = PS_OPERATOR; func->u.p.code[*codeptr].u.op = a; ++*codeptr; break; default: - return fz_error_make("calculator function syntax error"); + fz_throw(ctx, "calculator function syntax error"); } } } -static fz_error +static void load_postscript_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int gen) { - fz_error error; - fz_stream *stream; + fz_stream * volatile stream = NULL; int codeptr; char buf[64]; int tok; int len; + fz_context *ctx = xref->ctx; - error = pdf_open_stream(&stream, xref, num, gen); - if (error) - return fz_error_note(error, "cannot open calculator function stream"); - - error = pdf_lex(&tok, stream, buf, sizeof buf, &len); - if (error) + fz_try(ctx) { - fz_close(stream); - return fz_error_note(error, "stream is not a calculator function"); - } + stream = pdf_open_stream(xref, num, gen); + /* RJW: "cannot open calculator function stream" */ - if (tok != PDF_TOK_OPEN_BRACE) - { - fz_close(stream); - return fz_error_make("stream is not a calculator function"); - } + tok = pdf_lex(stream, buf, sizeof buf, &len); + if (tok != PDF_TOK_OPEN_BRACE) + { + fz_throw(ctx, "stream is not a calculator function"); + } - func->u.p.code = NULL; - func->u.p.cap = 0; + func->u.p.code = NULL; + func->u.p.cap = 0; - codeptr = 0; - error = parse_code(func, stream, &codeptr); - if (error) + codeptr = 0; + parse_code(func, stream, &codeptr); + } + fz_catch(ctx) { fz_close(stream); - return fz_error_note(error, "cannot parse calculator function (%d %d R)", num, gen); + fz_throw(ctx, "cannot parse calculator function (%d %d R)", num, gen); } fz_close(stream); - return fz_okay; } static void @@ -893,11 +878,10 @@ eval_postscript_func(fz_context *ctx, pdf_function *func, float *in, float *out) * Sample function */ -static fz_error +static void load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int gen) { fz_context *ctx = xref->ctx; - fz_error error; fz_stream *stream; fz_obj *obj; int samplecount; @@ -908,20 +892,20 @@ load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int obj = fz_dict_gets(dict, "Size"); if (!fz_is_array(obj) || fz_array_len(obj) != func->m) - return fz_error_make("malformed /Size"); + fz_throw(ctx, "malformed /Size"); for (i = 0; i < func->m; i++) func->u.sa.size[i] = fz_to_int(fz_array_get(obj, i)); obj = fz_dict_gets(dict, "BitsPerSample"); if (!fz_is_int(obj)) - return fz_error_make("malformed /BitsPerSample"); + fz_throw(ctx, "malformed /BitsPerSample"); func->u.sa.bps = bps = fz_to_int(obj); obj = fz_dict_gets(dict, "Encode"); if (fz_is_array(obj)) { if (fz_array_len(obj) != func->m * 2) - return fz_error_make("malformed /Encode"); + fz_throw(ctx, "malformed /Encode"); for (i = 0; i < func->m; i++) { func->u.sa.encode[i][0] = fz_to_real(fz_array_get(obj, i*2+0)); @@ -941,7 +925,7 @@ load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int if (fz_is_array(obj)) { if (fz_array_len(obj) != func->n * 2) - return fz_error_make("malformed /Decode"); + fz_throw(ctx, "malformed /Decode"); for (i = 0; i < func->n; i++) { func->u.sa.decode[i][0] = fz_to_real(fz_array_get(obj, i*2+0)); @@ -962,9 +946,8 @@ load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int func->u.sa.samples = fz_malloc_array(ctx, samplecount, sizeof(float)); - error = pdf_open_stream(&stream, xref, num, gen); - if (error) - return fz_error_note(error, "cannot open samples stream (%d %d R)", num, gen); + stream = pdf_open_stream(xref, num, gen); + /* RJW: "cannot open samples stream (%d %d R)", num, gen */ /* read samples */ for (i = 0; i < samplecount; i++) @@ -975,7 +958,7 @@ load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int if (fz_is_eof_bits(stream)) { fz_close(stream); - return fz_error_make("truncated sample stream"); + fz_throw(ctx, "truncated sample stream"); } switch (bps) @@ -1005,15 +988,13 @@ load_sample_func(pdf_function *func, pdf_xref *xref, fz_obj *dict, int num, int break; default: fz_close(stream); - return fz_error_make("sample stream bit depth %d unsupported", bps); + fz_throw(ctx, "sample stream bit depth %d unsupported", bps); } func->u.sa.samples[i] = s; } fz_close(stream); - - return fz_okay; } static float @@ -1183,12 +1164,11 @@ eval_exponential_func(fz_context *ctx, pdf_function *func, float in, float *out) * Stitching function */ -static fz_error +static void load_stitching_func(pdf_function *func, pdf_xref *xref, fz_obj *dict) { fz_context *ctx = xref->ctx; pdf_function **funcs; - fz_error error; fz_obj *obj; fz_obj *sub; fz_obj *num; @@ -1198,11 +1178,11 @@ load_stitching_func(pdf_function *func, pdf_xref *xref, fz_obj *dict) func->u.st.k = 0; if (func->m != 1) - return fz_error_make("/Domain must be one dimension (%d)", func->m); + fz_throw(ctx, "/Domain must be one dimension (%d)", func->m); obj = fz_dict_gets(dict, "Functions"); if (!fz_is_array(obj)) - return fz_error_make("stitching function has no input functions"); + fz_throw(ctx, "stitching function has no input functions"); { k = fz_array_len(obj); @@ -1214,35 +1194,34 @@ load_stitching_func(pdf_function *func, pdf_xref *xref, fz_obj *dict) for (i = 0; i < k; i++) { sub = fz_array_get(obj, i); - error = pdf_load_function(&funcs[i], xref, sub); - if (error) - return fz_error_note(error, "cannot load sub function %d (%d %d R)", i, fz_to_num(sub), fz_to_gen(sub)); + funcs[i] = pdf_load_function(xref, sub); + /* RJW: "cannot load sub function %d (%d %d R)", i, fz_to_num(sub), fz_to_gen(sub) */ if (funcs[i]->m != 1 || funcs[i]->n != funcs[0]->n) - return fz_error_make("sub function %d /Domain or /Range mismatch", i); + fz_throw(ctx, "sub function %d /Domain or /Range mismatch", i); func->u.st.k ++; } if (!func->n) func->n = funcs[0]->n; else if (func->n != funcs[0]->n) - return fz_error_make("sub function /Domain or /Range mismatch"); + fz_throw(ctx, "sub function /Domain or /Range mismatch"); } obj = fz_dict_gets(dict, "Bounds"); if (!fz_is_array(obj)) - return fz_error_make("stitching function has no bounds"); + fz_throw(ctx, "stitching function has no bounds"); { if (!fz_is_array(obj) || fz_array_len(obj) != k - 1) - return fz_error_make("malformed /Bounds (not array or wrong length)"); + fz_throw(ctx, "malformed /Bounds (not array or wrong length)"); for (i = 0; i < k-1; i++) { num = fz_array_get(obj, i); if (!fz_is_int(num) && !fz_is_real(num)) - return fz_error_make("malformed /Bounds (item not real)"); + fz_throw(ctx, "malformed /Bounds (item not real)"); func->u.st.bounds[i] = fz_to_real(num); if (i && func->u.st.bounds[i-1] > func->u.st.bounds[i]) - return fz_error_make("malformed /Bounds (item not monotonic)"); + fz_throw(ctx, "malformed /Bounds (item not monotonic)"); } if (k != 1 && (func->domain[0][0] > func->u.st.bounds[0] || @@ -1252,18 +1231,16 @@ load_stitching_func(pdf_function *func, pdf_xref *xref, fz_obj *dict) obj = fz_dict_gets(dict, "Encode"); if (!fz_is_array(obj)) - return fz_error_make("stitching function is missing encoding"); + fz_throw(ctx, "stitching function is missing encoding"); { if (!fz_is_array(obj) || fz_array_len(obj) != k * 2) - return fz_error_make("malformed /Encode"); + fz_throw(ctx, "malformed /Encode"); for (i = 0; i < k; i++) { func->u.st.encode[i*2+0] = fz_to_real(fz_array_get(obj, i*2+0)); func->u.st.encode[i*2+1] = fz_to_real(fz_array_get(obj, i*2+1)); } } - - return fz_okay; } static void @@ -1347,19 +1324,18 @@ pdf_drop_function(fz_context *ctx, pdf_function *func) } } -fz_error -pdf_load_function(pdf_function **funcp, pdf_xref *xref, fz_obj *dict) +pdf_function * +pdf_load_function(pdf_xref *xref, fz_obj *dict) { fz_context *ctx = xref->ctx; - fz_error error; - pdf_function *func; + pdf_function * volatile func; fz_obj *obj; int i; - if ((*funcp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_function, dict))) + if ((func = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_function, dict))) { - pdf_keep_function(*funcp); - return fz_okay; + pdf_keep_function(func); + return func; } func = fz_malloc(ctx, sizeof(pdf_function)); @@ -1399,56 +1375,48 @@ pdf_load_function(pdf_function **funcp, pdf_xref *xref, fz_obj *dict) if (func->m >= MAXM || func->n >= MAXN) { fz_free(ctx, func); - return fz_error_make("assert: /Domain or /Range too big"); + fz_throw(ctx, "assert: /Domain or /Range too big"); } - switch(func->type) + fz_try(ctx) { - case SAMPLE: - error = load_sample_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict)); - if (error) + switch(func->type) { - pdf_drop_function(ctx, func); - return fz_error_note(error, "cannot load sampled function (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); - } - break; + case SAMPLE: + load_sample_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict)); + break; - case EXPONENTIAL: - error = load_exponential_func(ctx, func, dict); - if (error) - { - pdf_drop_function(ctx, func); - return fz_error_note(error, "cannot load exponential function (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); - } - break; + case EXPONENTIAL: + load_exponential_func(ctx, func, dict); + break; - case STITCHING: - error = load_stitching_func(func, xref, dict); - if (error) - { - pdf_drop_function(ctx, func); - return fz_error_note(error, "cannot load stitching function (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); - } - break; + case STITCHING: + load_stitching_func(func, xref, dict); + break; - case POSTSCRIPT: - error = load_postscript_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict)); - if (error) - { - pdf_drop_function(ctx, func); - return fz_error_note(error, "cannot load calculator function (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); - } - break; + case POSTSCRIPT: + load_postscript_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict)); + break; - default: - fz_free(ctx, func); - return fz_error_make("unknown function type (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + default: + fz_free(ctx, func); + fz_throw(ctx, "unknown function type (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + } + } + fz_catch(ctx) + { + pdf_drop_function(ctx, func); + fz_throw(ctx, "cannot load %s function (%d %d R)", + (func->type == SAMPLE ? "sampled" : + (func->type == EXPONENTIAL ? "exponential" : + (func->type == STITCHING ? "stitching" : + (func->type == POSTSCRIPT ? "calculator" : + "unknown")))), fz_to_num(dict), fz_to_gen(dict)); } pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)pdf_keep_function, (pdf_store_drop_fn *)pdf_drop_function, dict, func); - *funcp = func; - return fz_okay; + return func; } void diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c index 31104b9f..1eff510a 100644 --- a/pdf/pdf_image.c +++ b/pdf/pdf_image.c @@ -4,7 +4,7 @@ /* TODO: store JPEG compressed samples */ /* TODO: store flate compressed samples */ -static fz_error pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict); +static fz_pixmap *pdf_load_jpx_image(pdf_xref *xref, fz_obj *dict); static void pdf_mask_color_key(fz_pixmap *pix, int n, int *colorkey) @@ -25,247 +25,240 @@ pdf_mask_color_key(fz_pixmap *pix, int n, int *colorkey) } } -static fz_error -pdf_load_image_imp(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm, int forcemask) +static fz_pixmap * +pdf_load_image_imp(pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm, int forcemask) { - fz_stream *stm; - fz_pixmap *tile; + fz_stream * volatile stm = NULL; + fz_pixmap * volatile tile = NULL; fz_obj *obj, *res; - fz_error error; int w, h, bpc, n; int imagemask; int interpolate; int indexed; - fz_colorspace *colorspace; - fz_pixmap *mask; /* explicit mask/softmask image */ + fz_colorspace * volatile colorspace = NULL; + fz_pixmap * volatile mask = NULL; /* explicit mask/softmask image */ int usecolorkey; int colorkey[FZ_MAX_COLORS * 2]; float decode[FZ_MAX_COLORS * 2]; int stride; - unsigned char *samples; + unsigned char * volatile samples = NULL; int i, len; fz_context *ctx = xref->ctx; - /* special case for JPEG2000 images */ - if (pdf_is_jpx_image(ctx, dict)) + fz_try(ctx) { - tile = NULL; - error = pdf_load_jpx_image(&tile, xref, dict); - if (error) - return fz_error_note(error, "cannot load jpx image"); - if (forcemask) + /* special case for JPEG2000 images */ + if (pdf_is_jpx_image(ctx, dict)) { - if (tile->n != 2) + tile = pdf_load_jpx_image(xref, dict); + /* RJW: "cannot load jpx image" */ + if (forcemask) { + if (tile->n != 2) + fz_throw(ctx, "softmask must be grayscale"); + mask = fz_alpha_from_gray(ctx, tile, 1); fz_drop_pixmap(ctx, tile); - return fz_error_make("softmask must be grayscale"); + tile = mask; + mask = NULL; } - mask = fz_alpha_from_gray(ctx, tile, 1); - fz_drop_pixmap(ctx, tile); - *imgp = mask; - return fz_okay; + goto end; } - *imgp = tile; - return fz_okay; - } - w = fz_to_int(fz_dict_getsa(dict, "Width", "W")); - h = fz_to_int(fz_dict_getsa(dict, "Height", "H")); - bpc = fz_to_int(fz_dict_getsa(dict, "BitsPerComponent", "BPC")); - imagemask = fz_to_bool(fz_dict_getsa(dict, "ImageMask", "IM")); - interpolate = fz_to_bool(fz_dict_getsa(dict, "Interpolate", "I")); - - indexed = 0; - usecolorkey = 0; - colorspace = NULL; - mask = NULL; - - if (imagemask) - bpc = 1; - - if (w == 0) - return fz_error_make("image width is zero"); - if (h == 0) - return fz_error_make("image height is zero"); - if (bpc == 0) - return fz_error_make("image depth is zero"); - if (bpc > 16) - return fz_error_make("image depth is too large: %d", bpc); - if (w > (1 << 16)) - return fz_error_make("image is too wide"); - if (h > (1 << 16)) - return fz_error_make("image is too high"); - - obj = fz_dict_getsa(dict, "ColorSpace", "CS"); - if (obj && !imagemask && !forcemask) - { - /* colorspace resource lookup is only done for inline images */ - if (fz_is_name(obj)) + w = fz_to_int(fz_dict_getsa(dict, "Width", "W")); + h = fz_to_int(fz_dict_getsa(dict, "Height", "H")); + bpc = fz_to_int(fz_dict_getsa(dict, "BitsPerComponent", "BPC")); + imagemask = fz_to_bool(fz_dict_getsa(dict, "ImageMask", "IM")); + interpolate = fz_to_bool(fz_dict_getsa(dict, "Interpolate", "I")); + + indexed = 0; + usecolorkey = 0; + mask = NULL; + + if (imagemask) + bpc = 1; + + if (w == 0) + fz_throw(ctx, "image width is zero"); + if (h == 0) + fz_throw(ctx, "image height is zero"); + if (bpc == 0) + fz_throw(ctx, "image depth is zero"); + if (bpc > 16) + fz_throw(ctx, "image depth is too large: %d", bpc); + if (w > (1 << 16)) + fz_throw(ctx, "image is too wide"); + if (h > (1 << 16)) + fz_throw(ctx, "image is too high"); + + obj = fz_dict_getsa(dict, "ColorSpace", "CS"); + if (obj && !imagemask && !forcemask) { - res = fz_dict_get(fz_dict_gets(rdb, "ColorSpace"), obj); - if (res) - obj = res; - } + /* colorspace resource lookup is only done for inline images */ + if (fz_is_name(obj)) + { + res = fz_dict_get(fz_dict_gets(rdb, "ColorSpace"), obj); + if (res) + obj = res; + } - error = pdf_load_colorspace(&colorspace, xref, obj); - if (error) - return fz_error_note(error, "cannot load image colorspace"); + colorspace = pdf_load_colorspace(xref, obj); + /* RJW: "cannot load image colorspace" */ - if (!strcmp(colorspace->name, "Indexed")) - indexed = 1; + if (!strcmp(colorspace->name, "Indexed")) + indexed = 1; - n = colorspace->n; - } - else - { - n = 1; - } + n = colorspace->n; + } + else + { + n = 1; + } - obj = fz_dict_getsa(dict, "Decode", "D"); - if (obj) - { - for (i = 0; i < n * 2; i++) - decode[i] = fz_to_real(fz_array_get(obj, i)); - } - else - { - float maxval = indexed ? (1 << bpc) - 1 : 1; - for (i = 0; i < n * 2; i++) - decode[i] = i & 1 ? maxval : 0; - } + obj = fz_dict_getsa(dict, "Decode", "D"); + if (obj) + { + for (i = 0; i < n * 2; i++) + decode[i] = fz_to_real(fz_array_get(obj, i)); + } + else + { + float maxval = indexed ? (1 << bpc) - 1 : 1; + for (i = 0; i < n * 2; i++) + decode[i] = i & 1 ? maxval : 0; + } - obj = fz_dict_getsa(dict, "SMask", "Mask"); - if (fz_is_dict(obj)) - { - /* Not allowed for inline images */ - if (!cstm) + obj = fz_dict_getsa(dict, "SMask", "Mask"); + if (fz_is_dict(obj)) { - error = pdf_load_image_imp(&mask, xref, rdb, obj, NULL, 1); - if (error) + /* Not allowed for inline images */ + if (!cstm) { - if (colorspace) - fz_drop_colorspace(ctx, colorspace); - return fz_error_note(error, "cannot load image mask/softmask"); + mask = pdf_load_image_imp(xref, rdb, obj, NULL, 1); + /* RJW: "cannot load image mask/softmask" */ } } - } - else if (fz_is_array(obj)) - { - usecolorkey = 1; - for (i = 0; i < n * 2; i++) - colorkey[i] = fz_to_int(fz_array_get(obj, i)); - } + else if (fz_is_array(obj)) + { + usecolorkey = 1; + for (i = 0; i < n * 2; i++) + colorkey[i] = fz_to_int(fz_array_get(obj, i)); + } + + /* Allocate now, to fail early if we run out of memory */ + tile = fz_new_pixmap_with_limit(ctx, colorspace, w, h); + if (!tile) + { + fz_throw(ctx, "out of memory"); + } - /* Allocate now, to fail early if we run out of memory */ - tile = fz_new_pixmap_with_limit(ctx, colorspace, w, h); - if (!tile) - { if (colorspace) + { fz_drop_colorspace(ctx, colorspace); - if (mask) - fz_drop_pixmap(ctx, mask); - return fz_error_make("out of memory"); - } - - if (colorspace) - fz_drop_colorspace(ctx, colorspace); + colorspace = NULL; + } - tile->mask = mask; - tile->interpolate = interpolate; + tile->mask = mask; + mask = NULL; + tile->interpolate = interpolate; - stride = (w * n * bpc + 7) / 8; + stride = (w * n * bpc + 7) / 8; - if (cstm) - { - stm = pdf_open_inline_stream(cstm, xref, dict, stride * h); - } - else - { - error = pdf_open_stream(&stm, xref, fz_to_num(dict), fz_to_gen(dict)); - if (error) + if (cstm) { - fz_drop_pixmap(ctx, tile); - return fz_error_note(error, "cannot open image data stream (%d 0 R)", fz_to_num(dict)); + stm = pdf_open_inline_stream(cstm, xref, dict, stride * h); + } + else + { + stm = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict)); + /* RJW: "cannot open image data stream (%d 0 R)", fz_to_num(dict) */ } - } - samples = fz_malloc_array(ctx, h, stride); + samples = fz_malloc_array(ctx, h, stride); - len = fz_read(stm, samples, h * stride); - if (len < 0) - { - fz_close(stm); - fz_free(ctx, samples); - fz_drop_pixmap(ctx, tile); - return fz_error_note(len, "cannot read image data"); - } + len = fz_read(stm, samples, h * stride); + if (len < 0) + { + fz_throw(ctx, "cannot read image data"); + } - /* Make sure we read the EOF marker (for inline images only) */ - if (cstm) - { - unsigned char tbuf[512]; - int tlen = fz_read(stm, tbuf, sizeof tbuf); - if (tlen < 0) - fz_error_handle(tlen, "ignoring error at end of image"); - if (tlen > 0) - fz_warn(ctx, "ignoring garbage at end of image"); - } + /* Make sure we read the EOF marker (for inline images only) */ + if (cstm) + { + unsigned char tbuf[512]; + int tlen = fz_read(stm, tbuf, sizeof tbuf); + if (tlen < 0) + fz_error_handle(tlen, "ignoring error at end of image"); + if (tlen > 0) + fz_warn(ctx, "ignoring garbage at end of image"); + } - fz_close(stm); + fz_close(stm); + stm = NULL; - /* Pad truncated images */ - if (len < stride * h) - { - fz_warn(ctx, "padding truncated image (%d 0 R)", fz_to_num(dict)); - memset(samples + len, 0, stride * h - len); - } + /* Pad truncated images */ + if (len < stride * h) + { + fz_warn(ctx, "padding truncated image (%d 0 R)", fz_to_num(dict)); + memset(samples + len, 0, stride * h - len); + } - /* Invert 1-bit image masks */ - if (imagemask) - { - /* 0=opaque and 1=transparent so we need to invert */ - unsigned char *p = samples; - len = h * stride; - for (i = 0; i < len; i++) - p[i] = ~p[i]; - } + /* Invert 1-bit image masks */ + if (imagemask) + { + /* 0=opaque and 1=transparent so we need to invert */ + unsigned char *p = samples; + len = h * stride; + for (i = 0; i < len; i++) + p[i] = ~p[i]; + } - fz_unpack_tile(tile, samples, n, bpc, stride, indexed); + fz_unpack_tile(tile, samples, n, bpc, stride, indexed); - fz_free(ctx, samples); + fz_free(ctx, samples); + samples = NULL; - if (usecolorkey) - pdf_mask_color_key(tile, n, colorkey); + if (usecolorkey) + pdf_mask_color_key(tile, n, colorkey); - if (indexed) - { - fz_pixmap *conv; - fz_decode_indexed_tile(tile, decode, (1 << bpc) - 1); - conv = pdf_expand_indexed_pixmap(ctx, tile); - fz_drop_pixmap(ctx, tile); - tile = conv; + if (indexed) + { + fz_pixmap *conv; + fz_decode_indexed_tile(tile, decode, (1 << bpc) - 1); + conv = pdf_expand_indexed_pixmap(ctx, tile); + fz_drop_pixmap(ctx, tile); + tile = conv; + } + else + { + fz_decode_tile(tile, decode); + } +end: + {} } - else + fz_catch(ctx) { - fz_decode_tile(tile, decode); + if (colorspace) + fz_drop_colorspace(ctx, colorspace); + if (mask) + fz_drop_pixmap(ctx, mask); + if (tile) + fz_drop_pixmap(ctx, tile); + fz_close(stm); + fz_free(ctx, samples); + + fz_rethrow(ctx); } - *imgp = tile; - return fz_okay; + return tile; } -fz_error -pdf_load_inline_image(fz_pixmap **pixp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file) +fz_pixmap * +pdf_load_inline_image(pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file) { - fz_error error; - - error = pdf_load_image_imp(pixp, xref, rdb, dict, file, 0); - if (error) - return fz_error_note(error, "cannot load inline image"); - - return fz_okay; + return pdf_load_image_imp(xref, rdb, dict, file, 0); + /* RJW: "cannot load inline image" */ } int @@ -284,75 +277,66 @@ pdf_is_jpx_image(fz_context *ctx, fz_obj *dict) return 0; } -static fz_error -pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict) +static fz_pixmap * +pdf_load_jpx_image(pdf_xref *xref, fz_obj *dict) { - fz_error error; - fz_buffer *buf; - fz_colorspace *colorspace; + fz_buffer * volatile buf = NULL; + fz_colorspace * volatile colorspace = NULL; fz_pixmap *img; fz_obj *obj; fz_context *ctx = xref->ctx; - colorspace = NULL; - - error = pdf_load_stream(&buf, xref, fz_to_num(dict), fz_to_gen(dict)); - if (error) - return fz_error_note(error, "cannot load jpx image data"); + buf = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict)); + /* RJW: "cannot load jpx image data" */ - obj = fz_dict_gets(dict, "ColorSpace"); - if (obj) + fz_try(ctx) { - error = pdf_load_colorspace(&colorspace, xref, obj); - if (error) - fz_error_handle(error, "cannot load image colorspace"); - } + obj = fz_dict_gets(dict, "ColorSpace"); + if (obj) + { + colorspace = pdf_load_colorspace(xref, obj); + /* RJW: "cannot load image colorspace" */ + } + + img = fz_load_jpx_image(ctx, buf->data, buf->len, colorspace); + /* RJW: "cannot load jpx image" */ - error = fz_load_jpx_image(ctx, &img, buf->data, buf->len, colorspace); - if (error) - { if (colorspace) fz_drop_colorspace(ctx, colorspace); fz_drop_buffer(ctx, buf); - return fz_error_note(error, "cannot load jpx image"); - } - if (colorspace) - fz_drop_colorspace(ctx, colorspace); - fz_drop_buffer(ctx, buf); - - obj = fz_dict_getsa(dict, "SMask", "Mask"); - if (fz_is_dict(obj)) - { - error = pdf_load_image_imp(&img->mask, xref, NULL, obj, NULL, 1); - if (error) + obj = fz_dict_getsa(dict, "SMask", "Mask"); + if (fz_is_dict(obj)) { - fz_drop_pixmap(ctx, img); - return fz_error_note(error, "cannot load image mask/softmask"); + img->mask = pdf_load_image_imp(xref, NULL, obj, NULL, 1); + /* RJW: "cannot load image mask/softmask" */ } } - - *imgp = img; - return fz_okay; + fz_catch(ctx) + { + if (colorspace) + fz_drop_colorspace(ctx, colorspace); + fz_drop_buffer(ctx, buf); + fz_drop_pixmap(ctx, img); + } + return img; } -fz_error -pdf_load_image(fz_pixmap **pixp, pdf_xref *xref, fz_obj *dict) +fz_pixmap * +pdf_load_image(pdf_xref *xref, fz_obj *dict) { - fz_error error; fz_context *ctx = xref->ctx; + fz_pixmap *pix; - if ((*pixp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_pixmap, dict))) + if ((pix = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_pixmap, dict))) { - fz_keep_pixmap(*pixp); - return fz_okay; + return fz_keep_pixmap(pix); } - error = pdf_load_image_imp(pixp, xref, NULL, dict, NULL, 0); - if (error) - return fz_error_note(error, "cannot load image (%d 0 R)", fz_to_num(dict)); + pix = pdf_load_image_imp(xref, NULL, dict, NULL, 0); + /* RJW: "cannot load image (%d 0 R)", fz_to_num(dict) */ - pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_pixmap, (pdf_store_drop_fn *)fz_drop_pixmap, dict, *pixp); + pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_pixmap, (pdf_store_drop_fn *)fz_drop_pixmap, dict, pix); - return fz_okay; + return pix; } diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c index cc320894..e7555e24 100644 --- a/pdf/pdf_interpret.c +++ b/pdf/pdf_interpret.c @@ -96,8 +96,8 @@ struct pdf_csi_s int gtop; }; -static fz_error pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents); -static fz_error pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform); +static void pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents); +static void pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform); static void pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what); @@ -128,7 +128,6 @@ static void pdf_begin_group(pdf_csi *csi, fz_rect bbox) { pdf_gstate *gstate = csi->gstate + csi->gtop; - fz_error error; if (gstate->softmask) { @@ -141,9 +140,8 @@ pdf_begin_group(pdf_csi *csi, fz_rect bbox) fz_begin_mask(csi->dev, bbox, gstate->luminosity, softmask->colorspace, gstate->softmask_bc); - error = pdf_run_xobject(csi, NULL, softmask, fz_identity); - if (error) - fz_error_handle(error, "cannot run softmask"); + pdf_run_xobject(csi, NULL, softmask, fz_identity); + /* RJW: "cannot run softmask" */ fz_end_mask(csi->dev); gstate->softmask = softmask; @@ -937,7 +935,6 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what) pdf_gstate *gstate; fz_matrix ptm, invptm; fz_matrix oldtopctm; - fz_error error; int x0, y0, x1, y1; int oldtop; @@ -998,9 +995,8 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what) gstate->ctm = ptm; csi->top_ctm = gstate->ctm; pdf_gsave(csi); - error = pdf_run_buffer(csi, pat->resources, pat->contents); - if (error) - fz_error_handle(error, "cannot render pattern tile"); + pdf_run_buffer(csi, pat->resources, pat->contents); + /* RJW: "cannot render pattern tile" */ pdf_grestore(csi); while (oldtop < csi->gtop) pdf_grestore(csi); @@ -1016,30 +1012,33 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what) gstate->ctm = fz_concat(fz_translate(x * pat->xstep, y * pat->ystep), ptm); csi->top_ctm = gstate->ctm; pdf_gsave(csi); - error = pdf_run_buffer(csi, pat->resources, pat->contents); + fz_try(ctx) + { + pdf_run_buffer(csi, pat->resources, pat->contents); + } + fz_catch(ctx) + { + pdf_grestore(csi); + while (oldtop < csi->gtop) + pdf_grestore(csi); + csi->top_ctm = oldtopctm; + fz_throw(ctx, "cannot render pattern tile"); + } pdf_grestore(csi); while (oldtop < csi->gtop) pdf_grestore(csi); - if (error) - { - fz_error_handle(error, "cannot render pattern tile"); - goto cleanup; - } } } } -cleanup: - csi->top_ctm = oldtopctm; pdf_grestore(csi); } -static fz_error +static void pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform) { fz_context *ctx = csi->dev->ctx; - fz_error error; pdf_gstate *gstate; fz_matrix oldtopctm; int oldtop; @@ -1068,9 +1067,8 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr fz_begin_mask(csi->dev, bbox, gstate->luminosity, softmask->colorspace, gstate->softmask_bc); - error = pdf_run_xobject(csi, resources, softmask, fz_identity); - if (error) - return fz_error_note(error, "cannot run softmask"); + pdf_run_xobject(csi, resources, softmask, fz_identity); + /* RJW: "cannot run softmask" */ fz_end_mask(csi->dev); pdf_drop_xobject(ctx, softmask); @@ -1103,9 +1101,8 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr if (xobj->resources) resources = xobj->resources; - error = pdf_run_buffer(csi, resources, xobj->contents); - if (error) - fz_error_note(error, "cannot interpret XObject stream"); + pdf_run_buffer(csi, resources, xobj->contents); + /* RJW: "cannot interpret XObject stream" */ csi->top_ctm = oldtopctm; @@ -1122,11 +1119,9 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr if (popmask) fz_pop_clip(csi->dev); } - - return fz_okay; } -static fz_error +static void pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) { fz_context *ctx = csi->dev->ctx; @@ -1147,7 +1142,6 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) { if (fz_is_array(val) && fz_array_len(val) == 2) { - fz_error error; fz_obj *font = fz_array_get(val, 0); if (gstate->font) @@ -1156,15 +1150,14 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) gstate->font = NULL; } - error = pdf_load_font(&gstate->font, csi->xref, rdb, font); - if (error) - return fz_error_note(error, "cannot load font (%d %d R)", fz_to_num(font), fz_to_gen(font)); + gstate->font = pdf_load_font(csi->xref, rdb, font); + /* RJW: "cannot load font (%d %d R)", fz_to_num(font), fz_to_gen(font) */ if (!gstate->font) - return fz_error_make("cannot find font in store"); + fz_throw(ctx, "cannot find font in store"); gstate->size = fz_to_real(fz_array_get(val, 1)); } else - return fz_error_make("malformed /Font dictionary"); + fz_throw(ctx, "malformed /Font dictionary"); } else if (!strcmp(s, "LC")) @@ -1191,7 +1184,7 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) gstate->stroke_state.dash_phase = fz_to_real(fz_array_get(val, 1)); } else - return fz_error_make("malformed /D"); + fz_throw(ctx, "malformed /D"); } else if (!strcmp(s, "CA")) @@ -1211,7 +1204,6 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) { if (fz_is_dict(val)) { - fz_error error; pdf_xobject *xobj; fz_obj *group, *luminosity, *bc; @@ -1223,10 +1215,9 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) group = fz_dict_gets(val, "G"); if (!group) - return fz_error_make("cannot load softmask xobject (%d %d R)", fz_to_num(val), fz_to_gen(val)); - error = pdf_load_xobject(&xobj, csi->xref, group); - if (error) - return fz_error_note(error, "cannot load xobject (%d %d R)", fz_to_num(val), fz_to_gen(val)); + fz_throw(ctx, "cannot load softmask xobject (%d %d R)", fz_to_num(val), fz_to_gen(val)); + xobj = pdf_load_xobject(csi->xref, group); + /* RJW: "cannot load xobject (%d %d R)", fz_to_num(val), fz_to_gen(val) */ colorspace = xobj->colorspace; if (!colorspace) @@ -1266,8 +1257,6 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate) fz_warn(ctx, "ignoring transfer function"); } } - - return fz_okay; } /* @@ -1278,19 +1267,17 @@ static void pdf_run_BDC(pdf_csi *csi) { } -static fz_error pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file) +static void pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file) { fz_context *ctx = csi->dev->ctx; int ch; - fz_error error; char *buf = csi->xref->scratch; int buflen = sizeof(csi->xref->scratch); fz_pixmap *img; fz_obj *obj; - error = pdf_parse_dict(&obj, csi->xref, file, buf, buflen); - if (error) - return fz_error_note(error, "cannot parse inline image dictionary"); + obj = pdf_parse_dict(csi->xref, file, buf, buflen); + /* RJW: "cannot parse inline image dictionary" */ /* read whitespace after ID keyword */ ch = fz_read_byte(file); @@ -1298,10 +1285,9 @@ static fz_error pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file) if (fz_peek_byte(file) == '\n') fz_read_byte(file); - error = pdf_load_inline_image(&img, csi->xref, rdb, obj, file); + img = pdf_load_inline_image(csi->xref, rdb, obj, file); fz_drop_obj(obj); - if (error) - return fz_error_note(error, "cannot load inline image"); + /* RJW: "cannot load inline image" */ pdf_show_image(csi, img); @@ -1313,9 +1299,7 @@ static fz_error pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file) ch = fz_read_byte(file); ch = fz_read_byte(file); if (ch != 'I') - return fz_error_note(error, "syntax error after inline image"); - - return fz_okay; + fz_throw(ctx, "syntax error after inline image"); } static void pdf_run_B(pdf_csi *csi) @@ -1344,12 +1328,11 @@ static void pdf_run_Bstar(pdf_csi *csi) pdf_show_path(csi, 0, 1, 1, 1); } -static fz_error pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what) +static void pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what) { fz_context *ctx = csi->dev->ctx; fz_colorspace *colorspace; fz_obj *obj, *dict; - fz_error error; if (!strcmp(csi->name, "Pattern")) { @@ -1367,64 +1350,57 @@ static fz_error pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what) { dict = fz_dict_gets(rdb, "ColorSpace"); if (!dict) - return fz_error_make("cannot find ColorSpace dictionary"); + fz_throw(ctx, "cannot find ColorSpace dictionary"); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find colorspace resource '%s'", csi->name); - error = pdf_load_colorspace(&colorspace, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load colorspace (%d 0 R)", fz_to_num(obj)); + fz_throw(ctx, "cannot find colorspace resource '%s'", csi->name); + colorspace = pdf_load_colorspace(csi->xref, obj); + /* RJW: "cannot load colorspace (%d 0 R)", fz_to_num(obj) */ } pdf_set_colorspace(csi, what, colorspace); fz_drop_colorspace(ctx, colorspace); } - return fz_okay; } static void pdf_run_CS(pdf_csi *csi, fz_obj *rdb) { - fz_error error; - error = pdf_run_cs_imp(csi, rdb, PDF_STROKE); - if (error) - fz_error_handle(error, "cannot set colorspace"); + pdf_run_cs_imp(csi, rdb, PDF_STROKE); + /* RJW: "cannot set colorspace" */ } static void pdf_run_cs(pdf_csi *csi, fz_obj *rdb) { - fz_error error; - error = pdf_run_cs_imp(csi, rdb, PDF_FILL); - if (error) - fz_error_handle(error, "cannot set colorspace"); + pdf_run_cs_imp(csi, rdb, PDF_FILL); + /* RJW: "cannot set colorspace" */ } static void pdf_run_DP(pdf_csi *csi) { } -static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb) +static void pdf_run_Do(pdf_csi *csi, fz_obj *rdb) { fz_context *ctx = csi->dev->ctx; fz_obj *dict; fz_obj *obj; fz_obj *subtype; - fz_error error; dict = fz_dict_gets(rdb, "XObject"); if (!dict) - return fz_error_make("cannot find XObject dictionary when looking for: '%s'", csi->name); + fz_throw(ctx, "cannot find XObject dictionary when looking for: '%s'", csi->name); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find xobject resource: '%s'", csi->name); + fz_throw(ctx, "cannot find xobject resource: '%s'", csi->name); subtype = fz_dict_gets(obj, "Subtype"); if (!fz_is_name(subtype)) - return fz_error_make("no XObject subtype specified"); + fz_throw(ctx, "no XObject subtype specified"); if (pdf_is_hidden_ocg(ctx, obj, csi->target)) - return fz_okay; + return; if (!strcmp(fz_to_name(subtype), "Form") && fz_dict_gets(obj, "Subtype2")) subtype = fz_dict_gets(obj, "Subtype2"); @@ -1433,17 +1409,15 @@ static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb) { pdf_xobject *xobj; - error = pdf_load_xobject(&xobj, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + xobj = pdf_load_xobject(csi->xref, obj); + /* RJW: "cannot load xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ /* Inherit parent resources, in case this one was empty XXX check where it's loaded */ if (!xobj->resources) xobj->resources = fz_keep_obj(rdb); - error = pdf_run_xobject(csi, xobj->resources, xobj, fz_identity); - if (error) - return fz_error_note(error, "cannot draw xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + pdf_run_xobject(csi, xobj->resources, xobj, fz_identity); + /* RJW: "cannot draw xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ pdf_drop_xobject(ctx, xobj); } @@ -1453,9 +1427,8 @@ static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb) if ((csi->dev->hints & FZ_IGNORE_IMAGE) == 0) { fz_pixmap *img; - error = pdf_load_image(&img, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load image (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + img = pdf_load_image(csi->xref, obj); + /* RJW: "cannot load image (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ pdf_show_image(csi, img); fz_drop_pixmap(ctx, img); } @@ -1468,10 +1441,8 @@ static fz_error pdf_run_Do(pdf_csi *csi, fz_obj *rdb) else { - return fz_error_make("unknown XObject subtype: '%s'", fz_to_name(subtype)); + fz_throw(ctx, "unknown XObject subtype: '%s'", fz_to_name(subtype)); } - - return fz_okay; } static void pdf_run_EMC(pdf_csi *csi) @@ -1541,10 +1512,9 @@ static void pdf_run_S(pdf_csi *csi) pdf_show_path(csi, 0, 0, 1, 0); } -static fz_error pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *mat) +static void pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *mat) { fz_context *ctx = csi->dev->ctx; - fz_error error; fz_obj *patterntype; fz_obj *dict; fz_obj *obj; @@ -1557,7 +1527,7 @@ static fz_error pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material switch (kind) { case PDF_MAT_NONE: - return fz_error_make("cannot set color in mask objects"); + fz_throw(ctx, "cannot set color in mask objects"); case PDF_MAT_COLOR: pdf_set_color(csi, what, csi->stack); @@ -1566,61 +1536,53 @@ static fz_error pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material case PDF_MAT_PATTERN: dict = fz_dict_gets(rdb, "Pattern"); if (!dict) - return fz_error_make("cannot find Pattern dictionary"); + fz_throw(ctx, "cannot find Pattern dictionary"); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find pattern resource '%s'", csi->name); + fz_throw(ctx, "cannot find pattern resource '%s'", csi->name); patterntype = fz_dict_gets(obj, "PatternType"); if (fz_to_int(patterntype) == 1) { pdf_pattern *pat; - error = pdf_load_pattern(&pat, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load pattern (%d 0 R)", fz_to_num(obj)); + pat = pdf_load_pattern(csi->xref, obj); + /* RJW: "cannot load pattern (%d 0 R)", fz_to_num(obj) */ pdf_set_pattern(csi, what, pat, csi->top > 0 ? csi->stack : NULL); pdf_drop_pattern(ctx, pat); } else if (fz_to_int(patterntype) == 2) { fz_shade *shd; - error = pdf_load_shading(&shd, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load shading (%d 0 R)", fz_to_num(obj)); + shd = pdf_load_shading(csi->xref, obj); + /* RJW: "cannot load shading (%d 0 R)", fz_to_num(obj) */ pdf_set_shade(csi, what, shd); fz_drop_shade(ctx, shd); } else { - return fz_error_make("unknown pattern type: %d", fz_to_int(patterntype)); + fz_throw(ctx, "unknown pattern type: %d", fz_to_int(patterntype)); } break; case PDF_MAT_SHADE: - return fz_error_make("cannot set color in shade objects"); + fz_throw(ctx, "cannot set color in shade objects"); } - - return fz_okay; } static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb) { - fz_error error; pdf_gstate *gstate = csi->gstate + csi->gtop; - error = pdf_run_SC_imp(csi, rdb, PDF_STROKE, &gstate->stroke); - if (error) - fz_error_handle(error, "cannot set color and colorspace"); + pdf_run_SC_imp(csi, rdb, PDF_STROKE, &gstate->stroke); + /* RJW: "cannot set color and colorspace" */ } static void pdf_run_sc(pdf_csi *csi, fz_obj *rdb) { - fz_error error; pdf_gstate *gstate = csi->gstate + csi->gtop; - error = pdf_run_SC_imp(csi, rdb, PDF_FILL, &gstate->fill); - if (error) - fz_error_handle(error, "cannot set color and colorspace"); + pdf_run_SC_imp(csi, rdb, PDF_FILL, &gstate->fill); + /* RJW: "cannot set color and colorspace" */ } static void pdf_run_Tc(pdf_csi *csi) @@ -1649,11 +1611,10 @@ static void pdf_run_TL(pdf_csi *csi) gstate->leading = csi->stack[0]; } -static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb) +static void pdf_run_Tf(pdf_csi *csi, fz_obj *rdb) { fz_context *ctx = csi->dev->ctx; pdf_gstate *gstate = csi->gstate + csi->gtop; - fz_error error; fz_obj *dict; fz_obj *obj; @@ -1664,17 +1625,14 @@ static fz_error pdf_run_Tf(pdf_csi *csi, fz_obj *rdb) dict = fz_dict_gets(rdb, "Font"); if (!dict) - return fz_error_make("cannot find Font dictionary"); + fz_throw(ctx, "cannot find Font dictionary"); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find font resource: '%s'", csi->name); - - error = pdf_load_font(&gstate->font, csi->xref, rdb, obj); - if (error) - return fz_error_note(error, "cannot load font (%d 0 R)", fz_to_num(obj)); + fz_throw(ctx, "cannot find font resource: '%s'", csi->name); - return fz_okay; + gstate->font = pdf_load_font(csi->xref, rdb, obj); + /* RJW: "cannot load font (%d 0 R)", fz_to_num(obj) */ } static void pdf_run_Tr(pdf_csi *csi) @@ -1828,24 +1786,22 @@ static void pdf_run_g(pdf_csi *csi) pdf_set_color(csi, PDF_FILL, csi->stack); } -static fz_error pdf_run_gs(pdf_csi *csi, fz_obj *rdb) +static void pdf_run_gs(pdf_csi *csi, fz_obj *rdb) { - fz_error error; fz_obj *dict; fz_obj *obj; + fz_context *ctx = csi->dev->ctx; dict = fz_dict_gets(rdb, "ExtGState"); if (!dict) - return fz_error_make("cannot find ExtGState dictionary"); + fz_throw(ctx, "cannot find ExtGState dictionary"); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find extgstate resource '%s'", csi->name); + fz_throw(ctx, "cannot find extgstate resource '%s'", csi->name); - error = pdf_run_extgstate(csi, rdb, obj); - if (error) - return fz_error_note(error, "cannot set ExtGState (%d 0 R)", fz_to_num(obj)); - return fz_okay; + pdf_run_extgstate(csi, rdb, obj); + /* RJW: "cannot set ExtGState (%d 0 R)", fz_to_num(obj) */ } static void pdf_run_h(pdf_csi *csi) @@ -1927,31 +1883,28 @@ static void pdf_run(pdf_csi *csi) pdf_show_path(csi, 1, 0, 1, 0); } -static fz_error pdf_run_sh(pdf_csi *csi, fz_obj *rdb) +static void pdf_run_sh(pdf_csi *csi, fz_obj *rdb) { fz_context *ctx = csi->dev->ctx; fz_obj *dict; fz_obj *obj; fz_shade *shd; - fz_error error; dict = fz_dict_gets(rdb, "Shading"); if (!dict) - return fz_error_make("cannot find shading dictionary"); + fz_throw(ctx, "cannot find shading dictionary"); obj = fz_dict_gets(dict, csi->name); if (!obj) - return fz_error_make("cannot find shading resource: '%s'", csi->name); + fz_throw(ctx, "cannot find shading resource: '%s'", csi->name); if ((csi->dev->hints & FZ_IGNORE_SHADE) == 0) { - error = pdf_load_shading(&shd, csi->xref, obj); - if (error) - return fz_error_note(error, "cannot load shading (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + shd = pdf_load_shading(csi->xref, obj); + /* RJW: "cannot load shading (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ pdf_show_shade(csi, shd); fz_drop_shade(ctx, shd); } - return fz_okay; } static void pdf_run_v(pdf_csi *csi) @@ -2018,11 +1971,10 @@ static void pdf_run_dquote(pdf_csi *csi) #define B(a,b) (a | b << 8) #define C(a,b,c) (a | b << 8 | c << 16) -static fz_error +static void pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) { fz_context *ctx = csi->dev->ctx; - fz_error error; int key; key = buf[0]; @@ -2045,9 +1997,8 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) case B('B','*'): pdf_run_Bstar(csi); break; case C('B','D','C'): pdf_run_BDC(csi); break; case B('B','I'): - error = pdf_run_BI(csi, rdb, file); - if (error) - return fz_error_note(error, "cannot draw inline image"); + pdf_run_BI(csi, rdb, file); + /* RJW: "cannot draw inline image" */ break; case C('B','M','C'): pdf_run_BMC(csi); break; case B('B','T'): pdf_run_BT(csi); break; @@ -2055,9 +2006,14 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) case B('C','S'): pdf_run_CS(csi, rdb); break; case B('D','P'): pdf_run_DP(csi); break; case B('D','o'): - error = pdf_run_Do(csi, rdb); - if (error) - fz_error_handle(error, "cannot draw xobject/image"); + fz_try(ctx) + { + pdf_run_Do(csi, rdb); + } + fz_catch(ctx) + { + fz_warn(ctx, "cannot draw xobject/image"); + } break; case C('E','M','C'): pdf_run_EMC(csi); break; case B('E','T'): pdf_run_ET(csi); break; @@ -2080,9 +2036,14 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) case B('T','c'): pdf_run_Tc(csi); break; case B('T','d'): pdf_run_Td(csi); break; case B('T','f'): - error = pdf_run_Tf(csi, rdb); - if (error) - fz_error_handle(error, "cannot set font"); + fz_try(ctx) + { + pdf_run_Tf(csi, rdb); + } + fz_catch(ctx) + { + fz_warn(ctx, "cannot set font"); + } break; case B('T','j'): pdf_run_Tj(csi); break; case B('T','m'): pdf_run_Tm(csi); break; @@ -2104,9 +2065,14 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) case B('f','*'): pdf_run_fstar(csi); break; case A('g'): pdf_run_g(csi); break; case B('g','s'): - error = pdf_run_gs(csi, rdb); - if (error) - fz_error_handle(error, "cannot set graphics state"); + fz_try(ctx) + { + pdf_run_gs(csi, rdb); + } + fz_catch(ctx) + { + fz_warn(ctx, "cannot set graphics state"); + } break; case A('h'): pdf_run_h(csi); break; case A('i'): pdf_run_i(csi); break; @@ -2123,9 +2089,14 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) case B('s','c'): pdf_run_sc(csi, rdb); break; case C('s','c','n'): pdf_run_sc(csi, rdb); break; case B('s','h'): - error = pdf_run_sh(csi, rdb); - if (error) - fz_error_handle(error, "cannot draw shading"); + fz_try(ctx) + { + pdf_run_sh(csi, rdb); + } + fz_catch(ctx) + { + fz_warn(ctx, "cannot draw shading"); + } break; case A('v'): pdf_run_v(csi); break; case A('w'): pdf_run_w(csi); break; @@ -2135,15 +2106,12 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf) fz_warn(ctx, "unknown keyword: '%s'", buf); break; } - - return fz_okay; } -static fz_error +static void pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen) { fz_context *ctx = csi->dev->ctx; - fz_error error; int tok, len, in_array; /* make sure we have a clean slate if we come here from flush_text */ @@ -2153,11 +2121,10 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen while (1) { if (csi->top == nelem(csi->stack) - 1) - return fz_error_make("stack overflow"); + fz_throw(ctx, "stack overflow"); - error = pdf_lex(&tok, file, buf, buflen, &len); - if (error) - return fz_error_note(error, "lexical error in content stream"); + tok = pdf_lex(file, buf, buflen, &len); + /* RJW: "lexical error in content stream" */ if (in_array) { @@ -2179,26 +2146,25 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen if (!strcmp(buf, "Tw") || !strcmp(buf, "Tc")) fz_warn(ctx, "ignoring keyword '%s' inside array", buf); else - return fz_error_make("syntax error in array"); + fz_throw(ctx, "syntax error in array"); } else if (tok == PDF_TOK_EOF) - return fz_okay; + return; else - return fz_error_make("syntax error in array"); + fz_throw(ctx, "syntax error in array"); } else switch (tok) { case PDF_TOK_ENDSTREAM: case PDF_TOK_EOF: - return fz_okay; + return; case PDF_TOK_OPEN_ARRAY: if (!csi->in_text) { - error = pdf_parse_array(&csi->obj, csi->xref, file, buf, buflen); - if (error) - return fz_error_note(error, "cannot parse array"); + csi->obj = pdf_parse_array(csi->xref, file, buf, buflen); + /* RJW: "cannot parse array" */ } else { @@ -2207,9 +2173,8 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen break; case PDF_TOK_OPEN_DICT: - error = pdf_parse_dict(&csi->obj, csi->xref, file, buf, buflen); - if (error) - return fz_error_note(error, "cannot parse dictionary"); + csi->obj = pdf_parse_dict(csi->xref, file, buf, buflen); + /* RJW: "cannot parse dictionary" */ break; case PDF_TOK_NAME: @@ -2239,14 +2204,13 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen break; case PDF_TOK_KEYWORD: - error = pdf_run_keyword(csi, rdb, file, buf); - if (error) - return fz_error_note(error, "cannot run keyword"); + pdf_run_keyword(csi, rdb, file, buf); + /* RJW: "cannot run keyword" */ pdf_clear_stack(csi); break; default: - return fz_error_make("syntax error in content stream"); + fz_throw(ctx, "syntax error in content stream"); } } } @@ -2255,30 +2219,38 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen * Entry points */ -static fz_error +static void pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents) { - fz_error error; fz_context *ctx = csi->dev->ctx; int len = sizeof csi->xref->scratch; - char *buf = fz_malloc(ctx, len); /* we must be re-entrant for type3 fonts */ - fz_stream *file = fz_open_buffer(ctx, contents); - int save_in_text = csi->in_text; - csi->in_text = 0; - error = pdf_run_stream(csi, rdb, file, buf, len); - csi->in_text = save_in_text; + char * volatile buf = NULL; + fz_stream * volatile file = NULL; + int save_in_text; + + fz_try(ctx) + { + buf = fz_malloc(ctx, len); /* we must be re-entrant for type3 fonts */ + file = fz_open_buffer(ctx, contents); + save_in_text = csi->in_text; + csi->in_text = 0; + pdf_run_stream(csi, rdb, file, buf, len); + csi->in_text = save_in_text; + } + fz_catch(ctx) + { + fz_close(file); + fz_free(ctx, buf); + fz_throw(ctx, "cannot parse context stream"); + } fz_close(file); fz_free(ctx, buf); - if (error) - return fz_error_note(error, "cannot parse content stream"); - return fz_okay; } -fz_error +void pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm, char *target) { pdf_csi *csi; - fz_error error; pdf_annot *annot; int flags; fz_context *ctx = dev->ctx; @@ -2287,10 +2259,16 @@ pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matri fz_begin_group(dev, fz_transform_rect(ctm, page->mediabox), 1, 0, 0, 1); csi = pdf_new_csi(xref, dev, ctm, target); - error = pdf_run_buffer(csi, page->resources, page->contents); + fz_try(ctx) + { + pdf_run_buffer(csi, page->resources, page->contents); + } + fz_catch(ctx) + { + pdf_free_csi(csi); + fz_throw(ctx, "cannot parse page content stream"); + } pdf_free_csi(csi); - if (error) - return fz_error_note(error, "cannot parse page content stream"); for (annot = page->annots; annot; annot = annot->next) { @@ -2308,31 +2286,42 @@ pdf_run_page_with_usage(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matri continue; csi = pdf_new_csi(xref, dev, ctm, target); - error = pdf_run_xobject(csi, page->resources, annot->ap, annot->matrix); + fz_try(ctx) + { + pdf_run_xobject(csi, page->resources, annot->ap, annot->matrix); + } + fz_catch(ctx) + { + pdf_free_csi(csi); + fz_throw(ctx, "cannot parse annotation appearance stream"); + } pdf_free_csi(csi); - if (error) - return fz_error_note(error, "cannot parse annotation appearance stream"); } if (page->transparency) fz_end_group(dev); - - return fz_okay; } -fz_error +void pdf_run_page(pdf_xref *xref, pdf_page *page, fz_device *dev, fz_matrix ctm) { - return pdf_run_page_with_usage(xref, page, dev, ctm, "View"); + pdf_run_page_with_usage(xref, page, dev, ctm, "View"); } -fz_error +void pdf_run_glyph(pdf_xref *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm) { pdf_csi *csi = pdf_new_csi(xref, dev, ctm, "View"); - fz_error error = pdf_run_buffer(csi, resources, contents); + fz_context *ctx = xref->ctx; + + fz_try(ctx) + { + pdf_run_buffer(csi, resources, contents); + } + fz_catch(ctx) + { + pdf_free_csi(csi); + fz_throw(ctx, "cannot parse glyph content stream"); + } pdf_free_csi(csi); - if (error) - return fz_error_note(error, "cannot parse glyph content stream"); - return fz_okay; } diff --git a/pdf/pdf_lex.c b/pdf/pdf_lex.c index d34b2b6f..edb27b7b 100644 --- a/pdf/pdf_lex.c +++ b/pdf/pdf_lex.c @@ -379,8 +379,8 @@ pdf_token_from_keyword(char *key) return PDF_TOK_KEYWORD; } -fz_error -pdf_lex(int *tok, fz_stream *f, char *buf, int n, int *sl) +int +pdf_lex(fz_stream *f, char *buf, int n, int *sl) { while (1) { @@ -388,8 +388,7 @@ pdf_lex(int *tok, fz_stream *f, char *buf, int n, int *sl) switch (c) { case EOF: - *tok = PDF_TOK_EOF; - return fz_okay; + return PDF_TOK_EOF; case IS_WHITE: lex_white(f); break; @@ -399,63 +398,51 @@ pdf_lex(int *tok, fz_stream *f, char *buf, int n, int *sl) case '/': lex_name(f, buf, n); *sl = strlen(buf); - *tok = PDF_TOK_NAME; - return fz_okay; + return PDF_TOK_NAME; case '(': *sl = lex_string(f, buf, n); - *tok = PDF_TOK_STRING; - return fz_okay; + return PDF_TOK_STRING; case ')': - *tok = PDF_TOK_ERROR; - goto cleanuperror; + fz_throw(f->ctx, "lexical error (unexpected ')')"); case '<': c = fz_read_byte(f); if (c == '<') { - *tok = PDF_TOK_OPEN_DICT; + return PDF_TOK_OPEN_DICT; } else { fz_unread_byte(f); *sl = lex_hex_string(f, buf, n); - *tok = PDF_TOK_STRING; + return PDF_TOK_STRING; } - return fz_okay; case '>': c = fz_read_byte(f); if (c == '>') { - *tok = PDF_TOK_CLOSE_DICT; - return fz_okay; + return PDF_TOK_CLOSE_DICT; } - *tok = PDF_TOK_ERROR; - goto cleanuperror; + fz_throw(f->ctx, "lexical error (unexpected '>')"); case '[': - *tok = PDF_TOK_OPEN_ARRAY; - return fz_okay; + return PDF_TOK_OPEN_ARRAY; case ']': - *tok = PDF_TOK_CLOSE_ARRAY; - return fz_okay; + return PDF_TOK_CLOSE_ARRAY; case '{': - *tok = PDF_TOK_OPEN_BRACE; - return fz_okay; + return PDF_TOK_OPEN_BRACE; case '}': - *tok = PDF_TOK_CLOSE_BRACE; - return fz_okay; + return PDF_TOK_CLOSE_BRACE; case IS_NUMBER: - fz_unread_byte(f); - *sl = lex_number(f, buf, n, tok); - return fz_okay; + { + int tok; + fz_unread_byte(f); + *sl = lex_number(f, buf, n, &tok); + return tok; + } default: /* isregular: !isdelim && !iswhite && c != EOF */ fz_unread_byte(f); lex_name(f, buf, n); *sl = strlen(buf); - *tok = pdf_token_from_keyword(buf); - return fz_okay; + return pdf_token_from_keyword(buf); } } - -cleanuperror: - *tok = PDF_TOK_ERROR; - return fz_error_make("lexical error"); } diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c index 9c67edf0..c97eb9b4 100644 --- a/pdf/pdf_page.c +++ b/pdf/pdf_page.c @@ -95,7 +95,7 @@ pdf_load_page_tree_node(pdf_xref *xref, fz_obj *node, struct info info) } } -fz_error +void pdf_load_page_tree(pdf_xref *xref) { struct info info; @@ -105,9 +105,9 @@ pdf_load_page_tree(pdf_xref *xref) fz_obj *count = fz_dict_gets(pages, "Count"); if (!fz_is_dict(pages)) - return fz_error_make("missing page tree"); + fz_throw(ctx, "missing page tree"); if (!fz_is_int(count)) - return fz_error_make("missing page count"); + fz_throw(ctx, "missing page count"); xref->page_cap = fz_to_int(count); xref->page_len = 0; @@ -120,8 +120,6 @@ pdf_load_page_tree(pdf_xref *xref) info.rotate = NULL; pdf_load_page_tree_node(xref, pages, info); - - return fz_okay; } /* We need to know whether to install a page-level transparency group */ @@ -202,10 +200,9 @@ found: /* we need to combine all sub-streams into one for the content stream interpreter */ -static fz_error -pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list) +static fz_buffer * +pdf_load_page_contents_array(pdf_xref *xref, fz_obj *list) { - fz_error error; fz_buffer *big; fz_buffer *one; int i, n; @@ -217,10 +214,13 @@ pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *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_try(ctx) { - fz_error_handle(error, "cannot load content stream part %d/%d", i + 1, n); + one = pdf_load_stream(xref, fz_to_num(stm), fz_to_gen(stm)); + } + fz_catch(ctx) + { + fz_warn(ctx, "cannot load content stream part %d/%d", i + 1, n); continue; } @@ -236,44 +236,35 @@ pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list) if (n > 0 && big->len == 0) { fz_drop_buffer(ctx, big); - return fz_error_make("cannot load content stream"); + fz_throw(ctx, "cannot load content stream"); } - *bigbufp = big; - return fz_okay; + return big; } -static fz_error -pdf_load_page_contents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj) +static fz_buffer * +pdf_load_page_contents(pdf_xref *xref, fz_obj *obj) { - fz_error error; fz_context *ctx = xref->ctx; if (fz_is_array(obj)) { - error = pdf_load_page_contents_array(bufp, xref, obj); - if (error) - return fz_error_note(error, "cannot load content stream array"); + return pdf_load_page_contents_array(xref, obj); + /* RJW: "cannot load content stream array" */ } else if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj))) { - error = pdf_load_stream(bufp, xref, fz_to_num(obj), fz_to_gen(obj)); - if (error) - return fz_error_note(error, "cannot load content stream (%d 0 R)", fz_to_num(obj)); - } - else - { - fz_warn(ctx, "page contents missing, leaving page blank"); - *bufp = fz_new_buffer(ctx, 0); + return pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj)); + /* RJW: "cannot load content stream (%d 0 R)", fz_to_num(obj) */ } - return fz_okay; + fz_warn(ctx, "page contents missing, leaving page blank"); + return fz_new_buffer(ctx, 0); } -fz_error -pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) +pdf_page * +pdf_load_page(pdf_xref *xref, int number) { - fz_error error; pdf_page *page; pdf_annot *annot; fz_obj *pageobj, *pageref; @@ -282,7 +273,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) fz_context *ctx = xref->ctx; if (number < 0 || number >= xref->page_len) - return fz_error_make("cannot find page %d", number + 1); + fz_throw(ctx, "cannot find page %d", number + 1); /* Ensure that we have a store for resource objects */ if (!xref->store) @@ -341,11 +332,14 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) fz_keep_obj(page->resources); obj = fz_dict_gets(pageobj, "Contents"); - error = pdf_load_page_contents(&page->contents, xref, obj); - if (error) + fz_try(ctx) + { + page->contents = pdf_load_page_contents(xref, obj); + } + fz_catch(ctx) { pdf_free_page(ctx, page); - return fz_error_note(error, "cannot load page %d contents (%d 0 R)", number + 1, fz_to_num(pageref)); + fz_throw(ctx, "cannot load page %d contents (%d 0 R)", number + 1, fz_to_num(pageref)); } if (pdf_resources_use_blending(ctx, page->resources)) @@ -355,8 +349,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number) if (pdf_resources_use_blending(ctx, annot->ap->resources)) page->transparency = 1; - *pagep = page; - return fz_okay; + return page; } void diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c index 5a243289..4e393370 100644 --- a/pdf/pdf_parse.c +++ b/pdf/pdf_parse.c @@ -170,147 +170,142 @@ pdf_to_utf8_name(fz_context *ctx, fz_obj *src) return dst; } -fz_error -pdf_parse_array(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap) +fz_obj * +pdf_parse_array(pdf_xref *xref, fz_stream *file, char *buf, int cap) { - fz_error error = fz_okay; fz_obj *ary = NULL; fz_obj *obj = NULL; int a = 0, b = 0, n = 0; int tok; int len; fz_context *ctx = file->ctx; + fz_obj *op; ary = fz_new_array(ctx, 4); - while (1) + fz_try(ctx) { - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) + while (1) { - fz_drop_obj(ary); - return fz_error_note(error, "cannot parse array"); - } + tok = pdf_lex(file, buf, cap, &len); - if (tok != PDF_TOK_INT && tok != PDF_TOK_R) - { - if (n > 0) + if (tok != PDF_TOK_INT && tok != PDF_TOK_R) + { + if (n > 0) + { + obj = fz_new_int(ctx, a); + fz_array_push(ary, obj); + fz_drop_obj(obj); + } + if (n > 1) + { + obj = fz_new_int(ctx, b); + fz_array_push(ary, obj); + fz_drop_obj(obj); + } + n = 0; + } + + if (tok == PDF_TOK_INT && n == 2) { obj = fz_new_int(ctx, a); fz_array_push(ary, obj); fz_drop_obj(obj); + a = b; + n --; } - if (n > 1) + + switch (tok) { - obj = fz_new_int(ctx, b); + case PDF_TOK_CLOSE_ARRAY: + op = ary; + goto end; + + case PDF_TOK_INT: + if (n == 0) + a = atoi(buf); + if (n == 1) + b = atoi(buf); + n ++; + break; + + case PDF_TOK_R: + if (n != 2) + { + fz_drop_obj(ary); + fz_throw(ctx, "cannot parse indirect reference in array"); + } + obj = fz_new_indirect(ctx, a, b, xref); fz_array_push(ary, obj); fz_drop_obj(obj); - } - n = 0; - } + n = 0; + break; - if (tok == PDF_TOK_INT && n == 2) - { - obj = fz_new_int(ctx, a); - fz_array_push(ary, obj); - fz_drop_obj(obj); - a = b; - n --; - } + case PDF_TOK_OPEN_ARRAY: + obj = pdf_parse_array(xref, file, buf, cap); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; - switch (tok) - { - case PDF_TOK_CLOSE_ARRAY: - *op = ary; - return fz_okay; - - case PDF_TOK_INT: - if (n == 0) - a = atoi(buf); - if (n == 1) - b = atoi(buf); - n ++; - break; - - case PDF_TOK_R: - if (n != 2) - { - fz_drop_obj(ary); - return fz_error_make("cannot parse indirect reference in array"); - } - obj = fz_new_indirect(ctx, a, b, xref); - fz_array_push(ary, obj); - fz_drop_obj(obj); - n = 0; - break; - - case PDF_TOK_OPEN_ARRAY: - error = pdf_parse_array(&obj, xref, file, buf, cap); - if (error) - { - fz_drop_obj(ary); - return fz_error_note(error, "cannot parse array"); - } - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; + case PDF_TOK_OPEN_DICT: + obj = pdf_parse_dict(xref, file, buf, cap); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; - case PDF_TOK_OPEN_DICT: - error = pdf_parse_dict(&obj, xref, file, buf, cap); - if (error) - { + case PDF_TOK_NAME: + obj = fz_new_name(ctx, buf); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + case PDF_TOK_REAL: + obj = fz_new_real(ctx, fz_atof(buf)); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + case PDF_TOK_STRING: + obj = fz_new_string(ctx, buf, len); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + case PDF_TOK_TRUE: + obj = fz_new_bool(ctx, 1); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + case PDF_TOK_FALSE: + obj = fz_new_bool(ctx, 0); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + case PDF_TOK_NULL: + obj = fz_new_null(ctx); + fz_array_push(ary, obj); + fz_drop_obj(obj); + break; + + default: fz_drop_obj(ary); - return fz_error_note(error, "cannot parse array"); + fz_throw(ctx, "cannot parse token in array"); } - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - - case PDF_TOK_NAME: - obj = fz_new_name(ctx, buf); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - case PDF_TOK_REAL: - obj = fz_new_real(ctx, fz_atof(buf)); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - case PDF_TOK_STRING: - obj = fz_new_string(ctx, buf, len); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - case PDF_TOK_TRUE: - obj = fz_new_bool(ctx, 1); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - case PDF_TOK_FALSE: - obj = fz_new_bool(ctx, 0); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - case PDF_TOK_NULL: - obj = fz_new_null(ctx); - fz_array_push(ary, obj); - fz_drop_obj(obj); - break; - - default: - fz_drop_obj(ary); - return fz_error_make("cannot parse token in array"); } +end: + {} + } + fz_catch(ctx) + { + fz_drop_obj(ary); + fz_throw(ctx, "cannot parse array"); } + return op; } -fz_error -pdf_parse_dict(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap) +fz_obj * +pdf_parse_dict(pdf_xref *xref, fz_stream *file, char *buf, int cap) { - fz_error error = fz_okay; - fz_obj *dict = NULL; - fz_obj *key = NULL; - fz_obj *val = NULL; + fz_obj * volatile dict = NULL; + fz_obj * volatile key = NULL; + fz_obj * volatile val = NULL; int tok; int len; int a, b; @@ -318,211 +313,161 @@ pdf_parse_dict(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap) dict = fz_new_dict(ctx, 8); - while (1) + fz_try(ctx) { - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) + while (1) { - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); - } + tok = pdf_lex(file, buf, cap, &len); + skip: + if (tok == PDF_TOK_CLOSE_DICT) + break; -skip: - if (tok == PDF_TOK_CLOSE_DICT) - { - *op = dict; - return fz_okay; - } + /* for BI .. ID .. EI in content streams */ + if (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID")) + break; - /* for BI .. ID .. EI in content streams */ - if (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID")) - { - *op = dict; - return fz_okay; - } + if (tok != PDF_TOK_NAME) + fz_throw(ctx, "invalid key in dict"); - if (tok != PDF_TOK_NAME) - { - fz_drop_obj(dict); - return fz_error_make("invalid key in dict"); - } + key = fz_new_name(ctx, buf); - key = fz_new_name(ctx, buf); + tok = pdf_lex(file, buf, cap, &len); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - { - fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); - } - - switch (tok) - { - case PDF_TOK_OPEN_ARRAY: - error = pdf_parse_array(&val, xref, file, buf, cap); - if (error) + switch (tok) { - fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); - } - break; + case PDF_TOK_OPEN_ARRAY: + val = pdf_parse_array(xref, file, buf, cap); + break; - case PDF_TOK_OPEN_DICT: - error = pdf_parse_dict(&val, xref, file, buf, cap); - if (error) - { - fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); - } - break; - - case PDF_TOK_NAME: val = fz_new_name(ctx, buf); break; - case PDF_TOK_REAL: val = fz_new_real(ctx, fz_atof(buf)); break; - case PDF_TOK_STRING: val = fz_new_string(ctx, buf, len); break; - case PDF_TOK_TRUE: val = fz_new_bool(ctx, 1); break; - case PDF_TOK_FALSE: val = fz_new_bool(ctx, 0); break; - case PDF_TOK_NULL: val = fz_new_null(ctx); break; - - case PDF_TOK_INT: - /* 64-bit to allow for numbers > INT_MAX and overflow */ - a = (int) strtoll(buf, 0, 10); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - { - fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); - } - if (tok == PDF_TOK_CLOSE_DICT || tok == PDF_TOK_NAME || - (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID"))) - { - val = fz_new_int(ctx, a); - fz_dict_put(dict, key, val); - fz_drop_obj(val); - fz_drop_obj(key); - goto skip; - } - if (tok == PDF_TOK_INT) - { - b = atoi(buf); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) + case PDF_TOK_OPEN_DICT: + val = pdf_parse_dict(xref, file, buf, cap); + break; + + case PDF_TOK_NAME: val = fz_new_name(ctx, buf); break; + case PDF_TOK_REAL: val = fz_new_real(ctx, fz_atof(buf)); break; + case PDF_TOK_STRING: val = fz_new_string(ctx, buf, len); break; + case PDF_TOK_TRUE: val = fz_new_bool(ctx, 1); break; + case PDF_TOK_FALSE: val = fz_new_bool(ctx, 0); break; + case PDF_TOK_NULL: val = fz_new_null(ctx); break; + + case PDF_TOK_INT: + /* 64-bit to allow for numbers > INT_MAX and overflow */ + a = (int) strtoll(buf, 0, 10); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TOK_CLOSE_DICT || tok == PDF_TOK_NAME || + (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID"))) { + val = fz_new_int(ctx, a); + fz_dict_put(dict, key, val); + fz_drop_obj(val); fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_note(error, "cannot parse dict"); + goto skip; } - if (tok == PDF_TOK_R) + if (tok == PDF_TOK_INT) { - val = fz_new_indirect(ctx, a, b, xref); - break; + b = atoi(buf); + tok = pdf_lex(file, buf, cap, &len); + if (tok == PDF_TOK_R) + { + val = fz_new_indirect(ctx, a, b, xref); + break; + } } + fz_throw(ctx, "invalid indirect reference in dict"); + + default: + fz_drop_obj(key); + fz_drop_obj(dict); + fz_throw(ctx, "unknown token in dict"); } - fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_make("invalid indirect reference in dict"); - default: + fz_dict_put(dict, key, val); + fz_drop_obj(val); fz_drop_obj(key); - fz_drop_obj(dict); - return fz_error_make("unknown token in dict"); + key = NULL; } - - fz_dict_put(dict, key, val); - fz_drop_obj(val); + } + fz_catch(ctx) + { + fz_drop_obj(dict); fz_drop_obj(key); + fz_throw(ctx, "cannot parse dict"); } + return dict; } -fz_error -pdf_parse_stm_obj(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap) +fz_obj * +pdf_parse_stm_obj(pdf_xref *xref, fz_stream *file, char *buf, int cap) { - fz_error error; int tok; int len; fz_context *ctx = file->ctx; - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse token in object stream"); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse token in object stream") */ switch (tok) { case PDF_TOK_OPEN_ARRAY: - error = pdf_parse_array(op, xref, file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse object stream"); - break; + return pdf_parse_array(xref, file, buf, cap); + /* RJW: "cannot parse object stream" */ case PDF_TOK_OPEN_DICT: - error = pdf_parse_dict(op, xref, file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse object stream"); - break; - case PDF_TOK_NAME: *op = fz_new_name(ctx, buf); break; - case PDF_TOK_REAL: *op = fz_new_real(ctx, fz_atof(buf)); break; - case PDF_TOK_STRING: *op = fz_new_string(ctx, buf, len); break; - case PDF_TOK_TRUE: *op = fz_new_bool(ctx, 1); break; - case PDF_TOK_FALSE: *op = fz_new_bool(ctx, 0); break; - case PDF_TOK_NULL: *op = fz_new_null(ctx); break; - case PDF_TOK_INT: *op = fz_new_int(ctx, atoi(buf)); break; - default: return fz_error_make("unknown token in object stream"); + return pdf_parse_dict(xref, file, buf, cap); + /* RJW: "cannot parse object stream" */ + case PDF_TOK_NAME: return fz_new_name(ctx, buf); break; + case PDF_TOK_REAL: return fz_new_real(ctx, fz_atof(buf)); break; + case PDF_TOK_STRING: return fz_new_string(ctx, buf, len); break; + case PDF_TOK_TRUE: return fz_new_bool(ctx, 1); break; + case PDF_TOK_FALSE: return fz_new_bool(ctx, 0); break; + case PDF_TOK_NULL: return fz_new_null(ctx); break; + case PDF_TOK_INT: return fz_new_int(ctx, atoi(buf)); break; + default: fz_throw(ctx, "unknown token in object stream"); } - - return fz_okay; + return NULL; /* Stupid MSVC */ } -fz_error -pdf_parse_ind_obj(fz_obj **op, pdf_xref *xref, +fz_obj * +pdf_parse_ind_obj(pdf_xref *xref, fz_stream *file, char *buf, int cap, int *onum, int *ogen, int *ostmofs) { - fz_error error = fz_okay; - fz_obj *obj = NULL; + fz_obj * volatile obj = NULL; int num = 0, gen = 0, stm_ofs; int tok; int len; int a, b; fz_context *ctx = file->ctx; - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_INT) - return fz_error_make("expected object number (%d %d R)", num, gen); + fz_throw(ctx, "expected object number (%d %d R)", num, gen); num = atoi(buf); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_INT) - return fz_error_make("expected generation number (%d %d R)", num, gen); + fz_throw(ctx, "expected generation number (%d %d R)", num, gen); gen = atoi(buf); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_OBJ) - return fz_error_make("expected 'obj' keyword (%d %d R)", num, gen); + fz_throw(ctx, "expected 'obj' keyword (%d %d R)", num, gen); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ switch (tok) { case PDF_TOK_OPEN_ARRAY: - error = pdf_parse_array(&obj, xref, file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + obj = pdf_parse_array(xref, file, buf, cap); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_OPEN_DICT: - error = pdf_parse_dict(&obj, xref, file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + obj = pdf_parse_dict(xref, file, buf, cap); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_NAME: obj = fz_new_name(ctx, buf); break; @@ -534,9 +479,8 @@ pdf_parse_ind_obj(fz_obj **op, pdf_xref *xref, case PDF_TOK_INT: a = atoi(buf); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* "cannot parse indirect object (%d %d R)", num, gen */ if (tok == PDF_TOK_STREAM || tok == PDF_TOK_ENDOBJ) { obj = fz_new_int(ctx, a); @@ -545,30 +489,32 @@ pdf_parse_ind_obj(fz_obj **op, pdf_xref *xref, if (tok == PDF_TOK_INT) { b = atoi(buf); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse indirect object (%d %d R)", num, gen); */ if (tok == PDF_TOK_R) { obj = fz_new_indirect(ctx, a, b, xref); break; } } - return fz_error_make("expected 'R' keyword (%d %d R)", num, gen); + fz_throw(ctx, "expected 'R' keyword (%d %d R)", num, gen); case PDF_TOK_ENDOBJ: obj = fz_new_null(ctx); goto skip; default: - return fz_error_make("syntax error in object (%d %d R)", num, gen); + fz_throw(ctx, "syntax error in object (%d %d R)", num, gen); } - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) + fz_try(ctx) + { + tok = pdf_lex(file, buf, cap, &len); + } + fz_catch(ctx) { fz_drop_obj(obj); - return fz_error_note(error, "cannot parse indirect object (%d %d R)", num, gen); + fz_throw(ctx, "cannot parse indirect object (%d %d R)", num, gen); } skip: @@ -600,6 +546,5 @@ skip: if (onum) *onum = num; if (ogen) *ogen = gen; if (ostmofs) *ostmofs = stm_ofs; - *op = obj; - return fz_okay; + return obj; } diff --git a/pdf/pdf_pattern.c b/pdf/pdf_pattern.c index c50f93ae..194d9650 100644 --- a/pdf/pdf_pattern.c +++ b/pdf/pdf_pattern.c @@ -1,18 +1,16 @@ #include "fitz.h" #include "mupdf.h" -fz_error -pdf_load_pattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict) +pdf_pattern * +pdf_load_pattern(pdf_xref *xref, fz_obj *dict) { - fz_error error; pdf_pattern *pat; fz_obj *obj; fz_context *ctx = xref->ctx; - if ((*patp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_pattern, dict))) + if ((pat = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_pattern, dict))) { - pdf_keep_pattern(*patp); - return fz_okay; + return pdf_keep_pattern(pat); } pat = fz_malloc(ctx, sizeof(pdf_pattern)); @@ -40,16 +38,17 @@ pdf_load_pattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict) if (pat->resources) fz_keep_obj(pat->resources); - error = pdf_load_stream(&pat->contents, xref, fz_to_num(dict), fz_to_gen(dict)); - if (error) + fz_try(ctx) + { + pat->contents = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict)); + } + fz_catch(ctx) { pdf_remove_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_pattern, dict); pdf_drop_pattern(ctx, pat); - return fz_error_note(error, "cannot load pattern stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + fz_throw(ctx, "cannot load pattern stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); } - - *patp = pat; - return fz_okay; + return pat; } pdf_pattern * diff --git a/pdf/pdf_repair.c b/pdf/pdf_repair.c index 969683d4..0a30f83b 100644 --- a/pdf/pdf_repair.c +++ b/pdf/pdf_repair.c @@ -12,31 +12,29 @@ struct entry int stm_len; }; -static fz_error +static void pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, fz_obj **encrypt, fz_obj **id) { - fz_error error; int tok; int stm_len; int len; int n; + fz_context *ctx = file->ctx; *stmofsp = 0; *stmlenp = -1; stm_len = 0; - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot parse object"); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot parse object" */ if (tok == PDF_TOK_OPEN_DICT) { fz_obj *dict, *obj; /* Send NULL xref so we don't try to resolve references */ - error = pdf_parse_dict(&dict, NULL, file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse object"); + dict = pdf_parse_dict(NULL, file, buf, cap); + /* RJW: "cannot parse object" */ obj = fz_dict_gets(dict, "Type"); if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "XRef")) @@ -70,9 +68,8 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, tok != PDF_TOK_ERROR && tok != PDF_TOK_EOF ) { - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot scan for endobj or stream token"); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot scan for endobj or stream token" */ } if (tok == PDF_TOK_STREAM) @@ -86,14 +83,19 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, *stmofsp = fz_tell(file); if (*stmofsp < 0) - return fz_error_make("cannot seek in file"); + fz_throw(ctx, "cannot seek in file"); if (stm_len > 0) { fz_seek(file, *stmofsp + stm_len, 0); - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - fz_error_handle(error, "cannot find endstream token, falling back to scanning"); + fz_try(ctx) + { + tok = pdf_lex(file, buf, cap, &len); + } + fz_catch(ctx) + { + fz_error_handle(1, "cannot find endstream token, falling back to scanning"); + } if (tok == PDF_TOK_ENDSTREAM) goto atobjend; fz_seek(file, *stmofsp, 0); @@ -101,7 +103,7 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, n = fz_read(file, (unsigned char *) buf, 9); if (n < 0) - return fz_error_note(n, "cannot read from file"); + fz_throw(ctx, "cannot read from file"); while (memcmp(buf, "endstream", 9) != 0) { @@ -115,82 +117,74 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, *stmlenp = fz_tell(file) - *stmofsp - 9; atobjend: - error = pdf_lex(&tok, file, buf, cap, &len); - if (error) - return fz_error_note(error, "cannot scan for endobj token"); + tok = pdf_lex(file, buf, cap, &len); + /* RJW: "cannot scan for endobj token" */ if (tok != PDF_TOK_ENDOBJ) - fz_warn(file->ctx, "object missing 'endobj' token"); + fz_warn(ctx, "object missing 'endobj' token"); } - - return fz_okay; } -static fz_error +static void pdf_repair_obj_stm(pdf_xref *xref, int num, int gen) { - fz_error error; fz_obj *obj; fz_stream *stm; int tok; int i, n, count; char buf[256]; + fz_context *ctx = xref->ctx; - error = pdf_load_object(&obj, xref, num, gen); - if (error) - return fz_error_note(error, "cannot load object stream object (%d %d R)", num, gen); - - count = fz_to_int(fz_dict_gets(obj, "N")); - - fz_drop_obj(obj); - - error = pdf_open_stream(&stm, xref, num, gen); - if (error) - return fz_error_note(error, "cannot open object stream object (%d %d R)", num, gen); + fz_try(ctx) + { + obj = pdf_load_object(xref, num, gen); - for (i = 0; i < count; i++) - { - error = pdf_lex(&tok, stm, buf, sizeof buf, &n); - if (error || tok != PDF_TOK_INT) - { - fz_close(stm); - return fz_error_note(error, "corrupt object stream (%d %d R)", num, gen); - } + count = fz_to_int(fz_dict_gets(obj, "N")); - n = atoi(buf); - if (n >= xref->len) - pdf_resize_xref(xref, n + 1); + fz_drop_obj(obj); - xref->table[n].ofs = num; - xref->table[n].gen = i; - xref->table[n].stm_ofs = 0; - xref->table[n].obj = NULL; - xref->table[n].type = 'o'; + stm = pdf_open_stream(xref, num, gen); - error = pdf_lex(&tok, stm, buf, sizeof buf, &n); - if (error || tok != PDF_TOK_INT) + for (i = 0; i < count; i++) { - fz_close(stm); - return fz_error_note(error, "corrupt object stream (%d %d R)", num, gen); + tok = pdf_lex(stm, buf, sizeof buf, &n); + if (tok != PDF_TOK_INT) + fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen); + + n = atoi(buf); + if (n >= xref->len) + pdf_resize_xref(xref, n + 1); + + xref->table[n].ofs = num; + xref->table[n].gen = i; + xref->table[n].stm_ofs = 0; + xref->table[n].obj = NULL; + xref->table[n].type = 'o'; + + tok = pdf_lex(stm, buf, sizeof buf, &n); + if (tok != PDF_TOK_INT) + fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen); } } - + fz_catch(ctx) + { + fz_close(stm); + fz_throw(ctx, "cannot load object stream object (%d %d R)", num, gen); + } fz_close(stm); - return fz_okay; } -fz_error +void pdf_repair_xref(pdf_xref *xref, char *buf, int bufsize) { - fz_error error; fz_obj *dict, *obj; fz_obj *length; - fz_obj *encrypt = NULL; - fz_obj *id = NULL; - fz_obj *root = NULL; - fz_obj *info = NULL; + fz_obj * volatile encrypt = NULL; + fz_obj * volatile id = NULL; + fz_obj * volatile root = NULL; + fz_obj * volatile info = NULL; - struct entry *list = NULL; + struct entry * volatile list = NULL; int listlen; int listcap; int maxnum = 0; @@ -206,244 +200,225 @@ pdf_repair_xref(pdf_xref *xref, char *buf, int bufsize) fz_seek(xref->file, 0, 0); - listlen = 0; - listcap = 1024; - list = fz_malloc_array(ctx, listcap, sizeof(struct entry)); - - /* look for '%PDF' version marker within first kilobyte of file */ - n = fz_read(xref->file, (unsigned char *)buf, MAX(bufsize, 1024)); - if (n < 0) + fz_try(ctx) { - error = fz_error_note(n, "cannot read from file"); - goto cleanup; - } + listlen = 0; + listcap = 1024; + list = fz_malloc_array(ctx, listcap, sizeof(struct entry)); - fz_seek(xref->file, 0, 0); - for (i = 0; i < n - 4; i++) - { - if (memcmp(buf + i, "%PDF", 4) == 0) + /* look for '%PDF' version marker within first kilobyte of file */ + n = fz_read(xref->file, (unsigned char *)buf, MAX(bufsize, 1024)); + if (n < 0) + fz_throw(ctx, "cannot read from file"); + + fz_seek(xref->file, 0, 0); + for (i = 0; i < n - 4; i++) { - fz_seek(xref->file, i + 8, 0); /* skip "%PDF-X.Y" */ - break; + if (memcmp(buf + i, "%PDF", 4) == 0) + { + fz_seek(xref->file, i + 8, 0); /* skip "%PDF-X.Y" */ + break; + } } - } - /* skip comment line after version marker since some generators - * forget to terminate the comment with a newline */ - c = fz_read_byte(xref->file); - while (c >= 0 && (c == ' ' || c == '%')) + /* skip comment line after version marker since some generators + * forget to terminate the comment with a newline */ c = fz_read_byte(xref->file); - fz_unread_byte(xref->file); + while (c >= 0 && (c == ' ' || c == '%')) + c = fz_read_byte(xref->file); + fz_unread_byte(xref->file); - while (1) - { - tmpofs = fz_tell(xref->file); - if (tmpofs < 0) + while (1) { - error = fz_error_make("cannot tell in file"); - goto cleanup; - } + tmpofs = fz_tell(xref->file); + if (tmpofs < 0) + fz_throw(ctx, "cannot tell in file"); - error = pdf_lex(&tok, xref->file, buf, bufsize, &n); - if (error) - { - fz_error_handle(error, "ignoring the rest of the file"); - break; - } + tok = pdf_lex(xref->file, buf, bufsize, &n); + /* RJW: "ignoring the rest of the file" */ - if (tok == PDF_TOK_INT) - { - numofs = genofs; - num = gen; - genofs = tmpofs; - gen = atoi(buf); - } + if (tok == PDF_TOK_INT) + { + numofs = genofs; + num = gen; + genofs = tmpofs; + gen = atoi(buf); + } - else if (tok == PDF_TOK_OBJ) - { - error = pdf_repair_obj(xref->file, buf, bufsize, &stm_ofs, &stm_len, &encrypt, &id); - if (error) + else if (tok == PDF_TOK_OBJ) { - error = fz_error_note(error, "cannot parse object (%d %d R)", num, gen); - goto cleanup; + pdf_repair_obj(xref->file, buf, bufsize, &stm_ofs, &stm_len, &encrypt, &id); + /* RJW: "cannot parse object (%d %d R)", num, gen); */ + + if (listlen + 1 == listcap) + { + listcap = (listcap * 3) / 2; + list = fz_resize_array(ctx, list, listcap, sizeof(struct entry)); + } + + list[listlen].num = num; + list[listlen].gen = gen; + list[listlen].ofs = numofs; + list[listlen].stm_ofs = stm_ofs; + list[listlen].stm_len = stm_len; + listlen ++; + + if (num > maxnum) + maxnum = num; } - if (listlen + 1 == listcap) + /* trailer dictionary */ + else if (tok == PDF_TOK_OPEN_DICT) { - listcap = (listcap * 3) / 2; - list = fz_resize_array(ctx, list, listcap, sizeof(struct entry)); + dict = pdf_parse_dict(xref, xref->file, buf, bufsize); + /* RJW: "cannot parse object" */ + + obj = fz_dict_gets(dict, "Encrypt"); + if (obj) + { + if (encrypt) + fz_drop_obj(encrypt); + encrypt = fz_keep_obj(obj); + } + + obj = fz_dict_gets(dict, "ID"); + if (obj) + { + if (id) + fz_drop_obj(id); + id = fz_keep_obj(obj); + } + + obj = fz_dict_gets(dict, "Root"); + if (obj) + { + if (root) + fz_drop_obj(root); + root = fz_keep_obj(obj); + } + + obj = fz_dict_gets(dict, "Info"); + if (obj) + { + if (info) + fz_drop_obj(info); + info = fz_keep_obj(obj); + } + + fz_drop_obj(dict); } - list[listlen].num = num; - list[listlen].gen = gen; - list[listlen].ofs = numofs; - list[listlen].stm_ofs = stm_ofs; - list[listlen].stm_len = stm_len; - listlen ++; + else if (tok == PDF_TOK_ERROR) + fz_read_byte(xref->file); - if (num > maxnum) - maxnum = num; + else if (tok == PDF_TOK_EOF) + break; } - /* trailer dictionary */ - else if (tok == PDF_TOK_OPEN_DICT) + /* make xref reasonable */ + + pdf_resize_xref(xref, maxnum + 1); + + for (i = 0; i < listlen; i++) { - error = pdf_parse_dict(&dict, xref, xref->file, buf, bufsize); - if (error) - { - error = fz_error_note(error, "cannot parse object"); - goto cleanup; - } + xref->table[list[i].num].type = 'n'; + xref->table[list[i].num].ofs = list[i].ofs; + xref->table[list[i].num].gen = list[i].gen; - obj = fz_dict_gets(dict, "Encrypt"); - if (obj) - { - if (encrypt) - fz_drop_obj(encrypt); - encrypt = fz_keep_obj(obj); - } + xref->table[list[i].num].stm_ofs = list[i].stm_ofs; - obj = fz_dict_gets(dict, "ID"); - if (obj) + /* corrected stream length */ + if (list[i].stm_len >= 0) { - if (id) - fz_drop_obj(id); - id = fz_keep_obj(obj); - } + dict = pdf_load_object(xref, list[i].num, list[i].gen); + /* RJW: "cannot load stream object (%d %d R)", list[i].num, list[i].gen */ - obj = fz_dict_gets(dict, "Root"); - if (obj) - { - if (root) - fz_drop_obj(root); - root = fz_keep_obj(obj); - } + length = fz_new_int(ctx, list[i].stm_len); + fz_dict_puts(dict, "Length", length); + fz_drop_obj(length); - obj = fz_dict_gets(dict, "Info"); - if (obj) - { - if (info) - fz_drop_obj(info); - info = fz_keep_obj(obj); + fz_drop_obj(dict); } - fz_drop_obj(dict); } - else if (tok == PDF_TOK_ERROR) - fz_read_byte(xref->file); - - else if (tok == PDF_TOK_EOF) - break; - } - - /* make xref reasonable */ - - pdf_resize_xref(xref, maxnum + 1); + xref->table[0].type = 'f'; + xref->table[0].ofs = 0; + xref->table[0].gen = 65535; + xref->table[0].stm_ofs = 0; + xref->table[0].obj = NULL; - for (i = 0; i < listlen; i++) - { - xref->table[list[i].num].type = 'n'; - xref->table[list[i].num].ofs = list[i].ofs; - xref->table[list[i].num].gen = list[i].gen; - - xref->table[list[i].num].stm_ofs = list[i].stm_ofs; - - /* corrected stream length */ - if (list[i].stm_len >= 0) + next = 0; + for (i = xref->len - 1; i >= 0; i--) { - error = pdf_load_object(&dict, xref, list[i].num, list[i].gen); - if (error) + if (xref->table[i].type == 'f') { - error = fz_error_note(error, "cannot load stream object (%d %d R)", list[i].num, list[i].gen); - goto cleanup; + xref->table[i].ofs = next; + if (xref->table[i].gen < 65535) + xref->table[i].gen ++; + next = i; } - - length = fz_new_int(ctx, list[i].stm_len); - fz_dict_puts(dict, "Length", length); - fz_drop_obj(length); - - fz_drop_obj(dict); } - } + /* create a repaired trailer, Root will be added later */ - xref->table[0].type = 'f'; - xref->table[0].ofs = 0; - xref->table[0].gen = 65535; - xref->table[0].stm_ofs = 0; - xref->table[0].obj = NULL; + xref->trailer = fz_new_dict(ctx, 5); - next = 0; - for (i = xref->len - 1; i >= 0; i--) - { - if (xref->table[i].type == 'f') + obj = fz_new_int(ctx, maxnum + 1); + fz_dict_puts(xref->trailer, "Size", obj); + fz_drop_obj(obj); + + if (root) { - xref->table[i].ofs = next; - if (xref->table[i].gen < 65535) - xref->table[i].gen ++; - next = i; + fz_dict_puts(xref->trailer, "Root", root); + fz_drop_obj(root); + } + if (info) + { + fz_dict_puts(xref->trailer, "Info", info); + fz_drop_obj(info); } - } - - /* create a repaired trailer, Root will be added later */ - - xref->trailer = fz_new_dict(ctx, 5); - - obj = fz_new_int(ctx, maxnum + 1); - fz_dict_puts(xref->trailer, "Size", obj); - fz_drop_obj(obj); - - if (root) - { - fz_dict_puts(xref->trailer, "Root", root); - fz_drop_obj(root); - } - if (info) - { - fz_dict_puts(xref->trailer, "Info", info); - fz_drop_obj(info); - } - if (encrypt) - { - if (fz_is_indirect(encrypt)) + if (encrypt) { - /* create new reference with non-NULL xref pointer */ - obj = fz_new_indirect(ctx, fz_to_num(encrypt), fz_to_gen(encrypt), xref); + if (fz_is_indirect(encrypt)) + { + /* create new reference with non-NULL xref pointer */ + obj = fz_new_indirect(ctx, fz_to_num(encrypt), fz_to_gen(encrypt), xref); + fz_drop_obj(encrypt); + encrypt = obj; + } + fz_dict_puts(xref->trailer, "Encrypt", encrypt); fz_drop_obj(encrypt); - encrypt = obj; } - fz_dict_puts(xref->trailer, "Encrypt", encrypt); - fz_drop_obj(encrypt); - } - if (id) - { - if (fz_is_indirect(id)) + if (id) { - /* create new reference with non-NULL xref pointer */ - obj = fz_new_indirect(ctx, fz_to_num(id), fz_to_gen(id), xref); + if (fz_is_indirect(id)) + { + /* create new reference with non-NULL xref pointer */ + obj = fz_new_indirect(ctx, fz_to_num(id), fz_to_gen(id), xref); + fz_drop_obj(id); + id = obj; + } + fz_dict_puts(xref->trailer, "ID", id); fz_drop_obj(id); - id = obj; } - fz_dict_puts(xref->trailer, "ID", id); - fz_drop_obj(id); - } - fz_free(ctx, list); - return fz_okay; - -cleanup: - if (encrypt) fz_drop_obj(encrypt); - if (id) fz_drop_obj(id); - if (root) fz_drop_obj(root); - if (info) fz_drop_obj(info); - fz_free(ctx, list); - return error; /* already rethrown */ + fz_free(ctx, list); + } + fz_catch(ctx) + { + if (encrypt) fz_drop_obj(encrypt); + if (id) fz_drop_obj(id); + if (root) fz_drop_obj(root); + if (info) fz_drop_obj(info); + fz_free(ctx, list); + fz_rethrow(ctx); + } } -fz_error +void pdf_repair_obj_stms(pdf_xref *xref) { fz_obj *dict; @@ -453,12 +428,10 @@ pdf_repair_obj_stms(pdf_xref *xref) { if (xref->table[i].stm_ofs) { - pdf_load_object(&dict, xref, i, 0); + dict = pdf_load_object(xref, i, 0); if (!strcmp(fz_to_name(fz_dict_gets(dict, "Type")), "ObjStm")) pdf_repair_obj_stm(xref, i, 0); fz_drop_obj(dict); } } - - return fz_okay; } diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c index 1c8897f6..ca39e1f8 100644 --- a/pdf/pdf_shade.c +++ b/pdf/pdf_shade.c @@ -957,155 +957,132 @@ pdf_load_type7_shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, /* Load all of the shading dictionary parameters, then switch on the shading type. */ -static fz_error -pdf_load_shading_dict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_matrix transform) +static fz_shade * +pdf_load_shading_dict(pdf_xref *xref, fz_obj *dict, fz_matrix transform) { - fz_error error; - fz_shade *shade; - pdf_function *func[FZ_MAX_COLORS] = { NULL }; - fz_stream *stream = NULL; + fz_shade * volatile shade = NULL; + pdf_function * volatile func[FZ_MAX_COLORS] = { NULL }; + fz_stream * volatile stream = NULL; fz_obj *obj; int funcs; int type; int i; fz_context *ctx = xref->ctx; - shade = fz_malloc(ctx, sizeof(fz_shade)); - shade->refs = 1; - shade->type = FZ_MESH; - shade->use_background = 0; - shade->use_function = 0; - shade->matrix = transform; - shade->bbox = fz_infinite_rect; - shade->extend[0] = 0; - shade->extend[1] = 0; + fz_try(ctx) + { + shade = fz_malloc(ctx, sizeof(fz_shade)); + shade->refs = 1; + shade->type = FZ_MESH; + shade->use_background = 0; + shade->use_function = 0; + shade->matrix = transform; + shade->bbox = fz_infinite_rect; + shade->extend[0] = 0; + shade->extend[1] = 0; - shade->mesh_len = 0; - shade->mesh_cap = 0; - shade->mesh = NULL; + shade->mesh_len = 0; + shade->mesh_cap = 0; + shade->mesh = NULL; - shade->colorspace = NULL; + shade->colorspace = NULL; - funcs = 0; + funcs = 0; - obj = fz_dict_gets(dict, "ShadingType"); - type = fz_to_int(obj); + obj = fz_dict_gets(dict, "ShadingType"); + type = fz_to_int(obj); - obj = fz_dict_gets(dict, "ColorSpace"); - if (!obj) - { - fz_drop_shade(ctx, shade); - return fz_error_make("shading colorspace is missing"); - } - error = pdf_load_colorspace(&shade->colorspace, xref, obj); - if (error) - { - fz_drop_shade(ctx, shade); - return fz_error_note(error, "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - } - - obj = fz_dict_gets(dict, "Background"); - if (obj) - { - shade->use_background = 1; - for (i = 0; i < shade->colorspace->n; i++) - shade->background[i] = fz_to_real(fz_array_get(obj, i)); - } - - obj = fz_dict_gets(dict, "BBox"); - if (fz_is_array(obj)) - { - shade->bbox = pdf_to_rect(ctx, obj); - } - - obj = fz_dict_gets(dict, "Function"); - if (fz_is_dict(obj)) - { - funcs = 1; + obj = fz_dict_gets(dict, "ColorSpace"); + if (!obj) + fz_throw(ctx, "shading colorspace is missing"); + shade->colorspace = pdf_load_colorspace(xref, obj); + /* RJW: "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ - error = pdf_load_function(&func[0], xref, obj); - if (error) + obj = fz_dict_gets(dict, "Background"); + if (obj) { - error = fz_error_note(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - goto cleanup; + shade->use_background = 1; + for (i = 0; i < shade->colorspace->n; i++) + shade->background[i] = fz_to_real(fz_array_get(obj, i)); } - } - else if (fz_is_array(obj)) - { - funcs = fz_array_len(obj); - if (funcs != 1 && funcs != shade->colorspace->n) + + obj = fz_dict_gets(dict, "BBox"); + if (fz_is_array(obj)) { - error = fz_error_make("incorrect number of shading functions"); - goto cleanup; + shade->bbox = pdf_to_rect(ctx, obj); } - for (i = 0; i < funcs; i++) + obj = fz_dict_gets(dict, "Function"); + if (fz_is_dict(obj)) + { + funcs = 1; + + func[0] = pdf_load_function(xref, obj); + /* RJW: "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ + } + else if (fz_is_array(obj)) { - error = pdf_load_function(&func[i], xref, fz_array_get(obj, i)); - if (error) + funcs = fz_array_len(obj); + if (funcs != 1 && funcs != shade->colorspace->n) + fz_throw(ctx, "incorrect number of shading functions"); + + for (i = 0; i < funcs; i++) { - error = fz_error_note(error, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); - goto cleanup; + func[i] = pdf_load_function(xref, fz_array_get(obj, i)); + fz_throw(ctx, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); } } - } - if (type >= 4 && type <= 7) - { - error = pdf_open_stream(&stream, xref, fz_to_num(dict), fz_to_gen(dict)); - if (error) + if (type >= 4 && type <= 7) { - error = fz_error_note(error, "cannot open shading stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); - goto cleanup; + stream = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict)); + /* RJW: "cannot open shading stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */ } - } - - switch (type) - { - case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; - case 2: pdf_load_axial_shading(shade, xref, dict, funcs, func); break; - case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; - case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func, stream); break; - case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func, stream); break; - case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func, stream); break; - case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func, stream); break; - default: - error = fz_error_make("unknown shading type: %d", type); - goto cleanup; - } - if (stream) - fz_close(stream); - for (i = 0; i < funcs; i++) - if (func[i]) - pdf_drop_function(ctx, func[i]); - - *shadep = shade; - return fz_okay; + switch (type) + { + case 1: pdf_load_function_based_shading(shade, xref, dict, func[0]); break; + case 2: pdf_load_axial_shading(shade, xref, dict, funcs, func); break; + case 3: pdf_load_radial_shading(shade, xref, dict, funcs, func); break; + case 4: pdf_load_type4_shade(shade, xref, dict, funcs, func, stream); break; + case 5: pdf_load_type5_shade(shade, xref, dict, funcs, func, stream); break; + case 6: pdf_load_type6_shade(shade, xref, dict, funcs, func, stream); break; + case 7: pdf_load_type7_shade(shade, xref, dict, funcs, func, stream); break; + default: + fz_throw(ctx, "unknown shading type: %d", type); + } -cleanup: - if (stream) - fz_close(stream); - for (i = 0; i < funcs; i++) - if (func[i]) - pdf_drop_function(ctx, func[i]); - fz_drop_shade(ctx, shade); + if (stream) + fz_close(stream); + for (i = 0; i < funcs; i++) + if (func[i]) + pdf_drop_function(ctx, func[i]); + } + fz_catch(ctx) + { + if (stream) + fz_close(stream); + for (i = 0; i < funcs; i++) + if (func[i]) + pdf_drop_function(ctx, func[i]); + fz_drop_shade(ctx, shade); - return fz_error_note(error, "cannot load shading type %d (%d %d R)", type, fz_to_num(dict), fz_to_gen(dict)); + fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, fz_to_num(dict), fz_to_gen(dict)); + } + return shade; } -fz_error -pdf_load_shading(fz_shade **shadep, pdf_xref *xref, fz_obj *dict) +fz_shade * +pdf_load_shading(pdf_xref *xref, fz_obj *dict) { - fz_error error; fz_matrix mat; fz_obj *obj; fz_context *ctx = xref->ctx; + fz_shade *shade; - if ((*shadep = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_shade, dict))) + if ((shade = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)fz_drop_shade, dict))) { - fz_keep_shade(*shadep); - return fz_okay; + return fz_keep_shade(shade); } /* Type 2 pattern dictionary */ @@ -1128,22 +1105,20 @@ pdf_load_shading(fz_shade **shadep, pdf_xref *xref, fz_obj *dict) obj = fz_dict_gets(dict, "Shading"); if (!obj) - return fz_error_make("syntaxerror: missing shading dictionary"); + fz_throw(ctx, "syntaxerror: missing shading dictionary"); - error = pdf_load_shading_dict(shadep, xref, obj, mat); - if (error) - return fz_error_note(error, "cannot load shading dictionary (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); + shade = pdf_load_shading_dict(xref, obj, mat); + /* RJW: "cannot load shading dictionary (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */ } /* Naked shading dictionary */ else { - error = pdf_load_shading_dict(shadep, xref, dict, fz_identity); - if (error) - return fz_error_note(error, "cannot load shading dictionary (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + shade = pdf_load_shading_dict(xref, dict, fz_identity); + /* RJW: "cannot load shading dictionary (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */ } - pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_shade, (pdf_store_drop_fn *)fz_drop_shade, dict, *shadep); + pdf_store_item(ctx, xref->store, (pdf_store_keep_fn *)fz_keep_shade, (pdf_store_drop_fn *)fz_drop_shade, dict, shade); - return fz_okay; + return shade; } diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c index c7259bc3..614f076a 100644 --- a/pdf/pdf_stream.c +++ b/pdf/pdf_stream.c @@ -7,17 +7,11 @@ int pdf_is_stream(pdf_xref *xref, int num, int gen) { - fz_error error; - if (num < 0 || num >= xref->len) return 0; - error = pdf_cache_object(xref, num, gen); - if (error) - { - fz_error_handle(error, "cannot load object, ignoring error"); - return 0; - } + pdf_cache_object(xref, num, gen); + /* RJW: "cannot load object, ignoring error" */ return xref->table[num].stm_ofs > 0; } @@ -57,7 +51,6 @@ pdf_stream_has_crypt(fz_context *ctx, fz_obj *stm) static fz_stream * build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen) { - fz_error error; char *s; fz_context *ctx = chain->ctx; @@ -100,9 +93,8 @@ build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num, if (obj) { fz_buffer *globals; - error = pdf_load_stream(&globals, xref, fz_to_num(obj), fz_to_gen(obj)); - if (error) - fz_error_handle(error, "cannot load jbig2 global segments"); + globals = pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj)); + /* RJW: "cannot load jbig2 global segments" */ chain = fz_open_jbig2d(chain, globals); fz_drop_buffer(ctx, globals); return chain; @@ -233,29 +225,26 @@ pdf_open_inline_stream(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int len * Open a stream for reading the raw (compressed but decrypted) data. * Using xref->file while this is open is a bad idea. */ -fz_error -pdf_open_raw_stream(fz_stream **stmp, pdf_xref *xref, int num, int gen) +fz_stream * +pdf_open_raw_stream(pdf_xref *xref, int num, int gen) { - pdf_xref_entry *x; - fz_error error; + pdf_xref_entry * volatile x; + fz_stream *stm; if (num < 0 || num >= xref->len) - return fz_error_make("object id out of range (%d %d R)", num, gen); + fz_throw(xref->ctx, "object id out of range (%d %d R)", num, gen); x = xref->table + num; - error = pdf_cache_object(xref, num, gen); - if (error) - return fz_error_note(error, "cannot load stream object (%d %d R)", num, gen); + pdf_cache_object(xref, num, gen); + /* RJW: "cannot load stream object (%d %d R)", num, gen */ - if (x->stm_ofs) - { - *stmp = pdf_open_raw_filter(xref->file, xref, x->obj, num, gen); - fz_seek(xref->file, x->stm_ofs, 0); - return fz_okay; - } + if (x->stm_ofs == 0) + fz_throw(xref->ctx, "object is not a stream"); - return fz_error_make("object is not a stream"); + stm = pdf_open_raw_filter(xref->file, xref, x->obj, num, gen); + fz_seek(xref->file, x->stm_ofs, 0); + return stm; } /* @@ -263,75 +252,67 @@ pdf_open_raw_stream(fz_stream **stmp, pdf_xref *xref, int num, int gen) * Put the opened file in xref->stream. * Using xref->file while a stream is open is a Bad idea. */ -fz_error -pdf_open_stream(fz_stream **stmp, pdf_xref *xref, int num, int gen) +fz_stream * +pdf_open_stream(pdf_xref *xref, int num, int gen) { pdf_xref_entry *x; - fz_error error; + fz_stream *stm; if (num < 0 || num >= xref->len) - return fz_error_make("object id out of range (%d %d R)", num, gen); + fz_throw(xref->ctx, "object id out of range (%d %d R)", num, gen); x = xref->table + num; - error = pdf_cache_object(xref, num, gen); - if (error) - return fz_error_note(error, "cannot load stream object (%d %d R)", num, gen); + pdf_cache_object(xref, num, gen); + /* RJW: "cannot load stream object (%d %d R)", num, gen */ - if (x->stm_ofs) - { - *stmp = pdf_open_filter(xref->file, xref, x->obj, num, gen); - fz_seek(xref->file, x->stm_ofs, 0); - return fz_okay; - } + if (x->stm_ofs == 0) + fz_throw(xref->ctx, "object is not a stream"); - return fz_error_make("object is not a stream"); + stm = pdf_open_filter(xref->file, xref, x->obj, num, gen); + fz_seek(xref->file, x->stm_ofs, 0); + return stm; } -fz_error -pdf_open_stream_at(fz_stream **stmp, pdf_xref *xref, int num, int gen, fz_obj *dict, int stm_ofs) +fz_stream * +pdf_open_stream_at(pdf_xref *xref, int num, int gen, fz_obj *dict, int stm_ofs) { - if (stm_ofs) - { - *stmp = pdf_open_filter(xref->file, xref, dict, num, gen); - fz_seek(xref->file, stm_ofs, 0); - return fz_okay; - } - return fz_error_make("object is not a stream"); + fz_stream *stm; + + if (stm_ofs == 0) + fz_throw(xref->ctx, "object is not a stream"); + + stm = pdf_open_filter(xref->file, xref, dict, num, gen); + fz_seek(xref->file, stm_ofs, 0); + return stm; } /* * Load raw (compressed but decrypted) contents of a stream into buf. */ -fz_error -pdf_load_raw_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) +fz_buffer * +pdf_load_raw_stream(pdf_xref *xref, int num, int gen) { - fz_error error; fz_stream *stm; fz_obj *dict; int len; + fz_buffer *buf; - error = pdf_load_object(&dict, xref, num, gen); - if (error) - return fz_error_note(error, "cannot load stream dictionary (%d %d R)", num, gen); + dict = pdf_load_object(xref, num, gen); + /* RJW: "cannot load stream dictionary (%d %d R)", num, gen */ len = fz_to_int(fz_dict_gets(dict, "Length")); fz_drop_obj(dict); - error = pdf_open_raw_stream(&stm, xref, num, gen); - if (error) - return fz_error_note(error, "cannot open raw stream (%d %d R)", num, gen); + stm = pdf_open_raw_stream(xref, num, gen); + /* RJW: "cannot open raw stream (%d %d R)", num, gen */ - error = fz_read_all(bufp, stm, len); - if (error) - { - fz_close(stm); - return fz_error_note(error, "cannot read raw stream (%d %d R)", num, gen); - } + buf = fz_read_all(stm, len); + /* RJW: "cannot read raw stream (%d %d R)", num, gen */ fz_close(stm); - return fz_okay; + return buf; } static int @@ -353,21 +334,20 @@ pdf_guess_filter_length(int len, char *filter) /* * Load uncompressed contents of a stream into buf. */ -fz_error -pdf_load_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) +fz_buffer * +pdf_load_stream(pdf_xref *xref, int num, int gen) { - fz_error error; + fz_context *ctx = xref->ctx; fz_stream *stm; fz_obj *dict, *obj; int i, len, n; + fz_buffer * volatile buf; - error = pdf_open_stream(&stm, xref, num, gen); - if (error) - return fz_error_note(error, "cannot open stream (%d %d R)", num, gen); + stm = pdf_open_stream(xref, num, gen); + /* RJW: "cannot open stream (%d %d R)", num, gen */ - error = pdf_load_object(&dict, xref, num, gen); - if (error) - return fz_error_note(error, "cannot load stream dictionary (%d %d R)", num, gen); + dict = pdf_load_object(xref, num, gen); + /* RJW: "cannot load stream dictionary (%d %d R)", num, gen */ len = fz_to_int(fz_dict_gets(dict, "Length")); obj = fz_dict_gets(dict, "Filter"); @@ -378,13 +358,16 @@ pdf_load_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen) fz_drop_obj(dict); - error = fz_read_all(bufp, stm, len); - if (error) + fz_try(ctx) + { + buf = fz_read_all(stm, len); + } + fz_catch(ctx) { fz_close(stm); - return fz_error_note(error, "cannot read raw stream (%d %d R)", num, gen); + fz_throw(ctx, "cannot read raw stream (%d %d R)", num, gen); } fz_close(stm); - return fz_okay; + return buf; } diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c index d2523ae6..c129350a 100644 --- a/pdf/pdf_type3.c +++ b/pdf/pdf_type3.c @@ -1,16 +1,15 @@ #include "fitz.h" #include "mupdf.h" -static fz_error +static void pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm) { - return pdf_run_glyph(xref, rdb, contents, dev, ctm); + pdf_run_glyph(xref, rdb, contents, dev, ctm); } -fz_error -pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) +pdf_font_desc * +pdf_load_type3_font(pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { - fz_error error; char buf[256]; char *estrings[256]; pdf_font_desc *fontdesc; @@ -24,136 +23,131 @@ pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_o fz_matrix matrix; fz_context *ctx = xref->ctx; - obj = fz_dict_gets(dict, "Name"); - if (fz_is_name(obj)) - fz_strlcpy(buf, fz_to_name(obj), sizeof buf); - else - sprintf(buf, "Unnamed-T3"); + fz_try(ctx) + { + obj = fz_dict_gets(dict, "Name"); + if (fz_is_name(obj)) + fz_strlcpy(buf, fz_to_name(obj), sizeof buf); + else + sprintf(buf, "Unnamed-T3"); - fontdesc = pdf_new_font_desc(ctx); + fontdesc = pdf_new_font_desc(ctx); - obj = fz_dict_gets(dict, "FontMatrix"); - matrix = pdf_to_matrix(ctx, obj); + obj = fz_dict_gets(dict, "FontMatrix"); + matrix = pdf_to_matrix(ctx, obj); - obj = fz_dict_gets(dict, "FontBBox"); - bbox = pdf_to_rect(ctx, obj); + obj = fz_dict_gets(dict, "FontBBox"); + bbox = pdf_to_rect(ctx, obj); - fontdesc->font = fz_new_type3_font(ctx, buf, matrix); + fontdesc->font = fz_new_type3_font(ctx, buf, matrix); - fz_set_font_bbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + fz_set_font_bbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); - /* Encoding */ + /* Encoding */ - for (i = 0; i < 256; i++) - estrings[i] = NULL; + for (i = 0; i < 256; i++) + estrings[i] = NULL; - encoding = fz_dict_gets(dict, "Encoding"); - if (!encoding) - { - error = fz_error_make("syntaxerror: Type3 font missing Encoding"); - goto cleanup; - } + encoding = fz_dict_gets(dict, "Encoding"); + if (!encoding) + { + fz_throw(ctx, "syntaxerror: Type3 font missing Encoding"); + } - if (fz_is_name(encoding)) - pdf_load_encoding(estrings, fz_to_name(encoding)); + if (fz_is_name(encoding)) + pdf_load_encoding(estrings, fz_to_name(encoding)); - if (fz_is_dict(encoding)) - { - fz_obj *base, *diff, *item; + if (fz_is_dict(encoding)) + { + fz_obj *base, *diff, *item; - base = fz_dict_gets(encoding, "BaseEncoding"); - if (fz_is_name(base)) - pdf_load_encoding(estrings, fz_to_name(base)); + base = fz_dict_gets(encoding, "BaseEncoding"); + if (fz_is_name(base)) + pdf_load_encoding(estrings, fz_to_name(base)); - diff = fz_dict_gets(encoding, "Differences"); - if (fz_is_array(diff)) - { - n = fz_array_len(diff); - k = 0; - for (i = 0; i < n; i++) + diff = fz_dict_gets(encoding, "Differences"); + if (fz_is_array(diff)) { - item = fz_array_get(diff, i); - if (fz_is_int(item)) - k = fz_to_int(item); - if (fz_is_name(item)) - estrings[k++] = fz_to_name(item); - if (k < 0) k = 0; - if (k > 255) k = 255; + n = fz_array_len(diff); + k = 0; + for (i = 0; i < n; i++) + { + item = fz_array_get(diff, i); + if (fz_is_int(item)) + k = fz_to_int(item); + if (fz_is_name(item)) + estrings[k++] = fz_to_name(item); + if (k < 0) k = 0; + if (k > 255) k = 255; + } } } - } - fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); + fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); - error = pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode")); - if (error) - goto cleanup; + pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode")); - /* Widths */ + /* Widths */ - pdf_set_default_hmtx(fontdesc, 0); + pdf_set_default_hmtx(fontdesc, 0); - first = fz_to_int(fz_dict_gets(dict, "FirstChar")); - last = fz_to_int(fz_dict_gets(dict, "LastChar")); + first = fz_to_int(fz_dict_gets(dict, "FirstChar")); + last = fz_to_int(fz_dict_gets(dict, "LastChar")); - widths = fz_dict_gets(dict, "Widths"); - if (!widths) - { - error = fz_error_make("syntaxerror: Type3 font missing Widths"); - goto cleanup; - } + widths = fz_dict_gets(dict, "Widths"); + if (!widths) + { + fz_throw(ctx, "syntaxerror: Type3 font missing Widths"); + } - for (i = first; i <= last; i++) - { - float w = fz_to_real(fz_array_get(widths, i - first)); - w = fontdesc->font->t3matrix.a * w * 1000; - fontdesc->font->t3widths[i] = w * 0.001f; - pdf_add_hmtx(ctx, fontdesc, i, i, w); - } + for (i = first; i <= last; i++) + { + float w = fz_to_real(fz_array_get(widths, i - first)); + w = fontdesc->font->t3matrix.a * w * 1000; + fontdesc->font->t3widths[i] = w * 0.001f; + pdf_add_hmtx(ctx, fontdesc, i, i, w); + } - pdf_end_hmtx(fontdesc); + pdf_end_hmtx(fontdesc); - /* Resources -- inherit page resources if the font doesn't have its own */ + /* Resources -- inherit page resources if the font doesn't have its own */ - fontdesc->font->t3resources = fz_dict_gets(dict, "Resources"); - if (!fontdesc->font->t3resources) - fontdesc->font->t3resources = rdb; - if (fontdesc->font->t3resources) - fz_keep_obj(fontdesc->font->t3resources); - if (!fontdesc->font->t3resources) - fz_warn(ctx, "no resource dictionary for type 3 font!"); + fontdesc->font->t3resources = fz_dict_gets(dict, "Resources"); + if (!fontdesc->font->t3resources) + fontdesc->font->t3resources = rdb; + if (fontdesc->font->t3resources) + fz_keep_obj(fontdesc->font->t3resources); + if (!fontdesc->font->t3resources) + fz_warn(ctx, "no resource dictionary for type 3 font!"); - fontdesc->font->t3xref = xref; - fontdesc->font->t3run = pdf_run_glyph_func; + fontdesc->font->t3xref = xref; + fontdesc->font->t3run = pdf_run_glyph_func; - /* CharProcs */ + /* CharProcs */ - charprocs = fz_dict_gets(dict, "CharProcs"); - if (!charprocs) - { - error = fz_error_make("syntaxerror: Type3 font missing CharProcs"); - goto cleanup; - } + charprocs = fz_dict_gets(dict, "CharProcs"); + if (!charprocs) + { + fz_throw(ctx, "syntaxerror: Type3 font missing CharProcs"); + } - for (i = 0; i < 256; i++) - { - if (estrings[i]) + for (i = 0; i < 256; i++) { - obj = fz_dict_gets(charprocs, estrings[i]); - if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj))) + if (estrings[i]) { - error = pdf_load_stream(&fontdesc->font->t3procs[i], xref, fz_to_num(obj), fz_to_gen(obj)); - if (error) - goto cleanup; + obj = fz_dict_gets(charprocs, estrings[i]); + if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj))) + { + fontdesc->font->t3procs[i] = pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj)); + } } } } - - *fontdescp = fontdesc; - return fz_okay; - -cleanup: - fz_drop_font(ctx, fontdesc->font); - fz_free(ctx, fontdesc); - return fz_error_note(error, "cannot load type3 font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + fz_catch(ctx) + { + fz_drop_font(ctx, fontdesc->font); + fz_free(ctx, fontdesc); + fz_throw(ctx, "cannot load type3 font (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + } + return fontdesc; } diff --git a/pdf/pdf_unicode.c b/pdf/pdf_unicode.c index 46c68a52..7968036a 100644 --- a/pdf/pdf_unicode.c +++ b/pdf/pdf_unicode.c @@ -3,11 +3,10 @@ /* Load or synthesize ToUnicode map for fonts */ -fz_error +void pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm) { - fz_error error = fz_okay; pdf_cmap *cmap; int cid; int ucsbuf[8]; @@ -17,9 +16,8 @@ pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, if (pdf_is_stream(xref, fz_to_num(cmapstm), fz_to_gen(cmapstm))) { - error = pdf_load_embedded_cmap(&cmap, xref, cmapstm); - if (error) - return fz_error_note(error, "cannot load embedded cmap (%d %d R)", fz_to_num(cmapstm), fz_to_gen(cmapstm)); + cmap = pdf_load_embedded_cmap(xref, cmapstm); + /* RJW: "cannot load embedded cmap (%d %d R)", fz_to_num(cmapstm), fz_to_gen(cmapstm) */ font->to_unicode = pdf_new_cmap(ctx); @@ -43,19 +41,17 @@ pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, else if (collection) { - error = fz_okay; - if (!strcmp(collection, "Adobe-CNS1")) - error = pdf_load_system_cmap(ctx, &font->to_unicode, "Adobe-CNS1-UCS2"); + font->to_unicode = pdf_load_system_cmap(ctx, "Adobe-CNS1-UCS2"); else if (!strcmp(collection, "Adobe-GB1")) - error = pdf_load_system_cmap(ctx, &font->to_unicode, "Adobe-GB1-UCS2"); + font->to_unicode = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); else if (!strcmp(collection, "Adobe-Japan1")) - error = pdf_load_system_cmap(ctx, &font->to_unicode, "Adobe-Japan1-UCS2"); + font->to_unicode = pdf_load_system_cmap(ctx, "Adobe-Japan1-UCS2"); else if (!strcmp(collection, "Adobe-Korea1")) - error = pdf_load_system_cmap(ctx, &font->to_unicode, "Adobe-Korea1-UCS2"); + font->to_unicode = pdf_load_system_cmap(ctx, "Adobe-Korea1-UCS2"); - if (error) - return fz_error_note(error, "cannot load ToUnicode system cmap %s-UCS2", collection); + return; + /* RJW: "cannot load ToUnicode system cmap %s-UCS2", collection */ } if (strings) @@ -79,6 +75,4 @@ pdf_load_to_unicode(pdf_font_desc *font, pdf_xref *xref, /* TODO: synthesize a ToUnicode if it's a freetype font with * cmap and/or post tables or if it has glyph names. */ } - - return fz_okay; } diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c index 25503374..ceec02d0 100644 --- a/pdf/pdf_xobject.c +++ b/pdf/pdf_xobject.c @@ -1,18 +1,16 @@ #include "fitz.h" #include "mupdf.h" -fz_error -pdf_load_xobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) +pdf_xobject * +pdf_load_xobject(pdf_xref *xref, fz_obj *dict) { - fz_error error; pdf_xobject *form; fz_obj *obj; fz_context *ctx = xref->ctx; - if ((*formp = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_xobject, dict))) + if ((form = pdf_find_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_xobject, dict))) { - pdf_keep_xobject(*formp); - return fz_okay; + return pdf_keep_xobject(form); } form = fz_malloc(ctx, sizeof(pdf_xobject)); @@ -52,9 +50,8 @@ pdf_load_xobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) obj = fz_dict_gets(attrs, "CS"); if (obj) { - error = pdf_load_colorspace(&form->colorspace, xref, obj); - if (error) - fz_error_handle(error, "cannot load xobject colorspace"); + form->colorspace = pdf_load_colorspace(xref, obj); + fz_throw(ctx, "cannot load xobject colorspace"); } } @@ -62,16 +59,18 @@ pdf_load_xobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) if (form->resources) fz_keep_obj(form->resources); - error = pdf_load_stream(&form->contents, xref, fz_to_num(dict), fz_to_gen(dict)); - if (error) + fz_try(ctx) + { + form->contents = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict)); + } + fz_catch(ctx) { pdf_remove_item(ctx, xref->store, (pdf_store_drop_fn *)pdf_drop_xobject, dict); pdf_drop_xobject(ctx, form); - return fz_error_note(error, "cannot load xobject content stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); + fz_throw(ctx, "cannot load xobject content stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict)); } - *formp = form; - return fz_okay; + return form; } pdf_xobject * diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index 37bbc977..cb538ae3 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -12,7 +12,7 @@ static inline int iswhite(int ch) * magic version tag and startxref */ -static fz_error +static void pdf_load_version(pdf_xref *xref) { char buf[20]; @@ -20,14 +20,12 @@ pdf_load_version(pdf_xref *xref) fz_seek(xref->file, 0, 0); fz_read_line(xref->file, buf, sizeof buf); if (memcmp(buf, "%PDF-", 5) != 0) - return fz_error_make("cannot recognize version marker"); + fz_throw(xref->ctx, "cannot recognize version marker"); xref->version = atoi(buf + 5) * 10 + atoi(buf + 7); - - return fz_okay; } -static fz_error +static void pdf_read_start_xref(pdf_xref *xref) { unsigned char buf[1024]; @@ -43,7 +41,7 @@ pdf_read_start_xref(pdf_xref *xref) n = fz_read(xref->file, buf, sizeof buf); if (n < 0) - return fz_error_note(n, "cannot read from file"); + fz_throw(xref->ctx, "cannot read from file"); for (i = n - 9; i >= 0; i--) { @@ -53,21 +51,20 @@ pdf_read_start_xref(pdf_xref *xref) while (iswhite(buf[i]) && i < n) i ++; xref->startxref = atoi((char*)(buf + i)); - return fz_okay; + return; } } - return fz_error_make("cannot find startxref"); + fz_throw(xref->ctx, "cannot find startxref"); } /* * trailer dictionary */ -static fz_error +static void pdf_read_old_trailer(pdf_xref *xref, char *buf, int cap) { - fz_error error; int len; char *s; int n; @@ -77,7 +74,7 @@ pdf_read_old_trailer(pdf_xref *xref, char *buf, int cap) fz_read_line(xref->file, buf, cap); if (strncmp(buf, "xref", 4) != 0) - return fz_error_make("cannot find xref marker"); + fz_throw(xref->ctx, "cannot find xref marker"); while (1) { @@ -89,7 +86,7 @@ pdf_read_old_trailer(pdf_xref *xref, char *buf, int cap) s = buf; fz_strsep(&s, " "); /* ignore ofs */ if (!s) - return fz_error_make("invalid range marker in xref"); + fz_throw(xref->ctx, "invalid range marker in xref"); len = atoi(fz_strsep(&s, " ")); /* broken pdfs where the section is not on a separate line */ @@ -98,43 +95,45 @@ pdf_read_old_trailer(pdf_xref *xref, char *buf, int cap) t = fz_tell(xref->file); if (t < 0) - return fz_error_make("cannot tell in file"); + fz_throw(xref->ctx, "cannot tell in file"); fz_seek(xref->file, t + 20 * len, 0); } - error = pdf_lex(&tok, xref->file, buf, cap, &n); - if (error) - return fz_error_note(error, "cannot parse trailer"); - if (tok != PDF_TOK_TRAILER) - return fz_error_make("expected trailer marker"); + fz_try(xref->ctx) + { + tok = pdf_lex(xref->file, buf, cap, &n); + if (tok != PDF_TOK_TRAILER) + fz_throw(xref->ctx, "expected trailer marker"); - error = pdf_lex(&tok, xref->file, buf, cap, &n); - if (error) - return fz_error_note(error, "cannot parse trailer"); - if (tok != PDF_TOK_OPEN_DICT) - return fz_error_make("expected trailer dictionary"); + tok = pdf_lex(xref->file, buf, cap, &n); + if (tok != PDF_TOK_OPEN_DICT) + fz_throw(xref->ctx, "expected trailer dictionary"); - error = pdf_parse_dict(&xref->trailer, xref, xref->file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse trailer"); - return fz_okay; + xref->trailer = pdf_parse_dict(xref, xref->file, buf, cap); + } + fz_catch(xref->ctx) + { + fz_throw(xref->ctx, "cannot parse trailer"); + } } -static fz_error +static void pdf_read_new_trailer(pdf_xref *xref, char *buf, int cap) { - fz_error error; - error = pdf_parse_ind_obj(&xref->trailer, xref, xref->file, buf, cap, NULL, NULL, NULL); - if (error) - return fz_error_note(error, "cannot parse trailer (compressed)"); - return fz_okay; + fz_try(xref->ctx) + { + xref->trailer = pdf_parse_ind_obj(xref, xref->file, buf, cap, NULL, NULL, NULL); + } + fz_catch(xref->ctx) + { + fz_throw(xref->ctx, "cannot parse trailer (compressed)"); + } } -static fz_error +static void pdf_read_trailer(pdf_xref *xref, char *buf, int cap) { - fz_error error; int c; fz_seek(xref->file, xref->startxref, 0); @@ -142,25 +141,20 @@ pdf_read_trailer(pdf_xref *xref, char *buf, int cap) while (iswhite(fz_peek_byte(xref->file))) fz_read_byte(xref->file); - c = fz_peek_byte(xref->file); - if (c == 'x') + fz_try(xref->ctx) { - error = pdf_read_old_trailer(xref, buf, cap); - if (error) - return fz_error_note(error, "cannot read trailer"); - } - else if (c >= '0' && c <= '9') - { - error = pdf_read_new_trailer(xref, buf, cap); - if (error) - return fz_error_note(error, "cannot read trailer"); + c = fz_peek_byte(xref->file); + if (c == 'x') + pdf_read_old_trailer(xref, buf, cap); + else if (c >= '0' && c <= '9') + pdf_read_new_trailer(xref, buf, cap); + else + fz_throw(xref->ctx, "cannot recognize xref format: '%c'", c); } - else + fz_catch(xref->ctx) { - return fz_error_make("cannot recognize xref format: '%c'", c); + fz_throw(xref->ctx, "cannot read trailer"); } - - return fz_okay; } /* @@ -184,20 +178,20 @@ pdf_resize_xref(pdf_xref *xref, int newlen) xref->len = newlen; } -static fz_error -pdf_read_old_xref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) +static fz_obj * +pdf_read_old_xref(pdf_xref *xref, char *buf, int cap) { - fz_error error; int ofs, len; char *s; int n; int tok; int i; int c; + fz_obj *trailer; fz_read_line(xref->file, buf, cap); if (strncmp(buf, "xref", 4) != 0) - return fz_error_make("cannot find xref marker"); + fz_throw(xref->ctx, "cannot find xref marker"); while (1) { @@ -228,7 +222,7 @@ pdf_read_old_xref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) { n = fz_read(xref->file, (unsigned char *) buf, 20); if (n < 0) - return fz_error_note(n, "cannot read xref table"); + fz_throw(xref->ctx, "cannot read xref table"); if (!xref->table[i].type) { s = buf; @@ -241,36 +235,37 @@ pdf_read_old_xref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) xref->table[i].gen = atoi(s + 11); xref->table[i].type = s[17]; if (s[17] != 'f' && s[17] != 'n' && s[17] != 'o') - return fz_error_make("unexpected xref type: %#x (%d %d R)", s[17], i, xref->table[i].gen); + fz_throw(xref->ctx, "unexpected xref type: %#x (%d %d R)", s[17], i, xref->table[i].gen); } } } - error = pdf_lex(&tok, xref->file, buf, cap, &n); - if (error) - return fz_error_note(error, "cannot parse trailer"); - if (tok != PDF_TOK_TRAILER) - return fz_error_make("expected trailer marker"); + fz_try(xref->ctx) + { + tok = pdf_lex(xref->file, buf, cap, &n); + if (tok != PDF_TOK_TRAILER) + fz_throw(xref->ctx, "expected trailer marker"); - error = pdf_lex(&tok, xref->file, buf, cap, &n); - if (error) - return fz_error_note(error, "cannot parse trailer"); - if (tok != PDF_TOK_OPEN_DICT) - return fz_error_make("expected trailer dictionary"); + tok = pdf_lex(xref->file, buf, cap, &n); + if (tok != PDF_TOK_OPEN_DICT) + fz_throw(xref->ctx, "expected trailer dictionary"); - error = pdf_parse_dict(trailerp, xref, xref->file, buf, cap); - if (error) - return fz_error_note(error, "cannot parse trailer"); - return fz_okay; + trailer = pdf_parse_dict(xref, xref->file, buf, cap); + } + fz_catch(xref->ctx) + { + fz_throw(xref->ctx, "cannot parse trailer"); + } + return trailer; } -static fz_error +static void pdf_read_new_xref_section(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0, int w1, int w2) { int i, n; if (i0 < 0 || i0 + i1 > xref->len) - return fz_error_make("xref stream has too many entries"); + fz_throw(xref->ctx, "xref stream has too many entries"); for (i = i0; i < i0 + i1; i++) { @@ -279,7 +274,7 @@ pdf_read_new_xref_section(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0 int c = 0; if (fz_is_eof(stm)) - return fz_error_make("truncated xref stream"); + fz_throw(xref->ctx, "truncated xref stream"); for (n = 0; n < w0; n++) a = (a << 8) + fz_read_byte(stm); @@ -296,217 +291,182 @@ pdf_read_new_xref_section(pdf_xref *xref, fz_stream *stm, int i0, int i1, int w0 xref->table[i].gen = w2 ? c : 0; } } - - return fz_okay; } -static fz_error -pdf_read_new_xref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) +static fz_obj * +pdf_read_new_xref(pdf_xref *xref, char *buf, int cap) { - fz_error error; fz_stream *stm; - fz_obj *trailer; - fz_obj *index; - fz_obj *obj; + fz_obj * volatile trailer = NULL; + fz_obj *index = NULL; + fz_obj *obj = NULL; int num, gen, stm_ofs; int size, w0, w1, w2; int t; + fz_context *ctx = xref->ctx; - error = pdf_parse_ind_obj(&trailer, xref, xref->file, buf, cap, &num, &gen, &stm_ofs); - if (error) - return fz_error_note(error, "cannot parse compressed xref stream object"); - - obj = fz_dict_gets(trailer, "Size"); - if (!obj) + fz_try(ctx) { - fz_drop_obj(trailer); - return fz_error_make("xref stream missing Size entry (%d %d R)", num, gen); + trailer = pdf_parse_ind_obj(xref, xref->file, buf, cap, &num, &gen, &stm_ofs); } - size = fz_to_int(obj); - - if (size > xref->len) + fz_catch(ctx) { - pdf_resize_xref(xref, size); + fz_throw(ctx, "cannot parse compressed xref stream object"); } - if (num < 0 || num >= xref->len) + fz_try(ctx) { - fz_drop_obj(trailer); - return fz_error_make("object id (%d %d R) out of range (0..%d)", num, gen, xref->len - 1); - } + obj = fz_dict_gets(trailer, "Size"); + if (!obj) + fz_throw(ctx, "xref stream missing Size entry (%d %d R)", num, gen); - obj = fz_dict_gets(trailer, "W"); - if (!obj) { - fz_drop_obj(trailer); - return fz_error_make("xref stream missing W entry (%d %d R)", num, gen); - } - w0 = fz_to_int(fz_array_get(obj, 0)); - w1 = fz_to_int(fz_array_get(obj, 1)); - w2 = fz_to_int(fz_array_get(obj, 2)); + size = fz_to_int(obj); + if (size > xref->len) + pdf_resize_xref(xref, size); - index = fz_dict_gets(trailer, "Index"); + if (num < 0 || num >= xref->len) + fz_throw(ctx, "object id (%d %d R) out of range (0..%d)", num, gen, xref->len - 1); - error = pdf_open_stream_at(&stm, xref, num, gen, trailer, stm_ofs); - if (error) - { - fz_drop_obj(trailer); - return fz_error_note(error, "cannot open compressed xref stream (%d %d R)", num, gen); - } + obj = fz_dict_gets(trailer, "W"); + if (!obj) + fz_throw(ctx, "xref stream missing W entry (%d %d R)", num, gen); + w0 = fz_to_int(fz_array_get(obj, 0)); + w1 = fz_to_int(fz_array_get(obj, 1)); + w2 = fz_to_int(fz_array_get(obj, 2)); - if (!index) - { - error = pdf_read_new_xref_section(xref, stm, 0, size, w0, w1, w2); - if (error) + index = fz_dict_gets(trailer, "Index"); + + stm = pdf_open_stream_at(xref, num, gen, trailer, stm_ofs); + /* RJW: Ensure pdf_open_stream does fz_throw(ctx, "cannot open compressed xref stream (%d %d R)", num, gen); */ + + if (!index) { - fz_close(stm); - fz_drop_obj(trailer); - return fz_error_note(error, "cannot read xref stream (%d %d R)", num, gen); + pdf_read_new_xref_section(xref, stm, 0, size, w0, w1, w2); + /* RJW: Ensure above does fz_throw(ctx, "cannot read xref stream (%d %d R)", num, gen); */ } - } - else - { - int n = fz_array_len(index); - for (t = 0; t < n; t += 2) + else { - int i0 = fz_to_int(fz_array_get(index, t + 0)); - int i1 = fz_to_int(fz_array_get(index, t + 1)); - error = pdf_read_new_xref_section(xref, stm, i0, i1, w0, w1, w2); - if (error) + int n = fz_array_len(index); + for (t = 0; t < n; t += 2) { - fz_close(stm); - fz_drop_obj(trailer); - return fz_error_note(error, "cannot read xref stream section (%d %d R)", num, gen); + int i0 = fz_to_int(fz_array_get(index, t + 0)); + int i1 = fz_to_int(fz_array_get(index, t + 1)); + pdf_read_new_xref_section(xref, stm, i0, i1, w0, w1, w2); } } } + fz_catch(ctx) + { + fz_close(stm); + fz_drop_obj(trailer); + fz_drop_obj(index); + fz_drop_obj(obj); + fz_rethrow(ctx); + } fz_close(stm); - *trailerp = trailer; - - return fz_okay; + return trailer; } -static fz_error -pdf_read_xref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap) +static fz_obj * +pdf_read_xref(pdf_xref *xref, int ofs, char *buf, int cap) { - fz_error error; int c; + fz_context *ctx = xref->ctx; + fz_obj *trailer; fz_seek(xref->file, ofs, 0); while (iswhite(fz_peek_byte(xref->file))) fz_read_byte(xref->file); - c = fz_peek_byte(xref->file); - if (c == 'x') + fz_try(ctx) { - error = pdf_read_old_xref(trailerp, xref, buf, cap); - if (error) - return fz_error_note(error, "cannot read xref (ofs=%d)", ofs); + c = fz_peek_byte(xref->file); + if (c == 'x') + trailer = pdf_read_old_xref(xref, buf, cap); + else if (c >= '0' && c <= '9') + trailer = pdf_read_new_xref(xref, buf, cap); + else + fz_throw(ctx, "cannot recognize xref format"); } - else if (c >= '0' && c <= '9') + fz_catch(ctx) { - error = pdf_read_new_xref(trailerp, xref, buf, cap); - if (error) - return fz_error_note(error, "cannot read xref (ofs=%d)", ofs); + fz_throw(ctx, "cannot read xref (ofs=%d)", ofs); } - else - { - return fz_error_make("cannot recognize xref format"); - } - - return fz_okay; + return trailer; } -static fz_error +static void pdf_read_xref_sections(pdf_xref *xref, int ofs, char *buf, int cap) { - fz_error error; - fz_obj *trailer; - fz_obj *prev; - fz_obj *xrefstm; - - error = pdf_read_xref(&trailer, xref, ofs, buf, cap); - if (error) - return fz_error_note(error, "cannot read xref section"); + fz_obj *trailer = NULL; + fz_obj *xrefstm = NULL; + fz_obj *prev = NULL; + fz_context *ctx = xref->ctx; - /* FIXME: do we overwrite free entries properly? */ - xrefstm = fz_dict_gets(trailer, "XRefStm"); - if (xrefstm) + fz_try(ctx) { - error = pdf_read_xref_sections(xref, fz_to_int(xrefstm), buf, cap); - if (error) - { - fz_drop_obj(trailer); - return fz_error_note(error, "cannot read /XRefStm xref section"); - } - } + trailer = pdf_read_xref(xref, ofs, buf, cap); + + /* FIXME: do we overwrite free entries properly? */ + xrefstm = fz_dict_gets(trailer, "XRefStm"); + if (xrefstm) + pdf_read_xref_sections(xref, fz_to_int(xrefstm), buf, cap); - prev = fz_dict_gets(trailer, "Prev"); - if (prev) + prev = fz_dict_gets(trailer, "Prev"); + if (prev) + pdf_read_xref_sections(xref, fz_to_int(prev), buf, cap); + } + fz_catch(ctx) { - error = pdf_read_xref_sections(xref, fz_to_int(prev), buf, cap); - if (error) - { - fz_drop_obj(trailer); - return fz_error_note(error, "cannot read /Prev xref section"); - } + fz_drop_obj(trailer); + fz_throw(ctx, "Failed to read xref at offset %d", ofs); } fz_drop_obj(trailer); - return fz_okay; } /* * load xref tables from pdf */ -static fz_error +static void pdf_load_xref(pdf_xref *xref, char *buf, int bufsize) { - fz_error error; fz_obj *size; int i; + fz_context *ctx = xref->ctx; - error = pdf_load_version(xref); - if (error) - return fz_error_note(error, "cannot read version marker"); + pdf_load_version(xref); - error = pdf_read_start_xref(xref); - if (error) - return fz_error_note(error, "cannot read startxref"); + pdf_read_start_xref(xref); - error = pdf_read_trailer(xref, buf, bufsize); - if (error) - return fz_error_note(error, "cannot read trailer"); + pdf_read_trailer(xref, buf, bufsize); size = fz_dict_gets(xref->trailer, "Size"); if (!size) - return fz_error_make("trailer missing Size entry"); + fz_throw(ctx, "trailer missing Size entry"); pdf_resize_xref(xref, fz_to_int(size)); - error = pdf_read_xref_sections(xref, xref->startxref, buf, bufsize); - if (error) - return fz_error_note(error, "cannot read xref"); + pdf_read_xref_sections(xref, xref->startxref, buf, bufsize); /* broken pdfs where first object is not free */ if (xref->table[0].type != 'f') - return fz_error_make("first object in xref is not free"); + fz_throw(ctx, "first object in xref is not free"); /* broken pdfs where object offsets are out of range */ for (i = 0; i < xref->len; i++) { if (xref->table[i].type == 'n') if (xref->table[i].ofs <= 0 || xref->table[i].ofs >= xref->file_size) - return fz_error_make("object offset out of range: %d (%d 0 R)", xref->table[i].ofs, i); + fz_throw(ctx, "object offset out of range: %d (%d 0 R)", xref->table[i].ofs, i); if (xref->table[i].type == 'o') if (xref->table[i].ofs <= 0 || xref->table[i].ofs >= xref->len || xref->table[xref->table[i].ofs].type != 'n') - return fz_error_make("invalid reference to an objstm that does not exist: %d (%d 0 R)", xref->table[i].ofs, i); + fz_throw(ctx, "invalid reference to an objstm that does not exist: %d (%d 0 R)", xref->table[i].ofs, i); } - - return fz_okay; } /* @@ -514,29 +474,32 @@ pdf_load_xref(pdf_xref *xref, char *buf, int bufsize) * If password is not null, try to decrypt. */ -fz_error -pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) +pdf_xref * +pdf_open_xref_with_stream(fz_stream *file, char *password) { pdf_xref *xref; - fz_error error; fz_obj *encrypt, *id; - fz_obj *dict, *obj; + fz_obj *dict = NULL; + fz_obj *obj; + fz_obj *nobj; int i, repaired = 0; fz_context *ctx = file->ctx; + //fz_var(dict); + /* install pdf specific callback */ fz_resolve_indirect = pdf_resolve_indirect; - xref = fz_malloc(ctx, sizeof(pdf_xref)); - memset(xref, 0, sizeof *xref); - + xref = fz_calloc(ctx, 1, sizeof(pdf_xref)); xref->file = fz_keep_stream(file); xref->ctx = ctx; - error = pdf_load_xref(xref, xref->scratch, sizeof xref->scratch); - if (error) + fz_try(ctx) + { + pdf_load_xref(xref, xref->scratch, sizeof xref->scratch); + } + fz_catch(ctx) { - fz_error_handle(error, "trying to repair"); if (xref->table) { fz_free(xref->ctx, xref->table); @@ -548,50 +511,31 @@ pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) fz_drop_obj(xref->trailer); xref->trailer = NULL; } - error = pdf_repair_xref(xref, xref->scratch, sizeof xref->scratch); - if (error) - { - pdf_free_xref(xref); - return fz_error_note(error, "cannot repair document"); - } + pdf_repair_xref(xref, xref->scratch, sizeof xref->scratch); repaired = 1; } - encrypt = fz_dict_gets(xref->trailer, "Encrypt"); - id = fz_dict_gets(xref->trailer, "ID"); - if (fz_is_dict(encrypt)) + fz_try(ctx) { - error = pdf_new_crypt(ctx, &xref->crypt, encrypt, id); - if (error) - { - pdf_free_xref(xref); - return fz_error_note(error, "cannot decrypt document"); - } - } + int hasroot, hasinfo; - if (pdf_needs_password(xref)) - { - /* Only care if we have a password */ - if (password) + encrypt = fz_dict_gets(xref->trailer, "Encrypt"); + id = fz_dict_gets(xref->trailer, "ID"); + if (fz_is_dict(encrypt)) + xref->crypt = pdf_new_crypt(ctx, encrypt, id); + + if (pdf_needs_password(xref)) { - int okay = pdf_authenticate_password(xref, password); - if (!okay) + /* Only care if we have a password */ + if (password) { - pdf_free_xref(xref); - return fz_error_make("invalid password"); + pdf_authenticate_password(xref, password); } } - } - - if (repaired) - { - int hasroot, hasinfo; - error = pdf_repair_obj_stms(xref); - if (error) + if (repaired) { - pdf_free_xref(xref); - return fz_error_note(error, "cannot repair document"); + pdf_repair_obj_stms(xref); } hasroot = fz_dict_gets(xref->trailer, "Root") != NULL; @@ -602,10 +546,13 @@ pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) if (xref->table[i].type == 0 || xref->table[i].type == 'f') continue; - error = pdf_load_object(&dict, xref, i, 0); - if (error) + fz_try(ctx) { - fz_error_handle(error, "ignoring broken object (%d 0 R)", i); + dict = pdf_load_object(xref, i, 0); + } + fz_catch(ctx) + { + fz_warn(ctx, "ignoring broken object (%d 0 R)", i); continue; } @@ -614,9 +561,10 @@ pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) obj = fz_dict_gets(dict, "Type"); if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Catalog")) { - obj = fz_new_indirect(ctx, i, 0, xref); - fz_dict_puts(xref->trailer, "Root", obj); - fz_drop_obj(obj); + nobj = fz_new_indirect(ctx, i, 0, xref); + fz_dict_puts(xref->trailer, "Root", nobj); + fz_drop_obj(nobj); + nobj = NULL; } } @@ -624,18 +572,26 @@ pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) { if (fz_dict_gets(dict, "Creator") || fz_dict_gets(dict, "Producer")) { - obj = fz_new_indirect(ctx, i, 0, xref); - fz_dict_puts(xref->trailer, "Info", obj); - fz_drop_obj(obj); + nobj = fz_new_indirect(ctx, i, 0, xref); + fz_dict_puts(xref->trailer, "Info", nobj); + fz_drop_obj(nobj); + nobj = NULL; } } fz_drop_obj(dict); + dict = NULL; } } + fz_catch(ctx) + { + fz_drop_obj(dict); + fz_drop_obj(nobj); + pdf_free_xref(xref); + fz_throw(ctx, "cannot open document"); + } - *xrefp = xref; - return fz_okay; + return xref; } void @@ -703,14 +659,13 @@ pdf_debug_xref(pdf_xref *xref) * compressed object streams */ -static fz_error +static void pdf_load_obj_stm(pdf_xref *xref, int num, int gen, char *buf, int cap) { - fz_error error; fz_stream *stm; fz_obj *objstm; - int *numbuf; - int *ofsbuf; + int * volatile numbuf = NULL; + int * volatile ofsbuf = NULL; fz_obj *obj; int first; @@ -719,125 +674,113 @@ pdf_load_obj_stm(pdf_xref *xref, int num, int gen, char *buf, int cap) int tok; fz_context *ctx = xref->ctx; - error = pdf_load_object(&objstm, xref, num, gen); - if (error) - return fz_error_note(error, "cannot load object stream object (%d %d R)", num, gen); - - count = fz_to_int(fz_dict_gets(objstm, "N")); - first = fz_to_int(fz_dict_gets(objstm, "First")); - - numbuf = fz_malloc_array(ctx, count, sizeof(int)); - ofsbuf = fz_malloc_array(ctx, count, sizeof(int)); - - error = pdf_open_stream(&stm, xref, num, gen); - if (error) + //fz_var(numbuf); + //fz_var(ofsbuf); + fz_try(ctx) { - error = fz_error_note(error, "cannot open object stream (%d %d R)", num, gen); - goto cleanupbuf; - } + objstm = pdf_load_object(xref, num, gen); - for (i = 0; i < count; i++) - { - error = pdf_lex(&tok, stm, buf, cap, &n); - if (error || tok != PDF_TOK_INT) - { - error = fz_error_note(error, "corrupt object stream (%d %d R)", num, gen); - goto cleanupstm; - } - numbuf[i] = atoi(buf); + count = fz_to_int(fz_dict_gets(objstm, "N")); + first = fz_to_int(fz_dict_gets(objstm, "First")); + + numbuf = fz_calloc(ctx, count, sizeof(int)); + ofsbuf = fz_calloc(ctx, count, sizeof(int)); - error = pdf_lex(&tok, stm, buf, cap, &n); - if (error || tok != PDF_TOK_INT) + stm = pdf_open_stream(xref, num, gen); + for (i = 0; i < count; i++) { - error = fz_error_note(error, "corrupt object stream (%d %d R)", num, gen); - goto cleanupstm; + tok = pdf_lex(stm, buf, cap, &n); + if (tok != PDF_TOK_INT) + fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen); + numbuf[i] = atoi(buf); + + tok = pdf_lex(stm, buf, cap, &n); + if (tok != PDF_TOK_INT) + fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen); + ofsbuf[i] = atoi(buf); } - ofsbuf[i] = atoi(buf); - } - fz_seek(stm, first, 0); + fz_seek(stm, first, 0); - for (i = 0; i < count; i++) - { - fz_seek(stm, first + ofsbuf[i], 0); - - error = pdf_parse_stm_obj(&obj, xref, stm, buf, cap); - if (error) + for (i = 0; i < count; i++) { - error = fz_error_note(error, "cannot parse object %d in stream (%d %d R)", i, num, gen); - goto cleanupstm; - } + fz_seek(stm, first + ofsbuf[i], 0); - if (numbuf[i] < 1 || numbuf[i] >= xref->len) - { - fz_drop_obj(obj); - error = fz_error_make("object id (%d 0 R) out of range (0..%d)", numbuf[i], xref->len - 1); - goto cleanupstm; - } + obj = pdf_parse_stm_obj(xref, stm, buf, cap); + /* RJW: Ensure above does fz_throw(ctx, "cannot parse object %d in stream (%d %d R)", i, num, gen); */ - if (xref->table[numbuf[i]].type == 'o' && xref->table[numbuf[i]].ofs == num) - { - if (xref->table[numbuf[i]].obj) - fz_drop_obj(xref->table[numbuf[i]].obj); - xref->table[numbuf[i]].obj = obj; - } - else - { - fz_drop_obj(obj); + if (numbuf[i] < 1 || numbuf[i] >= xref->len) + { + fz_drop_obj(obj); + fz_throw(ctx, "object id (%d 0 R) out of range (0..%d)", numbuf[i], xref->len - 1); + } + + if (xref->table[numbuf[i]].type == 'o' && xref->table[numbuf[i]].ofs == num) + { + if (xref->table[numbuf[i]].obj) + fz_drop_obj(xref->table[numbuf[i]].obj); + xref->table[numbuf[i]].obj = obj; + } + else + { + fz_drop_obj(obj); + } } } - - fz_close(stm); - fz_free(xref->ctx, ofsbuf); - fz_free(xref->ctx, numbuf); - fz_drop_obj(objstm); - return fz_okay; - -cleanupstm: + fz_catch(ctx) + { + fz_close(stm); + fz_free(xref->ctx, ofsbuf); + fz_free(xref->ctx, numbuf); + fz_drop_obj(objstm); + fz_throw(ctx, "cannot open object stream (%d %d R)", num, gen); + } fz_close(stm); -cleanupbuf: fz_free(xref->ctx, ofsbuf); fz_free(xref->ctx, numbuf); fz_drop_obj(objstm); - return error; /* already rethrown */ } /* * object loading */ -fz_error +void pdf_cache_object(pdf_xref *xref, int num, int gen) { - fz_error error; pdf_xref_entry *x; int rnum, rgen; fz_context *ctx = xref->ctx; if (num < 0 || num >= xref->len) - return fz_error_make("object out of range (%d %d R); xref size %d", num, gen, xref->len); + fz_throw(ctx, "object out of range (%d %d R); xref size %d", num, gen, xref->len); x = &xref->table[num]; if (x->obj) - return fz_okay; + return; if (x->type == 'f') { x->obj = fz_new_null(ctx); - return fz_okay; + return; } else if (x->type == 'n') { fz_seek(xref->file, x->ofs, 0); - error = pdf_parse_ind_obj(&x->obj, xref, xref->file, xref->scratch, sizeof xref->scratch, - &rnum, &rgen, &x->stm_ofs); - if (error) - return fz_error_note(error, "cannot parse object (%d %d R)", num, gen); + fz_try(ctx) + { + x->obj = pdf_parse_ind_obj(xref, xref->file, xref->scratch, sizeof xref->scratch, + &rnum, &rgen, &x->stm_ofs); + } + fz_catch(ctx) + { + fz_throw(ctx, "cannot parse object (%d %d R)", num, gen); + } if (rnum != num) - return fz_error_make("found object (%d %d R) instead of (%d %d R)", rnum, rgen, num, gen); + fz_throw(ctx, "found object (%d %d R) instead of (%d %d R)", rnum, rgen, num, gen); if (xref->crypt) pdf_crypt_obj(ctx, xref->crypt, x->obj, num, gen); @@ -846,35 +789,41 @@ pdf_cache_object(pdf_xref *xref, int num, int gen) { if (!x->obj) { - error = pdf_load_obj_stm(xref, x->ofs, 0, xref->scratch, sizeof xref->scratch); - if (error) - return fz_error_note(error, "cannot load object stream containing object (%d %d R)", num, gen); + fz_try(ctx) + { + pdf_load_obj_stm(xref, x->ofs, 0, xref->scratch, sizeof xref->scratch); + } + fz_catch(ctx) + { + fz_throw(ctx, "cannot load object stream containing object (%d %d R)", num, gen); + } if (!x->obj) - return fz_error_make("object (%d %d R) was not found in its object stream", num, gen); + fz_throw(ctx, "object (%d %d R) was not found in its object stream", num, gen); } } else { - return fz_error_make("assert: corrupt xref struct"); + fz_throw(ctx, "assert: corrupt xref struct"); } - - return fz_okay; } -fz_error -pdf_load_object(fz_obj **objp, pdf_xref *xref, int num, int gen) +fz_obj * +pdf_load_object(pdf_xref *xref, int num, int gen) { - fz_error error; + fz_context *ctx = xref->ctx; - error = pdf_cache_object(xref, num, gen); - if (error) - return fz_error_note(error, "cannot load object (%d %d R) into cache", num, gen); + fz_try(ctx) + { + pdf_cache_object(xref, num, gen); + } + fz_catch(ctx) + { + fz_throw(ctx, "cannot load object (%d %d R) into cache", num, gen); + } assert(xref->table[num].obj); - *objp = fz_keep_obj(xref->table[num].obj); - - return fz_okay; + return fz_keep_obj(xref->table[num].obj); } fz_obj * @@ -883,14 +832,18 @@ pdf_resolve_indirect(fz_obj *ref) if (fz_is_indirect(ref)) { pdf_xref *xref = fz_get_indirect_xref(ref); + fz_context *ctx = xref->ctx; int num = fz_to_num(ref); int gen = fz_to_gen(ref); if (xref) { - fz_error error = pdf_cache_object(xref, num, gen); - if (error) + fz_try(ctx) + { + pdf_cache_object(xref, num, gen); + } + fz_catch(ctx) { - fz_error_handle(error, "cannot load object (%d %d R) into cache", num, gen); + fz_warn(ctx, "cannot load object (%d %d R) into cache", num, gen); return ref; } if (xref->table[num].obj) @@ -926,20 +879,24 @@ pdf_update_object(pdf_xref *xref, int num, int gen, fz_obj *newobj) * Convenience function to open a file then call pdf_open_xref_with_stream. */ -fz_error -pdf_open_xref(fz_context *ctx, pdf_xref **xrefp, const char *filename, char *password) +pdf_xref * +pdf_open_xref(fz_context *ctx, const char *filename, char *password) { - fz_error error; - fz_stream *file; - - file = fz_open_file(ctx, filename); - if (!file) - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_stream *file = NULL; + pdf_xref *xref; - error = pdf_open_xref_with_stream(xrefp, file, password); - if (error) - return fz_error_note(error, "cannot load document '%s'", filename); + //fz_var(file); + fz_try(ctx) + { + file = fz_open_file(ctx, filename); + xref = pdf_open_xref_with_stream(file, password); + } + fz_catch(ctx) + { + fz_close(file); + fz_throw(ctx, "cannot load document '%s'", filename); + } fz_close(file); - return fz_okay; + return xref; } diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c index b245fd48..7f031b5f 100644 --- a/scripts/cmapdump.c +++ b/scripts/cmapdump.c @@ -89,8 +89,11 @@ main(int argc, char **argv) if (!fi) fz_error_make("cmapdump: could not open input file '%s'\n", argv[i]); - error = pdf_parse_cmap(&cmap, fi); - if (error) + fz_try(ctx) + { + cmap = pdf_parse_cmap(fi); + } + fz_catch(ctx) { fz_error_handle(error, "cmapdump: could not parse input cmap '%s'\n", argv[i]); return 1; diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index 1730c7ec..3abe1fa2 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -551,6 +551,10 @@ Name="xps" > <File + RelativePath="..\xps\muxps.h" + > + </File> + <File RelativePath="..\xps\xps_common.c" > </File> diff --git a/xps/muxps.h b/xps/muxps.h index 36635331..48ad2ae0 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -91,16 +91,16 @@ void xps_debug_page_list(xps_document *doc); void xps_free_page_list(xps_document *doc); int xps_count_pages(xps_document *doc); -int xps_load_page(xps_page **page, xps_document *doc, int number); +xps_page *xps_load_page(xps_document *doc, int number); void xps_free_page(xps_document *doc, xps_page *page); /* * Images, fonts, and colorspaces. */ -int xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen); -int xps_decode_png(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen); -int xps_decode_tiff(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen); +fz_pixmap *xps_decode_jpeg(fz_context *doc, byte *rbuf, int rlen); +fz_pixmap *xps_decode_png(fz_context *doc, byte *rbuf, int rlen); +fz_pixmap *xps_decode_tiff(fz_context *doc, byte *rbuf, int rlen); typedef struct xps_font_cache_s xps_font_cache; @@ -227,8 +227,8 @@ struct xps_document_s fz_device *dev; }; -int xps_open_file(fz_context *doc, xps_document **ctxp, char *filename); -int xps_open_stream(xps_document **ctxp, fz_stream *file); +xps_document *xps_open_file(fz_context *ctx, char *filename); +xps_document *xps_open_stream(fz_stream *file); void xps_free_context(xps_document *doc); #endif diff --git a/xps/xps_doc.c b/xps/xps_doc.c index 378006e3..dca1868c 100644 --- a/xps/xps_doc.c +++ b/xps/xps_doc.c @@ -305,11 +305,10 @@ xps_load_fixed_page(xps_document *doc, xps_page *page) return 0; } -int -xps_load_page(xps_page **pagep, xps_document *doc, int number) +xps_page * +xps_load_page(xps_document *doc, int number) { xps_page *page; - int code; int n = 0; for (page = doc->first_page; page; page = page->next) @@ -318,17 +317,16 @@ xps_load_page(xps_page **pagep, xps_document *doc, int number) { if (!page->root) { - code = xps_load_fixed_page(doc, page); - if (code) - return fz_error_note(code, "cannot load page %d", number + 1); + xps_load_fixed_page(doc, page); + /* RJW: "cannot load page %d", number + 1 */ } - *pagep = page; - return fz_okay; + return page; } n ++; } - return fz_error_make("cannot find page %d", number + 1); + fz_throw(doc->ctx, "cannot find page %d", number + 1); + return NULL; /* Stupid MSVC */ } void diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c index bcab9b39..56e6e4c6 100644 --- a/xps/xps_glyphs.c +++ b/xps/xps_glyphs.c @@ -369,7 +369,6 @@ xps_parse_glyphs(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *root) { xml_element *node; - int code; char *fill_uri; char *opacity_mask_uri; @@ -496,9 +495,13 @@ xps_parse_glyphs(xps_document *doc, fz_matrix ctm, if (strstr(part->name, ".ODTTF")) xps_deobfuscate_font_resource(doc, part); - code = fz_new_font_from_memory(doc->ctx, &font, part->data, part->size, subfontid); - if (code) { - fz_error_handle(code, "cannot load font resource '%s'", partname); + fz_try(doc->ctx) + { + font = fz_new_font_from_memory(doc->ctx, part->data, part->size, subfontid); + } + fz_catch(doc->ctx) + { + fz_error_handle(1, "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 dfe0dd91..129637d9 100644 --- a/xps/xps_image.c +++ b/xps/xps_image.c @@ -1,40 +1,37 @@ #include "fitz.h" #include "muxps.h" -static int -xps_decode_image(fz_context *doc, fz_pixmap **imagep, byte *buf, int len) +static fz_pixmap * +xps_decode_image(fz_context *ctx, byte *buf, int len) { - int error; + fz_pixmap *image; if (len < 8) - return fz_error_make("unknown image file format"); + fz_throw(ctx, "unknown image file format"); if (buf[0] == 0xff && buf[1] == 0xd8) { - error = xps_decode_jpeg(doc, imagep, buf, len); - if (error) - return fz_error_note(error, "cannot decode jpeg image"); + image = xps_decode_jpeg(ctx, buf, len); + /* RJW: "cannot decode jpeg image" */ } else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0) { - error = xps_decode_png(doc, imagep, buf, len); - if (error) - return fz_error_note(error, "cannot decode png image"); + image = xps_decode_png(ctx, buf, len); + /* RJW: "cannot decode png image" */ } else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC) { - return fz_error_make("JPEG-XR codec is not available"); + fz_throw(ctx, "JPEG-XR codec is not available"); } else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0) { - error = xps_decode_tiff(doc, imagep, buf, len); - if (error) - return fz_error_note(error, "cannot decode TIFF image"); + image = xps_decode_tiff(ctx, buf, len); + /* RJW: "cannot decode TIFF image" */ } else - return fz_error_make("unknown image file format"); + fz_throw(ctx, "unknown image file format"); - return fz_okay; + return image; } static void @@ -106,7 +103,6 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, { xps_part *part; fz_pixmap *image; - int code; part = xps_find_image_brush_source_part(doc, base_uri, root); if (!part) { @@ -114,8 +110,12 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, return; } - code = xps_decode_image(doc->ctx, &image, part->data, part->size); - if (code < 0) { + fz_try(doc->ctx) + { + image = xps_decode_image(doc->ctx, part->data, part->size); + } + fz_catch(doc->ctx) + { xps_free_part(doc, part); fz_error_handle(-1, "cannot decode image resource"); return; diff --git a/xps/xps_jpeg.c b/xps/xps_jpeg.c index e96bcd8c..381baffd 100644 --- a/xps/xps_jpeg.c +++ b/xps/xps_jpeg.c @@ -47,8 +47,8 @@ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) } } -int -xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen) +fz_pixmap * +xps_decode_jpeg(fz_context *ctx, byte *rbuf, int rlen) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr_jmp err; @@ -63,8 +63,8 @@ xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen) if (setjmp(err.env)) { if (image) - fz_drop_pixmap(doc, image); - return fz_error_make("jpeg error: %s", err.msg); + fz_drop_pixmap(ctx, image); + fz_throw(ctx, "jpeg error: %s", err.msg); } cinfo.err = jpeg_std_error(&err.super); @@ -92,14 +92,14 @@ xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen) else if (cinfo.output_components == 4) colorspace = fz_device_cmyk; else - return fz_error_make("bad number of components in jpeg: %d", cinfo.output_components); + fz_throw(ctx, "bad number of components in jpeg: %d", cinfo.output_components); - image = fz_new_pixmap_with_limit(doc, colorspace, cinfo.output_width, cinfo.output_height); + image = fz_new_pixmap_with_limit(ctx, colorspace, cinfo.output_width, cinfo.output_height); if (!image) { jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - return fz_error_make("out of memory"); + fz_throw(ctx, "out of memory"); } if (cinfo.density_unit == 1) @@ -115,7 +115,7 @@ xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen) fz_clear_pixmap(image); - row[0] = fz_malloc(doc, cinfo.output_components * cinfo.output_width); + row[0] = fz_malloc(ctx, cinfo.output_components * cinfo.output_width); dp = image->samples; while (cinfo.output_scanline < cinfo.output_height) { @@ -128,11 +128,10 @@ xps_decode_jpeg(fz_context *doc, fz_pixmap **imagep, byte *rbuf, int rlen) *dp++ = 255; } } - fz_free(doc, row[0]); + fz_free(ctx, row[0]); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - *imagep = image; - return fz_okay; + return image; } diff --git a/xps/xps_png.c b/xps/xps_png.c index 203f9676..d9e952a7 100644 --- a/xps/xps_png.c +++ b/xps/xps_png.c @@ -5,7 +5,7 @@ struct info { - fz_context *doc; + fz_context *ctx; int width, height, depth, n; int interlace, indexed; int size; @@ -189,7 +189,7 @@ png_deinterlace(struct info *info, int *passw, int *passh, int *passofs) unsigned char *output; int p, x, y, k; - output = fz_malloc_array(info->doc, info->height, stride); + output = fz_malloc_array(info->ctx, info->height, stride); for (p = 0; p < 7; p++) { @@ -215,7 +215,7 @@ png_deinterlace(struct info *info, int *passw, int *passh, int *passofs) } } - fz_free(info->doc, info->samples); + fz_free(info->ctx, info->samples); info->samples = output; } @@ -409,11 +409,11 @@ png_read_image(struct info *info, unsigned char *p, int total) info->size = passofs[7]; } - info->samples = fz_malloc(info->doc, info->size); + info->samples = fz_malloc(info->ctx, info->size); stm.zalloc = zalloc; stm.zfree = zfree; - stm.opaque = info->doc; + stm.opaque = info->ctx; stm.next_out = info->samples; stm.avail_out = info->size; @@ -481,9 +481,9 @@ png_read_image(struct info *info, unsigned char *p, int total) } static fz_pixmap * -png_expand_palette(fz_context *doc, struct info *info, fz_pixmap *src) +png_expand_palette(fz_context *ctx, struct info *info, fz_pixmap *src) { - fz_pixmap *dst = fz_new_pixmap(doc, fz_device_rgb, src->w, src->h); + fz_pixmap *dst = fz_new_pixmap(ctx, fz_device_rgb, src->w, src->h); unsigned char *sp = src->samples; unsigned char *dp = dst->samples; int x, y; @@ -504,7 +504,7 @@ png_expand_palette(fz_context *doc, struct info *info, fz_pixmap *src) } } - fz_drop_pixmap(info->doc, src); + fz_drop_pixmap(info->ctx, src); return dst; } @@ -532,19 +532,23 @@ png_mask_transparency(struct info *info, fz_pixmap *dst) } } -int -xps_decode_png(fz_context *doc, fz_pixmap **imagep, byte *p, int total) +fz_pixmap * +xps_decode_png(fz_context *ctx, byte *p, int total) { fz_pixmap *image; fz_colorspace *colorspace; struct info png; - int code; int stride; - png.doc = doc; - code = png_read_image(&png, p, total); - if (code) - return fz_error_note(code, "cannot read png image"); + png.ctx = ctx; + fz_try(ctx) + { + png_read_image(&png, p, total); + } + fz_catch(ctx) + { + fz_throw(ctx, "cannot read png image"); + } if (png.n == 3 || png.n == 4) colorspace = fz_device_rgb; @@ -553,11 +557,11 @@ xps_decode_png(fz_context *doc, fz_pixmap **imagep, byte *p, int total) stride = (png.width * png.n * png.depth + 7) / 8; - image = fz_new_pixmap_with_limit(doc, colorspace, png.width, png.height); + image = fz_new_pixmap_with_limit(ctx, colorspace, png.width, png.height); if (!image) { - fz_free(png.doc, png.samples); - return fz_error_make("out of memory"); + fz_free(png.ctx, png.samples); + fz_throw(ctx, "out of memory"); } image->xres = png.xres; @@ -566,15 +570,14 @@ xps_decode_png(fz_context *doc, fz_pixmap **imagep, byte *p, int total) fz_unpack_tile(image, png.samples, png.n, png.depth, stride, png.indexed); if (png.indexed) - image = png_expand_palette(doc, &png, image); + image = png_expand_palette(ctx, &png, image); else if (png.transparency) png_mask_transparency(&png, image); if (png.transparency || png.n == 2 || png.n == 4) fz_premultiply_pixmap(image); - fz_free(png.doc, png.samples); + fz_free(png.ctx, png.samples); - *imagep = image; - return fz_okay; + return image; } diff --git a/xps/xps_tiff.c b/xps/xps_tiff.c index 7496cb56..b9571465 100644 --- a/xps/xps_tiff.c +++ b/xps/xps_tiff.c @@ -56,7 +56,7 @@ struct tiff fz_colorspace *colorspace; byte *samples; int stride; - fz_context *doc; + fz_context *ctx; }; enum @@ -183,15 +183,15 @@ xps_decode_tiff_fax(struct tiff *tiff, int comp, fz_stream *chain, byte *wp, int fz_obj *params; fz_obj *columns, *rows, *black_is_1, *k, *encoded_byte_align; int n; - fz_context *doc = tiff->doc; + fz_context *ctx = tiff->ctx; - columns = fz_new_int(doc, tiff->imagewidth); - rows = fz_new_int(doc, tiff->imagelength); - black_is_1 = fz_new_bool(doc, tiff->photometric == 0); - k = fz_new_int(doc, comp == 4 ? -1 : 0); - encoded_byte_align = fz_new_bool(doc, comp == 2); + columns = fz_new_int(ctx, tiff->imagewidth); + rows = fz_new_int(ctx, tiff->imagelength); + black_is_1 = fz_new_bool(ctx, tiff->photometric == 0); + k = fz_new_int(ctx, comp == 4 ? -1 : 0); + encoded_byte_align = fz_new_bool(ctx, comp == 2); - params = fz_new_dict(doc, 5); + params = fz_new_dict(ctx, 5); fz_dict_puts(params, "Columns", columns); fz_dict_puts(params, "Rows", rows); fz_dict_puts(params, "BlackIs1", black_is_1); @@ -320,7 +320,7 @@ xps_expand_tiff_colormap(struct tiff *tiff) stride = tiff->imagewidth * (tiff->samplesperpixel + 2); - samples = fz_malloc(tiff->doc, stride * tiff->imagelength); + samples = fz_malloc(tiff->ctx, stride * tiff->imagelength); for (y = 0; y < tiff->imagelength; y++) { @@ -430,7 +430,7 @@ xps_decode_tiff_strips(struct tiff *tiff) tiff->yresolution = 96; } - tiff->samples = fz_malloc_array(tiff->doc, tiff->imagelength, tiff->stride); + tiff->samples = fz_malloc_array(tiff->ctx, tiff->imagelength, tiff->stride); memset(tiff->samples, 0x55, tiff->imagelength * tiff->stride); wp = tiff->samples; @@ -454,7 +454,7 @@ xps_decode_tiff_strips(struct tiff *tiff) rp[i] = bitrev[rp[i]]; /* the strip decoders will close this */ - stm = fz_open_memory(tiff->doc, rp, rlen); + stm = fz_open_memory(tiff->ctx, rp, rlen); switch (tiff->compression) { @@ -675,7 +675,7 @@ xps_read_tiff_tag(struct tiff *tiff, unsigned offset) break; case ICCProfile: - tiff->profile = fz_malloc(tiff->doc, count); + tiff->profile = fz_malloc(tiff->ctx, count); /* ICC profile data type is set to UNDEFINED. * TBYTE reading not correct in xps_read_tiff_tag_value */ xps_read_tiff_bytes(tiff->profile, tiff, value, count); @@ -683,23 +683,23 @@ xps_read_tiff_tag(struct tiff *tiff, unsigned offset) break; case JPEGTables: - fz_warn(tiff->doc, "jpeg tables in tiff not implemented"); + fz_warn(tiff->ctx, "jpeg tables in tiff not implemented"); tiff->jpegtables = tiff->bp + value; tiff->jpegtableslen = count; break; case StripOffsets: - tiff->stripoffsets = fz_malloc_array(tiff->doc, count, sizeof(unsigned)); + tiff->stripoffsets = fz_malloc_array(tiff->ctx, count, sizeof(unsigned)); xps_read_tiff_tag_value(tiff->stripoffsets, tiff, type, value, count); break; case StripByteCounts: - tiff->stripbytecounts = fz_malloc_array(tiff->doc, count, sizeof(unsigned)); + tiff->stripbytecounts = fz_malloc_array(tiff->ctx, count, sizeof(unsigned)); xps_read_tiff_tag_value(tiff->stripbytecounts, tiff, type, value, count); break; case ColorMap: - tiff->colormap = fz_malloc_array(tiff->doc, count, sizeof(unsigned)); + tiff->colormap = fz_malloc_array(tiff->ctx, count, sizeof(unsigned)); xps_read_tiff_tag_value(tiff->colormap, tiff, type, value, count); break; @@ -795,26 +795,23 @@ xps_decode_tiff_header(struct tiff *tiff, byte *buf, int len) return fz_okay; } -int -xps_decode_tiff(fz_context *doc, fz_pixmap **imagep, byte *buf, int len) +fz_pixmap * +xps_decode_tiff(fz_context *ctx, byte *buf, int len) { - int error; fz_pixmap *image; struct tiff tiff; - tiff.doc = doc; - error = xps_decode_tiff_header(&tiff, buf, len); - if (error) - return fz_error_note(error, "cannot decode tiff header"); + tiff.ctx = ctx; + xps_decode_tiff_header(&tiff, buf, len); + /* RJW: "cannot decode tiff header" */ /* Decode the image strips */ if (tiff.rowsperstrip > tiff.imagelength) tiff.rowsperstrip = tiff.imagelength; - error = xps_decode_tiff_strips(&tiff); - if (error) - return fz_error_note(error, "cannot decode image data"); + xps_decode_tiff_strips(&tiff); + /* RJW: "cannot decode image data" */ /* Byte swap 16-bit images to big endian if necessary */ if (tiff.bitspersample == 16) @@ -825,14 +822,14 @@ xps_decode_tiff(fz_context *doc, fz_pixmap **imagep, byte *buf, int len) /* Expand into fz_pixmap struct */ - image = fz_new_pixmap_with_limit(tiff.doc, tiff.colorspace, tiff.imagewidth, tiff.imagelength); + image = fz_new_pixmap_with_limit(tiff.ctx, tiff.colorspace, tiff.imagewidth, tiff.imagelength); if (!image) { - if (tiff.colormap) fz_free(doc, tiff.colormap); - if (tiff.stripoffsets) fz_free(doc, tiff.stripoffsets); - if (tiff.stripbytecounts) fz_free(doc, tiff.stripbytecounts); - if (tiff.samples) fz_free(doc, tiff.samples); - return fz_error_make("out of memory"); + if (tiff.colormap) fz_free(ctx, tiff.colormap); + if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets); + if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts); + if (tiff.samples) fz_free(ctx, tiff.samples); + fz_throw(ctx, "out of memory"); } image->xres = tiff.xresolution; @@ -846,11 +843,11 @@ xps_decode_tiff(fz_context *doc, fz_pixmap **imagep, byte *buf, int len) /* CMYK is a subtractive colorspace, we want additive for premul alpha */ if (image->n == 5) { - fz_pixmap *rgb = fz_new_pixmap(tiff.doc, fz_device_rgb, image->w, image->h); - fz_convert_pixmap(tiff.doc, image, rgb); + fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h); + fz_convert_pixmap(tiff.ctx, image, rgb); rgb->xres = image->xres; rgb->yres = image->yres; - fz_drop_pixmap(doc, image); + fz_drop_pixmap(ctx, image); image = rgb; } fz_premultiply_pixmap(image); @@ -858,11 +855,10 @@ xps_decode_tiff(fz_context *doc, fz_pixmap **imagep, byte *buf, int len) /* Clean up scratch memory */ - if (tiff.colormap) fz_free(doc, tiff.colormap); - if (tiff.stripoffsets) fz_free(doc, tiff.stripoffsets); - if (tiff.stripbytecounts) fz_free(doc, tiff.stripbytecounts); - if (tiff.samples) fz_free(doc, tiff.samples); + if (tiff.colormap) fz_free(ctx, tiff.colormap); + if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets); + if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts); + if (tiff.samples) fz_free(ctx, tiff.samples); - *imagep = image; - return fz_okay; + return image; } diff --git a/xps/xps_zip.c b/xps/xps_zip.c index 954a8a00..f02bf33e 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -389,66 +389,72 @@ xps_read_part(xps_document *doc, char *partname) return xps_read_zip_part(doc, partname); } -static int -xps_open_directory(fz_context *fctx, xps_document **ctxp, char *directory) +static xps_document * +xps_open_directory(fz_context *ctx, char *directory) { xps_document *doc; - int code; - doc = fz_malloc(fctx, sizeof(xps_document)); + doc = fz_malloc(ctx, sizeof(xps_document)); memset(doc, 0, sizeof *doc); - doc->directory = fz_strdup(fctx, directory); - doc->ctx = fctx; + doc->directory = fz_strdup(ctx, directory); + doc->ctx = ctx; - code = xps_read_page_list(doc); - if (code) + fz_try(ctx) + { + xps_read_page_list(doc); + } + fz_catch(ctx) { xps_free_context(doc); - return fz_error_note(code, "cannot read page list"); + fz_throw(ctx, "cannot read page list"); } - *ctxp = doc; - return fz_okay; + return doc; } -int -xps_open_stream(xps_document **ctxp, fz_stream *file) +xps_document * +xps_open_stream(fz_stream *file) { xps_document *doc; - int code; + fz_context *ctx = file->ctx; - doc = fz_malloc(file->ctx, sizeof(xps_document)); + doc = fz_malloc(ctx, sizeof(xps_document)); memset(doc, 0, sizeof *doc); - doc->ctx = file->ctx; + doc->ctx = ctx; doc->file = fz_keep_stream(file); - code = xps_find_and_read_zip_dir(doc); - if (code < 0) + fz_try(ctx) + { + xps_find_and_read_zip_dir(doc); + } + fz_catch(ctx) { xps_free_context(doc); - return fz_error_note(code, "cannot read zip central directory"); + fz_throw(ctx, "cannot read zip central directory"); } - code = xps_read_page_list(doc); - if (code) + fz_try(ctx) + { + xps_read_page_list(doc); + } + fz_catch(ctx) { xps_free_context(doc); - return fz_error_note(code, "cannot read page list"); + fz_throw(ctx, "cannot read page list"); } - *ctxp = doc; - return fz_okay; + return doc; } -int -xps_open_file(fz_context *doc, xps_document **ctxp, char *filename) +xps_document * +xps_open_file(fz_context *ctx, char *filename) { char buf[2048]; fz_stream *file; char *p; - int code; + xps_document *doc; if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels")) { @@ -457,18 +463,24 @@ xps_open_file(fz_context *doc, xps_document **ctxp, char *filename) if (!p) p = strstr(buf, "\\_rels\\.rels"); *p = 0; - return xps_open_directory(doc, ctxp, buf); + return xps_open_directory(ctx, buf); } - file = fz_open_file(doc, filename); + file = fz_open_file(ctx, filename); if (!file) - return fz_error_make("cannot open file '%s': %s", filename, strerror(errno)); + fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); - code = xps_open_stream(ctxp, file); + fz_try(ctx) + { + doc = xps_open_stream(file); + } + fz_catch(ctx) + { + fz_close(file); + fz_throw(ctx, "cannot load document '%s'", filename); + } fz_close(file); - if (code) - return fz_error_note(code, "cannot load document '%s'", filename); - return fz_okay; + return doc; } void |