diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-08-03 16:43:19 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-10-24 15:16:35 +0100 |
commit | c74080fc0f2016426d5401ca2eb497268400cb7f (patch) | |
tree | 43081a9d3b77bb7392a17e7f8470c86730841749 /source | |
parent | cdf1bf6dcac8fec399355f21772bd89785ef8599 (diff) | |
download | mupdf-c74080fc0f2016426d5401ca2eb497268400cb7f.tar.xz |
Look for changes to Default colorspaces in XObjects.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/colorspace.c | 12 | ||||
-rw-r--r-- | source/fitz/font-imp.h | 2 | ||||
-rw-r--r-- | source/fitz/font.c | 6 | ||||
-rw-r--r-- | source/pdf/pdf-op-run.c | 38 | ||||
-rw-r--r-- | source/pdf/pdf-page.c | 114 | ||||
-rw-r--r-- | source/pdf/pdf-run.c | 16 | ||||
-rw-r--r-- | source/pdf/pdf-type3.c | 4 |
7 files changed, 136 insertions, 56 deletions
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index 9d5c93ab..da4a4f29 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -3872,6 +3872,18 @@ fz_new_default_colorspaces(fz_context *ctx) } fz_default_colorspaces * +fz_clone_default_colorspaces(fz_context *ctx, fz_default_colorspaces *base) +{ + fz_default_colorspaces *default_cs = fz_malloc_struct(ctx, fz_default_colorspaces); + default_cs->refs = 1; + default_cs->gray = fz_keep_colorspace(ctx, base->gray); + default_cs->rgb = fz_keep_colorspace(ctx, base->rgb); + default_cs->cmyk = fz_keep_colorspace(ctx, base->cmyk); + default_cs->oi = fz_keep_colorspace(ctx, base->oi); + return default_cs; +} + +fz_default_colorspaces * fz_keep_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs) { return fz_keep_imp(ctx, default_cs, &default_cs->refs); diff --git a/source/fitz/font-imp.h b/source/fitz/font-imp.h index 59ae628e..74a25ccf 100644 --- a/source/fitz/font-imp.h +++ b/source/fitz/font-imp.h @@ -19,7 +19,7 @@ struct fz_font_s float *t3widths; /* has 256 entries if used */ unsigned short *t3flags; /* has 256 entries if used */ void *t3doc; /* a pdf_document for the callback */ - void (*t3run)(fz_context *ctx, void *doc, void *resources, fz_buffer *contents, struct fz_device_s *dev, const fz_matrix *ctm, void *gstate, int nestedDepth); + void (*t3run)(fz_context *ctx, void *doc, void *resources, fz_buffer *contents, struct fz_device_s *dev, const fz_matrix *ctm, void *gstate, int nested_depth, fz_default_colorspaces *default_cs); void (*t3freeres)(fz_context *ctx, void *doc, void *resources); fz_rect bbox; /* font bbox is used only for t3 fonts */ diff --git a/source/fitz/font.c b/source/fitz/font.c index 780d6c83..58a42314 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -1276,7 +1276,7 @@ fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nested_depth) FZ_DEVFLAG_LINEWIDTH_UNDEFINED; fz_try(ctx) { - font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, &fz_identity, NULL, 0); + font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, &fz_identity, NULL, 0, NULL); fz_close_device(ctx, dev); font->t3flags[gid] = dev->flags; d1_rect = dev->d1_rect; @@ -1418,7 +1418,7 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm } void -fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, const fz_matrix *trm, void *gstate, int nested_depth) +fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, const fz_matrix *trm, void *gstate, int nested_depth, fz_default_colorspaces *def_cs) { fz_matrix ctm; void *contents; @@ -1444,7 +1444,7 @@ fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gi } fz_concat(&ctm, &font->t3matrix, trm); - font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, &ctm, gstate, nested_depth); + font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, &ctm, gstate, nested_depth, def_cs); } fz_rect * diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index 324ee32d..2b9b134c 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -77,6 +77,8 @@ struct pdf_run_processor_s pdf_processor super; fz_device *dev; + fz_default_colorspaces *default_cs; + int nested_depth; /* path object state */ @@ -948,7 +950,7 @@ pdf_show_char(fz_context *ctx, pdf_run_processor *pr, int cid) * attributes, or type 3 glyphs within type3 glyphs). */ fz_matrix composed; fz_concat(&composed, &trm, &gstate->ctm); - fz_render_t3_glyph_direct(ctx, pr->dev, fontdesc->font, gid, &composed, gstate, pr->nested_depth); + fz_render_t3_glyph_direct(ctx, pr->dev, fontdesc->font, gid, &composed, gstate, pr->nested_depth, pr->default_cs); /* Render text invisibly so that it can still be extracted. */ pr->text_mode = 3; } @@ -1221,6 +1223,7 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf int transparency = 0; pdf_document *doc; fz_colorspace *cs = NULL; + fz_default_colorspaces *saved_def_cs = NULL; /* Avoid infinite recursion */ if (xobj == NULL || pdf_mark_obj(ctx, xobj->obj)) @@ -1231,6 +1234,7 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf fz_var(oldtop); fz_var(oldbot); fz_var(cs); + fz_var(saved_def_cs); gparent_save = pr->gparent; pr->gparent = pr->gtop; @@ -1304,6 +1308,13 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf if (!resources) resources = page_resources; + saved_def_cs = pr->default_cs; + pr->default_cs = NULL; + pr->default_cs = pdf_update_default_colorspaces(ctx, saved_def_cs, resources); + + if (pr->default_cs != saved_def_cs) + fz_set_default_colorspaces(ctx, pr->dev, pr->default_cs); + doc = pdf_get_bound_document(ctx, xobj->obj); oldbot = pr->gbot; @@ -1315,6 +1326,21 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf { fz_drop_colorspace(ctx, cs); + if (saved_def_cs) + { + fz_drop_default_colorspaces(ctx, pr->default_cs); + pr->default_cs = saved_def_cs; + fz_try(ctx) + { + fz_set_default_colorspaces(ctx, pr->dev, pr->default_cs); + } + fz_catch(ctx) + { + /* Postpone the problem */ + strcpy(errmess, fz_caught_message(ctx)); + } + } + /* Undo any gstate mismatches due to the pdf_process_contents call */ if (oldbot != -1) { @@ -1340,6 +1366,8 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf fz_catch(ctx) { /* Postpone the problem */ + if (errmess[0]) + fz_warn(ctx, errmess); strcpy(errmess, fz_caught_message(ctx)); } } @@ -1352,6 +1380,8 @@ pdf_run_xobject(fz_context *ctx, pdf_run_processor *proc, pdf_xobject *xobj, pdf fz_catch(ctx) { /* Postpone the problem */ + if (errmess[0]) + fz_warn(ctx, errmess); strcpy(errmess, fz_caught_message(ctx)); } } @@ -2059,11 +2089,13 @@ pdf_drop_run_processor(fz_context *ctx, pdf_processor *proc) fz_drop_path(ctx, pr->path); fz_drop_text(ctx, pr->text); + fz_drop_default_colorspaces(ctx, pr->default_cs); + fz_free(ctx, pr->gstate); } pdf_processor * -pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, const char *usage, pdf_gstate *gstate, int nested) +pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, const char *usage, pdf_gstate *gstate, int nested, fz_default_colorspaces *default_cs) { pdf_run_processor *proc = pdf_new_processor(ctx, sizeof *proc); { @@ -2195,6 +2227,8 @@ pdf_new_run_processor(fz_context *ctx, fz_device *dev, const fz_matrix *ctm, con proc->dev = dev; + proc->default_cs = fz_keep_default_colorspaces(ctx, default_cs); + proc->nested_depth = nested; proc->path = NULL; diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c index 90f77f1e..5d426455 100644 --- a/source/pdf/pdf-page.c +++ b/source/pdf/pdf-page.c @@ -867,12 +867,66 @@ pdf_new_page(fz_context *ctx, pdf_document *doc) return page; } +static void +pdf_load_default_colorspaces_imp(fz_context *ctx, fz_default_colorspaces *default_cs, pdf_obj *obj) +{ + pdf_obj *cs_obj; + + /* The spec says to ignore any colors we can't understand */ + fz_try(ctx) + { + cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultGray); + if (cs_obj) + { + fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); + fz_set_default_gray(ctx, default_cs, cs); + fz_drop_colorspace(ctx, cs); + } + } + fz_catch(ctx) + { + if (fz_caught(ctx) != FZ_ERROR_TRYLATER) + fz_warn(ctx, "Error while reading DefaultGray: %s", fz_caught_message(ctx)); + } + + fz_try(ctx) + { + cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultRGB); + if (cs_obj) + { + fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); + fz_set_default_rgb(ctx, default_cs, cs); + fz_drop_colorspace(ctx, cs); + } + } + fz_catch(ctx) + { + if (fz_caught(ctx) != FZ_ERROR_TRYLATER) + fz_warn(ctx, "Error while reading DefaultRGB: %s", fz_caught_message(ctx)); + } + + fz_try(ctx) + { + cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultCMYK); + if (cs_obj) + { + fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); + fz_set_default_cmyk(ctx, default_cs, cs); + fz_drop_colorspace(ctx, cs); + } + } + fz_catch(ctx) + { + if (fz_caught(ctx) != FZ_ERROR_TRYLATER) + fz_warn(ctx, "Error while reading DefaultCMYK: %s", fz_caught_message(ctx)); + } +} + fz_default_colorspaces * pdf_load_default_colorspaces(fz_context *ctx, pdf_document *doc, pdf_page *page) { pdf_obj *res; pdf_obj *obj; - pdf_obj *cs_obj; fz_default_colorspaces *default_cs; fz_colorspace *oi; @@ -885,47 +939,7 @@ pdf_load_default_colorspaces(fz_context *ctx, pdf_document *doc, pdf_page *page) res = pdf_page_resources(ctx, page); obj = pdf_dict_get(ctx, res, PDF_NAME_ColorSpace); if (obj) - { - /* The spec says to ignore any colors we can't understand */ - fz_try(ctx) - { - cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultGray); - if (cs_obj) - { - fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); - fz_set_default_gray(ctx, default_cs, cs); - fz_drop_colorspace(ctx, cs); - } - } - fz_catch(ctx) - {} - - fz_try(ctx) - { - cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultRGB); - if (cs_obj) - { - fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); - fz_set_default_rgb(ctx, default_cs, cs); - fz_drop_colorspace(ctx, cs); - } - } - fz_catch(ctx) - {} - - fz_try(ctx) - { - cs_obj = pdf_dict_get(ctx, obj, PDF_NAME_DefaultCMYK); - if (cs_obj) - { - fz_colorspace *cs = pdf_load_colorspace(ctx, cs_obj); - fz_set_default_cmyk(ctx, default_cs, cs); - fz_drop_colorspace(ctx, cs); - } - } - fz_catch(ctx) - {} - } + pdf_load_default_colorspaces_imp(ctx, default_cs, obj); oi = pdf_document_output_intent(ctx, doc); if (oi) @@ -934,6 +948,22 @@ pdf_load_default_colorspaces(fz_context *ctx, pdf_document *doc, pdf_page *page) return default_cs; } +fz_default_colorspaces * +pdf_update_default_colorspaces(fz_context *ctx, fz_default_colorspaces *old_cs, pdf_obj *res) +{ + pdf_obj *obj; + fz_default_colorspaces *new_cs; + + obj = pdf_dict_get(ctx, res, PDF_NAME_ColorSpace); + if (!obj) + return fz_keep_default_colorspaces(ctx, old_cs); + + new_cs = fz_clone_default_colorspaces(ctx, old_cs); + pdf_load_default_colorspaces_imp(ctx, new_cs, obj); + + return new_cs; +} + pdf_page * pdf_load_page(fz_context *ctx, pdf_document *doc, int number) { diff --git a/source/pdf/pdf-run.c b/source/pdf/pdf-run.c index b1de0342..1436e93a 100644 --- a/source/pdf/pdf-run.c +++ b/source/pdf/pdf-run.c @@ -6,25 +6,29 @@ pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf { fz_matrix local_ctm, page_ctm; fz_rect mediabox; - pdf_processor *proc; + pdf_processor *proc = NULL; fz_default_colorspaces *default_cs; + fz_var(proc); + default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); - fz_drop_default_colorspaces(ctx, default_cs); pdf_page_transform(ctx, page, &mediabox, &page_ctm); fz_concat(&local_ctm, &page_ctm, ctm); - proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); fz_try(ctx) { + proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0, default_cs); pdf_process_annot(ctx, proc, doc, page, annot, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) + { pdf_drop_processor(ctx, proc); + fz_drop_default_colorspaces(ctx, default_cs); + } fz_catch(ctx) fz_rethrow(ctx); } @@ -76,7 +80,7 @@ pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *p fz_drop_colorspace(ctx, colorspace); } - proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); + proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0, default_cs); pdf_process_contents(ctx, proc, doc, resources, contents, cookie); pdf_close_processor(ctx, proc); } @@ -204,14 +208,14 @@ pdf_run_page(fz_context *ctx, pdf_page *page, fz_device *dev, const fz_matrix *c } void -pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth) +pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth, fz_default_colorspaces *default_cs) { pdf_processor *proc; if (nested_depth > 10) fz_throw(ctx, FZ_ERROR_GENERIC, "Too many nestings of Type3 glyphs"); - proc = pdf_new_run_processor(ctx, dev, ctm, "View", gstate, nested_depth+1); + proc = pdf_new_run_processor(ctx, dev, ctm, "View", gstate, nested_depth+1, default_cs); fz_try(ctx) { pdf_process_glyph(ctx, proc, doc, resources, contents); diff --git a/source/pdf/pdf-type3.c b/source/pdf/pdf-type3.c index 074e3c36..f82bb2f0 100644 --- a/source/pdf/pdf-type3.c +++ b/source/pdf/pdf-type3.c @@ -4,9 +4,9 @@ #include "../fitz/font-imp.h" static void -pdf_run_glyph_func(fz_context *ctx, void *doc, void *rdb, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth) +pdf_run_glyph_func(fz_context *ctx, void *doc, void *rdb, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth, fz_default_colorspaces *default_cs) { - pdf_run_glyph(ctx, doc, (pdf_obj *)rdb, contents, dev, ctm, gstate, nested_depth); + pdf_run_glyph(ctx, doc, (pdf_obj *)rdb, contents, dev, ctm, gstate, nested_depth, default_cs); } static void |