diff options
author | Tor Andersson <tor@ghostscript.com> | 2009-03-05 19:53:53 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2009-03-05 19:53:53 +0100 |
commit | d219624c5cfb98556c71cf71d6eed6727846badc (patch) | |
tree | a1952fcc99482fdd7605fab75f7e21e339323aae | |
parent | 240bd7637433d5c162677c32dd0f77da92ebed80 (diff) | |
download | mupdf-d219624c5cfb98556c71cf71d6eed6727846badc.tar.xz |
Remove unused and mostly untested pdf updating and writing code.
-rw-r--r-- | fitz/Jamfile | 1 | ||||
-rw-r--r-- | fitz/fitz_stream.h | 22 | ||||
-rw-r--r-- | fitz/obj_print.c | 27 | ||||
-rw-r--r-- | fitz/stm_misc.c | 16 | ||||
-rw-r--r-- | fitz/stm_open.c | 103 | ||||
-rw-r--r-- | fitz/stm_read.c | 18 | ||||
-rw-r--r-- | fitz/stm_write.c | 313 | ||||
-rw-r--r-- | mupdf/Jamfile | 2 | ||||
-rw-r--r-- | mupdf/mupdf.h | 28 | ||||
-rw-r--r-- | mupdf/pdf_crypt.c | 31 | ||||
-rw-r--r-- | mupdf/pdf_doctor.c | 286 | ||||
-rw-r--r-- | mupdf/pdf_open.c | 8 | ||||
-rw-r--r-- | mupdf/pdf_page.c | 108 | ||||
-rw-r--r-- | mupdf/pdf_repair.c | 14 | ||||
-rw-r--r-- | mupdf/pdf_save.c | 335 | ||||
-rw-r--r-- | mupdf/pdf_stream.c | 32 | ||||
-rw-r--r-- | mupdf/pdf_xref.c | 195 |
17 files changed, 116 insertions, 1423 deletions
diff --git a/fitz/Jamfile b/fitz/Jamfile index 3e79a301..7099185e 100644 --- a/fitz/Jamfile +++ b/fitz/Jamfile @@ -50,7 +50,6 @@ Library libfitz : stm_filter.c stm_open.c stm_read.c - stm_write.c stm_misc.c filt_pipeline.c diff --git a/fitz/fitz_stream.h b/fitz/fitz_stream.h index 94d1a360..3f05801a 100644 --- a/fitz/fitz_stream.h +++ b/fitz/fitz_stream.h @@ -124,6 +124,7 @@ fz_error *fz_dictdels(fz_obj *dict, char *key); void fz_sortdict(fz_obj *dict); int fz_sprintobj(char *s, int n, fz_obj *obj, int tight); +int fz_fprintobj(FILE *fp, fz_obj *obj, int tight); void fz_debugobj(fz_obj *obj); fz_error *fz_parseobj(fz_obj **objp, char *s); @@ -322,13 +323,11 @@ void fz_arc4encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *sr 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; @@ -341,19 +340,14 @@ struct fz_stream_s * 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, unsigned char *mem, 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. @@ -413,17 +407,3 @@ static inline int fz_peekbyte(fz_stream *stm) #endif -/* - * Output stream functions. - */ - -int fz_wtell(fz_stream *stm); -fz_error * fz_wseek(fz_stream *stm, int offset, int whence); - -fz_error * fz_write(fz_stream *stm, unsigned char *buf, int n); -fz_error * fz_flush(fz_stream *stm); - -fz_error * fz_printstr(fz_stream *stm, char *s); -fz_error * fz_printobj(fz_stream *stm, fz_obj *obj, int tight); -fz_error * fz_print(fz_stream *stm, char *fmt, ...); - diff --git a/fitz/obj_print.c b/fitz/obj_print.c index 0c3eba42..01f5b877 100644 --- a/fitz/obj_print.c +++ b/fitz/obj_print.c @@ -311,29 +311,36 @@ fz_sprintobj(char *s, int n, fz_obj *obj, int tight) return fmt.len; } -void -fz_debugobj(fz_obj *obj) +int +fz_fprintobj(FILE *fp, fz_obj *obj, int tight) { char buf[1024]; char *ptr; int n; - n = fz_sprintobj(nil, 0, obj, 0); + n = fz_sprintobj(nil, 0, obj, tight); if (n < sizeof buf) { - fz_sprintobj(buf, sizeof buf, obj, 0); - fputs(buf, stdout); - fputc('\n', stdout); + fz_sprintobj(buf, sizeof buf, obj, tight); + fputs(buf, fp); + fputc('\n', fp); } else { ptr = fz_malloc(n); if (!ptr) - return; - fz_sprintobj(ptr, n, obj, 0); - fputs(ptr, stdout); - fputc('\n', stdout); + return -1; + fz_sprintobj(ptr, n, obj, tight); + fputs(ptr, fp); + fputc('\n', fp); fz_free(ptr); } + return n; +} + +void +fz_debugobj(fz_obj *obj) +{ + fz_fprintobj(stdout, obj, 0); } diff --git a/fitz/stm_misc.c b/fitz/stm_misc.c index af5e1445..4a51aeb8 100644 --- a/fitz/stm_misc.c +++ b/fitz/stm_misc.c @@ -5,22 +5,6 @@ #include "fitz_base.h" #include "fitz_stream.h" -int -fz_tell(fz_stream *stm) -{ - if (stm->mode == FZ_SREAD) - return fz_rtell(stm); - return fz_wtell(stm); -} - -fz_error * -fz_seek(fz_stream *stm, int offset, int whence) -{ - if (stm->mode == FZ_SREAD) - return fz_rseek(stm, offset, whence); - return fz_wseek(stm, offset, whence); -} - /* * Read a line terminated by LF or CR or CRLF. */ diff --git a/fitz/stm_open.c b/fitz/stm_open.c index 3c4e916b..41fc8d68 100644 --- a/fitz/stm_open.c +++ b/fitz/stm_open.c @@ -6,7 +6,7 @@ #include "fitz_stream.h" static fz_stream * -newstm(int kind, int mode) +newstm(int kind) { fz_stream *stm; @@ -16,7 +16,6 @@ newstm(int kind, int mode) stm->refs = 1; stm->kind = kind; - stm->mode = mode; stm->dead = 0; stm->error = fz_okay; stm->buffer = nil; @@ -50,12 +49,6 @@ fz_dropstream(fz_stream *stm) fz_warn("dropped unhandled ioerror"); } - if (stm->mode == FZ_SWRITE) - { - stm->buffer->eof = 1; - fz_flush(stm); - } - switch (stm->kind) { case FZ_SFILE: @@ -74,13 +67,12 @@ fz_dropstream(fz_stream *stm) } } -static fz_error * -openfile(fz_stream **stmp, char *path, int mode, int realmode) +fz_error * fz_openrfile(fz_stream **stmp, char *path) { fz_error *error; fz_stream *stm; - stm = newstm(FZ_SFILE, mode); + stm = newstm(FZ_SFILE); if (!stm) return fz_throw("outofmem: stream struct"); @@ -91,7 +83,7 @@ openfile(fz_stream **stmp, char *path, int mode, int realmode) return fz_rethrow(error, "cannot create buffer"); } - stm->file = open(path, realmode, 0666); + stm->file = open(path, O_BINARY | O_RDONLY, 0666); if (stm->file < 0) { fz_dropbuffer(stm->buffer); @@ -103,13 +95,12 @@ openfile(fz_stream **stmp, char *path, int mode, int realmode) return fz_okay; } -static fz_error * -openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode) +fz_error * fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src) { fz_error *error; fz_stream *stm; - stm = newstm(FZ_SFILTER, mode); + stm = newstm(FZ_SFILTER); if (!stm) return fz_throw("outofmem: stream struct"); @@ -127,98 +118,22 @@ openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode) return fz_okay; } -static fz_error * -openbuffer(fz_stream **stmp, fz_buffer *buf, int mode) +fz_error * fz_openrbuffer(fz_stream **stmp, fz_buffer *buf) { fz_stream *stm; - stm = newstm(FZ_SBUFFER, mode); + stm = newstm(FZ_SBUFFER); if (!stm) return fz_throw("outofmem: stream struct"); stm->buffer = fz_keepbuffer(buf); - if (mode == FZ_SREAD) - stm->buffer->eof = 1; + stm->buffer->eof = 1; *stmp = stm; return fz_okay; } -fz_error * fz_openrfile(fz_stream **stmp, char *path) -{ - fz_error *error; - error = openfile(stmp, path, FZ_SREAD, O_BINARY | O_RDONLY); - if (error) - return fz_rethrow(error, "cannot open file for reading: '%s'", path); - return fz_okay; -} - -fz_error * fz_openwfile(fz_stream **stmp, char *path) -{ - fz_error *error; - error = openfile(stmp, path, FZ_SWRITE, - O_BINARY | O_WRONLY | O_CREAT | O_TRUNC); - if (error) - return fz_rethrow(error, "cannot open file for writing: '%s'", path); - return fz_okay; -} - -fz_error * fz_openafile(fz_stream **stmp, char *path) -{ - fz_error *error; - int t; - - error = openfile(stmp, path, FZ_SWRITE, O_BINARY | O_WRONLY); - if (error) - return fz_rethrow(error, "cannot open file for writing: '%s'", path); - - t = lseek((*stmp)->file, 0, 2); - if (t < 0) - { - (*stmp)->dead = 1; - return fz_throw("syserr: lseek '%s': %s", path, strerror(errno)); - } - - return fz_okay; -} - -fz_error * fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src) -{ - fz_error *error; - error = openfilter(stmp, flt, src, FZ_SREAD); - if (error) - return fz_rethrow(error, "cannot create reading filter stream"); - return fz_okay; -} - -fz_error * fz_openwfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src) -{ - fz_error *error; - error = openfilter(stmp, flt, src, FZ_SWRITE); - if (error) - return fz_rethrow(error, "cannot create writing filter stream"); - return fz_okay; -} - -fz_error * fz_openrbuffer(fz_stream **stmp, fz_buffer *buf) -{ - fz_error *error; - error = openbuffer(stmp, buf, FZ_SREAD); - if (error) - return fz_rethrow(error, "cannot create reading buffer stream"); - return fz_okay; -} - -fz_error * fz_openwbuffer(fz_stream **stmp, fz_buffer *buf) -{ - fz_error *error; - error = openbuffer(stmp, buf, FZ_SWRITE); - if (error) - return fz_rethrow(error, "cannot create writing buffer stream"); - return fz_okay; -} - fz_error * fz_openrmemory(fz_stream **stmp, unsigned char *mem, int len) { fz_error *error; diff --git a/fitz/stm_read.c b/fitz/stm_read.c index 20a36a3e..1e3bd502 100644 --- a/fitz/stm_read.c +++ b/fitz/stm_read.c @@ -17,9 +17,6 @@ fz_readimp(fz_stream *stm) if (stm->dead) return fz_throw("assert: read from dead stream"); - if (stm->mode != FZ_SREAD) - return fz_throw("assert: read from writing stream"); - if (buf->eof) return fz_okay; @@ -123,15 +120,13 @@ fz_readimp(fz_stream *stm) } int -fz_rtell(fz_stream *stm) +fz_tell(fz_stream *stm) { fz_buffer *buf = stm->buffer; int t; if (stm->dead) return EOF; - if (stm->mode != FZ_SREAD) - return EOF; switch (stm->kind) { @@ -157,7 +152,7 @@ fz_rtell(fz_stream *stm) } fz_error * -fz_rseek(fz_stream *stm, int offset, int whence) +fz_seek(fz_stream *stm, int offset, int whence) { fz_error *error; fz_buffer *buf = stm->buffer; @@ -166,12 +161,9 @@ fz_rseek(fz_stream *stm, int offset, int whence) if (stm->dead) return fz_throw("assert: seek in dead stream"); - if (stm->mode != FZ_SREAD) - return fz_throw("assert: read operation on writing stream"); - if (whence == 1) { - int cur = fz_rtell(stm); + int cur = fz_tell(stm); if (cur < 0) return fz_throw("cannot tell current position"); offset = cur + offset; @@ -198,12 +190,12 @@ fz_rseek(fz_stream *stm, int offset, int whence) case FZ_SFILTER: if (whence == 0) { - if (offset < fz_rtell(stm)) + if (offset < fz_tell(stm)) { stm->dead = 1; return fz_throw("assert: seek backwards in filter"); } - while (fz_rtell(stm) < offset) + while (fz_tell(stm) < offset) { c = fz_readbyte(stm); if (c == EOF) diff --git a/fitz/stm_write.c b/fitz/stm_write.c deleted file mode 100644 index dd8c0ebf..00000000 --- a/fitz/stm_write.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Output streams. - */ - -#include "fitz_base.h" -#include "fitz_stream.h" - -int -fz_wtell(fz_stream *stm) -{ - fz_buffer *buf = stm->buffer; - int t; - - if (stm->dead) - return EOF; - - if (stm->mode != FZ_SWRITE) - return EOF; - - switch (stm->kind) - { - case FZ_SFILE: - t = lseek(stm->file, 0, 1); - if (t < 0) - { - fz_warn("syserr: lseek: %s", strerror(errno)); - stm->dead = 1; - return EOF; - } - return t + (buf->wp - buf->rp); - - case FZ_SFILTER: - return stm->filter->count + (buf->wp - buf->rp); - - case FZ_SBUFFER: - return buf->wp - buf->bp; - - default: - return EOF; - } -} - -fz_error * -fz_wseek(fz_stream *stm, int offset, int whence) -{ - fz_buffer *buf = stm->buffer; - int t; - - if (stm->dead) - return fz_throw("assert: seek in dead stream"); - - if (stm->mode != FZ_SWRITE) - return fz_throw("assert: write operation on reading stream"); - - if (stm->kind != FZ_SFILE) - return fz_throw("assert: write seek on non-file stream"); - - t = lseek(stm->file, offset, whence); - if (t < 0) - { - stm->dead = 1; - return fz_throw("syserr: lseek: %s", strerror(errno)); - } - - buf->rp = buf->bp; - buf->wp = buf->bp; - buf->eof = 0; - - return fz_okay; -} - -static fz_error * -fz_flushfilterimp(fz_stream *stm) -{ - fz_buffer *buf = stm->buffer; - fz_error *error; - fz_error *reason; - -loop: - - reason = fz_process(stm->filter, stm->buffer, stm->chain->buffer); - - if (reason == fz_ioneedin) - { - if (buf->rp > buf->bp) - { - error = fz_rewindbuffer(buf); - if (error) - { - stm->dead = 1; - return fz_rethrow(error, "cannot rewind buffer"); - } - } - else - { - error = fz_growbuffer(buf); - if (error) - { - stm->dead = 1; - return fz_rethrow(error, "cannot grow buffer"); - } - } - } - - else if (reason == fz_ioneedout) - { - error = fz_flush(stm->chain); - if (error) - return fz_rethrow(error, "cannot flush chain buffer"); - } - - else if (reason == fz_iodone) - { - stm->dead = 2; /* special flag that we are dead because of eod */ - } - - else - { - stm->dead = 1; - return fz_rethrow(reason, "cannot process filter"); - } - - /* if we are at eof, repeat until other filter sets otherside to eof */ - if (buf->eof && !stm->chain->buffer->eof) - goto loop; - - return fz_okay; -} - -/* - * Empty the buffer into the sink. - * Promise to make more space available. - * Called by fz_write and fz_dropstream. - * If buffer is eof, then all data must be flushed. - */ -fz_error * -fz_flush(fz_stream *stm) -{ - fz_buffer *buf = stm->buffer; - fz_error *error; - int t; - - if (stm->dead == 2) /* eod flag */ - return fz_okay; - - if (stm->dead) - return fz_throw("assert: flush on dead stream"); - - if (stm->mode != FZ_SWRITE) - return fz_throw("assert: write operation on reading stream"); - - switch (stm->kind) - { - case FZ_SFILE: - while (buf->rp < buf->wp) - { - t = write(stm->file, buf->rp, buf->wp - buf->rp); - if (t < 0) - { - stm->dead = 1; - return fz_throw("syserr: write: %s", strerror(errno)); - } - - buf->rp += t; - } - - if (buf->rp > buf->bp) - { - error = fz_rewindbuffer(buf); - if (error) - { - stm->dead = 1; - return fz_rethrow(error, "cannot rewind buffer"); - } - } - - return fz_okay; - - case FZ_SFILTER: - error = fz_flushfilterimp(stm); - if (error) - return fz_rethrow(error, "cannot flush through filter"); - return fz_okay; - - case FZ_SBUFFER: - if (!buf->eof && buf->wp == buf->ep) - { - error = fz_growbuffer(buf); - if (error) - { - stm->dead = 1; - return fz_rethrow(error, "cannot grow buffer"); - } - } - return fz_okay; - - default: - return fz_throw("unknown stream type"); - } -} - -/* - * Write data to stream. - * Buffer until internal buffer is full. - * When full, call fz_flush to make more space available. - * Return error if all the data could not be written. - */ -fz_error * -fz_write(fz_stream *stm, unsigned char *mem, int n) -{ - fz_buffer *buf = stm->buffer; - fz_error *error; - int i = 0; - - if (stm->dead) - return fz_throw("assert: write on dead stream"); - - if (stm->mode != FZ_SWRITE) - return fz_throw("assert: write on reading stream"); - - while (i < n) - { - while (buf->wp < buf->ep && i < n) - *buf->wp++ = mem[i++]; - - if (buf->wp == buf->ep && i < n) - { - error = fz_flush(stm); - if (error) - return fz_rethrow(error, "cannot flush buffer"); - if (stm->dead) - return fz_throw("assert: write on dead stream"); - } - } - - return fz_okay; -} - -fz_error * -fz_printstr(fz_stream *stm, char *s) -{ - return fz_write(stm, (unsigned char *) s, strlen(s)); -} - -fz_error * -fz_printobj(fz_stream *file, fz_obj *obj, int tight) -{ - fz_error *error; - unsigned 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); - error = fz_write(file, (unsigned char *) buf, n); - if (error) - return fz_rethrow(error, "cannot write buffer"); - return fz_okay; - } - else - { - ptr = fz_malloc(n); - if (!ptr) - return fz_throw("outofmem: scratch buffer"); - fz_sprintobj(ptr, n, obj, tight); - error = fz_write(file, (unsigned char *) ptr, n); - fz_free(ptr); - if (error) - return fz_rethrow(error, "cannot write buffer"); - return fz_okay; - } -} - -fz_error * -fz_print(fz_stream *stm, char *fmt, ...) -{ - fz_error *error; - 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) - { - error = fz_write(stm, (unsigned char *) buf, n); - if (error) - return fz_rethrow(error, "cannot write buffer"); - return fz_okay; - } - - p = fz_malloc(n); - if (!p) - return fz_throw("outofmem: scratch buffer"); - - va_start(ap, fmt); - vsnprintf(p, n, fmt, ap); - va_end(ap); - - error = fz_write(stm, (unsigned char *) p, n); - - fz_free(p); - - if (error) - return fz_rethrow(error, "cannot write buffer"); - return fz_okay; -} - diff --git a/mupdf/Jamfile b/mupdf/Jamfile index c741e7e6..4201fc48 100644 --- a/mupdf/Jamfile +++ b/mupdf/Jamfile @@ -14,13 +14,11 @@ Library libmupdf : # syntax layer pdf_crypt.c pdf_debug.c - pdf_doctor.c pdf_lex.c pdf_nametree.c pdf_open.c pdf_parse.c pdf_repair.c - pdf_save.c pdf_stream.c pdf_xref.c diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index acca2846..4184f662 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -37,7 +37,7 @@ fz_error *pdf_lex(pdf_token_e *tok, fz_stream *f, char *buf, int n, int *len); 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_error *pdf_parseindobj(fz_obj **op, fz_stream *f, char *buf, int cap, int *oid, int *gen, int *stmofs); fz_rect pdf_torect(fz_obj *array); fz_matrix pdf_tomatrix(fz_obj *array); @@ -91,8 +91,9 @@ int pdf_setpassword(pdf_crypt *crypt, char *pw); int pdf_setuserpassword(pdf_crypt *crypt, char *pw, int pwlen); int pdf_setownerpassword(pdf_crypt *crypt, char *pw, int pwlen); -fz_error *pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid); -void pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid); +fz_error *pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gen); +void pdf_cryptbuffer(pdf_crypt *crypt, fz_buffer *buf, int oid, int gen); +void pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gen); void pdf_dropcrypt(pdf_crypt *crypt); /* @@ -125,13 +126,11 @@ struct pdf_xref_s struct pdf_xrefentry_s { - unsigned int ofs; /* file offset / objstm object number */ - unsigned short gen; /* generation / objstm index */ - char type; /* 0=unset (f)ree i(n)use (o)bjstm (d)elete (a)dd */ - char mark; /* for garbage collection etc */ - fz_buffer *stmbuf; /* in-memory stream */ - int stmofs; /* on-disk stream */ - fz_obj *obj; /* stored/cached object */ + int ofs; /* file offset / objstm object number */ + int gen; /* generation / objstm index */ + int stmofs; /* on-disk stream */ + fz_obj *obj; /* stored/cached object */ + int type; /* 0=unset (f)ree i(n)use (o)bjstm */ }; fz_error *pdf_newxref(pdf_xref **); @@ -139,19 +138,10 @@ fz_error *pdf_repairxref(pdf_xref *, char *filename); fz_error *pdf_loadxref(pdf_xref *, char *filename); fz_error *pdf_initxref(pdf_xref *); -fz_error *pdf_openpdf(pdf_xref **, char *filename); -fz_error *pdf_updatexref(pdf_xref *, char *filename); -fz_error *pdf_savexref(pdf_xref *, char *filename, pdf_crypt *encrypt); - void pdf_debugxref(pdf_xref *); void pdf_flushxref(pdf_xref *, int force); void pdf_closexref(pdf_xref *); -fz_error *pdf_allocobject(pdf_xref *, int *oidp, int *genp); -fz_error *pdf_deleteobject(pdf_xref *, int oid, int gen); -fz_error *pdf_updateobject(pdf_xref *, int oid, int gen, fz_obj *obj); -fz_error *pdf_updatestream(pdf_xref *, int oid, int gen, fz_buffer *stm); - fz_error *pdf_cacheobject(pdf_xref *, int oid, int gen); 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); diff --git a/mupdf/pdf_crypt.c b/mupdf/pdf_crypt.c index d2470d4f..25de59e3 100644 --- a/mupdf/pdf_crypt.c +++ b/mupdf/pdf_crypt.c @@ -289,7 +289,7 @@ pdf_dropcrypt(pdf_crypt *crypt) } static void -createobjkey(pdf_crypt *crypt, unsigned oid, unsigned gid, unsigned char *key) +createobjkey(pdf_crypt *crypt, unsigned oid, unsigned gen, unsigned char *key) { unsigned char message[5]; fz_md5 md5; @@ -304,8 +304,8 @@ createobjkey(pdf_crypt *crypt, unsigned oid, unsigned gid, unsigned char *key) message[1] = (oid >> 8) & 0xFF; message[2] = (oid >> 16) & 0xFF; - message[3] = gid & 0xFF; - message[4] = (gid >> 8) & 0xFF; + message[3] = gen & 0xFF; + message[4] = (gen >> 8) & 0xFF; fz_md5update(&md5, message, 5); @@ -596,7 +596,7 @@ pdf_setownerpassword(pdf_crypt *crypt, char *ownerpw, int pwlen) * Recursively (and destructively!) de/encrypt all strings in obj */ void -pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid) +pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gen) { fz_arc4 arc4; unsigned char key[16]; @@ -607,7 +607,7 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid) { s = (unsigned char *) fz_tostrbuf(obj); n = fz_tostrlen(obj); - createobjkey(crypt, oid, gid, key); + createobjkey(crypt, oid, gen, key); fz_arc4init(&arc4, key, crypt->keylen); fz_arc4encrypt(&arc4, s, s, n); } @@ -617,7 +617,7 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid) n = fz_arraylen(obj); for (i = 0; i < n; i++) { - pdf_cryptobj(crypt, fz_arrayget(obj, i), oid, gid); + pdf_cryptobj(crypt, fz_arrayget(obj, i), oid, gen); } } @@ -626,20 +626,33 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid) n = fz_dictlen(obj); for (i = 0; i < n; i++) { - pdf_cryptobj(crypt, fz_dictgetval(obj, i), oid, gid); + pdf_cryptobj(crypt, fz_dictgetval(obj, i), oid, gen); } } } /* + * De/encrypt the contents of a buffer + */ +void +pdf_cryptbuffer(pdf_crypt *crypt, fz_buffer *buf, int oid, int gen) +{ + fz_arc4 arc4; + unsigned char key[16]; + createobjkey(crypt, oid, gen, key); + fz_arc4init(&arc4, key, crypt->keylen); + fz_arc4encrypt(&arc4, buf->rp, buf->rp, buf->wp - buf->rp); +} + +/* * Create filter suitable for de/encrypting a stream */ fz_error * -pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid) +pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gen) { fz_error *error; unsigned char key[16]; - createobjkey(crypt, oid, gid, key); + createobjkey(crypt, oid, gen, key); error = fz_newarc4filter(fp, key, crypt->keylen); if (error) return fz_rethrow(error, "cannot create crypt filter"); diff --git a/mupdf/pdf_doctor.c b/mupdf/pdf_doctor.c deleted file mode 100644 index 12ee46a1..00000000 --- a/mupdf/pdf_doctor.c +++ /dev/null @@ -1,286 +0,0 @@ -#include "fitz.h" -#include "mupdf.h" - -/* - * Sweep and mark reachable objects - * - * Don't bother chaining errors for this deep recursion - */ - -static fz_error *sweepref(pdf_xref *xref, fz_obj *ref); - -static fz_error * -sweepobj(pdf_xref *xref, fz_obj *obj) -{ - fz_error *error; - int i; - - if (fz_isdict(obj)) - { - for (i = 0; i < fz_dictlen(obj); i++) - { - error = sweepobj(xref, fz_dictgetval(obj, i)); - if (error) - return error; /* too deeply nested for rethrow */ - } - } - - if (fz_isarray(obj)) - { - for (i = 0; i < fz_arraylen(obj); i++) - { - error = sweepobj(xref, fz_arrayget(obj, i)); - if (error) - return error; /* too deeply nested for rethrow */ - } - } - - if (fz_isindirect(obj)) - return sweepref(xref, obj); - - return fz_okay; -} - -static fz_error * -sweepref(pdf_xref *xref, fz_obj *ref) -{ - fz_error *error; - fz_obj *obj; - int oid, gid; - - oid = fz_tonum(ref); - gid = fz_tonum(ref); - - if (oid < 0 || oid >= xref->len) - return fz_throw("object out of range (%d %d R)", oid, gid); - - if (xref->table[oid].mark) - return fz_okay; - - xref->table[oid].mark = 1; - - error = pdf_loadindirect(&obj, xref, ref); - if (error) - return fz_rethrow(error, "cannot load indirect object"); - - error = sweepobj(xref, obj); - if (error) - { - fz_dropobj(obj); - return error; /* too deeply nested for rethrow */ - } - - fz_dropobj(obj); - return fz_okay; -} - -/* - * Garbage collect objects not reachable from - * the trailer dictionary - */ - -fz_error * -pdf_garbagecollect(pdf_xref *xref) -{ - fz_error *error; - int i, g; - - pdf_logxref("garbage collect {\n"); - - for (i = 0; i < xref->len; i++) - xref->table[i].mark = 0; - - error = sweepobj(xref, xref->trailer); - if (error) - return fz_rethrow(error, "cannot mark used objects"); - - for (i = 0; i < xref->len; i++) - { - pdf_xrefentry *x = xref->table + i; - g = x->gen; - if (x->type == 'o') - g = 0; - if (!x->mark && x->type != 'f' && x->type != 'd') - { - error = pdf_deleteobject(xref, i, g); - if (error) - return fz_rethrow(error, "cannot delete unmarked object %d", i); - } - } - - pdf_logxref("}\n"); - - return fz_okay; -} - -/* - * Transplant (copy) objects and streams from one file to another - */ - -struct pair -{ - int soid, sgen; - int doid, dgen; -}; - -static fz_error * -remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n) -{ - fz_error *error; - int i, o, g; - fz_obj *tmp, *key; - - if (fz_isindirect(old)) - { - o = fz_tonum(old); - g = fz_togen(old); - for (i = 0; i < n; i++) - if (map[i].soid == o && map[i].sgen == g) - { - error = fz_newindirect(newp, map[i].doid, map[i].dgen); - if (error) - return fz_rethrow(error, "cannot remap indirect reference"); - } - } - - else if (fz_isarray(old)) - { - error = fz_newarray(newp, fz_arraylen(old)); - if (error) - return fz_rethrow(error, "cannot remap array"); - for (i = 0; i < fz_arraylen(old); i++) - { - tmp = fz_arrayget(old, i); - error = remaprefs(&tmp, tmp, map, n); - if (error) - goto cleanup; - error = fz_arraypush(*newp, tmp); - fz_dropobj(tmp); - if (error) - goto cleanup; - } - } - - else if (fz_isdict(old)) - { - error = fz_newdict(newp, fz_dictlen(old)); - if (error) - return fz_rethrow(error, "cannot remap dictionary"); - for (i = 0; i < fz_dictlen(old); i++) - { - key = fz_dictgetkey(old, i); - tmp = fz_dictgetval(old, i); - error = remaprefs(&tmp, tmp, map, n); - if (error) - goto cleanup; - error = fz_dictput(*newp, key, tmp); - fz_dropobj(tmp); - if (error) - goto cleanup; - } - } - - else - { - *newp = fz_keepobj(old); - } - - return fz_okay; - -cleanup: - fz_dropobj(*newp); - return fz_rethrow(error, "cannot remap object"); -} - -/* - * Recursively copy objects from src to dst xref. - * Start with root object in src xref. - * Put the dst copy of root into newp. - */ -fz_error * -pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root) -{ - fz_error *error; - struct pair *map; - fz_obj *old, *new; - fz_buffer *stm; - int i, n; - - pdf_logxref("transplant {\n"); - - for (i = 0; i < src->len; i++) - src->table[i].mark = 0; - - error = sweepobj(src, root); - if (error) - return fz_rethrow(error, "cannot mark used objects"); - - for (n = 0, i = 0; i < src->len; i++) - if (src->table[i].mark) - n++; - - pdf_logxref("marked %d\n", n); - - map = fz_malloc(sizeof(struct pair) * n); - if (!map) - return fz_throw("outofmem: remapping table"); - - for (n = 0, i = 0; i < src->len; i++) - { - if (src->table[i].mark) - { - map[n].soid = i; - map[n].sgen = src->table[i].gen; - if (src->table[i].type == 'o') - map[n].sgen = 0; - error = pdf_allocobject(dst, &map[n].doid, &map[n].dgen); - if (error) - goto cleanup; - n++; - } - } - - error = remaprefs(newp, root, map, n); - if (error) - goto cleanup; - - for (i = 0; i < n; i++) - { - pdf_logxref("copyfrom %d %d to %d %d\n", - map[i].soid, map[i].sgen, - map[i].doid, map[i].dgen); - - error = pdf_loadobject(&old, src, map[i].soid, map[i].sgen); - if (error) - goto cleanup; - - if (pdf_isstream(src, map[i].soid, map[i].sgen)) - { - error = pdf_loadrawstream(&stm, src, map[i].soid, map[i].sgen); - if (error) - goto cleanup; - pdf_updatestream(dst, map[i].doid, map[i].dgen, stm); - fz_dropbuffer(stm); - } - - error = remaprefs(&new, old, map, n); - fz_dropobj(old); - if (error) - goto cleanup; - - error = pdf_updateobject(dst, map[i].doid, map[i].dgen, new); - fz_dropobj(new); - if (error) - goto cleanup; - } - - pdf_logxref("}\n"); - - fz_free(map); - return fz_okay; - -cleanup: - fz_free(map); - return fz_rethrow(error, "cannot transplant objects"); -} - diff --git a/mupdf/pdf_open.c b/mupdf/pdf_open.c index 0571e561..d6948c32 100644 --- a/mupdf/pdf_open.c +++ b/mupdf/pdf_open.c @@ -258,11 +258,9 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) { xref->table[i].ofs = 0; xref->table[i].gen = 0; - xref->table[i].type = 0; - xref->table[i].mark = 0; - xref->table[i].stmbuf = nil; xref->table[i].stmofs = 0; xref->table[i].obj = nil; + xref->table[i].type = 0; } xref->len = ofs + len; } @@ -701,11 +699,9 @@ pdf_loadxref(pdf_xref *xref, char *filename) { xref->table[i].ofs = 0; xref->table[i].gen = 0; - xref->table[i].type = 0; - xref->table[i].mark = 0; - xref->table[i].stmbuf = nil; xref->table[i].stmofs = 0; xref->table[i].obj = nil; + xref->table[i].type = 0; } error = readxrefsections(xref, xref->startxref, buf, sizeof buf); diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c index 65dd532c..995ca690 100644 --- a/mupdf/pdf_page.c +++ b/mupdf/pdf_page.c @@ -29,81 +29,67 @@ runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref) static fz_error * runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list) { - fz_error *error; - fz_stream *file; - fz_buffer *big; - fz_buffer *one; - fz_obj *stm; - int i; - - pdf_logpage("multiple content streams: %d\n", fz_arraylen(list)); - - error = fz_newbuffer(&big, 32 * 1024); - if (error) - return fz_rethrow(error, "cannot create content buffer"); - - error = fz_openwbuffer(&file, big); + fz_error *error; + fz_stream *file; + fz_buffer *big; + fz_buffer *one; + fz_obj *stm; + int i, n; + + pdf_logpage("multiple content streams: %d\n", fz_arraylen(list)); + + error = fz_newbuffer(&big, 32 * 1024); + if (error) + return fz_rethrow(error, "cannot create content buffer"); + + for (i = 0; i < fz_arraylen(list); i++) + { + stm = fz_arrayget(list, i); + error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm)); if (error) { - error = fz_rethrow(error, "cannot open content buffer (write)"); - goto cleanupbuf; + fz_dropbuffer(big); + return fz_rethrow(error, "cannot load content stream part %d/%d", i + 1, fz_arraylen(list)); } - 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) - { - error = fz_rethrow(error, "cannot load content stream part %d/%d", i + 1, fz_arraylen(list)); - goto cleanupstm; - } - - error = fz_write(file, one->rp, one->wp - one->rp); - if (error) - { - fz_dropbuffer(one); - error = fz_rethrow(error, "cannot write to content buffer"); - goto cleanupstm; - } + n = one->wp - one->rp; + while (big->wp + n + 1 > big->ep) + { + error = fz_growbuffer(big); + if (error) + { fz_dropbuffer(one); - - error = fz_printstr(file, " "); - if (error) - { - error = fz_rethrow(error, "cannot write to content buffer"); - goto cleanupstm; - } + fz_dropbuffer(big); + return fz_rethrow(error, "cannot load content stream part %d/%d", i + 1, fz_arraylen(list)); + } } - fz_dropstream(file); + memcpy(big->wp, one->rp, n); - error = fz_openrbuffer(&file, big); - if (error) - { - error = fz_rethrow(error, "cannot open content buffer (read)"); - goto cleanupbuf; - } + *big->wp++ = ' '; - error = pdf_runcsi(csi, xref, rdb, file); - if (error) - { - error = fz_rethrow(error, "cannot interpret content buffer"); - goto cleanupstm; - } + fz_dropbuffer(one); + } - fz_dropstream(file); + error = fz_openrbuffer(&file, big); + if (error) + { fz_dropbuffer(big); - return fz_okay; + return fz_rethrow(error, "cannot open content buffer (read)"); + } -cleanupstm: - fz_dropstream(file); -cleanupbuf: + error = pdf_runcsi(csi, xref, rdb, file); + if (error) + { fz_dropbuffer(big); - return error; /* already rethrown */ + fz_dropstream(file); + return fz_rethrow(error, "cannot interpret content buffer"); + } + + fz_dropstream(file); + fz_dropbuffer(big); + return fz_okay; } static fz_error * diff --git a/mupdf/pdf_repair.c b/mupdf/pdf_repair.c index b39bbe17..7735a838 100644 --- a/mupdf/pdf_repair.c +++ b/mupdf/pdf_repair.c @@ -279,20 +279,16 @@ pdf_repairxref(pdf_xref *xref, char *filename) } xref->table[0].type = 'f'; - xref->table[0].mark = 0; xref->table[0].ofs = 0; xref->table[0].gen = 65535; - xref->table[0].stmbuf = nil; xref->table[0].stmofs = 0; xref->table[0].obj = nil; for (i = 1; i < xref->len; i++) { xref->table[i].type = 'f'; - xref->table[i].mark = 0; xref->table[i].ofs = 0; xref->table[i].gen = 0; - xref->table[i].stmbuf = nil; xref->table[i].stmofs = 0; xref->table[i].obj = nil; } @@ -302,7 +298,6 @@ pdf_repairxref(pdf_xref *xref, char *filename) xref->table[list[i].oid].type = 'n'; xref->table[list[i].oid].ofs = list[i].ofs; xref->table[list[i].oid].gen = list[i].gen; - xref->table[list[i].oid].mark = 0; xref->table[list[i].oid].stmofs = list[i].stmofs; @@ -338,14 +333,7 @@ pdf_repairxref(pdf_xref *xref, char *filename) goto cleanup; } - error = pdf_updateobject(xref, list[i].oid, list[i].gen, dict); - if (error) - { - fz_dropobj(length); - fz_dropobj(dict); - error = fz_rethrow(error, "cannot update stream object"); - goto cleanup; - } + xref->table[list[i].oid].obj = fz_keepobj(dict); fz_dropobj(length); fz_dropobj(dict); diff --git a/mupdf/pdf_save.c b/mupdf/pdf_save.c deleted file mode 100644 index 2c1e84ae..00000000 --- a/mupdf/pdf_save.c +++ /dev/null @@ -1,335 +0,0 @@ -#include "fitz.h" -#include "mupdf.h" - -/* TODO: error check prints */ - -#define TIGHT 1 - -static fz_error * -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; - - fz_print(out, "stream\n"); - - if (encrypt) - { - error = pdf_cryptstream(&ef, encrypt, oid, gen); - if (error) - return fz_rethrow(error, "cannot create encryption filter"); - - error = fz_openwfilter(&dststm, ef, out); - fz_dropfilter(ef); - if (error) - return fz_rethrow(error, "cannot open encryption stream"); - } - else - { - dststm = fz_keepstream(out); - } - - error = pdf_openrawstream(&srcstm, xref, oid, gen); - if (error) - { - error = fz_rethrow(error, "cannot open raw stream"); - goto cleanupdst; - } - - while (1) - { - error = fz_read(&n, srcstm, buf, sizeof buf); - if (error) - { - error = fz_rethrow(error, "cannot read stream"); - goto cleanupsrc; - } - if (n == 0) - break; - - error = fz_write(dststm, buf, n); - if (error) - { - error = fz_rethrow(error, "cannot write stream"); - goto cleanupsrc; - } - } - - fz_dropstream(srcstm); - fz_dropstream(dststm); - - fz_print(out, "endstream\n"); - - return fz_okay; - -cleanupsrc: - fz_dropstream(srcstm); -cleanupdst: - fz_dropstream(dststm); - return error; /* already rethrown */ -} - -static fz_error * -writeobject(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen) -{ - pdf_xrefentry *x = xref->table + oid; - fz_error *error; - - error = pdf_cacheobject(xref, oid, gen); - if (error) - return fz_rethrow(error, "cannot load object"); - - if (encrypt) - pdf_cryptobj(encrypt, x->obj, oid, gen); - - fz_print(out, "%d %d obj\n", oid, gen); - fz_printobj(out, x->obj, TIGHT); - fz_print(out, "\n"); - - if (encrypt) - pdf_cryptobj(encrypt, x->obj, oid, gen); - - if (pdf_isstream(xref, oid, gen)) - { - error = writestream(out, xref, encrypt, oid, gen); - if (error) - return fz_rethrow(error, "cannot write stream"); - } - - fz_print(out, "endobj\n\n"); - - return fz_okay; -} - -static int countmodified(pdf_xref *xref, int oid) -{ - int i; - for (i = oid; i < xref->len; i++) - if (xref->table[i].type != 'a' && xref->table[i].type != 'd') - return i - oid; - return i - oid; -} - -fz_error * -pdf_updatexref(pdf_xref *xref, char *path) -{ - fz_error *error; - fz_stream *out; - int oid, gid; - int i, n; - int startxref; - fz_obj *obj; - - pdf_logxref("updatexref '%s' %p\n", path, xref); - - error = fz_openafile(&out, path); - if (error) - return fz_rethrow(error, "cannot open output file"); - - fz_print(out, "\n"); - - for (oid = 0; oid < xref->len; oid++) - { - gid = xref->table[oid].gen; - if (xref->table[oid].type == 'a') - { - xref->table[oid].ofs = fz_tell(out); - error = writeobject(out, xref, xref->crypt, oid, gid); - if (error) - { - fz_dropstream(out); - return fz_rethrow(error, "cannot write object (%d %d R)", oid, gid); - } - } - } - - /* always write out entry 0 in appended xref sections */ - xref->table[0].type = 'd'; - - startxref = fz_tell(out); - fz_print(out, "xref\n"); - - oid = 0; - while (oid < xref->len) - { - n = countmodified(xref, oid); - - pdf_logxref(" section %d +%d\n", oid, n); - - fz_print(out, "%d %d\n", oid, n); - - for (i = 0; i < n; i++) - { - if (xref->table[oid + i].type == 'd') - xref->table[oid + i].type = 'f'; - if (xref->table[oid + i].type == 'a') - xref->table[oid + i].type = 'n'; - - fz_print(out, "%010d %05d %c \n", - xref->table[oid + i].ofs, - xref->table[oid + i].gen, - xref->table[oid + i].type); - } - - oid += n; - while (oid < xref->len && - xref->table[oid].type != 'a' && - xref->table[oid].type != 'd') - oid ++; - } - - fz_print(out, "\n"); - - fz_print(out, "trailer\n<<\n /Size %d\n /Prev %d", xref->len, xref->startxref); - - obj = fz_dictgets(xref->trailer, "Root"); - fz_print(out,"\n /Root %d %d R", fz_tonum(obj), fz_togen(obj)); - - obj = fz_dictgets(xref->trailer, "Info"); - if (obj) - fz_print(out,"\n /Info %d %d R", fz_tonum(obj), fz_togen(obj)); - - obj = fz_dictgets(xref->trailer, "Encrypt"); - if (obj) { - fz_print(out,"\n /Encrypt "); - fz_printobj(out, obj, TIGHT); - } - - obj = fz_dictgets(xref->trailer, "ID"); - if (obj) { - fz_print(out,"\n /ID "); - fz_printobj(out, obj, TIGHT); - } - - fz_print(out, "\n>>\n\n"); - - fz_print(out, "startxref\n"); - fz_print(out, "%d\n", startxref); - fz_print(out, "%%%%EOF\n"); - - xref->startxref = startxref; - - /* TODO: check for write errors */ - - fz_dropstream(out); - return fz_okay; -} - -fz_error * -pdf_savexref(pdf_xref *xref, char *path, pdf_crypt *encrypt) -{ - fz_error *error; - fz_stream *out; - int oid, gid; - int startxref; - int *ofsbuf; - fz_obj *obj; - int eoid, egen; - - pdf_logxref("savexref '%s' %p\n", path, xref); - - /* need to add encryption object for acrobat < 6 */ - if (encrypt) - { - pdf_logxref("make encryption dict\n"); - - error = pdf_allocobject(xref, &eoid, &egen); - if (error) - return fz_rethrow(error, "cannot allocate encryption object"); - - pdf_cryptobj(encrypt, encrypt->encrypt, eoid, egen); - - error = pdf_updateobject(xref, eoid, egen, encrypt->encrypt); - if (error) - return fz_rethrow(error, "cannot update encryption object"); - } - - ofsbuf = fz_malloc(sizeof(int) * xref->len); - if (!ofsbuf) - return fz_throw("outofmem: offset buffer"); - - error = fz_openwfile(&out, path); - if (error) - { - fz_free(ofsbuf); - return fz_rethrow(error, "cannot open output file"); - } - - fz_print(out, "%%PDF-%d.%d\n", xref->version / 10, xref->version % 10); - fz_print(out, "%%\342\343\317\323\n\n"); - - for (oid = 0; oid < xref->len; oid++) - { - pdf_xrefentry *x = xref->table + oid; - if (x->type == 'n' || x->type == 'o' || x->type == 'a') - { - ofsbuf[oid] = fz_tell(out); - gid = x->type == 'o' ? 0 : x->gen; - error = writeobject(out, xref, encrypt, oid, gid); - if (error) - { - if (ofsbuf) fz_free(ofsbuf); - fz_dropstream(out); - return fz_rethrow(error, "cannot write object (%d %d R)", oid, gid); - } - } - else - { - ofsbuf[oid] = x->ofs; - } - } - - startxref = fz_tell(out); - fz_print(out, "xref\n"); - fz_print(out, "0 %d\n", xref->len); - - for (oid = 0; oid < xref->len; oid++) - { - int gen = xref->table[oid].gen; - int type = xref->table[oid].type; - if (type == 'o') - gen = 0; - if (type == 'a' || type == 'o') - type = 'n'; - if (type == 'd') - type = 'f'; - fz_print(out, "%010d %05d %c \n", ofsbuf[oid], gen, type); - } - - fz_print(out, "\n"); - - fz_print(out, "trailer\n<<\n /Size %d", xref->len); - obj = fz_dictgets(xref->trailer, "Root"); - fz_print(out, "\n /Root %d %d R", fz_tonum(obj), fz_togen(obj)); - obj = fz_dictgets(xref->trailer, "Info"); - if (obj) - fz_print(out, "\n /Info %d %d R", fz_tonum(obj), fz_togen(obj)); - if (encrypt) - { - fz_print(out, "\n /Encrypt %d %d R", eoid, egen); - fz_print(out, "\n /ID ["); - fz_printobj(out, encrypt->id, 1); - fz_printobj(out, encrypt->id, 1); - fz_print(out, "]"); - - pdf_cryptobj(encrypt, encrypt->encrypt, eoid, egen); - } - fz_print(out, "\n>>\n\n"); - - fz_print(out, "startxref\n"); - fz_print(out, "%d\n", startxref); - fz_print(out, "%%%%EOF\n"); - - xref->startxref = startxref; - - /* TODO: check for write errors */ - - if(ofsbuf) fz_free(ofsbuf); - fz_dropstream(out); - return fz_okay; -} - diff --git a/mupdf/pdf_stream.c b/mupdf/pdf_stream.c index 3bd6df76..8e7be301 100644 --- a/mupdf/pdf_stream.c +++ b/mupdf/pdf_stream.c @@ -20,7 +20,7 @@ pdf_isstream(pdf_xref *xref, int oid, int gen) return 0; } - return xref->table[oid].stmbuf || xref->table[oid].stmofs; + return xref->table[oid].stmofs > 0; } /* @@ -370,14 +370,6 @@ pdf_openrawstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) if (error) return fz_rethrow(error, "cannot load stream object (%d %d R)", oid, gen); - if (x->stmbuf) - { - error = fz_openrbuffer(stmp, x->stmbuf); - if (error) - return fz_rethrow(error, "cannot open stream from buffer"); - return fz_okay; - } - if (x->stmofs) { error = buildrawfilter(&filter, xref, x->obj, oid, gen); @@ -414,7 +406,6 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) { pdf_xrefentry *x; fz_error *error; - fz_stream *rawstm; fz_filter *filter; if (oid < 0 || oid >= xref->len) @@ -426,27 +417,6 @@ pdf_openstream(fz_stream **stmp, pdf_xref *xref, int oid, int gen) if (error) return fz_rethrow(error, "cannot load stream object (%d %d R)", oid, gen); - if (x->stmbuf) - { - error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); - if (error) - return fz_rethrow(error, "cannot create filter"); - - error = fz_openrbuffer(&rawstm, x->stmbuf); - if (error) - { - fz_dropfilter(filter); - return fz_rethrow(error, "cannot open stream from buffer"); - } - - error = fz_openrfilter(stmp, filter, rawstm); - fz_dropfilter(filter); - fz_dropstream(rawstm); - if (error) - return fz_rethrow(error, "cannot open filter stream"); - return fz_okay; - } - if (x->stmofs) { error = pdf_buildfilter(&filter, xref, x->obj, oid, gen); diff --git a/mupdf/pdf_xref.c b/mupdf/pdf_xref.c index a2ad01ca..cba476e9 100644 --- a/mupdf/pdf_xref.c +++ b/mupdf/pdf_xref.c @@ -85,10 +85,8 @@ pdf_initxref(pdf_xref *xref) xref->crypt = nil; xref->table[0].type = 'f'; - xref->table[0].mark = 0; xref->table[0].ofs = 0; xref->table[0].gen = 65535; - xref->table[0].stmbuf = nil; xref->table[0].stmofs = 0; xref->table[0].obj = nil; @@ -106,11 +104,6 @@ pdf_flushxref(pdf_xref *xref, int force) { if (force) { - if (xref->table[i].stmbuf) - { - fz_dropbuffer(xref->table[i].stmbuf); - xref->table[i].stmbuf = nil; - } if (xref->table[i].obj) { fz_dropobj(xref->table[i].obj); @@ -119,11 +112,6 @@ pdf_flushxref(pdf_xref *xref, int force) } else { - if (xref->table[i].stmbuf && xref->table[i].stmbuf->refs == 1) - { - fz_dropbuffer(xref->table[i].stmbuf); - xref->table[i].stmbuf = nil; - } if (xref->table[i].obj && xref->table[i].obj->refs == 1) { fz_dropobj(xref->table[i].obj); @@ -140,13 +128,12 @@ pdf_debugxref(pdf_xref *xref) printf("xref\n0 %d\n", xref->len); for (i = 0; i < xref->len; i++) { - printf("%010d %05d %c | %d %c%c\n", + printf("%010d %05d %c (ref=%d, ofs=%d)\n", xref->table[i].ofs, xref->table[i].gen, xref->table[i].type, xref->table[i].obj ? xref->table[i].obj->refs : 0, - xref->table[i].stmofs ? 'f' : '-', - xref->table[i].stmbuf ? 'b' : '-'); + xref->table[i].stmofs); } } @@ -191,184 +178,6 @@ pdf_decryptxref(pdf_xref *xref) } /* - * mutate objects - */ - -static int findprev(pdf_xref *xref, int oid) -{ - int prev; - for (prev = oid - 1; prev >= 0; prev--) - if (xref->table[prev].type == 'f' || xref->table[prev].type == 'd') - return prev; - return 0; -} - -static int findnext(pdf_xref *xref, int oid) -{ - int next; - for (next = oid + 1; next < xref->len; next++) - if (xref->table[next].type == 'f' || xref->table[next].type == 'd') - return next; - return 0; -} - -fz_error * -pdf_allocobject(pdf_xref *xref, int *oidp, int *genp) -{ - pdf_xrefentry *x; - int prev, next; - int oid = 0; - - pdf_logxref("allocobj"); - - while (1) - { - x = xref->table + oid; - - if (x->type == 'f' || x->type == 'd') - { - if (x->gen < 65535) - { - *oidp = oid; - *genp = x->gen; - - pdf_logxref(" reuse %d %d\n", *oidp, *genp); - - x->type = 'a'; - x->ofs = 0; - - prev = findprev(xref, oid); - next = findnext(xref, oid); - xref->table[prev].type = 'd'; - xref->table[prev].ofs = next; - - return fz_okay; - } - } - - oid = x->ofs; - - if (oid == 0) - break; - } - - if (xref->len + 1 >= xref->cap) - { - int newcap = xref->cap + 256; - pdf_xrefentry *newtable; - - newtable = fz_realloc(xref->table, sizeof(pdf_xrefentry) * newcap); - if (!newtable) - return fz_throw("outofmem: xref table resize"); - - xref->table = newtable; - xref->cap = newcap; - } - - oid = xref->len ++; - - xref->table[oid].type = 'a'; - xref->table[oid].mark = 0; - xref->table[oid].ofs = 0; - xref->table[oid].gen = 0; - xref->table[oid].stmbuf = nil; - xref->table[oid].stmofs = 0; - xref->table[oid].obj = nil; - - *oidp = oid; - *genp = 0; - - pdf_logxref(" %d %d\n", *oidp, *genp); - - prev = findprev(xref, oid); - next = findnext(xref, oid); - xref->table[prev].type = 'd'; - xref->table[prev].ofs = next; - - return fz_okay; -} - -fz_error * -pdf_deleteobject(pdf_xref *xref, int oid, int gen) -{ - pdf_xrefentry *x; - int prev; - - if (oid < 0 || oid >= xref->len) - return fz_throw("assert: object out of range (%d %d R)", oid, gen); - - pdf_logxref("deleteobj %d %d\n", oid, gen); - - x = xref->table + oid; - - x->type = 'd'; - x->ofs = findnext(xref, oid); - x->gen ++; - - if (x->stmbuf) - fz_dropbuffer(x->stmbuf); - x->stmbuf = nil; - - if (x->obj) - fz_dropobj(x->obj); - x->obj = nil; - - prev = findprev(xref, oid); - xref->table[prev].type = 'd'; - xref->table[prev].ofs = oid; - - return fz_okay; -} - -fz_error * -pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj) -{ - pdf_xrefentry *x; - - if (oid < 0 || oid >= xref->len) - return fz_throw("assert: object out of range (%d %d R)", oid, gen); - - pdf_logxref("updateobj %d %d (%p)\n", oid, gen, obj); - - x = xref->table + oid; - - if (x->obj) - fz_dropobj(x->obj); - x->obj = fz_keepobj(obj); - - if (x->type == 'f' || x->type == 'd') - { - int prev = findprev(xref, oid); - int next = findnext(xref, oid); - xref->table[prev].type = 'd'; - xref->table[prev].ofs = next; - } - - x->type = 'a'; - - return fz_okay; -} - -fz_error * -pdf_updatestream(pdf_xref *xref, int oid, int gen, fz_buffer *stm) -{ - pdf_xrefentry *x; - - if (oid < 0 || oid >= xref->len) - return fz_throw("assert: object out of range (%d %d R)", oid, gen); - - pdf_logxref("updatestm %d %d (%p)\n", oid, gen, stm); - - x = xref->table + oid; - - if (x->stmbuf) - fz_dropbuffer(x->stmbuf); - x->stmbuf = fz_keepbuffer(stm); - - return fz_okay; -} - -/* * object loading */ |