diff options
-rw-r--r-- | Jamfile | 10 | ||||
-rw-r--r-- | filter/buffer.c | 27 | ||||
-rw-r--r-- | filter/file.c | 589 | ||||
-rw-r--r-- | filter/filec.c | 302 | ||||
-rw-r--r-- | filter/filer.c | 237 | ||||
-rw-r--r-- | filter/filew.c | 235 | ||||
-rw-r--r-- | include/fitz/file.h | 11 | ||||
-rw-r--r-- | include/fitz/filter.h | 2 | ||||
-rw-r--r-- | include/fitz/object.h | 6 | ||||
-rw-r--r-- | mupdf/cmap.c | 2 | ||||
-rw-r--r-- | mupdf/font.c | 2 | ||||
-rw-r--r-- | mupdf/pagetree.c | 4 | ||||
-rw-r--r-- | mupdf/save.c | 9 | ||||
-rw-r--r-- | mupdf/xref.c | 2 | ||||
-rw-r--r-- | object/print.c | 83 | ||||
-rw-r--r-- | test/pdfdebug.c (renamed from test/mupdf.c) | 12 | ||||
-rw-r--r-- | tree/debug.c | 2 |
17 files changed, 862 insertions, 673 deletions
@@ -33,7 +33,9 @@ Library libfitz : # filter filter/buffer.c filter/filter.c - filter/file.c # unistd.h + filter/filec.c # unistd.h + filter/filer.c # unistd.h + filter/filew.c # unistd.h filter/null.c filter/arc4filter.c @@ -118,8 +120,10 @@ LINKLIBS = -lm ; -Main t-mupdf : test/mupdf.c ; -LinkLibraries t-mupdf : libmupdf libfitz ; +Main pdfclean : test/pdfclean.c ; +Main pdfdebug : test/pdfdebug.c ; + +LinkLibraries pdfclean pdfdebug : libmupdf libfitz ; #Main t-filter : tests/t-filter.c ; #Main t-parse : tests/t-parse.c ; diff --git a/filter/buffer.c b/filter/buffer.c index 7b728b9b..25e30a55 100644 --- a/filter/buffer.c +++ b/filter/buffer.c @@ -8,6 +8,7 @@ fz_newbuffer(fz_buffer **bp, int size) b = *bp = fz_malloc(sizeof(fz_buffer)); if (!b) return fz_outofmem; + b->ownsdata = 1; b->bp = fz_malloc(size); if (!b->bp) { fz_free(b); return fz_outofmem; } @@ -19,10 +20,31 @@ fz_newbuffer(fz_buffer **bp, int size) return nil; } +fz_error * +fz_newbufferwithdata(fz_buffer **bp, unsigned char *data, int size) +{ + fz_buffer *b; + + b = *bp = fz_malloc(sizeof(fz_buffer)); + if (!b) return fz_outofmem; + + b->ownsdata = 0; + b->bp = data; + + b->rp = b->bp; + b->wp = b->bp; + b->ep = b->bp + size; + b->eof = 0; + + return nil; +} + + void fz_freebuffer(fz_buffer *buf) { - fz_free(buf->bp); + if (buf->ownsdata) + fz_free(buf->bp); fz_free(buf); } @@ -35,6 +57,8 @@ fz_growbuffer(fz_buffer *buf) int wp = buf->wp - buf->bp; int ep = buf->ep - buf->bp; + assert(buf->ownsdata); + newbp = fz_realloc(buf->bp, ep * 2); if (!newbp) return fz_outofmem; @@ -49,6 +73,7 @@ fz_growbuffer(fz_buffer *buf) fz_error * fz_rewindbuffer(fz_buffer *buf) { + assert(buf->ownsdata); memmove(buf->bp, buf->rp, buf->wp - buf->rp); buf->wp = buf->bp + (buf->wp - buf->rp); buf->rp = buf->bp; diff --git a/filter/file.c b/filter/file.c deleted file mode 100644 index c3ab63a4..00000000 --- a/filter/file.c +++ /dev/null @@ -1,589 +0,0 @@ -#include <fitz.h> - -/* TODO: nil filter on write */ - -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 fd; - - assert(mode == O_RDONLY || mode == O_WRONLY); - - file = *filep = fz_malloc(sizeof(fz_file)); - if (!file) - return fz_outofmem; - - fd = open(path, mode, 0); - if (fd == -1) - return fz_throw("ioerror: open '%s': %s", path, strerror(errno)); - - 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: - close(fd); - fz_free(file->out); - fz_free(file->in); - fz_free(file); - *filep = nil; - return error; -} - -void -fz_closefile(fz_file *file) -{ - assert(file->depth == 0); - - if (file->mode == O_WRONLY) - fz_flush(file); - - if (file->error) - { - fz_warn("%s", file->error->msg); - fz_freeerror(file->error); - file->error = nil; - } - - close(file->fd); - - if (file->filter) fz_freefilter(file->filter); - fz_freebuffer(file->in); - fz_freebuffer(file->out); - fz_free(file); -} - -fz_error * -fz_pushfilter(fz_file *file, fz_filter *filter) -{ - fz_error *error; - fz_buffer *buf; - - if (file->depth == 0) - { - buf = file->out; - file->out = file->in; - file->in = buf; - - file->out->rp = file->out->bp; - file->out->wp = file->out->bp; - file->out->eof = 0; - - file->filter = filter; - } - else - { - 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; - } - } - - file->depth ++; - - return nil; -} - -void -fz_popfilter(fz_file *file) -{ - fz_buffer *buf; - - assert(file->depth > 0); - - if (file->mode == O_WRONLY) - fz_flush(file); - - if (file->error) - { - fz_warn("%s", file->error->msg); - fz_freeerror(file->error); - file->error = nil; - } - - if (file->depth == 1) - { - fz_freefilter(file->filter); - file->filter = nil; - - buf = file->out; - file->out = file->in; - file->in = buf; - - file->in->rp = file->in->bp; - file->in->wp = file->in->bp; - file->in->eof = 0; - } - else - { - fz_freebuffer(file->out); - fz_unchainpipeline(file->filter, &file->filter, &file->out); - } - - file->depth --; -} - -int -fz_seek(fz_file *f, int ofs) -{ - int t; - int c; - - assert(f->mode == O_RDONLY); - - if (f->filter) - { - 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 0; - } - - t = lseek(f->fd, ofs, 0); - 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 0; -} - -int -fz_tell(fz_file *f) -{ - int t; - - if (f->filter) - { - return f->filter->count - (f->out->wp - f->out->rp); - } - - t = lseek(f->fd, 0, 1); - if (t == -1) - { - f->error = fz_throw("ioerror: lseek: %s", strerror(errno)); - return -1; - } - - return t - (f->out->wp - f->out->rp); -} - -/* - * Read mode - */ - -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; -} - -static int producedata(fz_file *f) -{ - fz_error *reason; - int produced; - int n; - - assert(f->mode == O_RDONLY); - 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 (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 (producedata(f)) return EOF; - } - - if (f->out->rp < f->out->wp) - return *f->out->rp++; - - return EOF; -} - -int -fz_read(fz_file *f, 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 (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; -} - -/* - * Write mode - */ - -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, char *buf, int n) -{ - fz_error *reason; - int i = 0; - int x; - - assert(f->mode == O_WRONLY); - assert(f->error == nil); - - while (i < n) - { - while (f->in->rp < f->in->wp && i < n) - { - *f->in->rp++ = buf[i++]; - } - - if (f->in->rp == f->in->wp) - { - 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) - { - 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) - { - 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 == O_WRONLY); - assert(f->error == nil); - - f->in->eof = 1; - - 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) - { - 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) - { - 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; -} - -/* - * Utility function to consume contents of file stream into - * a freshly allocated buffer; realloced and trimmed to size. - */ - -enum { CHUNKSIZE = 4096 }; - -fz_error * -fz_readfile(unsigned char **bufp, int *lenp, fz_file *file) -{ - unsigned char *newbuf; - unsigned char *buf; - int len; - int pos; - int n; - - *bufp = nil; - *lenp = 0; - - 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); - -printf("fz_read %d bytes\n", n); - - if (n < 0) - { - fz_free(buf); - return fz_ferror(file); - } - - pos += n; - - if (n < CHUNKSIZE) - { - newbuf = fz_realloc(buf, pos); - if (!newbuf) - { - fz_free(buf); - return fz_outofmem; - } - - *bufp = newbuf; - *lenp = pos; - return nil; - } - } -} - diff --git a/filter/filec.c b/filter/filec.c new file mode 100644 index 00000000..f62d1265 --- /dev/null +++ b/filter/filec.c @@ -0,0 +1,302 @@ +#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 fd; + + assert(mode == O_RDONLY || mode == O_WRONLY); + + file = *filep = fz_malloc(sizeof(fz_file)); + if (!file) + return fz_outofmem; + + fd = open(path, mode, 0); + if (fd == -1) + return fz_throw("ioerror: open '%s': %s", path, strerror(errno)); + + 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_free(file->out); + fz_free(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 == O_RDONLY || mode == O_WRONLY); + + 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 == O_RDONLY) + { + file->in = buf; + error = fz_newbuffer(&file->out, FZ_BUFSIZE); + if (error) + goto cleanup; + } + + else + { + error = fz_newbuffer(&file->in, FZ_BUFSIZE); + if (error) + goto cleanup; + file->out = buf; + } + + return nil; + +cleanup: + *filep = nil; + fz_free(file); + return error; +} + +void +fz_closefile(fz_file *file) +{ + assert(file->depth == 0); + + if (file->mode != O_RDONLY) + fz_flush(file); + + if (file->error) + { + fz_warn("%s", file->error->msg); + fz_freeerror(file->error); + file->error = nil; + } + + if (file->fd == -1) /* open to buffer not file */ + { + if (file->mode == O_RDONLY) + fz_freebuffer(file->out); + else + fz_freebuffer(file->in); + } + else + { + fz_freebuffer(file->in); + fz_freebuffer(file->out); + close(file->fd); + } + + if (file->filter) + fz_freefilter(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; + +// XXX + if (file->mode == O_RDONLY) + { + file->out->rp = file->out->bp; + file->out->wp = file->out->bp; + file->out->eof = 0; + } + + file->filter = filter; + } + + else + { + if (file->mode == O_RDONLY) + { + 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 != O_RDONLY) + fz_flush(file); + + if (file->error) + { + fz_warn("%s", file->error->msg); + fz_freeerror(file->error); + file->error = nil; + } + + if (file->depth == 1) + { + fz_freefilter(file->filter); + file->filter = nil; + + buf = file->out; + file->out = file->in; + file->in = buf; + +// XXX + file->in->rp = file->in->bp; + file->in->wp = file->in->bp; + file->in->eof = 0; + } + else + { + if (file->mode == O_RDONLY) + { + fz_freebuffer(file->out); + fz_unchainpipeline(file->filter, &file->filter, &file->out); + } + else + { + fz_freebuffer(file->in); + fz_unchainpipeline(file->filter, &file->filter, &file->in); + } + } + + file->depth --; +} + +int +fz_seek(fz_file *f, int ofs) +{ + int t; + int c; + + assert(f->mode == O_RDONLY); + + if (f->filter) + { + 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 0; + } + + t = lseek(f->fd, ofs, 0); + 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 0; +} + +int +fz_tell(fz_file *f) +{ + int t; + + if (f->filter) + { + assert(f->mode == O_RDONLY); + return f->filter->count - (f->out->wp - f->out->rp); + } + + t = lseek(f->fd, 0, 1); + if (t == -1) + { + f->error = fz_throw("ioerror: lseek: %s", strerror(errno)); + return -1; + } + + if (f->mode == O_RDONLY) + return t - (f->out->wp - f->out->rp); + else + return t - (f->in->wp - f->in->rp); +} + diff --git a/filter/filer.c b/filter/filer.c new file mode 100644 index 00000000..804d7f7e --- /dev/null +++ b/filter/filer.c @@ -0,0 +1,237 @@ +#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; +} + +static int producedata(fz_file *f) +{ + fz_error *reason; + int produced; + int n; + + assert(f->mode == O_RDONLY); + 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 (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 (producedata(f)) return EOF; + } + + if (f->out->rp < f->out->wp) + return *f->out->rp++; + + return EOF; +} + +int +fz_read(fz_file *f, 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 (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 = 4096 }; + +fz_error * +fz_readfile(unsigned char **bufp, int *lenp, fz_file *file) +{ + unsigned char *newbuf; + unsigned char *buf; + int len; + int pos; + int n; + + *bufp = nil; + *lenp = 0; + + 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); + +printf("fz_read %d bytes\n", n); + + if (n < 0) + { + fz_free(buf); + return fz_ferror(file); + } + + pos += n; + + if (n < CHUNKSIZE) + { + newbuf = fz_realloc(buf, pos); + if (!newbuf) + { + fz_free(buf); + return fz_outofmem; + } + + *bufp = newbuf; + *lenp = pos; + return nil; + } + } +} + diff --git a/filter/filew.c b/filter/filew.c new file mode 100644 index 00000000..0422e60e --- /dev/null +++ b/filter/filew.c @@ -0,0 +1,235 @@ +#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, buf, 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, char *buf, int n) +{ + fz_error *reason; + int i = 0; + int x; + + assert(f->mode == O_WRONLY); + 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) + { + x = dowrite(f->in, f->fd); + if (x < 0) { + f->error = fz_throw("ioerror in write: %s", strerror(errno)); + return -1; + } + + fz_rewindbuffer(f->in); + } + } + + return 0; + } + + while (i < n) + { + while (f->in->rp < f->in->wp && i < n) + { + *f->in->rp++ = buf[i++]; + } + + if (f->in->rp == f->in->wp) + { + 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) + { + 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) + { + 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 == O_WRONLY); + assert(f->error == nil); + + f->in->eof = 1; + + if (!f->filter) + { + 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) + { + 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) + { + 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; +} + diff --git a/include/fitz/file.h b/include/fitz/file.h index e687e572..7807570c 100644 --- a/include/fitz/file.h +++ b/include/fitz/file.h @@ -12,9 +12,11 @@ struct fz_file_s }; 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 fz_tell(fz_file *f); @@ -24,10 +26,11 @@ int fz_peekbyte(fz_file *f); int fz_readline(fz_file *f, char *buf, int n); int fz_read(fz_file *f, char *buf, int n); -int fz_write(fz_file *f, char *buf, int n); -int fz_flush(fz_file *f); - fz_error *fz_readfile(unsigned char **bufp, int *lenp, fz_file *file); -fz_error *fz_ferror(fz_file *f); +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, char *buf, int n); +int fz_flush(fz_file *f); diff --git a/include/fitz/filter.h b/include/fitz/filter.h index 6f234143..f6a1603f 100644 --- a/include/fitz/filter.h +++ b/include/fitz/filter.h @@ -35,6 +35,7 @@ struct fz_filter_s struct fz_buffer_s { + int ownsdata; unsigned char *bp; unsigned char *rp; unsigned char *wp; @@ -53,6 +54,7 @@ fz_error *fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_ 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); void fz_freebuffer(fz_buffer *buf); diff --git a/include/fitz/object.h b/include/fitz/object.h index 8ccdd153..2a9ab15f 100644 --- a/include/fitz/object.h +++ b/include/fitz/object.h @@ -113,10 +113,8 @@ fz_error *fz_dictdel(fz_obj *dict, fz_obj *key); fz_error *fz_dictdels(fz_obj *dict, char *key); void fz_freedict(fz_obj *dict); -int fz_sprintobj(char *s, fz_obj *obj); -int fz_sprintcobj(char *s, fz_obj *obj); -int fz_fprintobj(FILE *f, fz_obj *obj); -int fz_fprintcobj(FILE *f, fz_obj *obj); +int fz_sprintobj(char *s, int n, fz_obj *obj, int tight); +void fz_debugobj(fz_obj *obj); fz_error *fz_parseobj(fz_obj **objp, char *s); fz_error *fz_packobj(fz_obj **objp, char *fmt, ...); diff --git a/mupdf/cmap.c b/mupdf/cmap.c index cec14e19..180e93c3 100644 --- a/mupdf/cmap.c +++ b/mupdf/cmap.c @@ -385,7 +385,7 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref) return error; printf(" embedded cmap: "); -fz_fprintcobj(stdout, stmobj); +fz_debugobj(stmobj); printf("\n"); fflush(stdout); diff --git a/mupdf/font.c b/mupdf/font.c index 1fa5fa93..6d499c60 100644 --- a/mupdf/font.c +++ b/mupdf/font.c @@ -674,7 +674,7 @@ printf(" cidtogidmap %d\n", len / 2); goto cleanup; printf(" W2 "); -fz_fprintobj(stdout, widths); +fz_debugobj(widths); printf("\n"); for (i = 0; i < fz_arraylen(widths); ) diff --git a/mupdf/pagetree.c b/mupdf/pagetree.c index de500f18..6ddc07c9 100644 --- a/mupdf/pagetree.c +++ b/mupdf/pagetree.c @@ -87,9 +87,9 @@ pdf_debugpagetree(pdf_pagetree *pages) printf("<<\n /Type /Pages\n /Count %d\n /Kids [\n", pages->count); for (i = 0; i < pages->count; i++) { printf(" "); - fz_fprintobj(stdout, pages->pref[i]); + fz_debugobj(pages->pref[i]); printf("\t%% page %d\n", i + 1); - //fz_fprintobj(stdout, pages->pobj[i]); + //fz_debugobj(stdout, pages->pobj[i]); //printf("\n"); } printf(" ]\n>>\n"); diff --git a/mupdf/save.c b/mupdf/save.c index c86c9e72..1698fc23 100644 --- a/mupdf/save.c +++ b/mupdf/save.c @@ -4,7 +4,6 @@ static fz_error *writestored(FILE *out, pdf_xref *xref, int oid) { pdf_xrefentry *x = xref->table + oid; - fz_error *error; fz_obj *obj; fz_buffer *stm; @@ -18,7 +17,7 @@ static fz_error *writestored(FILE *out, pdf_xref *xref, int oid) pdf_cryptobj(xref->crypt, obj, oid, x->gen); fprintf(out, "%d %d obj\n", oid, x->gen); - fz_fprintobj(out, obj); + fz_debugobj(obj); fprintf(out, "\n"); if (stm) @@ -54,7 +53,7 @@ static fz_error *writecopy(FILE *out, pdf_xref *xref, int oid) return error; fprintf(out, "%d %d obj\n", oid, x->gen); - fz_fprintobj(out, obj); + fz_debugobj(obj); fprintf(out, "\n"); if (stmofs != -1) @@ -203,13 +202,13 @@ pdf_saveincrementalpdf(pdf_xref *xref, char *path) obj = fz_dictgets(xref->trailer, "Encrypt"); if (obj) { fprintf(out,"\n /Encrypt "); - fz_fprintobj(out, obj); + fz_debugobj(obj); } obj = fz_dictgets(xref->trailer, "ID"); if (obj) { fprintf(out,"\n /ID "); - fz_fprintobj(out, obj); + fz_debugobj(obj); } fprintf(out, "\n>>\n\n"); diff --git a/mupdf/xref.c b/mupdf/xref.c index 37cc16c2..53b9f239 100644 --- a/mupdf/xref.c +++ b/mupdf/xref.c @@ -117,7 +117,7 @@ pdf_debugxref(pdf_xref *xref) xref->table[i].type); } printf("trailer\n"); - fz_fprintobj(stdout, xref->trailer); + fz_debugobj(xref->trailer); printf("\n"); } diff --git a/object/print.c b/object/print.c index af6941f9..520e53b9 100644 --- a/object/print.c +++ b/object/print.c @@ -2,10 +2,9 @@ struct fmt { - FILE *file; char *buf; + int cap; int len; - int indent; int tight; int col; @@ -33,9 +32,7 @@ static inline void fmtputc(struct fmt *fmt, int c) } fmt->sep = 0; - if (fmt->file) - putc(c, fmt->file); - if (fmt->buf) + if (fmt->buf && fmt->len < fmt->cap) fmt->buf[fmt->len] = c; if (c == '\n') @@ -259,74 +256,48 @@ static void fmtobj(struct fmt *fmt, fz_obj *obj) } int -fz_sprintobj(char *s, fz_obj *obj) +fz_sprintobj(char *s, int n, fz_obj *obj, int tight) { struct fmt fmt; fmt.indent = 0; - fmt.tight = 0; fmt.col = 0; fmt.sep = 0; fmt.last = 0; - fmt.file = nil; + fmt.tight = tight; fmt.buf = s; + fmt.cap = n; fmt.len = 0; fmtobj(&fmt, obj); - return fmt.len; -} -int -fz_sprintcobj(char *s, fz_obj *obj) -{ - struct fmt fmt; - - fmt.indent = 0; - fmt.tight = 1; - fmt.col = 0; - fmt.sep = 0; - fmt.last = 0; + if (fmt.buf && fmt.len < fmt.cap) + fmt.buf[fmt.len] = '\0'; - fmt.file = nil; - fmt.buf = s; - fmt.len = 0; - fmtobj(&fmt, obj); return fmt.len; } -int -fz_fprintobj(FILE *file, fz_obj *obj) +void +fz_debugobj(fz_obj *obj) { - struct fmt fmt; + char buf[1024]; + char *ptr; + int n; - fmt.indent = 0; - fmt.tight = 0; - fmt.col = 0; - fmt.sep = 0; - fmt.last = 0; - - fmt.file = file; - fmt.buf = nil; - fmt.len = 0; - fmtobj(&fmt, obj); - return fmt.len; -} - -int -fz_fprintcobj(FILE *file, fz_obj *obj) -{ - struct fmt fmt; - - fmt.indent = 0; - fmt.tight = 1; - fmt.col = 0; - fmt.sep = 0; - fmt.last = 0; - - fmt.file = file; - fmt.buf = nil; - fmt.len = 0; - fmtobj(&fmt, obj); - return fmt.len; + n = fz_sprintobj(nil, 0, obj, 0); + if (n < sizeof buf) + { + fz_sprintobj(buf, sizeof buf, obj, 0); + fwrite(buf, 1, n, stdout); + } + else + { + ptr = fz_malloc(n); + if (!ptr) + return; + fz_sprintobj(ptr, n, obj, 0); + fwrite(ptr, 1, n, stdout); + fz_free(ptr); + } } diff --git a/test/mupdf.c b/test/pdfdebug.c index b51eb43d..d63a720c 100644 --- a/test/mupdf.c +++ b/test/pdfdebug.c @@ -112,7 +112,7 @@ void printobject(pdf_xref *xref, int oid, int gid) if (error) fz_abort(error); printf("%d %d obj\n", oid, gid); - fz_fprintobj(stdout, obj); + fz_debugobj(obj); printf("\n"); if (stmofs != -1) { printf("stream\n"); @@ -153,7 +153,7 @@ void showpage(pdf_xref *xref, fz_obj *page) fz_obj *contents; int i; - fz_fprintobj(stdout, page); + fz_debugobj(page); printf("\n"); resources = fz_dictgets(page, "Resources"); @@ -173,9 +173,9 @@ void showpage(pdf_xref *xref, fz_obj *page) printf("resources:\n"); printf(" font:\n"); -fz_fprintobj(stdout, rdb->font); +fz_debugobj(rdb->font); printf("\n extgstate:\n"); -fz_fprintobj(stdout, rdb->extgstate); +fz_debugobj(rdb->extgstate); printf("\nfitz tree:\n"); error = pdf_newcsi(&csi); @@ -319,7 +319,7 @@ int main(int argc, char **argv) if (optind == argc) { printf("trailer\n"); - fz_fprintobj(stdout, xref->trailer); + fz_debugobj(xref->trailer); printf("\n"); } @@ -330,6 +330,8 @@ int main(int argc, char **argv) } } +printf("done.\n"); + pdf_closexref(xref); return 0; diff --git a/tree/debug.c b/tree/debug.c index f5012c60..2e7cfc4f 100644 --- a/tree/debug.c +++ b/tree/debug.c @@ -13,7 +13,7 @@ static void lispmeta(fz_meta *node, int level) fz_node *child; indent(level); printf("(meta "); - fz_fprintcobj(stdout, node->info); + fz_debugobj(node->info); printf("\n"); for (child = node->child; child; child = child->next) lispnode(child, level + 1); |