diff options
46 files changed, 621 insertions, 1323 deletions
@@ -134,18 +134,21 @@ Library libstream : obj_print.c obj_simple.c - stm_filter.c stm_buffer.c - stm_filec.c - stm_filer.c - stm_filew.c + stm_filter.c + stm_open.c + stm_read.c + stm_write.c + stm_misc.c filt_pipeline.c + filt_arc4.c + filt_null.c + filt_a85d.c filt_a85e.c filt_ahxd.c filt_ahxe.c - filt_arc4.c filt_dctd.c filt_dcte.c filt_faxd.c @@ -155,7 +158,6 @@ Library libstream : filt_flate.c filt_lzwd.c filt_lzwe.c - filt_null.c filt_predict.c filt_rld.c filt_rle.c @@ -1,3 +1,5 @@ +heh. bug in pdfselect on compressed object streams. gc takes forever, no objects remain... + lazy nametree lazy pagetree diff --git a/apps/pdfdebug.c b/apps/pdfdebug.c index bb2d57e2..1ae84d7c 100644 --- a/apps/pdfdebug.c +++ b/apps/pdfdebug.c @@ -43,47 +43,49 @@ void printsafe(unsigned char *buf, int n) void decodestream(pdf_xref *xref, int oid, int gid) { fz_error *error; + fz_stream *stm; unsigned char buf[512]; safecol = 0; - error = pdf_openstream(xref, oid, gid); + error = pdf_openstream(&stm, xref, oid, gid); if (error) fz_abort(error); while (1) { - int n = fz_read(xref->stream, buf, sizeof buf); + int n = fz_read(stm, buf, sizeof buf); if (n == 0) break; if (n < 0) - fz_abort(fz_ferror(xref->stream)); + fz_abort(fz_throw("ioerror: read failed")); printsafe(buf, n); } - pdf_closestream(xref); + fz_dropstream(stm); } void copystream(pdf_xref *xref, int oid, int gid) { fz_error *error; + fz_stream *stm; unsigned char buf[512]; safecol = 0; - error = pdf_openrawstream(xref, oid, gid); + error = pdf_openrawstream(&stm, xref, oid, gid); if (error) fz_abort(error); while (1) { - int n = fz_read(xref->stream, buf, sizeof buf); + int n = fz_read(stm, buf, sizeof buf); if (n == 0) break; if (n < 0) - fz_abort(fz_ferror(xref->stream)); + fz_abort(fz_throw("ioerror: read failed")); printsafe(buf, n); } - pdf_closestream(xref); + fz_dropstream(stm); } void printobject(pdf_xref *xref, int oid, int gid) diff --git a/apps/samshow.c b/apps/samshow.c index d84799a0..aa4030cc 100644 --- a/apps/samshow.c +++ b/apps/samshow.c @@ -5,8 +5,9 @@ int runzip(int argc, char **argv) { fz_error *error; fz_buffer *buf; + fz_stream *stm; sa_zip *zip; - int i; + int i, n; error = sa_openzip(&zip, argv[1]); if (error) @@ -17,13 +18,13 @@ int runzip(int argc, char **argv) for (i = 2; i < argc; i++) { - error = sa_openzipentry(zip, argv[i]); + error = sa_openzipentry(&stm, zip, argv[i]); if (error) fz_abort(error); - error = fz_readfile(&buf, zip->file); - if (error) - fz_abort(error); - sa_closezipentry(zip); + n = fz_readall(&buf, stm); + if (n < 0) + fz_abort(fz_throw("ioerror: readall failed")); + fz_dropstream(stm); fwrite(buf->rp, 1, buf->wp - buf->rp, stdout); @@ -38,11 +39,11 @@ int runzip(int argc, char **argv) int runxml(int argc, char **argv) { fz_error *error; - fz_file *file; + fz_stream *file; sa_xmlparser *parser; sa_xmlitem *item; - error = fz_openfile(&file, argv[1], FZ_READ); + error = fz_openrfile(&file, argv[1]); if (error) fz_abort(error); @@ -55,19 +56,19 @@ int runxml(int argc, char **argv) sa_debugxml(item, 0); sa_closexml(parser); - fz_closefile(file); + fz_dropstream(file); return 0; } -extern fz_error *sa_readtiff(fz_file *); +extern fz_error *sa_readtiff(fz_stream *); int runtiff(int argc, char **argv) { fz_error *error; - fz_file *file; + fz_stream *file; - error = fz_openfile(&file, argv[1], FZ_READ); + error = fz_openrfile(&file, argv[1]); if (error) fz_abort(error); @@ -75,7 +76,7 @@ int runtiff(int argc, char **argv) if (error) fz_abort(error); - fz_closefile(file); + fz_dropstream(file); return 0; } diff --git a/include/fitz.h b/include/fitz.h index 7bcc2b01..942219bb 100644 --- a/include/fitz.h +++ b/include/fitz.h @@ -3,6 +3,9 @@ #endif #define _FITZ_H_ +/* + * Base library + */ #include "fitz/sysdep.h" #include "fitz/cpudep.h" #include "fitz/base.h" @@ -10,23 +13,35 @@ #include "fitz/geometry.h" #include "fitz/hash.h" +/* + * Streams and dynamic objects + */ +#include "fitz/crypt.h" +#include "fitz/object.h" +#include "fitz/buffer.h" +#include "fitz/filter.h" +#include "fitz/stream.h" + +/* + * Resources + */ #include "fitz/cmap.h" #include "fitz/font.h" - #include "fitz/pixmap.h" #include "fitz/colorspace.h" #include "fitz/image.h" #include "fitz/shade.h" +/* + * Display tree + */ #include "fitz/tree.h" #include "fitz/path.h" #include "fitz/text.h" +/* + * Renderer + */ #include "fitz/pathscan.h" #include "fitz/render.h" -#include "fitz/crypt.h" -#include "fitz/object.h" -#include "fitz/filter.h" -#include "fitz/file.h" - diff --git a/include/fitz/buffer.h b/include/fitz/buffer.h new file mode 100644 index 00000000..1a6f34ad --- /dev/null +++ b/include/fitz/buffer.h @@ -0,0 +1,41 @@ +/* + * Data buffers for streams and filters. + * + * bp is the pointer to the allocated memory + * rp is read-position (*in->rp++ to read data) + * wp is write-position (*out->wp++ to write data) + * ep is the sentinel + * + * Only the data between rp and wp is valid data. + * + * Writers set eof to true at the end. + * Readers look at eof. + * + * A buffer owns the memory it has allocated, unless ownsdata is false, + * in which case the creator of the buffer owns it. + */ + +typedef struct fz_buffer_s fz_buffer; + +#define FZ_BUFSIZE (8 * 1024) + +struct fz_buffer_s +{ + int refs; + int ownsdata; + unsigned char *bp; + unsigned char *rp; + unsigned char *wp; + unsigned char *ep; + int eof; +}; + +fz_error *fz_newbuffer(fz_buffer **bufp, int size); +fz_error *fz_newbufferwithmemory(fz_buffer **bufp, unsigned char *data, int size); + +fz_error *fz_rewindbuffer(fz_buffer *buf); +fz_error *fz_growbuffer(fz_buffer *buf); + +fz_buffer *fz_keepbuffer(fz_buffer *buf); +void fz_dropbuffer(fz_buffer *buf); + diff --git a/include/fitz/crypt.h b/include/fitz/crypt.h index 647a1eda..15191caa 100644 --- a/include/fitz/crypt.h +++ b/include/fitz/crypt.h @@ -1,3 +1,9 @@ +/* + * Basic crypto functions. + * Independent of the rest of fitz. + * For further encapsulation in filters, or not. + */ + /* md5 digests */ typedef struct fz_md5_s fz_md5; @@ -28,3 +34,6 @@ void fz_arc4init(fz_arc4 *state, unsigned char *key, unsigned len); unsigned char fz_arc4next(fz_arc4 *state); void fz_arc4encrypt(fz_arc4 *state, unsigned char *dest, unsigned char *src, unsigned len); +/* TODO: sha1 */ +/* TODO: aes */ + diff --git a/include/fitz/file.h b/include/fitz/file.h deleted file mode 100644 index c87ccf5d..00000000 --- a/include/fitz/file.h +++ /dev/null @@ -1,38 +0,0 @@ -typedef struct fz_file_s fz_file; - -enum { FZ_READ, FZ_WRITE, FZ_APPEND }; - -struct fz_file_s -{ - int mode; /* FZ_READ or FZ_WRITE */ - int fd; - int depth; - fz_filter *filter; - fz_buffer *in; - fz_buffer *out; - fz_error *error; -}; - -fz_error *fz_openfile(fz_file **filep, char *path, int mode); -fz_error *fz_openbuffer(fz_file **filep, fz_buffer *buf, int mode); -fz_error *fz_pushfilter(fz_file *file, fz_filter *filter); -void fz_popfilter(fz_file *file); -void fz_closefile(fz_file *file); -fz_error *fz_ferror(fz_file *f); - -int fz_seek(fz_file *f, int ofs, int whence); -int fz_tell(fz_file *f); - -int fz_readbyte(fz_file *f); -int fz_peekbyte(fz_file *f); -int fz_readline(fz_file *f, char *buf, int n); -int fz_read(fz_file *f, unsigned char *buf, int n); - -fz_error *fz_readfile(fz_buffer **bufp, fz_file *file); - -int fz_printstring(fz_file *f, char *s); -int fz_printobj(fz_file *f, fz_obj *o, int tight); -int fz_print(fz_file *f, char *fmt, ...); -int fz_write(fz_file *f, unsigned char *buf, int n); -int fz_flush(fz_file *f); - diff --git a/include/fitz/filter.h b/include/fitz/filter.h index bb33b8eb..f8902f98 100644 --- a/include/fitz/filter.h +++ b/include/fitz/filter.h @@ -1,7 +1,29 @@ -typedef struct fz_filter_s fz_filter; -typedef struct fz_buffer_s fz_buffer; +/* + * Data filters for encryption, compression and decompression. + * + * A filter has one method, process, that takes an input and an output buffer. + * + * It returns one of three statuses: + * ioneedin -- input buffer exhausted, please give me more data (wp-rp) + * ioneedout -- output buffer exhausted, please provide more space (ep-wp) + * iodone -- finished, please never call me again. ever! + * or... + * any other error object -- oops, something blew up. + * + * To make using the filter easier, three variables are updated: + * produced -- if we actually produced any new data + * consumed -- like above + * count -- number of bytes produced in total since the beginning + * + * Most filters take fz_obj as a way to specify parameters. + * In most cases, this is a dictionary that contains the same keys + * that the corresponding PDF filter would expect. + * + * The pipeline filter is special, and needs some care when chaining + * and unchaining new filters. + */ -#define FZ_BUFSIZE (32 * 1024) +typedef struct fz_filter_s fz_filter; #define fz_ioneedin (&fz_kioneedin) #define fz_ioneedout (&fz_kioneedout) @@ -11,6 +33,10 @@ extern fz_error fz_kioneedin; extern fz_error fz_kioneedout; extern fz_error fz_kiodone; +/* + * Evil looking macro to create an initialize a filter struct. + */ + #define FZ_NEWFILTER(TYPE,VAR,NAME) \ fz_error * fz_process ## NAME (fz_filter*,fz_buffer*,fz_buffer*); \ void fz_drop ## NAME (fz_filter*); \ @@ -35,35 +61,19 @@ struct fz_filter_s int count; }; -struct fz_buffer_s -{ - int refs; - int ownsdata; - unsigned char *bp; - unsigned char *rp; - unsigned char *wp; - unsigned char *ep; - int eof; -}; - fz_error *fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out); fz_filter *fz_keepfilter(fz_filter *f); void fz_dropfilter(fz_filter *f); -fz_error *fz_newnullfilter(fz_filter **fp, int len); -fz_error *fz_newarc4filter(fz_filter **fp, unsigned char *key, unsigned keylen); fz_error *fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail); - fz_error *fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_buffer *buf); void fz_unchainpipeline(fz_filter *pipe, fz_filter **oldfp, fz_buffer **oldbp); -fz_error *fz_newbuffer(fz_buffer **bufp, int size); -fz_error *fz_newbufferwithdata(fz_buffer **bufp, unsigned char *data, int size); -fz_error *fz_rewindbuffer(fz_buffer *buf); -fz_error *fz_growbuffer(fz_buffer *buf); -fz_buffer *fz_keepbuffer(fz_buffer *buf); -void fz_dropbuffer(fz_buffer *buf); +/* stop and reverse! special case needed for postscript only */ +void fz_pushbackahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out, int n); +fz_error *fz_newnullfilter(fz_filter **fp, int len); +fz_error *fz_newarc4filter(fz_filter **fp, unsigned char *key, unsigned keylen); fz_error *fz_newa85d(fz_filter **filterp, fz_obj *param); fz_error *fz_newa85e(fz_filter **filterp, fz_obj *param); fz_error *fz_newahxd(fz_filter **filterp, fz_obj *param); @@ -83,5 +93,3 @@ fz_error *fz_newpredicte(fz_filter **filterp, fz_obj *param); fz_error *fz_newjbig2d(fz_filter **filterp, fz_obj *param); fz_error *fz_newjpxd(fz_filter **filterp, fz_obj *param); -void fz_pushbackahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out, int n); - diff --git a/include/fitz/hash.h b/include/fitz/hash.h index 2ada17f4..5d2ec1b5 100644 --- a/include/fitz/hash.h +++ b/include/fitz/hash.h @@ -1,3 +1,7 @@ +/* + * Generic hash-table with fixed-length keys. + */ + typedef struct fz_hashtable_s fz_hashtable; fz_error *fz_newhash(fz_hashtable **tablep, int initialsize, int keylen); diff --git a/include/fitz/object.h b/include/fitz/object.h index 34b62f59..fe9c12e5 100644 --- a/include/fitz/object.h +++ b/include/fitz/object.h @@ -1,3 +1,9 @@ +/* + * Dynamic objects. + * The same type of objects as found in PDF and PostScript. + * Used by the filter library and the mupdf parser. + */ + typedef struct fz_obj_s fz_obj; typedef struct fz_keyval_s fz_keyval; diff --git a/include/fitz/path.h b/include/fitz/path.h index 75b3060d..6a7c55b7 100644 --- a/include/fitz/path.h +++ b/include/fitz/path.h @@ -1,3 +1,17 @@ +/* + * Vector path nodes in the display tree. + * They can be stroked and dashed, or be filled. + * They have a fill rule (nonzero or evenodd). + * + * When rendering, they are flattened, stroked and dashed straight + * into the Global Edge List. + * + * TODO flatten, stroke and dash into another path + * TODO set operations on flat paths (union, intersect, difference) + * TODO decide whether dashing should be part of the tree and renderer, + * or if it is something the client has to do (with a util function). + */ + typedef struct fz_stroke_s fz_stroke; typedef struct fz_dash_s fz_dash; typedef union fz_pathel_s fz_pathel; diff --git a/include/fitz/stream.h b/include/fitz/stream.h new file mode 100644 index 00000000..5140fcca --- /dev/null +++ b/include/fitz/stream.h @@ -0,0 +1,103 @@ +/*
+ * Stream API for Fitz.
+ * Read and write data to and from files, memory buffers and filters.
+ */
+
+typedef struct fz_stream_s fz_stream;
+
+enum { FZ_SFILE, FZ_SBUFFER, FZ_SFILTER };
+enum { FZ_SREAD, FZ_SWRITE };
+
+struct fz_stream_s
+{
+ int refs;
+ int kind;
+ int mode;
+ int dead;
+ fz_buffer *buffer;
+ fz_filter *filter;
+ fz_stream *chain;
+ int file;
+};
+
+/*
+ * Various stream creation functions.
+ */
+
+/* open() and creat() & co */
+fz_error *fz_openrfile(fz_stream **stmp, char *filename);
+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, char *buf, int len);
+fz_error *fz_openrbuffer(fz_stream **stmp, fz_buffer *buf);
+fz_error *fz_openwbuffer(fz_stream **stmp, fz_buffer *buf);
+
+/* almost like fork() exec() pipe() */
+fz_error *fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *chain);
+fz_error *fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *chain);
+
+/*
+ * Functions that are common to both input and output streams.
+ */
+
+/* behave like dup() */
+fz_stream *fz_keepstream(fz_stream *stm);
+
+/* essentially your close() */
+void fz_dropstream(fz_stream *stm);
+
+int fz_tell(fz_stream *stm);
+int 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);
+
+int fz_makedata(fz_stream *stm);
+int fz_read(fz_stream *stm, unsigned char *buf, int len);
+
+int fz_readall(fz_buffer **bufp, fz_stream *stm);
+int fz_readline(fz_stream *stm, char *buf, int max);
+
+int fz_readbytex(fz_stream *stm);
+int fz_peekbytex(fz_stream *stm);
+
+#if 1
+#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_READBYTE(*buf->rp++)
+static inline int fz_peekbyte(fz_stream *stm) FZ_READBYTE(*buf->rp)
+
+#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);
+
+int fz_write(fz_stream *stm, unsigned char *buf, int n);
+int 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, ...);
+
diff --git a/include/fitz/text.h b/include/fitz/text.h index 8bb6ee5a..619aae83 100644 --- a/include/fitz/text.h +++ b/include/fitz/text.h @@ -1,3 +1,25 @@ +/* + * Fitz display tree text node. + * + * The text node is an optimization to reference glyphs in a font resource + * and specifying an individual transform matrix for each one. + * + * The trm field contains the a, b, c and d coefficients. + * The e and f coefficients come from the individual elements, + * together they form the transform matrix for the glyph. + * + * Glyphs are referenced by glyph ID. + * The Unicode text equivalent is kept in a separate array + * with indexes into the glyph array. + * + +TODO the unicode textels + +struct fz_textgid_s { float e, f; int gid; }; +struct fz_textucs_s { int idx; int ucs; }; + + */ + typedef struct fz_textel_s fz_textel; struct fz_textel_s diff --git a/include/fitz/tree.h b/include/fitz/tree.h index ced3b491..9f76f167 100644 --- a/include/fitz/tree.h +++ b/include/fitz/tree.h @@ -1,3 +1,10 @@ +/* + * The display tree is at the center of attention in Fitz. + * The tree and most of its minor nodes. + * Paths and text nodes are found elsewhere. + * Resources used are also found elsewhere. + */ + typedef struct fz_tree_s fz_tree; typedef struct fz_node_s fz_node; diff --git a/include/mupdf/content.h b/include/mupdf/content.h index adc5757a..ad6b824d 100644 --- a/include/mupdf/content.h +++ b/include/mupdf/content.h @@ -105,6 +105,6 @@ fz_error *pdf_showimage(pdf_csi*, pdf_image *img); /* interpret.c */ fz_error *pdf_newcsi(pdf_csi **csip, int maskonly); -fz_error *pdf_runcsi(pdf_csi *, pdf_xref *xref, fz_obj *rdb, fz_file *); +fz_error *pdf_runcsi(pdf_csi *, pdf_xref *xref, fz_obj *rdb, fz_stream *); void pdf_dropcsi(pdf_csi *csi); diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h index 5b78a1e8..1b245987 100644 --- a/include/mupdf/rsrc.h +++ b/include/mupdf/rsrc.h @@ -135,7 +135,7 @@ struct pdf_image_s fz_buffer *samples; }; -fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_file *file); +fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *ref); fz_error *pdf_loadtile(fz_image *image, fz_pixmap *tile); @@ -197,7 +197,7 @@ struct pdf_font_s }; /* cmap.c */ -fz_error *pdf_parsecmap(fz_cmap **cmapp, fz_file *file); +fz_error *pdf_parsecmap(fz_cmap **cmapp, fz_stream *file); fz_error *pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *ref); fz_error *pdf_loadsystemcmap(fz_cmap **cmapp, char *name); fz_error *pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes); diff --git a/include/mupdf/syntax.h b/include/mupdf/syntax.h index 87fc946a..d5598cd5 100644 --- a/include/mupdf/syntax.h +++ b/include/mupdf/syntax.h @@ -17,13 +17,13 @@ enum }; /* lex.c */ -int pdf_lex(fz_file *f, unsigned char *buf, int n, int *len); +int pdf_lex(fz_stream *f, unsigned char *buf, int n, int *len); /* parse.c */ -fz_error *pdf_parsearray(fz_obj **op, fz_file *f, char *buf, int cap); -fz_error *pdf_parsedict(fz_obj **op, fz_file *f, char *buf, int cap); -fz_error *pdf_parsestmobj(fz_obj **op, fz_file *f, char *buf, int cap); -fz_error *pdf_parseindobj(fz_obj **op, fz_file *f, char *buf, int cap, int *oid, int *gid, int *stmofs); +fz_error *pdf_parsearray(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parsedict(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parsestmobj(fz_obj **op, fz_stream *f, char *buf, int cap); +fz_error *pdf_parseindobj(fz_obj **op, fz_stream *f, char *buf, int cap, int *oid, int *gid, int *stmofs); fz_rect pdf_torect(fz_obj *array); fz_matrix pdf_tomatrix(fz_obj *array); diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h index d16d81f4..3143719d 100644 --- a/include/mupdf/xref.h +++ b/include/mupdf/xref.h @@ -7,8 +7,7 @@ typedef struct pdf_xref_s pdf_xref; struct pdf_xref_s { - fz_file *file; - fz_file *stream; + fz_stream *file; float version; int startxref; pdf_crypt *crypt; @@ -61,13 +60,12 @@ fz_error *pdf_loadobject(fz_obj **objp, pdf_xref *, int oid, int gen); fz_error *pdf_loadindirect(fz_obj **objp, pdf_xref *, fz_obj *ref); fz_error *pdf_resolve(fz_obj **reforobj, pdf_xref *); -fz_error *pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj); int pdf_isstream(pdf_xref *xref, int oid, int gen); +fz_error *pdf_buildinlinefilter(fz_filter **filterp, fz_obj *stmobj); fz_error *pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); fz_error *pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen); -fz_error *pdf_openrawstream(pdf_xref *, int oid, int gen); -fz_error *pdf_openstream(pdf_xref *, int oid, int gen); -void pdf_closestream(pdf_xref *); +fz_error *pdf_openrawstream(fz_stream **stmp, pdf_xref *, int oid, int gen); +fz_error *pdf_openstream(fz_stream **stmp, pdf_xref *, int oid, int gen); fz_error *pdf_garbagecollect(pdf_xref *xref); fz_error *pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *old); diff --git a/include/samus.h b/include/samus.h index 215fe573..dd5e4656 100644 --- a/include/samus.h +++ b/include/samus.h @@ -9,4 +9,5 @@ #include "samus/zip.h" #include "samus/xml.h" +#include "samus/pack.h" diff --git a/include/samus/package.h b/include/samus/pack.h index 4c8512f7..bba55d2f 100644 --- a/include/samus/package.h +++ b/include/samus/pack.h @@ -6,7 +6,6 @@ typedef struct sa_package_s sa_package; fz_error *sa_openpackage(sa_package **packp, char *filename); char *sa_accesspart(sa_package *pack, char *partname); -fz_error *sa_openpart(fz_file **filep, sa_package *pack, char *partname); -void sa_closepart(sa_package *pack, fz_file *file); +fz_error *sa_openpart(fz_stream **filep, sa_package *pack, char *partname); void sa_closepackage(sa_package *pack); diff --git a/include/samus/xml.h b/include/samus/xml.h index 56c19b0a..b72fbe56 100644 --- a/include/samus/xml.h +++ b/include/samus/xml.h @@ -7,7 +7,7 @@ typedef struct sa_xmlparser_s sa_xmlparser; typedef struct sa_xmlitem_s sa_xmlitem; -fz_error *sa_openxml(sa_xmlparser **spp, fz_file *file, int ns); +fz_error *sa_openxml(sa_xmlparser **spp, fz_stream *file, int ns); void sa_debugxml(sa_xmlitem *item, int level); void sa_closexml(sa_xmlparser *sp); @@ -15,12 +15,6 @@ sa_xmlitem *sa_xmlnext(sa_xmlparser *sp); void sa_xmldown(sa_xmlparser *sp); void sa_xmlup(sa_xmlparser *sp); -int sa_isxmlerror(sa_xmlitem *item); -int sa_isxmltext(sa_xmlitem *item); -int sa_isxmltag(sa_xmlitem *item); - -char *sa_xmlerror(sa_xmlitem *item); char *sa_xmlname(sa_xmlitem *item); char *sa_xmlatt(sa_xmlitem *item, char *att); -char *sa_xmltext(sa_xmlitem *item); diff --git a/include/samus/zip.h b/include/samus/zip.h index 2d3635f7..e06e1e90 100644 --- a/include/samus/zip.h +++ b/include/samus/zip.h @@ -3,27 +3,10 @@ */ typedef struct sa_zip_s sa_zip; -typedef struct sa_zipent_s sa_zipent; - -struct sa_zipent_s -{ - unsigned offset; - unsigned csize; - unsigned usize; - char *name; -}; - -struct sa_zip_s -{ - fz_file *file; - int len; - sa_zipent *table; -}; fz_error *sa_openzip(sa_zip **zipp, char *filename); void sa_debugzip(sa_zip *zip); void sa_closezip(sa_zip *zip); int sa_accesszipentry(sa_zip *zip, char *name); -fz_error *sa_openzipentry(sa_zip *zip, char *name); -void sa_closezipentry(sa_zip *zip); +fz_error *sa_openzipentry(fz_stream **stmp, sa_zip *zip, char *name); diff --git a/mupdf/pdf_cmap.c b/mupdf/pdf_cmap.c index 5029ae4a..45a0eed7 100644 --- a/mupdf/pdf_cmap.c +++ b/mupdf/pdf_cmap.c @@ -40,7 +40,7 @@ static int codefromstring(unsigned char *buf, int len) return a; } -static int mylex(fz_file *file, char *buf, int n, int *sl) +static int mylex(fz_stream *file, char *buf, int n, int *sl) { int token = pdf_lex(file, buf, n, sl); if (token == PDF_TKEYWORD) @@ -48,7 +48,7 @@ static int mylex(fz_file *file, char *buf, int n, int *sl) return token; } -static fz_error *parsecmapname(fz_cmap *cmap, fz_file *file) +static fz_error *parsecmapname(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -63,7 +63,7 @@ static fz_error *parsecmapname(fz_cmap *cmap, fz_file *file) return fz_throw("syntaxerror in CMap after /CMapName"); } -static fz_error *parsewmode(fz_cmap *cmap, fz_file *file) +static fz_error *parsewmode(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -78,7 +78,7 @@ static fz_error *parsewmode(fz_cmap *cmap, fz_file *file) return fz_throw("syntaxerror in CMap after /WMode"); } -static fz_error *parsecodespacerange(fz_cmap *cmap, fz_file *file) +static fz_error *parsecodespacerange(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -113,7 +113,7 @@ static fz_error *parsecodespacerange(fz_cmap *cmap, fz_file *file) return fz_throw("syntaxerror in CMap codespacerange section"); } -static fz_error *parsecidrange(fz_cmap *cmap, fz_file *file) +static fz_error *parsecidrange(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -154,7 +154,7 @@ cleanup: return fz_throw("syntaxerror in CMap cidrange section"); } -static fz_error *parsecidchar(fz_cmap *cmap, fz_file *file) +static fz_error *parsecidchar(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -189,7 +189,7 @@ cleanup: return fz_throw("syntaxerror in CMap cidchar section"); } -static fz_error *parsebfrange(fz_cmap *cmap, fz_file *file) +static fz_error *parsebfrange(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -231,7 +231,7 @@ cleanup: return fz_throw("syntaxerror in CMap bfrange section"); } -static fz_error *parsebfchar(fz_cmap *cmap, fz_file *file) +static fz_error *parsebfchar(fz_cmap *cmap, fz_stream *file) { char buf[256]; int token; @@ -268,7 +268,7 @@ cleanup: } fz_error * -pdf_parsecmap(fz_cmap **cmapp, fz_file *file) +pdf_parsecmap(fz_cmap **cmapp, fz_stream *file) { fz_error *error; fz_cmap *cmap; @@ -377,6 +377,7 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) { fz_obj *stmobj = stmref; fz_error *error = nil; + fz_stream *file; fz_cmap *cmap = nil; fz_cmap *usecmap; fz_obj *wmode; @@ -394,15 +395,15 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) if (error) return error; - error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref)); + error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) goto cleanup; - error = pdf_parsecmap(&cmap, xref->file); + error = pdf_parsecmap(&cmap, file); if (error) goto cleanup; - pdf_closestream(xref); + fz_dropstream(file); wmode = fz_dictgets(stmobj, "WMode"); if (fz_isint(wmode)) @@ -456,7 +457,7 @@ fz_error * pdf_loadsystemcmap(fz_cmap **cmapp, char *name) { fz_error *error = nil; - fz_file *file; + fz_stream *file; char *cmapdir; char *usecmapname; fz_cmap *usecmap; @@ -473,7 +474,7 @@ pdf_loadsystemcmap(fz_cmap **cmapp, char *name) strlcat(path, "/", sizeof path); strlcat(path, name, sizeof path); - error = fz_openfile(&file, path, FZ_READ); + error = fz_openrfile(&file, path); if (error) goto cleanup; @@ -481,7 +482,7 @@ pdf_loadsystemcmap(fz_cmap **cmapp, char *name) if (error) goto cleanup; - fz_closefile(file); + fz_dropstream(file); usecmapname = fz_getusecmapname(cmap); if (usecmapname) @@ -503,7 +504,7 @@ cleanup: if (cmap) fz_dropcmap(cmap); if (file) - fz_closefile(file); + fz_dropstream(file); return error; } diff --git a/mupdf/pdf_function.c b/mupdf/pdf_function.c index d6279ef4..fd241e7c 100644 --- a/mupdf/pdf_function.c +++ b/mupdf/pdf_function.c @@ -358,7 +358,7 @@ resizecode(pdf_function *func, int newsize) } static fz_error * -parsecode(pdf_function *func, fz_file *stream, int *codeptr) +parsecode(pdf_function *func, fz_stream *stream, int *codeptr) { fz_error *error = nil; char buf[64]; @@ -488,14 +488,15 @@ static fz_error * loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen) { fz_error *error = nil; + fz_stream *stream; int codeptr; pdf_logrsrc("load postscript function %d %d\n", oid, gen); - error = pdf_openstream(xref, oid, gen); + error = pdf_openstream(&stream, xref, oid, gen); if (error) goto cleanup; - if (fz_readbyte(xref->stream) != '{') + if (fz_readbyte(stream) != '{') goto cleanup; func->u.p.code = nil; @@ -503,15 +504,15 @@ loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, in codeptr = 0; - error = parsecode(func, xref->stream, &codeptr); + error = parsecode(func, stream, &codeptr); if (error) goto cleanup; - pdf_closestream(xref); + fz_dropstream(stream); return nil; cleanup: - pdf_closestream(xref); + fz_dropstream(stream); if (error) return error; return fz_throw("syntaxerror: postscript calculator"); } @@ -910,6 +911,7 @@ static fz_error * loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gen) { fz_error *error = nil; + fz_stream *stream; fz_obj *obj; int samplecount; int bps; @@ -990,7 +992,7 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge goto cleanup0; } - error = pdf_openstream(xref, oid, gen); + error = pdf_openstream(&stream, xref, oid, gen); if (error) goto cleanup0; @@ -1003,29 +1005,29 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge for (i = 0; i < samplecount; ++i) { - if (fz_peekbyte(xref->stream) == EOF) + if (fz_peekbyte(stream) == EOF) { error = fz_throw("syntaxerror: too few samples in function"); goto cleanup1; } if (bps == 8) { - s = fz_readbyte(xref->stream); + s = fz_readbyte(stream); } else if (samplecount == 16) { - s = fz_readbyte(xref->stream); - s = (s << 8) + fz_readbyte(xref->stream); + s = fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); } else if (samplecount == 32) { - s = fz_readbyte(xref->stream); - s = (s << 8) + fz_readbyte(xref->stream); - s = (s << 8) + fz_readbyte(xref->stream); - s = (s << 8) + fz_readbyte(xref->stream); + s = fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); + s = (s << 8) + fz_readbyte(stream); } else { while (bits < bps) { - buf = (buf << 8) | (fz_readbyte(xref->stream) & 0xff); + buf = (buf << 8) | (fz_readbyte(stream) & 0xff); bits += 8; } s = (buf >> (bits - bps)) & bitmask; @@ -1033,21 +1035,17 @@ loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int ge } func->u.sa.samples[i] = s; - - error = fz_ferror(xref->stream); - if (error) - goto cleanup1; } } - pdf_closestream(xref); + fz_dropstream(stream); pdf_logrsrc("}\n"); return nil; cleanup1: - pdf_closestream(xref); + fz_dropstream(stream); cleanup0: if (error) return error; return fz_throw("syntaxerror: sample function"); diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c index 4fd6643c..cd7457a0 100644 --- a/mupdf/pdf_image.c +++ b/mupdf/pdf_image.c @@ -1,5 +1,9 @@ -#include <fitz.h> -#include <mupdf.h> +/* + * TODO: this needs serious cleaning up, and error checking. + */ + +#include "fitz.h" +#include "mupdf.h" void pdf_dropimage(fz_image *fzimg) { @@ -10,7 +14,8 @@ void pdf_dropimage(fz_image *fzimg) } fz_error * -pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_file *file) +pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, + fz_obj *rdb, fz_obj *dict, fz_stream *file) { fz_error *error; pdf_image *img; @@ -120,19 +125,22 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, f = fz_dictgetsa(dict, "Filter", "F"); if (f) { - error = pdf_decodefilter(&filter, dict); - if (error) - return error; + fz_stream *tempfile; - error = fz_pushfilter(file, filter); + error = pdf_buildinlinefilter(&filter, dict); if (error) return error; - error = fz_readfile(&img->samples, file); + error = fz_openrfilter(&tempfile, filter, file); if (error) return error; - fz_popfilter(file); + i = fz_readall(&img->samples, tempfile); + if (i < 0) + return fz_throw("ioerror: readall failed"); + + fz_dropfilter(filter); + fz_dropstream(tempfile); } else { @@ -141,9 +149,8 @@ pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, return error; i = fz_read(file, img->samples->bp, img->super.h * img->stride); - error = fz_ferror(file); - if (error) - return error; + if (i < 0) + return fz_throw("ioerror: read failed"); img->samples->wp += img->super.h * img->stride; } diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index d4b2b2be..e5ecf8ee 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -128,7 +128,7 @@ runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj) { fz_error *error; fz_node *transform; - fz_file *file; + fz_stream *file; /* gsave */ error = gsave(csi); @@ -152,13 +152,13 @@ runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj) xobj->contents->rp = xobj->contents->bp; - error = fz_openbuffer(&file, xobj->contents, FZ_READ); + error = fz_openrbuffer(&file, xobj->contents); if (error) return error; error = pdf_runcsi(csi, xref, xobj->resources, file); - fz_closefile(file); + fz_dropstream(file); if (error) return error; @@ -176,7 +176,7 @@ runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj) */ static fz_error * -runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file, fz_obj *dict) +runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file, fz_obj *dict) { fz_error *error; pdf_image *img; @@ -1080,7 +1080,7 @@ syntaxerror: } fz_error * -pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file) +pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_stream *file) { fz_error *error; char buf[65536]; diff --git a/mupdf/pdf_lex.c b/mupdf/pdf_lex.c index 36e7f50a..c1f9643f 100644 --- a/mupdf/pdf_lex.c +++ b/mupdf/pdf_lex.c @@ -50,7 +50,7 @@ static inline int fromhex(int ch) } static inline void -lexwhite(fz_file *f) +lexwhite(fz_stream *f) { int c; while (1) @@ -63,7 +63,7 @@ lexwhite(fz_file *f) } static inline void -lexcomment(fz_file *f) +lexcomment(fz_stream *f) { int c; while (1) @@ -76,7 +76,7 @@ lexcomment(fz_file *f) } static void -lexnumber(fz_file *f, unsigned char *s, int n) +lexnumber(fz_stream *f, unsigned char *s, int n) { while (n > 1) { @@ -89,7 +89,7 @@ lexnumber(fz_file *f, unsigned char *s, int n) } static void -lexname(fz_file *f, unsigned char *s, int n) +lexname(fz_stream *f, unsigned char *s, int n) { #if 0 unsigned char *p = s; @@ -121,7 +121,7 @@ lexname(fz_file *f, unsigned char *s, int n) } static int -lexstring(fz_file *f, unsigned char *buf, int n) +lexstring(fz_stream *f, unsigned char *buf, int n) { unsigned char *s = buf; unsigned char *e = buf + n; @@ -194,7 +194,7 @@ lexstring(fz_file *f, unsigned char *buf, int n) } static int -lexhexstring(fz_file *f, unsigned char *buf, int n) +lexhexstring(fz_stream *f, unsigned char *buf, int n) { unsigned char *s = buf; unsigned char *e = buf + n; @@ -249,7 +249,7 @@ tokenfromkeyword(char *key) } int -pdf_lex(fz_file *f, unsigned char *buf, int n, int *sl) +pdf_lex(fz_stream *f, unsigned char *buf, int n, int *sl) { int c; diff --git a/mupdf/pdf_open.c b/mupdf/pdf_open.c index 34caa862..67d9b5d9 100644 --- a/mupdf/pdf_open.c +++ b/mupdf/pdf_open.c @@ -19,7 +19,7 @@ loadversion(pdf_xref *xref) n = fz_seek(xref->file, 0, 0); if (n < 0) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); fz_readline(xref->file, buf, sizeof buf); if (memcmp(buf, "%PDF-", 5) != 0) @@ -41,15 +41,15 @@ readstartxref(pdf_xref *xref) t = fz_seek(xref->file, 0, 2); if (t == -1) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); t = fz_seek(xref->file, MAX(0, t - ((int)sizeof buf)), 0); if (t == -1) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); n = fz_read(xref->file, buf, sizeof buf); if (n == -1) - return fz_ferror(xref->file); + return fz_throw("ioerror: read failed"); for (i = n - 9; i >= 0; i--) { @@ -83,7 +83,7 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap) fz_readline(xref->file, buf, cap); if (strcmp(buf, "xref") != 0) - return fz_throw("syntaxerror: missing xref"); + return fz_throw("ioerror: missing xref"); while (1) { @@ -92,7 +92,8 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap) break; n = fz_readline(xref->file, buf, cap); - if (n < 0) return fz_ferror(xref->file); + if (n < 0) + return fz_throw("ioerror: read failed"); s = buf; ofs = atoi(strsep(&s, " ")); @@ -103,10 +104,12 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap) fz_seek(xref->file, -(n + buf - s + 2), 1); t = fz_tell(xref->file); - if (t < 0) return fz_ferror(xref->file); + if (t < 0) + return fz_throw("ioerror: tell failed"); n = fz_seek(xref->file, t + 20 * len, 0); - if (n < 0) return fz_ferror(xref->file); + if (n < 0) + return fz_throw("ioerror: seek failed"); } t = pdf_lex(xref->file, buf, cap, &n); @@ -135,7 +138,7 @@ readtrailer(pdf_xref *xref, char *buf, int cap) n = fz_seek(xref->file, xref->startxref, 0); if (n < 0) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); c = fz_peekbyte(xref->file); if (c == 'x') @@ -173,7 +176,8 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) break; n = fz_readline(xref->file, buf, cap); - if (n < 0) return fz_ferror(xref->file); + if (n < 0) + return fz_throw("ioerror: read failed"); s = buf; ofs = atoi(strsep(&s, " ")); @@ -189,8 +193,10 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) for (i = 0; i < len; i++) { n = fz_read(xref->file, buf, 20); - if (n < 0) return fz_ferror(xref->file); - if (n != 20) return fz_throw("syntaxerror: truncated xref table"); + if (n < 0) + return fz_throw("ioerror: read failed"); + if (n != 20) + return fz_throw("syntaxerror: truncated xref table"); if (!xref->table[ofs + i].type) { s = buf; @@ -215,6 +221,7 @@ static fz_error * readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) { fz_error *error; + fz_stream *stm; fz_obj *trailer; fz_obj *obj; int oid, gen, stmofs; @@ -268,7 +275,7 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) goto cleanup; } - error = pdf_openstream(xref, oid, gen); + error = pdf_openstream(&stm, xref, oid, gen); if (error) goto cleanup; @@ -278,21 +285,19 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) int b = 0; int c = 0; - if (fz_peekbyte(xref->stream) == EOF) + if (fz_peekbyte(stm) == EOF) { - error = fz_ferror(xref->stream); - if (!error) - error = fz_throw("syntaxerror: truncated xref stream"); - pdf_closestream(xref); + error = fz_throw("syntaxerror: truncated xref stream"); + fz_dropstream(stm); goto cleanup; } for (n = 0; n < w0; n++) - a = (a << 8) + fz_readbyte(xref->stream); + a = (a << 8) + fz_readbyte(stm); for (n = 0; n < w1; n++) - b = (b << 8) + fz_readbyte(xref->stream); + b = (b << 8) + fz_readbyte(stm); for (n = 0; n < w2; n++) - c = (c << 8) + fz_readbyte(xref->stream); + c = (c << 8) + fz_readbyte(stm); if (!xref->table[i].type) { @@ -303,7 +308,7 @@ readnewxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) } } - pdf_closestream(xref); + fz_dropstream(stm); *trailerp = trailer; @@ -322,7 +327,7 @@ readxref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap) n = fz_seek(xref->file, ofs, 0); if (n < 0) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); c = fz_peekbyte(xref->file); if (c == 'x') @@ -380,6 +385,7 @@ fz_error * pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap) { fz_error *error; + fz_stream *stm; fz_obj *objstm; int *oidbuf; int *ofsbuf; @@ -401,53 +407,53 @@ 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 cleanup1; } + if (!oidbuf) { error = fz_outofmem; goto cleanupobj; } ofsbuf = fz_malloc(count * sizeof(int)); - if (!ofsbuf) { error = fz_outofmem; goto cleanup2; } + if (!ofsbuf) { error = fz_outofmem; goto cleanupoid; } - error = pdf_openstream(xref, oid, gen); + error = pdf_openstream(&stm, xref, oid, gen); if (error) - goto cleanup3; + goto cleanupofs; for (i = 0; i < count; i++) { - t = pdf_lex(xref->stream, buf, cap, &n); + t = pdf_lex(stm, buf, cap, &n); if (t != PDF_TINT) { error = fz_throw("syntaxerror: corrupt object stream"); - goto cleanup4; + goto cleanupstm; } oidbuf[i] = atoi(buf); - t = pdf_lex(xref->stream, buf, cap, &n); + t = pdf_lex(stm, buf, cap, &n); if (t != PDF_TINT) { error = fz_throw("syntaxerror: corrupt object stream"); - goto cleanup4; + goto cleanupstm; } ofsbuf[i] = atoi(buf); } - n = fz_seek(xref->stream, first, 0); + n = fz_seek(stm, first, 0); if (n < 0) { - error = fz_ferror(xref->stream); - goto cleanup4; + error = fz_throw("ioerror: seek failed"); + goto cleanupstm; } for (i = 0; i < count; i++) { /* FIXME: seek to first + ofsbuf[i] */ - error = pdf_parsestmobj(&obj, xref->stream, buf, cap); + error = pdf_parsestmobj(&obj, stm, buf, cap); if (error) - goto cleanup4; + goto cleanupstm; if (oidbuf[i] < 1 || oidbuf[i] >= xref->len) { error = fz_throw("rangecheck: object number out of range"); - goto cleanup4; + goto cleanupstm; } if (xref->table[oidbuf[i]].obj) @@ -455,19 +461,19 @@ pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap) xref->table[oidbuf[i]].obj = obj; } - pdf_closestream(xref); + fz_dropstream(stm); fz_free(ofsbuf); fz_free(oidbuf); fz_dropobj(objstm); return nil; -cleanup4: - pdf_closestream(xref); -cleanup3: +cleanupstm: + fz_dropstream(stm); +cleanupofs: fz_free(ofsbuf); -cleanup2: +cleanupoid: fz_free(oidbuf); -cleanup1: +cleanupobj: fz_dropobj(objstm); return error; } @@ -487,7 +493,7 @@ pdf_loadxref(pdf_xref *xref, char *filename) pdf_logxref("loadxref '%s' %p\n", filename, xref); - error = fz_openfile(&xref->file, filename, FZ_READ); + error = fz_openrfile(&xref->file, filename); if (error) return error; diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c index b230c871..44ac769c 100644 --- a/mupdf/pdf_page.c +++ b/mupdf/pdf_page.c @@ -5,16 +5,17 @@ static fz_error * runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) { fz_error *error; + fz_stream *stm; pdf_logpage("simple content stream\n"); - error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref)); + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) return error; - error = pdf_runcsi(csi, xref, rdb, xref->stream); + error = pdf_runcsi(csi, xref, rdb, stm); - pdf_closestream(xref); + fz_dropstream(stm); return error; } @@ -26,7 +27,7 @@ static fz_error * runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) { fz_error *error; - fz_file *file; + fz_stream *file; fz_buffer *big; fz_buffer *one; fz_obj *stm; @@ -39,12 +40,14 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) if (error) return error; - error = fz_openbuffer(&file, big, FZ_WRITE); + error = fz_openwbuffer(&file, big); if (error) goto cleanup0; for (i = 0; i < fz_arraylen(list); i++) { + /* TODO dont use loadstream here */ + stm = fz_arrayget(list, i); error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm)); if (error) @@ -56,33 +59,28 @@ runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) if (n == -1) { - error = fz_ferror(file); + error = fz_throw("ioerror: write failed"); goto cleanup1; } - n = fz_printstring(file, " "); - if (n == -1) - { - error = fz_ferror(file); - goto cleanup1; - } + fz_printstr(file, " "); } - fz_closefile(file); + fz_dropstream(file); - error = fz_openbuffer(&file, big, FZ_READ); + error = fz_openrbuffer(&file, big); if (error) goto cleanup0; error = pdf_runcsi(csi, xref, rdb, file); - fz_closefile(file); + fz_dropstream(file); fz_dropbuffer(big); return error; cleanup1: - fz_closefile(file); + fz_dropstream(file); cleanup0: fz_dropbuffer(big); return error; diff --git a/mupdf/pdf_parse.c b/mupdf/pdf_parse.c index e30bb3a2..8b091d67 100644 --- a/mupdf/pdf_parse.c +++ b/mupdf/pdf_parse.c @@ -107,7 +107,7 @@ pdf_toucs2(unsigned short **dstp, fz_obj *src) } fz_error * -pdf_parsearray(fz_obj **op, fz_file *file, char *buf, int cap) +pdf_parsearray(fz_obj **op, fz_stream *file, char *buf, int cap) { fz_error *error = nil; fz_obj *ary = nil; @@ -206,7 +206,7 @@ cleanup: } fz_error * -pdf_parsedict(fz_obj **op, fz_file *file, char *buf, int cap) +pdf_parsedict(fz_obj **op, fz_stream *file, char *buf, int cap) { fz_error *error = nil; fz_obj *dict = nil; @@ -298,7 +298,7 @@ cleanup: } fz_error * -pdf_parsestmobj(fz_obj **op, fz_file *file, char *buf, int cap) +pdf_parsestmobj(fz_obj **op, fz_stream *file, char *buf, int cap) { int tok, len; @@ -321,7 +321,7 @@ pdf_parsestmobj(fz_obj **op, fz_file *file, char *buf, int cap) } fz_error * -pdf_parseindobj(fz_obj **op, fz_file *file, char *buf, int cap, +pdf_parseindobj(fz_obj **op, fz_stream *file, char *buf, int cap, int *ooid, int *ogid, int *ostmofs) { fz_error *error = nil; diff --git a/mupdf/pdf_pattern.c b/mupdf/pdf_pattern.c index d4e99c48..8b9e9bc4 100644 --- a/mupdf/pdf_pattern.c +++ b/mupdf/pdf_pattern.c @@ -24,6 +24,7 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref { fz_error *error; pdf_pattern *pat; + fz_stream *stm; fz_obj *resources; fz_obj *obj; pdf_csi *csi; @@ -98,13 +99,13 @@ pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict, fz_obj *stmref if (error) goto cleanup; - error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref)); + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) goto cleanup2; - error = pdf_runcsi(csi, xref, resources, xref->stream); + error = pdf_runcsi(csi, xref, resources, stm); - pdf_closestream(xref); + fz_dropstream(stm); if (error) goto cleanup2; diff --git a/mupdf/pdf_repair.c b/mupdf/pdf_repair.c index e533d826..6fcbde63 100644 --- a/mupdf/pdf_repair.c +++ b/mupdf/pdf_repair.c @@ -15,7 +15,7 @@ struct entry }; static fz_error * -parseobj(fz_file *file, char *buf, int cap, int *stmofs, int *stmlen, +parseobj(fz_stream *file, char *buf, int cap, int *stmofs, int *stmlen, int *isroot, int *isinfo) { fz_error *error; @@ -108,7 +108,7 @@ fz_error * pdf_repairxref(pdf_xref *xref, char *filename) { fz_error *error; - fz_file *file; + fz_stream *file; struct entry *list = nil; int listlen; @@ -127,7 +127,7 @@ pdf_repairxref(pdf_xref *xref, char *filename) int next; int i; - error = fz_openfile(&file, filename, FZ_READ); + error = fz_openrfile(&file, filename); if (error) return error; @@ -295,7 +295,7 @@ pdf_repairxref(pdf_xref *xref, char *filename) return nil; cleanup: - fz_closefile(file); + fz_dropstream(file); fz_free(list); return error; } diff --git a/mupdf/pdf_save.c b/mupdf/pdf_save.c index 344d942c..a23fa419 100644 --- a/mupdf/pdf_save.c +++ b/mupdf/pdf_save.c @@ -1,12 +1,14 @@ #include <fitz.h> #include <mupdf.h> -#define TIGHT 0 +#define TIGHT 1 static fz_error * -writestream(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) +writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) { fz_error *error; + fz_stream *dststm; + fz_stream *srcstm; unsigned char buf[4096]; fz_filter *ef; int n; @@ -19,47 +21,55 @@ writestream(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) if (error) return error; - error = fz_pushfilter(out, ef); + error = fz_openrfilter(&dststm, ef, out); fz_dropfilter(ef); if (error) return error; } + else + { + dststm = fz_keepstream(out); + } - error = pdf_openrawstream(xref, oid, gen); + error = pdf_openrawstream(&srcstm, xref, oid, gen); if (error) - goto cleanup; + goto cleanupdst; while (1) { - n = fz_read(xref->stream, buf, sizeof buf); + n = fz_read(srcstm, buf, sizeof buf); if (n == 0) break; if (n < 0) { - error = fz_ferror(xref->stream); - pdf_closestream(xref); - goto cleanup; + error = fz_throw("ioerror: read failed"); + goto cleanupsrc; + } + + n = fz_write(dststm, buf, n); + if (n < 0) + { + error = fz_throw("ioerror: write failed"); + goto cleanupsrc; } - fz_write(out, buf, n); } - pdf_closestream(xref); - - if (encrypt) - fz_popfilter(out); + fz_dropstream(srcstm); + fz_dropstream(dststm); fz_print(out, "endstream\n"); return nil; -cleanup: - if (encrypt) - fz_popfilter(out); +cleanupsrc: + fz_dropstream(srcstm); +cleanupdst: + fz_dropstream(dststm); return error; } static fz_error * -writeobject(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) +writeobject(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) { pdf_xrefentry *x = xref->table + oid; fz_error *error; @@ -87,10 +97,6 @@ writeobject(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) fz_print(out, "endobj\n\n"); - error = fz_ferror(out); - if (error) - return error; - return nil; } @@ -107,7 +113,7 @@ fz_error * pdf_updatexref(pdf_xref *xref, char *path) { fz_error *error; - fz_file *out; + fz_stream *out; int oid; int i, n; int startxref; @@ -115,7 +121,7 @@ pdf_updatexref(pdf_xref *xref, char *path) pdf_logxref("updatexref '%s' %p\n", path, xref); - error = fz_openfile(&out, path, FZ_APPEND); + error = fz_openafile(&out, path); if (error) return error; @@ -198,11 +204,11 @@ pdf_updatexref(pdf_xref *xref, char *path) xref->startxref = startxref; - fz_closefile(out); + fz_dropstream(out); return nil; cleanup: - fz_closefile(out); + fz_dropstream(out); return error; } @@ -210,7 +216,7 @@ fz_error * pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt) { fz_error *error; - fz_file *out; + fz_stream *out; int oid; int startxref; int *ofsbuf; @@ -239,7 +245,7 @@ pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt) if (!ofsbuf) return fz_outofmem; - error = fz_openfile(&out, path, FZ_WRITE); + error = fz_openwfile(&out, path); if (error) { fz_free(ofsbuf); @@ -309,12 +315,12 @@ pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt) xref->startxref = startxref; if(ofsbuf) fz_free(ofsbuf); - fz_closefile(out); + fz_dropstream(out); return nil; cleanup: if(ofsbuf) fz_free(ofsbuf); - fz_closefile(out); + fz_dropstream(out); return error; } diff --git a/mupdf/pdf_shade4.c b/mupdf/pdf_shade4.c index 8454643f..ddd42efd 100644 --- a/mupdf/pdf_shade4.c +++ b/mupdf/pdf_shade4.c @@ -164,7 +164,7 @@ cleanup: } static int -getdata(fz_file *stream, int bps) +getdata(fz_stream *stream, int bps) { unsigned int bitmask = (1 << bps) - 1; unsigned int buf = 0; @@ -188,6 +188,7 @@ fz_error * pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { fz_error *error; + fz_stream *stream; fz_obj *obj; int bpcoord; @@ -256,31 +257,29 @@ pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref } q = 0; - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); if (error) goto cleanup; - while (fz_peekbyte(xref->stream) != EOF) + while (fz_peekbyte(stream) != EOF) { for (p = 0; p < vpr; ++p) { int idx; idx = q * vpr + p; - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); for (i=0; i < ncomp; ++i) { - t = getdata(xref->stream, bpcomp); + t = getdata(stream, bpcomp); c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); } } q++; } - if ((error = fz_ferror(xref->stream))) - goto cleanup; - pdf_closestream(xref); + fz_dropstream(stream); #define ADD_VERTEX(idx) \ {\ @@ -564,6 +563,7 @@ fz_error * pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { fz_error *error; + fz_stream *stream; fz_obj *obj; int bpcoord; @@ -626,24 +626,24 @@ pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref n = 2 + shade->cs->n; j = 0; - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); if (error) goto cleanup; - while (fz_peekbyte(xref->stream) != EOF) + while (fz_peekbyte(stream) != EOF) { - flag = getdata(xref->stream, bpflag); + flag = getdata(stream, bpflag); for (i = 0; i < 12; ++i) { - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); p[i].x = (float)(p0.x + (t * (p1.x - p0.x) / (pow(2, bpcoord) - 1.))); - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); p[i].y = (float)(p0.y + (t * (p1.y - p0.y) / (pow(2, bpcoord) - 1.))); } for (i = 0; i < 4; ++i) { int k; for (k=0; k < ncomp; ++k) { - t = getdata(xref->stream, bpcomp); + t = getdata(stream, bpcomp); patch.color[i][k] = c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); } @@ -665,10 +665,8 @@ pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref j = drawpatch(patch, shade, j, ncomp, 0); } - if ((error = fz_ferror(xref->stream)) ) - goto cleanup; - pdf_closestream(xref); + fz_dropstream(stream); shade->meshlen = j / n / 3; @@ -681,6 +679,7 @@ fz_error * pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { fz_error *error; + fz_stream *stream; fz_obj *obj; int bpcoord; @@ -742,24 +741,24 @@ pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref n = 2 + shade->cs->n; j = 0; - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); if (error) goto cleanup; - while (fz_peekbyte(xref->stream) != EOF) + while (fz_peekbyte(stream) != EOF) { - flag = getdata(xref->stream, bpflag); + flag = getdata(stream, bpflag); for (i = 0; i < 16; ++i) { - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); p[i].x = x0 + (t * (x1 - x0) / (pow(2, bpcoord) - 1.)); - t = getdata(xref->stream, bpcoord); + t = getdata(stream, bpcoord); p[i].y = y0 + (t * (y1 - y0) / (pow(2, bpcoord) - 1.)); } for (i = 0; i < 4; ++i) { int k; for (k=0; k < ncomp; ++k) { - t = getdata(xref->stream, bpcomp); + t = getdata(stream, bpcomp); patch.color[i][k] = c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); } @@ -784,10 +783,8 @@ pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref j = drawpatch(patch, shade, j, ncomp, 0); } - if ((error = fz_ferror(xref->stream)) ) - goto cleanup; - pdf_closestream(xref); + fz_dropstream(stream); shade->meshlen = j / n / 3; diff --git a/mupdf/pdf_stream.c b/mupdf/pdf_stream.c index 01958853..0479dfd7 100644 --- a/mupdf/pdf_stream.c +++ b/mupdf/pdf_stream.c @@ -1,5 +1,5 @@ -#include <fitz.h> -#include <mupdf.h> +#include "fitz.h" +#include "mupdf.h" /* * Check if an object is a stream or not. @@ -173,7 +173,7 @@ buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps) * stream length, followed by a decryption filter. */ static fz_error * -makerawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) +buildrawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) { fz_error *error; fz_filter *base; @@ -224,7 +224,7 @@ makerawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int * constraining to stream length, and without decryption. */ fz_error * -pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj) +pdf_buildinlinefilter(fz_filter **filterp, fz_obj *stmobj) { fz_obj *filters; fz_obj *params; @@ -250,14 +250,14 @@ pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj) * to stream length and decrypting. */ static fz_error * -makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) +pdf_buildfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen) { fz_error *error; fz_filter *base, *pipe, *tmp; fz_obj *filters; fz_obj *params; - error = makerawfilter(&base, xref, stmobj, oid, gen); + error = buildrawfilter(&base, xref, stmobj, oid, gen); if (error) return error; @@ -321,11 +321,10 @@ cleanup0: /* * Open a stream for reading the raw (compressed but decrypted) data. - * Put the opened file in xref->stream. Using xref->file while this - * is open is a bad idea. + * Using xref->file while this is open is a bad idea. */ fz_error * -pdf_openrawstream(pdf_xref *xref, int oid, int gen) +pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) { pdf_xrefentry *x; fz_error *error; @@ -343,12 +342,12 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen) if (x->stmbuf) { - return fz_openbuffer(&xref->stream, x->stmbuf, FZ_READ); + return fz_openrbuffer(stmp, x->stmbuf); } if (x->stmofs) { - error = makerawfilter(&filter, xref, x->obj, oid, gen); + error = buildrawfilter(&filter, xref, x->obj, oid, gen); if (error) return error; @@ -356,15 +355,16 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen) if (n == -1) { fz_dropfilter(filter); - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); } - error = fz_pushfilter(xref->file, filter); + error = fz_openrfilter(stmp, filter, xref->file); + fz_dropfilter(filter); + if (error) return error; - xref->stream = xref->file; return nil; } @@ -377,10 +377,11 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen) * Using xref->file while a stream is open is a Bad idea. */ fz_error * -pdf_openstream(pdf_xref *xref, int oid, int gen) +pdf_openstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) { pdf_xrefentry *x; fz_error *error; + fz_stream *rawstm; fz_filter *filter; int n; @@ -395,25 +396,26 @@ pdf_openstream(pdf_xref *xref, int oid, int gen) if (x->stmbuf) { - error = makedecodefilter(&filter, xref, x->obj, oid, gen); + error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); if (error) return error; - error = fz_openbuffer(&xref->stream, x->stmbuf, FZ_READ); + error = fz_openrbuffer(&rawstm, x->stmbuf); if (error) { fz_dropfilter(filter); return error; } - error = fz_pushfilter(xref->stream, filter); + error = fz_openrfilter(stmp, filter, rawstm); fz_dropfilter(filter); + fz_dropstream(rawstm); return error; } if (x->stmofs) { - error = makedecodefilter(&filter, xref, x->obj, oid, gen); + error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); if (error) return error; @@ -421,15 +423,14 @@ pdf_openstream(pdf_xref *xref, int oid, int gen) if (n == -1) { fz_dropfilter(filter); - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); } - error = fz_pushfilter(xref->file, filter); + error = fz_openrfilter(stmp, filter, xref->file); fz_dropfilter(filter); if (error) return error; - xref->stream = xref->file; return nil; } @@ -437,36 +438,26 @@ pdf_openstream(pdf_xref *xref, int oid, int gen) } /* - * Close the xref->stream file opened by either - * pdf_openrawstream or pdf_openstream. - */ -void -pdf_closestream(pdf_xref *xref) -{ - if (xref->stream == xref->file) - fz_popfilter(xref->file); - else - fz_closefile(xref->stream); - xref->stream = nil; -} - -/* * Load raw (compressed but decrypted) contents of a stream into buf. */ fz_error * pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen) { fz_error *error; + fz_stream *stm; + int n; - error = pdf_openrawstream(xref, oid, gen); + error = pdf_openrawstream(&stm, xref, oid, gen); if (error) return error; - error = fz_readfile(bufp, xref->stream); + n = fz_readall(bufp, stm); - pdf_closestream(xref); + fz_dropstream(stm); - return error; + if (n < 0) + return fz_throw("ioerror: readall failed"); + return nil; } /* @@ -476,15 +467,19 @@ fz_error * pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen) { fz_error *error; + fz_stream *stm; + int n; - error = pdf_openstream(xref, oid, gen); + error = pdf_openstream(&stm, xref, oid, gen); if (error) return error; - error = fz_readfile(bufp, xref->stream); + n = fz_readall(bufp, stm); - pdf_closestream(xref); + fz_dropstream(stm); - return error; + if (n < 0) + return fz_throw("ioerror: readall failed"); + return nil; } diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c index b1da3380..092db4de 100644 --- a/mupdf/pdf_type3.c +++ b/mupdf/pdf_type3.c @@ -66,16 +66,17 @@ loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) { fz_error *error; pdf_csi *csi; + fz_stream *stm; error = pdf_newcsi(&csi, 1); - error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref)); + error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) return error; - error = pdf_runcsi(csi, xref, rdb, xref->stream); + error = pdf_runcsi(csi, xref, rdb, stm); - pdf_closestream(xref); + fz_dropstream(stm); *treep = csi->tree; csi->tree = nil; diff --git a/mupdf/pdf_xref.c b/mupdf/pdf_xref.c index 7095850c..e4d25832 100644 --- a/mupdf/pdf_xref.c +++ b/mupdf/pdf_xref.c @@ -54,7 +54,7 @@ pdf_closexref(pdf_xref *xref) } if (xref->file) - fz_closefile(xref->file); + fz_dropstream(xref->file); if (xref->trailer) fz_dropobj(xref->trailer); @@ -389,7 +389,7 @@ pdf_cacheobject(pdf_xref *xref, int oid, int gen) { n = fz_seek(xref->file, x->ofs, 0); if (n < 0) - return fz_ferror(xref->file); + return fz_throw("ioerror: seek failed"); error = pdf_parseindobj(&x->obj, xref->file, buf, sizeof buf, &roid, &rgen, &x->stmofs); if (error) diff --git a/samus/sa_tiff.c b/samus/sa_tiff.c index 3530f944..6a6db2d7 100644 --- a/samus/sa_tiff.c +++ b/samus/sa_tiff.c @@ -11,7 +11,7 @@ typedef struct sa_tiff_s sa_tiff; struct sa_tiff_s { /* file and byte order */ - fz_file *file; + fz_stream *file; unsigned order; /* where we can find the strips of image data */ @@ -199,7 +199,7 @@ tiffreadstrips(sa_tiff *tiff) fz_error *error; fz_obj *params; fz_buffer *buf; - fz_file *file; + fz_stream *file; fz_filter *filter; unsigned char tmp[512]; @@ -264,17 +264,20 @@ printf("w=%d h=%d n=%d bpc=%d ", /* TODO: scrap write-file and decode with filter directly to final destination */ error = fz_newbuffer(&buf, 4096); - error = fz_openbuffer(&file, buf, FZ_WRITE); + error = fz_openwbuffer(&file, buf); if (filter) { - error = fz_pushfilter(file, filter); + fz_stream *temp; + error = fz_openwfilter(&temp, filter, file); if (error) { fz_dropfilter(filter); - fz_closefile(file); + fz_dropstream(file); return error; } + fz_dropstream(file); + file = temp; } strip = 0; @@ -289,7 +292,7 @@ printf("w=%d h=%d n=%d bpc=%d ", { len = fz_read(tiff->file, tmp, MIN(bytecount, sizeof tmp)); if (len < 0) - return fz_ferror(tiff->file); + return fz_throw("ioerror: read failed"); bytecount -= len; if (tiff->fillorder == 2) @@ -300,23 +303,16 @@ printf("w=%d h=%d n=%d bpc=%d ", len = fz_write(file, tmp, len); if (len < 0) - return fz_ferror(file); + return fz_throw("ioerror: write failed"); } strip ++; } - len = fz_flush(file); - if (len < 0) - return fz_ferror(file); - if (filter) - { - fz_popfilter(file); fz_dropfilter(filter); - } - fz_closefile(file); + fz_dropstream(file); if (tiff->photometric == 3 && tiff->colormap) { @@ -453,7 +449,7 @@ tiffreadifd(sa_tiff *tiff, unsigned offset) } static fz_error * -tiffreadifh(sa_tiff *tiff, fz_file *file) +tiffreadifh(sa_tiff *tiff, fz_stream *file) { unsigned version; unsigned offset; @@ -488,23 +484,24 @@ tiffreadifh(sa_tiff *tiff, fz_file *file) } fz_error * -sa_readtiff(fz_file *file) +sa_readtiff(fz_stream *file) { fz_error *error; fz_buffer *buf; - fz_file *newfile; + fz_stream *newfile; sa_tiff tiff; + int n; /* TIFF requires random access. In Metro TIFFs are embedded in ZIP files. * Compressed streams are not seekable, so we copy the data to an * in-memory data buffer instead of reading from the original stream. */ - error = fz_readfile(&buf, file); - if (error) - return error; + n = fz_readall(&buf, file); + if (n < 0) + return fz_throw("ioerror: readall failed"); - error = fz_openbuffer(&newfile, buf, FZ_READ); + error = fz_openrbuffer(&newfile, buf); if (error) { fz_dropbuffer(buf); @@ -517,7 +514,7 @@ sa_readtiff(fz_file *file) fz_free(tiff.stripoffsets); fz_free(tiff.stripbytecounts); - fz_closefile(newfile); + fz_dropstream(newfile); fz_dropbuffer(buf); return error; diff --git a/samus/sa_xml.c b/samus/sa_xml.c index 198ef6b2..a7b2c764 100644 --- a/samus/sa_xml.c +++ b/samus/sa_xml.c @@ -156,7 +156,7 @@ static void ontext(void *zp, const char *buf, int len) } fz_error * -sa_openxml(sa_xmlparser **spp, fz_file *file, int ns) +sa_openxml(sa_xmlparser **spp, fz_stream *file, int ns) { fz_error *error = nil; sa_xmlparser *sp; @@ -197,7 +197,7 @@ sa_openxml(sa_xmlparser **spp, fz_file *file, int ns) len = fz_read(file, buf, XMLBUFLEN); if (len < 0) { - error = fz_ferror(file); + error = fz_throw("ioerror: read failed"); goto cleanup; } @@ -254,8 +254,8 @@ sa_debugxml(sa_xmlitem *item, int level) { indent(level); - if (sa_isxmltext(item)) - printf("%s\n", sa_xmltext(item)); + if (strlen(item->name) == 0) + printf("%s\n", item->atts[1]); else { printf("<%s", item->name); @@ -317,50 +317,19 @@ sa_xmlup(sa_xmlparser *sp) sp->downed --; } -int -sa_isxmlerror(sa_xmlitem *item) -{ - return item && item->name[0] == '!'; -} - -int -sa_isxmltext(sa_xmlitem *item) -{ - return item && item->name[0] == '\0'; -} - -int -sa_isxmltag(sa_xmlitem *item) -{ - return item && item->name[0] != '\0' && item->name[0] != '!'; -} - char * sa_xmlname(sa_xmlitem *item) { - if (sa_isxmltag(item)) - return item->name; - return nil; + return item->name; } char * sa_xmlatt(sa_xmlitem *item, char *att) { int i; - if (sa_isxmltag(item)) - { - for (i = 0; item->atts[i]; i += 2) - if (!strcmp(item->atts[i], att)) - return item->atts[i + 1]; - } - return nil; -} - -char * -sa_xmltext(sa_xmlitem *item) -{ - if (sa_isxmltext(item)) - return item->atts[1]; + for (i = 0; item->atts[i]; i += 2) + if (!strcmp(item->atts[i], att)) + return item->atts[i + 1]; return nil; } diff --git a/samus/sa_zip.c b/samus/sa_zip.c index a989f16d..eb182c01 100644 --- a/samus/sa_zip.c +++ b/samus/sa_zip.c @@ -12,14 +12,31 @@ #include "fitz.h" #include "samus.h" -static inline unsigned int read2(fz_file *f) +typedef struct sa_zipent_s sa_zipent; + +struct sa_zipent_s +{ + unsigned offset; + unsigned csize; + unsigned usize; + char *name; +}; + +struct sa_zip_s +{ + fz_stream *file; + int len; + sa_zipent *table; +}; + +static inline unsigned int read2(fz_stream *f) { unsigned char a = fz_readbyte(f); unsigned char b = fz_readbyte(f); return (b << 8) | a; } -static inline unsigned int read4(fz_file *f) +static inline unsigned int read4(fz_stream *f) { unsigned char a = fz_readbyte(f); unsigned char b = fz_readbyte(f); @@ -75,7 +92,7 @@ static fz_error *readzipdir(sa_zip *zip, int startoffset) fz_seek(zip->file, comsize, 1); } - return fz_ferror(zip->file); + return nil; } static fz_error *readzipendofdir(sa_zip *zip, int startoffset) @@ -115,7 +132,7 @@ static fz_error *findzipendofdir(sa_zip *zip) filesize = fz_seek(zip->file, 0, 2); if (filesize == -1) - return fz_ferror(zip->file); + return fz_throw("ioerror: seek failed"); maxback = MIN(filesize, 0xFFFF + sizeof buf); back = MIN(maxback, sizeof buf); @@ -125,7 +142,7 @@ static fz_error *findzipendofdir(sa_zip *zip) fz_seek(zip->file, filesize - back, 0); n = fz_read(zip->file, buf, sizeof buf); if (n < 0) - return fz_ferror(zip->file); + return fz_throw("ioerror: read failed"); for (i = n - 4; i > 0; i--) if (!memcmp(buf + i, "\120\113\5\6", 4)) @@ -155,7 +172,7 @@ sa_openzip(sa_zip **zipp, char *filename) zip->len = 0; zip->table = nil; - error = fz_openfile(&zip->file, filename, FZ_READ); + error = fz_openrfile(&zip->file, filename); if (error) return error; @@ -171,7 +188,7 @@ sa_closezip(sa_zip *zip) int i; if (zip->file) - fz_closefile(zip->file); + fz_dropstream(zip->file); for (i = 0; i < zip->len; i++) if (zip->table[i].name) @@ -212,7 +229,7 @@ sa_accesszipentry(sa_zip *zip, char *name) /* * Seek and push decoding filter to read an individual file in the zip archive. */ -static fz_error *reallyopenzipentry(sa_zip *zip, int idx) +static fz_error *reallyopenzipentry(fz_stream **stmp, sa_zip *zip, int idx) { fz_error *error; fz_filter *filter; @@ -224,7 +241,7 @@ static fz_error *reallyopenzipentry(sa_zip *zip, int idx) t = fz_seek(zip->file, zip->table[idx].offset, 0); if (t < 0) - return fz_ferror(zip->file); + return fz_throw("ioerror: seek failed"); sign = read4(zip->file); if (sign != 0x04034b50) @@ -247,7 +264,9 @@ static fz_error *reallyopenzipentry(sa_zip *zip, int idx) if (general & 0x0001) return fz_throw("ioerror: encrypted zip entry"); - fz_seek(zip->file, namesize + metasize, 1); + t = fz_seek(zip->file, namesize + metasize, 1); + if (t < 0) + return fz_throw("ioerror: seek failed"); switch (method) { @@ -272,7 +291,7 @@ static fz_error *reallyopenzipentry(sa_zip *zip, int idx) break; } - error = fz_pushfilter(zip->file, filter); + error = fz_openrfilter(stmp, filter, zip->file); fz_dropfilter(filter); if (error) return error; @@ -281,23 +300,14 @@ static fz_error *reallyopenzipentry(sa_zip *zip, int idx) } fz_error * -sa_openzipentry(sa_zip *zip, char *name) +sa_openzipentry(fz_stream **stmp, sa_zip *zip, char *name) { int i; for (i = 0; i < zip->len; i++) if (!strcmp(name, zip->table[i].name)) - return reallyopenzipentry(zip, i); + return reallyopenzipentry(stmp, zip, i); return fz_throw("ioerror: file not found in zip: '%s'", name); } -/* - * Pop decompression filter and clean up after reading a file in the archive. - */ -void -sa_closezipentry(sa_zip *zip) -{ - fz_popfilter(zip->file); -} - diff --git a/stream/filt_predict.c b/stream/filt_predict.c index d7b594ac..f3c50f6e 100644 --- a/stream/filt_predict.c +++ b/stream/filt_predict.c @@ -2,7 +2,7 @@ /* TODO: check if this works with 16bpp images */ -enum { MAXC = 16 }; +enum { MAXC = 32 }; typedef struct fz_predict_s fz_predict; diff --git a/stream/stm_buffer.c b/stream/stm_buffer.c index 206137a6..7d58e192 100644 --- a/stream/stm_buffer.c +++ b/stream/stm_buffer.c @@ -22,7 +22,7 @@ fz_newbuffer(fz_buffer **bp, int size) } fz_error * -fz_newbufferwithdata(fz_buffer **bp, unsigned char *data, int size) +fz_newbufferwithmemory(fz_buffer **bp, unsigned char *data, int size) { fz_buffer *b; diff --git a/stream/stm_filec.c b/stream/stm_filec.c deleted file mode 100644 index 93f9ce5a..00000000 --- a/stream/stm_filec.c +++ /dev/null @@ -1,349 +0,0 @@ -#include <fitz.h> - -fz_error * -fz_ferror(fz_file *f) -{ - fz_error *e = f->error; - f->error = nil; - return e; -} - -fz_error * -fz_openfile(fz_file **filep, char *path, int mode) -{ - fz_error *error; - fz_file *file; - int realmode; - int fd; - int n; - - assert(mode == FZ_READ || mode == FZ_WRITE || mode == FZ_APPEND); - - realmode = 0; - if (mode == FZ_READ) - realmode = O_BINARY | O_RDONLY; - if (mode == FZ_WRITE) - realmode = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC; - if (mode == FZ_APPEND) - realmode = O_BINARY | O_WRONLY; - - fd = open(path, realmode, 0644); - if (fd == -1) - return fz_throw("ioerror: open '%s': %s", path, strerror(errno)); - - if (mode == FZ_APPEND) - { - mode = FZ_WRITE; - n = lseek(fd, 0, 2); - if (n == -1) { - error = fz_throw("ioerror: lseek: %s", strerror(errno)); - close(fd); - return error; - } - } - - file = *filep = fz_malloc(sizeof(fz_file)); - if (!file) - return fz_outofmem; - - file->mode = mode; - file->fd = fd; - file->depth = 0; - file->error = nil; - file->filter = nil; - file->in = nil; - file->out = nil; - - error = fz_newbuffer(&file->in, FZ_BUFSIZE); - if (error) - goto cleanup; - - error = fz_newbuffer(&file->out, FZ_BUFSIZE); - if (error) - goto cleanup; - - return nil; - -cleanup: - *filep = nil; - close(fd); - fz_dropbuffer(file->out); - fz_dropbuffer(file->in); - fz_free(file); - return error; -} - -fz_error * -fz_openbuffer(fz_file **filep, fz_buffer *buf, int mode) -{ - fz_error *error; - fz_file *file; - - assert(mode == FZ_READ || mode == FZ_WRITE); - - file = *filep = fz_malloc(sizeof(fz_file)); - if (!file) - return fz_outofmem; - - file->mode = mode; - file->fd = -1; - file->depth = 0; - file->error = nil; - file->filter = nil; - - if (mode == FZ_READ) - { - file->out = fz_keepbuffer(buf); - error = fz_newbuffer(&file->in, FZ_BUFSIZE); - if (error) - goto cleanup; - } - - else - { - error = fz_newbuffer(&file->out, FZ_BUFSIZE); - if (error) - goto cleanup; - file->in = fz_keepbuffer(buf); - } - - return nil; - -cleanup: - *filep = nil; - fz_free(file); - return error; -} - -void -fz_closefile(fz_file *file) -{ - assert(file->depth == 0); - - if (file->mode == FZ_WRITE) - fz_flush(file); - - if (file->error) - { - fz_warn("%s", file->error->msg); - fz_droperror(file->error); - file->error = nil; - } - - if (file->fd != -1) /* open to real file */ - close(file->fd); - - fz_dropbuffer(file->in); - fz_dropbuffer(file->out); - - if (file->filter) - fz_dropfilter(file->filter); - - fz_free(file); -} - -fz_error * -fz_pushfilter(fz_file *file, fz_filter *filter) -{ - fz_error *error; - - /* without a filter, one buffer is ignored: unignore. */ - if (file->depth == 0) - { - fz_buffer *buf; - - buf = file->out; - file->out = file->in; - file->in = buf; - - if (file->mode == FZ_READ) - { - file->out->rp = file->out->bp; - file->out->wp = file->out->bp; - file->out->eof = 0; - } - else - { - file->out->eof = 0; - file->in->rp = file->in->bp; - file->in->wp = file->in->bp; - file->in->eof = 0; - } - - file->filter = fz_keepfilter(filter); - } - - else - { - if (file->mode == FZ_READ) - { - error = fz_chainpipeline(&file->filter, file->filter, filter, file->out); - if (error) - return error; - - error = fz_newbuffer(&file->out, FZ_BUFSIZE); - if (error) - { - fz_unchainpipeline(file->filter, &file->filter, &file->out); - return error; - } - } - - else - { - error = fz_chainpipeline(&file->filter, filter, file->filter, file->in); - if (error) - return error; - - error = fz_newbuffer(&file->in, FZ_BUFSIZE); - if (error) - { - fz_unchainpipeline(file->filter, &file->filter, &file->in); - return error; - } - } - } - - file->depth ++; - - return nil; -} - -void -fz_popfilter(fz_file *file) -{ - fz_buffer *buf; - - assert(file->depth > 0); - - if (file->mode == FZ_WRITE) - fz_flush(file); - - if (file->error) - { - fz_warn("%s", file->error->msg); - fz_droperror(file->error); - file->error = nil; - } - - if (file->depth == 1) - { - fz_dropfilter(file->filter); - file->filter = nil; - - buf = file->out; - file->out = file->in; - file->in = buf; - } - else - { - if (file->mode == FZ_READ) - { - fz_dropbuffer(file->out); - fz_unchainpipeline(file->filter, &file->filter, &file->out); - } - else - { - fz_dropbuffer(file->in); - fz_unchainpipeline(file->filter, &file->filter, &file->in); - } - } - - file->depth --; -} - -int -fz_seek(fz_file *f, int ofs, int whence) -{ - int t; - int c; - - if (f->filter) - { - assert(f->mode == FZ_READ && whence == 0); - - if (ofs < fz_tell(f)) - { - f->error = fz_throw("ioerror: cannot seek backwards in filter"); - return -1; - } - while (fz_tell(f) < ofs) - { - c = fz_readbyte(f); - if (c == EOF) - return -1; - } - return ofs; - } - - if (whence == 1) - { - ofs = fz_tell(f) + ofs; - whence = 0; - } - - if (f->fd == -1) - { - if (whence == 0) - { - if (f->mode == FZ_READ) - f->out->rp = CLAMP(f->out->bp + ofs, f->out->bp, f->out->ep); - else - f->in->wp = CLAMP(f->in->bp + ofs, f->in->bp, f->in->ep); - } - else - { - if (f->mode == FZ_READ) - f->out->rp = CLAMP(f->out->ep + ofs, f->out->bp, f->out->ep); - else - f->in->wp = CLAMP(f->in->ep + ofs, f->in->bp, f->in->ep); - } - return fz_tell(f); - } - - t = lseek(f->fd, ofs, whence); - if (t == -1) - { - f->error = fz_throw("ioerror: lseek: %s", strerror(errno)); - return -1; - } - - f->out->rp = f->out->bp; - f->out->wp = f->out->bp; - f->out->eof = 0; - - return t; -} - -int -fz_tell(fz_file *f) -{ - int t; - - if (f->filter) - { - assert(f->mode == FZ_READ); - return f->filter->count - (f->out->wp - f->out->rp); - } - - if (f->fd == -1) - { - if (f->mode == FZ_READ) - return f->out->rp - f->out->bp; - else - return f->in->wp - f->in->bp; - } - - t = lseek(f->fd, 0, 1); - if (t == -1) - { - f->error = fz_throw("ioerror: lseek: %s", strerror(errno)); - return -1; - } - - if (f->mode == FZ_READ) - return t - (f->out->wp - f->out->rp); - else - return t + (f->in->wp - f->in->rp); -} - diff --git a/stream/stm_filer.c b/stream/stm_filer.c deleted file mode 100644 index a63a7dd2..00000000 --- a/stream/stm_filer.c +++ /dev/null @@ -1,252 +0,0 @@ -#include <fitz.h> - -static int doread(fz_buffer *b, int fd) -{ - int n = read(fd, b->wp, b->ep - b->wp); - if (n == -1) - return -1; - if (n == 0) - b->eof = 1; - b->wp += n; - return n; -} - -int fz_producedata(fz_file *f) -{ - fz_error *reason; - int produced; - int n; - - assert(f->mode == FZ_READ); - assert(f->error == nil); - - if (!f->filter) - { - fz_rewindbuffer(f->out); - n = doread(f->out, f->fd); - if (n < 0) { - f->error = fz_throw("ioerror in read: %s", strerror(errno)); - return -1; - } - return 0; - } - - produced = 0; - - while (1) - { - reason = fz_process(f->filter, f->in, f->out); - - if (f->filter->produced) - produced = 1; - - if (reason == fz_ioneedin) - { - if (f->in->eof) { - f->error = fz_throw("ioerror: premature eof in filter"); - return -1; - } - - /* no space to produce, rewind or grow */ - if (f->in->wp == f->in->ep) - { - if (f->in->rp > f->in->bp) - f->error = fz_rewindbuffer(f->in); - else - f->error = fz_growbuffer(f->in); - if (f->error) - return -1; - } - - /* then fill with more input */ - n = doread(f->in, f->fd); - if (n < 0) { - f->error = fz_throw("ioerror in read: %s", strerror(errno)); - return -1; - } - - if (produced) - return 0; - } - - else if (reason == fz_ioneedout) - { - if (produced) - return 0; - - /* need more outspace, and produced no data */ - if (f->out->rp > f->out->bp) - f->error = fz_rewindbuffer(f->out); - else - f->error = fz_growbuffer(f->out); - if (f->error) - return -1; - } - - else if (reason == fz_iodone) - return 0; - - else { - f->error = reason; - return -1; - } - } -} - -int -fz_peekbyte(fz_file *f) -{ - if (f->out->rp == f->out->wp) - { - if (f->out->eof) return EOF; - if (fz_producedata(f)) return EOF; - } - - if (f->out->rp < f->out->wp) - return *f->out->rp; - - return EOF; -} - -int -fz_readbyte(fz_file *f) -{ - if (f->out->rp == f->out->wp) - { - if (f->out->eof) return EOF; - if (fz_producedata(f)) return EOF; - } - - if (f->out->rp < f->out->wp) - return *f->out->rp++; - - return EOF; -} - -int -fz_read(fz_file *f, unsigned char *buf, int n) -{ - int i = 0; - - while (i < n) - { - while (f->out->rp < f->out->wp && i < n) - buf[i++] = *f->out->rp ++; - - if (f->out->rp == f->out->wp) - { - if (f->out->eof) return i; - if (fz_producedata(f) < 0) return -1; - } - } - - return i; -} - -int -fz_readline(fz_file *f, char *buf, int n) -{ - int c = EOF; - char *s = buf; - - while (n > 1) - { - c = fz_readbyte(f); - if (c == EOF) - break; - if (c == '\r') { - c = fz_peekbyte(f); - if (c == '\n') - c = fz_readbyte(f); - break; - } - if (c == '\n') - break; - *s++ = c; - n--; - } - if (n) - *s = '\0'; - return s - buf; -} - -/* - * Utility function to consume contents of file stream into - * a freshly allocated buffer; realloced and trimmed to size. - */ - -enum { CHUNKSIZE = 1024 * 32 }; - -fz_error * -fz_readfile(fz_buffer **bufp, fz_file *file) -{ - fz_buffer *real; - unsigned char *newbuf; - unsigned char *buf; - int len; - int pos; - int n; - - *bufp = nil; - - len = 0; - pos = 0; - buf = nil; - - while (1) - { - if (len - pos == 0) - { - len += CHUNKSIZE; - newbuf = fz_realloc(buf, len); - if (!newbuf) - { - fz_free(buf); - return fz_outofmem; - } - buf = newbuf; - } - - n = fz_read(file, buf + pos, len - pos); - - if (n < 0) - { - fz_free(buf); - return fz_ferror(file); - } - - pos += n; - - if (n < CHUNKSIZE) - { - if (pos > 0) - { - newbuf = fz_realloc(buf, pos); - if (!newbuf) - { - fz_free(buf); - return fz_outofmem; - } - } - else newbuf = buf; - - real = *bufp = fz_malloc(sizeof(fz_buffer)); - if (!real) - { - fz_free(newbuf); - return fz_outofmem; - } - - real->refs = 1; - real->ownsdata = 1; - real->bp = buf; - real->rp = buf; - real->wp = buf + pos; - real->ep = buf + pos; - real->eof = 1; - - return nil; - } - } -} - diff --git a/stream/stm_filew.c b/stream/stm_filew.c deleted file mode 100644 index f83399a2..00000000 --- a/stream/stm_filew.c +++ /dev/null @@ -1,260 +0,0 @@ -#include <fitz.h> - -int -fz_printstring(fz_file *f, char *s) -{ - return fz_write(f, s, strlen(s)); -} - -int -fz_printobj(fz_file *file, fz_obj *obj, int tight) -{ - char buf[1024]; - char *ptr; - int n; - - n = fz_sprintobj(nil, 0, obj, tight); - if (n < sizeof buf) - { - fz_sprintobj(buf, sizeof buf, obj, tight); - return fz_write(file, buf, n); - } - else - { - ptr = fz_malloc(n); - if (!ptr) { - file->error = fz_outofmem; - return -1; - } - fz_sprintobj(ptr, n, obj, tight); - n = fz_write(file, ptr, n); - fz_free(ptr); - return n; - } -} - -int -fz_print(fz_file *f, char *fmt, ...) -{ - va_list ap; - char buf[1024]; - char *p; - int n; - - va_start(ap, fmt); - n = vsnprintf(buf, sizeof buf, fmt, ap); - va_end(ap); - - if (n < sizeof buf) - return fz_write(f, buf, n); - - p = fz_malloc(n); - if (!p) { - f->error = fz_outofmem; - return -1; - } - - va_start(ap, fmt); - vsnprintf(p, n, fmt, ap); - va_end(ap); - - n = fz_write(f, p, n); - - fz_free(p); - - return n; -} - -static int dowrite(fz_buffer *b, int fd) -{ - int n = write(fd, b->rp, b->wp - b->rp); - if (n == -1) - return -1; - b->rp += n; - return n; -} - -int -fz_write(fz_file *f, unsigned char *buf, int n) -{ - fz_error *reason; - int i = 0; - int x; - - assert(f->mode == FZ_WRITE); - assert(f->error == nil); - - if (!f->filter) - { - while (i < n) - { - while (f->in->wp < f->in->ep && i < n) - *f->in->wp++ = buf[i++]; - - if (f->in->wp == f->in->ep) - { - if (f->fd != -1) - { - x = dowrite(f->in, f->fd); - if (x < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - - if (f->in->rp > f->in->bp) - f->error = fz_rewindbuffer(f->in); - else - f->error = fz_growbuffer(f->in); - if (f->error) - return -1; - } - } - - return 0; - } - - while (i < n) - { - while (f->in->wp < f->in->ep && i < n) - *f->in->wp++ = buf[i++]; - - if (f->in->wp == f->in->ep) - { - reason = fz_process(f->filter, f->in, f->out); - - if (reason == fz_ioneedin) - { - if (f->in->wp == f->in->ep) { - if (f->in->rp > f->in->bp) - f->error = fz_rewindbuffer(f->in); - else - f->error = fz_growbuffer(f->in); - if (f->error) - return -1; - } - } - - else if (reason == fz_ioneedout) - { - if (f->fd != -1) - { - x = dowrite(f->out, f->fd); - if (x < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - - if (f->out->rp > f->out->bp) - f->error = fz_rewindbuffer(f->out); - else - f->error = fz_growbuffer(f->out); - if (f->error) - return -1; - } - - else if (reason == fz_iodone) - { - if (f->fd != -1) - { - while (f->out->rp < f->out->wp) - { - x = dowrite(f->out, f->fd); - if (x < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - } - break; - } - - else { - f->error = reason; - return -1; - } - } - } - - return i; -} - -int -fz_flush(fz_file *f) -{ - fz_error *reason; - int n; - - assert(f->mode == FZ_WRITE); - assert(f->error == nil); - - f->in->eof = 1; - - if (!f->filter) - { - if (f->fd != -1) - { - while (f->in->rp < f->in->wp) - { - n = dowrite(f->in, f->fd); - if (n < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - } - return 0; - } - - while (!f->out->eof) - { - reason = fz_process(f->filter, f->in, f->out); - - if (reason == fz_ioneedin) { - f->error = fz_throw("ioerror: premature eof in filter"); - return -1; - } - - else if (reason == fz_ioneedout) - { - if (f->fd != -1) - { - n = dowrite(f->out, f->fd); - if (n < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - - if (f->out->rp > f->out->bp) - f->error = fz_rewindbuffer(f->out); - else - f->error = fz_growbuffer(f->out); - if (f->error) - return -1; - } - - else if (reason == fz_iodone) - { - if (f->fd != -1) - { - n = dowrite(f->out, f->fd); - if (n < 0) { - f->error = fz_throw("ioerror in write: %s", strerror(errno)); - return -1; - } - } - break; - } - - else - { - f->error = reason; - return -1; - } - } - - return 0; -} - |