summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/pdftool.c34
-rw-r--r--base/base_error.c118
-rw-r--r--base/base_hash.c26
-rw-r--r--base/base_memory.c38
-rw-r--r--base/base_rune.c42
-rw-r--r--include/fitz/base_runtime.h35
-rw-r--r--include/fitz/stm_filter.h4
-rw-r--r--include/fitz/stm_object.h2
-rw-r--r--include/fitz/stm_stream.h62
-rw-r--r--include/fitz/wld_path.h3
-rw-r--r--include/mupdf/syntax.h10
-rw-r--r--include/mupdf/xref.h2
-rw-r--r--mupdf/pdf_annot.c4
-rw-r--r--mupdf/pdf_build.c427
-rw-r--r--mupdf/pdf_cmap.c343
-rw-r--r--mupdf/pdf_colorspace1.c4
-rw-r--r--mupdf/pdf_colorspace2.c4
-rw-r--r--mupdf/pdf_crypt.c54
-rw-r--r--mupdf/pdf_debug.c4
-rw-r--r--mupdf/pdf_doctor.c62
-rw-r--r--mupdf/pdf_font.c60
-rw-r--r--mupdf/pdf_fontagl.c97
-rw-r--r--mupdf/pdf_fontenc.c4
-rw-r--r--mupdf/pdf_fontfile.c49
-rw-r--r--mupdf/pdf_fontfilems.c8
-rw-r--r--mupdf/pdf_function.c610
-rw-r--r--mupdf/pdf_image.c20
-rw-r--r--mupdf/pdf_interpret.c324
-rw-r--r--mupdf/pdf_lex.c126
-rw-r--r--mupdf/pdf_open.c311
-rw-r--r--mupdf/pdf_page.c133
-rw-r--r--mupdf/pdf_pagetree.c36
-rw-r--r--mupdf/pdf_parse.c212
-rw-r--r--mupdf/pdf_pattern.c53
-rw-r--r--mupdf/pdf_repair.c117
-rw-r--r--mupdf/pdf_resources.c138
-rw-r--r--mupdf/pdf_save.c69
-rw-r--r--mupdf/pdf_shade.c6
-rw-r--r--mupdf/pdf_shade1.c1
-rw-r--r--mupdf/pdf_store.c41
-rw-r--r--mupdf/pdf_stream.c199
-rw-r--r--mupdf/pdf_type3.c43
-rw-r--r--mupdf/pdf_xobject.c26
-rw-r--r--mupdf/pdf_xref.c100
-rw-r--r--stream/crypt_arc4.c12
-rw-r--r--stream/crypt_md5.c12
-rw-r--r--stream/filt_a85d.c8
-rw-r--r--stream/filt_a85e.c2
-rw-r--r--stream/filt_ahxd.c4
-rw-r--r--stream/filt_ahxe.c2
-rw-r--r--stream/filt_arc4.c2
-rw-r--r--stream/filt_dctc.h2
-rw-r--r--stream/filt_dctd.c11
-rw-r--r--stream/filt_dcte.c24
-rw-r--r--stream/filt_faxd.c43
-rw-r--r--stream/filt_faxe.c21
-rw-r--r--stream/filt_flate.c12
-rw-r--r--stream/filt_jbig2d.c4
-rw-r--r--stream/filt_jpxd.c17
-rw-r--r--stream/filt_lzwd.c4
-rw-r--r--stream/filt_lzwe.c2
-rw-r--r--stream/filt_null.c7
-rw-r--r--stream/filt_pipeline.c20
-rw-r--r--stream/filt_predict.c41
-rw-r--r--stream/filt_rld.c2
-rw-r--r--stream/filt_rle.c2
-rw-r--r--stream/obj_array.c107
-rw-r--r--stream/obj_dict.c104
-rw-r--r--stream/obj_parse.c180
-rw-r--r--stream/obj_simple.c54
-rw-r--r--stream/stm_buffer.c31
-rw-r--r--stream/stm_filter.c10
-rw-r--r--stream/stm_misc.c41
-rw-r--r--stream/stm_open.c86
-rw-r--r--stream/stm_read.c209
-rw-r--r--stream/stm_write.c169
-rw-r--r--world/node_optimize.c2
-rw-r--r--world/node_path.c47
-rw-r--r--world/node_toxml.c30
79 files changed, 3322 insertions, 2063 deletions
diff --git a/apps/pdftool.c b/apps/pdftool.c
index ce0380ee..b086eec0 100644
--- a/apps/pdftool.c
+++ b/apps/pdftool.c
@@ -27,10 +27,10 @@ pdf_pagetree *srcpages = nil;
void die(fz_error *eo)
{
- fflush(stdout);
- fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
- fflush(stderr);
- abort();
+ fflush(stdout);
+ fz_printerror(eo);
+ fflush(stderr);
+ abort();
}
void closesrc(void)
@@ -70,6 +70,7 @@ void opensrc(char *filename, char *password, int loadpages)
error = pdf_loadxref(src, filename);
if (error)
{
+ fz_printerror(error);
fz_warn("trying to repair");
error = pdf_repairxref(src, filename);
if (error)
@@ -82,9 +83,9 @@ void opensrc(char *filename, char *password, int loadpages)
if (src->crypt)
{
- error = pdf_setpassword(src->crypt, password);
- if (error)
- die(error);
+ int okay = pdf_setpassword(src->crypt, password);
+ if (!okay)
+ die(fz_throw("invalid password"));
}
if (loadpages)
@@ -188,12 +189,11 @@ void showstream(int num, int gen)
while (1)
{
- n = fz_read(stm, buf, sizeof buf);
+ error = fz_read(&n, stm, buf, sizeof buf);
+ if (error)
+ die (error);
if (n == 0)
break;
- if (n < 0)
- die(fz_ioerror(stm));
-
if (showbinary)
fwrite(buf, 1, n, stdout);
else
@@ -243,8 +243,8 @@ showmain(int argc, char **argv)
case 'b': showbinary ++; break;
case 'd': showdecode ++; break;
default:
- showusage();
- break;
+ showusage();
+ break;
}
}
@@ -459,7 +459,7 @@ void
drawusage(void)
{
fprintf(stderr,
- "usage: pdftool draw [options] [file.pdf pages ... ]\n"
+ "usage: pdftool draw [options] [file.pdf pages ... ]\n"
" -b -\tdraw page in N bands\n"
" -d -\tpassword for decryption\n"
" -o -\tpattern (%%d for page number) for output file\n"
@@ -468,7 +468,7 @@ drawusage(void)
" -x \txml dump of display tree\n"
" -m \tprint benchmark results\n"
" example:\n"
- " pdftool draw -o out%%0.3d.pnm a.pdf 1-3,5,9-\n");
+ " pdftool draw -o out%%03d.pnm a.pdf 1-3,5,9-\n");
exit(1);
}
@@ -772,8 +772,8 @@ drawmain(int argc, char **argv)
case 'x': drawmode = DRAWXML; break;
case 'm': benchmark = 1; break;
default:
- drawusage();
- break;
+ drawusage();
+ break;
}
}
diff --git a/base/base_error.c b/base/base_error.c
index e0bf1567..fa1c9878 100644
--- a/base/base_error.c
+++ b/base/base_error.c
@@ -1,74 +1,88 @@
#include "fitz-base.h"
-void
-fz_warn(char *fmt, ...)
+fz_error *
+fz_keeperror(fz_error *eo)
{
- va_list ap;
- fprintf(stderr, "warning: ");
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
+ eo->refs++;
+ return eo;
}
-fz_error *
-fz_throw1(char *fmt, ...)
+void
+fz_droperror(fz_error *eo)
{
- va_list ap;
- fz_error *eo;
+ if (eo->refs > 0)
+ eo->refs--;
+ if (eo->refs == 0)
+ {
+ if (eo->cause)
+ fz_droperror(eo->cause);
+ fz_free(eo);
+ }
+}
- eo = fz_malloc(sizeof(fz_error));
- if (!eo) return fz_outofmem;
+void
+fz_printerror(fz_error *eo)
+{
+#if 1
+ if (eo->cause)
+ {
+ fz_printerror(eo->cause);
+ fprintf(stderr, "| %s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
+ }
+ else
+ {
+ fprintf(stderr, "+ %s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
+ }
+#else
+ fprintf(stderr, "+ %s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
+ eo = eo->cause;
- eo->refs = 1;
- strlcpy(eo->func, "unknown", sizeof eo->func);
- strlcpy(eo->file, "unknown", sizeof eo->file);
- eo->line = 0;
+ while (eo)
+ {
+ fprintf(stderr, "| %s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
+ eo = eo->cause;
+ }
+#endif
+}
- va_start(ap, fmt);
- vsnprintf(eo->msg, sizeof eo->msg, fmt, ap);
- eo->msg[sizeof(eo->msg) - 1] = '\0';
- va_end(ap);
- return eo;
+void
+fz_warn(char *fmt, ...)
+{
+ va_list ap;
+ fprintf(stderr, "warning: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
}
fz_error *
-fz_throw0(const char *func, const char *file, int line, char *fmt, ...)
+fz_throwimp(fz_error *cause, const char *func, const char *file, int line, char *fmt, ...)
{
- va_list ap;
- fz_error *eo;
+ va_list ap;
+ fz_error *eo;
- eo = fz_malloc(sizeof(fz_error));
- if (!eo) return fz_outofmem;
+ eo = fz_malloc(sizeof(fz_error));
+ if (!eo)
+ return fz_outofmem; /* oops. we're *really* out of memory here. */
- eo->refs = 1;
- strlcpy(eo->func, func, sizeof eo->func);
- strlcpy(eo->file, file, sizeof eo->file);
- eo->line = line;
+ eo->refs = 1;
- va_start(ap, fmt);
- vsnprintf(eo->msg, sizeof eo->msg, fmt, ap);
- eo->msg[sizeof(eo->msg) - 1] = '\0';
- va_end(ap);
+ va_start(ap, fmt);
+ vsnprintf(eo->msg, sizeof eo->msg, fmt, ap);
+ eo->msg[sizeof(eo->msg) - 1] = '\0';
+ va_end(ap);
- if (getenv("BOMB"))
- {
- fflush(stdout);
- fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
- fflush(stderr);
- abort();
- }
+ strlcpy(eo->func, func, sizeof eo->func);
+ strlcpy(eo->file, file, sizeof eo->file);
+ eo->line = line;
- return eo;
-}
+ if (cause)
+ eo->cause = fz_keeperror(cause);
+ else
+ eo->cause = nil;
-void
-fz_droperror(fz_error *eo)
-{
- if (eo->refs > 0)
- eo->refs--;
- if (eo->refs == 0)
- fz_free(eo);
+ return eo;
}
diff --git a/base/base_hash.c b/base/base_hash.c
index dedd1c5e..b43ee611 100644
--- a/base/base_hash.c
+++ b/base/base_hash.c
@@ -54,7 +54,7 @@ fz_newhash(fz_hashtable **tablep, int initialsize, int keylen)
table = *tablep = fz_malloc(sizeof(fz_hashtable));
if (!table)
- return fz_outofmem;
+ return fz_throw("outofmem: hash table struct");
table->keylen = keylen;
table->size = initialsize;
@@ -65,12 +65,12 @@ fz_newhash(fz_hashtable **tablep, int initialsize, int keylen)
{
fz_free(table);
*tablep = nil;
- return fz_outofmem;
+ return fz_throw("outofmem: hash table entries (size=%d)", initialsize);
}
memset(table->ents, 0, sizeof(fz_hashentry) * table->size);
- return nil;
+ return fz_okay;
}
void
@@ -120,11 +120,11 @@ fz_resizehash(fz_hashtable *table, int newsize)
oldents = table->ents;
if (newsize < oldload * 8 / 10)
- return fz_throw("rangecheck: resize hash too small");
+ return fz_throw("assert: resize hash too small");
newents = fz_malloc(sizeof(fz_hashentry) * newsize);
if (!newents)
- return fz_outofmem;
+ return fz_throw("outofmem: hash table (size=%d)", newsize);
table->size = newsize;
table->load = 0;
@@ -142,13 +142,14 @@ fz_resizehash(fz_hashtable *table, int newsize)
table->load = oldload;
table->ents = oldents;
fz_free(newents);
- return error;
+ return fz_rethrow(error, "cannot re-insert old entries");
}
}
}
fz_free(oldents);
- return nil;
+
+ return fz_okay;
}
void *
@@ -182,7 +183,7 @@ fz_hashinsert(fz_hashtable *table, void *key, void *val)
{
error = fz_resizehash(table, table->size * 2);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resize hash table");
}
ents = table->ents;
@@ -200,12 +201,12 @@ fz_hashinsert(fz_hashtable *table, void *key, void *val)
}
if (memcmp(key, &ents[pos].key, table->keylen) == 0)
- return fz_throw("rangecheck: overwrite hash slot");
+ return fz_throw("assert: overwrite hash slot");
pos = (pos + 1) % size;
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -219,7 +220,7 @@ fz_hashremove(fz_hashtable *table, void *key)
while (1)
{
if (!ents[pos].val)
- return fz_throw("rangecheck: remove inexistant hash entry");
+ return fz_throw("assert: remove inexistant hash entry");
if (memcmp(key, &ents[pos].key, table->keylen) == 0)
{
@@ -244,7 +245,8 @@ fz_hashremove(fz_hashtable *table, void *key)
}
table->load --;
- return nil;
+
+ return fz_okay;
}
pos = (pos + 1) % size;
diff --git a/base/base_memory.c b/base/base_memory.c
index a14a3122..1fa918c2 100644
--- a/base/base_memory.c
+++ b/base/base_memory.c
@@ -4,30 +4,12 @@
static void *stdmalloc(fz_memorycontext *mem, int n)
{
-#if 0
- void *p = malloc(n);
- if (!p)
- fprintf(stderr, "failed to malloc %d bytes\n", n);
- return p;
-#else
return malloc(n);
-#endif
}
static void *stdrealloc(fz_memorycontext *mem, void *p, int n)
{
-#if 0
- void *np = realloc(p, n);
- if (np == nil)
- fprintf(stderr, "realloc failed %d nytes", n);
- else if (np == p)
- fprintf(stderr, "realloc kept %d\n", n);
- else
- fprintf(stderr, "realloc moved %d\n", n);
- return np;
-#else
return realloc(p, n);
-#endif
}
static void stdfree(fz_memorycontext *mem, void *p)
@@ -41,9 +23,9 @@ static fz_memorycontext *curmem = &defmem;
fz_error fz_koutofmem = {
-1,
{"out of memory"},
- {"<malloc>"},
- {"memory.c"},
- 0
+ {"<internal>"},
+ {"<internal>"},
+ 0, 0
};
fz_memorycontext *
@@ -61,15 +43,21 @@ fz_setmemorycontext(fz_memorycontext *mem)
void *
fz_malloc(int n)
{
- fz_memorycontext *mem = fz_currentmemorycontext();
- return mem->malloc(mem, n);
+ fz_memorycontext *mem = fz_currentmemorycontext();
+ void *p = mem->malloc(mem, n);
+ if (!p)
+ fz_warn("cannot malloc %d bytes", n);
+ return p;
}
void *
fz_realloc(void *p, int n)
{
- fz_memorycontext *mem = fz_currentmemorycontext();
- return mem->realloc(mem, p, n);
+ fz_memorycontext *mem = fz_currentmemorycontext();
+ void *np = mem->realloc(mem, p, n);
+ if (np == nil)
+ fz_warn("cannot realloc %d bytes", n);
+ return np;
}
void
diff --git a/base/base_rune.c b/base/base_rune.c
index 4aa81df3..32168792 100644
--- a/base/base_rune.c
+++ b/base/base_rune.c
@@ -41,7 +41,8 @@ chartorune(int *rune, char *str)
* 00000-0007F => T1
*/
c = *(unsigned char*)str;
- if(c < Tx) {
+ if (c < Tx)
+ {
*rune = c;
return 1;
}
@@ -51,13 +52,14 @@ chartorune(int *rune, char *str)
* 0080-07FF => T2 Tx
*/
c1 = *(unsigned char*)(str+1) ^ Tx;
- if(c1 & Testx)
+ if (c1 & Testx)
goto bad;
- if(c < T3) {
- if(c < T2)
+ if (c < T3)
+ {
+ if (c < T2)
goto bad;
l = ((c << Bitx) | c1) & Rune2;
- if(l <= Rune1)
+ if (l <= Rune1)
goto bad;
*rune = l;
return 2;
@@ -68,11 +70,12 @@ chartorune(int *rune, char *str)
* 0800-FFFF => T3 Tx Tx
*/
c2 = *(unsigned char*)(str+2) ^ Tx;
- if(c2 & Testx)
+ if (c2 & Testx)
goto bad;
- if(c < T4) {
+ if (c < T4)
+ {
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
- if(l <= Rune2)
+ if (l <= Rune2)
goto bad;
*rune = l;
return 3;
@@ -96,7 +99,8 @@ runetochar(char *str, int *rune)
* 00000-0007F => 00-7F
*/
c = *rune;
- if(c <= Rune1) {
+ if (c <= Rune1)
+ {
str[0] = c;
return 1;
}
@@ -105,7 +109,8 @@ runetochar(char *str, int *rune)
* two character sequence
* 0080-07FF => T2 Tx
*/
- if(c <= Rune2) {
+ if (c <= Rune2)
+ {
str[0] = T2 | (c >> 1*Bitx);
str[1] = Tx | (c & Maskx);
return 2;
@@ -137,12 +142,12 @@ runenlen(int *r, int nrune)
int nb, c;
nb = 0;
- while(nrune--) {
+ while (nrune--)
+ {
c = *r++;
- if(c <= Rune1)
+ if (c <= Rune1)
nb++;
- else
- if(c <= Rune2)
+ else if (c <= Rune2)
nb += 2;
else
nb += 3;
@@ -155,12 +160,13 @@ fullrune(char *str, int n)
{
int c;
- if(n > 0) {
+ if (n > 0)
+ {
c = *(unsigned char*)str;
- if(c < Tx)
+ if (c < Tx)
return 1;
- if(n > 1)
- if(c < T3 || n > 2)
+ if (n > 1)
+ if (c < T3 || n > 2)
return 1;
}
return 0;
diff --git a/include/fitz/base_runtime.h b/include/fitz/base_runtime.h
index 717b22e9..274b2903 100644
--- a/include/fitz/base_runtime.h
+++ b/include/fitz/base_runtime.h
@@ -1,3 +1,17 @@
+/*
+ * Base Fitz runtime.
+ * Contains: errors, memory manager, utf-8 strings, "standard" macros
+ */
+
+#ifndef __printflike
+#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+#define __printflike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#else
+#define __printflike(fmtarg, firstvararg)
+#endif
+#endif
+
#undef nil
#define nil ((void*)0)
@@ -41,23 +55,22 @@ struct fz_error_s
char file[32];
char func[32];
int line;
+ fz_error *cause;
};
#define fz_outofmem (&fz_koutofmem)
extern fz_error fz_koutofmem;
-#ifdef WIN32
-#define fz_throw(...) fz_throw0(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
-#elif HAVE_C99
-#define fz_throw(...) fz_throw0(__func__, __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define fz_throw fz_throw1
-#endif
-fz_error *fz_throw0(const char *func, const char *file, int line, char *fmt, ...);
-fz_error *fz_throw1(char *fmt, ...);
-
-void fz_warn(char *fmt, ...);
+void fz_printerror(fz_error *eo);
+fz_error *fz_keeperror(fz_error *eo);
void fz_droperror(fz_error *eo);
+void fz_warn(char *fmt, ...) __printflike(1,2);
+
+#define fz_throw(...) fz_throwimp(nil, __func__, __FILE__, __LINE__, __VA_ARGS__)
+#define fz_rethrow(cause, ...) fz_throwimp(cause, __func__, __FILE__, __LINE__, __VA_ARGS__)
+#define fz_okay ((fz_error*)0)
+
+fz_error *fz_throwimp(fz_error *cause, const char *func, const char *file, int line, char *fmt, ...) __printflike(5, 6);
typedef struct fz_memorycontext_s fz_memorycontext;
diff --git a/include/fitz/stm_filter.h b/include/fitz/stm_filter.h
index f8902f98..b707838f 100644
--- a/include/fitz/stm_filter.h
+++ b/include/fitz/stm_filter.h
@@ -37,12 +37,12 @@ extern fz_error fz_kiodone;
* Evil looking macro to create an initialize a filter struct.
*/
-#define FZ_NEWFILTER(TYPE,VAR,NAME) \
+#define FZ_NEWFILTER(TYPE,VAR,NAME) \
fz_error * fz_process ## NAME (fz_filter*,fz_buffer*,fz_buffer*); \
void fz_drop ## NAME (fz_filter*); \
TYPE *VAR; \
*fp = fz_malloc(sizeof(TYPE)); \
- if (!*fp) return fz_outofmem; \
+ if (!*fp) return fz_throw("outofmem: %s filter struct", #NAME); \
(*fp)->refs = 1; \
(*fp)->process = fz_process ## NAME ; \
(*fp)->drop = fz_drop ## NAME ; \
diff --git a/include/fitz/stm_object.h b/include/fitz/stm_object.h
index fe9c12e5..74a8e1cf 100644
--- a/include/fitz/stm_object.h
+++ b/include/fitz/stm_object.h
@@ -130,3 +130,5 @@ fz_error *fz_parseobj(fz_obj **objp, char *s);
fz_error *fz_packobj(fz_obj **objp, char *fmt, ...);
fz_error *fz_unpackobj(fz_obj *obj, char *fmt, ...);
+char *fz_objkindstr(fz_obj *obj);
+
diff --git a/include/fitz/stm_stream.h b/include/fitz/stm_stream.h
index d2ac7c94..62eb8515 100644
--- a/include/fitz/stm_stream.h
+++ b/include/fitz/stm_stream.h
@@ -17,7 +17,7 @@ struct fz_stream_s
fz_buffer *buffer;
fz_filter *filter;
fz_stream *chain;
- fz_error *error;
+ fz_error *error; /* delayed error from readbyte and peekbyte */
int file;
};
@@ -31,7 +31,7 @@ fz_error *fz_openwfile(fz_stream **stmp, char *filename);
fz_error *fz_openafile(fz_stream **stmp, char *filename);
/* write to memory buffers! */
-fz_error * fz_openrmemory(fz_stream **stmp, unsigned char *mem, int len);
+fz_error *fz_openrmemory(fz_stream **stmp, char *mem, int len);
fz_error *fz_openrbuffer(fz_stream **stmp, fz_buffer *buf);
fz_error *fz_openwbuffer(fz_stream **stmp, fz_buffer *buf);
@@ -43,61 +43,71 @@ fz_error *fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *chain);
* Functions that are common to both input and output streams.
*/
-fz_error *fz_ioerror(fz_stream *stm);
-
fz_stream *fz_keepstream(fz_stream *stm);
void fz_dropstream(fz_stream *stm);
int fz_tell(fz_stream *stm);
-int fz_seek(fz_stream *stm, int offset, int whence);
+fz_error * fz_seek(fz_stream *stm, int offset, int whence);
/*
* Input stream functions.
- * Return EOF (-1) on errors.
*/
int fz_rtell(fz_stream *stm);
-int fz_rseek(fz_stream *stm, int offset, int whence);
+fz_error * fz_rseek(fz_stream *stm, int offset, int whence);
-int fz_makedata(fz_stream *stm);
-int fz_read(fz_stream *stm, unsigned char *buf, int len);
+fz_error * fz_readimp(fz_stream *stm);
+fz_error * fz_read(int *np, fz_stream *stm, unsigned char *buf, int len);
+fz_error * fz_readall(fz_buffer **bufp, fz_stream *stm);
+fz_error * fz_readline(fz_stream *stm, char *buf, int max);
-int fz_readall(fz_buffer **bufp, fz_stream *stm);
-int fz_readline(fz_stream *stm, char *buf, int max);
+/*
+ * Error handling when reading with readbyte/peekbyte is non-standard.
+ * The cause of an error is stuck into the stream struct,
+ * and EOF is returned. Not good, but any other way is too painful.
+ * So we have to be careful to check the error status eventually.
+ */
+fz_error *fz_readerror(fz_stream *stm);
int fz_readbytex(fz_stream *stm);
int fz_peekbytex(fz_stream *stm);
#ifdef DEBUG
+
#define fz_readbyte fz_readbytex
#define fz_peekbyte fz_peekbytex
+
#else
-#define FZ_READBYTE(XXX) { \
- fz_buffer *buf = stm->buffer; \
- if (buf->rp == buf->wp) \
- if (fz_makedata(stm) < 0) \
- return EOF; \
- return buf->rp < buf->wp ? XXX : EOF ; \
+static inline int fz_readbyte(fz_stream *stm)
+{
+ fz_buffer *buf = stm->buffer;
+ if (buf->rp < buf->wp)
+ return *buf->rp++;
+ return fz_readbytex(stm);
}
-static inline int fz_readbyte(fz_stream *stm) FZ_READBYTE(*buf->rp++)
-static inline int fz_peekbyte(fz_stream *stm) FZ_READBYTE(*buf->rp)
+static inline int fz_peekbyte(fz_stream *stm)
+{
+ fz_buffer *buf = stm->buffer;
+ if (buf->rp < buf->wp)
+ return *buf->rp;
+ return fz_peekbytex(stm);
+}
#endif
/*
* Output stream functions.
- * Return N or 0 on success, -1 on failure.
*/
int fz_wtell(fz_stream *stm);
-int fz_wseek(fz_stream *stm, int offset, int whence);
+fz_error * fz_wseek(fz_stream *stm, int offset, int whence);
-int fz_write(fz_stream *stm, unsigned char *buf, int n);
-int fz_flush(fz_stream *stm);
+fz_error * fz_write(fz_stream *stm, unsigned char *buf, int n);
+fz_error * fz_flush(fz_stream *stm);
-int fz_printstr(fz_stream *stm, char *s);
-int fz_printobj(fz_stream *stm, fz_obj *obj, int tight);
-int fz_print(fz_stream *stm, char *fmt, ...);
+fz_error * fz_printstr(fz_stream *stm, char *s);
+fz_error * fz_printobj(fz_stream *stm, fz_obj *obj, int tight);
+fz_error * fz_print(fz_stream *stm, char *fmt, ...);
diff --git a/include/fitz/wld_path.h b/include/fitz/wld_path.h
index 6a7c55b7..74f04fc2 100644
--- a/include/fitz/wld_path.h
+++ b/include/fitz/wld_path.h
@@ -76,7 +76,8 @@ fz_error *fz_closepath(fz_pathnode*);
fz_error *fz_endpath(fz_pathnode*, fz_pathkind paint, fz_stroke *stroke, fz_dash *dash);
fz_rect fz_boundpathnode(fz_pathnode *node, fz_matrix ctm);
-void fz_debugpathnode(fz_pathnode *node);
+void fz_debugpathnode(fz_pathnode *node, int indent);
+void fz_printpathnode(fz_pathnode *node, int indent);
fz_error *fz_newdash(fz_dash **dashp, float phase, int len, float *array);
void fz_dropdash(fz_dash *dash);
diff --git a/include/mupdf/syntax.h b/include/mupdf/syntax.h
index d5598cd5..f9602c35 100644
--- a/include/mupdf/syntax.h
+++ b/include/mupdf/syntax.h
@@ -17,7 +17,7 @@ enum
};
/* lex.c */
-int pdf_lex(fz_stream *f, unsigned char *buf, int n, int *len);
+fz_error *pdf_lex(int *token, fz_stream *f, unsigned char *buf, int n, int *len);
/* parse.c */
fz_error *pdf_parsearray(fz_obj **op, fz_stream *f, char *buf, int cap);
@@ -54,9 +54,11 @@ struct pdf_crypt_s
/* crypt.c */
fz_error *pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id);
fz_error *pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj *id);
-fz_error *pdf_setpassword(pdf_crypt *crypt, char *pw);
-fz_error *pdf_setuserpassword(pdf_crypt *crypt, char *pw, int pwlen);
-fz_error *pdf_setownerpassword(pdf_crypt *crypt, char *pw, int pwlen);
+
+int pdf_setpassword(pdf_crypt *crypt, char *pw);
+int pdf_setuserpassword(pdf_crypt *crypt, char *pw, int pwlen);
+int pdf_setownerpassword(pdf_crypt *crypt, char *pw, int pwlen);
+
fz_error *pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid);
void pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid);
void pdf_dropcrypt(pdf_crypt *crypt);
diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h
index 3143719d..23b7e135 100644
--- a/include/mupdf/xref.h
+++ b/include/mupdf/xref.h
@@ -8,7 +8,7 @@ typedef struct pdf_xref_s pdf_xref;
struct pdf_xref_s
{
fz_stream *file;
- float version;
+ int version;
int startxref;
pdf_crypt *crypt;
diff --git a/mupdf/pdf_annot.c b/mupdf/pdf_annot.c
index da4dbe80..a2839f6e 100644
--- a/mupdf/pdf_annot.c
+++ b/mupdf/pdf_annot.c
@@ -90,8 +90,8 @@ pdf_loadlink(pdf_link **linkp, pdf_xref *xref, fz_obj *dict)
{
bbox = pdf_torect(obj);
pdf_logpage("rect [%g %g %g %g]\n",
- bbox.x0, bbox.y0,
- bbox.x1, bbox.y1);
+ bbox.x0, bbox.y0,
+ bbox.x1, bbox.y1);
}
else
bbox = fz_emptyrect;
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 2e58246c..55e33fa1 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
void
pdf_initgstate(pdf_gstate *gs)
@@ -49,7 +49,7 @@ pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs)
error = pdf_flushtext(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot finish text node (state change)");
mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
@@ -73,7 +73,7 @@ pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs)
if (!strcmp(cs->name, "Lab"))
mat->kind = PDF_MLAB;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -87,7 +87,7 @@ pdf_setcolor(pdf_csi *csi, int what, float *v)
error = pdf_flushtext(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot finish text node (state change)");
mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
@@ -121,10 +121,10 @@ Lindexed:
break;
default:
- return fz_throw("syntaxerror: color not compatible with material");
+ return fz_throw("color incompatible with material");
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -136,7 +136,7 @@ pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v)
error = pdf_flushtext(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot finish text node (state change)");
mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
@@ -150,9 +150,13 @@ pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v)
mat->pattern = nil;
if (v)
- return pdf_setcolor(csi, what, v);
+ {
+ error = pdf_setcolor(csi, what, v);
+ if (error)
+ return fz_rethrow(error, "cannot set color");
+ }
- return nil;
+ return fz_okay;
}
fz_error *
@@ -164,7 +168,7 @@ pdf_setshade(pdf_csi *csi, int what, fz_shade *shade)
error = pdf_flushtext(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot finish text node (state change)");
mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
@@ -174,7 +178,7 @@ pdf_setshade(pdf_csi *csi, int what, fz_shade *shade)
mat->kind = PDF_MSHADE;
mat->shade = fz_keepshade(shade);
- return nil;
+ return fz_okay;
}
fz_error *
@@ -193,44 +197,54 @@ pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path)
{
error = fz_newdash(&dash, gs->dashphase, gs->dashlen, gs->dashlist);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create dash pattern");
}
else
dash = nil;
error = fz_endpath(path, FZ_STROKE, &stroke, dash);
- if (error) {
+ if (error)
+ {
fz_dropdash(dash);
- return error;
+ return fz_rethrow(error, "cannot finish path node");
}
- return nil;
+ return fz_okay;
}
fz_error *
pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int eofill)
{
- return fz_endpath(path, eofill ? FZ_EOFILL : FZ_FILL, nil, nil);
+ fz_error *error;
+ error = fz_endpath(path, eofill ? FZ_EOFILL : FZ_FILL, nil, nil);
+ if (error)
+ return fz_rethrow(error, "cannot finish path node");
+ return fz_okay;
}
static fz_error *
-addcolorshape(pdf_gstate *gs, fz_node *shape, float alpha, fz_colorspace *cs, float *v)
+addcolorshape(pdf_gstate *gs, fz_node *shape, fz_colorspace *cs, float *v)
{
fz_error *error;
fz_node *mask;
fz_node *solid;
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create mask node");
- error = fz_newsolidnode(&solid, alpha, cs, cs->n, v);
- if (error) return error;
+ error = fz_newsolidnode(&solid, 1.0, cs, cs->n, v);
+ if (error)
+ {
+ fz_dropnode(mask);
+ return fz_rethrow(error, "cannot create color node");
+ }
fz_insertnodelast(mask, shape);
fz_insertnodelast(mask, solid);
fz_insertnodelast(gs->head, mask);
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -241,18 +255,29 @@ addinvisibleshape(pdf_gstate *gs, fz_node *shape)
fz_pathnode *path;
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create mask node");
error = fz_newpathnode(&path);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(mask);
+ return fz_rethrow(error, "cannot create path node");
+ }
+
error = fz_endpath(path, FZ_FILL, nil, nil);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(mask);
+ fz_dropnode((fz_node*)path);
+ return fz_rethrow(error, "cannot finish path node");
+ }
fz_insertnodelast(mask, (fz_node*)path);
fz_insertnodelast(mask, shape);
fz_insertnodelast(gs->head, mask);
- return nil;
+ return fz_okay;
}
static fz_matrix getmatrix(fz_node *node)
@@ -271,19 +296,17 @@ static fz_matrix getmatrix(fz_node *node)
static fz_error *
addpatternshape(pdf_gstate *gs, fz_node *shape,
- pdf_pattern *pat, fz_colorspace *cs, float *v)
+ pdf_pattern *pat, fz_colorspace *cs, float *v)
{
fz_error *error;
fz_node *xform;
fz_node *over;
fz_node *mask;
- fz_node *meta;
fz_node *link;
fz_matrix ctm;
fz_matrix inv;
fz_matrix ptm;
fz_rect bbox;
- fz_obj *dict;
int x, y, x0, y0, x1, y1;
/* patterns are painted in user space */
@@ -291,30 +314,32 @@ addpatternshape(pdf_gstate *gs, fz_node *shape,
inv = fz_invertmatrix(ctm);
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create mask node");
ptm = fz_concat(pat->matrix, fz_invertmatrix(ctm));
error = fz_newtransformnode(&xform, ptm);
- if (error) return error;
-
- error = fz_packobj(&dict, "<< /Tree %p /XStep %f /YStep %f "
- " /Matrix[%f %f %f %f %f %f] >>",
- pat->tree, pat->xstep, pat->ystep,
- pat->matrix.a, pat->matrix.b,
- pat->matrix.c, pat->matrix.d,
- pat->matrix.e, pat->matrix.f);
- if (error) return error;
-
- error = fz_newmetanode(&meta, "Pattern", dict);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(mask);
+ return fz_rethrow(error, "cannot create transform node");
+ }
error = fz_newovernode(&over);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(xform);
+ fz_dropnode(mask);
+ return fz_rethrow(error, "cannot create over node");
+ }
fz_insertnodelast(mask, shape);
- fz_insertnodelast(mask, meta);
- fz_insertnodelast(meta, xform);
+ fz_insertnodelast(mask, xform);
fz_insertnodelast(xform, over);
+ xform = nil;
+ mask = nil;
+
+ /* over, xform, mask are now owned by the tree */
/* get bbox of shape in pattern space for stamping */
ptm = fz_concat(ctm, fz_invertmatrix(pat->matrix));
@@ -337,19 +362,29 @@ addpatternshape(pdf_gstate *gs, fz_node *shape,
{
ptm = fz_translate(x * pat->xstep, y * pat->ystep);
error = fz_newtransformnode(&xform, ptm);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create transform node for stamp");
error = fz_newlinknode(&link, pat->tree);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(xform);
+ return fz_rethrow(error, "cannot create link node for stamp");
+ }
fz_insertnodelast(xform, link);
fz_insertnodelast(over, xform);
}
}
if (pat->ismask)
- return addcolorshape(gs, mask, 1.0, cs, v);
+ {
+ error = addcolorshape(gs, mask, cs, v);
+ if (error)
+ return fz_rethrow(error, "cannot add colored shape");
+ return fz_okay;
+ }
fz_insertnodelast(gs->head, mask);
- return nil;
+ return fz_okay;
}
fz_error *
@@ -359,11 +394,12 @@ pdf_addshade(pdf_gstate *gs, fz_shade *shade)
fz_node *node;
error = fz_newshadenode(&node, shade);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create shade node");
fz_insertnodelast(gs->head, node);
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -382,21 +418,44 @@ addshadeshape(pdf_gstate *gs, fz_node *shape, fz_shade *shade)
inv = fz_invertmatrix(ctm);
error = fz_newtransformnode(&xform, inv);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create transform node");
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(xform);
+ return fz_rethrow(error, "cannot create mask node");
+ }
error = fz_newshadenode(&color, shade);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(mask);
+ fz_dropnode(xform);
+ return fz_rethrow(error, "cannot create shade node");
+ }
if (shade->usebackground)
{
error = fz_newovernode(&over);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(color);
+ fz_dropnode(mask);
+ fz_dropnode(xform);
+ return fz_rethrow(error, "cannot create over node for background color");
+ }
error = fz_newsolidnode(&bgnd, 1.0, shade->cs, shade->cs->n, shade->background);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(over);
+ fz_dropnode(color);
+ fz_dropnode(mask);
+ fz_dropnode(xform);
+ return fz_rethrow(error, "cannot create solid node for background color");;
+ }
fz_insertnodelast(mask, shape);
fz_insertnodelast(over, bgnd);
@@ -413,49 +472,83 @@ addshadeshape(pdf_gstate *gs, fz_node *shape, fz_shade *shade)
fz_insertnodelast(gs->head, mask);
}
- return nil;
+ return fz_okay;
}
fz_error *
pdf_addfillshape(pdf_gstate *gs, fz_node *shape)
{
+ fz_error *error;
+
switch (gs->fill.kind)
{
case PDF_MNONE:
fz_insertnodelast(gs->head, shape);
- return nil;
+ break;
+
case PDF_MCOLOR:
case PDF_MLAB:
case PDF_MINDEXED:
- return addcolorshape(gs, shape, gs->fill.alpha, gs->fill.cs, gs->fill.v);
+ error = addcolorshape(gs, shape, gs->fill.cs, gs->fill.v);
+ if (error)
+ return fz_rethrow(error, "cannot add colored shape");
+ break;
+
case PDF_MPATTERN:
- return addpatternshape(gs, shape, gs->fill.pattern, gs->fill.cs, gs->fill.v);
+ error = addpatternshape(gs, shape, gs->fill.pattern, gs->fill.cs, gs->fill.v);
+ if (error)
+ return fz_rethrow(error, "cannot add pattern shape");
+ break;
+
case PDF_MSHADE:
- return addshadeshape(gs, shape, gs->fill.shade);
+ error = addshadeshape(gs, shape, gs->fill.shade);
+ if (error)
+ return fz_rethrow(error, "cannot add shade shape");
+ break;
+
default:
- return fz_throw("unimplemented material");
+ return fz_throw("assert: unknown material");
}
+
+ return fz_okay;
}
fz_error *
pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape)
{
+ fz_error *error;
+
switch (gs->stroke.kind)
{
case PDF_MNONE:
fz_insertnodelast(gs->head, shape);
- return nil;
+ break;
+
case PDF_MCOLOR:
case PDF_MLAB:
case PDF_MINDEXED:
- return addcolorshape(gs, shape, gs->stroke.alpha, gs->stroke.cs, gs->stroke.v);
+ error = addcolorshape(gs, shape, gs->stroke.cs, gs->stroke.v);
+ if (error)
+ return fz_rethrow(error, "cannot add colored shape");
+ break;
+
case PDF_MPATTERN:
- return addpatternshape(gs, shape, gs->stroke.pattern, gs->stroke.cs, gs->stroke.v);
+ error = addpatternshape(gs, shape, gs->stroke.pattern, gs->stroke.cs, gs->stroke.v);
+ if (error)
+ return fz_rethrow(error, "cannot add pattern shape");
+ break;
+
case PDF_MSHADE:
- return addshadeshape(gs, shape, gs->stroke.shade);
+ error = addshadeshape(gs, shape, gs->stroke.shade);
+ if (error)
+ return fz_rethrow(error, "cannot add shade shape");
+ break;
+
default:
- return fz_throw("unimplemented material");
+ return fz_throw("assert: unknown material");
}
+
+ return fz_okay;
}
fz_error *
@@ -466,17 +559,22 @@ pdf_addclipmask(pdf_gstate *gs, fz_node *shape)
fz_node *over;
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create mask node");
error = fz_newovernode(&over);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(mask);
+ return fz_rethrow(error, "cannot create over node");
+ }
fz_insertnodelast(mask, shape);
fz_insertnodelast(mask, over);
fz_insertnodelast(gs->head, mask);
gs->head = over;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -486,13 +584,14 @@ pdf_addtransform(pdf_gstate *gs, fz_node *transform)
fz_node *over;
error = fz_newovernode(&over);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create over node");
fz_insertnodelast(gs->head, transform);
fz_insertnodelast(transform, over);
gs->head = over;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -505,24 +604,35 @@ pdf_showimage(pdf_csi *csi, pdf_image *img)
error = fz_newimagenode(&color, (fz_image*)img);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create image node");
if (img->super.n == 0 && img->super.a == 1)
{
error = pdf_addfillshape(csi->gstate + csi->gtop, color);
- if (error) {
+ if (error)
+ {
fz_dropnode(color);
- return error;
+ return fz_rethrow(error, "cannot add filled image mask");
}
}
+
else
{
if (img->mask)
{
error = fz_newimagenode(&shape, (fz_image*)img->mask);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(color);
+ return fz_rethrow(error, "cannot create image node for image mask");
+ }
error = fz_newmasknode(&mask);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode(shape);
+ fz_dropnode(color);
+ return fz_rethrow(error, "cannot create mask node for image mask");
+ }
fz_insertnodelast(mask, shape);
fz_insertnodelast(mask, color);
fz_insertnodelast(csi->gstate[csi->gtop].head, mask);
@@ -533,76 +643,141 @@ pdf_showimage(pdf_csi *csi, pdf_image *img)
}
}
- return nil;
+ return fz_okay;
}
fz_error *
pdf_showpath(pdf_csi *csi,
- int doclose, int dofill, int dostroke, int evenodd)
+ int doclose, int dofill, int dostroke, int evenodd)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_error *error;
fz_pathnode *spath;
fz_pathnode *fpath;
+ fz_pathnode *clip;
+
+ /* TODO this is too messy and hairy with memory cleanups */
if (doclose)
{
error = fz_closepath(csi->path);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create path node");
+ }
+
+ /*
+ * Prepare the various copies of the path node.
+ */
+
+ if (csi->clip)
+ {
+ error = fz_clonepathnode(&clip, csi->path);
+ if (error)
+ return error;
}
if (dofill && dostroke)
{
fpath = csi->path;
error = fz_clonepathnode(&spath, fpath);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot duplicate path node");
+ }
+ else if (dofill)
+ {
+ fpath = csi->path;
+ spath = nil;
+ }
+ else if (dostroke)
+ {
+ fpath = nil;
+ spath = csi->path;
}
else
{
- spath = fpath = csi->path;
+ fz_dropnode((fz_node*)csi->path);
+ spath = nil;
+ fpath = nil;
}
+ csi->path = nil;
+
+ /*
+ * Add nodes to the tree.
+ */
+
if (dofill)
{
error = pdf_buildfillpath(gstate, fpath, evenodd);
- if (error) return error;
+ if (error)
+ {
+ if (fpath) fz_dropnode((fz_node*)fpath);
+ if (spath) fz_dropnode((fz_node*)spath);
+ if (clip) fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot finish fill path");
+ }
+
error = pdf_addfillshape(gstate, (fz_node*)fpath);
- if (error) return error;
+ if (error)
+ {
+ if (fpath) fz_dropnode((fz_node*)fpath);
+ if (spath) fz_dropnode((fz_node*)spath);
+ if (clip) fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot add filled path");
+ }
}
if (dostroke)
{
error = pdf_buildstrokepath(gstate, spath);
- if (error) return error;
+ if (error)
+ {
+ if (fpath) fz_dropnode((fz_node*)fpath);
+ if (spath) fz_dropnode((fz_node*)spath);
+ if (clip) fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot finish stroke path");
+ }
+
error = pdf_addstrokeshape(gstate, (fz_node*)spath);
- if (error) return error;
+ if (error)
+ {
+ if (fpath) fz_dropnode((fz_node*)fpath);
+ if (spath) fz_dropnode((fz_node*)spath);
+ if (clip) fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot add stroked path");
+ }
}
if (csi->clip)
{
- fz_pathnode *clip;
- error = fz_clonepathnode(&clip, csi->path);
- if (error) return error;
error = fz_endpath(clip, FZ_FILL, nil, nil);
- if (error) return error;
+ if (error)
+ {
+ fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot finish clip path");
+ }
+
error = pdf_addclipmask(gstate, (fz_node*)clip);
- if (error) return error;
- csi->clip = 0;
- }
+ if (error)
+ {
+ fz_dropnode((fz_node*)clip);
+ return fz_rethrow(error, "cannot add clip mask");
+ }
- if (!dofill && !dostroke)
- {
- fz_dropnode((fz_node*)csi->path);
+ csi->clip = 0;
}
- csi->path = nil;
-
error = fz_newpathnode(&csi->path);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create path node");;
- return nil;
+ return fz_okay;
}
+/*
+ * Text
+ */
+
fz_error *
pdf_flushtext(pdf_csi *csi)
{
@@ -618,13 +793,13 @@ pdf_flushtext(pdf_csi *csi)
case 2: /* stroke + fill */
error = pdf_addfillshape(gstate, (fz_node*)csi->text);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add filled text");
break;
case 3: /* invisible */
error = addinvisibleshape(gstate, (fz_node*)csi->text);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add invisible text");
break;
case 4: /* fill + clip */
@@ -632,21 +807,28 @@ pdf_flushtext(pdf_csi *csi)
case 6: /* stroke + fill + clip */
{
fz_textnode *temp;
+
error = fz_clonetextnode(&temp, csi->text);
if (error)
- return error;
+ return fz_rethrow(error, "cannot duplicate text");
+
error = pdf_addfillshape(gstate, (fz_node*)temp);
if (error)
- return error;
+ {
+ fz_dropnode((fz_node*)temp);
+ return fz_rethrow(error, "cannot add filled text");
+ }
+
+ /* FIXME stroked text */
}
/* fall through */
- case 7: /* invisible clip */
+ case 7: /* invisible clip ( + fallthrough clips ) */
if (!csi->textclip)
{
error = fz_newovernode(&csi->textclip);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create over node");
}
fz_insertnodelast(csi->textclip, (fz_node*)csi->text);
break;
@@ -655,7 +837,7 @@ pdf_flushtext(pdf_csi *csi)
csi->text = nil;
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -687,18 +869,20 @@ showglyph(pdf_csi *csi, int cid)
/* flush buffered text if face or matrix or rendermode has changed */
if (!csi->text ||
- ((fz_font*)font) != csi->text->font ||
- fabs(trm.a - csi->text->trm.a) > FLT_EPSILON ||
- fabs(trm.b - csi->text->trm.b) > FLT_EPSILON ||
- fabs(trm.c - csi->text->trm.c) > FLT_EPSILON ||
- fabs(trm.d - csi->text->trm.d) > FLT_EPSILON ||
- gstate->render != csi->textmode)
+ ((fz_font*)font) != csi->text->font ||
+ fabs(trm.a - csi->text->trm.a) > FLT_EPSILON ||
+ fabs(trm.b - csi->text->trm.b) > FLT_EPSILON ||
+ fabs(trm.c - csi->text->trm.c) > FLT_EPSILON ||
+ fabs(trm.d - csi->text->trm.d) > FLT_EPSILON ||
+ gstate->render != csi->textmode)
{
error = pdf_flushtext(csi);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot finish text node (face/matrix change)");
error = fz_newtextnode(&csi->text, (fz_font*)font);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create text node");
csi->text->trm = trm;
csi->text->trm.e = 0;
@@ -709,7 +893,7 @@ showglyph(pdf_csi *csi, int cid)
/* add glyph to textobject */
error = fz_addtext(csi->text, cid, trm.e, trm.f);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add glyph to text node");
if (font->super.wmode == 0)
{
@@ -725,7 +909,7 @@ showglyph(pdf_csi *csi, int cid)
csi->tm = fz_concat(fz_translate(0, ty), csi->tm);
}
- return nil;
+ return fz_okay;
}
void
@@ -758,7 +942,8 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
if (fz_isstring(item))
{
error = pdf_showtext(csi, item);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot draw text item");
}
else
{
@@ -768,7 +953,7 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
return nil;
}
- buf = (unsigned char *) fz_tostrbuf(text);
+ buf = fz_tostrbuf(text);
len = fz_tostrlen(text);
end = buf + len;
@@ -781,12 +966,12 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
error = showglyph(csi, cid);
if (error)
- return error;
+ return fz_rethrow(error, "cannot draw glyph");
if (cpt == 32)
showspace(csi, gstate->wordspace);
}
- return nil;
+ return fz_okay;
}
diff --git a/mupdf/pdf_cmap.c b/mupdf/pdf_cmap.c
index 997e5afb..9031aeb6 100644
--- a/mupdf/pdf_cmap.c
+++ b/mupdf/pdf_cmap.c
@@ -72,7 +72,7 @@ pdf_newcmap(pdf_cmap **cmapp)
cmap = *cmapp = fz_malloc(sizeof(pdf_cmap));
if (!cmap)
- return fz_outofmem;
+ return fz_throw("outofmem: cmap struct");
cmap->refs = 1;
strcpy(cmap->cmapname, "");
@@ -92,7 +92,7 @@ pdf_newcmap(pdf_cmap **cmapp)
cmap->tcap = 0;
cmap->table = nil;
- return nil;
+ return fz_okay;
}
pdf_cmap *
@@ -214,7 +214,7 @@ pdf_addcodespace(pdf_cmap *cmap, unsigned lo, unsigned hi, int n)
int i;
if (cmap->ncspace + 1 == MAXCODESPACE)
- return fz_throw("rangelimit: too many code space ranges");
+ return fz_throw("assert: too many code space ranges");
cmap->cspace[cmap->ncspace].n = n;
@@ -227,7 +227,7 @@ pdf_addcodespace(pdf_cmap *cmap, unsigned lo, unsigned hi, int n)
cmap->ncspace ++;
- return nil;
+ return fz_okay;
}
/*
@@ -241,14 +241,14 @@ addtable(pdf_cmap *cmap, int value)
int newcap = cmap->tcap == 0 ? 256 : cmap->tcap * 2;
int *newtable = fz_realloc(cmap->table, newcap * sizeof(int));
if (!newtable)
- return fz_outofmem;
+ return fz_throw("outofmem: cmap table");
cmap->tcap = newcap;
cmap->table = newtable;
}
cmap->table[cmap->tlen++] = value;
- return nil;
+ return fz_okay;
}
/*
@@ -263,7 +263,7 @@ addrange(pdf_cmap *cmap, int low, int high, int flag, int offset)
int newcap = cmap->rcap == 0 ? 256 : cmap->rcap * 2;
newranges = fz_realloc(cmap->ranges, newcap * sizeof(pdf_range));
if (!newranges)
- return fz_outofmem;
+ return fz_throw("outofmem: cmap ranges");
cmap->rcap = newcap;
cmap->ranges = newranges;
}
@@ -274,7 +274,7 @@ addrange(pdf_cmap *cmap, int low, int high, int flag, int offset)
cmap->ranges[cmap->rlen].offset = offset;
cmap->rlen ++;
- return nil;
+ return fz_okay;
}
/*
@@ -295,10 +295,14 @@ pdf_maprangetotable(pdf_cmap *cmap, int low, int *table, int len)
{
error = addtable(cmap, table[i]);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add range-to-table index");
}
- return addrange(cmap, low, high, TABLE, offset);
+ error = addrange(cmap, low, high, TABLE, offset);
+ if (error)
+ return fz_rethrow(error, "cannot add range-to-table range");
+
+ return fz_okay;
}
/*
@@ -307,7 +311,11 @@ pdf_maprangetotable(pdf_cmap *cmap, int low, int *table, int len)
fz_error *
pdf_maprangetorange(pdf_cmap *cmap, int low, int high, int offset)
{
- return addrange(cmap, low, high, high - low == 0 ? SINGLE : RANGE, offset);
+ fz_error *error;
+ error = addrange(cmap, low, high, high - low == 0 ? SINGLE : RANGE, offset);
+ if (error)
+ return fz_rethrow(error, "cannot add range-to-range mapping");
+ return fz_okay;
}
/*
@@ -321,22 +329,31 @@ pdf_maponetomany(pdf_cmap *cmap, int low, int *values, int len)
int i;
if (len == 1)
- return addrange(cmap, low, low, SINGLE, values[0]);
+ {
+ error = addrange(cmap, low, low, SINGLE, values[0]);
+ if (error)
+ return fz_rethrow(error, "cannot add one-to-one mapping");
+ return fz_okay;
+ }
offset = cmap->tlen;
error = addtable(cmap, len);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add one-to-many table length");
for (i = 0; i < len; i++)
{
addtable(cmap, values[i]);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add one-to-many table index");
}
- return addrange(cmap, low, low, MULTI, offset);
+ error = addrange(cmap, low, low, MULTI, offset);
+ if (error)
+ return fz_rethrow(error, "cannot add one-to-many mapping");
+
+ return fz_okay;
}
/*
@@ -385,7 +402,7 @@ pdf_sortcmap(pdf_cmap *cmap)
a->high = b->high;
error = addtable(cmap, b->offset);
if (error)
- return error;
+ return fz_rethrow(error, "cannot convert LS -> L");
}
/* LR -> LR */
@@ -412,11 +429,11 @@ pdf_sortcmap(pdf_cmap *cmap)
error = addtable(cmap, a->offset);
if (error)
- return error;
+ return fz_rethrow(error, "cannot convert SS -> L");
error = addtable(cmap, b->offset);
if (error)
- return error;
+ return fz_rethrow(error, "cannot convert SS -> L");
a->offset = cmap->tlen - 2;
}
@@ -427,7 +444,7 @@ pdf_sortcmap(pdf_cmap *cmap)
a->high = b->high;
error = addtable(cmap, b->offset);
if (error)
- return error;
+ return fz_rethrow(error, "cannot convert LS -> L");
}
/* XX -> XX */
@@ -453,7 +470,7 @@ pdf_sortcmap(pdf_cmap *cmap)
newranges = fz_realloc(cmap->ranges, cmap->rlen * sizeof(pdf_range));
if (!newranges)
- return fz_outofmem;
+ return fz_throw("outofmem: cmap ranges");
cmap->rcap = cmap->rlen;
cmap->ranges = newranges;
@@ -461,12 +478,12 @@ pdf_sortcmap(pdf_cmap *cmap)
{
newtable = fz_realloc(cmap->table, cmap->tlen * sizeof(int));
if (!newtable)
- return fz_outofmem;
+ return fz_throw("outofmem: cmap table");
cmap->tcap = cmap->tlen;
cmap->table = newtable;
}
- return nil;
+ return fz_okay;
}
/*
@@ -580,69 +597,84 @@ static int codefromstring(unsigned char *buf, int len)
return a;
}
-static int mylex(fz_stream *file, unsigned char *buf, int n, int *sl)
+static fz_error *mylex(int *token, fz_stream *file, char *buf, int n, int *sl)
{
- int token = pdf_lex(file, (unsigned char *) buf, n, sl);
- if (token == PDF_TKEYWORD)
- token = tokenfromkeyword((char *) buf);
- return token;
+ fz_error *error;
+ error = pdf_lex(token, file, buf, n, sl);
+ if (!error && *token == PDF_TKEYWORD)
+ *token = tokenfromkeyword(buf);
+ return error;
}
static fz_error *parsecmapname(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- token = mylex(file, buf, sizeof buf, &len);
- if (token == PDF_TNAME) {
- strlcpy(cmap->cmapname, (char *) buf, sizeof(cmap->cmapname));
- return nil;
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
+
+ if (token == PDF_TNAME)
+ {
+ strlcpy(cmap->cmapname, buf, sizeof(cmap->cmapname));
+ return fz_okay;
}
- return fz_throw("syntaxerror in CMap after /CMapName");
+ return fz_throw("expected name");
}
static fz_error *parsewmode(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- token = mylex(file, buf, sizeof buf, &len);
- if (token == PDF_TINT) {
- pdf_setwmode(cmap, atoi((char *) buf));
- return nil;
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
+
+ if (token == PDF_TINT)
+ {
+ pdf_setwmode(cmap, atoi(buf));
+ return fz_okay;
}
- return fz_throw("syntaxerror in CMap after /WMode");
+ return fz_throw("expected integer");
}
static fz_error *parsecodespacerange(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int lo, hi;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == TENDCODESPACERANGE)
- return nil;
+ return fz_okay;
else if (token == PDF_TSTRING)
{
lo = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == PDF_TSTRING)
{
hi = codefromstring(buf, len);
error = pdf_addcodespace(cmap, lo, hi, len);
if (error)
- return error;
+ return fz_rethrow(error, "cannot add code space");
}
else break;
}
@@ -650,104 +682,110 @@ static fz_error *parsecodespacerange(pdf_cmap *cmap, fz_stream *file)
else break;
}
- return fz_throw("syntaxerror in CMap codespacerange section");
+ return fz_throw("expected string or endcodespacerange");
}
static fz_error *parsecidrange(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int lo, hi, dst;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == TENDCIDRANGE)
- return nil;
+ return fz_okay;
else if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string or endcidrange");
lo = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string");
hi = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token != PDF_TINT)
- goto cleanup;
+ return fz_throw("expected integer");
- dst = atoi((char *) buf);
+ dst = atoi(buf);
error = pdf_maprangetorange(cmap, lo, hi, dst);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map cidrange");
}
-
-cleanup:
- return fz_throw("syntaxerror in CMap cidrange section");
}
static fz_error *parsecidchar(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int src, dst;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == TENDCIDCHAR)
- return nil;
+ return fz_okay;
else if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string or endcidchar");
src = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token != PDF_TINT)
- goto cleanup;
+ return fz_throw("expected integer");
- dst = atoi((char *) buf);
+ dst = atoi(buf);
error = pdf_maprangetorange(cmap, src, src, dst);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map cidchar");
}
-
-cleanup:
- return fz_throw("syntaxerror in CMap cidchar section");
}
static fz_error *parsebfrangearray(pdf_cmap *cmap, fz_stream *file, int lo, int hi)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int dst[256];
int i;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
- /* Note: does not handle [ /Name /Name ... ] */
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == PDF_TCARRAY)
- return nil;
+ return fz_okay;
+ /* Note: does not handle [ /Name /Name ... ] */
else if (token != PDF_TSTRING)
- return fz_throw("syntaxerror in CMap bfrange array section");
+ return fz_throw("expected string or ]");
if (len / 2)
{
@@ -756,7 +794,7 @@ static fz_error *parsebfrangearray(pdf_cmap *cmap, fz_stream *file, int lo, int
error = pdf_maponetomany(cmap, lo, dst, len / 2);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map bfrange array");
}
lo ++;
@@ -765,31 +803,37 @@ static fz_error *parsebfrangearray(pdf_cmap *cmap, fz_stream *file, int lo, int
static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int lo, hi, dst;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == TENDBFRANGE)
- return nil;
+ return fz_okay;
else if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string or endbfrange");
lo = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string");
hi = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == PDF_TSTRING)
{
@@ -798,7 +842,7 @@ static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file)
dst = codefromstring(buf, len);
error = pdf_maprangetorange(cmap, lo, hi, dst);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map bfrange");
}
else
{
@@ -815,7 +859,7 @@ static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file)
dststr[i-1] ++;
error = pdf_maponetomany(cmap, lo, dststr, i);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map bfrange");
lo ++;
}
}
@@ -826,45 +870,46 @@ static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file)
{
error = parsebfrangearray(cmap, file, lo, hi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map bfrange");
}
else
{
- goto cleanup;
+ return fz_throw("expected string or array or endbfrange");
}
}
-
-cleanup:
- return fz_throw("syntaxerror in CMap bfrange section");
}
static fz_error *parsebfchar(pdf_cmap *cmap, fz_stream *file)
{
- unsigned char buf[256];
+ fz_error *error;
+ char buf[256];
int token;
int len;
- fz_error *error;
int dst[256];
int src;
int i;
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
if (token == TENDBFCHAR)
- return nil;
+ return fz_okay;
else if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string or endbfchar");
src = codefromstring(buf, len);
- token = mylex(file, buf, sizeof buf, &len);
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "syntaxerror in cmap");
/* Note: does not handle /dstName */
if (token != PDF_TSTRING)
- goto cleanup;
+ return fz_throw("expected string");
if (len / 2)
{
@@ -873,12 +918,9 @@ static fz_error *parsebfchar(pdf_cmap *cmap, fz_stream *file)
error = pdf_maponetomany(cmap, src, dst, i);
if (error)
- return error;
+ return fz_rethrow(error, "cannot map bfchar");
}
}
-
-cleanup:
- return fz_throw("syntaxerror in CMap bfchar section");
}
fz_error *
@@ -887,45 +929,50 @@ pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file)
fz_error *error;
pdf_cmap *cmap;
char key[64];
- unsigned char buf[256];
+ char buf[256];
int token;
int len;
error = pdf_newcmap(&cmap);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create cmap");
strcpy(key, ".notdef");
while (1)
{
- token = mylex(file, buf, sizeof buf, &len);
-
- if (token == PDF_TEOF)
- break;
-
- else if (token == PDF_TERROR)
+ error = mylex(&token, file, buf, sizeof buf, &len);
+ if (error)
{
- error = fz_throw("syntaxerror in CMap");
+ error = fz_rethrow(error, "syntaxerror in cmap");
goto cleanup;
}
+ if (token == PDF_TEOF)
+ break;
+
else if (token == PDF_TNAME)
{
- if (!strcmp((char *) buf, "CMapName"))
+ if (!strcmp(buf, "CMapName"))
{
error = parsecmapname(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap after /CMapName");
goto cleanup;
+ }
}
- else if (!strcmp((char *) buf, "WMode"))
+ else if (!strcmp(buf, "WMode"))
{
error = parsewmode(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap after /WMode");
goto cleanup;
+ }
}
else
- strlcpy(key, (char *) buf, sizeof key);
+ strlcpy(key, buf, sizeof key);
}
else if (token == TUSECMAP)
@@ -937,35 +984,50 @@ pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file)
{
error = parsecodespacerange(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap codespacerange");
goto cleanup;
+ }
}
else if (token == TBEGINBFCHAR)
{
error = parsebfchar(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap bfchar");
goto cleanup;
+ }
}
else if (token == TBEGINCIDCHAR)
{
error = parsecidchar(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap cidchar");
goto cleanup;
+ }
}
else if (token == TBEGINBFRANGE)
{
error = parsebfrange(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap bfrange");
goto cleanup;
+ }
}
else if (token == TBEGINCIDRANGE)
{
error = parsecidrange(cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "syntaxerror in cmap cidrange");
goto cleanup;
+ }
}
/* ignore everything else */
@@ -973,10 +1035,13 @@ pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file)
error = pdf_sortcmap(cmap);
if (error)
+ {
+ error = fz_rethrow(error, "cannot sort cmap");
goto cleanup;
+ }
*cmapp = cmap;
- return nil;
+ return fz_okay;
cleanup:
pdf_dropcmap(cmap);
@@ -989,8 +1054,8 @@ cleanup:
fz_error *
pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
{
- fz_obj *stmobj = stmref;
fz_error *error = nil;
+ fz_obj *stmobj = stmref;
fz_stream *file;
pdf_cmap *cmap = nil;
pdf_cmap *usecmap;
@@ -1007,15 +1072,21 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
error = pdf_resolve(&stmobj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve cmap object");
error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
+ {
+ error = fz_rethrow(error, "cannot open cmap stream");
goto cleanup;
+ }
error = pdf_parsecmap(&cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "cannot parse cmap stream");
goto cleanup;
+ }
fz_dropstream(file);
@@ -1032,7 +1103,10 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
pdf_logfont("usecmap /%s\n", fz_toname(obj));
error = pdf_loadsystemcmap(&usecmap, fz_toname(obj));
if (error)
+ {
+ error = fz_rethrow(error, "cannot load system usecmap '%s'", fz_toname(obj));
goto cleanup;
+ }
pdf_setusecmap(cmap, usecmap);
pdf_dropcmap(usecmap);
}
@@ -1041,7 +1115,10 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
pdf_logfont("usecmap %d %d R\n", fz_tonum(obj), fz_togen(obj));
error = pdf_loadembeddedcmap(&usecmap, xref, obj);
if (error)
+ {
+ error = fz_rethrow(error, "cannot load embedded usecmap");
goto cleanup;
+ }
pdf_setusecmap(cmap, usecmap);
pdf_dropcmap(usecmap);
}
@@ -1050,12 +1127,15 @@ pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap);
if (error)
+ {
+ error = fz_rethrow(error, "cannot store cmap resource");
goto cleanup;
+ }
fz_dropobj(stmobj);
*cmapp = cmap;
- return nil;
+ return fz_okay;
cleanup:
if (cmap)
@@ -1093,11 +1173,17 @@ pdf_loadsystemcmap(pdf_cmap **cmapp, char *name)
error = fz_openrfile(&file, path);
if (error)
+ {
+ error = fz_rethrow(error, "cannot open cmap file '%s'", name);
goto cleanup;
+ }
error = pdf_parsecmap(&cmap, file);
if (error)
+ {
+ error = fz_rethrow(error, "cannot parse cmap file");
goto cleanup;
+ }
fz_dropstream(file);
@@ -1107,7 +1193,10 @@ pdf_loadsystemcmap(pdf_cmap **cmapp, char *name)
pdf_logfont("usecmap %s\n", usecmapname);
error = pdf_loadsystemcmap(&usecmap, usecmapname);
if (error)
+ {
+ error = fz_rethrow(error, "cannot load system usecmap '%s'", usecmapname);
goto cleanup;
+ }
pdf_setusecmap(cmap, usecmap);
pdf_dropcmap(usecmap);
}
@@ -1115,7 +1204,7 @@ pdf_loadsystemcmap(pdf_cmap **cmapp, char *name)
pdf_logfont("}\n");
*cmapp = cmap;
- return nil;
+ return fz_okay;
cleanup:
if (cmap)
@@ -1136,31 +1225,31 @@ pdf_newidentitycmap(pdf_cmap **cmapp, int wmode, int bytes)
error = pdf_newcmap(&cmap);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create cmap");
sprintf(cmap->cmapname, "Identity-%c", wmode ? 'V' : 'H');
error = pdf_addcodespace(cmap, 0x0000, 0xffff, bytes);
if (error) {
pdf_dropcmap(cmap);
- return error;
+ return fz_rethrow(error, "cannot add code space");
}
error = pdf_maprangetorange(cmap, 0x0000, 0xffff, 0);
if (error) {
pdf_dropcmap(cmap);
- return error;
+ return fz_rethrow(error, "cannot map <0000> to <ffff>");
}
error = pdf_sortcmap(cmap);
if (error) {
pdf_dropcmap(cmap);
- return error;
+ return fz_rethrow(error, "cannot sort cmap");
}
pdf_setwmode(cmap, wmode);
*cmapp = cmap;
- return nil;
+ return fz_okay;
}
diff --git a/mupdf/pdf_colorspace1.c b/mupdf/pdf_colorspace1.c
index 3cb5c95c..7c79f79a 100644
--- a/mupdf/pdf_colorspace1.c
+++ b/mupdf/pdf_colorspace1.c
@@ -534,8 +534,8 @@ loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
}
initcs((fz_colorspace*)cs,
- n == 1 ? "Separation" : "DeviceN", n,
- separationtoxyz, nil, dropseparation);
+ n == 1 ? "Separation" : "DeviceN", n,
+ separationtoxyz, nil, dropseparation);
cs->base = base;
cs->tint = tint;
diff --git a/mupdf/pdf_colorspace2.c b/mupdf/pdf_colorspace2.c
index 9e792b00..028628a1 100644
--- a/mupdf/pdf_colorspace2.c
+++ b/mupdf/pdf_colorspace2.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
* Optimized color conversions for Device colorspaces
diff --git a/mupdf/pdf_crypt.c b/mupdf/pdf_crypt.c
index dd13ed9a..2fac478f 100644
--- a/mupdf/pdf_crypt.c
+++ b/mupdf/pdf_crypt.c
@@ -52,7 +52,7 @@ static void padpassword(unsigned char *buf, char *pw, int pwlen)
fz_error *
pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
{
- pdf_crypt *crypt = nil;
+ pdf_crypt *crypt;
fz_obj *obj;
int m;
@@ -65,7 +65,7 @@ pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
crypt = fz_malloc(sizeof(pdf_crypt));
if (!crypt)
- return fz_outofmem;
+ return fz_throw("outofmem: crypt struct");
crypt->encrypt = fz_keepobj(enc);
crypt->id = nil;
@@ -116,7 +116,7 @@ pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
memset(crypt->key, 0, 16);
*cp = crypt;
- return nil;
+ return fz_okay;
cleanup:
pdf_dropcrypt(crypt);
@@ -288,7 +288,7 @@ pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj
crypt = fz_malloc(sizeof(pdf_crypt));
if (!crypt)
- return fz_outofmem;
+ return fz_throw("outofmem: crypt struct");
crypt->encrypt = nil;
crypt->id = fz_keepobj(fz_arrayget(id, 0));
@@ -302,10 +302,10 @@ pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj
error = fz_packobj(&crypt->encrypt,
"<< /Filter /Standard "
- "/V %i /R %i "
- "/O %# /U %# "
- "/P %i "
- "/Length %i >>",
+ "/V %i /R %i "
+ "/O %# /U %# "
+ "/P %i "
+ "/Length %i >>",
crypt->r == 2 ? 1 : 2,
crypt->r,
crypt->o, 32,
@@ -315,30 +315,29 @@ pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj
if (error)
{
pdf_dropcrypt(crypt);
- return error;
+ return fz_rethrow(error, "cannot create encryption dictionary");
}
*cp = crypt;
- return nil;
+ return fz_okay;
}
/*
* Algorithm 3.6 Checking the user password
+ *
+ * Return true if the password is valid.
*/
-fz_error *
+int
pdf_setpassword(pdf_crypt *crypt, char *pw)
{
- fz_error *error = pdf_setuserpassword(crypt, pw, strlen(pw));
- if (error)
- {
- fz_droperror(error);
- error = pdf_setownerpassword(crypt, pw, strlen(pw));
- }
- return error;
+ int okay = pdf_setuserpassword(crypt, pw, strlen(pw));
+ if (!okay)
+ okay = pdf_setownerpassword(crypt, pw, strlen(pw));
+ return okay;
}
-fz_error *
+int
pdf_setuserpassword(pdf_crypt *crypt, char *userpw, int pwlen)
{
unsigned char saved[32];
@@ -350,12 +349,11 @@ pdf_setuserpassword(pdf_crypt *crypt, char *userpw, int pwlen)
memcpy(crypt->u, saved, 32);
if (memcmp(test, saved, crypt->r == 3 ? 16 : 32) != 0)
- return fz_throw("invalid password");
-
- return nil;
+ return 0;
+ return 1;
}
-fz_error *
+int
pdf_setownerpassword(pdf_crypt *crypt, char *ownerpw, int pwlen)
{
unsigned char buf[32];
@@ -398,7 +396,7 @@ pdf_setownerpassword(pdf_crypt *crypt, char *ownerpw, int pwlen)
}
}
- return pdf_setuserpassword(crypt, (char *) buf, 32);
+ return pdf_setuserpassword(crypt, buf, 32);
}
/*
@@ -414,7 +412,7 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid)
if (fz_isstring(obj))
{
- s = (unsigned char *) fz_tostrbuf(obj);
+ s = fz_tostrbuf(obj);
n = fz_tostrlen(obj);
createobjkey(crypt, oid, gid, key);
fz_arc4init(&arc4, key, crypt->keylen);
@@ -446,8 +444,12 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid)
fz_error *
pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid)
{
+ fz_error *error;
unsigned char key[16];
createobjkey(crypt, oid, gid, key);
- return fz_newarc4filter(fp, key, crypt->keylen);
+ error = fz_newarc4filter(fp, key, crypt->keylen);
+ if (error)
+ return fz_rethrow(error, "cannot create crypt filter");
+ return fz_okay;
}
diff --git a/mupdf/pdf_debug.c b/mupdf/pdf_debug.c
index 4704794b..aafc4e9c 100644
--- a/mupdf/pdf_debug.c
+++ b/mupdf/pdf_debug.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
* Enable logging by setting environment variable MULOG to:
diff --git a/mupdf/pdf_doctor.c b/mupdf/pdf_doctor.c
index 99d9ff85..97e96479 100644
--- a/mupdf/pdf_doctor.c
+++ b/mupdf/pdf_doctor.c
@@ -1,8 +1,10 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
* Sweep and mark reachable objects
+ *
+ * Don't bother chaining errors for this deep recursion
*/
static fz_error *sweepref(pdf_xref *xref, fz_obj *ref);
@@ -36,7 +38,7 @@ sweepobj(pdf_xref *xref, fz_obj *obj)
if (fz_isindirect(obj))
return sweepref(xref, obj);
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -49,16 +51,16 @@ sweepref(pdf_xref *xref, fz_obj *ref)
oid = fz_tonum(ref);
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object number out of range");
+ return fz_throw("object out of range %d", oid);
if (xref->table[oid].mark)
- return nil;
+ return fz_okay;
xref->table[oid].mark = 1;
error = pdf_loadindirect(&obj, xref, ref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load indirect object");
error = sweepobj(xref, obj);
if (error)
@@ -68,7 +70,7 @@ sweepref(pdf_xref *xref, fz_obj *ref)
}
fz_dropobj(obj);
- return nil;
+ return fz_okay;
}
/*
@@ -89,7 +91,7 @@ pdf_garbagecollect(pdf_xref *xref)
error = sweepobj(xref, xref->trailer);
if (error)
- return error;
+ return fz_rethrow(error, "cannot mark used objects");
for (i = 0; i < xref->len; i++)
{
@@ -98,12 +100,16 @@ pdf_garbagecollect(pdf_xref *xref)
if (x->type == 'o')
g = 0;
if (!x->mark && x->type != 'f' && x->type != 'd')
- pdf_deleteobject(xref, i, g);
+ {
+ error = pdf_deleteobject(xref, i, g);
+ if (error)
+ return fz_rethrow(error, "cannot delete unmarked object %d", i);
+ }
}
pdf_logxref("}\n");
- return nil;
+ return fz_okay;
}
/*
@@ -129,14 +135,18 @@ remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n)
g = fz_togen(old);
for (i = 0; i < n; i++)
if (map[i].soid == o && map[i].sgen == g)
- return fz_newindirect(newp, map[i].doid, map[i].dgen);
+ {
+ error = fz_newindirect(newp, map[i].doid, map[i].dgen);
+ if (error)
+ return fz_rethrow(error, "cannot remap indirect reference");
+ }
}
else if (fz_isarray(old))
{
error = fz_newarray(newp, fz_arraylen(old));
if (error)
- return error;
+ return fz_rethrow(error, "cannot remap array");
for (i = 0; i < fz_arraylen(old); i++)
{
tmp = fz_arrayget(old, i);
@@ -154,7 +164,7 @@ remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n)
{
error = fz_newdict(newp, fz_dictlen(old));
if (error)
- return error;
+ return fz_rethrow(error, "cannot remap dictionary");
for (i = 0; i < fz_dictlen(old); i++)
{
key = fz_dictgetkey(old, i);
@@ -174,11 +184,11 @@ remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n)
*newp = fz_keepobj(old);
}
- return nil;
+ return fz_okay;
cleanup:
fz_dropobj(*newp);
- return error;
+ return fz_rethrow(error, "cannot remap object");
}
/*
@@ -202,9 +212,9 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
error = sweepobj(src, root);
if (error)
- return error;
+ return fz_rethrow(error, "cannot mark used objects");
- for (n = 0, i = 0; i < src->len; i++)
+ for (n = 0, i = 0; i < src->len; i++)
if (src->table[i].mark)
n++;
@@ -212,9 +222,9 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
map = fz_malloc(sizeof(struct pair) * n);
if (!map)
- return fz_outofmem;
+ return fz_throw("outofmem: remapping table");
- for (n = 0, i = 0; i < src->len; i++)
+ for (n = 0, i = 0; i < src->len; i++)
{
if (src->table[i].mark)
{
@@ -229,15 +239,15 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
}
}
- error = remaprefs(newp, root, map, n);
+ error == remaprefs(newp, root, map, n);
if (error)
goto cleanup;
- for (i = 0; i < n; i++)
+ for (i = 0; i < n; i++)
{
pdf_logxref("copyfrom %d %d to %d %d\n",
- map[i].soid, map[i].sgen,
- map[i].doid, map[i].dgen);
+ map[i].soid, map[i].sgen,
+ map[i].doid, map[i].dgen);
error = pdf_loadobject(&old, src, map[i].soid, map[i].sgen);
if (error)
@@ -257,8 +267,10 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
if (error)
goto cleanup;
- pdf_updateobject(dst, map[i].doid, map[i].dgen, new);
+ error = pdf_updateobject(dst, map[i].doid, map[i].dgen, new);
fz_dropobj(new);
+ if (error)
+ goto cleanup;
}
pdf_logxref("}\n");
@@ -268,6 +280,6 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
cleanup:
fz_free(map);
- return error;
+ return fz_rethrow(error, "cannot transplant objects");
}
diff --git a/mupdf/pdf_font.c b/mupdf/pdf_font.c
index 08de54e2..a2386fed 100644
--- a/mupdf/pdf_font.c
+++ b/mupdf/pdf_font.c
@@ -9,32 +9,32 @@
static char *basefontnames[14][7] =
{
- { "Courier", "CourierNew", "CourierNewPSMT", 0 },
- { "Courier-Bold", "CourierNew,Bold", "Courier,Bold",
- "CourierNewPS-BoldMT", "CourierNew-Bold", 0 },
- { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic",
- "CourierNewPS-ItalicMT", "CourierNew-Italic", 0 },
- { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic",
- "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", 0 },
- { "Helvetica", "ArialMT", "Arial", 0 },
- { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold",
- "Helvetica,Bold", 0 },
- { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic",
- "Helvetica,Italic", "Helvetica-Italic", 0 },
- { "Helvetica-BoldOblique", "Arial-BoldItalicMT",
- "Arial,BoldItalic", "Arial-BoldItalic",
- "Helvetica,BoldItalic", "Helvetica-BoldItalic", 0 },
- { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman",
- "TimesNewRomanPS", 0 },
- { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold",
- "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", 0 },
- { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic",
- "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", 0 },
- { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT",
- "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic",
- "TimesNewRoman-BoldItalic", 0 },
- { "Symbol", 0 },
- { "ZapfDingbats", 0 }
+ { "Courier", "CourierNew", "CourierNewPSMT", 0 },
+ { "Courier-Bold", "CourierNew,Bold", "Courier,Bold",
+ "CourierNewPS-BoldMT", "CourierNew-Bold", 0 },
+ { "Courier-Oblique", "CourierNew,Italic", "Courier,Italic",
+ "CourierNewPS-ItalicMT", "CourierNew-Italic", 0 },
+ { "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic",
+ "CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", 0 },
+ { "Helvetica", "ArialMT", "Arial", 0 },
+ { "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold",
+ "Helvetica,Bold", 0 },
+ { "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic",
+ "Helvetica,Italic", "Helvetica-Italic", 0 },
+ { "Helvetica-BoldOblique", "Arial-BoldItalicMT",
+ "Arial,BoldItalic", "Arial-BoldItalic",
+ "Helvetica,BoldItalic", "Helvetica-BoldItalic", 0 },
+ { "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman",
+ "TimesNewRomanPS", 0 },
+ { "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold",
+ "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", 0 },
+ { "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic",
+ "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", 0 },
+ { "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT",
+ "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic",
+ "TimesNewRoman-BoldItalic", 0 },
+ { "Symbol", 0 },
+ { "ZapfDingbats", 0 }
};
/*
@@ -107,7 +107,7 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
FT_Set_Char_Size(face, 1000, 1000, 72, 72);
fterr = FT_Load_Glyph(font->ftface, gid,
- FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
+ FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
if (fterr)
return fz_throw("freetype failed to load glyph: 0x%x", fterr);
@@ -517,7 +517,7 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
font->cidtogid = etable;
error = pdf_loadtounicode(font, xref,
- estrings, nil, fz_dictgets(dict, "ToUnicode"));
+ estrings, nil, fz_dictgets(dict, "ToUnicode"));
if (error)
goto cleanup;
@@ -966,8 +966,8 @@ pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *colle
bbox = pdf_torect(fz_dictgets(desc, "FontBBox"));
pdf_logfont("bbox [%g %g %g %g]\n",
- bbox.x0, bbox.y0,
- bbox.x1, bbox.y1);
+ bbox.x0, bbox.y0,
+ bbox.x1, bbox.y1);
pdf_logfont("flags %d\n", font->flags);
diff --git a/mupdf/pdf_fontagl.c b/mupdf/pdf_fontagl.c
index d4ce0540..8929c14d 100644
--- a/mupdf/pdf_fontagl.c
+++ b/mupdf/pdf_fontagl.c
@@ -4585,62 +4585,63 @@ static const unsigned short agldat[4368] = {
int pdf_lookupagl(char *name, int *ucsbuf, int ucscap)
{
- char buf[256];
- int ucslen = 0;
- char *p;
- char *s;
- int i;
+ char buf[256];
+ int ucslen = 0;
+ char *p;
+ char *s;
+ int i;
- strlcpy(buf, name, sizeof buf);
+ strlcpy(buf, name, sizeof buf);
- /* kill anything after first period */
- p = strchr(buf, '.');
- if (p)
- p[0] = 0;
+ /* kill anything after first period */
+ p = strchr(buf, '.');
+ if (p)
+ p[0] = 0;
- /* split into components separated by underscore */
- p = buf;
- s = strsep(&p, "_");
- while (s)
- {
- int l = 0;
- int r = nelem(aglidx) - 1;
+ /* split into components separated by underscore */
+ p = buf;
+ s = strsep(&p, "_");
+ while (s)
+ {
+ int l = 0;
+ int r = nelem(aglidx) - 1;
- while (l <= r)
- {
- int m = (l + r) >> 1;
- int c = strcmp(s, aglidx[m].name);
- if (c < 0)
- r = m - 1;
- else if (c > 0)
- l = m + 1;
- else
- {
- for (i = 0; i < aglidx[m].num; i++)
- ucsbuf[ucslen++] = agldat[aglidx[m].ofs + i];
- goto next;
- }
- }
+ while (l <= r)
+ {
+ int m = (l + r) >> 1;
+ int c = strcmp(s, aglidx[m].name);
+ if (c < 0)
+ r = m - 1;
+ else if (c > 0)
+ l = m + 1;
+ else
+ {
+ for (i = 0; i < aglidx[m].num; i++)
+ ucsbuf[ucslen++] = agldat[aglidx[m].ofs + i];
+ goto next;
+ }
+ }
- if (strstr(s, "uni") == s)
- {
- char tmp[5];
- s += 3;
- while (s[0])
- {
- strlcpy(tmp, s, 5);
- ucsbuf[ucslen++] = strtol(tmp, 0, 16);
- s += MIN(strlen(s), 4);
- }
- }
+ if (strstr(s, "uni") == s)
+ {
+ char tmp[5];
+ s += 3;
+ while (s[0])
+ {
+ strlcpy(tmp, s, 5);
+ ucsbuf[ucslen++] = strtol(tmp, 0, 16);
+ s += MIN(strlen(s), 4);
+ }
+ }
- else if (strstr(s, "u") == s)
- ucsbuf[ucslen++] = strtol(s + 1, 0, 16);
+ else if (strstr(s, "u") == s)
+ ucsbuf[ucslen++] = strtol(s + 1, 0, 16);
next:
- s = strsep(&p, "_");
- }
+ s = strsep(&p, "_");
+ }
- return ucslen;
+ return ucslen;
}
+
diff --git a/mupdf/pdf_fontenc.c b/mupdf/pdf_fontenc.c
index d3726675..d45f4edb 100644
--- a/mupdf/pdf_fontenc.c
+++ b/mupdf/pdf_fontenc.c
@@ -2,8 +2,8 @@
* Built-in font tables
*/
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
#define _notdef 0
diff --git a/mupdf/pdf_fontfile.c b/mupdf/pdf_fontfile.c
index b90c71c0..868b0341 100644
--- a/mupdf/pdf_fontfile.c
+++ b/mupdf/pdf_fontfile.c
@@ -1,7 +1,7 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
-#include <mupdf/base14.h>
+#include "mupdf/base14.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -26,8 +26,7 @@ static const struct
const char *name;
const unsigned char *cff;
const unsigned int *len;
-} basefonts[15] =
-{
+} basefonts[15] = {
{ "Courier",
fonts_NimbusMonL_Regu_cff,
&fonts_NimbusMonL_Regu_cff_len },
@@ -127,7 +126,7 @@ static fz_error *initfontlibs(void)
if (maj == 2 && min == 1 && pat < 7)
return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat);
- return nil;
+ return fz_okay;
}
fz_error *
@@ -141,13 +140,13 @@ pdf_loadbuiltinfont(pdf_font *font, char *fontname)
error = initfontlibs();
if (error)
- return error;
+ return fz_rethrow(error, "cannot init font libraries");
for (i = 0; i < 15; i++)
if (!strcmp(fontname, basefonts[i].name))
goto found;
- return fz_throw("font not found: %s", fontname);
+ return fz_throw("cannot find font: %s", fontname);
found:
pdf_logfont("load builtin font %s\n", fontname);
@@ -157,9 +156,9 @@ found:
e = FT_New_Memory_Face(ftlib, data, len, 0, (FT_Face*)&font->ftface);
if (e)
- return fz_throw("freetype: could not load font: 0x%x", e);
+ return fz_throw("freetype: cannot load font: 0x%x", e);
- return nil;
+ return fz_okay;
}
static int
@@ -245,13 +244,13 @@ loadcidfont(pdf_font *font, int csi, int kind)
pdf_logfont("load system font '%s'\n", fontsubs[i].name);
e = FT_New_Face(ftlib, path, 0, (FT_Face*)&font->ftface);
if (e)
- return fz_throw("freetype: could not load font: 0x%x", e);
- return nil;
+ return fz_throw("freetype: cannot load font: 0x%x", e);
+ return fz_okay;
}
}
}
- return fz_throw("could not find cid font file");
+ return fz_throw("cannot find cid font file");
}
fz_error *
@@ -268,7 +267,7 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
error = initfontlibs();
if (error)
- return error;
+ return fz_rethrow(error, "cannot init font libraries");
font->substitute = 1;
@@ -291,7 +290,7 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
isbold = 1;
pdf_logfont("fixed-%d serif-%d italic-%d script-%d bold-%d\n",
- isfixed, isserif, isitalic, isscript, isbold);
+ isfixed, isserif, isitalic, isscript, isbold);
if (collection)
{
@@ -355,7 +354,11 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
}
}
- return pdf_loadbuiltinfont(font, name);
+ error = pdf_loadbuiltinfont(font, name);
+ if (error)
+ return fz_throw("cannot load builtin substitute font: %s", name);
+
+ return fz_okay;
}
fz_error *
@@ -368,24 +371,24 @@ pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
error = initfontlibs();
if (error)
- return error;
+ return fz_rethrow(error, "cannot init font libraries");
pdf_logfont("load embedded font\n");
error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
- return error;
+ return fz_rethrow(error, "cannot load font stream");
fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face);
-
- if (fterr) {
- fz_free(buf);
- return fz_throw("freetype could not load embedded font: 0x%x", fterr);
+ if (fterr)
+ {
+ fz_dropbuffer(buf);
+ return fz_throw("freetype: cannot load embedded font: 0x%x", fterr);
}
font->ftface = face;
font->fontdata = buf;
- return nil;
+ return fz_okay;
}
diff --git a/mupdf/pdf_fontfilems.c b/mupdf/pdf_fontfilems.c
index f37d8668..b30bbdec 100644
--- a/mupdf/pdf_fontfilems.c
+++ b/mupdf/pdf_fontfilems.c
@@ -610,10 +610,10 @@ pdf_createfontlistMS()
removeredundancy(&fontlistMS);
- return nil;
-
cleanup:
- fz_abort(err);
+ if(err)
+ fz_abort(err);
+ return nil;
}
void
@@ -644,7 +644,7 @@ pdf_lookupfontMS(char *fontname, char **fontpath, int *index)
strlcpy(fontmap.fontface,pattern,sizeof(fontmap.fontface));
found = localbsearch(&fontmap,fontlistMS.fontmap,fontlistMS.len,
- sizeof(pdf_fontmapMS),compare);
+ sizeof(pdf_fontmapMS),compare);
if(found)
{
diff --git a/mupdf/pdf_function.c b/mupdf/pdf_function.c
index c6cfd9a6..76142d8b 100644
--- a/mupdf/pdf_function.c
+++ b/mupdf/pdf_function.c
@@ -1,7 +1,7 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
-/* this mess is seokgyo's */
+/* this mess is seokgyo's doing */
enum
{
@@ -60,21 +60,15 @@ struct pdf_function_s
} u;
};
+/*
+ * PostScript calculator
+ */
+
#define RADIAN 57.2957795
#define LERP(x, xmin, xmax, ymin, ymax) \
(ymin) + ((x) - (xmin)) * ((ymax) - (ymin)) / ((xmax) - (xmin))
-#define SAFE_PUSHINT(st, a) {error = pspushint(st, a); if (error) goto cleanup;}
-#define SAFE_PUSHREAL(st, a) {error = pspushreal(st, a); if (error) goto cleanup;}
-#define SAFE_PUSHBOOL(st, a) {error = pspushbool(st, a); if (error) goto cleanup;}
-#define SAFE_POPINT(st, a) {error = pspopint(st, a); if (error) goto cleanup;}
-#define SAFE_POPNUM(st, a) {error = pspopnum(st, a); if (error) goto cleanup;}
-#define SAFE_POPBOOL(st, a) {error = pspopbool(st, a); if (error) goto cleanup;}
-#define SAFE_POP(st) {error = pspop(st); if (error) goto cleanup;}
-#define SAFE_INDEX(st, i) {error = psindex(st, i); if (error) goto cleanup;}
-#define SAFE_COPY(st, n) {error = pscopy(st, n); if (error) goto cleanup;}
-
enum { PSBOOL, PSINT, PSREAL, PSOPERATOR, PSBLOCK };
enum
@@ -111,15 +105,11 @@ struct psobj_s
} u;
};
-/*
- * PostScript calculator
- */
-
enum { PSSTACKSIZE = 100 };
-#define fz_stackoverflow fz_throw("rangecheck: stackoverflow in calculator")
-#define fz_stackunderflow fz_throw("rangecheck: stackunderflow in calculator")
-#define fz_stacktypemismatch fz_throw("typecheck: postscript calculator")
+#define fz_stackoverflow fz_throw("stack overflow in calculator function")
+#define fz_stackunderflow fz_throw("stack underflow in calculator function")
+#define fz_stacktypemismatch fz_throw("type mismatch in calculator function")
typedef struct psstack_s psstack;
@@ -149,95 +139,74 @@ pscheckunderflow(psstack *st)
}
static int
-pschecktype(psstack *st, unsigned short t1, unsigned short t2)
+pschecktype(psstack *st, unsigned short type)
{
- return (st->stack[st->sp].type == t1 ||
- st->stack[st->sp].type == t2);
+ return st->stack[st->sp].type == type;
}
static fz_error *
pspushbool(psstack *st, int booln)
{
- if (pscheckoverflow(st, 1))
- {
- st->stack[--st->sp].type = PSBOOL;
- st->stack[st->sp].u.b = booln;
- }
- else
+ if (!pscheckoverflow(st, 1))
return fz_stackoverflow;
- return nil;
+ st->stack[--st->sp].type = PSBOOL;
+ st->stack[st->sp].u.b = booln;
+ return fz_okay;
}
static fz_error *
pspushint(psstack *st, int intg)
{
- if (pscheckoverflow(st, 1))
- {
- st->stack[--st->sp].type = PSINT;
- st->stack[st->sp].u.i = intg;
- }
- else
+ if (!pscheckoverflow(st, 1))
return fz_stackoverflow;
- return nil;
+ st->stack[--st->sp].type = PSINT;
+ st->stack[st->sp].u.i = intg;
+ return fz_okay;
}
static fz_error *
pspushreal(psstack *st, float real)
{
- if (pscheckoverflow(st, 1))
- {
- st->stack[--st->sp].type = PSREAL;
- st->stack[st->sp].u.f = real;
- }
- else
+ if (!pscheckoverflow(st, 1))
return fz_stackoverflow;
- return nil;
+ st->stack[--st->sp].type = PSREAL;
+ st->stack[st->sp].u.f = real;
+ return fz_okay;
}
static fz_error *
pspopbool(psstack *st, int *booln)
{
- if (pscheckunderflow(st) && pschecktype(st, PSBOOL, PSBOOL))
- {
- *booln = st->stack[st->sp++].u.b;
- }
- else if (pscheckunderflow(st))
+ if (!pscheckunderflow(st))
return fz_stackunderflow;
- else
+ if (!pschecktype(st, PSBOOL))
return fz_stacktypemismatch;
- return nil;
+ *booln = st->stack[st->sp++].u.b;
+ return fz_okay;
}
static fz_error *
pspopint(psstack *st, int *intg)
{
- if (pscheckunderflow(st) && pschecktype(st, PSINT, PSINT))
- {
- *intg = st->stack[st->sp++].u.i;
- }
- else if (pscheckunderflow(st))
+ if (!pscheckunderflow(st))
return fz_stackunderflow;
- else
+ if (!pschecktype(st, PSINT))
return fz_stacktypemismatch;
- return nil;
+ *intg = st->stack[st->sp++].u.i;
+ return fz_okay;
}
static fz_error *
pspopnum(psstack *st, float *real)
{
- if (pscheckunderflow(st) && pschecktype(st, PSINT, PSREAL))
- {
- float ret;
- ret = (st->stack[st->sp].type == PSINT) ?
- (float) st->stack[st->sp].u.i : st->stack[st->sp].u.f;
- ++st->sp;
- *real = ret;
- }
- else if (pscheckunderflow(st))
+ if (!pscheckunderflow(st))
return fz_stackunderflow;
- else
+ if (!pschecktype(st, PSINT) && !pschecktype(st, PSREAL))
return fz_stacktypemismatch;
- return nil;
+ *real = (st->stack[st->sp].type == PSINT) ?
+ st->stack[st->sp].u.i : st->stack[st->sp].u.f;
+ ++st->sp;
+ return fz_okay;
}
static int
@@ -250,8 +219,8 @@ static int
pstoptwoareints(psstack *st)
{
return st->sp < PSSTACKSIZE - 1 &&
- st->stack[st->sp].type == PSINT &&
- st->stack[st->sp + 1].type == PSINT;
+ st->stack[st->sp].type == PSINT &&
+ st->stack[st->sp + 1].type == PSINT;
}
static int
@@ -264,8 +233,8 @@ static int
pstoptwoarenums(psstack *st)
{
return st->sp < PSSTACKSIZE - 1 &&
- (st->stack[st->sp].type == PSINT || st->stack[st->sp].type == PSREAL) &&
- (st->stack[st->sp + 1].type == PSINT || st->stack[st->sp + 1].type == PSREAL);
+ (st->stack[st->sp].type == PSINT || st->stack[st->sp].type == PSREAL) &&
+ (st->stack[st->sp + 1].type == PSINT || st->stack[st->sp + 1].type == PSREAL);
}
static fz_error *
@@ -282,7 +251,7 @@ pscopy(psstack *st, int n)
}
st->sp -= n;
- return nil;
+ return fz_okay;
}
static void
@@ -309,6 +278,7 @@ psroll(psstack *st, int n, int j)
}
for (i = 0; i < j; ++i)
{
+ /* FIXME check for underflow? */
obj = st->stack[st->sp];
for (k = st->sp; k < st->sp + n - 1; ++k)
{
@@ -322,23 +292,19 @@ static fz_error *
psindex(psstack *st, int i)
{
if (!pscheckoverflow(st, 1))
- {
return fz_stackoverflow;
- }
--st->sp;
st->stack[st->sp] = st->stack[st->sp + 1 + i];
- return nil;
+ return fz_okay;
}
static fz_error *
pspop(psstack *st)
{
if (!pscheckoverflow(st, 1))
- {
return fz_stackoverflow;
- }
++st->sp;
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -350,19 +316,18 @@ resizecode(pdf_function *func, int newsize)
psobj *newcode;
newcode = fz_realloc(func->u.p.code, newcodecap * sizeof(psobj));
if (!newcode)
- return fz_outofmem;
+ return fz_throw("outofmem: calculator function code");
func->u.p.cap = newcodecap;
func->u.p.code = newcode;
}
- return nil;
+ return fz_okay;
}
static fz_error *
parsecode(pdf_function *func, fz_stream *stream, int *codeptr)
{
- fz_error *error = nil;
- unsigned char buf[64];
- int buflen = sizeof(buf) / sizeof(buf[0]);
+ fz_error *error;
+ char buf[64];
int len;
int token;
int opptr, elseptr;
@@ -372,62 +337,80 @@ parsecode(pdf_function *func, fz_stream *stream, int *codeptr)
while (1)
{
- token = pdf_lex(stream, buf, buflen, &len);
-
- if (token == PDF_TERROR || token == PDF_TEOF)
- goto cleanup;
+ error = pdf_lex(&token, stream, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "calculator function lexical error");
switch(token)
{
+ case PDF_TEOF:
+ return fz_throw("truncated calculator function");
+
case PDF_TINT:
- resizecode(func, *codeptr);
+ error = resizecode(func, *codeptr);
+ if (error)
+ return fz_rethrow(error, "resize calculator function code");
func->u.p.code[*codeptr].type = PSINT;
- func->u.p.code[*codeptr].u.i = atoi((char *) buf);
+ func->u.p.code[*codeptr].u.i = atoi(buf);
++*codeptr;
break;
case PDF_TREAL:
- resizecode(func, *codeptr);
+ error = resizecode(func, *codeptr);
+ if (error)
+ return fz_rethrow(error, "resize calculator function code");
func->u.p.code[*codeptr].type = PSREAL;
- func->u.p.code[*codeptr].u.f = atof((char *) buf);
+ func->u.p.code[*codeptr].u.f = atof(buf);
++*codeptr;
break;
case PDF_TOBRACE:
opptr = *codeptr;
*codeptr += 3;
- resizecode(func, opptr + 2);
- error = parsecode(func, stream, codeptr);
- if (error) goto cleanup;
- token = pdf_lex(stream, buf, buflen, &len);
+ error = resizecode(func, opptr + 2);
+ if (error)
+ return fz_rethrow(error, "resize calculator function code");
+
+ error = parsecode(func, stream, codeptr);
+ if (error)
+ return fz_rethrow(error, "error in 'if' branch");
- if (token == PDF_TEOF || token == PDF_TERROR)
- goto cleanup;
+ error = pdf_lex(&token, stream, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "calculator function syntax error");
- if (token == PDF_TOBRACE) {
+ if (token == PDF_TOBRACE)
+ {
elseptr = *codeptr;
error = parsecode(func, stream, codeptr);
- if (error) goto cleanup;
- token = pdf_lex(stream, buf, buflen, &len);
- if (token == PDF_TERROR || token == PDF_TEOF)
- goto cleanup;
+ if (error)
+ return fz_rethrow(error, "error in 'else' branch");
+
+ error = pdf_lex(&token, stream, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "calculator function syntax error");
}
- else
+ else
+ {
elseptr = -1;
+ }
- if (token == PDF_TKEYWORD) {
- if (!strcmp((char *) buf, "if")) {
+ if (token == PDF_TKEYWORD)
+ {
+ if (!strcmp(buf, "if"))
+ {
if (elseptr >= 0)
- goto cleanup;
+ return fz_throw("too many branches for 'if'");
func->u.p.code[opptr].type = PSOPERATOR;
func->u.p.code[opptr].u.op = PSOIF;
func->u.p.code[opptr+2].type = PSBLOCK;
func->u.p.code[opptr+2].u.block = *codeptr;
}
- else if (!strcmp((char *) buf, "ifelse")) {
+ else if (!strcmp(buf, "ifelse"))
+ {
if (elseptr < 0)
- goto cleanup;
+ return fz_throw("not enough branches for 'ifelse'");
func->u.p.code[opptr].type = PSOPERATOR;
func->u.p.code[opptr].u.op = PSOIFELSE;
func->u.p.code[opptr+1].type = PSBLOCK;
@@ -436,91 +419,107 @@ parsecode(pdf_function *func, fz_stream *stream, int *codeptr)
func->u.p.code[opptr+2].u.block = *codeptr;
}
else
- goto cleanup;
+ {
+ return fz_throw("unknown keyword in 'if-else' context: '%s'", buf);
+ }
}
else
- goto cleanup;
+ {
+ return fz_throw("missing keyword in 'if-else' context");
+ }
break;
case PDF_TCBRACE:
- resizecode(func, *codeptr);
+ error = resizecode(func, *codeptr);
+ if (error)
+ return fz_rethrow(error, "resize calculator function code");
func->u.p.code[*codeptr].type = PSOPERATOR;
func->u.p.code[*codeptr].u.op = PSORETURN;
++*codeptr;
- return nil;
+ return fz_okay;
case PDF_TKEYWORD:
+ cmp = -1;
a = -1;
b = sizeof(psopnames) / sizeof(psopnames[0]);
- /* invariant: psopnames[a] < op < psopnames[b] */
- while (b - a > 1) {
+ while (b - a > 1)
+ {
mid = (a + b) / 2;
- cmp = strcmp((char *) buf, psopnames[mid]);
- if (cmp > 0) {
+ cmp = strcmp(buf, psopnames[mid]);
+ if (cmp > 0)
a = mid;
- } else if (cmp < 0) {
+ else if (cmp < 0)
b = mid;
- } else {
+ else
a = b = mid;
- }
}
if (cmp != 0)
- goto cleanup;
+ return fz_throw("unknown operator: '%s'", buf);
+
+ error = resizecode(func, *codeptr);
+ if (error)
+ return fz_rethrow(error, "resize calculator function code");
- resizecode(func, *codeptr);
func->u.p.code[*codeptr].type = PSOPERATOR;
func->u.p.code[*codeptr].u.op = a;
++*codeptr;
break;
default:
- goto cleanup;
+ return fz_throw("calculator function syntax error");
}
}
- return nil;
-
-cleanup:
- if (error) return error;
- return fz_throw("syntaxerror: postscript calculator");
}
static fz_error *
loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen)
{
- fz_error *error = nil;
+ fz_error *error;
fz_stream *stream;
int codeptr;
pdf_logrsrc("load postscript function %d %d\n", oid, gen);
error = pdf_openstream(&stream, xref, oid, gen);
- if (error) goto cleanup;
+ if (error)
+ return fz_rethrow(error, "cannot open calculator function stream");
if (fz_readbyte(stream) != '{')
- goto cleanup;
+ {
+ fz_dropstream(stream);
+ return fz_throw("stream is not a calculator function");
+ }
func->u.p.code = nil;
func->u.p.cap = 0;
-
codeptr = 0;
error = parsecode(func, stream, &codeptr);
- if (error) goto cleanup;
-
- fz_dropstream(stream);
-
- return nil;
+ if (error)
+ {
+ fz_dropstream(stream);
+ return fz_rethrow(error, "cannot parse calculator function");
+ }
-cleanup:
fz_dropstream(stream);
- if (error) return error;
- return fz_throw("syntaxerror: postscript calculator");
+ return fz_okay;
}
+#define SAFE_RETHROW if (error) fz_rethrow(error, "runtime error in calculator function")
+#define SAFE_PUSHINT(st, a) { error = pspushint(st, a); SAFE_RETHROW; }
+#define SAFE_PUSHREAL(st, a) { error = pspushreal(st, a); SAFE_RETHROW; }
+#define SAFE_PUSHBOOL(st, a) { error = pspushbool(st, a); SAFE_RETHROW; }
+#define SAFE_POPINT(st, a) { error = pspopint(st, a); SAFE_RETHROW; }
+#define SAFE_POPNUM(st, a) { error = pspopnum(st, a); SAFE_RETHROW; }
+#define SAFE_POPBOOL(st, a) { error = pspopbool(st, a); SAFE_RETHROW; }
+#define SAFE_POP(st) { error = pspop(st); SAFE_RETHROW; }
+#define SAFE_INDEX(st, i) { error = psindex(st, i); SAFE_RETHROW; }
+#define SAFE_COPY(st, n) { error = pscopy(st, n); SAFE_RETHROW; }
+
static fz_error *
evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
{
- fz_error *error = nil;
+ fz_error *error;
int i1, i2;
float r1, r2;
int b1, b2;
@@ -544,7 +543,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
if (pstopisint(st)) {
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, abs(i1));
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r1);
SAFE_PUSHREAL(st, fabs(r1));
}
@@ -555,7 +555,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, i1 + i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHREAL(st, r1 + r2);
@@ -567,7 +568,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, i1 & i2);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b2);
SAFE_POPBOOL(st, &b1);
SAFE_PUSHBOOL(st, b1 && b2);
@@ -585,9 +587,11 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i1);
if (i2 > 0) {
SAFE_PUSHINT(st, i1 << i2);
- } else if (i2 < 0) {
+ }
+ else if (i2 < 0) {
SAFE_PUSHINT(st, (int)((unsigned int)i1 >> i2));
- } else {
+ }
+ else {
SAFE_PUSHINT(st, i1);
}
break;
@@ -638,11 +642,13 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 == i2);
- } else if (pstoptwoarenums(st)) {
+ }
+ else if (pstoptwoarenums(st)) {
SAFE_POPNUM(st, &r1);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 == r2);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b2);
SAFE_POPBOOL(st, &b2);
SAFE_PUSHBOOL(st, b1 == b2);
@@ -675,7 +681,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 >= i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 >= r2);
@@ -687,7 +694,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 > i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 > r2);
@@ -710,7 +718,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 <= i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 <= r2);
@@ -732,7 +741,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 < i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 < r2);
@@ -749,9 +759,10 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
if (pstoptwoareints(st)) {
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
- /*~ should check for out-of-range, and push a real instead */
+ /* FIXME should check for out-of-range, and push a real instead */
SAFE_PUSHINT(st, i1 * i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHREAL(st, r1 * r2);
@@ -763,11 +774,13 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHBOOL(st, i1 != i2);
- } else if (pstoptwoarenums(st)) {
+ }
+ else if (pstoptwoarenums(st)) {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHBOOL(st, r1 != r2);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b2);
SAFE_POPBOOL(st, &b1);
SAFE_PUSHBOOL(st, b1 != b2);
@@ -778,7 +791,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
if (pstopisint(st)) {
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, -i1);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r1);
SAFE_PUSHREAL(st, -r1);
}
@@ -788,7 +802,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
if (pstopisint(st)) {
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, ~i1);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b1);
SAFE_PUSHBOOL(st, !b1);
}
@@ -799,7 +814,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, i1 | i2);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b2);
SAFE_POPBOOL(st, &b1);
SAFE_PUSHBOOL(st, b1 || b2);
@@ -838,7 +854,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, i1 - i2);
- } else {
+ }
+ else {
SAFE_POPNUM(st, &r2);
SAFE_POPNUM(st, &r1);
SAFE_PUSHREAL(st, r1 - r2);
@@ -861,7 +878,8 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
SAFE_POPINT(st, &i2);
SAFE_POPINT(st, &i1);
SAFE_PUSHINT(st, i1 ^ i2);
- } else {
+ }
+ else {
SAFE_POPBOOL(st, &b2);
SAFE_POPBOOL(st, &b1);
SAFE_PUSHBOOL(st, b1 ^ b2);
@@ -871,7 +889,9 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
case PSOIF:
SAFE_POPBOOL(st, &b1);
if (b1) {
- evalpostscriptfunc(func, st, codeptr + 2);
+ error = evalpostscriptfunc(func, st, codeptr + 2);
+ if (error)
+ return fz_rethrow(error, "runtime error in if-branch");
}
codeptr = func->u.p.code[codeptr + 1].u.block;
break;
@@ -879,26 +899,30 @@ evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr)
case PSOIFELSE:
SAFE_POPBOOL(st, &b1);
if (b1) {
- evalpostscriptfunc(func, st, codeptr + 2);
- } else {
- evalpostscriptfunc(func, st, func->u.p.code[codeptr].u.block);
+ error = evalpostscriptfunc(func, st, codeptr + 2);
+ if (error)
+ return fz_rethrow(error, "runtime error in if-branch");
+ }
+ else {
+ error = evalpostscriptfunc(func, st, func->u.p.code[codeptr].u.block);
+ if (error)
+ return fz_rethrow(error, "runtime error in else-branch");
}
codeptr = func->u.p.code[codeptr + 1].u.block;
break;
case PSORETURN:
- return nil;
+ return fz_okay;
+
+ default:
+ return fz_throw("foreign operator in calculator function");
}
break;
default:
- return fz_throw("syntaxerror: postscript calculator");
- break;
+ return fz_throw("foreign object in calculator function");
}
}
-
-cleanup:
- return error;
}
/*
@@ -910,7 +934,7 @@ static int bps_supported[] = { 1, 2, 4, 8, 12, 16, 24, 32 };
static fz_error *
loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen)
{
- fz_error *error = nil;
+ fz_error *error;
fz_stream *stream;
fz_obj *obj;
int samplecount;
@@ -923,28 +947,28 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge
obj = fz_dictgets(dict, "Size");
if (!fz_isarray(obj) || fz_arraylen(obj) != func->m)
- goto cleanup0;
+ return fz_throw("malformed /Size");
for (i = 0; i < func->m; ++i)
func->u.sa.size[i] = fz_toint(fz_arrayget(obj, i));
obj = fz_dictgets(dict, "BitsPerSample");
if (!fz_isint(obj))
- goto cleanup0;
+ return fz_throw("malformed /BitsPerSample");
func->u.sa.bps = bps = fz_toint(obj);
- pdf_logrsrc("bsp %d\n", bps);
+ pdf_logrsrc("bps %d\n", bps);
for (i = 0; i < nelem(bps_supported); ++i)
if (bps == bps_supported[i])
break;
if (i == nelem(bps_supported))
- goto cleanup0;
+ return fz_throw("unsupported BitsPerSample (%d)", bps);
obj = fz_dictgets(dict, "Encode");
if (fz_isarray(obj))
{
if (fz_arraylen(obj) != func->m * 2)
- goto cleanup0;
+ return fz_throw("malformed /Encode");
for (i = 0; i < func->m; ++i)
{
func->u.sa.encode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0));
@@ -964,7 +988,7 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge
if (fz_isarray(obj))
{
if (fz_arraylen(obj) != func->n * 2)
- goto cleanup0;
+ return fz_throw("malformed /Decode");
for (i = 0; i < func->n; ++i)
{
func->u.sa.decode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0));
@@ -987,14 +1011,11 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge
func->u.sa.samples = fz_malloc(samplecount * sizeof(int));
if (!func->u.sa.samples)
- {
- error = fz_outofmem;
- goto cleanup0;
- }
+ return fz_throw("outofmem: samples");
error = pdf_openstream(&stream, xref, oid, gen);
if (error)
- goto cleanup0;
+ return fz_rethrow(error, "cannot open samples stream");
/* read samples */
{
@@ -1007,8 +1028,11 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge
{
if (fz_peekbyte(stream) == EOF)
{
- error = fz_throw("syntaxerror: too few samples in function");
- goto cleanup1;
+ fz_dropstream(stream);
+ error = fz_readerror(stream);
+ if (error)
+ return fz_rethrow(error, "truncated sample stream");
+ return fz_throw("truncated sample stream");
}
if (bps == 8) {
@@ -1036,19 +1060,17 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge
func->u.sa.samples[i] = s;
}
+
+ error = fz_readerror(stream);
+ if (error)
+ return fz_rethrow(error, "truncated sample stream");
}
fz_dropstream(stream);
pdf_logrsrc("}\n");
- return nil;
-
-cleanup1:
- fz_dropstream(stream);
-cleanup0:
- if (error) return error;
- return fz_throw("syntaxerror: sample function");
+ return fz_okay;
}
static fz_error *
@@ -1069,7 +1091,7 @@ evalsamplefunc(pdf_function *func, float *in, float *out)
{
x = CLAMP(in[i], func->domain[i][0], func->domain[i][1]);
x = LERP(x, func->domain[i][0], func->domain[i][1],
- func->u.sa.encode[i][0], func->u.sa.encode[i][1]);
+ func->u.sa.encode[i][0], func->u.sa.encode[i][1]);
x = CLAMP(x, 0, func->u.sa.size[i] - 1);
e[0][i] = floor(x);
e[1][i] = ceil(x);
@@ -1081,7 +1103,7 @@ evalsamplefunc(pdf_function *func, float *in, float *out)
s0 = fz_malloc((1 << func->m) * 2 * sizeof(float));
s1 = s0 + (1 << func->m);
if (!s0)
- return fz_outofmem;
+ return fz_throw("outofmem: scratch buffer");
}
/* FIXME i think this is wrong... test with 2 samples it gets wrong idxs */
@@ -1107,14 +1129,14 @@ evalsamplefunc(pdf_function *func, float *in, float *out)
/* decode output values */
out[i] = LERP(s0[0], 0, (1 << func->u.sa.bps) - 1,
- func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
+ func->u.sa.decode[i][0], func->u.sa.decode[i][1]);
out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]);
}
if (func->m > 4)
fz_free(s0);
- return nil;
+ return fz_okay;
}
/*
@@ -1124,18 +1146,17 @@ evalsamplefunc(pdf_function *func, float *in, float *out)
static fz_error *
loadexponentialfunc(pdf_function *func, fz_obj *dict)
{
- fz_error *error = nil;
fz_obj *obj;
int i;
pdf_logrsrc("exponential function {\n");
if (func->m != 1)
- goto cleanup;
+ return fz_throw("/Domain must be one dimension (%d)", func->m);
obj = fz_dictgets(dict, "N");
if (!fz_isint(obj) && !fz_isreal(obj))
- goto cleanup;
+ return fz_throw("malformed /N");
func->u.e.n = fz_toreal(obj);
pdf_logrsrc("n %g\n", func->u.e.n);
@@ -1157,7 +1178,7 @@ loadexponentialfunc(pdf_function *func, fz_obj *dict)
if (fz_isarray(obj))
{
if (fz_arraylen(obj) != func->n)
- goto cleanup;
+ return fz_throw("/C1 must match /C0 length");
for (i = 0; i < func->n; ++i)
func->u.e.c1[i] = fz_toreal(fz_arrayget(obj, i));
pdf_logrsrc("c1 %d\n", func->n);
@@ -1165,23 +1186,18 @@ loadexponentialfunc(pdf_function *func, fz_obj *dict)
else
{
if (func->n != 1)
- goto cleanup;
+ return fz_throw("/C1 must match /C0 length");
func->u.e.c1[0] = 1;
}
pdf_logrsrc("}\n");
- return nil;
-
-cleanup:
- if (error) return error;
- return fz_throw("syntaxerror: exponential function");
+ return fz_okay;
}
static fz_error *
evalexponentialfunc(pdf_function *func, float in, float *out)
{
- fz_error *error = nil;
float x = in;
float tmp;
int i;
@@ -1190,9 +1206,9 @@ evalexponentialfunc(pdf_function *func, float in, float *out)
/* constraint */
if (func->u.e.n != (int)func->u.e.n && x < 0)
- goto cleanup;
+ return fz_throw("constraint error");
if (func->u.e.n < 0 && x == 0)
- goto cleanup;
+ return fz_throw("constraint error");
tmp = pow(x, func->u.e.n);
for (i = 0; i < func->n; ++i)
@@ -1202,11 +1218,7 @@ evalexponentialfunc(pdf_function *func, float in, float *out)
out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]);
}
- return nil;
-
-cleanup:
- if (error) return error;
- return fz_throw("rangecheck: exponential function");
+ return fz_okay;
}
/*
@@ -1217,7 +1229,7 @@ static fz_error *
loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict)
{
pdf_function **funcs = func->u.st.funcs;
- fz_error *error = nil;
+ fz_error *error;
fz_obj *obj;
fz_obj *sub;
fz_obj *num;
@@ -1229,34 +1241,50 @@ loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict)
func->u.st.k = 0;
if (func->m != 1)
- goto cleanup;
+ return fz_throw("/Domain must be one dimension (%d)", func->m);
obj = fz_dictgets(dict, "Functions");
{
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve /Functions");
k = fz_arraylen(obj);
func->u.st.k = k;
pdf_logrsrc("k %d\n", func->u.st.k);
- assert(k < MAXK);
+
+ if (k >= MAXK)
+ {
+ fz_dropobj(obj);
+ return fz_throw("assert: /K too big (%d)", k);
+ }
for (i = 0; i < k; ++i)
{
sub = fz_arrayget(obj, i);
error = pdf_loadfunction(funcs + i, xref, sub);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_rethrow(error, "cannot load sub function %d", i);
+ }
if (funcs[i]->m != 1 || funcs[i]->n != funcs[0]->n)
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_rethrow(error, "sub function %d /Domain or /Range mismatch", i);
+ }
}
if (!func->n)
+ {
func->n = funcs[0]->n;
+ }
else if (func->n != funcs[0]->n)
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_rethrow(error, "sub function /Domain or /Range mismatch");
+ }
fz_dropobj(obj);
}
@@ -1265,25 +1293,37 @@ loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict)
{
error = pdf_resolve(&obj, xref);
if (error)
- goto cleanup;
+ return fz_rethrow(error, "cannot resolve /Bounds");
if (!fz_isarray(obj) || fz_arraylen(obj) != k - 1)
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_throw("malformed /Bounds (not array or wrong length)");
+ }
for (i = 0; i < k-1; ++i)
{
num = fz_arrayget(obj, i);
if (!fz_isint(num) && !fz_isreal(num))
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_throw("malformed /Bounds (item not number)");
+ }
func->u.st.bounds[i] = fz_toreal(num);
if (i && func->u.st.bounds[i-1] >= func->u.st.bounds[i])
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_throw("malformed /Bounds (item not monotonic)");
+ }
}
if (k != 1 &&
- (func->domain[0][0] >= func->u.st.bounds[0] ||
- func->domain[0][1] <= func->u.st.bounds[k-2]))
- goto cleanup;
+ (func->domain[0][0] >= func->u.st.bounds[0] ||
+ func->domain[0][1] <= func->u.st.bounds[k-2]))
+ {
+ fz_dropobj(obj);
+ return fz_throw("malformed /Bounds (domain mismatch)");
+ }
fz_dropobj(obj);
}
@@ -1291,31 +1331,33 @@ loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict)
obj = fz_dictgets(dict, "Encode");
{
error = pdf_resolve(&obj, xref);
+ if (error)
+ return fz_rethrow(error, "cannot resolve /Encode");
+
if (!fz_isarray(obj) || fz_arraylen(obj) != k * 2)
- goto cleanup;
+ {
+ fz_dropobj(obj);
+ return fz_throw("malformed /Encode");
+ }
+
for (i = 0; i < k; ++i)
{
func->u.st.encode[i][0] = fz_toreal(fz_arrayget(obj, i*2+0));
func->u.st.encode[i][1] = fz_toreal(fz_arrayget(obj, i*2+1));
}
+
fz_dropobj(obj);
}
pdf_logrsrc("}\n");
- return nil;
-
-cleanup:
- fz_dropobj(obj);
- if (error)
- return error;
- return fz_throw("syntaxerror: stitching function");
+ return fz_okay;
}
static fz_error*
evalstitchingfunc(pdf_function *func, float in, float *out)
{
- fz_error *error = nil;
+ fz_error *error;
float low, high;
int k = func->u.st.k;
float *bounds = func->u.st.bounds;
@@ -1354,9 +1396,9 @@ evalstitchingfunc(pdf_function *func, float in, float *out)
error = pdf_evalfunction(func->u.st.funcs[i], &in, 1, out, func->n);
if (error)
- return error;
+ return fz_rethrow(error, "cannot evaluate sub function %d", i);
- return nil;
+ return fz_okay;
}
/*
@@ -1407,15 +1449,16 @@ pdf_loadfunction(pdf_function **funcp, pdf_xref *xref, fz_obj *ref)
if ((*funcp = pdf_finditem(xref->store, PDF_KFUNCTION, ref)))
{
pdf_keepfunction(*funcp);
- return nil;
+ return fz_okay;
}
pdf_logrsrc("load function %d %d {\n", fz_tonum(ref), fz_togen(ref));
func = fz_malloc(sizeof(pdf_function));
if (!func)
- return fz_outofmem;
+ return fz_throw("outofmem: function struct");
+ memset(func, 0, sizeof(pdf_function));
func->refs = 1;
dict = ref;
@@ -1423,7 +1466,7 @@ pdf_loadfunction(pdf_function **funcp, pdf_xref *xref, fz_obj *ref)
if (error)
{
fz_free(func);
- goto cleanup;
+ return fz_rethrow(error, "cannot resolve function object");
}
obj = fz_dictgets(dict, "FunctionType");
@@ -1460,38 +1503,59 @@ pdf_loadfunction(pdf_function **funcp, pdf_xref *xref, fz_obj *ref)
func->n = 0;
}
- assert(func->m < MAXM);
- assert(func->n < MAXN);
+ if (func->m >= MAXM || func->n >= MAXN)
+ {
+ fz_free(func);
+ fz_dropobj(dict);
+ return fz_throw("assert: /Domain or /Range too big");
+ }
switch(func->type)
{
case SAMPLE:
error = loadsamplefunc(func, xref, dict, fz_tonum(ref), fz_togen(ref));
if (error)
- goto cleanup;
+ {
+ pdf_dropfunction(func);
+ fz_dropobj(dict);
+ return fz_rethrow(error, "cannot load sampled function (%d)", fz_tonum(ref));
+ }
break;
case EXPONENTIAL:
error = loadexponentialfunc(func, dict);
if (error)
- goto cleanup;
+ {
+ pdf_dropfunction(func);
+ fz_dropobj(dict);
+ return fz_rethrow(error, "cannot load exponential function (%d)", fz_tonum(ref));
+ }
break;
case STITCHING:
error = loadstitchingfunc(func, xref, dict);
if (error)
- goto cleanup;
+ {
+ pdf_dropfunction(func);
+ fz_dropobj(dict);
+ return fz_rethrow(error, "cannot load stitching function (%d)", fz_tonum(ref));
+ }
break;
case POSTSCRIPT:
error = loadpostscriptfunc(func, xref, dict, fz_tonum(ref), fz_togen(ref));
if (error)
- goto cleanup;
+ {
+ pdf_dropfunction(func);
+ fz_dropobj(dict);
+ return fz_rethrow(error, "cannot load calculator function (%d)", fz_tonum(ref));
+ }
break;
default:
- error = fz_throw("syntaxerror: unknown function type");
- goto cleanup;
+ fz_free(func);
+ fz_dropobj(dict);
+ return fz_throw("unknown function type %d (function %d)", func->type, fz_tonum(ref));
}
fz_dropobj(dict);
@@ -1500,34 +1564,44 @@ pdf_loadfunction(pdf_function **funcp, pdf_xref *xref, fz_obj *ref)
error = pdf_storeitem(xref->store, PDF_KFUNCTION, ref, func);
if (error)
- goto cleanup;
+ {
+ pdf_dropfunction(func);
+ fz_dropobj(dict);
+ return fz_rethrow(error, "cannot store function resource");
+ }
*funcp = func;
- return nil;
-
-cleanup:
- fz_dropobj(dict);
- pdf_dropfunction(func);
- return error;
+ return fz_okay;
}
fz_error *
pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outlen)
{
- fz_error *error = nil;
+ fz_error *error;
int i;
if (func->m != inlen || func->n != outlen)
- return fz_throw("rangecheck: function argument count mismatch");
+ return fz_throw("function argument count mismatch");
switch(func->type)
{
case SAMPLE:
- return evalsamplefunc(func, in, out);
+ error = evalsamplefunc(func, in, out);
+ if (error)
+ return fz_rethrow(error, "cannot evaluate sampled function");
+ break;
+
case EXPONENTIAL:
- return evalexponentialfunc(func, *in, out);
+ error = evalexponentialfunc(func, *in, out);
+ if (error)
+ return fz_rethrow(error, "cannot evaluate exponential function");
+ break;
+
case STITCHING:
- return evalstitchingfunc(func, *in, out);
+ error = evalstitchingfunc(func, *in, out);
+ if (error)
+ return fz_rethrow(error, "cannot evaluate stitching function");
+ break;
case POSTSCRIPT:
{
@@ -1539,7 +1613,7 @@ pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outle
error = evalpostscriptfunc(func, &st, 0);
if (error)
- return error;
+ return fz_rethrow(error, "cannot evaluate calculator function");
for (i = func->n - 1; i >= 0; --i)
{
@@ -1547,10 +1621,12 @@ pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outle
out[i] = CLAMP(out[i], func->range[i][0], func->range[i][1]);
}
}
- return nil;
+ break;
+
+ default:
+ return fz_throw("assert: unknown function type");
}
-cleanup:
- return error;
+ return fz_okay;
}
diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c
index b6d7327a..27cc7680 100644
--- a/mupdf/pdf_image.c
+++ b/mupdf/pdf_image.c
@@ -28,7 +28,7 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref,
img = fz_malloc(sizeof(pdf_image));
if (!img)
- return fz_outofmem;
+ return fz_throw("outofmem: image struct");
pdf_logimage("load inline image %p {\n", img);
@@ -132,30 +132,26 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref,
if (error)
return error;
- if (filter == nil)
- goto thereisnofilter;
-
error = fz_openrfilter(&tempfile, filter, file);
if (error)
return error;
- i = fz_readall(&img->samples, tempfile);
- if (i < 0)
- return fz_ioerror(tempfile);
+ error = fz_readall(&img->samples, tempfile);
+ if (error)
+ return error;
fz_dropfilter(filter);
fz_dropstream(tempfile);
}
else
{
-thereisnofilter:
error = fz_newbuffer(&img->samples, img->super.h * img->stride);
if (error)
return error;
- i = fz_read(file, img->samples->bp, img->super.h * img->stride);
- if (i < 0)
- return fz_ioerror(file);
+ error = fz_read(&i, file, img->samples->bp, img->super.h * img->stride);
+ if (error)
+ return error;
img->samples->wp += img->super.h * img->stride;
}
@@ -225,7 +221,7 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
img = fz_malloc(sizeof(pdf_image));
if (!img)
- return fz_outofmem;
+ return fz_throw("outofmem: image struct");
pdf_logimage("load image %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), img);
diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c
index a458750b..0404a292 100644
--- a/mupdf/pdf_interpret.c
+++ b/mupdf/pdf_interpret.c
@@ -8,9 +8,9 @@ pdf_newcsi(pdf_csi **csip, int maskonly)
pdf_csi *csi;
fz_node *node;
- csi = *csip = fz_malloc(sizeof(pdf_csi));
+ csi = fz_malloc(sizeof(pdf_csi));
if (!csi)
- return fz_outofmem;
+ return fz_throw("outofmem: interpreter struct");
pdf_initgstate(&csi->gstate[0]);
@@ -22,14 +22,14 @@ pdf_newcsi(pdf_csi **csip, int maskonly)
error = fz_newpathnode(&csi->path);
if (error) {
fz_free(csi);
- return error;
+ return fz_rethrow(error, "cannot create path node");
}
error = fz_newtree(&csi->tree);
if (error) {
fz_dropnode((fz_node*)csi->path);
fz_free(csi);
- return error;
+ return fz_rethrow(error, "cannot create tree");
}
error = fz_newovernode(&node);
@@ -50,7 +50,8 @@ pdf_newcsi(pdf_csi **csip, int maskonly)
csi->tm = fz_identity();
csi->tlm = fz_identity();
- return nil;
+ *csip = csi;
+ return fz_okay;
}
static void
@@ -107,7 +108,7 @@ gsave(pdf_csi *csi)
pdf_keepmaterial(&gs->stroke);
pdf_keepmaterial(&gs->fill);
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -123,14 +124,14 @@ grestore(pdf_csi *csi)
csi->gtop --;
- return nil;
+ return fz_okay;
}
void
pdf_dropcsi(pdf_csi *csi)
{
while (csi->gtop)
- grestore(csi);
+ grestore(csi); /* no need to check for impossible errors */
if (csi->gstate[csi->gtop].fill.cs)
fz_dropcolorspace(csi->gstate[csi->gtop].fill.cs);
@@ -176,13 +177,13 @@ runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj)
error = fz_newtransformnode(&transform, xobj->matrix);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create transform node");
error = pdf_addtransform(csi->gstate + csi->gtop, transform);
if (error)
{
fz_dropnode(transform);
- return error;
+ return fz_rethrow(error, "cannot add transform node");
}
/* run contents */
@@ -191,21 +192,21 @@ runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj)
error = fz_openrbuffer(&file, xobj->contents);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open XObject stream");
error = pdf_runcsi(csi, xref, xobj->resources, file);
fz_dropstream(file);
if (error)
- return error;
+ return fz_rethrow(error, "cannot interpret XObject stream");
/* grestore */
error = grestore(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot grestore");
- return nil;
+ return fz_okay;
}
/*
@@ -217,26 +218,36 @@ runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file, fz_ob
{
fz_error *error;
pdf_image *img;
- unsigned char buf[256];
+ char buf[256];
int token;
int len;
error = pdf_loadinlineimage(&img, xref, rdb, dict, file);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load inline image");
- token = pdf_lex(file, buf, sizeof buf, &len);
- if (token != PDF_TKEYWORD || memcmp("EI", buf, 2))
- fz_warn("syntaxerror: corrupt inline image");
+ error = pdf_lex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ {
+ fz_dropimage((fz_image*)img);
+ return fz_rethrow(error, "syntax error after inline image");
+ }
+
+ if (token != PDF_TKEYWORD || strcmp("EI", buf))
+ {
+ fz_dropimage((fz_image*)img);
+ return fz_throw("syntax error after inline image");
+ }
error = pdf_showimage(csi, img);
if (error)
{
fz_dropimage((fz_image*)img);
- return error;
+ return fz_rethrow(error, "cannot draw image");
}
- return nil;
+ fz_dropimage((fz_image*)img);
+ return fz_okay;
}
/*
@@ -260,11 +271,11 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
{
gstate->font = pdf_finditem(xref->store, PDF_KFONT, fz_arrayget(val, 0));
if (!gstate->font)
- return fz_throw("syntaxerror: missing font resource");
+ return fz_throw("cannot find font in store");
gstate->size = fz_toreal(fz_arrayget(val, 1));
}
else
- return fz_throw("syntaxerror in ExtGState/Font");
+ return fz_throw("malformed /Font");
}
else if (!strcmp(s, "LW"))
@@ -287,7 +298,7 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
gstate->dashphase = fz_toreal(fz_arrayget(val, 1));
}
else
- return fz_throw("syntaxerror in ExtGState/D");
+ return fz_throw("malformed /D");
}
else if (!strcmp(s, "CA"))
@@ -296,7 +307,7 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
gstate->fill.alpha = fz_toreal(val);
}
- return nil;
+ return fz_okay;
}
/*
@@ -377,9 +388,12 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
m.f = fz_toreal(csi->stack[5]);
error = fz_newtransformnode(&transform, m);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot concatenate matrix");
+
error = pdf_addtransform(gstate, transform);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot concatenate matrix");
}
else if (!strcmp(buf, "ri"))
@@ -398,33 +412,37 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
dict = fz_dictgets(rdb, "ExtGState");
if (!dict)
- return fz_throw("syntaxerror: missing extgstate resource");
+ return fz_throw("cannot find ExtGState dictionary");
obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
- return fz_throw("syntaxerror: missing extgstate resource");
+ return fz_throw("cannot find extgstate resource /%s", fz_toname(csi->stack[0]));
- runextgstate(gstate, xref, obj);
+ error = runextgstate(gstate, xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot set ExtGState");
}
else if (!strcmp(buf, "re"))
{
if (csi->top != 4)
goto syntaxerror;
+
x = fz_toreal(csi->stack[0]);
y = fz_toreal(csi->stack[1]);
w = fz_toreal(csi->stack[2]);
h = fz_toreal(csi->stack[3]);
+
error = fz_moveto(csi->path, x, y);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw rectangle");
error = fz_lineto(csi->path, x + w, y);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw rectangle");
error = fz_lineto(csi->path, x + w, y + h);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw rectangle");
error = fz_lineto(csi->path, x, y + h);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw rectangle");
error = fz_closepath(csi->path);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw rectangle");
}
else if (!strcmp(buf, "f*"))
@@ -432,7 +450,7 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 1, 0, 1);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
}
else if (!strcmp(buf, "B*"))
@@ -440,7 +458,7 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 1, 1, 1);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
}
else if (!strcmp(buf, "b*"))
@@ -448,7 +466,7 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 1, 1, 1, 1);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
}
else if (!strcmp(buf, "W*"))
@@ -480,10 +498,10 @@ Lsetcolorspace:
if (!strcmp(fz_toname(obj), "Pattern"))
{
error = pdf_setpattern(csi, what, nil, nil);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set pattern");
}
- else
+ else
{
if (!strcmp(fz_toname(obj), "DeviceGray"))
cs = pdf_devicegray;
@@ -495,18 +513,18 @@ Lsetcolorspace:
{
fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
if (!dict)
- return fz_throw("syntaxerror: missing colorspace resource");
+ return fz_throw("cannot find ColorSpace dictionary");
obj = fz_dictget(dict, obj);
if (!obj)
- return fz_throw("syntaxerror: missing colorspace resource");
+ return fz_throw("cannot find colorspace resource /%s", fz_toname(csi->stack[0]));
cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj);
if (!cs)
- return fz_throw("syntaxerror: missing colorspace resource");
+ return fz_throw("cannot find colorspace in store");
}
error = pdf_setcolorspace(csi, what, cs);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set colorspace");
}
}
@@ -537,14 +555,14 @@ Lsetcolor:
switch (kind)
{
case PDF_MNONE:
- return fz_throw("syntaxerror: cannot set color in mask objects");
+ return fz_throw("cannot set color in mask objects");
case PDF_MINDEXED:
if (csi->top != 1)
goto syntaxerror;
v[0] = fz_toreal(csi->stack[0]);
error = pdf_setcolor(csi, what, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set indexed color");
break;
case PDF_MCOLOR:
@@ -554,7 +572,7 @@ Lsetcolor:
for (i = 0; i < csi->top; i++)
v[i] = fz_toreal(csi->stack[i]);
error = pdf_setcolor(csi, what, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set color");
break;
case PDF_MPATTERN:
@@ -563,33 +581,34 @@ Lsetcolor:
dict = fz_dictgets(rdb, "Pattern");
if (!dict)
- return fz_throw("syntaxerror: missing pattern resource");
+ return fz_throw("cannot find Pattern dictionary");
obj = fz_dictget(dict, csi->stack[csi->top - 1]);
if (!obj)
- return fz_throw("syntaxerror: missing pattern resource");
+ return fz_throw("cannot find pattern resource /%s",
+ fz_toname(csi->stack[csi->top - 1]));
pat = pdf_finditem(xref->store, PDF_KPATTERN, obj);
if (pat)
{
error = pdf_setpattern(csi, what, pat, csi->top == 1 ? nil : v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set pattern");
}
shd = pdf_finditem(xref->store, PDF_KSHADE, obj);
if (shd)
{
error = pdf_setshade(csi, what, shd);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set shade");
}
if (!pat && !shd)
- return fz_throw("syntaxerror: missing pattern resource");
+ return fz_throw("cannot find pattern or shade in store");
break;
case PDF_MSHADE:
- return fz_throw("syntaxerror: cannot set color in shade objects");
+ return fz_throw("cannot set color in shade objects");
}
}
@@ -603,9 +622,9 @@ Lsetcolor:
v[2] = fz_toreal(csi->stack[2]);
error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicergb);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set rgb colorspace");
error = pdf_setcolor(csi, PDF_MFILL, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set rgb color");
}
else if (!strcmp(buf, "RG"))
@@ -618,9 +637,9 @@ Lsetcolor:
v[2] = fz_toreal(csi->stack[2]);
error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicergb);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set rgb colorspace");
error = pdf_setcolor(csi, PDF_MSTROKE, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set rgb color");
}
else if (!strcmp(buf, "BT"))
@@ -638,12 +657,12 @@ Lsetcolor:
error = pdf_flushtext(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot finish text object (ET)");
if (csi->textclip)
{
error = pdf_addclipmask(gstate, csi->textclip);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot add text clip mask");
csi->textclip = nil;
}
}
@@ -668,7 +687,8 @@ Lsetcolor:
goto syntaxerror;
error = pdf_flushtext(csi);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot finish text object (state change)");
gstate->scale = fz_toreal(csi->stack[0]) / 100.0;
}
@@ -690,15 +710,15 @@ Lsetcolor:
dict = fz_dictgets(rdb, "Font");
if (!dict)
- return fz_throw("syntaxerror: missing font resource");
+ return fz_throw("cannot find Font dictionary");
obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
- return fz_throw("syntaxerror: missing font resource");
+ return fz_throw("cannot find font resource: %s", fz_toname(csi->stack[0]));
gstate->font = pdf_finditem(xref->store, PDF_KFONT, obj);
if (!gstate->font)
- return fz_throw("syntaxerror: missing font resource");
+ return fz_throw("cannot find font in store");
gstate->size = fz_toreal(csi->stack[1]);
}
@@ -742,7 +762,8 @@ Lsetcolor:
goto syntaxerror;
error = pdf_flushtext(csi);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot finish text object (state change)");
csi->tm.a = fz_toreal(csi->stack[0]);
csi->tm.b = fz_toreal(csi->stack[1]);
@@ -767,7 +788,7 @@ Lsetcolor:
if (csi->top != 1)
goto syntaxerror;
error = pdf_showtext(csi, csi->stack[0]);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw text");
}
else if (!strcmp(buf, "TJ"))
@@ -775,7 +796,7 @@ Lsetcolor:
if (csi->top != 1)
goto syntaxerror;
error = pdf_showtext(csi, csi->stack[0]);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw text");
}
else if (!strcmp(buf, "Do"))
@@ -790,26 +811,23 @@ Lsetcolor:
dict = fz_dictgets(rdb, "XObject");
if (!dict)
-{
-fz_debugobj(rdb);
- return fz_throw("syntaxerror: missing xobject resource");
-}
+ return fz_throw("cannot find XObject dictionary");
obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
- return fz_throw("syntaxerror: missing xobject resource");
+ return fz_throw("cannot find xobject resource: %s", fz_toname(csi->stack[0]));
img = pdf_finditem(xref->store, PDF_KIMAGE, obj);
xobj = pdf_finditem(xref->store, PDF_KXOBJECT, obj);
if (!img && !xobj)
- return fz_throw("syntaxerror: missing xobject resource");
+ return fz_throw("cannot find image or xobject in store");
if (img)
{
error = pdf_showimage(csi, img);
if (error)
- return error;
+ return fz_rethrow(error, "cannot draw image");
}
if (xobj)
@@ -817,7 +835,7 @@ fz_debugobj(rdb);
clearstack(csi);
error = runxobject(csi, xref, xobj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot draw xobject");
}
}
@@ -832,18 +850,18 @@ fz_debugobj(rdb);
dict = fz_dictgets(rdb, "Shading");
if (!dict)
- return fz_throw("syntaxerror: missing shading resource");
+ return fz_throw("cannot find Shading dictionary");
obj = fz_dictget(dict, csi->stack[csi->top - 1]);
if (!obj)
- return fz_throw("syntaxerror: missing shading resource");
+ return fz_throw("cannot find shade resource: %s", fz_toname(csi->stack[csi->top - 1]));
shd = pdf_finditem(xref->store, PDF_KSHADE, obj);
if (!shd)
- return fz_throw("syntaxerror: missing shading resource");
+ return fz_throw("cannot find shade in store");
error = pdf_addshade(gstate, shd);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw shade");
}
else if (!strcmp(buf, "d0"))
@@ -856,7 +874,11 @@ fz_debugobj(rdb);
}
else
- if (!csi->xbalance) goto syntaxerror;
+ {
+ /* don't fail on unknown keywords if braced by BX/EX */
+ if (!csi->xbalance)
+ goto syntaxerror;
+ }
}
else switch (buf[0])
@@ -867,7 +889,7 @@ fz_debugobj(rdb);
goto syntaxerror;
error = gsave(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot gsave");
break;
case 'Q':
@@ -875,7 +897,7 @@ fz_debugobj(rdb);
goto syntaxerror;
error = grestore(csi);
if (error)
- return error;
+ return fz_rethrow(error, "cannot grestore");
break;
case 'w':
@@ -910,7 +932,7 @@ fz_debugobj(rdb);
fz_obj *array = csi->stack[0];
gstate->dashlen = fz_arraylen(array);
if (gstate->dashlen > 32)
- return fz_throw("rangecheck: too large dash pattern");
+ return fz_throw("assert: dash pattern too big");
for (i = 0; i < gstate->dashlen; i++)
gstate->dashlist[i] = fz_toreal(fz_arrayget(array, i));
gstate->dashphase = fz_toreal(csi->stack[1]);
@@ -928,14 +950,18 @@ fz_debugobj(rdb);
goto syntaxerror;
a = fz_toreal(csi->stack[0]);
b = fz_toreal(csi->stack[1]);
- return fz_moveto(csi->path, a, b);
+ error = fz_moveto(csi->path, a, b);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'l':
if (csi->top != 2)
goto syntaxerror;
a = fz_toreal(csi->stack[0]);
b = fz_toreal(csi->stack[1]);
- return fz_lineto(csi->path, a, b);
+ error = fz_lineto(csi->path, a, b);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'c':
if (csi->top != 6)
@@ -946,7 +972,9 @@ fz_debugobj(rdb);
d = fz_toreal(csi->stack[3]);
e = fz_toreal(csi->stack[4]);
f = fz_toreal(csi->stack[5]);
- return fz_curveto(csi->path, a, b, c, d, e, f);
+ error = fz_curveto(csi->path, a, b, c, d, e, f);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'v':
if (csi->top != 4)
@@ -955,7 +983,9 @@ fz_debugobj(rdb);
b = fz_toreal(csi->stack[1]);
c = fz_toreal(csi->stack[2]);
d = fz_toreal(csi->stack[3]);
- return fz_curvetov(csi->path, a, b, c, d);
+ error = fz_curvetov(csi->path, a, b, c, d);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'y':
if (csi->top != 4)
@@ -964,25 +994,29 @@ fz_debugobj(rdb);
b = fz_toreal(csi->stack[1]);
c = fz_toreal(csi->stack[2]);
d = fz_toreal(csi->stack[3]);
- return fz_curvetoy(csi->path, a, b, c, d);
+ error = fz_curvetoy(csi->path, a, b, c, d);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'h':
if (csi->top != 0)
goto syntaxerror;
- return fz_closepath(csi->path);
+ error = fz_closepath(csi->path);
+ if (error) return fz_rethrow(error, "cannot create path node");
+ break;
case 'S':
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 0, 1, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 's':
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 1, 0, 1, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 'F':
@@ -990,28 +1024,28 @@ fz_debugobj(rdb);
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 1, 0, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 'B':
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 1, 1, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 'b':
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 1, 1, 1, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 'n':
if (csi->top != 0)
goto syntaxerror;
error = pdf_showpath(csi, 0, 0, 0, 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw path");
break;
case 'W':
@@ -1020,15 +1054,15 @@ fz_debugobj(rdb);
csi->clip = 1;
break;
- case 'g':
+ case 'g':
if (csi->top != 1)
goto syntaxerror;
v[0] = fz_toreal(csi->stack[0]);
error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicegray);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set gray colorspace");
error = pdf_setcolor(csi, PDF_MFILL, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set gray color");
break;
case 'G':
@@ -1037,9 +1071,9 @@ fz_debugobj(rdb);
v[0] = fz_toreal(csi->stack[0]);
error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicegray);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set gray colorspace");
error = pdf_setcolor(csi, PDF_MSTROKE, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set gray color");
break;
case 'k':
@@ -1052,9 +1086,9 @@ fz_debugobj(rdb);
v[3] = fz_toreal(csi->stack[3]);
error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicecmyk);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set cmyk colorspace");
error = pdf_setcolor(csi, PDF_MFILL, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set cmyk color");
break;
case 'K':
@@ -1067,9 +1101,9 @@ fz_debugobj(rdb);
v[3] = fz_toreal(csi->stack[3]);
error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicecmyk);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set cmyk colorspace");
error = pdf_setcolor(csi, PDF_MSTROKE, v);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot set cmyk color");
break;
case '\'':
@@ -1081,7 +1115,7 @@ fz_debugobj(rdb);
csi->tm = csi->tlm;
error = pdf_showtext(csi, csi->stack[0]);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw text");
break;
case '"':
@@ -1096,33 +1130,37 @@ fz_debugobj(rdb);
csi->tm = csi->tlm;
error = pdf_showtext(csi, csi->stack[2]);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot draw text");
break;
default:
- if (!csi->xbalance) goto syntaxerror;
+ /* don't fail on unknown keywords if braced by BX/EX */
+ if (!csi->xbalance)
+ goto syntaxerror;
}
- return nil;
+ return fz_okay;
syntaxerror:
- return fz_throw("syntaxerror in content stream: '%s'", buf);
+ return fz_throw("syntaxerror near '%s'", buf);
}
fz_error *
pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file)
{
fz_error *error;
- unsigned char buf[65536];
+ char buf[65536];
int token, len;
fz_obj *obj;
while (1)
{
if (csi->top == 31)
- return fz_throw("stack overflow in content stream");
+ return fz_throw("stack overflow");
- token = pdf_lex(file, buf, sizeof buf, &len);
+ error = pdf_lex(&token, file, buf, sizeof buf, &len);
+ if (error)
+ return fz_rethrow(error, "lexical error in content stream");
if (csi->array)
{
@@ -1134,111 +1172,115 @@ pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file)
}
else if (token == PDF_TINT || token == PDF_TREAL)
{
- error = fz_newreal(&obj, atof((char *) buf));
- if (error) return error;
+ error = fz_newreal(&obj, atof(buf));
+ if (error) return fz_rethrow(error, "cannot create number");
error = fz_arraypush(csi->array, obj);
fz_dropobj(obj);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot add number to array");
}
else if (token == PDF_TSTRING)
{
- error = fz_newstring(&obj, (char *) buf, len);
- if (error) return error;
+ error = fz_newstring(&obj, buf, len);
+ if (error) return fz_rethrow(error, "cannot create string");
error = fz_arraypush(csi->array, obj);
fz_dropobj(obj);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot add string to array");
}
else if (token == PDF_TEOF)
{
- return nil;
+ return fz_okay;
}
else
{
clearstack(csi);
- return fz_throw("syntaxerror in content stream");
+ return fz_throw("syntaxerror in array");
}
}
else switch (token)
{
case PDF_TEOF:
- return nil;
+ return fz_okay;
- /* optimize text-object array parsing */
+ /* optimize text-object array parsing */
case PDF_TOARRAY:
error = fz_newarray(&csi->array, 8);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot create array");
break;
case PDF_TODICT:
- error = pdf_parsedict(&csi->stack[csi->top], file, (char *) buf, sizeof buf);
- if (error) return error;
+ error = pdf_parsedict(&csi->stack[csi->top], file, buf, sizeof buf);
+ if (error) return fz_rethrow(error, "cannot parse dictionary");
csi->top ++;
break;
case PDF_TNAME:
- error = fz_newname(&csi->stack[csi->top], (char *) buf);
- if (error) return error;
+ error = fz_newname(&csi->stack[csi->top], buf);
+ if (error) return fz_rethrow(error, "cannot create name");
csi->top ++;
break;
case PDF_TINT:
- error = fz_newint(&csi->stack[csi->top], atoi((char *) buf));
- if (error) return error;
+ error = fz_newint(&csi->stack[csi->top], atoi(buf));
+ if (error) return fz_rethrow(error, "cannot create integer");
csi->top ++;
break;
case PDF_TREAL:
- error = fz_newreal(&csi->stack[csi->top], atof((char *) buf));
- if (error) return error;
+ error = fz_newreal(&csi->stack[csi->top], atof(buf));
+ if (error) return fz_rethrow(error, "cannot create real");
csi->top ++;
break;
case PDF_TSTRING:
- error = fz_newstring(&csi->stack[csi->top], (char *) buf, len);
- if (error) return error;
+ error = fz_newstring(&csi->stack[csi->top], buf, len);
+ if (error) return fz_rethrow(error, "cannot create string");
csi->top ++;
break;
case PDF_TTRUE:
error = fz_newbool(&csi->stack[csi->top], 1);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot create true");
csi->top ++;
break;
case PDF_TFALSE:
error = fz_newbool(&csi->stack[csi->top], 0);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot create false");
csi->top ++;
break;
case PDF_TNULL:
error = fz_newnull(&csi->stack[csi->top]);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot create null");
csi->top ++;
break;
case PDF_TKEYWORD:
- if (!strcmp((char *) buf, "BI"))
+ if (!strcmp(buf, "BI"))
{
fz_obj *obj;
- error = pdf_parsedict(&obj, file, (char *) buf, sizeof buf);
+ error = pdf_parsedict(&obj, file, buf, sizeof buf);
if (error)
- return error;
+ return fz_rethrow(error, "cannot parse inline image dictionary");
/* read whitespace after ID keyword */
fz_readbyte(file);
+ error = fz_readerror(file);
+ if (error)
+ return fz_rethrow(error, "cannot parse whitespace before inline image");
error = runinlineimage(csi, xref, rdb, file, obj);
fz_dropobj(obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot parse inline image");
}
else
{
- error = runkeyword(csi, xref, rdb, (char *) buf);
- if (error) return error;
+ error = runkeyword(csi, xref, rdb, buf);
+ if (error)
+ return fz_rethrow(error, "cannot run '%s'", buf);
clearstack(csi);
}
break;
diff --git a/mupdf/pdf_lex.c b/mupdf/pdf_lex.c
index 70fafd98..3af88497 100644
--- a/mupdf/pdf_lex.c
+++ b/mupdf/pdf_lex.c
@@ -1,24 +1,31 @@
#include <fitz.h>
#include <mupdf.h>
+/*
+ * pdf_lex will use fz_peekbyte and fz_readbyte.
+ * have to check for file errors with fz_readerror() after lexing.
+ */
+
static inline int iswhite(int ch)
{
- return ch == '\000' ||
- ch == '\011' ||
- ch == '\012' ||
- ch == '\014' ||
- ch == '\015' ||
- ch == '\040';
+ return
+ ch == '\000' ||
+ ch == '\011' ||
+ ch == '\012' ||
+ ch == '\014' ||
+ ch == '\015' ||
+ ch == '\040';
}
static inline int isdelim(int ch)
{
- return ch == '(' || ch == ')' ||
- ch == '<' || ch == '>' ||
- ch == '[' || ch == ']' ||
- ch == '{' || ch == '}' ||
- ch == '/' ||
- ch == '%';
+ return
+ ch == '(' || ch == ')' ||
+ ch == '<' || ch == '>' ||
+ ch == '[' || ch == ']' ||
+ ch == '{' || ch == '}' ||
+ ch == '/' ||
+ ch == '%';
}
static inline int isregular(int ch)
@@ -28,14 +35,15 @@ static inline int isregular(int ch)
static inline int isnumber(int ch)
{
- return ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9');
+ return ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9');
}
static inline int ishex(int ch)
{
- return (ch >= '0' && ch <= '9') ||
- (ch >= 'A' && ch <= 'F') ||
- (ch >= 'a' && ch <= 'f');
+ return
+ (ch >= '0' && ch <= '9') ||
+ (ch >= 'A' && ch <= 'F') ||
+ (ch >= 'a' && ch <= 'f');
}
static inline int fromhex(int ch)
@@ -244,9 +252,10 @@ tokenfromkeyword(char *key)
return PDF_TKEYWORD;
}
-int
-pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
+fz_error *
+pdf_lex(int *ret, fz_stream *f, unsigned char *buf, int n, int *sl)
{
+ fz_error *error;
int c;
while (1)
@@ -254,7 +263,10 @@ pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
c = fz_peekbyte(f);
if (c == EOF)
- return PDF_TEOF;
+ {
+ *ret = PDF_TEOF;
+ goto cleanupokay;
+ }
else if (iswhite(c))
lexwhite(f);
@@ -262,20 +274,21 @@ pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
else if (c == '%')
lexcomment(f);
-
else if (c == '/')
{
fz_readbyte(f);
lexname(f, buf, n);
- *sl = strlen((char *) buf);
- return PDF_TNAME;
+ *sl = strlen(buf);
+ *ret = PDF_TNAME;
+ goto cleanupokay;
}
else if (c == '(')
{
fz_readbyte(f);
*sl = lexstring(f, buf, n);
- return PDF_TSTRING;
+ *ret = PDF_TSTRING;
+ goto cleanupokay;
}
else if (c == '<')
@@ -285,12 +298,14 @@ pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
if (c == '<')
{
fz_readbyte(f);
- return PDF_TODICT;
+ *ret = PDF_TODICT;
+ goto cleanupokay;
}
else
{
*sl = lexhexstring(f, buf, n);
- return PDF_TSTRING;
+ *ret = PDF_TSTRING;
+ goto cleanupokay;
}
}
@@ -299,52 +314,87 @@ pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl)
fz_readbyte(f);
c = fz_readbyte(f);
if (c == '>')
- return PDF_TCDICT;
- return PDF_TERROR;
+ {
+ *ret = PDF_TCDICT;
+ goto cleanupokay;
+ }
+ *ret = PDF_TERROR;
+ goto cleanuperror;
}
else if (c == '[')
{
fz_readbyte(f);
- return PDF_TOARRAY;
+ *ret = PDF_TOARRAY;
+ goto cleanupokay;
}
else if (c == ']')
{
fz_readbyte(f);
- return PDF_TCARRAY;
+ *ret = PDF_TCARRAY;
+ goto cleanupokay;
}
else if (c == '{')
{
fz_readbyte(f);
- return PDF_TOBRACE;
+ *ret = PDF_TOBRACE;
+ goto cleanupokay;
}
else if (c == '}')
{
fz_readbyte(f);
- return PDF_TCBRACE;
+ *ret = PDF_TCBRACE;
+ goto cleanupokay;
}
else if (isnumber(c))
{
lexnumber(f, buf, n);
- *sl = strlen((char *) buf);
- if (strchr((char *) buf, '.'))
- return PDF_TREAL;
- return PDF_TINT;
+ *sl = strlen(buf);
+ if (strchr(buf, '.'))
+ {
+ *ret = PDF_TREAL;
+ goto cleanupokay;
+ }
+ *ret = PDF_TINT;
+ goto cleanupokay;
}
else if (isregular(c))
{
lexname(f, buf, n);
- *sl = strlen((char *) buf);
- return tokenfromkeyword((char *) buf);
+ *sl = strlen(buf);
+ *ret = tokenfromkeyword(buf);
+ goto cleanupokay;
}
else
- return PDF_TERROR;
+ {
+ *ret = PDF_TERROR;
+ goto cleanuperror;
+ }
+ }
+
+cleanupokay:
+ error = fz_readerror(f);
+ if (error)
+ {
+ *ret = PDF_TERROR;
+ return fz_rethrow(error, "cannot read token");
+ }
+ return fz_okay;
+
+cleanuperror:
+ error = fz_readerror(f);
+ if (error)
+ {
+ *ret = PDF_TERROR;
+ return fz_rethrow(error, "cannot read token");
}
+ *ret = PDF_TERROR;
+ return fz_throw("lexical error");
}
diff --git a/mupdf/pdf_open.c b/mupdf/pdf_open.c
index d67fd82c..e9facef4 100644
--- a/mupdf/pdf_open.c
+++ b/mupdf/pdf_open.c
@@ -1,10 +1,11 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
static inline int iswhite(int ch)
{
- return ch == '\000' || ch == '\011' || ch == '\012' ||
- ch == '\014' || ch == '\015' || ch == '\040';
+ return
+ ch == '\000' || ch == '\011' || ch == '\012' ||
+ ch == '\014' || ch == '\015' || ch == '\040';
}
/*
@@ -14,42 +15,46 @@ static inline int iswhite(int ch)
static fz_error *
loadversion(pdf_xref *xref)
{
+ fz_error *error;
char buf[20];
- int n;
- n = fz_seek(xref->file, 0, 0);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, 0, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek to beginning of file");
- fz_readline(xref->file, buf, sizeof buf);
+ error = fz_readline(xref->file, buf, sizeof buf);
+ if (error)
+ return fz_rethrow(error, "cannot read version marker");
if (memcmp(buf, "%PDF-", 5) != 0)
- return fz_throw("syntaxerror: corrupt version marker");
+ return fz_throw("cannot recognize version marker");
- xref->version = atof(buf + 5);
+ xref->version = (int) atof(buf + 5) * 10.0 + 0.5;
- pdf_logxref("version %g\n", xref->version);
+ pdf_logxref("version %d.%d\n", xref->version / 10, xref->version % 10);
- return nil;
+ return fz_okay;
}
static fz_error *
readstartxref(pdf_xref *xref)
{
+ fz_error *error;
char buf[1024];
int t, n;
int i;
- t = fz_seek(xref->file, 0, 2);
- if (t == -1)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, 0, 2);
+ if (error)
+ return fz_rethrow(error, "cannot seek to end of file");
- t = fz_seek(xref->file, MAX(0, t - ((int)sizeof buf)), 0);
- if (t == -1)
- return fz_ioerror(xref->file);
+ t = MAX(0, fz_tell(xref->file) - ((int)sizeof buf));
+ error = fz_seek(xref->file, t, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek to offset %d", t);
- n = fz_read(xref->file, (unsigned char *) buf, sizeof buf);
- if (n == -1)
- return fz_ioerror(xref->file);
+ error = fz_read(&n, xref->file, buf, sizeof buf);
+ if (error)
+ return fz_rethrow(error, "cannot read from file");
for (i = n - 9; i >= 0; i--)
{
@@ -59,11 +64,11 @@ readstartxref(pdf_xref *xref)
while (iswhite(buf[i]) && i < n)
i ++;
xref->startxref = atoi(buf + i);
- return nil;
+ return fz_okay;
}
}
- return fz_throw("syntaxerror: could not find startxref");
+ return fz_throw("cannot find startxref");
}
/*
@@ -73,6 +78,7 @@ readstartxref(pdf_xref *xref)
static fz_error *
readoldtrailer(pdf_xref *xref, char *buf, int cap)
{
+ fz_error *error;
int ofs, len;
char *s;
int n;
@@ -81,9 +87,11 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap)
pdf_logxref("load old xref format trailer\n");
- fz_readline(xref->file, buf, cap);
+ error = fz_readline(xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref marker");
if (strcmp(buf, "xref") != 0)
- return fz_throw("ioerror: missing xref");
+ return fz_throw("cannot find xref marker");
while (1)
{
@@ -91,9 +99,9 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- n = fz_readline(xref->file, buf, cap);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_readline(xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref count");
s = buf;
ofs = atoi(strsep(&s, " "));
@@ -101,52 +109,89 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap)
/* broken pdfs where the section is not on a separate line */
if (s && *s != '\0')
- fz_seek(xref->file, -(n + buf - s + 2), 1);
+ {
+ error = fz_seek(xref->file, -(n + buf - s + 2), 1);
+ if (error)
+ return fz_rethrow(error, "cannot seek in file");
+ }
t = fz_tell(xref->file);
if (t < 0)
- return fz_ioerror(xref->file);
+ return fz_throw("cannot tell in file");
- n = fz_seek(xref->file, t + 20 * len, 0);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, t + 20 * len, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek in file");
}
- t = pdf_lex(xref->file, (unsigned char *) buf, cap, &n);
+ error = fz_readerror(xref->file);
+ if (error)
+ return fz_rethrow(error, "cannot read from file");
+
+ error = pdf_lex(&t, xref->file, buf, cap, &n);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
if (t != PDF_TTRAILER)
- return fz_throw("syntaxerror: expected trailer");
+ return fz_throw("expected trailer marker");
- t = pdf_lex(xref->file, (unsigned char *) buf, cap, &n);
+ error = pdf_lex(&t, xref->file, buf, cap, &n);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
if (t != PDF_TODICT)
- return fz_throw("syntaxerror: expected trailer dictionary");
+ return fz_throw("expected trailer dictionary");
- return pdf_parsedict(&xref->trailer, xref->file, buf, cap);
+ error = pdf_parsedict(&xref->trailer, xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
+ return fz_okay;
}
static fz_error *
readnewtrailer(pdf_xref *xref, char *buf, int cap)
{
+ fz_error *error;
+
pdf_logxref("load new xref format trailer\n");
- return pdf_parseindobj(&xref->trailer, xref->file, buf, cap, nil, nil, nil);
+
+ error = pdf_parseindobj(&xref->trailer, xref->file, buf, cap, nil, nil, nil);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer (compressed)");
+ return fz_okay;
}
static fz_error *
readtrailer(pdf_xref *xref, char *buf, int cap)
{
- int n;
+ fz_error *error;
int c;
- n = fz_seek(xref->file, xref->startxref, 0);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, xref->startxref, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek to startxref");
c = fz_peekbyte(xref->file);
+ error = fz_readerror(xref->file);
+ if (error)
+ return fz_rethrow(error, "cannot read trailer");
+
if (c == 'x')
- return readoldtrailer(xref, buf, cap);
+ {
+ error = readoldtrailer(xref, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read trailer");
+ }
else if (c >= '0' && c <= '9')
- return readnewtrailer(xref, buf, cap);
+ {
+ error = readnewtrailer(xref, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read trailer");
+ }
+ else
+ {
+ return fz_throw("cannot recognize xref format");
+ }
- return fz_throw("syntaxerror: could not find xref");
+ return fz_okay;
}
/*
@@ -156,6 +201,7 @@ readtrailer(pdf_xref *xref, char *buf, int cap)
static fz_error *
readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
{
+ fz_error *error;
int ofs, len;
char *s;
int n;
@@ -165,9 +211,11 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
pdf_logxref("load old xref format\n");
- fz_readline(xref->file, buf, cap);
+ error = fz_readline(xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref marker");
if (strcmp(buf, "xref") != 0)
- return fz_throw("syntaxerror: expected xref");
+ return fz_throw("cannot find xref marker");
while (1)
{
@@ -175,9 +223,9 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- n = fz_readline(xref->file, buf, cap);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_readline(xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref count");
s = buf;
ofs = atoi(strsep(&s, " "));
@@ -186,17 +234,17 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
/* broken pdfs where the section is not on a separate line */
if (s && *s != '\0')
{
- fz_warn("syntaxerror: broken xref section");
- fz_seek(xref->file, -(n + buf - s + 2), 1);
+ fz_warn("broken xref section. proceeding anyway.");
+ error = fz_seek(xref->file, -(n + buf - s + 2), 1);
+ if (error)
+ return fz_rethrow(error, "cannot seek to xref");
}
for (i = 0; i < len; i++)
{
- n = fz_read(xref->file, (unsigned char *) buf, 20);
- if (n < 0)
- return fz_ioerror(xref->file);
- if (n != 20)
- return fz_throw("syntaxerror: truncated xref table");
+ error = fz_read(&n, xref->file, buf, 20);
+ if (error)
+ return fz_rethrow(error, "cannot read xref table");
if (!xref->table[ofs + i].type)
{
s = buf;
@@ -207,14 +255,22 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
}
}
- t = pdf_lex(xref->file, (unsigned char *) buf, cap, &n);
+ error = pdf_lex(&t, xref->file, buf, cap, &n);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
if (t != PDF_TTRAILER)
- return fz_throw("syntaxerror: expected trailer");
- t = pdf_lex(xref->file, (unsigned char *) buf, cap, &n);
+ return fz_throw("expected trailer marker");
+
+ error = pdf_lex(&t, xref->file, buf, cap, &n);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
if (t != PDF_TODICT)
- return fz_throw("syntaxerror: expected trailer dictionary");
+ return fz_throw("expected trailer dictionary");
- return pdf_parsedict(trailerp, xref->file, buf, cap);
+ error = pdf_parsedict(trailerp, xref->file, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot parse trailer");
+ return fz_okay;
}
static fz_error *
@@ -232,10 +288,11 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
error = pdf_parseindobj(&trailer, xref->file, buf, cap, &oid, &gen, &stmofs);
if (error)
- return error;
+ return fz_rethrow(error, "cannot parse compressed xref stream object");
- if (oid < 0 || oid >= xref->len) {
- error = fz_throw("rangecheck: object id out of range");
+ if (oid < 0 || oid >= xref->len)
+ {
+ error = fz_throw("object id out of range");
goto cleanup;
}
@@ -245,15 +302,16 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
xref->table[oid].stmofs = stmofs;
obj = fz_dictgets(trailer, "Size");
- if (!obj) {
- error = fz_throw("syntaxerror: xref stream missing Size entry");
+ if (!obj)
+ {
+ error = fz_throw("xref stream missing Size entry");
goto cleanup;
}
size = fz_toint(obj);
obj = fz_dictgets(trailer, "W");
if (!obj) {
- error = fz_throw("syntaxerror: xref stream missing W entry");
+ error = fz_throw("xref stream missing W entry");
goto cleanup;
}
w0 = fz_toint(fz_arrayget(obj, 0));
@@ -271,13 +329,16 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
}
if (i0 < 0 || i1 > xref->len) {
- error = fz_throw("syntaxerror: xref stream has too many entries");
+ error = fz_throw("xref stream has too many entries");
goto cleanup;
}
error = pdf_openstream(&stm, xref, oid, gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot open compressed xref stream");
goto cleanup;
+ }
for (i = i0; i < i0 + i1; i++)
{
@@ -287,7 +348,11 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
if (fz_peekbyte(stm) == EOF)
{
- error = fz_throw("syntaxerror: truncated xref stream");
+ error = fz_readerror(stm);
+ if (error)
+ error = fz_rethrow(error, "truncated xref stream");
+ else
+ error = fz_throw("truncated xref stream");
fz_dropstream(stm);
goto cleanup;
}
@@ -299,6 +364,14 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
for (n = 0; n < w2; n++)
c = (c << 8) + fz_readbyte(stm);
+ error = fz_readerror(stm);
+ if (error)
+ {
+ error = fz_rethrow(error, "truncated xref stream");
+ fz_dropstream(stm);
+ goto cleanup;
+ }
+
if (!xref->table[i].type)
{
int t = w0 ? a : 1;
@@ -322,20 +395,36 @@ cleanup:
static fz_error *
readxref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap)
{
- int n;
+ fz_error *error;
int c;
- n = fz_seek(xref->file, ofs, 0);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, ofs, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek to xref");
c = fz_peekbyte(xref->file);
+ error = fz_readerror(xref->file);
+ if (error)
+ return fz_rethrow(error, "cannot read trailer");
+
if (c == 'x')
- return readoldxref(trailerp, xref, buf, cap);
+ {
+ error = readoldxref(trailerp, xref, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref (ofs=%d)", ofs);
+ }
else if (c >= '0' && c <= '9')
- return readnewxref(trailerp, xref, buf, cap);
+ {
+ error = readnewxref(trailerp, xref, buf, cap);
+ if (error)
+ return fz_rethrow(error, "cannot read xref (ofs=%d)", ofs);
+ }
+ else
+ {
+ return fz_throw("cannot recognize xref format");
+ }
- return fz_throw("syntaxerror: expected xref");
+ return fz_okay;
}
static fz_error *
@@ -348,7 +437,7 @@ readxrefsections(pdf_xref *xref, int ofs, char *buf, int cap)
error = readxref(&trailer, xref, ofs, buf, cap);
if (error)
- return error;
+ return fz_rethrow(error, "cannot read xref section");
/* FIXME: do we overwrite free entries properly? */
xrefstm = fz_dictgets(trailer, "XrefStm");
@@ -357,7 +446,10 @@ readxrefsections(pdf_xref *xref, int ofs, char *buf, int cap)
pdf_logxref("load xrefstm\n");
error = readxrefsections(xref, fz_toint(xrefstm), buf, cap);
if (error)
+ {
+ error = fz_rethrow(error, "cannot read /XrefStm xref section");
goto cleanup;
+ }
}
prev = fz_dictgets(trailer, "Prev");
@@ -366,7 +458,10 @@ readxrefsections(pdf_xref *xref, int ofs, char *buf, int cap)
pdf_logxref("load prev\n");
error = readxrefsections(xref, fz_toint(prev), buf, cap);
if (error)
+ {
+ error = fz_rethrow(error, "cannot read /Prev xref section");
goto cleanup;
+ }
}
fz_dropobj(trailer);
@@ -399,7 +494,7 @@ pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap)
error = pdf_loadobject(&objstm, xref, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load object stream object");
count = fz_toint(fz_dictgets(objstm, "N"));
first = fz_toint(fz_dictgets(objstm, "First"));
@@ -407,38 +502,49 @@ pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap)
pdf_logxref(" count %d\n", count);
oidbuf = fz_malloc(count * sizeof(int));
- if (!oidbuf) { error = fz_outofmem; goto cleanupobj; }
+ if (!oidbuf)
+ {
+ error = fz_throw("outofmem: object id buffer");
+ goto cleanupobj;
+ }
ofsbuf = fz_malloc(count * sizeof(int));
- if (!ofsbuf) { error = fz_outofmem; goto cleanupoid; }
+ if (!ofsbuf)
+ {
+ error = fz_throw("outofmem: offset buffer");
+ goto cleanupoid;
+ }
error = pdf_openstream(&stm, xref, oid, gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot open object stream");
goto cleanupofs;
+ }
for (i = 0; i < count; i++)
{
- t = pdf_lex(stm, (unsigned char *) buf, cap, &n);
- if (t != PDF_TINT)
+ error = pdf_lex(&t, stm, buf, cap, &n);
+ if (error || t != PDF_TINT)
{
- error = fz_throw("syntaxerror: corrupt object stream");
+ error = fz_rethrow(error, "corrupt object stream");
goto cleanupstm;
}
oidbuf[i] = atoi(buf);
- t = pdf_lex(stm, (unsigned char *) buf, cap, &n);
- if (t != PDF_TINT)
+ error = pdf_lex(&t, stm, buf, cap, &n);
+ if (error || t != PDF_TINT)
{
- error = fz_throw("syntaxerror: corrupt object stream");
+ error = fz_rethrow(error, "corrupt object stream");
goto cleanupstm;
}
ofsbuf[i] = atoi(buf);
}
- n = fz_seek(stm, first, 0);
- if (n < 0)
+ error = fz_seek(stm, first, 0);
+ if (error)
{
- error = fz_ioerror(stm);
+ error = fz_rethrow(error, "cannot seek in object stream");
goto cleanupstm;
}
@@ -448,11 +554,14 @@ pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap)
error = pdf_parsestmobj(&obj, stm, buf, cap);
if (error)
+ {
+ error = fz_rethrow(error, "cannot parse object %d in stream", i);
goto cleanupstm;
+ }
if (oidbuf[i] < 1 || oidbuf[i] >= xref->len)
{
- error = fz_throw("rangecheck: object number out of range");
+ error = fz_throw("object id out of range (%d)", oidbuf[i]);
goto cleanupstm;
}
@@ -495,23 +604,23 @@ pdf_loadxref(pdf_xref *xref, char *filename)
error = fz_openrfile(&xref->file, filename);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open file: '%s'", filename);
error = loadversion(xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot read version marker");
error = readstartxref(xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot read startxref");
error = readtrailer(xref, buf, sizeof buf);
if (error)
- return error;
+ return fz_rethrow(error, "cannot read trailer");
size = fz_dictgets(xref->trailer, "Size");
if (!size)
- return fz_throw("syntaxerror: trailer missing Size entry");
+ return fz_throw("trailer missing Size entry");
pdf_logxref(" size %d\n", fz_toint(size));
@@ -521,7 +630,7 @@ pdf_loadxref(pdf_xref *xref, char *filename)
xref->len = fz_toint(size);
xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry));
if (!xref->table)
- return fz_outofmem;
+ return fz_throw("outofmem: xref table");
for (i = 0; i < xref->len; i++)
{
@@ -536,8 +645,8 @@ pdf_loadxref(pdf_xref *xref, char *filename)
error = readxrefsections(xref, xref->startxref, buf, sizeof buf);
if (error)
- return error;
+ return fz_rethrow(error, "cannot read xref");
- return nil;
+ return fz_okay;
}
diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c
index 25400f2f..f509737b 100644
--- a/mupdf/pdf_page.c
+++ b/mupdf/pdf_page.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
static fz_error *
runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
@@ -11,13 +11,16 @@ runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
- return error;
+ return fz_rethrow(error, "cannot open content stream %d", fz_tonum(stmref));
error = pdf_runcsi(csi, xref, rdb, stm);
fz_dropstream(stm);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot interpret content stream %d", fz_tonum(stmref));
+
+ return fz_okay;
}
/* we need to combine all sub-streams into one for pdf_runcsi
@@ -31,18 +34,20 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list)
fz_buffer *big;
fz_buffer *one;
fz_obj *stm;
- int n;
int i;
pdf_logpage("multiple content streams: %d\n", fz_arraylen(list));
error = fz_newbuffer(&big, 32 * 1024);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create content buffer");
error = fz_openwbuffer(&file, big);
if (error)
- goto cleanup0;
+ {
+ error = fz_rethrow(error, "cannot open content buffer (write)");
+ goto cleanupbuf;
+ }
for (i = 0; i < fz_arraylen(list); i++)
{
@@ -51,37 +56,52 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list)
stm = fz_arrayget(list, i);
error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm));
if (error)
- goto cleanup1;
+ {
+ error = fz_rethrow(error, "cannot load content stream");
+ goto cleanupstm;
+ }
- n = fz_write(file, one->rp, one->wp - one->rp);
+ error = fz_write(file, one->rp, one->wp - one->rp);
+ if (error)
+ {
+ fz_dropbuffer(one);
+ error = fz_rethrow(error, "cannot write to content buffer");
+ goto cleanupstm;
+ }
fz_dropbuffer(one);
- if (n == -1)
+ fz_printstr(file, " ");
+ if (error)
{
- error = fz_ioerror(file);
- goto cleanup1;
+ error = fz_rethrow(error, "cannot write to content buffer");
+ goto cleanupstm;
}
-
- fz_printstr(file, " ");
}
fz_dropstream(file);
error = fz_openrbuffer(&file, big);
if (error)
- goto cleanup0;
+ {
+ error = fz_rethrow(error, "cannot open content buffer (read)");
+ goto cleanupbuf;
+ }
error = pdf_runcsi(csi, xref, rdb, file);
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot interpret content buffer");
+ goto cleanupstm;
+ }
fz_dropstream(file);
fz_dropbuffer(big);
+ return fz_okay;
- return error;
-
-cleanup1:
+cleanupstm:
fz_dropstream(file);
-cleanup0:
+cleanupbuf:
fz_dropbuffer(big);
return error;
}
@@ -95,13 +115,13 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
error = pdf_newcsi(&csi, 0);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create interpreter");
if (fz_isindirect(ref))
{
error = pdf_loadindirect(&obj, xref, ref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load page contents (%d)", fz_tonum(ref));
if (fz_isarray(obj))
{
@@ -114,8 +134,12 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
error = runone(csi, xref, rdb, ref);
fz_dropobj(obj);
+
if (error)
- goto cleanup;
+ {
+ pdf_dropcsi(csi);
+ return fz_rethrow(error, "cannot interpret page contents (%d)", fz_tonum(ref));
+ }
}
else if (fz_isarray(ref))
@@ -124,15 +148,20 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
error = runone(csi, xref, rdb, fz_arrayget(ref, 0));
else
error = runmany(csi, xref, rdb, ref);
+
+ if (error)
+ {
+ pdf_dropcsi(csi);
+ return fz_rethrow(error, "cannot interpret page contents (%d)", fz_tonum(ref));
+ }
}
*treep = csi->tree;
csi->tree = nil;
- error = nil;
-cleanup:
pdf_dropcsi(csi);
- return error;
+
+ return fz_okay;
}
fz_error *
@@ -158,11 +187,11 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
if (!obj)
obj = fz_dictgets(dict, "MediaBox");
if (!fz_isarray(obj))
- return fz_throw("syntaxerror: Page missing MediaBox");
+ return fz_throw("cannot find page bounds");
bbox = pdf_torect(obj);
pdf_logpage("bbox [%g %g %g %g]\n",
- bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+ bbox.x0, bbox.y0, bbox.x1, bbox.y1);
obj = fz_dictgets(dict, "Rotate");
if (fz_isint(obj))
@@ -181,11 +210,11 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
{
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve annotations");
error = pdf_loadannots(&comments, &links, xref, obj);
fz_dropobj(obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load annotations");
}
/*
@@ -194,14 +223,14 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
obj = fz_dictgets(dict, "Resources");
if (!obj)
- return fz_throw("syntaxerror: Page missing Resources");
+ return fz_throw("cannot find page resources");
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve page resources");
error = pdf_loadresources(&rdb, xref, obj);
fz_dropobj(obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load page resources");
/*
* Interpret content stream to build display tree
@@ -210,33 +239,30 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
obj = fz_dictgets(dict, "Contents");
error = loadpagecontents(&tree, xref, rdb, obj);
- if (error) {
+ if (error)
+ {
fz_dropobj(rdb);
- return error;
+ return fz_rethrow(error, "cannot load page contents");
}
- if (!getenv("DONTOPT"))
+ pdf_logpage("optimize tree\n");
+ error = fz_optimizetree(tree);
+ if (error)
{
- if (getenv("SHOWTREE"))
- fz_debugtree(tree);
-
- pdf_logpage("optimize tree\n");
-
- error = fz_optimizetree(tree);
- if (error) {
- fz_dropobj(rdb);
- return error;
- }
+ fz_dropobj(rdb);
+ return fz_rethrow(error, "cannot optimize page display tree");
}
+
/*
* Create page object
*/
- page = *pagep = fz_malloc(sizeof(pdf_page));
- if (!page) {
+ page = fz_malloc(sizeof(pdf_page));
+ if (!page)
+ {
fz_droptree(tree);
fz_dropobj(rdb);
- return fz_outofmem;
+ return fz_throw("outofmem: page struct");
}
page->mediabox.x0 = MIN(bbox.x0, bbox.x1);
@@ -252,20 +278,15 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
pdf_logpage("} %p\n", page);
- if (getenv("SHOWTREE"))
- fz_debugtree(tree);
-
- return nil;
+ *pagep = page;
+ return fz_okay;
}
void
pdf_droppage(pdf_page *page)
{
pdf_logpage("drop page %p\n", page);
-/*
- if (page->comments)
- pdf_dropcomment(page->comments);
-*/
+ /* if (page->comments) pdf_dropcomment(page->comments); */
if (page->links)
pdf_droplink(page->links);
fz_dropobj(page->resources);
diff --git a/mupdf/pdf_pagetree.c b/mupdf/pdf_pagetree.c
index f44e3ed9..47c0362b 100644
--- a/mupdf/pdf_pagetree.c
+++ b/mupdf/pdf_pagetree.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
struct stuff
{
@@ -11,7 +11,7 @@ struct stuff
static fz_error *
loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
- struct stuff inherit, fz_obj *obj, fz_obj *ref)
+ struct stuff inherit, fz_obj *obj, fz_obj *ref)
{
fz_error *error;
fz_obj *type;
@@ -28,28 +28,28 @@ loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
{
pdf_logpage("inherit resources (%d)\n", pages->cursor);
error = fz_dictputs(obj, "Resources", inherit.resources);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot inherit page tree resources");
}
if (inherit.mediabox && !fz_dictgets(obj, "MediaBox"))
{
pdf_logpage("inherit mediabox (%d)\n", pages->cursor);
error = fz_dictputs(obj, "MediaBox", inherit.mediabox);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot inherit page tree mediabox");
}
if (inherit.cropbox && !fz_dictgets(obj, "CropBox"))
{
pdf_logpage("inherit cropbox (%d)\n", pages->cursor);
error = fz_dictputs(obj, "CropBox", inherit.cropbox);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot inherit page tree cropbox");
}
if (inherit.rotate && !fz_dictgets(obj, "Rotate"))
{
pdf_logpage("inherit rotate (%d)\n", pages->cursor);
error = fz_dictputs(obj, "Rotate", inherit.rotate);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot inherit page tree rotate");
}
pages->pref[pages->cursor] = fz_keepobj(ref);
@@ -74,7 +74,7 @@ loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
kids = fz_dictgets(obj, "Kids");
error = pdf_resolve(&kids, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve /Kids");
pdf_logpage("subtree %d {\n", fz_arraylen(kids));
@@ -83,11 +83,11 @@ loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
kref = fz_arrayget(kids, i);
error = pdf_loadindirect(&kobj, xref, kref);
- if (error) { fz_dropobj(kids); return error; }
+ if (error) { fz_dropobj(kids); return fz_rethrow(error, "cannot load kid"); }
error = loadpagetree(xref, pages, inherit, kobj, kref);
fz_dropobj(kobj);
- if (error) { fz_dropobj(kids); return error; }
+ if (error) { fz_dropobj(kids); return fz_rethrow(error, "cannot load subtree"); }
}
fz_dropobj(kids);
@@ -95,7 +95,7 @@ loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
pdf_logpage("}\n");
}
- return nil;
+ return fz_okay;
}
void
@@ -132,17 +132,17 @@ pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref)
ref = fz_dictgets(trailer, "Root");
error = pdf_loadindirect(&catalog, xref, ref);
- if (error) goto cleanup;
+ if (error) { error = fz_rethrow(error, "cannot load Root object"); goto cleanup; }
ref = fz_dictgets(catalog, "Pages");
error = pdf_loadindirect(&pages, xref, ref);
- if (error) goto cleanup;
+ if (error) { error = fz_rethrow(error, "cannot load Pages object"); goto cleanup; }
ref = fz_dictgets(pages, "Count");
count = fz_toint(ref);
p = fz_malloc(sizeof(pdf_pagetree));
- if (!p) { error = fz_outofmem; goto cleanup; }
+ if (!p) { error = fz_throw("outofmem: page tree struct"); goto cleanup; }
pdf_logpage("load pagetree %p {\n", p);
pdf_logpage("count %d\n", count);
@@ -153,13 +153,13 @@ pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref)
p->cursor = 0;
p->pref = fz_malloc(sizeof(fz_obj*) * count);
- if (!p->pref) { error = fz_outofmem; goto cleanup; }
+ if (!p->pref) { error = fz_throw("outofmem: page tree reference array"); goto cleanup; }
p->pobj = fz_malloc(sizeof(fz_obj*) * count);
- if (!p->pobj) { error = fz_outofmem; goto cleanup; }
+ if (!p->pobj) { error = fz_throw("outofmem: page tree object array"); goto cleanup; }
error = loadpagetree(xref, p, inherit, pages, ref);
- if (error) goto cleanup;
+ if (error) { error = fz_rethrow(error, "cannot load page tree"); goto cleanup; }
fz_dropobj(pages);
fz_dropobj(catalog);
@@ -167,7 +167,7 @@ pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref)
pdf_logpage("}\n", count);
*pp = p;
- return nil;
+ return fz_okay;
cleanup:
if (pages) fz_dropobj(pages);
diff --git a/mupdf/pdf_parse.c b/mupdf/pdf_parse.c
index 91a5892d..2353ba4e 100644
--- a/mupdf/pdf_parse.c
+++ b/mupdf/pdf_parse.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
fz_rect pdf_torect(fz_obj *array)
{
@@ -30,7 +30,7 @@ fz_matrix pdf_tomatrix(fz_obj *array)
fz_error *
pdf_toutf8(char **dstp, fz_obj *src)
{
- unsigned char *srcptr = (unsigned char *) fz_tostrbuf(src);
+ unsigned char *srcptr = fz_tostrbuf(src);
char *dstptr;
int srclen = fz_tostrlen(src);
int dstlen = 0;
@@ -47,7 +47,7 @@ pdf_toutf8(char **dstp, fz_obj *src)
dstptr = *dstp = fz_malloc(dstlen + 1);
if (!dstptr)
- return fz_outofmem;
+ return fz_throw("outofmem: utf-8 string");
for (i = 2; i < srclen; i += 2)
{
@@ -63,7 +63,7 @@ pdf_toutf8(char **dstp, fz_obj *src)
dstptr = *dstp = fz_malloc(dstlen + 1);
if (!dstptr)
- return fz_outofmem;
+ return fz_throw("outofmem: utf-8 string");
for (i = 0; i < srclen; i++)
{
@@ -73,13 +73,13 @@ pdf_toutf8(char **dstp, fz_obj *src)
}
*dstptr = '\0';
- return nil;
+ return fz_okay;
}
fz_error *
pdf_toucs2(unsigned short **dstp, fz_obj *src)
{
- unsigned char *srcptr = (unsigned char *) fz_tostrbuf(src);
+ unsigned char *srcptr = fz_tostrbuf(src);
unsigned short *dstptr;
int srclen = fz_tostrlen(src);
int i;
@@ -88,7 +88,7 @@ pdf_toucs2(unsigned short **dstp, fz_obj *src)
{
dstptr = *dstp = fz_malloc(((srclen - 2) / 2 + 1) * sizeof(short));
if (!dstptr)
- return fz_outofmem;
+ return fz_throw("outofmem: ucs-2 string");
for (i = 2; i < srclen; i += 2)
*dstptr++ = (srcptr[i] << 8) | srcptr[i+1];
}
@@ -97,13 +97,13 @@ pdf_toucs2(unsigned short **dstp, fz_obj *src)
{
dstptr = *dstp = fz_malloc((srclen + 1) * sizeof(short));
if (!dstptr)
- return fz_outofmem;
+ return fz_throw("outofmem: ucs-2 string");
for (i = 0; i < srclen; i++)
*dstptr++ = pdf_docencoding[srcptr[i]];
}
*dstptr = '\0';
- return nil;
+ return fz_okay;
}
fz_error *
@@ -116,30 +116,37 @@ pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap)
int tok, len;
error = fz_newarray(op, 4);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create array");
ary = *op;
while (1)
{
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ goto cleanup;
if (tok != PDF_TINT && tok != PDF_TR)
{
if (n > 0)
{
error = fz_newint(&obj, a);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
error = fz_arraypush(ary, obj);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
fz_dropobj(obj);
obj = nil;
}
if (n > 1)
{
error = fz_newint(&obj, b);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
error = fz_arraypush(ary, obj);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
fz_dropobj(obj);
obj = nil;
}
@@ -149,9 +156,11 @@ pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap)
if (tok == PDF_TINT && n == 2)
{
error = fz_newint(&obj, a);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
error = fz_arraypush(ary, obj);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
fz_dropobj(obj);
obj = nil;
a = b;
@@ -186,12 +195,14 @@ pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap)
case PDF_TNULL: error = fz_newnull(&obj); break;
default: goto cleanup;
}
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
if (obj)
{
error = fz_arraypush(ary, obj);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
fz_dropobj(obj);
}
@@ -201,8 +212,7 @@ pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap)
cleanup:
if (obj) fz_dropobj(obj);
if (ary) fz_dropobj(ary);
- if (error) return error;
- return fz_throw("syntaxerror: corrupt array");
+ return fz_rethrow(error, "cannot parse array");
}
fz_error *
@@ -216,12 +226,15 @@ pdf_parsedict(fz_obj **op, fz_stream *file, char *buf, int cap)
int a, b;
error = fz_newdict(op, 8);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot create dict");
dict = *op;
while (1)
{
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ goto cleanup;
skip:
if (tok == PDF_TCDICT)
@@ -235,9 +248,12 @@ skip:
goto cleanup;
error = fz_newname(&key, buf);
- if (error) goto cleanup;
+ if (error)
+ goto cleanup;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ goto cleanup;
switch (tok)
{
@@ -250,33 +266,35 @@ skip:
case PDF_TFALSE: error = fz_newbool(&val, 0); break;
case PDF_TNULL: error = fz_newnull(&val); break;
case PDF_TINT:
- a = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
- if (tok == PDF_TCDICT || tok == PDF_TNAME ||
- (tok == PDF_TKEYWORD && !strcmp(buf, "ID")))
- {
- error = fz_newint(&val, a);
- if (error) goto cleanup;
- error = fz_dictput(dict, key, val);
- if (error) goto cleanup;
- fz_dropobj(val);
- fz_dropobj(key);
- key = val = nil;
- goto skip;
- }
- if (tok == PDF_TINT)
- {
- b = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
- if (tok == PDF_TR)
- {
- error = fz_newindirect(&val, a, b);
- break;
- }
- }
- goto cleanup;
+ a = atoi(buf);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error) goto cleanup;
+ if (tok == PDF_TCDICT || tok == PDF_TNAME ||
+ (tok == PDF_TKEYWORD && !strcmp(buf, "ID")))
+ {
+ error = fz_newint(&val, a);
+ if (error) goto cleanup;
+ error = fz_dictput(dict, key, val);
+ if (error) goto cleanup;
+ fz_dropobj(val);
+ fz_dropobj(key);
+ key = val = nil;
+ goto skip;
+ }
+ if (tok == PDF_TINT)
+ {
+ b = atoi(buf);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error) goto cleanup;
+ if (tok == PDF_TR)
+ {
+ error = fz_newindirect(&val, a, b);
+ break;
+ }
+ }
+ goto cleanup;
default:
- goto cleanup;
+ goto cleanup;
}
if (error) goto cleanup;
@@ -293,31 +311,36 @@ cleanup:
if (key) fz_dropobj(key);
if (val) fz_dropobj(val);
if (dict) fz_dropobj(dict);
- if (error) return error;
- return fz_throw("syntaxerror: corrupt dictionary");
+ return fz_rethrow(error, "cannot parse dict");
}
fz_error *
pdf_parsestmobj(fz_obj **op, fz_stream *file, char *buf, int cap)
{
+ fz_error *error;
int tok, len;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ return fz_rethrow(error, "cannot parse token in object stream");
switch (tok)
{
- case PDF_TOARRAY: return pdf_parsearray(op, file, buf, cap);
- case PDF_TODICT: return pdf_parsedict(op, file, buf, cap);
- case PDF_TNAME: return fz_newname(op, buf);
- case PDF_TREAL: return fz_newreal(op, atof(buf));
- case PDF_TSTRING: return fz_newstring(op, buf, len);
- case PDF_TTRUE: return fz_newbool(op, 1);
- case PDF_TFALSE: return fz_newbool(op, 0);
- case PDF_TNULL: return fz_newnull(op);
- case PDF_TINT: return fz_newint(op, atoi(buf));
+ case PDF_TOARRAY: error = pdf_parsearray(op, file, buf, cap); break;
+ case PDF_TODICT: error = pdf_parsedict(op, file, buf, cap); break;
+ case PDF_TNAME: error = fz_newname(op, buf); break;
+ case PDF_TREAL: error = fz_newreal(op, atof(buf)); break;
+ case PDF_TSTRING: error = fz_newstring(op, buf, len); break;
+ case PDF_TTRUE: error = fz_newbool(op, 1); break;
+ case PDF_TFALSE: error = fz_newbool(op, 0); break;
+ case PDF_TNULL: error = fz_newnull(op); break;
+ case PDF_TINT: error = fz_newint(op, atoi(buf)); break;
+ default: return fz_throw("unknown token in object stream");
}
- return fz_throw("syntaxerror: corrupt object stream");
+ if (error)
+ return fz_rethrow(error, "cannot parse object stream");
+ return fz_okay;
}
fz_error *
@@ -330,34 +353,38 @@ pdf_parseindobj(fz_obj **op, fz_stream *file, char *buf, int cap,
int tok, len;
int a, b;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
- if (tok != PDF_TINT)
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error || tok != PDF_TINT)
goto cleanup;
oid = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
- if (tok != PDF_TINT)
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error || tok != PDF_TINT)
goto cleanup;
gid = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
- if (tok != PDF_TOBJ)
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error || tok != PDF_TOBJ)
+ goto cleanup;
+
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
goto cleanup;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
switch (tok)
{
- case PDF_TOARRAY: error = pdf_parsearray(&obj, file, buf, cap); break;
- case PDF_TODICT: error = pdf_parsedict(&obj, file, buf, cap); break;
- case PDF_TNAME: error = fz_newname(&obj, buf); break;
- case PDF_TREAL: error = fz_newreal(&obj, atof(buf)); break;
- case PDF_TSTRING: error = fz_newstring(&obj, buf, len); break;
- case PDF_TTRUE: error = fz_newbool(&obj, 1); break;
- case PDF_TFALSE: error = fz_newbool(&obj, 0); break;
- case PDF_TNULL: error = fz_newnull(&obj); break;
- case PDF_TINT:
+ case PDF_TOARRAY: error = pdf_parsearray(&obj, file, buf, cap); break;
+ case PDF_TODICT: error = pdf_parsedict(&obj, file, buf, cap); break;
+ case PDF_TNAME: error = fz_newname(&obj, buf); break;
+ case PDF_TREAL: error = fz_newreal(&obj, atof(buf)); break;
+ case PDF_TSTRING: error = fz_newstring(&obj, buf, len); break;
+ case PDF_TTRUE: error = fz_newbool(&obj, 1); break;
+ case PDF_TFALSE: error = fz_newbool(&obj, 0); break;
+ case PDF_TNULL: error = fz_newnull(&obj); break;
+ case PDF_TINT:
a = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error) goto cleanup;
if (tok == PDF_TSTREAM || tok == PDF_TENDOBJ)
{
error = fz_newint(&obj, a);
@@ -367,7 +394,8 @@ pdf_parseindobj(fz_obj **op, fz_stream *file, char *buf, int cap,
if (tok == PDF_TINT)
{
b = atoi(buf);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error) goto cleanup;
if (tok == PDF_TR)
{
error = fz_newindirect(&obj, a, b);
@@ -375,12 +403,13 @@ pdf_parseindobj(fz_obj **op, fz_stream *file, char *buf, int cap,
}
}
goto cleanup;
- default:
+ default:
goto cleanup;
}
if (error) goto cleanup;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error) goto cleanup;
skip:
if (tok == PDF_TSTREAM)
@@ -390,10 +419,13 @@ skip:
{
c = fz_peekbyte(file);
if (c != '\n')
- fz_warn("syntaxerror: DOS format line ending after stream keyword (%d %d)\n", oid, gid);
+ fz_warn("syntaxerror: corrupt pdf stream (%d %d)\n", oid, gid);
else
c = fz_readbyte(file);
}
+ error = fz_readerror(file);
+ if (error)
+ goto cleanup;
stmofs = fz_tell(file);
}
else if (tok == PDF_TENDOBJ)
@@ -408,8 +440,10 @@ skip:
return nil;
cleanup:
- if (obj) fz_dropobj(obj);
- if (error) return error;
- return fz_throw("syntaxerror: corrupt indirect object (%d %d)", oid, gid);
+ if (obj)
+ fz_dropobj(obj);
+ if (error)
+ return fz_rethrow(error, "cannot parse indirect object (%d %d)", oid, gid);
+ return fz_throw("cannot parse indirect object (%d %d)", oid, gid);
}
diff --git a/mupdf/pdf_pattern.c b/mupdf/pdf_pattern.c
index 8b9e9bc4..c5668884 100644
--- a/mupdf/pdf_pattern.c
+++ b/mupdf/pdf_pattern.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
pdf_pattern *
pdf_keeppattern(pdf_pattern *pat)
@@ -32,14 +32,14 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
if ((*patp = pdf_finditem(xref->store, PDF_KPATTERN, stmref)))
{
pdf_keeppattern(*patp);
- return nil;
+ return fz_okay;
}
pdf_logrsrc("load pattern %d %d {\n", fz_tonum(stmref), fz_togen(stmref));
pat = fz_malloc(sizeof(pdf_pattern));
if (!pat)
- return fz_outofmem;
+ return fz_throw("outofmem: pattern struct");
pat->tree = nil;
pat->ismask = fz_toint(fz_dictgets(dict, "PaintType")) == 2;
@@ -54,8 +54,8 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
pat->bbox = pdf_torect(obj);
pdf_logrsrc("bbox [%g %g %g %g]\n",
- pat->bbox.x0, pat->bbox.y0,
- pat->bbox.x1, pat->bbox.y1);
+ pat->bbox.x0, pat->bbox.y0,
+ pat->bbox.x1, pat->bbox.y1);
obj = fz_dictgets(dict, "Matrix");
if (obj)
@@ -64,9 +64,9 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
pat->matrix = fz_identity();
pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
- pat->matrix.a, pat->matrix.b,
- pat->matrix.c, pat->matrix.d,
- pat->matrix.e, pat->matrix.f);
+ pat->matrix.a, pat->matrix.b,
+ pat->matrix.c, pat->matrix.d,
+ pat->matrix.e, pat->matrix.f);
/*
* Resources
@@ -74,20 +74,26 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
obj = fz_dictgets(dict, "Resources");
if (!obj) {
- error = fz_throw("syntaxerror: Pattern missing Resources");
+ error = fz_throw("cannot find Resources dictionary");
goto cleanup;
}
error = pdf_resolve(&obj, xref);
if (error)
+ {
+ error = fz_rethrow(error, "cannot resolve resource dictionary");
goto cleanup;
+ }
error = pdf_loadresources(&resources, xref, obj);
fz_dropobj(obj);
if (error)
+ {
+ error = fz_rethrow(error, "cannot load resources");
goto cleanup;
+ }
/*
* Content stream
@@ -97,18 +103,27 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
error = pdf_newcsi(&csi, pat->ismask);
if (error)
+ {
+ error = fz_rethrow(error, "cannot create interpreter");
goto cleanup;
+ }
error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
- goto cleanup2;
+ {
+ error = fz_rethrow(error, "cannot open pattern stream %d", fz_tonum(stmref));
+ goto cleanupcsi;
+ }
error = pdf_runcsi(csi, xref, resources, stm);
fz_dropstream(stm);
if (error)
- goto cleanup2;
+ {
+ error = fz_rethrow(error, "cannot interpret pattern stream %d", fz_tonum(stmref));
+ goto cleanupcsi;
+ }
pat->tree = csi->tree;
csi->tree = nil;
@@ -118,18 +133,26 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref
fz_dropobj(resources);
pdf_logrsrc("optimize tree\n");
- fz_optimizetree(pat->tree);
+ error = fz_optimizetree(pat->tree);
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot optimize pattern tree");
+ goto cleanup;
+ }
pdf_logrsrc("}\n");
error = pdf_storeitem(xref->store, PDF_KPATTERN, stmref, pat);
if (error)
+ {
+ error = fz_rethrow(error, "cannot store pattern resource");
goto cleanup;
+ }
*patp = pat;
- return nil;
+ return fz_okay;
-cleanup2:
+cleanupcsi:
pdf_dropcsi(csi);
cleanup:
pdf_droppattern(pat);
diff --git a/mupdf/pdf_repair.c b/mupdf/pdf_repair.c
index e350cd31..ffced0e0 100644
--- a/mupdf/pdf_repair.c
+++ b/mupdf/pdf_repair.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
* open pdf and scan objects to reconstruct xref table
@@ -16,7 +16,7 @@ struct entry
static fz_error *
parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
- int *isroot, int *isinfo)
+ int *isroot, int *isinfo)
{
fz_error *error;
fz_obj *dict = nil;
@@ -24,17 +24,18 @@ parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
fz_obj *filter;
fz_obj *type;
int tok, len;
+ int n;
*stmlen = -1;
*isroot = 0;
*isinfo = 0;
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
if (tok == PDF_TODICT)
{
error = pdf_parsedict(&dict, file, buf, cap);
if (error)
- return error;
+ return fz_rethrow(error, "cannot parse object");
}
if (fz_isdict(dict))
@@ -45,7 +46,10 @@ parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
filter = fz_dictgets(dict, "Filter");
if (fz_isname(filter) && !strcmp(fz_toname(filter), "Standard"))
+ {
+ fz_dropobj(dict);
return fz_throw("cannot repair encrypted files");
+ }
if (fz_dictgets(dict, "Producer"))
if (fz_dictgets(dict, "Creator"))
@@ -53,11 +57,15 @@ parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
*isinfo = 1;
}
- while ( tok != PDF_TSTREAM &&
+ while ( tok != PDF_TSTREAM &&
tok != PDF_TENDOBJ &&
tok != PDF_TERROR &&
tok != PDF_TEOF )
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ {
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ return fz_rethrow(error, "cannot scan for endobj or stream token");
+ }
if (tok == PDF_TSTREAM)
{
@@ -68,19 +76,34 @@ parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
fz_readbyte(file);
}
+ error = fz_readerror(file);
+ if (error)
+ return fz_rethrow(error, "cannot read from file");
+
*stmofs = fz_tell(file);
+ if (*stmofs < 0)
+ return fz_throw("cannot seek in file");
length = fz_dictgets(dict, "Length");
if (fz_isint(length))
{
- fz_seek(file, *stmofs + fz_toint(length), 0);
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = fz_seek(file, *stmofs + fz_toint(length), 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek in file");
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ return fz_rethrow(error, "cannot scan for endstream token");
if (tok == PDF_TENDSTREAM)
goto atobjend;
- fz_seek(file, *stmofs, 0);
+ error = fz_seek(file, *stmofs, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek in file");
}
- fz_read(file, (unsigned char *) buf, 9);
+ error = fz_read(&n, file, buf, 9);
+ if (error)
+ return fz_rethrow(error, "cannot read from file");
+
while (memcmp(buf, "endstream", 9) != 0)
{
c = fz_readbyte(file);
@@ -90,10 +113,16 @@ parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen,
buf[8] = c;
}
+ error = fz_readerror(file);
+ if (error)
+ return fz_rethrow(error, "cannot read from file");
+
*stmlen = fz_tell(file) - *stmofs - 9;
atobjend:
- tok = pdf_lex(file, (unsigned char *) buf, cap, &len);
+ error = pdf_lex(&tok, file, buf, cap, &len);
+ if (error)
+ return fz_rethrow(error, "cannot scan for endobj token");
if (tok == PDF_TENDOBJ)
;
}
@@ -101,7 +130,7 @@ atobjend:
if (dict)
fz_dropobj(dict);
- return nil;
+ return fz_okay;
}
fz_error *
@@ -129,7 +158,7 @@ pdf_repairxref(pdf_xref *xref, char *filename)
error = fz_openrfile(&file, filename);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open file '%s'", filename);
pdf_logxref("repairxref '%s' %p\n", filename, xref);
@@ -141,13 +170,27 @@ pdf_repairxref(pdf_xref *xref, char *filename)
listcap = 1024;
list = fz_malloc(listcap * sizeof(struct entry));
if (!list)
+ {
+ error = fz_throw("outofmem: reparation object list");
goto cleanup;
+ }
while (1)
{
tmpofs = fz_tell(file);
+ if (tmpofs < 0)
+ {
+ error = fz_throw("cannot tell in file");
+ goto cleanup;
+ }
+
+ error = pdf_lex(&tok, file, buf, sizeof buf, &len);
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot scan for objects");
+ goto cleanup;
+ }
- tok = pdf_lex(file, (unsigned char *) buf, sizeof buf, &len);
if (tok == PDF_TINT)
{
oidofs = genofs;
@@ -160,7 +203,10 @@ pdf_repairxref(pdf_xref *xref, char *filename)
{
error = parseobj(file, buf, sizeof buf, &stmofs, &stmlen, &isroot, &isinfo);
if (error)
+ {
+ error = fz_rethrow(error, "cannot parse object");
goto cleanup;
+ }
if (isroot) {
pdf_logxref("found catalog: %d %d\n", oid, gen);
@@ -180,7 +226,7 @@ pdf_repairxref(pdf_xref *xref, char *filename)
listcap = listcap * 2;
newlist = fz_realloc(list, listcap * sizeof(struct entry));
if (!newlist) {
- error = fz_outofmem;
+ error = fz_throw("outofmem: resize reparation object list");
goto cleanup;
}
list = newlist;
@@ -206,22 +252,25 @@ pdf_repairxref(pdf_xref *xref, char *filename)
if (rootoid == 0)
{
- error = fz_throw("syntaxerror: could not find catalog");
+ error = fz_throw("cannot find catalog object");
goto cleanup;
}
error = fz_packobj(&xref->trailer,
- "<< /Size %i /Root %r >>",
- maxoid + 1, rootoid, rootgen);
+ "<< /Size %i /Root %r >>",
+ maxoid + 1, rootoid, rootgen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot create new trailer");
goto cleanup;
+ }
xref->len = maxoid + 1;
xref->cap = xref->len;
xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry));
if (!xref->table)
{
- error = fz_outofmem;
+ error = fz_throw("outofmem: xref table");
goto cleanup;
}
@@ -259,21 +308,42 @@ pdf_repairxref(pdf_xref *xref, char *filename)
fz_obj *dict, *length;
pdf_logxref("correct stream length %d %d = %d\n",
- list[i].oid, list[i].gen, list[i].stmlen);
+ list[i].oid, list[i].gen, list[i].stmlen);
error = pdf_loadobject(&dict, xref, list[i].oid, list[i].gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot load stream object");
goto cleanup;
+ }
error = fz_newint(&length, list[i].stmlen);
if (error)
+ {
+ fz_dropobj(dict);
+ error = fz_rethrow(error, "cannot create integer object");
goto cleanup;
+ }
+
error = fz_dictputs(dict, "Length", length);
if (error)
+ {
+ fz_dropobj(length);
+ fz_dropobj(dict);
+ error = fz_rethrow(error, "cannot update stream length");
goto cleanup;
+ }
- pdf_updateobject(xref, list[i].oid, list[i].gen, dict);
+ error = pdf_updateobject(xref, list[i].oid, list[i].gen, dict);
+ if (error)
+ {
+ fz_dropobj(length);
+ fz_dropobj(dict);
+ error = fz_rethrow(error, "cannot update stream object");
+ goto cleanup;
+ }
+ fz_dropobj(length);
fz_dropobj(dict);
}
}
@@ -291,8 +361,7 @@ pdf_repairxref(pdf_xref *xref, char *filename)
}
fz_free(list);
-
- return nil;
+ return fz_okay;
cleanup:
fz_dropstream(file);
diff --git a/mupdf/pdf_resources.c b/mupdf/pdf_resources.c
index 2ea688c1..3d5503f6 100644
--- a/mupdf/pdf_resources.c
+++ b/mupdf/pdf_resources.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
@@ -53,15 +53,15 @@ preloadcolorspace(pdf_xref *xref, fz_obj *ref)
fz_obj *obj = ref;
if (pdf_finditem(xref->store, PDF_KCOLORSPACE, ref))
- return nil;
+ return fz_okay;
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve colorspace resource %d", fz_tonum(ref));
error = pdf_loadcolorspace(&colorspace, xref, obj);
fz_dropobj(obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load colorspace resource %d", fz_tonum(ref));
pdf_logrsrc("rsrc colorspace %s\n", colorspace->name);
@@ -69,10 +69,10 @@ preloadcolorspace(pdf_xref *xref, fz_obj *ref)
if (error)
{
fz_dropcolorspace(colorspace);
- return error;
+ return fz_rethrow(error, "cannot store colorspace resource");
}
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -86,7 +86,7 @@ preloadpattern(pdf_xref *xref, fz_obj *ref)
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve pattern/shade resource %d", fz_tonum(ref));
type = fz_dictgets(obj, "PatternType");
@@ -94,20 +94,24 @@ preloadpattern(pdf_xref *xref, fz_obj *ref)
{
error = pdf_loadpattern(&pattern, xref, obj, ref);
fz_dropobj(obj);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load pattern resource %d", fz_tonum(ref));
+ return fz_okay;
}
else if (fz_toint(type) == 2)
{
error = pdf_loadshade(&shade, xref, obj, ref);
fz_dropobj(obj);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load shade resource %d", fz_tonum(ref));
+ return fz_okay;
}
else
{
fz_dropobj(obj);
- return fz_throw("syntaxerror: unknown Pattern type");
+ return fz_throw("unknown pattern resource type");
}
}
@@ -118,10 +122,10 @@ preloadshading(pdf_xref *xref, fz_obj *ref)
fz_shade *shade;
fz_obj *obj = ref;
error = pdf_resolve(&obj, xref);
- if (error) return error;
+ if (error) return fz_rethrow(error, "cannot resolve shade resource %d", fz_tonum(ref));
error = pdf_loadshade(&shade, xref, obj, ref);
fz_dropobj(obj);
- return error;
+ return fz_rethrow(error, "cannot load shade resource %d", fz_tonum(ref));
}
static fz_error *
@@ -135,7 +139,7 @@ preloadxobject(pdf_xref *xref, fz_obj *ref)
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve xobject/image resource %d", fz_tonum(ref));
subtype = fz_dictgets(obj, "Subtype");
@@ -143,20 +147,24 @@ preloadxobject(pdf_xref *xref, fz_obj *ref)
{
error = pdf_loadxobject(&xobject, xref, obj, ref);
fz_dropobj(obj);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load xobject resource %d", fz_tonum(ref));
+ return fz_okay;
}
else if (!strcmp(fz_toname(subtype), "Image"))
{
error = pdf_loadimage(&image, xref, obj, ref);
fz_dropobj(obj);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load image resource %d", fz_tonum(ref));
+ return fz_okay;
}
else
{
fz_dropobj(obj);
- return fz_throw("syntaxerror: unknown XObject subtype");
+ return fz_throw("unknown xobject resource type");
}
}
@@ -168,9 +176,11 @@ preloadfont(pdf_xref *xref, fz_obj *ref)
fz_obj *obj = ref;
error = pdf_resolve(&obj, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve font resource %d", fz_tonum(ref));
error = pdf_loadfont(&font, xref, obj, ref);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load font resource %d", fz_tonum(ref));
+ return fz_okay;
}
static fz_error *
@@ -193,7 +203,7 @@ scanfonts(pdf_xref *xref, fz_obj *rdb)
pdf_logrsrc("extgstate font\n");
error = preloadfont(xref, fz_arrayget(obj, 0));
if (error)
- return error;
+ return fz_rethrow(error, "cannot preload font listed in ExtGState");
}
}
}
@@ -206,11 +216,11 @@ scanfonts(pdf_xref *xref, fz_obj *rdb)
obj = fz_dictgetval(dict, i);
error = preloadfont(xref, obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot preload font resource");
}
}
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -223,7 +233,7 @@ copyresolved(fz_obj **outp, pdf_xref *xref, fz_obj *dict)
error = fz_newdict(&copy, fz_dictlen(dict));
if (error)
- return error;
+ return fz_rethrow(error, "cannot create dictionary");
for (i = 0; i < fz_dictlen(dict); i++)
{
@@ -234,26 +244,31 @@ copyresolved(fz_obj **outp, pdf_xref *xref, fz_obj *dict)
{
error = pdf_loadindirect(&obj, xref, val);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load object");
+ }
error = fz_dictput(copy, key, obj);
fz_dropobj(obj);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot save object");
+ }
}
else
{
error = fz_dictput(copy, key, val);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot copy object");
+ }
}
}
*outp = copy;
- return nil;
-
-cleanup:
- fz_dropobj(copy);
- return error;
+ return fz_okay;
}
fz_error *
@@ -275,7 +290,7 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
{
error = pdf_newstore(&xref->store);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create resource store");
}
pdf_logrsrc("load resources {\n");
@@ -286,18 +301,24 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
error = copyresolved(&copy, xref, orig);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve indirect objects");
old = fz_dictgets(copy, "ExtGState");
if (old)
{
error = copyresolved(&new, xref, old);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot resolve indirect objects");
+ }
error = fz_dictputs(copy, "ExtGState", new);
fz_dropobj(new);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot copy extgstate");
+ }
}
/*
@@ -310,9 +331,12 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
for (i = 0; i < fz_dictlen(dict); i++)
{
obj = fz_dictgetval(dict, i);
- error = preloadcolorspace(xref, obj);
- if (error)
- return error;
+ error = preloadcolorspace(xref, obj);
+ if (error)
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load colorspace resource");
+ }
}
}
@@ -326,9 +350,12 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
for (i = 0; i < fz_dictlen(dict); i++)
{
obj = fz_dictgetval(dict, i);
- error = preloadpattern(xref, obj);
- if (error)
- return error;
+ error = preloadpattern(xref, obj);
+ if (error)
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load pattern resource");
+ }
}
}
@@ -338,9 +365,12 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
for (i = 0; i < fz_dictlen(dict); i++)
{
obj = fz_dictgetval(dict, i);
- error = preloadshading(xref, obj);
- if (error)
- return error;
+ error = preloadshading(xref, obj);
+ if (error)
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load shade resource");
+ }
}
}
@@ -354,9 +384,12 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
for (i = 0; i < fz_dictlen(dict); i++)
{
obj = fz_dictgetval(dict, i);
- error = preloadxobject(xref, obj);
- if (error)
- return error;
+ error = preloadxobject(xref, obj);
+ if (error)
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load xobject resource");
+ }
}
}
@@ -366,15 +399,14 @@ pdf_loadresources(fz_obj **rdbp, pdf_xref *xref, fz_obj *orig)
error = scanfonts(xref, copy);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(copy);
+ return fz_rethrow(error, "cannot load font resources");
+ }
pdf_logrsrc("}\n");
*rdbp = copy;
- return nil;
-
-cleanup:
- fz_dropobj(copy);
- return error;
+ return fz_okay;
}
diff --git a/mupdf/pdf_save.c b/mupdf/pdf_save.c
index 0bcb8ac1..1338493d 100644
--- a/mupdf/pdf_save.c
+++ b/mupdf/pdf_save.c
@@ -1,5 +1,7 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
+
+/* TODO: error check prints */
#define TIGHT 1
@@ -19,12 +21,12 @@ writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen
{
error = pdf_cryptstream(&ef, encrypt, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create encryption filter");
- error = fz_openrfilter(&dststm, ef, out);
+ error = fz_openwfilter(&dststm, ef, out);
fz_dropfilter(ef);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open encryption stream");
}
else
{
@@ -33,23 +35,26 @@ writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen
error = pdf_openrawstream(&srcstm, xref, oid, gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot open raw stream");
goto cleanupdst;
+ }
while (1)
{
- n = fz_read(srcstm, buf, sizeof buf);
- if (n == 0)
- break;
- if (n < 0)
+ error = fz_read(&n, srcstm, buf, sizeof buf);
+ if (error)
{
- error = fz_ioerror(srcstm);
+ error = fz_rethrow(error, "cannot read stream");
goto cleanupsrc;
}
+ if (n == 0)
+ break;
- n = fz_write(dststm, buf, n);
- if (n < 0)
+ error = fz_write(dststm, buf, n);
+ if (error)
{
- error = fz_ioerror(dststm);
+ error = fz_rethrow(error, "cannot write stream");
goto cleanupsrc;
}
}
@@ -59,7 +64,7 @@ writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen
fz_print(out, "endstream\n");
- return nil;
+ return fz_okay;
cleanupsrc:
fz_dropstream(srcstm);
@@ -76,7 +81,7 @@ writeobject(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen
error = pdf_cacheobject(xref, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load object");
if (encrypt)
pdf_cryptobj(encrypt, x->obj, oid, gen);
@@ -92,12 +97,12 @@ writeobject(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen
{
error = writestream(out, xref, encrypt, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot write stream");
}
fz_print(out, "endobj\n\n");
- return nil;
+ return fz_okay;
}
static int countmodified(pdf_xref *xref, int oid)
@@ -123,7 +128,7 @@ pdf_updatexref(pdf_xref *xref, char *path)
error = fz_openafile(&out, path);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open output file");
fz_print(out, "\n");
@@ -134,7 +139,10 @@ pdf_updatexref(pdf_xref *xref, char *path)
xref->table[oid].ofs = fz_tell(out);
error = writeobject(out, xref, xref->crypt, oid, xref->table[oid].gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot write object (oid=%d)", oid);
goto cleanup;
+ }
}
}
@@ -161,9 +169,9 @@ pdf_updatexref(pdf_xref *xref, char *path)
xref->table[oid + i].type = 'n';
fz_print(out, "%010d %05d %c \n",
- xref->table[oid + i].ofs,
- xref->table[oid + i].gen,
- xref->table[oid + i].type);
+ xref->table[oid + i].ofs,
+ xref->table[oid + i].gen,
+ xref->table[oid + i].type);
}
oid += n;
@@ -205,7 +213,7 @@ pdf_updatexref(pdf_xref *xref, char *path)
xref->startxref = startxref;
fz_dropstream(out);
- return nil;
+ return fz_okay;
cleanup:
fz_dropstream(out);
@@ -232,27 +240,27 @@ pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt)
error = pdf_allocobject(xref, &eoid, &egen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot allocate encryption object");
pdf_cryptobj(encrypt, encrypt->encrypt, eoid, egen);
error = pdf_updateobject(xref, eoid, egen, encrypt->encrypt);
if (error)
- return error;
+ return fz_rethrow(error, "cannot update encryption object");
}
ofsbuf = fz_malloc(sizeof(int) * xref->len);
if (!ofsbuf)
- return fz_outofmem;
+ return fz_throw("outofmem: offset buffer");
error = fz_openwfile(&out, path);
if (error)
{
fz_free(ofsbuf);
- return error;
+ return fz_rethrow(error, "cannot open output file");
}
- fz_print(out, "%%PDF-%1.1f\n", xref->version);
+ fz_print(out, "%%PDF-%d.%df\n", xref->version / 10, xref->version % 10);
fz_print(out, "%%\342\343\317\323\n\n");
for (oid = 0; oid < xref->len; oid++)
@@ -263,7 +271,10 @@ pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt)
ofsbuf[oid] = fz_tell(out);
error = writeobject(out, xref, encrypt, oid, x->type == 'o' ? 0 : x->gen);
if (error)
+ {
+ error = fz_rethrow(error, "cannot write object (oid=%d)", oid);
goto cleanup;
+ }
}
else
{
@@ -316,10 +327,10 @@ pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt)
if(ofsbuf) fz_free(ofsbuf);
fz_dropstream(out);
- return nil;
+ return fz_okay;
cleanup:
- if(ofsbuf) fz_free(ofsbuf);
+ if (ofsbuf) fz_free(ofsbuf);
fz_dropstream(out);
return error;
}
diff --git a/mupdf/pdf_shade.c b/mupdf/pdf_shade.c
index 7da1824a..da185a8c 100644
--- a/mupdf/pdf_shade.c
+++ b/mupdf/pdf_shade.c
@@ -107,8 +107,8 @@ loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_m
{
shade->bbox = pdf_torect(obj);
pdf_logshade("bbox [%g %g %g %g]\n",
- shade->bbox.x0, shade->bbox.y0,
- shade->bbox.x1, shade->bbox.y1);
+ shade->bbox.x0, shade->bbox.y0,
+ shade->bbox.x1, shade->bbox.y1);
}
switch(type)
@@ -179,7 +179,7 @@ pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
mat = pdf_tomatrix(obj);
pdf_logshade("matrix [%g %g %g %g %g %g]\n",
- mat.a, mat.b, mat.c, mat.d, mat.e, mat.f);
+ mat.a, mat.b, mat.c, mat.d, mat.e, mat.f);
}
else
{
diff --git a/mupdf/pdf_shade1.c b/mupdf/pdf_shade1.c
index 837a499e..217284ca 100644
--- a/mupdf/pdf_shade1.c
+++ b/mupdf/pdf_shade1.c
@@ -20,6 +20,7 @@ pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
float x, y;
float xn, yn;
float x0, y0, x1, y1;
+ float t;
int n;
pdf_logshade("load type1 shade {\n");
diff --git a/mupdf/pdf_store.c b/mupdf/pdf_store.c
index f632657f..71978292 100644
--- a/mupdf/pdf_store.c
+++ b/mupdf/pdf_store.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
typedef struct pdf_item_s pdf_item;
@@ -32,19 +32,19 @@ pdf_newstore(pdf_store **storep)
store = fz_malloc(sizeof(pdf_store));
if (!store)
- return fz_outofmem;
+ return fz_throw("outofmem: store struct");;
error = fz_newhash(&store->hash, 4096, sizeof(struct refkey));
if (error)
{
fz_free(store);
- return error;
+ return fz_rethrow(error, "cannot create hash");
}
store->root = nil;
*storep = store;
- return nil;
+ return fz_okay;
}
static void dropitem(pdf_itemkind kind, void *val)
@@ -78,6 +78,7 @@ pdf_emptystore(pdf_store *store)
if (val)
dropitem(key->kind, val);
}
+
fz_emptyhash(store->hash);
for (item = store->root; item; item = next)
@@ -104,18 +105,6 @@ pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val)
{
fz_error *error;
- switch (kind)
- {
- case PDF_KCOLORSPACE: fz_keepcolorspace(val); break;
- case PDF_KFUNCTION: pdf_keepfunction(val); break;
- case PDF_KXOBJECT: pdf_keepxobject(val); break;
- case PDF_KIMAGE: fz_keepimage(val); break;
- case PDF_KPATTERN: pdf_keeppattern(val); break;
- case PDF_KSHADE: fz_keepshade(val); break;
- case PDF_KCMAP: pdf_keepcmap(val); break;
- case PDF_KFONT: fz_keepfont(val); break;
- }
-
if (fz_isindirect(key))
{
struct refkey item;
@@ -128,7 +117,7 @@ pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val)
error = fz_hashinsert(store->hash, &item, val);
if (error)
- return error;
+ return fz_rethrow(error, "cannot insert object into hash");
}
else
@@ -137,7 +126,7 @@ pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val)
item = fz_malloc(sizeof(pdf_item));
if (!item)
- return fz_outofmem;
+ return fz_throw("outofmem: store list node");
pdf_logrsrc("store item %d: ... = %p\n", kind, val);
@@ -149,7 +138,19 @@ pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val)
store->root = item;
}
- return nil;
+ switch (kind)
+ {
+ case PDF_KCOLORSPACE: fz_keepcolorspace(val); break;
+ case PDF_KFUNCTION: pdf_keepfunction(val); break;
+ case PDF_KXOBJECT: pdf_keepxobject(val); break;
+ case PDF_KIMAGE: fz_keepimage(val); break;
+ case PDF_KPATTERN: pdf_keeppattern(val); break;
+ case PDF_KSHADE: fz_keepshade(val); break;
+ case PDF_KCMAP: pdf_keepcmap(val); break;
+ case PDF_KFONT: fz_keepfont(val); break;
+ }
+
+ return fz_okay;
}
void *
diff --git a/mupdf/pdf_stream.c b/mupdf/pdf_stream.c
index b1570c17..a6cf696c 100644
--- a/mupdf/pdf_stream.c
+++ b/mupdf/pdf_stream.c
@@ -13,7 +13,8 @@ pdf_isstream(pdf_xref *xref, int oid, int gen)
return 0;
error = pdf_cacheobject(xref, oid, gen);
- if (error) {
+ if (error)
+ {
fz_warn("%s", error->msg);
fz_droperror(error);
return 0;
@@ -36,21 +37,21 @@ buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
s = fz_toname(f);
if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx"))
- return fz_newahxd(fp, p);
+ error = fz_newahxd(fp, p);
- if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85"))
- return fz_newa85d(fp, p);
+ else if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85"))
+ error = fz_newa85d(fp, p);
- if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF"))
- return fz_newfaxd(fp, p);
+ else if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF"))
+ error = fz_newfaxd(fp, p);
- if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT"))
- return fz_newdctd(fp, p);
+ else if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT"))
+ error = fz_newdctd(fp, p);
- if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL"))
- return fz_newrld(fp, p);
+ else if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL"))
+ error = fz_newrld(fp, p);
- if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl"))
+ else if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl"))
{
if (fz_isdict(p))
{
@@ -59,25 +60,27 @@ buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
{
error = fz_newflated(&decompress, p);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create deflate filter");
error = fz_newpredictd(&predict, p);
if (error)
{
fz_dropfilter(decompress);
- return error;
+ return fz_rethrow(error, "cannot create predictor filter");
}
error = fz_newpipeline(fp, decompress, predict);
fz_dropfilter(decompress);
fz_dropfilter(predict);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot create pipeline filter");
+ return fz_okay;
}
}
- return fz_newflated(fp, p);
+ error = fz_newflated(fp, p);
}
- if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW"))
+ else if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW"))
{
if (fz_isdict(p))
{
@@ -86,38 +89,47 @@ buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
{
error = fz_newlzwd(&decompress, p);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create lzwd filter");
error = fz_newpredictd(&predict, p);
if (error)
{
fz_dropfilter(decompress);
- return error;
+ return fz_rethrow(error, "cannot create predictor filter");
}
error = fz_newpipeline(fp, decompress, predict);
fz_dropfilter(decompress);
fz_dropfilter(predict);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot create pipeline filter");
+ return fz_okay;
}
}
- return fz_newlzwd(fp, p);
+ error = fz_newlzwd(fp, p);
}
#ifdef HAVE_JBIG2DEC
- if (!strcmp(s, "JBIG2Decode"))
+ else if (!strcmp(s, "JBIG2Decode"))
{
/* TODO: extract and feed JBIG2Global */
- return fz_newjbig2d(fp, p);
+ error = fz_newjbig2d(fp, p);
}
#endif
#ifdef HAVE_JASPER
- if (!strcmp(s, "JPXDecode"))
- return fz_newjpxd(fp, p);
+ else if (!strcmp(s, "JPXDecode"))
+ error = fz_newjpxd(fp, p);
#endif
- return fz_throw("syntaxerror: unknown filter: %s", s);
+ else
+ {
+ return fz_throw("unknown filter name (%s)", s);
+ }
+
+ if (error)
+ return fz_rethrow(error, "cannot create filter");
+ return fz_okay;
}
/*
@@ -145,7 +157,7 @@ buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
error = buildonefilter(&tail, f, p);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create filter");
if (head)
{
@@ -155,7 +167,7 @@ buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
if (error)
{
fz_dropfilter(newhead);
- return error;
+ return fz_rethrow(error, "cannot create pipeline filter");
}
head = newhead;
}
@@ -164,7 +176,7 @@ buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
}
*filterp = head;
- return nil;
+ return fz_okay;
}
/*
@@ -183,13 +195,13 @@ buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int
stmlen = fz_dictgets(stmobj, "Length");
error = pdf_resolve(&stmlen, xref);
if (error)
- return error;
+ return fz_rethrow(error, "cannot resolve stream /Length");
len = fz_toint(stmlen);
fz_dropobj(stmlen);
error = fz_newnullfilter(&base, len);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create null filter");
if (xref->crypt)
{
@@ -200,14 +212,14 @@ buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int
if (error)
{
fz_dropfilter(base);
- return error;
+ return fz_rethrow(error, "cannot create decryption filter");
}
error = fz_newpipeline(&pipe, base, crypt);
fz_dropfilter(base);
fz_dropfilter(crypt);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create pipeline filter");
*filterp = pipe;
}
@@ -216,7 +228,7 @@ buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int
*filterp = base;
}
- return nil;
+ return fz_okay;
}
/*
@@ -226,25 +238,26 @@ buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int
fz_error *
pdf_buildinlinefilter(fz_filter **filterp, fz_obj *stmobj)
{
+ fz_error *error;
fz_obj *filters;
fz_obj *params;
filters = fz_dictgetsa(stmobj, "Filter", "F");
params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
- *filterp = nil;
-
if (filters)
{
if (fz_isname(filters))
- return buildonefilter(filterp, filters, params);
- else if (fz_arraylen(filters) > 0)
- return buildfilterchain(filterp, nil, filters, params);
+ error = buildonefilter(filterp, filters, params);
+ else
+ error = buildfilterchain(filterp, nil, filters, params);
}
+ else
+ error = fz_newnullfilter(filterp, -1);
- /* uh oh, no filter */
-
- return nil;
+ if (error)
+ return fz_rethrow(error, "cannot create inline filter chain");
+ return fz_okay;
}
/*
@@ -261,7 +274,7 @@ pdf_buildfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, in
error = buildrawfilter(&base, xref, stmobj, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create raw filter chain");
filters = fz_dictgetsa(stmobj, "Filter", "F");
params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
@@ -270,31 +283,46 @@ pdf_buildfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, in
{
error = pdf_resolve(&filters, xref);
if (error)
+ {
+ error = fz_rethrow(error, "cannot resolve stream /Filter");
goto cleanup0;
+ }
if (params)
{
error = pdf_resolve(&params, xref);
if (error)
+ {
+ error = fz_rethrow(error, "cannot resolve stream /DecodeParms");
goto cleanup1;
+ }
}
if (fz_isname(filters))
{
error = buildonefilter(&tmp, filters, params);
if (error)
+ {
+ error = fz_rethrow(error, "cannot create filter");
goto cleanup2;
+ }
error = fz_newpipeline(&pipe, base, tmp);
fz_dropfilter(tmp);
if (error)
+ {
+ error = fz_rethrow(error, "cannot create filter pipeline");
goto cleanup2;
+ }
}
else
{
error = buildfilterchain(&pipe, base, filters, params);
if (error)
+ {
+ error = fz_rethrow(error, "cannot create filter chain");
goto cleanup2;
+ }
}
if (params)
@@ -309,7 +337,7 @@ pdf_buildfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, in
*filterp = base;
}
- return nil;
+ return fz_okay;
cleanup2:
if (params)
@@ -322,7 +350,7 @@ cleanup0:
}
/*
- * Open a stream for reading the raw (compressed but decrypted) data.
+ * Open a stream for reading the raw (compressed but decrypted) data.
* Using xref->file while this is open is a bad idea.
*/
fz_error *
@@ -331,33 +359,35 @@ pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen)
pdf_xrefentry *x;
fz_error *error;
fz_filter *filter;
- int n;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object id out of range");
+ return fz_throw("object id out of range (%d)", oid);
x = xref->table + oid;
error = pdf_cacheobject(xref, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load stream object (%d)", oid);
if (x->stmbuf)
{
- return fz_openrbuffer(stmp, x->stmbuf);
+ error = fz_openrbuffer(stmp, x->stmbuf);
+ if (error)
+ return fz_rethrow(error, "cannot open stream from buffer");
+ return fz_okay;
}
if (x->stmofs)
{
error = buildrawfilter(&filter, xref, x->obj, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create raw filter");
- n = fz_seek(xref->file, x->stmofs, 0);
- if (n == -1)
+ error = fz_seek(xref->file, x->stmofs, 0);
+ if (error)
{
fz_dropfilter(filter);
- return fz_ioerror(xref->file);
+ return fz_rethrow(error, "cannot seek to stream");
}
error = fz_openrfilter(stmp, filter, xref->file);
@@ -365,16 +395,16 @@ pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen)
fz_dropfilter(filter);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open filter stream");
- return nil;
+ return fz_okay;
}
- return fz_throw("syntaxerror: object is not a stream");
+ return fz_throw("object is not a stream");
}
/*
- * Open a stream for reading uncompressed data.
+ * Open a stream for reading uncompressed data.
* Put the opened file in xref->stream.
* Using xref->file while a stream is open is a Bad idea.
*/
@@ -385,58 +415,59 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen)
fz_error *error;
fz_stream *rawstm;
fz_filter *filter;
- int n;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object id out of range");
+ return fz_throw("object id out of range (%d)", oid);
x = xref->table + oid;
error = pdf_cacheobject(xref, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load stream object (%d)", oid);
if (x->stmbuf)
{
error = pdf_buildfilter(&filter, xref, x->obj, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create filter");
error = fz_openrbuffer(&rawstm, x->stmbuf);
if (error)
{
fz_dropfilter(filter);
- return error;
+ return fz_rethrow(error, "cannot open stream from buffer");
}
error = fz_openrfilter(stmp, filter, rawstm);
fz_dropfilter(filter);
fz_dropstream(rawstm);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot open filter stream");
+ return fz_okay;
}
if (x->stmofs)
{
error = pdf_buildfilter(&filter, xref, x->obj, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create filter");
- n = fz_seek(xref->file, x->stmofs, 0);
- if (n == -1)
+ error = fz_seek(xref->file, x->stmofs, 0);
+ if (error)
{
fz_dropfilter(filter);
- return fz_ioerror(xref->file);
+ return fz_rethrow(error, "cannot seek to stream");
}
error = fz_openrfilter(stmp, filter, xref->file);
fz_dropfilter(filter);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open filter stream");
- return nil;
+ return fz_okay;
}
- return fz_throw("syntaxerror: object is not a stream");
+ return fz_throw("object is not a stream");
}
/*
@@ -447,21 +478,16 @@ pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen)
{
fz_error *error;
fz_stream *stm;
- int n;
error = pdf_openrawstream(&stm, xref, oid, gen);
if (error)
- return error;
-
- n = fz_readall(bufp, stm);
- if (n < 0)
- error = fz_ioerror(stm);
- else
- error = nil;
+ return fz_rethrow(error, "cannot open raw stream (%d)", oid);
+ error = fz_readall(bufp, stm);
fz_dropstream(stm);
-
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load stream into buffer (%d)", oid);
+ return fz_okay;
}
/*
@@ -472,20 +498,15 @@ pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen)
{
fz_error *error;
fz_stream *stm;
- int n;
error = pdf_openstream(&stm, xref, oid, gen);
if (error)
- return error;
-
- n = fz_readall(bufp, stm);
- if (n < 0)
- error = fz_ioerror(stm);
- else
- error = nil;
+ return fz_rethrow(error, "cannot open stream (%d)", oid);
+ error = fz_readall(bufp, stm);
fz_dropstream(stm);
-
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot load stream into buffer (%d)", oid);
+ return fz_okay;
}
diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c
index b19a7308..27ecfa3a 100644
--- a/mupdf/pdf_type3.c
+++ b/mupdf/pdf_type3.c
@@ -1,5 +1,7 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
+
+/* TODO: we leak the pixmap buffer. not good. we should render into the glyph cache directly or keep it in the font struct.. */
#define GCMEM (4 * 1024)
@@ -29,14 +31,14 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
fz_irect bbox;
if (cid < 0 || cid > 255)
- return fz_throw("rangecheck: glyph out of range");
+ return fz_throw("assert: glyph out of range");
tree = font->charprocs[cid];
if (!tree)
{
glyph->w = 0;
glyph->h = 0;
- return nil;
+ return fz_okay;
}
ctm = fz_concat(font->matrix, trm);
@@ -69,21 +71,30 @@ loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
fz_stream *stm;
error = pdf_newcsi(&csi, 1);
+ if (error)
+ return fz_rethrow(error, "cannot create interpreter");
error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
- return error;
+ {
+ pdf_dropcsi(csi);
+ return fz_rethrow(error, "cannot open glyph content stream");
+ }
error = pdf_runcsi(csi, xref, rdb, stm);
-
- fz_dropstream(stm);
+ if (error)
+ {
+ fz_dropstream(stm);
+ pdf_dropcsi(csi);
+ return fz_rethrow(error, "cannot interpret glyph content stream");
+ }
*treep = csi->tree;
csi->tree = nil;
+ fz_dropstream(stm);
pdf_dropcsi(csi);
-
- return error;
+ return fz_okay;
}
fz_error *
@@ -110,7 +121,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
font = pdf_newfont(buf);
if (!font)
- return fz_outofmem;
+ return fz_throw("outofmem: font struct");
pdf_logfont("load type3 font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font);
pdf_logfont("name %s\n", buf);
@@ -122,16 +133,16 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
font->matrix = pdf_tomatrix(obj);
pdf_logfont("matrix [%g %g %g %g %g %g]\n",
- font->matrix.a, font->matrix.b,
- font->matrix.c, font->matrix.d,
- font->matrix.e, font->matrix.f);
+ font->matrix.a, font->matrix.b,
+ font->matrix.c, font->matrix.d,
+ font->matrix.e, font->matrix.f);
obj = fz_dictgets(dict, "FontBBox");
bbox = pdf_torect(obj);
pdf_logfont("bbox [%g %g %g %g]\n",
- bbox.x0, bbox.y0,
- bbox.x1, bbox.y1);
+ bbox.x0, bbox.y0,
+ bbox.x1, bbox.y1);
bbox = fz_transformaabb(font->matrix, bbox);
bbox.x0 = fz_floor(bbox.x0 * 1000);
@@ -193,7 +204,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
goto cleanup;
error = pdf_loadtounicode(font, xref,
- estrings, nil, fz_dictgets(dict, "ToUnicode"));
+ estrings, nil, fz_dictgets(dict, "ToUnicode"));
if (error)
goto cleanup;
diff --git a/mupdf/pdf_xobject.c b/mupdf/pdf_xobject.c
index 0819f04b..54062351 100644
--- a/mupdf/pdf_xobject.c
+++ b/mupdf/pdf_xobject.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
fz_error *
pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
@@ -11,12 +11,12 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, ref)))
{
pdf_keepxobject(*formp);
- return nil;
+ return fz_okay;
}
form = fz_malloc(sizeof(pdf_xobject));
if (!form)
- return fz_outofmem;
+ return fz_throw("outofmem: xobject struct");
form->refs = 1;
form->resources = nil;
@@ -28,8 +28,8 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
form->bbox = pdf_torect(obj);
pdf_logrsrc("bbox [%g %g %g %g]\n",
- form->bbox.x0, form->bbox.y0,
- form->bbox.x1, form->bbox.y1);
+ form->bbox.x0, form->bbox.y0,
+ form->bbox.x1, form->bbox.y1);
obj = fz_dictgets(dict, "Matrix");
if (obj)
@@ -38,9 +38,9 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
form->matrix = fz_identity();
pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
- form->matrix.a, form->matrix.b,
- form->matrix.c, form->matrix.d,
- form->matrix.e, form->matrix.f);
+ form->matrix.a, form->matrix.b,
+ form->matrix.c, form->matrix.d,
+ form->matrix.e, form->matrix.f);
obj = fz_dictgets(dict, "Resources");
if (obj)
@@ -49,14 +49,14 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
if (error)
{
pdf_dropxobject(form);
- return error;
+ return fz_rethrow(error, "cannot resolve xobject resources");
}
error = pdf_loadresources(&form->resources, xref, obj);
fz_dropobj(obj);
if (error)
{
pdf_dropxobject(form);
- return error;
+ return fz_rethrow(error, "cannot load xobject resources");
}
}
@@ -64,7 +64,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
if (error)
{
pdf_dropxobject(form);
- return error;
+ return fz_rethrow(error, "cannot load xobject content stream");
}
pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);
@@ -75,7 +75,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
if (error)
{
pdf_dropxobject(form);
- return error;
+ return fz_rethrow(error, "cannot store xobject resource");
}
*formp = form;
diff --git a/mupdf/pdf_xref.c b/mupdf/pdf_xref.c
index cd787ff8..c9245bf0 100644
--- a/mupdf/pdf_xref.c
+++ b/mupdf/pdf_xref.c
@@ -1,5 +1,5 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
/*
* create xref structure.
@@ -13,13 +13,14 @@ pdf_newxref(pdf_xref **xrefp)
xref = fz_malloc(sizeof(pdf_xref));
if (!xref)
- return fz_outofmem;
+ return fz_throw("outofmem: xref struct");
+
memset(xref, 0, sizeof(pdf_xref));
pdf_logxref("newxref %p\n", xref);
xref->file = nil;
- xref->version = 1.3;
+ xref->version = 13;
xref->startxref = 0;
xref->crypt = nil;
@@ -36,7 +37,7 @@ pdf_newxref(pdf_xref **xrefp)
xref->store = nil; /* you need to create this if you want to render */
*xrefp = xref;
- return nil;
+ return fz_okay;
}
void
@@ -44,6 +45,7 @@ pdf_closexref(pdf_xref *xref)
{
pdf_logxref("closexref %p\n", xref);
+ /* don't touch the pdf_store module ... we don't want that dependency here */
if (xref->store)
fz_warn("someone forgot to empty the store before freeing xref!");
@@ -73,7 +75,7 @@ pdf_initxref(pdf_xref *xref)
{
xref->table = fz_malloc(sizeof(pdf_xrefentry) * 128);
if (!xref->table)
- return fz_outofmem;
+ return fz_throw("outofmem: xref table");
xref->cap = 128;
xref->len = 1;
@@ -86,7 +88,7 @@ pdf_initxref(pdf_xref *xref)
xref->table[0].stmofs = 0;
xref->table[0].obj = nil;
- return nil;
+ return fz_okay;
}
void
@@ -135,12 +137,12 @@ pdf_debugxref(pdf_xref *xref)
for (i = 0; i < xref->len; i++)
{
printf("%010d %05d %c | %d %c%c\n",
- xref->table[i].ofs,
- xref->table[i].gen,
- xref->table[i].type,
- xref->table[i].obj ? xref->table[i].obj->refs : 0,
- xref->table[i].stmofs ? 'f' : '-',
- xref->table[i].stmbuf ? 'b' : '-');
+ xref->table[i].ofs,
+ xref->table[i].gen,
+ xref->table[i].type,
+ xref->table[i].obj ? xref->table[i].obj->refs : 0,
+ xref->table[i].stmofs ? 'f' : '-',
+ xref->table[i].stmbuf ? 'b' : '-');
}
}
@@ -171,16 +173,17 @@ pdf_decryptxref(pdf_xref *xref)
if (error)
{
fz_dropobj(encrypt);
- return error;
+ return fz_rethrow(error, "cannot resolve /ID object");
}
error = pdf_newdecrypt(&xref->crypt, encrypt, id);
fz_dropobj(encrypt);
fz_dropobj(id);
- return error;
+ if (error)
+ return fz_rethrow(error, "cannot create decrypter");
}
- return nil;
+ return fz_okay;
}
/*
@@ -252,7 +255,7 @@ pdf_allocobject(pdf_xref *xref, int *oidp, int *genp)
newtable = fz_realloc(xref->table, sizeof(pdf_xrefentry) * newcap);
if (!newtable)
- return fz_outofmem;
+ return fz_throw("outofmem: xref table resize");
xref->table = newtable;
xref->cap = newcap;
@@ -278,7 +281,7 @@ pdf_allocobject(pdf_xref *xref, int *oidp, int *genp)
xref->table[prev].type = 'd';
xref->table[prev].ofs = next;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -288,7 +291,7 @@ pdf_deleteobject(pdf_xref *xref, int oid, int gen)
int prev;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object number out of range: %d", oid);
+ return fz_throw("assert: object out of range: %d", oid);
pdf_logxref("deleteobj %d %d\n", oid, gen);
@@ -310,7 +313,7 @@ pdf_deleteobject(pdf_xref *xref, int oid, int gen)
xref->table[prev].type = 'd';
xref->table[prev].ofs = oid;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -319,7 +322,7 @@ pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj)
pdf_xrefentry *x;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object number out of range: %d", oid);
+ return fz_throw("assert: object out of range: %d", oid);
pdf_logxref("updateobj %d %d (%p)\n", oid, gen, obj);
@@ -339,7 +342,7 @@ pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj)
x->type = 'a';
- return nil;
+ return fz_okay;
}
fz_error *
@@ -348,7 +351,7 @@ pdf_updatestream(pdf_xref *xref, int oid, int gen, fz_buffer *stm)
pdf_xrefentry *x;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object number out of range: %d", oid);
+ return fz_throw("assert: object out of range: %d", oid);
pdf_logxref("updatestm %d %d (%p)\n", oid, gen, stm);
@@ -358,7 +361,7 @@ pdf_updatestream(pdf_xref *xref, int oid, int gen, fz_buffer *stm)
fz_dropbuffer(x->stmbuf);
x->stmbuf = fz_keepbuffer(stm);
- return nil;
+ return fz_okay;
}
/*
@@ -373,10 +376,9 @@ pdf_cacheobject(pdf_xref *xref, int oid, int gen)
fz_error *error;
pdf_xrefentry *x;
int roid, rgen;
- int n;
if (oid < 0 || oid >= xref->len)
- return fz_throw("rangecheck: object number out of range: %d", oid);
+ return fz_throw("object out of range: %d", oid);
x = &xref->table[oid];
@@ -387,22 +389,22 @@ pdf_cacheobject(pdf_xref *xref, int oid, int gen)
{
error = fz_newnull(&x->obj);
if (error)
- return error;
- return nil;
+ return fz_rethrow(error, "cannot create null for empty object slot");
+ return fz_okay;
}
if (x->type == 'n')
{
- n = fz_seek(xref->file, x->ofs, 0);
- if (n < 0)
- return fz_ioerror(xref->file);
+ error = fz_seek(xref->file, x->ofs, 0);
+ if (error)
+ return fz_rethrow(error, "cannot seek to object %d (ofs=%d)", oid, x->ofs);
error = pdf_parseindobj(&x->obj, xref->file, buf, sizeof buf, &roid, &rgen, &x->stmofs);
if (error)
- return error;
+ return fz_rethrow(error, "cannot parse object %d", oid);;
if (roid != oid || rgen != gen)
- return fz_throw("syntaxerror: found wrong object");
+ return fz_throw("found object %d instead of %d", roid, oid);
if (xref->crypt)
pdf_cryptobj(xref->crypt, x->obj, oid, gen);
@@ -414,11 +416,11 @@ pdf_cacheobject(pdf_xref *xref, int oid, int gen)
{
error = pdf_loadobjstm(xref, x->ofs, 0, buf, sizeof buf);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load object stream containing object %d", oid);
}
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -428,26 +430,42 @@ pdf_loadobject(fz_obj **objp, pdf_xref *xref, int oid, int gen)
error = pdf_cacheobject(xref, oid, gen);
if (error)
- return error;
+ return fz_rethrow(error, "cannot load object %d into cache", oid);
*objp = fz_keepobj(xref->table[oid].obj);
- return nil;
+ return fz_okay;
}
fz_error *
pdf_loadindirect(fz_obj **objp, pdf_xref *xref, fz_obj *ref)
{
- assert(ref != nil);
- return pdf_loadobject(objp, xref, fz_tonum(ref), fz_togen(ref));
+ fz_error *error;
+
+ if (ref == nil)
+ return fz_throw("assert: dereference null indirect reference");
+
+ error = pdf_loadobject(objp, xref, fz_tonum(ref), fz_togen(ref));
+ if (error)
+ return fz_rethrow(error, "cannot load indirect object %d", fz_tonum(ref));
+
+ return fz_okay;
}
fz_error *
pdf_resolve(fz_obj **objp, pdf_xref *xref)
{
+ fz_error *error;
+
if (fz_isindirect(*objp))
- return pdf_loadindirect(objp, xref, *objp);
+ {
+ error = pdf_loadindirect(objp, xref, *objp);
+ if (error)
+ return fz_rethrow(error, "cannot load indirect object %d", fz_tonum(*objp));
+ return fz_okay;
+ }
+
fz_keepobj(*objp);
- return nil;
+ return fz_okay;
}
diff --git a/stream/crypt_arc4.c b/stream/crypt_arc4.c
index 0a5c942f..a1eef199 100644
--- a/stream/crypt_arc4.c
+++ b/stream/crypt_arc4.c
@@ -38,14 +38,16 @@ fz_arc4init(fz_arc4 *arc4, unsigned char *key, unsigned keylen)
arc4->x = 0;
arc4->y = 0;
- for (counter = 0; counter < 256; counter++) {
+ for (counter = 0; counter < 256; counter++)
+ {
state[counter] = counter;
}
keyindex = 0;
stateindex = 0;
- for (counter = 0; counter < 256; counter++) {
+ for (counter = 0; counter < 256; counter++)
+ {
t = state[counter];
stateindex = (stateindex + key[keyindex] + t) & 0xff;
u = state[stateindex];
@@ -53,7 +55,8 @@ fz_arc4init(fz_arc4 *arc4, unsigned char *key, unsigned keylen)
state[stateindex] = t;
state[counter] = u;
- if (++keyindex >= keylen) {
+ if (++keyindex >= keylen)
+ {
keyindex = 0;
}
}
@@ -87,7 +90,8 @@ void
fz_arc4encrypt(fz_arc4 *arc4, unsigned char *dest, unsigned char *src, unsigned len)
{
unsigned int i;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
+ {
unsigned char x;
x = fz_arc4next(arc4);
dest[i] = src[i] ^ x;
diff --git a/stream/crypt_md5.c b/stream/crypt_md5.c
index cf20024b..7a600612 100644
--- a/stream/crypt_md5.c
+++ b/stream/crypt_md5.c
@@ -83,7 +83,8 @@ static void encode(unsigned char *output, unsigned long *input, unsigned len)
{
unsigned i, j;
- for (i = 0, j = 0; j < len; i++, j += 4) {
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
@@ -95,7 +96,8 @@ static void decode(unsigned long *output, unsigned char *input, unsigned len)
{
unsigned i, j;
- for (i = 0, j = 0; j < len; i++, j += 4) {
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ {
output[i] = ((unsigned long)input[j]) |
(((unsigned long)input[j+1]) << 8) |
(((unsigned long)input[j+2]) << 16) |
@@ -225,7 +227,8 @@ void fz_md5update(fz_md5 *context, unsigned char *input, unsigned inlen)
partlen = 64 - index;
/* Transform as many times as possible. */
- if (inlen >= partlen) {
+ if (inlen >= partlen)
+ {
memcpy(context->buffer + index, input, partlen);
transform(context->state, context->buffer);
@@ -234,7 +237,8 @@ void fz_md5update(fz_md5 *context, unsigned char *input, unsigned inlen)
index = 0;
}
- else {
+ else
+ {
i = 0;
}
diff --git a/stream/filt_a85d.c b/stream/filt_a85d.c
index 3db4951a..5bbe68cb 100644
--- a/stream/filt_a85d.c
+++ b/stream/filt_a85d.c
@@ -26,7 +26,7 @@ fz_newa85d(fz_filter **fp, fz_obj *params)
FZ_NEWFILTER(fz_a85d, f, a85d);
f->word = 0;
f->count = 0;
- return nil;
+ return fz_okay;
}
void
@@ -90,7 +90,7 @@ fz_processa85d(fz_filter *filter, fz_buffer *in, fz_buffer *out)
c = *in->rp++;
if (c != '>') {
- return fz_throw("ioerror: bad eod marker in a85d");
+ return fz_throw("bad eod marker in a85d");
}
if (out->wp + f->count - 1 > out->ep) {
@@ -102,7 +102,7 @@ fz_processa85d(fz_filter *filter, fz_buffer *in, fz_buffer *out)
case 0:
break;
case 1:
- return fz_throw("ioerror: partial final byte in a85d");
+ return fz_throw("partial final byte in a85d");
case 2:
f->word = f->word * (85L * 85 * 85) + 0xffffffL;
goto o1;
@@ -122,7 +122,7 @@ o1: *(out->wp+0) = f->word >> 24;
}
else if (!iswhite(c)) {
- return fz_throw("ioerror: bad data in a85d: '%c'", c);
+ return fz_throw("bad data in a85d: '%c'", c);
}
}
}
diff --git a/stream/filt_a85e.c b/stream/filt_a85e.c
index f7b5912d..a33ee7c5 100644
--- a/stream/filt_a85e.c
+++ b/stream/filt_a85e.c
@@ -14,7 +14,7 @@ fz_newa85e(fz_filter **fp, fz_obj *params)
{
FZ_NEWFILTER(fz_a85e, f, a85e);
f->c = 0;
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/filt_ahxd.c b/stream/filt_ahxd.c
index f54670b2..d670a8d9 100644
--- a/stream/filt_ahxd.c
+++ b/stream/filt_ahxd.c
@@ -44,7 +44,7 @@ fz_newahxd(fz_filter **fp, fz_obj *params)
FZ_NEWFILTER(fz_ahxd, f, ahxd);
f->odd = 0;
f->a = 0;
- return nil;
+ return fz_okay;
}
void
@@ -88,7 +88,7 @@ fz_processahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
}
else if (!iswhite(c)) {
- return fz_throw("ioerror: bad data in ahxd: '%c'", c);
+ return fz_throw("bad data in ahxd: '%c'", c);
}
}
}
diff --git a/stream/filt_ahxe.c b/stream/filt_ahxe.c
index 12c8aad0..8a2e271b 100644
--- a/stream/filt_ahxe.c
+++ b/stream/filt_ahxe.c
@@ -16,7 +16,7 @@ fz_newahxe(fz_filter **fp, fz_obj *params)
{
FZ_NEWFILTER(fz_ahxe, f, ahxe);
f->c = 0;
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/filt_arc4.c b/stream/filt_arc4.c
index 3b3c5957..af038599 100644
--- a/stream/filt_arc4.c
+++ b/stream/filt_arc4.c
@@ -14,7 +14,7 @@ fz_newarc4filter(fz_filter **fp, unsigned char *key, unsigned keylen)
{
FZ_NEWFILTER(fz_arc4c, f, arc4filter);
fz_arc4init(&f->arc4, key, keylen);
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/filt_dctc.h b/stream/filt_dctc.h
index 8aa6aeb7..72f61ef2 100644
--- a/stream/filt_dctc.h
+++ b/stream/filt_dctc.h
@@ -27,7 +27,7 @@ static void myoutmess(j_common_ptr cinfo)
struct myerrmgr *err = (struct myerrmgr *)cinfo->err;
char msgbuf[JMSG_LENGTH_MAX];
err->super.format_message(cinfo, msgbuf);
- fprintf(stderr, "ioerror: dct: %s", msgbuf);
+ fz_warn("jpeg error: %s", msgbuf);
}
static void myiniterr(struct myerrmgr *err)
diff --git a/stream/filt_dctd.c b/stream/filt_dctd.c
index 38ab3fbf..d8fd552f 100644
--- a/stream/filt_dctd.c
+++ b/stream/filt_dctd.c
@@ -72,7 +72,7 @@ fz_newdctd(fz_filter **fp, fz_obj *params)
d->cinfo.err = (struct jpeg_error_mgr*) &d->err;
if (setjmp(d->err.jb)) {
- err = fz_throw("ioerror in dctd: %s", d->err.msg);
+ err = fz_throw("cannot decode jpeg: %s", d->err.msg);
fz_free(d);
return err;
}
@@ -96,7 +96,7 @@ fz_newdctd(fz_filter **fp, fz_obj *params)
d->cinfo.dct_method = JDCT_FASTEST;
d->cinfo.do_fancy_upsampling = FALSE;
- return nil;
+ return fz_okay;
}
void
@@ -104,7 +104,7 @@ fz_dropdctd(fz_filter *filter)
{
fz_dctd *d = (fz_dctd*)filter;
if (setjmp(d->err.jb)) {
- fprintf(stderr, "ioerror in dct: jpeg_destroy_decompress: %s", d->err.msg);
+ fz_warn("jpeg error: jpeg_destroy_decompress: %s", d->err.msg);
return;
}
jpeg_destroy_decompress(&d->cinfo);
@@ -137,8 +137,9 @@ fz_processdctd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
d->src.super.bytes_in_buffer = in->wp - in->rp;
d->src.super.next_input_byte = in->rp;
- if (setjmp(d->err.jb)) {
- return fz_throw("ioerror in dctd: %s", d->err.msg);
+ if (setjmp(d->err.jb))
+ {
+ return fz_throw("cannot decode jpeg: %s", d->err.msg);
}
switch (d->stage)
diff --git a/stream/filt_dcte.c b/stream/filt_dcte.c
index 06f3fcbe..3ce0f21d 100644
--- a/stream/filt_dcte.c
+++ b/stream/filt_dcte.c
@@ -41,23 +41,24 @@ fz_newdcte(fz_filter **fp, fz_obj *params)
e->stage = 0;
obj = fz_dictgets(params, "Columns");
- if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Columns parameter"); }
+ if (!obj) { fz_free(e); return fz_throw("missing Columns parameter"); }
e->columns = fz_toint(obj);
obj = fz_dictgets(params, "Rows");
- if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Rows parameter"); }
+ if (!obj) { fz_free(e); return fz_throw("missing Rows parameter"); }
e->rows = fz_toint(obj);
obj = fz_dictgets(params, "Colors");
- if (!obj) { fz_free(e); return fz_throw("ioerror in dcte: missing Colors parameter"); }
+ if (!obj) { fz_free(e); return fz_throw("missing Colors parameter"); }
e->colors = fz_toint(obj);
/* setup error callback first thing */
myiniterr(&e->err);
e->cinfo.err = (struct jpeg_error_mgr*) &e->err;
- if (setjmp(e->err.jb)) {
- err = fz_throw("ioerror in dcte: %s", e->err.msg);
+ if (setjmp(e->err.jb))
+ {
+ err = fz_throw("cannot encode jpeg: %s", e->err.msg);
fz_free(e);
return err;
}
@@ -119,7 +120,7 @@ fz_newdcte(fz_filter **fp, fz_obj *params)
/* TODO: quant-tables and huffman-tables */
- return nil;
+ return fz_okay;
}
void
@@ -128,7 +129,7 @@ fz_dropdcte(fz_filter *filter)
fz_dcte *e = (fz_dcte*)filter;
if (setjmp(e->err.jb)) {
- fprintf(stderr, "ioerror in dcte: jpeg_destroy_compress: %s", e->err.msg);
+ fz_warn("jpeg error: jpeg_destroy_compress: %s", e->err.msg);
return;
}
@@ -161,7 +162,7 @@ fz_setquanttables(fz_dcte *e, unsigned int **qtables, int qfactor)
unsigned int table[64];
if (setjmp(e->err.jb)) {
- return fz_throw("ioerror in dcte: %s", e->err.msg);
+ return fz_throw("jpeg error: jpeg_add_quant_table: %s", e->err.msg);
}
/* TODO: check for duplicate tables */
@@ -174,7 +175,7 @@ fz_setquanttables(fz_dcte *e, unsigned int **qtables, int qfactor)
e->cinfo.comp_info[i].quant_tbl_no = i;
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -189,8 +190,9 @@ fz_processdcte(fz_filter *filter, fz_buffer *in, fz_buffer *out)
e->dst.super.free_in_buffer = out->ep - out->wp;
e->dst.super.next_output_byte = out->wp;
- if (setjmp(e->err.jb)) {
- return fz_throw("ioerror in dcte: %s", e->err.msg);
+ if (setjmp(e->err.jb))
+ {
+ return fz_throw("cannot encode jpeg: %s", e->err.msg);
}
switch (e->stage)
diff --git a/stream/filt_faxd.c b/stream/filt_faxd.c
index a0449078..4de4d226 100644
--- a/stream/filt_faxd.c
+++ b/stream/filt_faxd.c
@@ -90,15 +90,24 @@ fz_newfaxd(fz_filter **fp, fz_obj *params)
fax->eolc = 0;
fax->ref = fz_malloc(fax->stride);
- if (!fax->ref) { fz_free(fax); return fz_outofmem; }
+ if (!fax->ref)
+ {
+ fz_free(fax);
+ return fz_throw("outofmem: scanline buffer one");
+ }
fax->dst = fz_malloc(fax->stride);
- if (!fax->dst) { fz_free(fax); fz_free(fax->ref); return fz_outofmem; }
+ if (!fax->dst)
+ {
+ fz_free(fax);
+ fz_free(fax->ref);
+ return fz_throw("outofmem: scanline buffer two");
+ }
memset(fax->ref, 0, fax->stride);
memset(fax->dst, 0, fax->stride);
- return nil;
+ return fz_okay;
}
void
@@ -125,7 +134,7 @@ static inline fz_error * fillbits(fz_faxd *fax, fz_buffer *in)
fax->word |= *in->rp << fax->bidx;
in->rp ++;
}
- return nil;
+ return fz_okay;
}
static int
@@ -164,13 +173,13 @@ dec1d(fz_faxd *fax)
code = getcode(fax, cf_white_decode, cfd_white_initial_bits);
if (code == UNCOMPRESSED)
- return fz_throw("ioerror: uncompressed data in faxd");
+ return fz_throw("uncompressed data in faxd");
if (code < 0)
- return fz_throw("ioerror: negative code in 1d faxd");
+ return fz_throw("negative code in 1d faxd");
if (fax->a + code > fax->columns)
- return fz_throw("ioerror: overflow in 1d faxd");
+ return fz_throw("overflow in 1d faxd");
if (fax->c)
setbits(fax->dst, fax->a, fax->a + code);
@@ -185,7 +194,7 @@ dec1d(fz_faxd *fax)
else
fax->stage = SMAKEUP;
- return nil;
+ return fz_okay;
}
/* decode one 2d code */
@@ -205,13 +214,13 @@ dec2d(fz_faxd *fax)
code = getcode(fax, cf_white_decode, cfd_white_initial_bits);
if (code == UNCOMPRESSED)
- return fz_throw("ioerror: uncompressed data in faxd");
+ return fz_throw("uncompressed data in faxd");
if (code < 0)
- return fz_throw("ioerror: negative code in 2d faxd");
+ return fz_throw("negative code in 2d faxd");
if (fax->a + code > fax->columns)
- return fz_throw("ioerror: overflow in 2d faxd");
+ return fz_throw("overflow in 2d faxd");
if (fax->c)
setbits(fax->dst, fax->a, fax->a + code);
@@ -227,7 +236,7 @@ dec2d(fz_faxd *fax)
fax->stage = SNORMAL;
}
- return nil;
+ return fz_okay;
}
code = getcode(fax, cf_2d_decode, cfd_2d_initial_bits);
@@ -295,13 +304,13 @@ dec2d(fz_faxd *fax)
break;
case UNCOMPRESSED:
- return fz_throw("ioerror: uncompressed data in faxd");
+ return fz_throw("uncompressed data in faxd");
case ERROR:
- return fz_throw("ioerror: invalid code in 2d faxd");
+ return fz_throw("invalid code in 2d faxd");
default:
- return fz_throw("ioerror: invalid code in 2d faxd (%d)", code);
+ return fz_throw("invalid code in 2d faxd (%d)", code);
}
return 0;
@@ -361,14 +370,14 @@ loop:
{
fax->eolc = 0;
error = dec1d(fax);
- if (error) return error;
+ if (error) return error; /* can be fz_io* or real error */
}
else if (fax->dim == 2)
{
fax->eolc = 0;
error = dec2d(fax);
- if (error) return error;
+ if (error) return error; /* can be fz_io* or real error */
}
/* no eol check after makeup codes nor in the middle of an H code */
diff --git a/stream/filt_faxe.c b/stream/filt_faxe.c
index 811b5a29..39d46a8c 100644
--- a/stream/filt_faxe.c
+++ b/stream/filt_faxe.c
@@ -75,15 +75,24 @@ fz_newfaxe(fz_filter **fp, fz_obj *params)
fax->c = 0;
fax->ref = fz_malloc(fax->stride);
- if (!fax->ref) { fz_free(fax); return fz_outofmem; }
+ if (!fax->ref)
+ {
+ fz_free(fax);
+ return fz_throw("outofmemory: scanline buffer one");
+ }
fax->src = fz_malloc(fax->stride);
- if (!fax->src) { fz_free(fax); fz_free(fax->ref); return fz_outofmem; }
+ if (!fax->src)
+ {
+ fz_free(fax);
+ fz_free(fax->ref);
+ return fz_throw("outofmemory: scanline buffer two");
+ }
memset(fax->ref, 0, fax->stride);
memset(fax->src, 0, fax->stride);
- return nil;
+ return fz_okay;
}
void
@@ -188,7 +197,7 @@ enc1d(fz_faxe *fax, unsigned char *line, fz_buffer *out)
fax->c = !fax->c;
}
- return 0;
+ return fz_okay;
}
static fz_error *
@@ -245,7 +254,7 @@ enc2d(fz_faxe *fax, unsigned char *ref, unsigned char *src, fz_buffer *out)
}
}
- return 0;
+ return fz_okay;
}
static fz_error *
@@ -349,7 +358,7 @@ process(fz_faxe *fax, fz_buffer *in, fz_buffer *out)
}
if (error)
- return error;
+ return error; /* one of fz_io* */
fax->ridx ++;
diff --git a/stream/filt_flate.c b/stream/filt_flate.c
index 1e048c17..cd079cd2 100644
--- a/stream/filt_flate.c
+++ b/stream/filt_flate.c
@@ -52,12 +52,12 @@ fz_newflated(fz_filter **fp, fz_obj *params)
if (ei != Z_OK)
{
- eo = fz_throw("ioerror: inflateInit: %s", f->z.msg);
+ eo = fz_throw("zlib error: inflateInit: %s", f->z.msg);
fz_free(f);
return eo;
}
- return nil;
+ return fz_okay;
}
void
@@ -108,7 +108,7 @@ fz_processflated(fz_filter *f, fz_buffer *in, fz_buffer *out)
}
else
{
- return fz_throw("ioerror: inflate: %s", zp->msg);
+ return fz_throw("zlib error: inflate: %s", zp->msg);
}
}
@@ -147,12 +147,12 @@ fz_newflatee(fz_filter **fp, fz_obj *params)
if (ei != Z_OK)
{
- eo = fz_throw("ioerror: deflateInit: %s", f->z.msg);
+ eo = fz_throw("zlib error: deflateInit: %s", f->z.msg);
fz_free(f);
return eo;
}
- return nil;
+ return fz_okay;
}
void
@@ -205,7 +205,7 @@ fz_processflatee(fz_filter *f, fz_buffer *in, fz_buffer *out)
}
else
{
- return fz_throw("ioerror: deflate: %s", zp->msg);
+ return fz_throw("zlib error: deflate: %s", zp->msg);
}
}
diff --git a/stream/filt_jbig2d.c b/stream/filt_jbig2d.c
index ce73ee53..17abecd4 100644
--- a/stream/filt_jbig2d.c
+++ b/stream/filt_jbig2d.c
@@ -48,7 +48,7 @@ fz_newjbig2d(fz_filter **fp, fz_obj *params)
d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, nil, nil, nil);
d->page = nil;
d->idx = 0;
- return nil;
+ return fz_okay;
}
void
@@ -65,7 +65,7 @@ fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len)
jbig2_data_in(d->ctx, buf, len);
d->gctx = jbig2_make_global_ctx(d->ctx);
d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, d->gctx, nil, nil);
- return nil;
+ return fz_okay;
}
fz_error *
diff --git a/stream/filt_jpxd.c b/stream/filt_jpxd.c
index 1b93f477..a8e14d0d 100644
--- a/stream/filt_jpxd.c
+++ b/stream/filt_jpxd.c
@@ -42,22 +42,24 @@ fz_newjpxd(fz_filter **fp, fz_obj *params)
FZ_NEWFILTER(fz_jpxd, d, jpxd);
err = jas_init();
- if (err) {
+ if (err)
+ {
fz_free(d);
- return fz_throw("ioerror in jpxd: jas_init()");
+ return fz_throw("jasper error: jas_init()");
}
d->stream = jas_stream_memopen(nil, 0);
- if (!d->stream) {
+ if (!d->stream)
+ {
fz_free(d);
- return fz_throw("ioerror in jpxd: jas_stream_memopen()");
+ return fz_throw("jasper error: jas_stream_memopen()");
}
d->image = nil;
d->offset = 0;
d->stage = 0;
- return nil;
+ return fz_okay;
}
void
@@ -83,7 +85,8 @@ fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
}
input:
- while (in->rp < in->wp) {
+ while (in->rp < in->wp)
+ {
n = jas_stream_write(d->stream, in->rp, in->wp - in->rp);
in->rp += n;
}
@@ -98,7 +101,7 @@ decode:
d->image = jas_image_decode(d->stream, -1, 0);
if (!d->image)
- return fz_throw("ioerror in jpxd: unable to decode image data");
+ return fz_throw("jasper error: jas_image_decode()");
fprintf(stderr, "P%c\n# JPX %d x %d n=%d bpc=%d colorspace=%04x %s\n%d %d\n%d\n",
jas_image_numcmpts(d->image) == 1 ? '5' : '6',
diff --git a/stream/filt_lzwd.c b/stream/filt_lzwd.c
index bbdb4984..127ebde8 100644
--- a/stream/filt_lzwd.c
+++ b/stream/filt_lzwd.c
@@ -83,7 +83,7 @@ fz_newlzwd(fz_filter **fp, fz_obj *params)
lzw->oldcode = -1;
lzw->resume = 0;
- return nil;
+ return fz_okay;
}
void
@@ -107,7 +107,7 @@ static inline fz_error * fillbits(fz_lzwd *lzw, fz_buffer *in)
lzw->word |= *in->rp << lzw->bidx;
in->rp ++;
}
- return nil;
+ return fz_okay;
}
static inline void unstuff(fz_lzwd *lzw, fz_buffer *in)
diff --git a/stream/filt_lzwe.c b/stream/filt_lzwe.c
index 978b6ef2..ec6f5f7a 100644
--- a/stream/filt_lzwe.c
+++ b/stream/filt_lzwe.c
@@ -83,7 +83,7 @@ fz_newlzwe(fz_filter **fp, fz_obj *params)
clearhash(lzw);
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/filt_null.c b/stream/filt_null.c
index f51039b4..601ed815 100644
--- a/stream/filt_null.c
+++ b/stream/filt_null.c
@@ -16,7 +16,7 @@ fz_newnullfilter(fz_filter **fp, int len)
FZ_NEWFILTER(fz_nullfilter, f, nullfilter);
f->len = len;
f->cur = 0;
- return nil;
+ return fz_okay;
}
void
@@ -34,7 +34,8 @@ fz_processnullfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
if (f->len >= 0)
n = MIN(n, f->len - f->cur);
- if (n) {
+ if (n)
+ {
memcpy(out->wp, in->rp, n);
in->rp += n;
out->wp += n;
@@ -48,6 +49,6 @@ fz_processnullfilter(fz_filter *filter, fz_buffer *in, fz_buffer *out)
if (out->wp == out->ep)
return fz_ioneedout;
- return fz_throw("braindead programmer in nullfilter");
+ return fz_throw("braindead programmer trapped in nullfilter");
}
diff --git a/stream/filt_pipeline.c b/stream/filt_pipeline.c
index 65e1c38d..ea0b9885 100644
--- a/stream/filt_pipeline.c
+++ b/stream/filt_pipeline.c
@@ -24,7 +24,7 @@ fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_buffer *bu
p->tail = fz_keepfilter(tail);
p->tailneedsin = 1;
p->buffer = fz_keepbuffer(buf);
- return nil;
+ return fz_okay;
}
void
@@ -49,9 +49,13 @@ fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail)
p->tailneedsin = 1;
error = fz_newbuffer(&p->buffer, FZ_BUFSIZE);
- if (error) { fz_free(p); return error; }
+ if (error)
+ {
+ fz_free(p);
+ return fz_rethrow(error, "cannot create buffer");
+ }
- return nil;
+ return fz_okay;
}
void
@@ -100,8 +104,11 @@ head:
else if (e == fz_iodone)
goto tail;
+ else if (e)
+ return fz_rethrow(e, "cannot process head filter");
+
else
- return e;
+ return fz_okay;
tail:
e = fz_process(p->tail, p->buffer, out);
@@ -123,7 +130,10 @@ tail:
else if (e == fz_iodone)
return fz_iodone;
+ else if (e)
+ return fz_rethrow(e, "cannot process tail filter");
+
else
- return e;
+ return fz_okay;
}
diff --git a/stream/filt_predict.c b/stream/filt_predict.c
index bf4680e7..4654e792 100644
--- a/stream/filt_predict.c
+++ b/stream/filt_predict.c
@@ -52,16 +52,22 @@ fz_newpredict(fz_filter **fp, fz_obj *params, int encode)
p->stride = (p->bpc * p->colors * p->columns + 7) / 8;
p->bpp = (p->bpc * p->colors + 7) / 8;
- if (p->predictor >= 10) {
+ if (p->predictor >= 10)
+ {
p->ref = fz_malloc(p->stride);
- if (!p->ref) { fz_free(p); return fz_outofmem; }
+ if (!p->ref)
+ {
+ fz_free(p);
+ return fz_throw("outofmem: scanline buffer");
+ }
memset(p->ref, 0, p->stride);
}
- else {
+ else
+ {
p->ref = nil;
}
- return nil;
+ return fz_okay;
}
void
@@ -122,8 +128,10 @@ tiff(fz_predict *p, unsigned char *in, unsigned char *out)
for (k = 0; k < p->colors; k++)
left[k] = 0;
- for (i = 0; i < p->columns; i++) {
- for (k = 0; k < p->colors; k++) {
+ for (i = 0; i < p->columns; i++)
+ {
+ for (k = 0; k < p->colors; k++)
+ {
int a = getcomponent(in, i * p->colors + k, p->bpc);
int b = p->encode ? a - left[k] : a + left[k];
int c = b % (1 << p->bpc);
@@ -138,7 +146,8 @@ png(fz_predict *p, unsigned char *in, unsigned char *out, int predictor)
{
int upleft[MAXC], left[MAXC], i, k;
- for (k = 0; k < p->bpp; k++) {
+ for (k = 0; k < p->bpp; k++)
+ {
left[k] = 0;
upleft[k] = 0;
}
@@ -187,7 +196,8 @@ fz_processpredict(fz_filter *filter, fz_buffer *in, fz_buffer *out)
while (1)
{
- if (in->rp + dec->stride + (!dec->encode && ispng) > in->wp) {
+ if (in->rp + dec->stride + (!dec->encode && ispng) > in->wp)
+ {
if (in->eof)
return fz_iodone;
return fz_ioneedin;
@@ -196,22 +206,27 @@ fz_processpredict(fz_filter *filter, fz_buffer *in, fz_buffer *out)
if (out->wp + dec->stride + (dec->encode && ispng) > out->ep)
return fz_ioneedout;
- if (dec->predictor == 1) {
+ if (dec->predictor == 1)
+ {
none(dec, in->rp, out->wp);
}
- else if (dec->predictor == 2) {
+ else if (dec->predictor == 2)
+ {
if (dec->bpc != 8)
memset(out->wp, 0, dec->stride);
tiff(dec, in->rp, out->wp);
}
- else {
- if (dec->encode) {
+ else
+ {
+ if (dec->encode)
+ {
predictor = dec->predictor - 10;
if (predictor < 0 || predictor > 4)
predictor = 1;
*out->wp ++ = predictor;
}
- else {
+ else
+ {
predictor = *in->rp++;
}
png(dec, in->rp, out->wp, predictor);
diff --git a/stream/filt_rld.c b/stream/filt_rld.c
index dc720fbd..74499a57 100644
--- a/stream/filt_rld.c
+++ b/stream/filt_rld.c
@@ -5,7 +5,7 @@ fz_error *
fz_newrld(fz_filter **fp, fz_obj *params)
{
FZ_NEWFILTER(fz_filter, f, rld);
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/filt_rle.c b/stream/filt_rle.c
index 6160e148..458bf3ba 100644
--- a/stream/filt_rle.c
+++ b/stream/filt_rle.c
@@ -42,7 +42,7 @@ fz_newrle(fz_filter **fp, fz_obj *params)
enc->state = ZERO;
enc->run = 0;
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/obj_array.c b/stream/obj_array.c
index cfcd3fb1..3953470a 100644
--- a/stream/obj_array.c
+++ b/stream/obj_array.c
@@ -10,7 +10,8 @@ fz_newarray(fz_obj **op, int initialcap)
int i;
obj = *op = fz_malloc(sizeof (fz_obj));
- if (!obj) return fz_outofmem;
+ if (!obj)
+ return fz_throw("outofmem: array struct");
obj->refs = 1;
obj->kind = FZ_ARRAY;
@@ -19,12 +20,16 @@ fz_newarray(fz_obj **op, int initialcap)
obj->u.a.cap = initialcap > 0 ? initialcap : 6;
obj->u.a.items = fz_malloc(sizeof (fz_obj*) * obj->u.a.cap);
- if (!obj->u.a.items) { fz_free(obj); return fz_outofmem; }
+ if (!obj->u.a.items)
+ {
+ fz_free(obj);
+ return fz_throw("outofmem: array item buffer");
+ }
for (i = 0; i < obj->u.a.cap; i++)
obj->u.a.items[i] = nil;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -35,18 +40,25 @@ fz_copyarray(fz_obj **op, fz_obj *obj)
int i;
if (!fz_isarray(obj))
- return fz_throw("typecheck in copyarray");
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
error = fz_newarray(&new, fz_arraylen(obj));
- if (error) return error;
- *op = new;
+ if (error)
+ return fz_rethrow(error, "cannot create new array");
- for (i = 0; i < fz_arraylen(obj); i++) {
+ for (i = 0; i < fz_arraylen(obj); i++)
+ {
error = fz_arraypush(new, fz_arrayget(obj, i));
- if (error) { fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add item to array");
+ }
}
- return nil;
+ *op = new;
+
+ return fz_okay;
}
fz_error *
@@ -58,39 +70,69 @@ fz_deepcopyarray(fz_obj **op, fz_obj *obj)
int i;
if (!fz_isarray(obj))
- return fz_throw("typecheck in deepcopyarray");
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
error = fz_newarray(&new, fz_arraylen(obj));
- if (error) return error;
- *op = new;
+ if (error)
+ return fz_rethrow(error, "cannot create new array");
for (i = 0; i < fz_arraylen(obj); i++)
{
val = fz_arrayget(obj, i);
- if (fz_isarray(val)) {
+ if (fz_isarray(val))
+ {
error = fz_deepcopyarray(&val, val);
- if (error) { fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
+
error = fz_arraypush(new, val);
- if (error) { fz_dropobj(val); fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
+
fz_dropobj(val);
}
- else if (fz_isdict(val)) {
+ else if (fz_isdict(val))
+ {
error = fz_deepcopydict(&val, val);
- if (error) { fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
+
error = fz_arraypush(new, val);
- if (error) { fz_dropobj(val); fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
fz_dropobj(val);
}
- else {
+ else
+ {
error = fz_arraypush(new, val);
- if (error) { fz_droparray(new); return error; }
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
}
}
- return nil;
+ *op = new;
+
+ return fz_okay;
}
int
@@ -117,17 +159,17 @@ fz_error *
fz_arrayput(fz_obj *obj, int i, fz_obj *item)
{
if (!fz_isarray(obj))
- return fz_throw("typecheck in arrayput");
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
if (i < 0)
- return fz_throw("rangecheck in arrayput: %d < 0", i);
+ return fz_throw("assert: index %d < 0", i);
if (i >= obj->u.a.len)
- return fz_throw("rangecheck in arrayput: %d > %d", i, obj->u.a.len);
+ return fz_throw("assert: index %d > length %d", i, obj->u.a.len);
if (obj->u.a.items[i])
fz_dropobj(obj->u.a.items[i]);
obj->u.a.items[i] = fz_keepobj(item);
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -139,14 +181,15 @@ growarray(fz_obj *obj)
newcap = obj->u.a.cap * 2;
newitems = fz_realloc(obj->u.a.items, sizeof (fz_obj*) * newcap);
- if (!newitems) return fz_outofmem;
+ if (!newitems)
+ return fz_throw("outofmem: resize item buffer");
obj->u.a.items = newitems;
for (i = obj->u.a.cap ; i < newcap; i++)
obj->u.a.items[i] = nil;
obj->u.a.cap = newcap;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -155,17 +198,19 @@ fz_arraypush(fz_obj *obj, fz_obj *item)
fz_error *error;
if (!fz_isarray(obj))
- return fz_throw("typecheck in arraypush");
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
- if (obj->u.a.len + 1 > obj->u.a.cap) {
+ if (obj->u.a.len + 1 > obj->u.a.cap)
+ {
error = growarray(obj);
- if (error) return error;
+ if (error)
+ return fz_rethrow(error, "cannot grow item buffer");
}
obj->u.a.items[obj->u.a.len] = fz_keepobj(item);
obj->u.a.len++;
- return nil;
+ return fz_okay;
}
void
diff --git a/stream/obj_dict.c b/stream/obj_dict.c
index 0981e8a3..a93ae1bd 100644
--- a/stream/obj_dict.c
+++ b/stream/obj_dict.c
@@ -30,7 +30,8 @@ fz_newdict(fz_obj **op, int initialcap)
int i;
obj = *op = fz_malloc(sizeof (fz_obj));
- if (!obj) return fz_outofmem;
+ if (!obj)
+ return fz_throw("outofmem: dict struct");
obj->refs = 1;
obj->kind = FZ_DICT;
@@ -40,9 +41,14 @@ fz_newdict(fz_obj **op, int initialcap)
obj->u.d.cap = initialcap > 0 ? initialcap : 10;
obj->u.d.items = fz_malloc(sizeof(fz_keyval) * obj->u.d.cap);
- if (!obj->u.d.items) { fz_free(obj); return fz_outofmem; }
+ if (!obj->u.d.items)
+ {
+ fz_free(obj);
+ return fz_throw("outofmem: dict item buffer");
+ }
- for (i = 0; i < obj->u.d.cap; i++) {
+ for (i = 0; i < obj->u.d.cap; i++)
+ {
obj->u.d.items[i].k = nil;
obj->u.d.items[i].v = nil;
}
@@ -58,18 +64,24 @@ fz_copydict(fz_obj **op, fz_obj *obj)
int i;
if (!fz_isdict(obj))
- return fz_throw("typecheck in copydict");
+ return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
error = fz_newdict(&new, obj->u.d.cap);
- if (error) return error;
- *op = new;
+ if (error)
+ return fz_rethrow(error, "cannot create new dict");
- for (i = 0; i < fz_dictlen(obj); i++) {
+ for (i = 0; i < fz_dictlen(obj); i++)
+ {
error = fz_dictput(new, fz_dictgetkey(obj, i), fz_dictgetval(obj, i));
- if (error) { fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot copy dict entry");
+ }
}
- return nil;
+ *op = new;
+ return fz_okay;
}
fz_error *
@@ -81,39 +93,65 @@ fz_deepcopydict(fz_obj **op, fz_obj *obj)
int i;
if (!fz_isdict(obj))
- return fz_throw("typecheck in deepcopydict");
+ return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
error = fz_newdict(&new, obj->u.d.cap);
- if (error) return error;
- *op = new;
+ if (error)
+ return fz_rethrow(error, "cannot create new dict");
for (i = 0; i < fz_dictlen(obj); i++)
{
val = fz_dictgetval(obj, i);
- if (fz_isarray(val)) {
+ if (fz_isarray(val))
+ {
error = fz_deepcopyarray(&val, val);
- if (error) { fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropobj(val); fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot add copied dict entry");
+ }
fz_dropobj(val);
}
- else if (fz_isdict(val)) {
+ else if (fz_isdict(val))
+ {
error = fz_deepcopydict(&val, val);
- if (error) { fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropobj(val); fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot add copied dict entry");
+ }
fz_dropobj(val);
}
- else {
+ else
+ {
error = fz_dictput(new, fz_dictgetkey(obj, i), val);
- if (error) { fz_dropobj(new); return error; }
+ if (error)
+ {
+ fz_dropobj(new);
+ return fz_rethrow(error, "cannot copy dict entry");
+ }
}
}
- return nil;
+ *op = new;
+ return fz_okay;
}
static fz_error *
@@ -126,16 +164,18 @@ growdict(fz_obj *obj)
newcap = obj->u.d.cap * 2;
newitems = fz_realloc(obj->u.d.items, sizeof(fz_keyval) * newcap);
- if (!newitems) return fz_outofmem;
+ if (!newitems)
+ return fz_throw("outofmem: resize item buffer");
obj->u.d.items = newitems;
- for (i = obj->u.d.cap; i < newcap; i++) {
+ for (i = obj->u.d.cap; i < newcap; i++)
+ {
obj->u.d.items[i].k = nil;
obj->u.d.items[i].v = nil;
}
obj->u.d.cap = newcap;
- return nil;
+ return fz_okay;
}
int
@@ -243,28 +283,28 @@ fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val)
int i;
if (!fz_isdict(obj))
- return fz_throw("typecheck in dictput");
+ return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
if (fz_isname(key))
s = fz_toname(key);
else if (fz_isstring(key))
s = fz_tostrbuf(key);
else
- return fz_throw("typecheck in dictput");
+ return fz_throw("assert: key is not string or name (%s)", fz_objkindstr(obj));
i = dictfinds(obj, s);
if (i >= 0)
{
fz_dropobj(obj->u.d.items[i].v);
obj->u.d.items[i].v = fz_keepobj(val);
- return nil;
+ return fz_okay;
}
if (obj->u.d.len + 1 > obj->u.d.cap)
{
error = growdict(obj);
if (error)
- return error;
+ return fz_rethrow(error, "cannot grow dict item buffer");
}
/* borked! */
@@ -276,7 +316,7 @@ fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val)
obj->u.d.items[obj->u.d.len].v = fz_keepobj(val);
obj->u.d.len ++;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -297,7 +337,7 @@ fz_dictdels(fz_obj *obj, char *key)
int i;
if (!fz_isdict(obj))
- return fz_throw("typecheck in dictdel");
+ return fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
i = dictfinds(obj, key);
if (i >= 0)
@@ -309,7 +349,7 @@ fz_dictdels(fz_obj *obj, char *key)
obj->u.d.len --;
}
- return nil;
+ return fz_okay;
}
fz_error *
@@ -320,7 +360,7 @@ fz_dictdel(fz_obj *obj, fz_obj *key)
else if (fz_isstring(key))
return fz_dictdels(obj, fz_tostrbuf(key));
else
- return fz_throw("typecheck in dictdel");
+ return fz_throw("assert: key is not string or name (%s)", fz_objkindstr(obj));
}
void
diff --git a/stream/obj_parse.c b/stream/obj_parse.c
index 73b761cb..316e8ad4 100644
--- a/stream/obj_parse.c
+++ b/stream/obj_parse.c
@@ -62,6 +62,7 @@ static void parsekeyword(char **sp, char *b, char *eb)
static fz_error *parsename(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[64];
char *s = *sp;
char *p = buf;
@@ -72,11 +73,15 @@ static fz_error *parsename(fz_obj **obj, char **sp)
*p++ = 0;
*sp = s;
- return fz_newname(obj, buf);
+ error = fz_newname(obj, buf);
+ if (error)
+ return fz_rethrow(error, "cannot create name");
+ return fz_okay;
}
static fz_error *parsenumber(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[32];
char *s = *sp;
char *p = buf;
@@ -92,8 +97,13 @@ static fz_error *parsenumber(fz_obj **obj, char **sp)
*sp = s;
if (strchr(buf, '.'))
- return fz_newreal(obj, atof(buf));
- return fz_newint(obj, atoi(buf));
+ error = fz_newreal(obj, atof(buf));
+ else
+ error = fz_newint(obj, atoi(buf));
+
+ if (error)
+ return fz_rethrow(error, "cannot parse number");
+ return fz_okay;
}
static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
@@ -105,8 +115,8 @@ static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
error = fz_newdict(&dict, 8);
- if (error) return error;
- *obj = dict;
+ if (error)
+ return fz_rethrow(error, "cannot create dict");
s += 2; /* skip "<<" */
@@ -115,39 +125,55 @@ static fz_error *parsedict(fz_obj **obj, char **sp, struct vap *v)
skipwhite(&s);
/* end-of-dict marker >> */
- if (*s == '>') {
+ if (*s == '>')
+ {
s ++;
- if (*s == '>') {
+ if (*s == '>')
+ {
s ++;
break;
}
- error = fz_throw("syntaxerror in parsedict");
+ error = fz_throw("malformed >> marker");
goto cleanup;
}
/* non-name as key, bail */
- if (*s != '/') {
- error = fz_throw("syntaxerror in parsedict");
+ if (*s != '/')
+ {
+ error = fz_throw("key is not a name");
goto cleanup;
}
error = parsename(&key, &s);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot parse key");
+ goto cleanup;
+ }
skipwhite(&s);
error = parseobj(&val, &s, v);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot parse value");
+ goto cleanup;
+ }
error = fz_dictput(dict, key, val);
- if (error) goto cleanup;
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot insert dict entry");
+ goto cleanup;
+ }
fz_dropobj(val); val = nil;
fz_dropobj(key); key = nil;
}
+ *obj = dict;
*sp = s;
- return nil;
+ return fz_okay;
cleanup:
if (val) fz_dropobj(val);
@@ -166,8 +192,8 @@ static fz_error *parsearray(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
error = fz_newarray(&a, 8);
- if (error) return error;
- *obj = a;
+ if (error)
+ return fz_rethrow(error, "cannot create array");
s ++; /* skip '[' */
@@ -175,26 +201,38 @@ static fz_error *parsearray(fz_obj **obj, char **sp, struct vap *v)
{
skipwhite(&s);
- if (*s == ']') {
+ if (*s == ']')
+ {
s ++;
break;
}
error = parseobj(&o, &s, v);
- if (error) { *obj = nil; fz_dropobj(a); return error; }
+ if (error)
+ {
+ fz_dropobj(a);
+ return fz_rethrow(error, "cannot parse item");
+ }
error = fz_arraypush(a, o);
- if (error) { fz_dropobj(o); *obj = nil; fz_dropobj(a); return error; }
+ if (error)
+ {
+ fz_dropobj(o);
+ fz_dropobj(a);
+ return fz_rethrow(error, "cannot add item to array");
+ }
fz_dropobj(o);
}
+ *obj = a;
*sp = s;
- return nil;
+ return fz_okay;
}
static fz_error *parsestring(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[512];
char *s = *sp;
char *p = buf;
@@ -236,12 +274,12 @@ static fz_error *parsestring(fz_obj **obj, char **sp)
}
else switch (*s)
{
- case 'n': *p++ = '\n'; s++; break;
- case 'r': *p++ = '\r'; s++; break;
- case 't': *p++ = '\t'; s++; break;
- case 'b': *p++ = '\b'; s++; break;
- case 'f': *p++ = '\f'; s++; break;
- default: *p++ = *s++; break;
+ case 'n': *p++ = '\n'; s++; break;
+ case 'r': *p++ = '\r'; s++; break;
+ case 't': *p++ = '\t'; s++; break;
+ case 'b': *p++ = '\b'; s++; break;
+ case 'f': *p++ = '\f'; s++; break;
+ default: *p++ = *s++; break;
}
}
else
@@ -252,11 +290,16 @@ static fz_error *parsestring(fz_obj **obj, char **sp)
}
*sp = s;
- return fz_newstring(obj, buf, p - buf - 1);
+
+ error = fz_newstring(obj, buf, p - buf - 1);
+ if (error)
+ return fz_rethrow(error, "cannot create string");
+ return fz_okay;
}
static fz_error *parsehexstring(fz_obj **obj, char **sp)
{
+ fz_error *error;
char buf[512];
char *s = *sp;
char *p = buf;
@@ -287,7 +330,10 @@ static fz_error *parsehexstring(fz_obj **obj, char **sp)
}
*sp = s;
- return fz_newstring(obj, buf, p - buf);
+ error = fz_newstring(obj, buf, p - buf);
+ if (error)
+ return fz_rethrow(error, "cannot create string");
+ return fz_okay;
}
static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
@@ -299,7 +345,7 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
char *s = *sp;
if (*s == '\0')
- return fz_throw("syntaxerror in parseobj: end-of-string");
+ return fz_throw("end of data");
skipwhite(&s);
@@ -308,6 +354,7 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
if (v != nil && *s == '%')
{
s ++;
+
switch (*s)
{
case 'p': error = fz_newpointer(obj, va_arg(v->ap, void*)); break;
@@ -317,61 +364,102 @@ static fz_error *parseobj(fz_obj **obj, char **sp, struct vap *v)
case 'f': error = fz_newreal(obj, (float)va_arg(v->ap, double)); break;
case 'n': error = fz_newname(obj, va_arg(v->ap, char*)); break;
case 'r':
- oid = va_arg(v->ap, int);
- gid = va_arg(v->ap, int);
- error = fz_newindirect(obj, oid, gid);
- break;
+ oid = va_arg(v->ap, int);
+ gid = va_arg(v->ap, int);
+ error = fz_newindirect(obj, oid, gid);
+ break;
case 's':
- tmp = va_arg(v->ap, char*);
- error = fz_newstring(obj, tmp, strlen(tmp));
- break;
+ tmp = va_arg(v->ap, char*);
+ error = fz_newstring(obj, tmp, strlen(tmp));
+ break;
case '#':
- tmp = va_arg(v->ap, char*);
- len = va_arg(v->ap, int);
- error = fz_newstring(obj, tmp, len);
- break;
+ tmp = va_arg(v->ap, char*);
+ len = va_arg(v->ap, int);
+ error = fz_newstring(obj, tmp, len);
+ break;
default:
- error = fz_throw("unknown format specifier in packobj: '%c'", *s);
- break;
+ error = fz_throw("unknown format specifier in packobj: '%c'", *s);
+ break;
}
+
+ if (error)
+ error = fz_rethrow(error, "cannot create object for %% format");
+
s ++;
}
else if (*s == '/')
+ {
error = parsename(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse name");
+ }
else if (*s == '(')
+ {
error = parsestring(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse string");
+ }
- else if (*s == '<') {
+ else if (*s == '<')
+ {
if (s[1] == '<')
+ {
error = parsedict(obj, &s, v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse dict");
+ }
else
+ {
error = parsehexstring(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse hex string");
+ }
}
else if (*s == '[')
+ {
error = parsearray(obj, &s, v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse array");
+ }
else if (*s == '-' || *s == '.' || (*s >= '0' && *s <= '9'))
+ {
error = parsenumber(obj, &s);
+ if (error)
+ error = fz_rethrow(error, "cannot parse number");
+ }
else if (isregular(*s))
{
parsekeyword(&s, buf, buf + sizeof buf);
if (strcmp("true", buf) == 0)
+ {
error = fz_newbool(obj, 1);
+ if (error)
+ error = fz_rethrow(error, "cannot create bool (true)");
+ }
else if (strcmp("false", buf) == 0)
+ {
error = fz_newbool(obj, 0);
+ if (error)
+ error = fz_rethrow(error, "cannot create bool (false)");
+ }
else if (strcmp("null", buf) == 0)
+ {
error = fz_newnull(obj);
+ if (error)
+ error = fz_rethrow(error, "cannot create null object");
+ }
else
- error = fz_throw("syntaxerror in parseobj: undefined keyword %s", buf);
+ error = fz_throw("undefined keyword %s", buf);
}
else
- error = fz_throw("syntaxerror in parseobj");
+ error = fz_throw("syntax error: unknown byte 0x%d", *s);
*sp = s;
return error;
@@ -388,6 +476,8 @@ fz_packobj(fz_obj **op, char *fmt, ...)
va_copy(v.ap, ap);
error = parseobj(op, &fmt, &v);
+ if (error)
+ error = fz_rethrow(error, "cannot parse object");
va_end(ap);
diff --git a/stream/obj_simple.c b/stream/obj_simple.c
index 77a7bca8..d8eb77b7 100644
--- a/stream/obj_simple.c
+++ b/stream/obj_simple.c
@@ -4,18 +4,18 @@
extern void fz_droparray(fz_obj *array);
extern void fz_dropdict(fz_obj *dict);
-#define NEWOBJ(KIND,SIZE) \
- fz_obj *o; \
- o = *op = fz_malloc(SIZE); \
- if (!o) return fz_outofmem; \
- o->refs = 1; \
- o->kind = KIND; \
+#define NEWOBJ(KIND,SIZE) \
+ fz_obj *o; \
+ o = *op = fz_malloc(SIZE); \
+ if (!o) return fz_throw("outofmem: dynamic object"); \
+ o->refs = 1; \
+ o->kind = KIND;
fz_error *
fz_newnull(fz_obj **op)
{
NEWOBJ(FZ_NULL, sizeof (fz_obj));
- return nil;
+ return fz_okay;
}
fz_error *
@@ -23,7 +23,7 @@ fz_newbool(fz_obj **op, int b)
{
NEWOBJ(FZ_BOOL, sizeof (fz_obj));
o->u.b = b;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -31,7 +31,7 @@ fz_newint(fz_obj **op, int i)
{
NEWOBJ(FZ_INT, sizeof (fz_obj));
o->u.i = i;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -39,7 +39,7 @@ fz_newreal(fz_obj **op, float f)
{
NEWOBJ(FZ_REAL, sizeof (fz_obj));
o->u.f = f;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -49,7 +49,7 @@ fz_newstring(fz_obj **op, char *str, int len)
o->u.s.len = len;
memcpy(o->u.s.buf, str, len);
o->u.s.buf[len] = '\0';
- return nil;
+ return fz_okay;
}
fz_error *
@@ -57,7 +57,7 @@ fz_newname(fz_obj **op, char *str)
{
NEWOBJ(FZ_NAME, offsetof(fz_obj, u.n) + strlen(str) + 1);
strcpy(o->u.n, str);
- return nil;
+ return fz_okay;
}
fz_error *
@@ -66,7 +66,7 @@ fz_newindirect(fz_obj **op, int objid, int genid)
NEWOBJ(FZ_INDIRECT, sizeof (fz_obj));
o->u.r.oid = objid;
o->u.r.gid = genid;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -74,7 +74,7 @@ fz_newpointer(fz_obj **op, void *p)
{
NEWOBJ(FZ_POINTER, sizeof (fz_obj));
o->u.p = p;
- return nil;
+ return fz_okay;
}
fz_obj *
@@ -233,7 +233,7 @@ fz_topointer(fz_obj *obj)
{
if (fz_ispointer(obj))
return obj->u.p;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -242,7 +242,7 @@ fz_newnamefromstring(fz_obj **op, fz_obj *str)
NEWOBJ(FZ_NAME, offsetof(fz_obj, u.n) + fz_tostrlen(str) + 1);
memcpy(o->u.n, fz_tostrbuf(str), fz_tostrlen(str));
o->u.n[fz_tostrlen(str)] = '\0';
- return nil;
+ return fz_okay;
}
int
@@ -261,10 +261,12 @@ fz_objcmp(fz_obj *a, fz_obj *b)
case FZ_BOOL: return a->u.b - b->u.b;
case FZ_INT: return a->u.i - b->u.i;
case FZ_REAL: return a->u.f - b->u.f;
+
case FZ_STRING:
if (a->u.s.len != b->u.s.len)
return a->u.s.len - b->u.s.len;
return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len);
+
case FZ_NAME:
return strcmp(a->u.n, b->u.n);
@@ -299,3 +301,23 @@ fz_objcmp(fz_obj *a, fz_obj *b)
return 1;
}
+char *fz_objkindstr(fz_obj *obj)
+{
+ if (obj == nil)
+ return "<nil>";
+ switch (obj->kind)
+ {
+ case FZ_NULL: return "null";
+ case FZ_BOOL: return "boolean";
+ case FZ_INT: return "integer";
+ case FZ_REAL: return "real";
+ case FZ_STRING: return "string";
+ case FZ_NAME: return "name";
+ case FZ_ARRAY: return "array";
+ case FZ_DICT: return "dictionary";
+ case FZ_INDIRECT: return "reference";
+ case FZ_POINTER: return "pointer";
+ }
+ return "<unknown>";
+}
+
diff --git a/stream/stm_buffer.c b/stream/stm_buffer.c
index 4fc5636c..8a1e0850 100644
--- a/stream/stm_buffer.c
+++ b/stream/stm_buffer.c
@@ -7,19 +7,24 @@ fz_newbuffer(fz_buffer **bp, int size)
fz_buffer *b;
b = *bp = fz_malloc(sizeof(fz_buffer));
- if (!b) return fz_outofmem;
+ if (!b)
+ return fz_throw("outofmem: buffer struct");
b->refs = 1;
b->ownsdata = 1;
b->bp = fz_malloc(size);
- if (!b->bp) { fz_free(b); return fz_outofmem; }
+ if (!b->bp)
+ {
+ fz_free(b);
+ return fz_throw("outofmem: buffer memory");
+ }
b->rp = b->bp;
b->wp = b->bp;
b->ep = b->bp + size;
b->eof = 0;
- return nil;
+ return fz_okay;
}
fz_error *
@@ -28,7 +33,8 @@ fz_newbufferwithmemory(fz_buffer **bp, unsigned char *data, int size)
fz_buffer *b;
b = *bp = fz_malloc(sizeof(fz_buffer));
- if (!b) return fz_outofmem;
+ if (!b)
+ return fz_throw("outofmem: buffer struct");
b->refs = 1;
b->ownsdata = 0;
@@ -39,7 +45,7 @@ fz_newbufferwithmemory(fz_buffer **bp, unsigned char *data, int size)
b->ep = b->bp + size;
b->eof = 0;
- return nil;
+ return fz_okay;
}
fz_buffer *
@@ -69,26 +75,31 @@ fz_growbuffer(fz_buffer *buf)
int wp = buf->wp - buf->bp;
int ep = buf->ep - buf->bp;
- assert(buf->ownsdata);
+ if (!buf->ownsdata)
+ return fz_throw("assert: grow borrowed memory");
newbp = fz_realloc(buf->bp, ep * 2);
- if (!newbp) return fz_outofmem;
+ if (!newbp)
+ return fz_throw("outofmem: resize buffer memory");
buf->bp = newbp;
buf->rp = buf->bp + rp;
buf->wp = buf->bp + wp;
buf->ep = buf->bp + ep * 2;
- return nil;
+ return fz_okay;
}
fz_error *
fz_rewindbuffer(fz_buffer *buf)
{
- assert(buf->ownsdata);
+ if (!buf->ownsdata)
+ return fz_throw("assert: rewind borrowed memory");
+
memmove(buf->bp, buf->rp, buf->wp - buf->rp);
buf->wp = buf->bp + (buf->wp - buf->rp);
buf->rp = buf->bp;
- return nil;
+
+ return fz_okay;
}
diff --git a/stream/stm_filter.c b/stream/stm_filter.c
index c8091136..65b917d5 100644
--- a/stream/stm_filter.c
+++ b/stream/stm_filter.c
@@ -1,9 +1,9 @@
#include "fitz-base.h"
#include "fitz-stream.h"
-fz_error fz_kioneedin = { -1, "<ioneedin>", "<process>", "filter.c", 0 };
-fz_error fz_kioneedout = { -1, "<ioneedout>", "<process>", "filter.c", 0 };
-fz_error fz_kiodone = { -1, "<iodone>", "<process>", "filter.c", 0 };
+fz_error fz_kioneedin = { -1, "<ioneedin>", "<internal>", "<internal>", 0, 0 };
+fz_error fz_kioneedout = { -1, "<ioneedout>", "<internal>", "<internal>", 0, 0 };
+fz_error fz_kiodone = { -1, "<iodone>", "<internal>", "<internal>", 0, 0 };
fz_error *
fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out)
@@ -27,7 +27,11 @@ fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out)
f->count += out->wp - oldwp;
if (reason != fz_ioneedin && reason != fz_ioneedout)
+ {
+ if (reason != fz_iodone)
+ reason = fz_rethrow(reason, "cannot process filter");
out->eof = 1;
+ }
return reason;
}
diff --git a/stream/stm_misc.c b/stream/stm_misc.c
index bc739055..22d993d1 100644
--- a/stream/stm_misc.c
+++ b/stream/stm_misc.c
@@ -5,14 +5,16 @@
#include "fitz-base.h"
#include "fitz-stream.h"
-int fz_tell(fz_stream *stm)
+int
+fz_tell(fz_stream *stm)
{
if (stm->mode == FZ_SREAD)
return fz_rtell(stm);
return fz_wtell(stm);
}
-int fz_seek(fz_stream *stm, int offset, int whence)
+fz_error *
+fz_seek(fz_stream *stm, int offset, int whence)
{
if (stm->mode == FZ_SREAD)
return fz_rseek(stm, offset, whence);
@@ -23,8 +25,11 @@ int fz_seek(fz_stream *stm, int offset, int whence)
* Read a line terminated by LF or CR or CRLF.
*/
-int fz_readline(fz_stream *stm, char *mem, int n)
+fz_error *
+fz_readline(fz_stream *stm, char *mem, int n)
{
+ fz_error *error;
+
char *s = mem;
int c = EOF;
while (n > 1)
@@ -45,7 +50,11 @@ int fz_readline(fz_stream *stm, char *mem, int n)
}
if (n)
*s = '\0';
- return s - mem;
+
+ error = fz_readerror(stm);
+ if (error)
+ return fz_rethrow(error, "cannot read line");
+ return fz_okay;
}
/*
@@ -55,8 +64,10 @@ int fz_readline(fz_stream *stm, char *mem, int n)
enum { CHUNKSIZE = 1024 * 4 };
-int fz_readall(fz_buffer **bufp, fz_stream *stm)
+fz_error *
+fz_readall(fz_buffer **bufp, fz_stream *stm)
{
+ fz_error *error;
fz_buffer *real;
unsigned char *newbuf;
unsigned char *buf;
@@ -64,8 +75,6 @@ int fz_readall(fz_buffer **bufp, fz_stream *stm)
int pos;
int n;
- *bufp = nil;
-
len = 0;
pos = 0;
buf = nil;
@@ -79,17 +88,16 @@ int fz_readall(fz_buffer **bufp, fz_stream *stm)
if (!newbuf)
{
fz_free(buf);
- return -1;
+ return fz_throw("outofmem: scratch buffer");
}
buf = newbuf;
}
- n = fz_read(stm, buf + pos, len - pos);
-
- if (n < 0)
+ error = fz_read(&n, stm, buf + pos, len - pos);
+ if (error)
{
fz_free(buf);
- return -1;
+ return fz_rethrow(error, "cannot read data");
}
pos += n;
@@ -102,16 +110,16 @@ int fz_readall(fz_buffer **bufp, fz_stream *stm)
if (!newbuf)
{
fz_free(buf);
- return -1;
+ return fz_throw("outofmem: scratch buffer");
}
}
else newbuf = buf;
- real = *bufp = fz_malloc(sizeof(fz_buffer));
+ real = fz_malloc(sizeof(fz_buffer));
if (!real)
{
fz_free(newbuf);
- return -1;
+ return fz_throw("outofmem: buffer struct");
}
real->refs = 1;
@@ -122,7 +130,8 @@ int fz_readall(fz_buffer **bufp, fz_stream *stm)
real->ep = buf + pos;
real->eof = 1;
- return real->wp - real->rp;
+ *bufp = real;
+ return fz_okay;
}
}
}
diff --git a/stream/stm_open.c b/stream/stm_open.c
index 43d2a60b..c10d1509 100644
--- a/stream/stm_open.c
+++ b/stream/stm_open.c
@@ -28,19 +28,6 @@ newstm(int kind, int mode)
return stm;
}
-fz_error *
-fz_ioerror(fz_stream *stm)
-{
- fz_error *error;
- if (stm->error)
- {
- error = stm->error;
- stm->error = nil;
- return error;
- }
- return fz_throw("ioerror: no error");
-}
-
fz_stream *
fz_keepstream(fz_stream *stm)
{
@@ -56,7 +43,7 @@ fz_dropstream(fz_stream *stm)
{
if (stm->error)
{
- fz_warn("unhandled %s", stm->error->msg);
+ fz_warn("dropping unhandled ioerror");
fz_droperror(stm->error);
}
@@ -92,13 +79,13 @@ openfile(fz_stream **stmp, char *path, int mode, int realmode)
stm = newstm(FZ_SFILE, mode);
if (!stm)
- return fz_outofmem;
+ return fz_throw("outofmem: stream struct");
error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
if (error)
{
fz_free(stm);
- return error;
+ return fz_rethrow(error, "cannot create buffer");
}
stm->file = open(path, realmode, 0666);
@@ -106,11 +93,11 @@ openfile(fz_stream **stmp, char *path, int mode, int realmode)
{
fz_dropbuffer(stm->buffer);
fz_free(stm);
- return fz_throw("ioerror: open '%s' failed: %s", path, strerror(errno));
+ return fz_throw("syserr: open '%s': %s", path, strerror(errno));
}
*stmp = stm;
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -121,20 +108,20 @@ openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode)
stm = newstm(FZ_SFILTER, mode);
if (!stm)
- return fz_outofmem;
+ return fz_throw("outofmem: stream struct");
error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
if (error)
{
fz_free(stm);
- return error;
+ return fz_rethrow(error, "cannot create buffer");
}
stm->chain = fz_keepstream(src);
stm->filter = fz_keepfilter(flt);
*stmp = stm;
- return nil;
+ return fz_okay;
}
static fz_error *
@@ -144,7 +131,7 @@ openbuffer(fz_stream **stmp, fz_buffer *buf, int mode)
stm = newstm(FZ_SBUFFER, mode);
if (!stm)
- return fz_outofmem;
+ return fz_throw("outofmem: stream struct");
stm->buffer = fz_keepbuffer(buf);
@@ -152,18 +139,26 @@ openbuffer(fz_stream **stmp, fz_buffer *buf, int mode)
stm->buffer->eof = 1;
*stmp = stm;
- return nil;
+ return fz_okay;
}
fz_error * fz_openrfile(fz_stream **stmp, char *path)
{
- return openfile(stmp, path, FZ_SREAD, O_BINARY | O_RDONLY);
+ fz_error *error;
+ error = openfile(stmp, path, FZ_SREAD, O_BINARY | O_RDONLY);
+ if (error)
+ return fz_rethrow(error, "cannot open file for reading: '%s'", path);
+ return fz_okay;
}
fz_error * fz_openwfile(fz_stream **stmp, char *path)
{
- return openfile(stmp, path, FZ_SWRITE,
+ fz_error *error;
+ error = openfile(stmp, path, FZ_SWRITE,
O_BINARY | O_WRONLY | O_CREAT | O_TRUNC);
+ if (error)
+ return fz_rethrow(error, "cannot open file for writing: '%s'", path);
+ return fz_okay;
}
fz_error * fz_openafile(fz_stream **stmp, char *path)
@@ -173,51 +168,72 @@ fz_error * fz_openafile(fz_stream **stmp, char *path)
error = openfile(stmp, path, FZ_SWRITE, O_BINARY | O_WRONLY);
if (error)
- return error;
+ return fz_rethrow(error, "cannot open file for writing: '%s'", path);
t = lseek((*stmp)->file, 0, 2);
if (t < 0)
{
(*stmp)->dead = 1;
- return fz_throw("ioerror: lseek: %s", strerror(errno));
+ return fz_throw("syserr: lseek '%s': %s", path, strerror(errno));
}
- return nil;
+ return fz_okay;
}
fz_error * fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src)
{
- return openfilter(stmp, flt, src, FZ_SREAD);
+ fz_error *error;
+ error = openfilter(stmp, flt, src, FZ_SREAD);
+ if (error)
+ return fz_rethrow(error, "cannot create reading filter stream");
+ return fz_okay;
}
fz_error * fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src)
{
- return openfilter(stmp, flt, src, FZ_SWRITE);
+ fz_error *error;
+ error = openfilter(stmp, flt, src, FZ_SWRITE);
+ if (error)
+ return fz_rethrow(error, "cannot create writing filter stream");
+ return fz_okay;
}
fz_error * fz_openrbuffer(fz_stream **stmp, fz_buffer *buf)
{
- return openbuffer(stmp, buf, FZ_SREAD);
+ fz_error *error;
+ error = openbuffer(stmp, buf, FZ_SREAD);
+ if (error)
+ return fz_rethrow(error, "cannot create reading buffer stream");
+ return fz_okay;
}
fz_error * fz_openwbuffer(fz_stream **stmp, fz_buffer *buf)
{
- return openbuffer(stmp, buf, FZ_SWRITE);
+ fz_error *error;
+ error = openbuffer(stmp, buf, FZ_SWRITE);
+ if (error)
+ return fz_rethrow(error, "cannot create writing buffer stream");
+ return fz_okay;
}
-fz_error * fz_openrmemory(fz_stream **stmp, unsigned char *mem, int len)
+fz_error * fz_openrmemory(fz_stream **stmp, char *mem, int len)
{
fz_error *error;
fz_buffer *buf;
error = fz_newbufferwithmemory(&buf, mem, len);
if (error)
- return error;
+ return fz_rethrow(error, "cannot create memory buffer");
error = fz_openrbuffer(stmp, buf);
+ if (error)
+ {
+ fz_dropbuffer(buf);
+ return fz_rethrow(error, "cannot open memory buffer stream");
+ }
fz_dropbuffer(buf);
- return error;
+ return fz_okay;
}
diff --git a/stream/stm_read.c b/stream/stm_read.c
index 0ab7e076..43bdb192 100644
--- a/stream/stm_read.c
+++ b/stream/stm_read.c
@@ -5,8 +5,8 @@
#include "fitz-base.h"
#include "fitz-stream.h"
-int
-fz_makedata(fz_stream *stm)
+fz_error *
+fz_readimp(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
fz_error *error;
@@ -15,23 +15,29 @@ fz_makedata(fz_stream *stm)
int n;
if (stm->dead)
- return -1;
+ return fz_throw("assert: read from dead stream");
if (stm->mode != FZ_SREAD)
- return -1;
+ return fz_throw("assert: read from writing stream");
if (buf->eof)
- return 0;
+ return fz_okay;
error = fz_rewindbuffer(buf);
if (error)
- goto cleanup;
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot rewind output buffer");
+ }
if (buf->ep - buf->wp == 0)
{
error = fz_growbuffer(buf);
if (error)
- goto cleanup;
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot grow output buffer");
+ }
}
switch (stm->kind)
@@ -41,14 +47,15 @@ fz_makedata(fz_stream *stm)
n = read(stm->file, buf->wp, buf->ep - buf->wp);
if (n == -1)
{
- stm->error = fz_throw("ioerror: read: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return fz_throw("syserr: read: %s", strerror(errno));
}
+
if (n == 0)
buf->eof = 1;
buf->wp += n;
- return n;
+
+ return fz_okay;
case FZ_SFILTER:
produced = 0;
@@ -62,10 +69,11 @@ fz_makedata(fz_stream *stm)
if (reason == fz_ioneedin)
{
- if (fz_makedata(stm->chain) < 0)
+ error = fz_readimp(stm->chain);
+ if (error)
{
stm->dead = 1;
- return -1;
+ return fz_rethrow(error, "cannot read from input stream");
}
}
@@ -78,50 +86,52 @@ fz_makedata(fz_stream *stm)
{
error = fz_rewindbuffer(buf);
if (error)
- goto cleanup;
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot rewind buffer");
+ }
}
else
{
error = fz_growbuffer(buf);
if (error)
- goto cleanup;
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot grow buffer");
+ }
}
}
else if (reason == fz_iodone)
{
- return 0;
+ return fz_okay;
}
else
{
- error = reason;
- goto cleanup;
+ stm->dead = 1;
+ return fz_rethrow(reason, "cannot process filter");
}
}
case FZ_SBUFFER:
- return 0;
- }
+ return fz_okay;
- return -1;
-
-cleanup:
- stm->error = error;
- stm->dead = 1;
- return -1;
+ default:
+ return fz_throw("assert: unknown stream type");
+ }
}
-int fz_rtell(fz_stream *stm)
+int
+fz_rtell(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
int t;
if (stm->dead)
- return -1;
-
+ return EOF;
if (stm->mode != FZ_SREAD)
- return -1;
+ return EOF;
switch (stm->kind)
{
@@ -129,8 +139,9 @@ int fz_rtell(fz_stream *stm)
t = lseek(stm->file, 0, 1);
if (t < 0)
{
+ fz_warn("syserr: lseek: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return EOF;
}
return t - (buf->wp - buf->rp);
@@ -139,27 +150,30 @@ int fz_rtell(fz_stream *stm)
case FZ_SBUFFER:
return buf->rp - buf->bp;
- }
- return -1;
+ default:
+ return EOF;
+ }
}
-int fz_rseek(fz_stream *stm, int offset, int whence)
+fz_error *
+fz_rseek(fz_stream *stm, int offset, int whence)
{
+ fz_error *error;
fz_buffer *buf = stm->buffer;
int t, c;
if (stm->dead)
- return -1;
+ return fz_throw("assert: seek in dead stream");
if (stm->mode != FZ_SREAD)
- return -1;
+ return fz_throw("assert: read operation on writing stream");
if (whence == 1)
{
int cur = fz_rtell(stm);
if (cur < 0)
- return -1;
+ return fz_throw("cannot tell current position");
offset = cur + offset;
whence = 0;
}
@@ -172,103 +186,128 @@ int fz_rseek(fz_stream *stm, int offset, int whence)
t = lseek(stm->file, offset, whence);
if (t < 0)
{
- stm->error = fz_throw("ioerror: lseek: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return fz_throw("syserr: lseek: %s", strerror(errno));
}
buf->rp = buf->bp;
buf->wp = buf->bp;
- return t;
+ return fz_okay;
case FZ_SFILTER:
if (whence == 0)
{
- if (offset < fz_tell(stm))
+ if (offset < fz_rtell(stm))
{
- stm->error = fz_throw("ioerror: cannot seek back in filter");
stm->dead = 1;
- return -1;
+ return fz_throw("assert: seek backwards in filter");
}
- while (fz_tell(stm) < offset)
+ while (fz_rtell(stm) < offset)
{
c = fz_readbyte(stm);
if (c == EOF)
+ {
+ error = fz_readerror(stm);
+ if (error)
+ return fz_rethrow(error, "cannot seek forward in filter");
break;
+ }
}
- return fz_tell(stm);
- }
- else
- {
- stm->dead = 1;
- return -1;
+ return fz_okay;
}
+ stm->dead = 1;
+ return fz_throw("assert: relative seek in filter");
+
case FZ_SBUFFER:
if (whence == 0)
buf->rp = CLAMP(buf->bp + offset, buf->bp, buf->ep);
else
buf->rp = CLAMP(buf->ep + offset, buf->bp, buf->ep);
- return buf->rp - buf->bp;
- }
+ return fz_okay;
- return -1;
+ default:
+ return fz_throw("unknown stream type");
+ }
}
-int fz_readbytex(fz_stream *stm)
+fz_error *
+fz_read(int *np, fz_stream *stm, unsigned char *mem, int n)
{
+ fz_error *error;
fz_buffer *buf = stm->buffer;
- if (buf->rp == buf->wp)
+ int i = 0;
+
+ while (i < n)
{
- if (buf->eof) return EOF;
- if (fz_makedata(stm) < 0) return EOF;
+ while (buf->rp < buf->wp && i < n)
+ mem[i++] = *buf->rp++;
+
+ if (buf->rp == buf->wp)
+ {
+ if (buf->eof)
+ {
+ *np = i;
+ return fz_okay;
+ }
+
+ error = fz_readimp(stm);
+ if (error)
+ return fz_rethrow(error, "cannot produce data");
+ }
}
- if (buf->rp < buf->wp)
- return *buf->rp++;
- return EOF;
+
+ *np = i;
+ return fz_okay;
}
-int fz_peekbytex(fz_stream *stm)
+fz_error *
+fz_readerror(fz_stream *stm)
+{
+ fz_error *error;
+ if (stm->error)
+ {
+ error = stm->error;
+ stm->error = nil;
+ return fz_rethrow(error, "delayed read error");
+ }
+ return fz_okay;
+}
+
+int
+fz_readbytex(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
+
if (buf->rp == buf->wp)
{
- if (buf->eof) return EOF;
- if (fz_makedata(stm) < 0) return EOF;
+ if (!buf->eof && !stm->error)
+ {
+ fz_error *error = fz_readimp(stm);
+ if (error)
+ stm->error = fz_rethrow(error, "cannot read data");
+ }
}
- if (buf->rp < buf->wp)
- return *buf->rp;
- return EOF;
+
+ return buf->rp < buf->wp ? *buf->rp++ : EOF ;
}
-int fz_read(fz_stream *stm, unsigned char * restrict mem, int n)
+int
+fz_peekbytex(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
- int i = 0;
- while (i < n)
+ if (buf->rp == buf->wp)
{
-#if 0
- while (buf->rp < buf->wp && i < n)
- mem[i++] = *buf->rp++;
-#else
- int l = buf->wp - buf->rp;
- int ln = n;
- unsigned char * restrict src = buf->rp;
- ln = MIN(n - i, l) + i;
- while (i < ln) {
- mem[i++] = *src++;
- }
- buf->rp = src;
-#endif
- if (buf->rp == buf->wp)
+ if (!buf->eof && !stm->error)
{
- if (buf->eof) return i;
- if (fz_makedata(stm) < 0) return -1;
+ fz_error *error = fz_readimp(stm);
+ if (error)
+ stm->error = fz_rethrow(error, "cannot read data");
}
}
- return i;
+ return buf->rp < buf->wp ? *buf->rp : EOF ;
}
diff --git a/stream/stm_write.c b/stream/stm_write.c
index f619da9c..23b268d9 100644
--- a/stream/stm_write.c
+++ b/stream/stm_write.c
@@ -5,16 +5,17 @@
#include "fitz-base.h"
#include "fitz-stream.h"
-int fz_wtell(fz_stream *stm)
+int
+fz_wtell(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
int t;
if (stm->dead)
- return -1;
+ return EOF;
if (stm->mode != FZ_SWRITE)
- return -1;
+ return EOF;
switch (stm->kind)
{
@@ -22,9 +23,9 @@ int fz_wtell(fz_stream *stm)
t = lseek(stm->file, 0, 1);
if (t < 0)
{
- stm->error = fz_throw("ioerror: lseek: %s", strerror(errno));
+ fz_warn("syserr: lseek: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return EOF;
}
return t + (buf->wp - buf->rp);
@@ -33,46 +34,47 @@ int fz_wtell(fz_stream *stm)
case FZ_SBUFFER:
return buf->wp - buf->bp;
- }
- return -1;
+ default:
+ return EOF;
+ }
}
-int fz_wseek(fz_stream *stm, int offset, int whence)
+fz_error *
+fz_wseek(fz_stream *stm, int offset, int whence)
{
fz_buffer *buf = stm->buffer;
int t;
if (stm->dead)
- return -1;
+ return fz_throw("assert: seek in dead stream");
if (stm->mode != FZ_SWRITE)
- return -1;
+ return fz_throw("assert: write operation on reading stream");
if (stm->kind != FZ_SFILE)
- return -1;
+ return fz_throw("assert: write seek on non-file stream");
t = lseek(stm->file, offset, whence);
if (t < 0)
{
- stm->error = fz_throw("ioerror: lseek: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return fz_throw("syserr: lseek: %s", strerror(errno));
}
buf->rp = buf->bp;
buf->wp = buf->bp;
buf->eof = 0;
- return t;
+ return fz_okay;
}
-static int flushfilter(fz_stream *stm)
+static fz_error *
+fz_flushfilterimp(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
fz_error *error;
fz_error *reason;
- int t;
loop:
@@ -81,20 +83,30 @@ loop:
if (reason == fz_ioneedin)
{
if (buf->rp > buf->ep)
- fz_rewindbuffer(buf);
+ {
+ error = fz_rewindbuffer(buf);
+ if (error)
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot rewind buffer");
+ }
+ }
else
{
error = fz_growbuffer(buf);
if (error)
- goto cleanup;
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot grow buffer");
+ }
}
}
else if (reason == fz_ioneedout)
{
- t = fz_flush(stm->chain);
- if (t < 0)
- return -1;
+ error = fz_flush(stm->chain);
+ if (error)
+ return fz_rethrow(error, "cannot flush chain buffer");
}
else if (reason == fz_iodone)
@@ -104,20 +116,15 @@ loop:
else
{
- error = reason;
- goto cleanup;
+ stm->dead = 1;
+ return fz_rethrow(reason, "cannot process filter");
}
/* if we are at eof, repeat until other filter sets otherside to eof */
if (buf->eof && !stm->chain->buffer->eof)
goto loop;
- return 0;
-
-cleanup:
- stm->error = error;
- stm->dead = 1;
- return -1;
+ return fz_okay;
}
/*
@@ -126,20 +133,21 @@ cleanup:
* Called by fz_write and fz_dropstream.
* If buffer is eof, then all data must be flushed.
*/
-int fz_flush(fz_stream *stm)
+fz_error *
+fz_flush(fz_stream *stm)
{
fz_buffer *buf = stm->buffer;
fz_error *error;
int t;
- if (stm->dead == 2)
- return 0;
+ if (stm->dead == 2) /* eod flag */
+ return fz_okay;
if (stm->dead)
- return -1;
+ return fz_throw("assert: flush on dead stream");
if (stm->mode != FZ_SWRITE)
- return -1;
+ return fz_throw("assert: write operation on reading stream");
switch (stm->kind)
{
@@ -149,21 +157,30 @@ int fz_flush(fz_stream *stm)
t = write(stm->file, buf->rp, buf->wp - buf->rp);
if (t < 0)
{
- stm->error = fz_throw("ioerror: write: %s", strerror(errno));
stm->dead = 1;
- return -1;
+ return fz_throw("syserr: write: %s", strerror(errno));
}
buf->rp += t;
}
if (buf->rp > buf->bp)
- fz_rewindbuffer(buf);
+ {
+ error = fz_rewindbuffer(buf);
+ if (error)
+ {
+ stm->dead = 1;
+ return fz_rethrow(error, "cannot rewind buffer");
+ }
+ }
- return 0;
+ return fz_okay;
case FZ_SFILTER:
- return flushfilter(stm);
+ error = fz_flushfilterimp(stm);
+ if (error)
+ return fz_rethrow(error, "cannot flush through filter");
+ return fz_okay;
case FZ_SBUFFER:
if (!buf->eof && buf->wp == buf->ep)
@@ -171,36 +188,35 @@ int fz_flush(fz_stream *stm)
error = fz_growbuffer(buf);
if (error)
{
- stm->error = error;
stm->dead = 1;
- return -1;
+ return fz_rethrow(error, "cannot grow buffer");
}
}
- return 0;
- }
+ return fz_okay;
- return -1;
+ default:
+ return fz_throw("unknown stream type");
+ }
}
/*
* Write data to stream.
* Buffer until internal buffer is full.
* When full, call fz_flush to make more space available.
+ * Return error if all the data could not be written.
*/
-int fz_write(fz_stream *stm, unsigned char *mem, int n)
+fz_error *
+fz_write(fz_stream *stm, unsigned char *mem, int n)
{
fz_buffer *buf = stm->buffer;
+ fz_error *error;
int i = 0;
- int t;
-
- if (stm->dead == 2)
- return 0;
if (stm->dead)
- return -1;
+ return fz_throw("assert: write on dead stream");
if (stm->mode != FZ_SWRITE)
- return -1;
+ return fz_throw("assert: write on reading stream");
while (i < n)
{
@@ -209,24 +225,27 @@ int fz_write(fz_stream *stm, unsigned char *mem, int n)
if (buf->wp == buf->ep && i < n)
{
- t = fz_flush(stm);
- if (t < 0)
- return -1;
+ error = fz_flush(stm);
+ if (error)
+ return fz_rethrow(error, "cannot flush buffer");
if (stm->dead)
- return i;
+ return fz_throw("assert: write on dead stream");
}
}
- return n;
+ return fz_okay;
}
-int fz_printstr(fz_stream *stm, char *s)
+fz_error *
+fz_printstr(fz_stream *stm, char *s)
{
- return fz_write(stm, (unsigned char *) s, strlen(s));
+ return fz_write(stm, s, strlen(s));
}
-int fz_printobj(fz_stream *file, fz_obj *obj, int tight)
+fz_error *
+fz_printobj(fz_stream *file, fz_obj *obj, int tight)
{
+ fz_error *error;
char buf[1024];
char *ptr;
int n;
@@ -235,22 +254,29 @@ int fz_printobj(fz_stream *file, fz_obj *obj, int tight)
if (n < sizeof buf)
{
fz_sprintobj(buf, sizeof buf, obj, tight);
- return fz_write(file, (unsigned char *) buf, n);
+ error = fz_write(file, buf, n);
+ if (error)
+ return fz_rethrow(error, "cannot write buffer");
+ return fz_okay;
}
else
{
ptr = fz_malloc(n);
if (!ptr)
- return -1;
+ return fz_throw("outofmem: scratch buffer");
fz_sprintobj(ptr, n, obj, tight);
- n = fz_write(file, (unsigned char *) ptr, n);
+ error = fz_write(file, ptr, n);
+ if (error)
+ error = fz_rethrow(error, "cannot write buffer");
fz_free(ptr);
- return n;
+ return error;
}
}
-int fz_print(fz_stream *stm, char *fmt, ...)
+fz_error *
+fz_print(fz_stream *stm, char *fmt, ...)
{
+ fz_error *error;
va_list ap;
char buf[1024];
char *p;
@@ -261,20 +287,27 @@ int fz_print(fz_stream *stm, char *fmt, ...)
va_end(ap);
if (n < sizeof buf)
- return fz_write(stm, (unsigned char *) buf, n);
+ {
+ error = fz_write(stm, buf, n);
+ if (error)
+ return fz_rethrow(error, "cannot write buffer");
+ return fz_okay;
+ }
p = fz_malloc(n);
if (!p)
- return -1;
+ return fz_throw("outofmem: scratch buffer");
va_start(ap, fmt);
vsnprintf(p, n, fmt, ap);
va_end(ap);
- n = fz_write(stm, (unsigned char *) p, n);
+ error = fz_write(stm, p, n);
+ if (error)
+ error = fz_rethrow(error, "cannot write buffer");
fz_free(p);
- return n;
+ return error;
}
diff --git a/world/node_optimize.c b/world/node_optimize.c
index 7ee92496..69ca59cc 100644
--- a/world/node_optimize.c
+++ b/world/node_optimize.c
@@ -303,6 +303,8 @@ static fz_error *clean1x1(fz_node *node)
fz_error *
fz_optimizetree(fz_tree *tree)
{
+ if (getenv("DONTOPT"))
+ return nil;
cleanwhite(tree->root);
cleanovers(tree->root);
cleanmasks(tree->root);
diff --git a/world/node_path.c b/world/node_path.c
index b64d0742..dfae1560 100644
--- a/world/node_path.c
+++ b/world/node_path.c
@@ -232,12 +232,15 @@ fz_boundpathnode(fz_pathnode *path, fz_matrix ctm)
}
void
-fz_debugpathnode(fz_pathnode *path)
+fz_printpathnode(fz_pathnode *path, int indent)
{
float x, y;
int i = 0;
+ int n;
while (i < path->len)
{
+ for (n = 0; n < indent; n++)
+ putchar(' ');
switch (path->els[i++].k)
{
case FZ_MOVETO:
@@ -266,6 +269,9 @@ fz_debugpathnode(fz_pathnode *path)
}
}
+ for (n = 0; n < indent; n++)
+ putchar(' ');
+
switch (path->paint)
{
case FZ_STROKE:
@@ -280,6 +286,45 @@ fz_debugpathnode(fz_pathnode *path)
}
}
+void
+fz_debugpathnode(fz_pathnode *path, int indent)
+{
+ float x, y;
+ int i = 0;
+ int n;
+ while (i < path->len)
+ {
+ for (n = 0; n < indent; n++)
+ putchar(' ');
+ switch (path->els[i++].k)
+ {
+ case FZ_MOVETO:
+ x = path->els[i++].v;
+ y = path->els[i++].v;
+ printf("<moveto x=\"%g\" y=\"%g\" />\n", x, y);
+ break;
+ case FZ_LINETO:
+ x = path->els[i++].v;
+ y = path->els[i++].v;
+ printf("<lineto x=\"%g\" y=\"%g\" />\n", x, y);
+ break;
+ case FZ_CURVETO:
+ x = path->els[i++].v;
+ y = path->els[i++].v;
+ printf("<curveto x1=\"%g\" y1=\"%g\" ", x, y);
+ x = path->els[i++].v;
+ y = path->els[i++].v;
+ printf("x2=\"%g\" y2=\"%g\" ", x, y);
+ x = path->els[i++].v;
+ y = path->els[i++].v;
+ printf("x3=\"%g\" y3=\"%g\" />\n", x, y);
+ break;
+ case FZ_CLOSEPATH:
+ printf("<closepath />\n");
+ }
+ }
+}
+
fz_error *
fz_newdash(fz_dash **dashp, float phase, int len, float *array)
{
diff --git a/world/node_toxml.c b/world/node_toxml.c
index c6cf146e..ad2143c4 100644
--- a/world/node_toxml.c
+++ b/world/node_toxml.c
@@ -49,7 +49,7 @@ static void xmlblend(fz_blendnode *node, int level)
{
fz_node *child;
indent(level);
- printf("<blend mode=\"%d\" refs=\"%d\">\n", node->mode, node->cs->refs);
+ printf("<blend mode=\"%d\">\n", node->mode);
for (child = node->super.first; child; child = child->next)
xmlnode(child, level + 1);
indent(level);
@@ -60,9 +60,9 @@ static void xmltransform(fz_transformnode *node, int level)
{
indent(level);
printf("<transform matrix=\"%g %g %g %g %g %g\">\n",
- node->m.a, node->m.b,
- node->m.c, node->m.d,
- node->m.e, node->m.f);
+ node->m.a, node->m.b,
+ node->m.c, node->m.d,
+ node->m.e, node->m.f);
xmlnode(node->super.first, level + 1);
indent(level);
printf("</transform>\n");
@@ -79,13 +79,13 @@ static void xmlsolid(fz_solidnode *node, int level)
if (i < node->n - 1)
putchar(' ');
}
- printf("\" refs=\"%d\" />\n", node->cs->refs);
+ printf("\" />\n");
}
static void xmllink(fz_linknode *node, int level)
{
indent(level);
- printf("<link name=\"%p\" refs=\"%d\" />\n", (void *) node->tree, node->tree->refs);
+ printf("<link name=\"%p\" />\n", node->tree);
}
static void xmlpath(fz_pathnode *node, int level)
@@ -97,10 +97,10 @@ static void xmlpath(fz_pathnode *node, int level)
if (node->paint == FZ_STROKE)
{
printf("<path fill=\"stroke\" cap=\"%d\" join=\"%d\" width=\"%g\" miter=\"%g\"",
- node->linecap,
- node->linejoin,
- node->linewidth,
- node->miterlimit);
+ node->linecap,
+ node->linejoin,
+ node->linewidth,
+ node->miterlimit);
if (node->dash)
{
printf(" phase=\"%g\" array=\"", node->dash->phase);
@@ -116,7 +116,7 @@ static void xmlpath(fz_pathnode *node, int level)
node->paint == FZ_FILL ? "nonzero" : "evenodd");
}
- fz_debugpathnode(node);
+ fz_debugpathnode(node, level + 2);
indent(level);
printf("</path>\n");
@@ -128,7 +128,7 @@ static void xmltext(fz_textnode *node, int level)
indent(level);
printf("<text font=\"%s\" matrix=\"%g %g %g %g\">\n", node->font->name,
- node->trm.a, node->trm.b, node->trm.c, node->trm.d);
+ node->trm.a, node->trm.b, node->trm.c, node->trm.d);
for (i = 0; i < node->len; i++)
{
@@ -149,14 +149,14 @@ static void xmlimage(fz_imagenode *node, int level)
{
fz_image *image = node->image;
indent(level);
- printf("<image w=\"%d\" h=\"%d\" n=\"%d\" a=\"%d\" refs=\"%d\" />\n",
- image->w, image->h, image->n, image->a, image->refs);
+ printf("<image w=\"%d\" h=\"%d\" n=\"%d\" a=\"%d\" />\n",
+ image->w, image->h, image->n, image->a);
}
static void xmlshade(fz_shadenode *node, int level)
{
indent(level);
- printf("<shade refs=\"%d\" />\n", node->shade->refs);
+ printf("<shade />\n");
}
static void xmlnode(fz_node *node, int level)