diff options
-rw-r--r-- | include/mupdf/fitz/context.h | 6 | ||||
-rw-r--r-- | include/mupdf/fitz/document.h | 23 | ||||
-rw-r--r-- | include/mupdf/fitz/system.h | 2 | ||||
-rw-r--r-- | include/mupdf/pdf/document.h | 2 | ||||
-rw-r--r-- | platform/win32/libmupdf.vcproj | 8 | ||||
-rw-r--r-- | platform/x11/pdfapp.c | 2 | ||||
-rw-r--r-- | scripts/cmapdump.c | 13 | ||||
-rw-r--r-- | source/cbz/mucbz.c | 23 | ||||
-rw-r--r-- | source/fitz/context.c | 4 | ||||
-rw-r--r-- | source/fitz/document-all.c | 9 | ||||
-rw-r--r-- | source/fitz/document-no-run.c | 9 | ||||
-rw-r--r-- | source/fitz/document.c | 163 | ||||
-rw-r--r-- | source/img/muimage.c | 31 | ||||
-rw-r--r-- | source/pdf/pdf-xref-aux.c | 7 | ||||
-rw-r--r-- | source/pdf/pdf-xref.c | 24 | ||||
-rw-r--r-- | source/tools/mudraw.c | 2 | ||||
-rw-r--r-- | source/xps/xps-doc.c | 25 |
17 files changed, 296 insertions, 57 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h index bb171b3f..c6adbb3f 100644 --- a/include/mupdf/fitz/context.h +++ b/include/mupdf/fitz/context.h @@ -18,6 +18,7 @@ typedef struct fz_aa_context_s fz_aa_context; typedef struct fz_locks_context_s fz_locks_context; typedef struct fz_store_s fz_store; typedef struct fz_glyph_cache_s fz_glyph_cache; +typedef struct fz_document_handler_context_s fz_document_handler_context; typedef struct fz_context_s fz_context; struct fz_alloc_context_s @@ -107,6 +108,7 @@ struct fz_context_s fz_aa_context *aa; fz_store *store; fz_glyph_cache *glyph_cache; + fz_document_handler_context *handler; }; /* @@ -416,6 +418,10 @@ void fz_new_aa_context(fz_context *ctx); void fz_free_aa_context(fz_context *ctx); void fz_copy_aa_context(fz_context *dst, fz_context *src); +void fz_new_document_handler_context(fz_context *ctx); +void fz_drop_document_handler_context(fz_context *ctx); +fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx); + /* Default allocator */ extern fz_alloc_context fz_alloc_default; diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h index 887ca151..cda8870a 100644 --- a/include/mupdf/fitz/document.h +++ b/include/mupdf/fitz/document.h @@ -13,6 +13,7 @@ Document interface */ typedef struct fz_document_s fz_document; +typedef struct fz_document_handler_s fz_document_handler; typedef struct fz_page_s fz_page; typedef struct fz_annot_s fz_annot; @@ -60,6 +61,28 @@ struct fz_document_s fz_document_rebind_fn *rebind; }; +typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const char *filename); +typedef fz_document *(fz_document_open_with_stream_fn)(fz_context *ctx, fz_stream *stream); +typedef int (fz_document_recognize_fn)(fz_context *ctx, const char *magic); + +struct fz_document_handler_s +{ + fz_document_recognize_fn *recognize; + fz_document_open_fn *open; + fz_document_open_with_stream_fn *open_with_stream; +}; + +extern fz_document_handler pdf_document_handler; +extern fz_document_handler pdf_no_run_document_handler; +extern fz_document_handler xps_document_handler; +extern fz_document_handler cbz_document_handler; +extern fz_document_handler img_document_handler; + +void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler); + +void fz_register_document_handlers(fz_context *ctx); +void fz_register_no_run_document_handlers(fz_context *ctx); + /* fz_open_document: Open a PDF, XPS or CBZ document. diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h index 1decfda6..2f4868f2 100644 --- a/include/mupdf/fitz/system.h +++ b/include/mupdf/fitz/system.h @@ -355,4 +355,6 @@ static inline float my_atan2f(float o, float a) #define atan2f(x,y) my_atan2f((x),(y)) #endif +int fz_strcasecmp(const char *a, const char *b); + #endif diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index 73b3692d..8c71d88b 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -308,4 +308,6 @@ fz_device *pdf_page_write(pdf_document *doc, pdf_page *page); void pdf_finish_edit(pdf_document *doc); +int pdf_recognize(fz_context *doc, const char *magic); + #endif diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj index 74f6df79..e8dc6fc6 100644 --- a/platform/win32/libmupdf.vcproj +++ b/platform/win32/libmupdf.vcproj @@ -434,6 +434,10 @@ > </File> <File + RelativePath="..\..\source\fitz\document-all.c" + > + </File> + <File RelativePath="..\..\source\fitz\document.c" > </File> @@ -989,6 +993,10 @@ > </File> <File + RelativePath="..\..\source\fitz\document-no-run.c" + > + </File> + <File RelativePath="..\..\include\mupdf\fitz\document.h" > </File> diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 10a44573..e9349526 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -192,6 +192,8 @@ void pdfapp_open_progressive(pdfapp_t *app, char *filename, int reload, int bps) { pdf_document *idoc; + fz_register_document_handlers(ctx); + #ifdef HAVE_CURL if (!strncmp(filename, "http://", 7)) { diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c index 88f1f800..a9e5de18 100644 --- a/scripts/cmapdump.c +++ b/scripts/cmapdump.c @@ -246,3 +246,16 @@ fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx) { return NULL; } + +void fz_new_document_handler_context(fz_context *ctx) +{ +} + +void fz_drop_document_handler_context(fz_context *ctx) +{ +} + +fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx) +{ + return NULL; +} diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c index fa654a54..dc36e0be 100644 --- a/source/cbz/mucbz.c +++ b/source/cbz/mucbz.c @@ -430,3 +430,26 @@ cbz_init_document(cbz_document *doc) doc->super.meta = (fz_document_meta_fn *)cbz_meta; doc->super.rebind = (fz_document_rebind_fn *)cbz_rebind; } + +static int +cbz_recognize(fz_context *doc, const char *magic) +{ + char *ext = strrchr(magic, '.'); + + if (ext) + { + if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) + return 100; + } + if (!strcmp(magic, "cbz") || !strcmp(magic, "application/x-cbz")) + return 100; + + return 0; +} + +fz_document_handler cbz_document_handler = +{ + (fz_document_recognize_fn *)&cbz_recognize, + (fz_document_open_fn *)&cbz_open_document, + (fz_document_open_with_stream_fn *)&cbz_open_document_with_stream +}; diff --git a/source/fitz/context.c b/source/fitz/context.c index 72ea2d6a..d54e5b7d 100644 --- a/source/fitz/context.c +++ b/source/fitz/context.c @@ -49,6 +49,7 @@ fz_free_context(fz_context *ctx) return; /* Other finalisation calls go here (in reverse order) */ + fz_drop_document_handler_context(ctx); fz_drop_glyph_cache_context(ctx); fz_drop_store_context(ctx); fz_free_aa_context(ctx); @@ -149,6 +150,7 @@ fz_new_context_imp(fz_alloc_context *alloc, fz_locks_context *locks, unsigned in fz_new_colorspace_context(ctx); fz_new_font_context(ctx); fz_new_id_context(ctx); + fz_new_document_handler_context(ctx); } fz_catch(ctx) { @@ -195,6 +197,8 @@ fz_clone_context_internal(fz_context *ctx) new_ctx->font = fz_keep_font_context(new_ctx); new_ctx->id = ctx->id; new_ctx->id = fz_keep_id_context(new_ctx); + new_ctx->handler = ctx->handler; + new_ctx->handler = fz_keep_document_handler_context(new_ctx); return new_ctx; } diff --git a/source/fitz/document-all.c b/source/fitz/document-all.c new file mode 100644 index 00000000..92b1c037 --- /dev/null +++ b/source/fitz/document-all.c @@ -0,0 +1,9 @@ +#include "mupdf/fitz.h" + +void fz_register_document_handlers(fz_context *ctx) +{ + fz_register_document_handler(ctx, &pdf_document_handler); + fz_register_document_handler(ctx, &xps_document_handler); + fz_register_document_handler(ctx, &cbz_document_handler); + fz_register_document_handler(ctx, &img_document_handler); +} diff --git a/source/fitz/document-no-run.c b/source/fitz/document-no-run.c new file mode 100644 index 00000000..b0defe91 --- /dev/null +++ b/source/fitz/document-no-run.c @@ -0,0 +1,9 @@ +#include "mupdf/fitz.h" + +void fz_register_no_run_document_handlers(fz_context *ctx) +{ + fz_register_document_handler(ctx, &pdf_no_run_document_handler); + fz_register_document_handler(ctx, &xps_document_handler); + fz_register_document_handler(ctx, &cbz_document_handler); + fz_register_document_handler(ctx, &img_document_handler); +} diff --git a/source/fitz/document.c b/source/fitz/document.c index a86c2f6e..d4838d0c 100644 --- a/source/fitz/document.c +++ b/source/fitz/document.c @@ -1,17 +1,66 @@ #include "mupdf/fitz.h" -/* Yuck! Promiscuous we are. */ -extern struct pdf_document *pdf_open_document(fz_context *ctx, const char *filename); -extern struct xps_document *xps_open_document(fz_context *ctx, const char *filename); -extern struct cbz_document *cbz_open_document(fz_context *ctx, const char *filename); -extern struct image_document *image_open_document(fz_context *ctx, const char *filename); +extern int pdf_js_supported(void); -extern struct pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file); -extern struct xps_document *xps_open_document_with_stream(fz_context *ctx, fz_stream *file); -extern struct cbz_document *cbz_open_document_with_stream(fz_context *ctx, fz_stream *file); -extern struct image_document *image_open_document_with_stream(fz_context *ctx, fz_stream *file); +enum +{ + FZ_DOCUMENT_HANDLER_MAX = 10 +}; -extern int pdf_js_supported(void); +struct fz_document_handler_context_s +{ + int refs; + int count; + const fz_document_handler *handler[FZ_DOCUMENT_HANDLER_MAX]; +}; + +void fz_new_document_handler_context(fz_context *ctx) +{ + ctx->handler = fz_malloc_struct(ctx, fz_document_handler_context); + ctx->handler->refs = 1; +} + +fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx) +{ + if (!ctx || !ctx->handler) + return NULL; + ctx->handler->refs++; + return ctx->handler; +} + +void fz_drop_document_handler_context(fz_context *ctx) +{ + if (!ctx || !ctx->handler) + return; + + if (--ctx->handler->refs != 0) + return; + + fz_free(ctx, ctx->handler); + ctx->handler = NULL; +} + +void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler) +{ + fz_document_handler_context *dc; + int i; + + if (!ctx || !handler) + return; + + dc = ctx->handler; + if (dc == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "Document handler list not found"); + + for (i = 0; i < dc->count; i++) + if (dc->handler[i] == handler) + return; + + if (dc->count >= FZ_DOCUMENT_HANDLER_MAX) + fz_throw(ctx, FZ_ERROR_GENERIC, "Too many document handlers"); + + dc->handler[dc->count++] = handler; +} static inline int fz_tolower(int c) { @@ -20,7 +69,7 @@ static inline int fz_tolower(int c) return c; } -static inline int fz_strcasecmp(const char *a, const char *b) +int fz_strcasecmp(const char *a, const char *b) { while (fz_tolower(*a) == fz_tolower(*b)) { @@ -34,65 +83,65 @@ static inline int fz_strcasecmp(const char *a, const char *b) fz_document * fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream) { - char *ext = strrchr(magic, '.'); + int i, score; + int best_i, best_score; + fz_document_handler_context *dc; - if (ext) + if (ctx == NULL || magic == NULL || stream == NULL) + return NULL; + + dc = ctx->handler; + if (dc->count == 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "No document handlers registered"); + + best_i = -1; + best_score = 0; + for (i = 0; i < dc->count; i++) { - if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels") || !fz_strcasecmp(ext, ".oxps")) - return (fz_document*) xps_open_document_with_stream(ctx, stream); - if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) - return (fz_document*) cbz_open_document_with_stream(ctx, stream); - if (!fz_strcasecmp(ext, ".pdf")) - return (fz_document*) pdf_open_document_with_stream(ctx, stream); - if (!fz_strcasecmp(ext, ".png") || !fz_strcasecmp(ext, ".jpg") || - !fz_strcasecmp(ext, ".jpeg") || !fz_strcasecmp(ext, ".jfif") || - !fz_strcasecmp(ext, ".jfif-tbnl") || !fz_strcasecmp(ext, ".jpe") || - !fz_strcasecmp(ext, ".tif") || !fz_strcasecmp(ext, ".tiff")) - return (fz_document*) image_open_document_with_stream(ctx, stream); + score = dc->handler[i]->recognize(ctx, magic); + if (best_score < score) + { + best_score = score; + best_i = i; + } } - if (!strcmp(magic, "cbz") || !strcmp(magic, "application/x-cbz")) - return (fz_document*) cbz_open_document_with_stream(ctx, stream); - if (!strcmp(magic, "xps") || !strcmp(magic, "oxps") || - !strcmp(magic, "application/vnd.ms-xpsdocument") || - !strcmp(magic, "application/oxps")) - return (fz_document*) xps_open_document_with_stream(ctx, stream); - if (!strcmp(magic, "pdf") || !strcmp(magic, "application/pdf")) - return (fz_document*) pdf_open_document_with_stream(ctx, stream); - if (!strcmp(magic, "png") || !strcmp(magic, "image/png") || - !strcmp(magic, "jpg") || !strcmp(magic, "image/jpeg") || - !strcmp(magic, "jpeg") || !strcmp(magic, "image/pjpeg") || - !strcmp(magic, "jpe") || !strcmp(magic, "jfif") || - !strcmp(magic, "tif") || !strcmp(magic, "image/tiff") || - !strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff")) - return (fz_document*) image_open_document_with_stream(ctx, stream); - - /* last guess: pdf */ - return (fz_document*) pdf_open_document_with_stream(ctx, stream); + if (best_i >= 0) + return dc->handler[best_i]->open_with_stream(ctx, stream); + + return NULL; } fz_document * fz_open_document(fz_context *ctx, const char *filename) { - char *ext = strrchr(filename, '.'); + int i, score; + int best_i, best_score; + fz_document_handler_context *dc; + + if (ctx == NULL || filename == NULL) + return NULL; + + dc = ctx->handler; + if (dc->count == 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "No document handlers registered"); - if (ext) + best_i = -1; + best_score = 0; + for (i = 0; i < dc->count; i++) { - if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels") || !fz_strcasecmp(ext, ".oxps")) - return (fz_document*) xps_open_document(ctx, filename); - if (!fz_strcasecmp(ext, ".cbz") || !fz_strcasecmp(ext, ".zip")) - return (fz_document*) cbz_open_document(ctx, filename); - if (!fz_strcasecmp(ext, ".pdf")) - return (fz_document*) pdf_open_document(ctx, filename); - if (!fz_strcasecmp(ext, ".png") || !fz_strcasecmp(ext, ".jpg") || - !fz_strcasecmp(ext, ".jpeg") || !fz_strcasecmp(ext, ".jpe") || - !fz_strcasecmp(ext, ".jfif") || !fz_strcasecmp(ext, ".jfif-tbnl") || - !fz_strcasecmp(ext, ".tif") || !fz_strcasecmp(ext, ".tiff")) - return (fz_document*) image_open_document(ctx, filename); + score = dc->handler[i]->recognize(ctx, filename); + if (best_score < score) + { + best_score = score; + best_i = i; + } } - /* last guess: pdf */ - return (fz_document*) pdf_open_document(ctx, filename); + if (best_i >= 0) + return dc->handler[best_i]->open(ctx, filename); + + return NULL; } void diff --git a/source/img/muimage.c b/source/img/muimage.c index 26f4a0f3..300d6603 100644 --- a/source/img/muimage.c +++ b/source/img/muimage.c @@ -154,3 +154,34 @@ image_init_document(image_document *doc) doc->super.meta = (fz_document_meta_fn *)image_meta; doc->super.rebind = (fz_document_rebind_fn *)image_rebind; } + +static int +image_recognize(fz_context *doc, const char *magic) +{ + char *ext = strrchr(magic, '.'); + + if (ext) + { + if (!fz_strcasecmp(ext, ".png") || !fz_strcasecmp(ext, ".jpg") || + !fz_strcasecmp(ext, ".jpeg") || !fz_strcasecmp(ext, ".jfif") || + !fz_strcasecmp(ext, ".jfif-tbnl") || !fz_strcasecmp(ext, ".jpe") || + !fz_strcasecmp(ext, ".tif") || !fz_strcasecmp(ext, ".tiff")) + return 100; + } + if (!strcmp(magic, "png") || !strcmp(magic, "image/png") || + !strcmp(magic, "jpg") || !strcmp(magic, "image/jpeg") || + !strcmp(magic, "jpeg") || !strcmp(magic, "image/pjpeg") || + !strcmp(magic, "jpe") || !strcmp(magic, "jfif") || + !strcmp(magic, "tif") || !strcmp(magic, "image/tiff") || + !strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff")) + return 100; + + return 0; +} + +fz_document_handler img_document_handler = +{ + (fz_document_recognize_fn *)&image_recognize, + (fz_document_open_fn *)&image_open_document, + (fz_document_open_with_stream_fn *)&image_open_document_with_stream +}; diff --git a/source/pdf/pdf-xref-aux.c b/source/pdf/pdf-xref-aux.c index 968a8f9f..aac323de 100644 --- a/source/pdf/pdf-xref-aux.c +++ b/source/pdf/pdf-xref-aux.c @@ -27,3 +27,10 @@ pdf_open_document(fz_context *ctx, const char *filename) doc->update_appearance = pdf_update_appearance; return doc; } + +fz_document_handler pdf_document_handler = +{ + (fz_document_recognize_fn *)&pdf_recognize, + (fz_document_open_fn *)&pdf_open_document, + (fz_document_open_with_stream_fn *)&pdf_open_document_with_stream +}; diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index d7c5cd1b..2afe4de8 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -1,4 +1,5 @@ #include "mupdf/pdf.h" +#include "mupdf/fitz/document.h" #undef DEBUG_PROGESSIVE_ADVANCE @@ -2417,3 +2418,26 @@ pdf_document *pdf_create_document(fz_context *ctx) } return doc; } + +int +pdf_recognize(fz_context *doc, const char *magic) +{ + char *ext = strrchr(magic, '.'); + + if (ext) + { + if (!fz_strcasecmp(ext, ".pdf")) + return 100; + } + if (!strcmp(magic, "pdf") || !strcmp(magic, "application/pdf")) + return 100; + + return 1; +} + +fz_document_handler pdf_no_run_document_handler = +{ + (fz_document_recognize_fn *)&pdf_recognize, + (fz_document_open_fn *)&pdf_open_document_no_run, + (fz_document_open_with_stream_fn *)&pdf_open_document_no_run_with_stream +}; diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 682aab86..914f6ba5 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -1193,6 +1193,8 @@ int main(int argc, char **argv) fz_try(ctx) { + fz_register_document_handlers(ctx); + while (fz_optind < argc) { fz_try(ctx) diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c index 86d67d4a..af5bfe5a 100644 --- a/source/xps/xps-doc.c +++ b/source/xps/xps-doc.c @@ -531,3 +531,28 @@ xps_free_page(xps_document *doc, xps_page *page) fz_free_xml(doc->ctx, page->root); page->root = NULL; } + +static int +xps_recognize(fz_context *doc, const char *magic) +{ + char *ext = strrchr(magic, '.'); + + if (ext) + { + if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels") || !fz_strcasecmp(ext, ".oxps")) + return 100; + } + if (!strcmp(magic, "xps") || !strcmp(magic, "oxps") || + !strcmp(magic, "application/vnd.ms-xpsdocument") || + !strcmp(magic, "application/oxps")) + return 100; + + return 0; +} + +fz_document_handler xps_document_handler = +{ + (fz_document_recognize_fn *)&xps_recognize, + (fz_document_open_fn *)&xps_open_document, + (fz_document_open_with_stream_fn *)&xps_open_document_with_stream +}; |