diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-01-03 16:50:41 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-01-07 10:25:42 +0000 |
commit | 7f009acebb75ff88c1ee934b03fa2d15f7785b32 (patch) | |
tree | 7be547523d730d104c62e4b5d43685dd8bb5bd40 /source/fitz | |
parent | 016adfa063293281a0896c62bf22e406b09ddf21 (diff) | |
download | mupdf-7f009acebb75ff88c1ee934b03fa2d15f7785b32.tar.xz |
Introduce 'document handlers'.
We define a document handler for each file type (2 in the case of PDF, one
to handle files with the ability to 'run' them, and one without).
We then register these handlers with the context at startup, and then
call fz_open_document... as usual. This enables people to select the
document types they want at will (and even to extend the library with more
document types should they wish).
Diffstat (limited to 'source/fitz')
-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 |
4 files changed, 128 insertions, 57 deletions
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 |