diff options
author | Paul Gardiner <paulg.artifex@glidos.net> | 2012-08-08 14:03:34 +0100 |
---|---|---|
committer | Paul Gardiner <paulg.artifex@glidos.net> | 2012-08-08 14:03:34 +0100 |
commit | 274ab2d66943bb891976ef712a816e7d128eff22 (patch) | |
tree | bee912b4426f3dfe4acc176a57fd5b55db58d53c /pdf | |
parent | 51661f29a5f229f30ae16e16bd0ef6396cd001af (diff) | |
parent | 511ea75a53db6e72334438bcda2ce774c7d72d1e (diff) | |
download | mupdf-274ab2d66943bb891976ef712a816e7d128eff22.tar.xz |
Merge branch 'master' into forms
Conflicts:
Makefile
apps/mudraw.c
pdf/pdf_write.c
win32/libmupdf-v8.vcproj
Diffstat (limited to 'pdf')
-rw-r--r-- | pdf/mupdf-internal.h | 1 | ||||
-rw-r--r-- | pdf/pdf_annot.c | 3 | ||||
-rw-r--r-- | pdf/pdf_cmap.c | 8 | ||||
-rw-r--r-- | pdf/pdf_cmap_parse.c | 19 | ||||
-rw-r--r-- | pdf/pdf_colorspace.c | 4 | ||||
-rw-r--r-- | pdf/pdf_crypt.c | 13 | ||||
-rw-r--r-- | pdf/pdf_font.c | 11 | ||||
-rw-r--r-- | pdf/pdf_function.c | 38 | ||||
-rw-r--r-- | pdf/pdf_image.c | 13 | ||||
-rw-r--r-- | pdf/pdf_interpret.c | 113 | ||||
-rw-r--r-- | pdf/pdf_object.c | 12 | ||||
-rw-r--r-- | pdf/pdf_outline.c | 8 | ||||
-rw-r--r-- | pdf/pdf_page.c | 20 | ||||
-rw-r--r-- | pdf/pdf_parse.c | 10 | ||||
-rw-r--r-- | pdf/pdf_repair.c | 78 | ||||
-rw-r--r-- | pdf/pdf_shade.c | 3 | ||||
-rw-r--r-- | pdf/pdf_stream.c | 18 | ||||
-rw-r--r-- | pdf/pdf_type3.c | 6 | ||||
-rw-r--r-- | pdf/pdf_unicode.c | 2 | ||||
-rw-r--r-- | pdf/pdf_write.c | 111 | ||||
-rw-r--r-- | pdf/pdf_xobject.c | 6 | ||||
-rw-r--r-- | pdf/pdf_xref.c | 19 |
22 files changed, 261 insertions, 255 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index 8422fce3..65e968fb 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -263,6 +263,7 @@ void pdf_crypt_buffer(fz_context *ctx, pdf_crypt *crypt, fz_buffer *buf, int num fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen); fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen); +int pdf_crypt_version(pdf_document *doc); int pdf_crypt_revision(pdf_document *doc); char *pdf_crypt_method(pdf_document *doc); int pdf_crypt_length(pdf_document *doc); diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index fc436409..5a463336 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -320,8 +320,7 @@ pdf_free_annot(fz_context *ctx, pdf_annot *annot) next = annot->next; if (annot->ap) pdf_drop_xobject(ctx, annot->ap); - if (annot->obj) - pdf_drop_obj(annot->obj); + pdf_drop_obj(annot->obj); fz_free(ctx, annot); annot = next; } diff --git a/pdf/pdf_cmap.c b/pdf/pdf_cmap.c index cd0d6385..d6cb3103 100644 --- a/pdf/pdf_cmap.c +++ b/pdf/pdf_cmap.c @@ -184,7 +184,7 @@ pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, int low, int high, int n) static void add_table(fz_context *ctx, pdf_cmap *cmap, int value) { - if (cmap->tlen == USHRT_MAX) + if (cmap->tlen >= USHRT_MAX + 1) { fz_warn(ctx, "cmap table is full; ignoring additional entries"); return; @@ -233,7 +233,7 @@ pdf_map_range_to_table(fz_context *ctx, pdf_cmap *cmap, int low, int *table, int int i; int high = low + len; int offset = cmap->tlen; - if (cmap->tlen + len >= USHRT_MAX) + if (cmap->tlen + len >= USHRT_MAX + 1) fz_warn(ctx, "cannot map range to table; table is full"); else { @@ -280,7 +280,7 @@ pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, int low, int *values, int l return; } - if (cmap->tlen + len + 1 >= USHRT_MAX) + if (cmap->tlen + len + 1 >= USHRT_MAX + 1) fz_warn(ctx, "cannot map one to many; table is full"); else { @@ -314,7 +314,7 @@ pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap) qsort(cmap->ranges, cmap->rlen, sizeof(pdf_range), cmprange); - if (cmap->tlen == USHRT_MAX) + if (cmap->tlen >= USHRT_MAX + 1) { fz_warn(ctx, "cmap table is full; will not combine ranges"); return; diff --git a/pdf/pdf_cmap_parse.c b/pdf/pdf_cmap_parse.c index b78a36ec..7f2587ec 100644 --- a/pdf/pdf_cmap_parse.c +++ b/pdf/pdf_cmap_parse.c @@ -53,8 +53,6 @@ pdf_lex_cmap(fz_stream *file, pdf_lexbuf *buf) { int tok = pdf_lex(file, buf); - /* RJW: Lost debugging here: "cannot parse cmap token" */ - if (tok == PDF_TOK_KEYWORD) tok = pdf_cmap_token_from_keyword(buf->scratch); @@ -67,7 +65,6 @@ pdf_parse_cmap_name(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf int tok; tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_NAME) fz_strlcpy(cmap->cmap_name, buf->scratch, sizeof(cmap->cmap_name)); @@ -81,7 +78,6 @@ pdf_parse_wmode(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *bu int tok; tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_INT) pdf_set_cmap_wmode(ctx, cmap, buf->i); @@ -98,7 +94,6 @@ pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_ while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == TOK_END_CODESPACE_RANGE) return; @@ -107,7 +102,6 @@ pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_ { lo = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == PDF_TOK_STRING) { hi = pdf_code_from_string(buf->scratch, buf->len); @@ -131,7 +125,6 @@ pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok == TOK_END_CID_RANGE) return; @@ -142,14 +135,12 @@ pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf lo = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok != PDF_TOK_STRING) fz_throw(ctx, "expected string"); hi = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: Lost debugging: "syntaxerror in cmap" */ if (tok != PDF_TOK_INT) fz_throw(ctx, "expected integer"); @@ -168,7 +159,6 @@ pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_CID_CHAR) return; @@ -179,8 +169,6 @@ pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf src = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ - if (tok != PDF_TOK_INT) fz_throw(ctx, "expected integer"); @@ -200,7 +188,6 @@ pdf_parse_bf_range_array(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_l while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok == PDF_TOK_CLOSE_ARRAY) return; @@ -230,7 +217,6 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_BF_RANGE) return; @@ -241,14 +227,12 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf lo = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok != PDF_TOK_STRING) fz_throw(ctx, "expected string"); hi = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok == PDF_TOK_STRING) { @@ -280,7 +264,6 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf else if (tok == PDF_TOK_OPEN_ARRAY) { pdf_parse_bf_range_array(ctx, cmap, file, buf, lo, hi); - /* RJW: "cannot map bfrange" */ } else @@ -301,7 +284,6 @@ pdf_parse_bf_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf * while (1) { tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ if (tok == TOK_END_BF_CHAR) return; @@ -312,7 +294,6 @@ pdf_parse_bf_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf * src = pdf_code_from_string(buf->scratch, buf->len); tok = pdf_lex_cmap(file, buf); - /* RJW: "syntaxerror in cmap" */ /* Note: does not handle /dstName */ if (tok != PDF_TOK_STRING) fz_throw(ctx, "expected string"); diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c index 7a3835dd..7ebda6cf 100644 --- a/pdf/pdf_colorspace.c +++ b/pdf/pdf_colorspace.c @@ -115,7 +115,6 @@ load_separation(pdf_document *xref, pdf_obj *array) fz_throw(ctx, "too many components in colorspace"); base = pdf_load_colorspace(xref, baseobj); - /* RJW: "cannot load base colorspace (%d %d R)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */ fz_try(ctx) { @@ -234,7 +233,6 @@ load_indexed(pdf_document *xref, pdf_obj *array) fz_try(ctx) { base = pdf_load_colorspace(xref, baseobj); - /* "cannot load base colorspace (%d %d R)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */ idx = fz_malloc_struct(ctx, struct indexed); idx->lookup = NULL; @@ -340,7 +338,6 @@ pdf_load_colorspace_imp(pdf_document *xref, pdf_obj *obj) } return pdf_load_colorspace(xref, obj); - /* RJW: "cannot load pattern (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ } else if (!strcmp(pdf_to_name(name), "G")) @@ -399,7 +396,6 @@ pdf_load_colorspace(pdf_document *xref, pdf_obj *obj) } cs = pdf_load_colorspace_imp(xref, obj); - /* RJW: "cannot load colorspace (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ pdf_store_item(ctx, obj, cs, cs->size); diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c index a8f92823..5329e845 100644 --- a/pdf/pdf_crypt.c +++ b/pdf/pdf_crypt.c @@ -255,8 +255,8 @@ pdf_new_crypt(fz_context *ctx, pdf_obj *dict, pdf_obj *id) void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt) { - if (crypt->id) pdf_drop_obj(crypt->id); - if (crypt->cf) pdf_drop_obj(crypt->cf); + pdf_drop_obj(crypt->id); + pdf_drop_obj(crypt->cf); fz_free(ctx, crypt); } @@ -636,13 +636,20 @@ pdf_crypt_key(pdf_document *xref) } int -pdf_crypt_revision(pdf_document *xref) +pdf_crypt_version(pdf_document *xref) { if (xref->crypt) return xref->crypt->v; return 0; } +int pdf_crypt_revision(pdf_document *xref) +{ + if (xref->crypt) + return xref->crypt->r; + return 0; +} + char * pdf_crypt_method(pdf_document *xref) { diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c index 1a0177b6..33a1a651 100644 --- a/pdf/pdf_font.c +++ b/pdf/pdf_font.c @@ -186,7 +186,6 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname) fz_throw(ctx, "cannot find builtin font: '%s'", fontname); fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); - /* RJW: "cannot load freetype font from memory" */ if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) fontdesc->flags |= PDF_FD_SYMBOLIC; @@ -203,7 +202,6 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontnam fz_throw(ctx, "cannot find substitute font"); fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); - /* RJW: "cannot load freetype font from memory" */ fontdesc->font->ft_substitute = 1; fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face); @@ -222,7 +220,6 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fon /* a glyph bbox cache is too big for droid sans fallback (51k glyphs!) */ fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 0); - /* RJW: "cannot load builtin CJK font" */ fontdesc->font->ft_substitute = 1; } @@ -462,7 +459,6 @@ pdf_load_simple_font(pdf_document *xref, pdf_obj *dict) 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); @@ -546,7 +542,7 @@ pdf_load_simple_font(pdf_document *xref, pdf_obj *dict) item = pdf_array_get(diff, i); if (pdf_is_int(item)) k = pdf_to_int(item); - if (pdf_is_name(item) && k >= 0 && k < 256) + if (pdf_is_name(item) && k >= 0 && k < nelem(estrings)) estrings[k++] = pdf_to_name(item); } } @@ -865,12 +861,10 @@ load_cid_font(pdf_document *xref, pdf_obj *dict, pdf_obj *encoding, pdf_obj *to_ 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_load_to_unicode(xref, fontdesc, NULL, collection, to_unicode); - /* RJW: "cannot load to_unicode" */ /* Horizontal */ @@ -999,7 +993,7 @@ pdf_load_type0_font(pdf_document *xref, pdf_obj *dict) return load_cid_font(xref, dfont, encoding, to_unicode); else fz_throw(xref->ctx, "syntaxerror: unknown cid font type"); - /* RJW: "cannot load descendant font (%d %d R)", pdf_to_num(dfont), pdf_to_gen(dfont) */ + return NULL; /* Stupid MSVC */ } @@ -1144,7 +1138,6 @@ pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) fz_warn(ctx, "unknown font format, guessing type1 or truetype."); fontdesc = pdf_load_simple_font(xref, dict); } - /* RJW: "cannot load font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */ /* Save the widths to stretch non-CJK substitute fonts */ if (fontdesc->font->ft_substitute && !fontdesc->to_ttf_cmap) diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index eab7bedf..c9bbc5b5 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -711,7 +711,6 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr, pdf_lexbuf *buf) while (1) { tok = pdf_lex(stream, buf); - /* RJW: "calculator function lexical error" */ switch(tok) { @@ -754,19 +753,15 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr, pdf_lexbuf *buf) ifptr = *codeptr; parse_code(func, stream, codeptr, buf); - /* RJW: "error in 'if' branch" */ tok = pdf_lex(stream, buf); - /* RJW: "calculator function syntax error" */ if (tok == PDF_TOK_OPEN_BRACE) { elseptr = *codeptr; parse_code(func, stream, codeptr, buf); - /* RJW: "error in 'else' branch" */ tok = pdf_lex(stream, buf); - /* RJW: "calculator function syntax error" */ } else { @@ -861,7 +856,6 @@ load_postscript_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int fz_try(ctx) { stream = pdf_open_stream(xref, num, gen); - /* RJW: "cannot open calculator function stream" */ tok = pdf_lex(stream, &buf); if (tok != PDF_TOK_OPEN_BRACE) @@ -958,7 +952,7 @@ load_sample_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int num, { int ranges = fz_mini(func->m, pdf_array_len(obj) / 2); if (ranges != func->m) - fz_warn(ctx, "too few/many sample function input mappings"); + fz_warn(ctx, "wrong number of sample function input mappings"); for (i = 0; i < ranges; i++) { @@ -978,7 +972,7 @@ load_sample_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int num, { int ranges = fz_mini(func->n, pdf_array_len(obj) / 2); if (ranges != func->n) - fz_warn(ctx, "too few/many sample function output mappings"); + fz_warn(ctx, "wrong number of sample function output mappings"); for (i = 0; i < ranges; i++) { @@ -997,7 +991,6 @@ load_sample_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int num, func->size += samplecount * sizeof(float); 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++) @@ -1179,7 +1172,7 @@ load_exponential_func(fz_context *ctx, pdf_function *func, pdf_obj *dict) { int ranges = fz_mini(func->n, pdf_array_len(obj)); if (ranges != func->n) - fz_warn(ctx, "too few/many C0 constants for exponential function"); + fz_warn(ctx, "wrong number of C0 constants for exponential function"); for (i = 0; i < ranges; i++) func->u.e.c0[i] = pdf_to_real(pdf_array_get(obj, i)); @@ -1190,7 +1183,7 @@ load_exponential_func(fz_context *ctx, pdf_function *func, pdf_obj *dict) { int ranges = fz_mini(func->n, pdf_array_len(obj)); if (ranges != func->n) - fz_warn(ctx, "too few/many C1 constants for exponential function"); + fz_warn(ctx, "wrong number of C1 constants for exponential function"); for (i = 0; i < ranges; i++) func->u.e.c1[i] = pdf_to_real(pdf_array_get(obj, i)); @@ -1255,17 +1248,18 @@ load_stitching_func(pdf_function *func, pdf_document *xref, pdf_obj *dict) { sub = pdf_array_get(obj, i); funcs[i] = pdf_load_function(xref, sub, 1, func->n); - /* RJW: "cannot load sub function %d (%d %d R)", i, pdf_to_num(sub), pdf_to_gen(sub) */ - if (funcs[i]->m != 1 || funcs[i]->n != funcs[0]->n) - fz_throw(ctx, "sub function %d /Domain or /Range mismatch", i); + func->size += pdf_function_size(funcs[i]); func->u.st.k ++; - } - if (func->n != funcs[0]->n) - fz_throw(ctx, "sub function /Domain or /Range mismatch"); + if (funcs[i]->m != func->m) + fz_warn(ctx, "wrong number of inputs for sub function %d", i); + if (funcs[i]->n != func->n) + fz_warn(ctx, "wrong number of outputs for sub function %d", i); + } } + obj = pdf_dict_gets(dict, "Bounds"); if (!pdf_is_array(obj)) fz_throw(ctx, "stitching function has no bounds"); @@ -1299,7 +1293,7 @@ load_stitching_func(pdf_function *func, pdf_document *xref, pdf_obj *dict) { int ranges = fz_mini(k, pdf_array_len(obj) / 2); if (ranges != k) - fz_warn(ctx, "too few/many stitching function input mappings"); + fz_warn(ctx, "wrong number of stitching function input mappings"); for (i = 0; i < ranges; i++) { @@ -1422,7 +1416,7 @@ pdf_load_function(pdf_document *xref, pdf_obj *dict, int in, int out) /* required for all */ obj = pdf_dict_gets(dict, "Domain"); - func->m = fz_clampi(pdf_array_len(obj) / 2, 1, MAXN); + func->m = fz_clampi(pdf_array_len(obj) / 2, 1, MAXM); for (i = 0; i < func->m; i++) { func->domain[i][0] = pdf_to_real(pdf_array_get(obj, i * 2 + 0)); @@ -1448,9 +1442,9 @@ pdf_load_function(pdf_document *xref, pdf_obj *dict, int in, int out) } if (func->m != in) - fz_warn(ctx, "too few/many function inputs"); + fz_warn(ctx, "wrong number of function inputs"); if (func->n != out) - fz_warn(ctx, "too few/many function outputs"); + fz_warn(ctx, "wrong number of function outputs"); fz_try(ctx) { @@ -1498,7 +1492,7 @@ pdf_load_function(pdf_document *xref, pdf_obj *dict, int in, int out) void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in_, int inlen, float *out_, int outlen) { - float fakein[MAXN]; + float fakein[MAXM]; float fakeout[MAXN]; float *in = in_; float *out = out_; diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c index 58a17ed0..249e2c65 100644 --- a/pdf/pdf_image.c +++ b/pdf/pdf_image.c @@ -317,7 +317,7 @@ pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *c if (pdf_is_jpx_image(ctx, dict)) { pdf_load_jpx(xref, dict, image); - /* RJW: "cannot load jpx image" */ + if (forcemask) { fz_pixmap *mask_pixmap; @@ -368,7 +368,6 @@ pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *c } image->base.colorspace = pdf_load_colorspace(xref, obj); - /* RJW: "cannot load image colorspace" */ if (!strcmp(image->base.colorspace->name, "Indexed")) indexed = 1; @@ -400,7 +399,6 @@ pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *c if (!cstm) { mask = (fz_image *)pdf_load_image_imp(xref, rdb, obj, NULL, 1); - /* RJW: "cannot load image mask/softmask" */ } } else if (pdf_is_array(obj)) @@ -449,14 +447,13 @@ pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *c else { stm = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); - /* RJW: "cannot open image data stream (%d 0 R)", pdf_to_num(dict) */ } image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 1, 0); } fz_catch(ctx) { - fz_drop_image(ctx, &image->base); + pdf_free_image(ctx, (fz_storable *) image); fz_rethrow(ctx); } return image; @@ -466,7 +463,6 @@ fz_image * pdf_load_inline_image(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *file) { return (fz_image *)pdf_load_image_imp(xref, rdb, dict, file, 0); - /* RJW: "cannot load inline image" */ } int @@ -500,7 +496,6 @@ pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image) fz_var(colorspace); buf = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); - /* RJW: "cannot load jpx image data" */ /* FIXME: We can't handle decode arrays for indexed images currently */ fz_try(ctx) @@ -509,12 +504,10 @@ pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image) if (obj) { colorspace = pdf_load_colorspace(xref, obj); - /* RJW: "cannot load image colorspace" */ indexed = !strcmp(colorspace->name, "Indexed"); } img = fz_load_jpx(ctx, buf->data, buf->len, colorspace, indexed); - /* RJW: "cannot load jpx image" */ if (img && colorspace == NULL) colorspace = fz_keep_colorspace(ctx, img->colorspace); @@ -526,7 +519,6 @@ pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image) if (pdf_is_dict(obj)) { image->base.mask = (fz_image *)pdf_load_image_imp(xref, NULL, obj, NULL, 1); - /* RJW: "cannot load image mask/softmask" */ } obj = pdf_dict_getsa(dict, "Decode", "D"); @@ -584,7 +576,6 @@ pdf_load_image(pdf_document *xref, pdf_obj *dict) } image = pdf_load_image_imp(xref, NULL, dict, NULL, 0); - /* RJW: "cannot load image (%d 0 R)", pdf_to_num(dict) */ pdf_store_item(ctx, dict, image, pdf_image_size(ctx, image)); diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c index ab55ee66..704f6e78 100644 --- a/pdf/pdf_interpret.c +++ b/pdf/pdf_interpret.c @@ -319,7 +319,7 @@ pdf_begin_group(pdf_csi *csi, fz_rect bbox) fz_begin_mask(csi->dev, bbox, gstate->luminosity, softmask->colorspace, gstate->softmask_bc); pdf_run_xobject(csi, NULL, softmask, fz_identity); - /* RJW: "cannot run softmask" */ + fz_end_mask(csi->dev); gstate->softmask = softmask; @@ -539,12 +539,14 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd) if (dofill || dostroke) pdf_end_group(csi); } - fz_catch(ctx) + fz_always(ctx) { fz_free_path(ctx, path); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - fz_free_path(ctx, path); } /* @@ -658,13 +660,14 @@ pdf_flush_text(pdf_csi *csi) pdf_end_group(csi); } - fz_catch(ctx) + fz_always(ctx) { fz_free_text(ctx, text); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - - fz_free_text(ctx, text); } static void @@ -926,6 +929,8 @@ copy_state(fz_context *ctx, pdf_gstate *gs, pdf_gstate *old) gs->fill = old->fill; gs->font = old->font; gs->softmask = old->softmask; + + fz_drop_stroke_state(ctx, gs->stroke_state); gs->stroke_state = fz_keep_stroke_state(ctx, old->stroke_state); pdf_keep_material(ctx, &gs->stroke); @@ -996,8 +1001,7 @@ pdf_clear_stack(pdf_csi *csi) { int i; - if (csi->obj) - pdf_drop_obj(csi->obj); + pdf_drop_obj(csi->obj); csi->obj = NULL; csi->name[0] = 0; @@ -1292,7 +1296,6 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what) csi->top_ctm = gstate->ctm; pdf_gsave(csi); pdf_run_contents_object(csi, pat->resources, pat->contents); - /* RJW: "cannot render pattern tile" */ pdf_grestore(csi); while (oldtop < csi->gtop) pdf_grestore(csi); @@ -1312,17 +1315,17 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what) { pdf_run_contents_object(csi, pat->resources, pat->contents); } - fz_catch(ctx) + fz_always(ctx) { pdf_grestore(csi); while (oldtop < csi->gtop) pdf_grestore(csi); + } + fz_catch(ctx) + { csi->top_ctm = oldtopctm; fz_throw(ctx, "cannot render pattern tile"); } - pdf_grestore(csi); - while (oldtop < csi->gtop) - pdf_grestore(csi); } } } @@ -1374,7 +1377,6 @@ pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix t fz_begin_mask(csi->dev, bbox, gstate->luminosity, softmask->colorspace, gstate->softmask_bc); pdf_run_xobject(csi, resources, softmask, fz_identity); - /* RJW: "cannot run softmask" */ fz_end_mask(csi->dev); pdf_drop_xobject(ctx, softmask); @@ -1408,7 +1410,6 @@ pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix t resources = xobj->resources; pdf_run_contents_object(csi, resources, xobj->contents); - /* RJW: "cannot interpret XObject stream" */ } fz_always(ctx) { @@ -1468,7 +1469,6 @@ pdf_run_extgstate(pdf_csi *csi, pdf_obj *rdb, pdf_obj *extgstate) } gstate->font = pdf_load_font(csi->xref, rdb, font); - /* RJW: "cannot load font (%d %d R)", pdf_to_num(font), pdf_to_gen(font) */ if (!gstate->font) fz_throw(ctx, "cannot find font in store"); gstate->size = pdf_to_real(pdf_array_get(val, 1)); @@ -1550,7 +1550,6 @@ pdf_run_extgstate(pdf_csi *csi, pdf_obj *rdb, pdf_obj *extgstate) if (!group) fz_throw(ctx, "cannot load softmask xobject (%d %d R)", pdf_to_num(val), pdf_to_gen(val)); xobj = pdf_load_xobject(csi->xref, group); - /* RJW: "cannot load xobject (%d %d R)", pdf_to_num(val), pdf_to_gen(val) */ colorspace = xobj->colorspace; if (!colorspace) @@ -1633,7 +1632,6 @@ static void pdf_run_BI(pdf_csi *csi, pdf_obj *rdb, fz_stream *file) pdf_obj *obj; obj = pdf_parse_dict(csi->xref, file, &csi->xref->lexbuf.base); - /* RJW: "cannot parse inline image dictionary" */ /* read whitespace after ID keyword */ ch = fz_read_byte(file); @@ -1641,9 +1639,18 @@ static void pdf_run_BI(pdf_csi *csi, pdf_obj *rdb, fz_stream *file) if (fz_peek_byte(file) == '\n') fz_read_byte(file); - img = pdf_load_inline_image(csi->xref, rdb, obj, file); - pdf_drop_obj(obj); - /* RJW: "cannot load inline image" */ + fz_try(ctx) + { + img = pdf_load_inline_image(csi->xref, rdb, obj, file); + } + fz_always(ctx) + { + pdf_drop_obj(obj); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } pdf_show_image(csi, img); @@ -1718,7 +1725,6 @@ static void pdf_run_cs_imp(pdf_csi *csi, pdf_obj *rdb, int what) if (!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)", pdf_to_num(obj) */ } pdf_set_colorspace(csi, what, colorspace); @@ -1732,7 +1738,6 @@ static void pdf_run_CS(pdf_csi *csi, pdf_obj *rdb) csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_run_cs_imp(csi, rdb, PDF_STROKE); - /* RJW: "cannot set colorspace" */ } static void pdf_run_cs(pdf_csi *csi, pdf_obj *rdb) @@ -1740,7 +1745,6 @@ static void pdf_run_cs(pdf_csi *csi, pdf_obj *rdb) csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_run_cs_imp(csi, rdb, PDF_FILL); - /* RJW: "cannot set colorspace" */ } static void pdf_run_DP(pdf_csi *csi) @@ -1777,7 +1781,6 @@ static void pdf_run_Do(pdf_csi *csi, pdf_obj *rdb) pdf_xobject *xobj; xobj = pdf_load_xobject(csi->xref, obj); - /* RJW: "cannot load xobject (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ /* Inherit parent resources, in case this one was empty XXX check where it's loaded */ if (!xobj->resources) @@ -1787,13 +1790,14 @@ static void pdf_run_Do(pdf_csi *csi, pdf_obj *rdb) { pdf_run_xobject(csi, xobj->resources, xobj, fz_identity); } - fz_catch(ctx) + fz_always(ctx) { pdf_drop_xobject(ctx, xobj); + } + fz_catch(ctx) + { fz_throw(ctx, "cannot draw xobject (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } - - pdf_drop_xobject(ctx, xobj); } else if (!strcmp(pdf_to_name(subtype), "Image")) @@ -1801,7 +1805,7 @@ static void pdf_run_Do(pdf_csi *csi, pdf_obj *rdb) if ((csi->dev->hints & FZ_IGNORE_IMAGE) == 0) { fz_image *img = pdf_load_image(csi->xref, obj); - /* RJW: "cannot load image (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ + fz_try(ctx) { pdf_show_image(csi, img); @@ -1940,7 +1944,6 @@ static void pdf_run_SC_imp(pdf_csi *csi, pdf_obj *rdb, int what, pdf_material *m { pdf_pattern *pat; pat = pdf_load_pattern(csi->xref, obj); - /* RJW: "cannot load pattern (%d 0 R)", pdf_to_num(obj) */ pdf_set_pattern(csi, what, pat, csi->top > 0 ? csi->stack : NULL); pdf_drop_pattern(ctx, pat); } @@ -1948,7 +1951,6 @@ static void pdf_run_SC_imp(pdf_csi *csi, pdf_obj *rdb, int what, pdf_material *m { fz_shade *shd; shd = pdf_load_shading(csi->xref, obj); - /* RJW: "cannot load shading (%d 0 R)", pdf_to_num(obj) */ pdf_set_shade(csi, what, shd); fz_drop_shade(ctx, shd); } @@ -1968,7 +1970,6 @@ static void pdf_run_SC(pdf_csi *csi, pdf_obj *rdb) pdf_gstate *gstate = csi->gstate + csi->gtop; csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED; pdf_run_SC_imp(csi, rdb, PDF_STROKE, &gstate->stroke); - /* RJW: "cannot set color and colorspace" */ } static void pdf_run_sc(pdf_csi *csi, pdf_obj *rdb) @@ -1976,7 +1977,6 @@ static void pdf_run_sc(pdf_csi *csi, pdf_obj *rdb) pdf_gstate *gstate = csi->gstate + csi->gtop; csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED; pdf_run_SC_imp(csi, rdb, PDF_FILL, &gstate->fill); - /* RJW: "cannot set color and colorspace" */ } static void pdf_run_Tc(pdf_csi *csi) @@ -2026,7 +2026,6 @@ static void pdf_run_Tf(pdf_csi *csi, pdf_obj *rdb) fz_throw(ctx, "cannot find font resource: '%s'", csi->name); gstate->font = pdf_load_font(csi->xref, rdb, obj); - /* RJW: "cannot load font (%d 0 R)", pdf_to_num(obj) */ } static void pdf_run_Tr(pdf_csi *csi) @@ -2209,7 +2208,6 @@ static void pdf_run_gs(pdf_csi *csi, pdf_obj *rdb) fz_throw(ctx, "cannot find extgstate resource '%s'", csi->name); pdf_run_extgstate(csi, rdb, obj); - /* RJW: "cannot set ExtGState (%d 0 R)", pdf_to_num(obj) */ } static void pdf_run_h(pdf_csi *csi) @@ -2313,17 +2311,19 @@ static void pdf_run_sh(pdf_csi *csi, pdf_obj *rdb) if ((csi->dev->hints & FZ_IGNORE_SHADE) == 0) { shd = pdf_load_shading(csi->xref, obj); - /* RJW: "cannot load shading (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ + fz_try(ctx) { pdf_show_shade(csi, shd); } - fz_catch(ctx) + fz_always(ctx) { fz_drop_shade(ctx, shd); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - fz_drop_shade(ctx, shd); } } @@ -2420,7 +2420,6 @@ pdf_run_keyword(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, char *buf) case C('B','D','C'): pdf_run_BDC(csi, rdb); break; case B('B','I'): 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; @@ -2540,6 +2539,7 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) fz_context *ctx = csi->dev->ctx; int tok = PDF_TOK_ERROR; int in_array; + int ignoring_errors = 0; /* make sure we have a clean slate if we come here from flush_text */ pdf_clear_stack(csi); @@ -2560,9 +2560,6 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) { do { - if (csi->top == nelem(csi->stack) - 1) - fz_throw(ctx, "stack overflow"); - /* Check the cookie */ if (csi->cookie) { @@ -2575,7 +2572,6 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) } tok = pdf_lex(file, buf); - /* RJW: "lexical error in content stream" */ if (in_array) { @@ -2621,7 +2617,6 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) if (!csi->in_text) { csi->obj = pdf_parse_array(csi->xref, file, buf); - /* RJW: "cannot parse array" */ } else { @@ -2631,7 +2626,6 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) case PDF_TOK_OPEN_DICT: csi->obj = pdf_parse_dict(csi->xref, file, buf); - /* RJW: "cannot parse dictionary" */ break; case PDF_TOK_NAME: @@ -2639,13 +2633,21 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) break; case PDF_TOK_INT: - csi->stack[csi->top] = buf->i; - csi->top ++; + if (csi->top < nelem(csi->stack)) { + csi->stack[csi->top] = buf->i; + csi->top ++; + } + else + fz_throw(ctx, "stack overflow"); break; case PDF_TOK_REAL: - csi->stack[csi->top] = buf->f; - csi->top ++; + if (csi->top < nelem(csi->stack)) { + csi->stack[csi->top] = buf->f; + csi->top ++; + } + else + fz_throw(ctx, "stack overflow"); break; case PDF_TOK_STRING: @@ -2665,7 +2667,6 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) { tok = PDF_TOK_EOF; } - /* RJW: "cannot run keyword" */ pdf_clear_stack(csi); break; @@ -2680,7 +2681,11 @@ pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf) /* Swallow the error */ if (csi->cookie) csi->cookie->errors++; - fz_warn(ctx, "Ignoring error during rendering"); + if (!ignoring_errors) + { + fz_warn(ctx, "Ignoring errors during rendering"); + ignoring_errors = 1; + } /* If we do catch an error, then reset ourselves to a * base lexing state */ in_array = 0; @@ -2863,10 +2868,12 @@ pdf_run_glyph(pdf_document *xref, pdf_obj *resources, fz_buffer *contents, fz_de { pdf_run_contents_buffer(csi, resources, contents); } - fz_catch(ctx) + fz_always(ctx) { pdf_free_csi(csi); + } + fz_catch(ctx) + { fz_throw(ctx, "cannot parse glyph content stream"); } - pdf_free_csi(csi); } diff --git a/pdf/pdf_object.c b/pdf/pdf_object.c index 819607ce..fb53d9b8 100644 --- a/pdf/pdf_object.c +++ b/pdf/pdf_object.c @@ -512,8 +512,7 @@ pdf_array_put(pdf_obj *obj, int i, pdf_obj *item) fz_warn(obj->ctx, "assert: index %d > length %d", i, obj->u.a.len); else { - if (obj->u.a.items[i]) - pdf_drop_obj(obj->u.a.items[i]); + pdf_drop_obj(obj->u.a.items[i]); obj->u.a.items[i] = pdf_keep_obj(item); } } @@ -1090,8 +1089,7 @@ pdf_free_array(pdf_obj *obj) int i; for (i = 0; i < obj->u.a.len; i++) - if (obj->u.a.items[i]) - pdf_drop_obj(obj->u.a.items[i]); + pdf_drop_obj(obj->u.a.items[i]); fz_free(obj->ctx, obj->u.a.items); fz_free(obj->ctx, obj); @@ -1103,10 +1101,8 @@ pdf_free_dict(pdf_obj *obj) int i; for (i = 0; i < obj->u.d.len; i++) { - if (obj->u.d.items[i].k) - pdf_drop_obj(obj->u.d.items[i].k); - if (obj->u.d.items[i].v) - pdf_drop_obj(obj->u.d.items[i].v); + pdf_drop_obj(obj->u.d.items[i].k); + pdf_drop_obj(obj->u.d.items[i].v); } fz_free(obj->ctx, obj->u.d.items); diff --git a/pdf/pdf_outline.c b/pdf/pdf_outline.c index 48f3853c..616f5a15 100644 --- a/pdf/pdf_outline.c +++ b/pdf/pdf_outline.c @@ -43,16 +43,16 @@ pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict) dict = pdf_dict_gets(dict, "Next"); } } - fz_catch(ctx) + fz_always(ctx) { for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next")) pdf_dict_unmark(dict); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next")) - pdf_dict_unmark(dict); - return first; } diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c index c1d454f0..458ab4d4 100644 --- a/pdf/pdf_page.c +++ b/pdf/pdf_page.c @@ -19,12 +19,14 @@ put_marker_bool(fz_context *ctx, pdf_obj *rdb, char *marker, int val) { pdf_dict_puts(rdb, marker, tmp); } - fz_catch(ctx) + fz_always(ctx) { pdf_drop_obj(tmp); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - pdf_drop_obj(tmp); } typedef struct pdf_page_load_s pdf_page_load; @@ -152,7 +154,7 @@ pdf_load_page_tree(pdf_document *xref) pdf_obj *count; struct info info; - if (xref->page_len) + if (xref->page_refs) return; catalog = pdf_dict_gets(xref->trailer, "Root"); @@ -270,12 +272,14 @@ found: useBM = 1; } } - fz_catch(ctx) + fz_always(ctx) { pdf_dict_unmark(rdb); + } + fz_catch(ctx) + { fz_rethrow(ctx); } - pdf_dict_unmark(rdb); put_marker_bool(ctx, rdb, ".useBM", useBM); return useBM; @@ -404,10 +408,8 @@ pdf_load_links(pdf_document *xref, pdf_page *page) void pdf_free_page(pdf_document *xref, pdf_page *page) { - if (page->resources) - pdf_drop_obj(page->resources); - if (page->contents) - pdf_drop_obj(page->contents); + pdf_drop_obj(page->resources); + pdf_drop_obj(page->contents); if (page->links) fz_drop_link(xref->ctx, page->links); if (page->annots) diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c index 213c399e..4a7e421f 100644 --- a/pdf/pdf_parse.c +++ b/pdf/pdf_parse.c @@ -448,16 +448,13 @@ pdf_parse_stm_obj(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf) fz_context *ctx = file->ctx; tok = pdf_lex(file, buf); - /* RJW: "cannot parse token in object stream") */ switch (tok) { case PDF_TOK_OPEN_ARRAY: return pdf_parse_array(xref, file, buf); - /* RJW: "cannot parse object stream" */ case PDF_TOK_OPEN_DICT: return pdf_parse_dict(xref, file, buf); - /* RJW: "cannot parse object stream" */ case PDF_TOK_NAME: return fz_new_name(ctx, buf->scratch); break; case PDF_TOK_REAL: return pdf_new_real(ctx, buf->f); break; case PDF_TOK_STRING: return pdf_new_string(ctx, buf->scratch, buf->len); break; @@ -494,23 +491,19 @@ pdf_parse_ind_obj(pdf_document *xref, gen = buf->i; tok = pdf_lex(file, buf); - /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_OBJ) fz_throw(ctx, "expected 'obj' keyword (%d %d ?)", num, gen); tok = pdf_lex(file, buf); - /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ switch (tok) { case PDF_TOK_OPEN_ARRAY: obj = pdf_parse_array(xref, file, buf); - /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_OPEN_DICT: obj = pdf_parse_dict(xref, file, buf); - /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_NAME: obj = fz_new_name(ctx, buf->scratch); break; @@ -523,7 +516,7 @@ pdf_parse_ind_obj(pdf_document *xref, case PDF_TOK_INT: a = buf->i; tok = pdf_lex(file, buf); - /* "cannot parse indirect object (%d %d R)", num, gen */ + if (tok == PDF_TOK_STREAM || tok == PDF_TOK_ENDOBJ) { obj = pdf_new_int(ctx, a); @@ -533,7 +526,6 @@ pdf_parse_ind_obj(pdf_document *xref, { b = buf->i; tok = pdf_lex(file, buf); - /* RJW: "cannot parse indirect object (%d %d R)", num, gen); */ if (tok == PDF_TOK_R) { obj = pdf_new_indirect(ctx, a, b, xref); diff --git a/pdf/pdf_repair.c b/pdf/pdf_repair.c index bfbc581e..10762dde 100644 --- a/pdf/pdf_repair.c +++ b/pdf/pdf_repair.c @@ -3,6 +3,9 @@ /* Scan file for objects and reconstruct xref table */ +/* Define in PDF 1.7 to be 8388607, but mupdf is more lenient. */ +#define MAX_OBJECT_NUMBER (10 << 20) + struct entry { int num; @@ -26,7 +29,7 @@ pdf_repair_obj(fz_stream *file, pdf_lexbuf *buf, int *stmofsp, int *stmlenp, pdf stm_len = 0; tok = pdf_lex(file, buf); - /* RJW: "cannot parse object" */ + if (tok == PDF_TOK_OPEN_DICT) { pdf_obj *dict, *obj; @@ -51,16 +54,14 @@ pdf_repair_obj(fz_stream *file, pdf_lexbuf *buf, int *stmofsp, int *stmlenp, pdf obj = pdf_dict_gets(dict, "Encrypt"); if (obj) { - if (*encrypt) - pdf_drop_obj(*encrypt); + pdf_drop_obj(*encrypt); *encrypt = pdf_keep_obj(obj); } obj = pdf_dict_gets(dict, "ID"); if (obj) { - if (*id) - pdf_drop_obj(*id); + pdf_drop_obj(*id); *id = pdf_keep_obj(obj); } } @@ -79,7 +80,6 @@ pdf_repair_obj(fz_stream *file, pdf_lexbuf *buf, int *stmofsp, int *stmlenp, pdf tok != PDF_TOK_INT ) { tok = pdf_lex(file, buf); - /* RJW: "cannot scan for endobj or stream token" */ } if (tok == PDF_TOK_INT) @@ -133,7 +133,6 @@ pdf_repair_obj(fz_stream *file, pdf_lexbuf *buf, int *stmofsp, int *stmlenp, pdf atobjend: tok = pdf_lex(file, buf); - /* RJW: "cannot scan for endobj token" */ if (tok != PDF_TOK_ENDOBJ) fz_warn(ctx, "object missing 'endobj' token"); } @@ -170,6 +169,16 @@ pdf_repair_obj_stm(pdf_document *xref, int num, int gen) fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen); n = buf.i; + if (n < 0) + { + fz_warn(ctx, "ignoring object with invalid object number (%d %d R)", n, i); + continue; + } + else if (n > MAX_OBJECT_NUMBER) + { + fz_warn(ctx, "ignoring object with invalid object number (%d %d R)", n, i); + continue; + } if (n >= xref->len) pdf_resize_xref(xref, n + 1); @@ -301,6 +310,19 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) break; } + if (num < 0) + { + fz_warn(ctx, "ignoring object with invalid object number (%d %d R)", num, gen); + continue; + } + else if (num > MAX_OBJECT_NUMBER) + { + fz_warn(ctx, "ignoring object with invalid object number (%d %d R)", num, gen); + continue; + } + + gen = fz_clampi(gen, 0, 65535); + if (listlen + 1 == listcap) { listcap = (listcap * 3) / 2; @@ -339,32 +361,28 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) obj = pdf_dict_gets(dict, "Encrypt"); if (obj) { - if (encrypt) - pdf_drop_obj(encrypt); + pdf_drop_obj(encrypt); encrypt = pdf_keep_obj(obj); } obj = pdf_dict_gets(dict, "ID"); if (obj) { - if (id) - pdf_drop_obj(id); + pdf_drop_obj(id); id = pdf_keep_obj(obj); } obj = pdf_dict_gets(dict, "Root"); if (obj) { - if (root) - pdf_drop_obj(root); + pdf_drop_obj(root); root = pdf_keep_obj(obj); } obj = pdf_dict_gets(dict, "Info"); if (obj) { - if (info) - pdf_drop_obj(info); + pdf_drop_obj(info); info = pdf_keep_obj(obj); } @@ -394,7 +412,6 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) if (list[i].stm_len >= 0) { 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 */ length = pdf_new_int(ctx, list[i].stm_len); pdf_dict_puts(dict, "Length", length); @@ -435,11 +452,13 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) { pdf_dict_puts(xref->trailer, "Root", root); pdf_drop_obj(root); + root = NULL; } if (info) { pdf_dict_puts(xref->trailer, "Info", info); pdf_drop_obj(info); + info = NULL; } if (encrypt) @@ -453,6 +472,7 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) } pdf_dict_puts(xref->trailer, "Encrypt", encrypt); pdf_drop_obj(encrypt); + encrypt = NULL; } if (id) @@ -466,16 +486,17 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) } pdf_dict_puts(xref->trailer, "ID", id); pdf_drop_obj(id); + id = NULL; } fz_free(ctx, list); } fz_catch(ctx) { - if (encrypt) pdf_drop_obj(encrypt); - if (id) pdf_drop_obj(id); - if (root) pdf_drop_obj(root); - if (info) pdf_drop_obj(info); + pdf_drop_obj(encrypt); + pdf_drop_obj(id); + pdf_drop_obj(root); + pdf_drop_obj(info); fz_free(ctx, list); fz_rethrow(ctx); } @@ -484,6 +505,7 @@ pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf) void pdf_repair_obj_stms(pdf_document *xref) { + fz_context *ctx = xref->ctx; pdf_obj *dict; int i; @@ -492,9 +514,19 @@ pdf_repair_obj_stms(pdf_document *xref) if (xref->table[i].stm_ofs) { dict = pdf_load_object(xref, i, 0); - if (!strcmp(pdf_to_name(pdf_dict_gets(dict, "Type")), "ObjStm")) - pdf_repair_obj_stm(xref, i, 0); - pdf_drop_obj(dict); + fz_try(ctx) + { + if (!strcmp(pdf_to_name(pdf_dict_gets(dict, "Type")), "ObjStm")) + pdf_repair_obj_stm(xref, i, 0); + } + fz_always(ctx) + { + pdf_drop_obj(dict); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } } } diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c index 9e056c14..39e71626 100644 --- a/pdf/pdf_shade.c +++ b/pdf/pdf_shade.c @@ -1019,7 +1019,6 @@ pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform) if (!obj) fz_throw(ctx, "shading colorspace is missing"); shade->colorspace = pdf_load_colorspace(xref, obj); - /* RJW: "cannot load colorspace (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ obj = pdf_dict_gets(dict, "Background"); if (obj) @@ -1143,14 +1142,12 @@ pdf_load_shading(pdf_document *xref, pdf_obj *dict) fz_throw(ctx, "syntaxerror: missing shading dictionary"); shade = pdf_load_shading_dict(xref, obj, mat); - /* RJW: "cannot load shading dictionary (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */ } /* Naked shading dictionary */ else { shade = pdf_load_shading_dict(xref, dict, fz_identity); - /* RJW: "cannot load shading dictionary (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */ } pdf_store_item(ctx, dict, shade, fz_shade_size(shade)); diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c index a4af8e39..a81ecb18 100644 --- a/pdf/pdf_stream.c +++ b/pdf/pdf_stream.c @@ -11,7 +11,6 @@ pdf_is_stream(pdf_document *xref, int num, int gen) return 0; pdf_cache_object(xref, num, gen); - /* RJW: "cannot load object, ignoring error" */ return xref->table[num].stm_ofs != 0 || xref->table[num].stm_buf; } @@ -226,10 +225,10 @@ build_filter_chain(fz_stream *chain, pdf_document *xref, pdf_obj *fs, pdf_obj *p * allow for other people accessing the file), followed by a decryption * filter. * - * num and gen are used purely to seed the encryption. + * orig_num and orig_gen are used purely to seed the encryption. */ static fz_stream * -pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int gen, int offset) +pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int orig_num, int orig_gen, int offset) { fz_context *ctx = chain->ctx; int hascrypt; @@ -248,7 +247,7 @@ pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int n { hascrypt = pdf_stream_has_crypt(ctx, stmobj); if (xref->crypt && !hascrypt) - chain = pdf_open_crypt(chain, xref->crypt, num, gen); + chain = pdf_open_crypt(chain, xref->crypt, orig_num, orig_gen); } fz_catch(ctx) { @@ -272,7 +271,7 @@ pdf_open_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, filters = pdf_dict_getsa(stmobj, "Filter", "F"); params = pdf_dict_getsa(stmobj, "DecodeParms", "DP"); - chain = pdf_open_raw_filter(chain, xref, stmobj, num, gen, offset); + chain = pdf_open_raw_filter(chain, xref, stmobj, num, num, gen, offset); if (pdf_is_name(filters)) chain = build_filter(chain, xref, filters, params, num, gen, imparams); @@ -326,12 +325,11 @@ pdf_open_raw_renumbered_stream(pdf_document *xref, int num, int gen, int orig_nu x = xref->table + num; pdf_cache_object(xref, num, gen); - /* RJW: "cannot load stream object (%d %d R)", num, gen */ if (x->stm_ofs == 0) fz_throw(xref->ctx, "object is not a stream"); - return pdf_open_raw_filter(xref->file, xref, x->obj, orig_num, orig_gen, x->stm_ofs); + return pdf_open_raw_filter(xref->file, xref, x->obj, num, orig_num, orig_gen, x->stm_ofs); } /* @@ -356,7 +354,6 @@ pdf_open_image_stream(pdf_document *xref, int num, int gen, int orig_num, int or x = xref->table + num; pdf_cache_object(xref, num, gen); - /* RJW: "cannot load stream object (%d %d R)", num, gen */ if (x->stm_ofs == 0 && x->stm_buf == NULL) fz_throw(xref->ctx, "object is not a stream"); @@ -438,17 +435,14 @@ pdf_load_raw_renumbered_stream(pdf_document *xref, int num, int gen, int orig_nu return fz_keep_buffer(xref->ctx, xref->table[num].stm_buf); dict = pdf_load_object(xref, num, gen); - /* RJW: "cannot load stream dictionary (%d %d R)", num, gen */ len = pdf_to_int(pdf_dict_gets(dict, "Length")); pdf_drop_obj(dict); stm = pdf_open_raw_renumbered_stream(xref, num, gen, orig_num, orig_gen); - /* RJW: "cannot open 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 buf; @@ -500,7 +494,6 @@ pdf_load_image_stream(pdf_document *xref, int num, int gen, int orig_num, int or return fz_keep_buffer(xref->ctx, xref->table[num].stm_buf); dict = pdf_load_object(xref, num, gen); - /* RJW: "cannot load stream dictionary (%d %d R)", num, gen */ len = pdf_to_int(pdf_dict_gets(dict, "Length")); obj = pdf_dict_gets(dict, "Filter"); @@ -512,7 +505,6 @@ pdf_load_image_stream(pdf_document *xref, int num, int gen, int orig_num, int or pdf_drop_obj(dict); stm = pdf_open_image_stream(xref, num, gen, orig_num, orig_gen, params); - /* RJW: "cannot open stream (%d %d R)", num, gen */ fz_try(ctx) { diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c index bd60216d..4fc7803e 100644 --- a/pdf/pdf_type3.c +++ b/pdf/pdf_type3.c @@ -87,9 +87,8 @@ pdf_load_type3_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) item = pdf_array_get(diff, i); if (pdf_is_int(item)) k = pdf_to_int(item); - if (pdf_is_name(item)) + if (pdf_is_name(item) && k >= 0 && k < nelem(estrings)) estrings[k++] = pdf_to_name(item); - k = fz_clampi(k, 0, 255); } } } @@ -163,8 +162,7 @@ pdf_load_type3_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict) fz_catch(ctx) { if (fontdesc) - fz_drop_font(ctx, fontdesc->font); - fz_free(ctx, fontdesc); + pdf_drop_font(ctx, fontdesc); fz_throw(ctx, "cannot load type3 font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict)); } return fontdesc; diff --git a/pdf/pdf_unicode.c b/pdf/pdf_unicode.c index c94a6683..a6e14d9b 100644 --- a/pdf/pdf_unicode.c +++ b/pdf/pdf_unicode.c @@ -17,7 +17,6 @@ pdf_load_to_unicode(pdf_document *xref, pdf_font_desc *font, if (pdf_is_stream(xref, pdf_to_num(cmapstm), pdf_to_gen(cmapstm))) { cmap = pdf_load_embedded_cmap(xref, cmapstm); - /* RJW: "cannot load embedded cmap (%d %d R)", pdf_to_num(cmapstm), pdf_to_gen(cmapstm) */ font->to_unicode = pdf_new_cmap(ctx); @@ -52,7 +51,6 @@ pdf_load_to_unicode(pdf_document *xref, pdf_font_desc *font, font->to_unicode = pdf_load_system_cmap(ctx, "Adobe-Korea1-UCS2"); return; - /* RJW: "cannot load ToUnicode system cmap %s-UCS2", collection */ } if (strings) diff --git a/pdf/pdf_write.c b/pdf/pdf_write.c index 9c5c5a53..5d03ffe3 100644 --- a/pdf/pdf_write.c +++ b/pdf/pdf_write.c @@ -3,6 +3,8 @@ /* #define DEBUG_LINEARIZATION */ /* #define DEBUG_HEAP_SORT */ +/* #define DEBUG_WRITING */ + typedef struct pdf_write_options_s pdf_write_options; @@ -128,10 +130,11 @@ page_objects_list_destroy(fz_context *ctx, page_objects_list *pol) static void page_objects_list_ensure(fz_context *ctx, page_objects_list **pol, int newcap) { - if (newcap <= (*pol)->cap) + int oldcap = (*pol)->cap; + if (newcap <= oldcap) return; - *pol = fz_resize_array(ctx, *pol, 1, sizeof(**pol) + (newcap-1)*sizeof(int)); - memset(&(*pol)->page[(*pol)->cap], 0, sizeof(page_objects *)*(newcap-(*pol)->cap)); + *pol = fz_resize_array(ctx, *pol, 1, sizeof(page_objects_list) + (newcap-1)*sizeof(page_objects *)); + memset(&(*pol)->page[oldcap], 0, (newcap-oldcap)*sizeof(page_objects *)); (*pol)->cap = newcap; } @@ -254,6 +257,7 @@ order_ge(int ui, int uj) * Catalogue (and other document level objects) * First page * (Primary Hint stream) (*) + * Any free objects * Note, this is NOT the same order they appear in * the final file! * @@ -264,7 +268,12 @@ order_ge(int ui, int uj) * first. */ if (((ui ^ uj) & ~USE_PAGE_OBJECT) == 0) return ((ui & USE_PAGE_OBJECT) == 0); - /* Put the hint stream last. */ + /* Put unused objects last */ + else if (ui == 0) + return 1; + else if (uj == 0) + return 0; + /* Put the hint stream before that... */ else if (ui & USE_HINTS) return 1; else if (uj & USE_HINTS) @@ -301,7 +310,7 @@ order_ge(int ui, int uj) } static void -heap_sort(int *list, int n, int *val, int (*ge)(int, int)) +heap_sort(int *list, int n, const int *val, int (*ge)(int, int)) { int i, j; @@ -731,12 +740,11 @@ static void renumberobjs(pdf_document *xref, pdf_write_options *opts) if (newlen < opts->renumber_map[num]) newlen = opts->renumber_map[num]; xref->table[opts->renumber_map[num]] = oldxref[num]; - new_use_list[opts->renumber_map[num]] = 1; + new_use_list[opts->renumber_map[num]] = opts->use_list[num]; } else { - if (oldxref[num].obj) - pdf_drop_obj(oldxref[num].obj); + pdf_drop_obj(oldxref[num].obj); } } } @@ -1266,6 +1274,14 @@ linearize(pdf_document *xref, pdf_write_options *opts) /* Add new objects required for linearization */ add_linearization_objs(xref, opts); +#ifdef DEBUG_WRITING + fprintf(stderr, "Usage calculated:\n"); + for (i=0; i < xref->len; i++) + { + fprintf(stderr, "%d: use=%d\n", i, opts->use_list[i]); + } +#endif + /* Allocate/init the structures used for renumbering the objects */ reorder = fz_calloc(ctx, n, sizeof(int)); rev_renumber_map = fz_calloc(ctx, n, sizeof(int)); @@ -1278,6 +1294,14 @@ linearize(pdf_document *xref, pdf_write_options *opts) /* Heap sort the reordering */ heap_sort(reorder+1, n-1, opts->use_list, &order_ge); +#ifdef DEBUG_WRITING + fprintf(stderr, "Reordered:\n"); + for (i=1; i < xref->len; i++) + { + fprintf(stderr, "%d: use=%d\n", i, opts->use_list[reorder[i]]); + } +#endif + /* Find the split point */ for (i = 1; (opts->use_list[reorder[i]] & USE_PARAMS) == 0; i++); opts->start = i; @@ -1305,18 +1329,21 @@ linearize(pdf_document *xref, pdf_write_options *opts) static void update_linearization_params(pdf_document *xref, pdf_write_options *opts) { + int offset; pdf_set_int(opts->linear_l, opts->file_len); /* Primary hint stream offset (of object, not stream!) */ pdf_set_int(opts->linear_h0, opts->ofs_list[xref->len-1]); /* Primary hint stream length (of object, not stream!) */ - pdf_set_int(opts->linear_h1, opts->ofs_list[1] - opts->ofs_list[xref->len-1] + opts->hintstream_len); + offset = (opts->start == 1 ? opts->main_xref_offset : opts->ofs_list[1] + opts->hintstream_len); + pdf_set_int(opts->linear_h1, offset - opts->ofs_list[xref->len-1]); /* Object number of first pages page object (the first object of page 0) */ pdf_set_int(opts->linear_o, opts->page_object_lists->page[0]->object[0]); /* Offset of end of first page (first page is followed by primary * hint stream (object n-1) then remaining pages (object 1...). The * primary hint stream counts as part of the first pages data, I think. */ - pdf_set_int(opts->linear_e, opts->ofs_list[1] + opts->hintstream_len); + offset = (opts->start == 1 ? opts->main_xref_offset : opts->ofs_list[1] + opts->hintstream_len); + pdf_set_int(opts->linear_e, offset); /* Number of pages in document */ pdf_set_int(opts->linear_n, opts->page_count); /* Offset of first entry in main xref table */ @@ -1435,10 +1462,8 @@ static void addhexfilter(pdf_document *xref, pdf_obj *dict) pdf_drop_obj(ahx); pdf_drop_obj(nullobj); - if (newf) - pdf_drop_obj(newf); - if (newdp) - pdf_drop_obj(newdp); + pdf_drop_obj(newf); + pdf_drop_obj(newdp); } static void copystream(pdf_document *xref, pdf_write_options *opts, pdf_obj *obj_orig, int num, int gen) @@ -1694,6 +1719,7 @@ padto(FILE *file, int target) { int pos = ftell(file); + assert(pos <= target); while (pos < target) { fputc('\n', file); @@ -1739,27 +1765,25 @@ writeobjects(pdf_document *xref, pdf_write_options *opts, int pass) { /* Write first xref */ if (pass == 0) - { opts->first_xref_offset = ftell(opts->out); - } else - { - int pos = ftell(opts->out); - while (pos < opts->first_xref_offset) - { - fputc('\n', opts->out); - pos++; - } - } + padto(opts->out, opts->first_xref_offset); writexref(xref, opts, opts->start, xref->len, 1, opts->main_xref_offset, 0); } for (num = opts->start+1; num < xref->len; num++) dowriteobject(xref, opts, num, pass); if (opts->do_linear && pass == 1) - padto(opts->out, opts->ofs_list[1] + opts->hintstream_len); + { + int offset = (opts->start == 1 ? opts->main_xref_offset : opts->ofs_list[1] + opts->hintstream_len); + padto(opts->out, offset); + } for (num = 1; num < opts->start; num++) + { + if (pass == 1) + opts->ofs_list[num] += opts->hintstream_len; dowriteobject(xref, opts, num, pass); + } } static int @@ -1798,17 +1822,17 @@ make_page_offset_hints(pdf_document *xref, pdf_write_options *opts, fz_buffer *b max_shared_object = 1; min_shared_length = opts->file_len; max_shared_length = 0; - for (i=0; i < xref->len; i++) + for (i=1; i < xref->len; i++) { int min, max, page; min = opts->ofs_list[i]; - if (i == opts->start-1) + if (i == opts->start-1 || (opts->start == 1 && i == xref->len-1)) max = opts->main_xref_offset; - else if (i < xref->len-1) - max = opts->ofs_list[i+1]; - else + else if (i == xref->len-1) max = opts->ofs_list[1]; + else + max = opts->ofs_list[i+1]; assert(max > min); @@ -2070,6 +2094,18 @@ make_hint_stream(pdf_document *xref, pdf_write_options *opts) } } +#ifdef DEBUG_WRITING +static void dump_object_details(pdf_document *xref, pdf_write_options *opts) +{ + int i; + + for (i = 0; i < xref->len; i++) + { + fprintf(stderr, "%d@%d: use=%d\n", i, opts->ofs_list[i], opts->use_list[i]); + } +} +#endif + void pdf_write_document(pdf_document *xref, char *filename, fz_write_options *fz_opts) { @@ -2129,11 +2165,11 @@ void pdf_write_document(pdf_document *xref, char *filename, fz_write_options *fz removeduplicateobjs(xref, &opts); /* Compact xref by renumbering and removing unused objects */ - if (opts.do_garbage >= 2) + if (opts.do_garbage >= 2 || opts.do_linear) compactxref(xref, &opts); /* Make renumbering affect all indirect references and update xref */ - if (opts.do_garbage >= 2) + if (opts.do_garbage >= 2 || opts.do_linear) renumberobjs(xref, &opts); if (opts.do_linear) @@ -2143,6 +2179,10 @@ void pdf_write_document(pdf_document *xref, char *filename, fz_write_options *fz writeobjects(xref, &opts, 0); +#ifdef DEBUG_WRITING + dump_object_details(xref, &opts); +#endif + /* Construct linked list of free object slots */ lastfree = 0; for (num = 0; num < xref->len; num++) @@ -2158,7 +2198,7 @@ void pdf_write_document(pdf_document *xref, char *filename, fz_write_options *fz if (opts.do_linear) { opts.main_xref_offset = ftell(opts.out); - writexref(xref, &opts, 0, xref->len, !opts.do_linear, 0, opts.first_xref_offset); + writexref(xref, &opts, 0, opts.start, 0, 0, opts.first_xref_offset); opts.file_len = ftell(opts.out); make_hint_stream(xref, &opts); @@ -2169,15 +2209,14 @@ void pdf_write_document(pdf_document *xref, char *filename, fz_write_options *fz writeobjects(xref, &opts, 1); padto(opts.out, opts.main_xref_offset); - + writexref(xref, &opts, 0, opts.start, 0, 0, opts.first_xref_offset); } else { opts.first_xref_offset = ftell(opts.out); + writexref(xref, &opts, 0, xref->len, 1, 0, opts.first_xref_offset); } - writexref(xref, &opts, 0, xref->len, !opts.do_linear, 0, opts.first_xref_offset); - xref->dirty = 0; } fz_always(ctx) diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c index 3777602d..afa86527 100644 --- a/pdf/pdf_xobject.c +++ b/pdf/pdf_xobject.c @@ -20,10 +20,8 @@ pdf_free_xobject_imp(fz_context *ctx, fz_storable *xobj_) if (xobj->colorspace) fz_drop_colorspace(ctx, xobj->colorspace); - if (xobj->resources) - pdf_drop_obj(xobj->resources); - if (xobj->contents) - pdf_drop_obj(xobj->contents); + pdf_drop_obj(xobj->resources); + pdf_drop_obj(xobj->contents); pdf_drop_obj(xobj->me); fz_free(ctx, xobj); } diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index f7350407..7c14265d 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -363,12 +363,10 @@ pdf_read_new_xref(pdf_document *xref, pdf_lexbuf *buf) index = pdf_dict_gets(trailer, "Index"); stm = pdf_open_stream_with_offset(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) { 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 { @@ -388,7 +386,6 @@ pdf_read_new_xref(pdf_document *xref, pdf_lexbuf *buf) fz_catch(ctx) { pdf_drop_obj(trailer); - pdf_drop_obj(index); fz_rethrow(ctx); } @@ -551,8 +548,7 @@ pdf_ocg_set_config(pdf_document *xref, int config) fz_throw(xref->ctx, "Illegal OCG config"); } - if (desc->intent) - pdf_drop_obj(desc->intent); + pdf_drop_obj(desc->intent); desc->intent = pdf_dict_gets(cobj, "Intent"); if (desc->intent) pdf_keep_obj(desc->intent); @@ -677,8 +673,7 @@ pdf_free_ocg(fz_context *ctx, pdf_ocg_descriptor *desc) if (!desc) return; - if (desc->intent) - pdf_drop_obj(desc->intent); + pdf_drop_obj(desc->intent); fz_free(ctx, desc->ocgs); fz_free(ctx, desc); } @@ -850,8 +845,7 @@ pdf_close_document(pdf_document *xref) pdf_drop_obj(xref->focus_obj); if (xref->file) fz_close(xref->file); - if (xref->trailer) - pdf_drop_obj(xref->trailer); + pdf_drop_obj(xref->trailer); if (xref->crypt) pdf_free_crypt(ctx, xref->crypt); @@ -940,7 +934,6 @@ pdf_load_obj_stm(pdf_document *xref, int num, int gen, pdf_lexbuf *buf) fz_seek(stm, first + ofsbuf[i], 0); obj = pdf_parse_stm_obj(xref, stm, buf); - /* RJW: Ensure above does fz_throw(ctx, "cannot parse object %d in stream (%d %d R)", i, num, gen); */ if (numbuf[i] < 1 || numbuf[i] >= xref->len) { @@ -1159,8 +1152,7 @@ pdf_update_object(pdf_document *xref, int num, pdf_obj *newobj) x = &xref->table[num]; - if (x->obj) - pdf_drop_obj(x->obj); + pdf_drop_obj(x->obj); x->type = 'n'; x->ofs = 0; @@ -1199,7 +1191,8 @@ pdf_meta(pdf_document *doc, int key, void *ptr, int size) return FZ_META_OK; case FZ_META_CRYPT_INFO: if (doc->crypt) - sprintf((char *)ptr, "Standard V%d %d-bit %s", + sprintf((char *)ptr, "Standard V%d R%d %d-bit %s", + pdf_crypt_version(doc), pdf_crypt_revision(doc), pdf_crypt_length(doc), pdf_crypt_method(doc)); |