summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2012-08-08 14:03:34 +0100
committerPaul Gardiner <paulg.artifex@glidos.net>2012-08-08 14:03:34 +0100
commit274ab2d66943bb891976ef712a816e7d128eff22 (patch)
treebee912b4426f3dfe4acc176a57fd5b55db58d53c /pdf
parent51661f29a5f229f30ae16e16bd0ef6396cd001af (diff)
parent511ea75a53db6e72334438bcda2ce774c7d72d1e (diff)
downloadmupdf-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.h1
-rw-r--r--pdf/pdf_annot.c3
-rw-r--r--pdf/pdf_cmap.c8
-rw-r--r--pdf/pdf_cmap_parse.c19
-rw-r--r--pdf/pdf_colorspace.c4
-rw-r--r--pdf/pdf_crypt.c13
-rw-r--r--pdf/pdf_font.c11
-rw-r--r--pdf/pdf_function.c38
-rw-r--r--pdf/pdf_image.c13
-rw-r--r--pdf/pdf_interpret.c113
-rw-r--r--pdf/pdf_object.c12
-rw-r--r--pdf/pdf_outline.c8
-rw-r--r--pdf/pdf_page.c20
-rw-r--r--pdf/pdf_parse.c10
-rw-r--r--pdf/pdf_repair.c78
-rw-r--r--pdf/pdf_shade.c3
-rw-r--r--pdf/pdf_stream.c18
-rw-r--r--pdf/pdf_type3.c6
-rw-r--r--pdf/pdf_unicode.c2
-rw-r--r--pdf/pdf_write.c111
-rw-r--r--pdf/pdf_xobject.c6
-rw-r--r--pdf/pdf_xref.c19
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));