diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2017-03-28 20:14:53 +0800 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2017-04-13 14:13:31 +0200 |
commit | 0cd7f2e8397e2caf47f3d46ef635358fa0ba194c (patch) | |
tree | 74dd47522cbcd34873121bed2520834613ae9957 /source/fitz | |
parent | 48be72fb64202cb52d5ebe3a4c931aa925276b6d (diff) | |
download | mupdf-0cd7f2e8397e2caf47f3d46ef635358fa0ba194c.tar.xz |
Move extension/mimetype detection to common function.
A document handler normally only exposes a list of extensions and
mimetypes. Only formats that use some kind of extra detection mechnism
need to supply a recognize() callback, such as xps that can handle
.xps-files unpacked into a directory.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/document.c | 97 |
1 files changed, 61 insertions, 36 deletions
diff --git a/source/fitz/document.c b/source/fitz/document.c index 8bf8d348..8f3163c4 100644 --- a/source/fitz/document.c +++ b/source/fitz/document.c @@ -63,25 +63,51 @@ void fz_register_document_handler(fz_context *ctx, const fz_document_handler *ha dc->handler[dc->count++] = handler; } -fz_document * -fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream) +static const fz_document_handler * +fz_recognize_document(fz_context *ctx, const char *magic) { - int i, score; - int best_i, best_score; fz_document_handler_context *dc; - - if (magic == NULL || stream == NULL) - fz_throw(ctx, FZ_ERROR_GENERIC, "no document to open"); + int i, best_score, best_i; + const char *ext, *needle; dc = ctx->handler; if (dc->count == 0) fz_throw(ctx, FZ_ERROR_GENERIC, "No document handlers registered"); - best_i = -1; + ext = strrchr(magic, '.'); + if (ext) + needle = ext + 1; + else + needle = magic; + best_score = 0; + best_i = -1; + for (i = 0; i < dc->count; i++) { - score = dc->handler[i]->recognize(ctx, magic); + int score = 0; + const char **entry; + + if (dc->handler[i]->recognize) + score = dc->handler[i]->recognize(ctx, magic); + + if (!ext) + { + for (entry = &dc->handler[i]->mimetypes[0]; *entry; entry++) + if (!fz_strcasecmp(needle, *entry) && score < 100) + { + score = 100; + break; + } + } + + for (entry = &dc->handler[i]->extensions[0]; *entry; entry++) + if (!fz_strcasecmp(needle, *entry) && score < 100) + { + score = 100; + break; + } + if (best_score < score) { best_score = score; @@ -89,50 +115,49 @@ fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stre } } - if (best_i >= 0) - return dc->handler[best_i]->open_with_stream(ctx, stream); + if (best_i < 0) + return NULL; - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find document handler for file type: %s", magic); + return dc->handler[best_i]; +} + + +fz_document * +fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream) +{ + const fz_document_handler *handler; + + if (magic == NULL || stream == NULL) + fz_throw(ctx, FZ_ERROR_GENERIC, "no document to open"); + + handler = fz_recognize_document(ctx, magic); + if (!handler) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find document handler for file type: %s", magic); + + return handler->open_with_stream(ctx, stream); } fz_document * fz_open_document(fz_context *ctx, const char *filename) { - int i, score; - int best_i, best_score; - fz_document_handler_context *dc; + const fz_document_handler *handler; fz_stream *file; fz_document *doc; if (filename == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "no document to open"); - 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++) - { - score = dc->handler[i]->recognize(ctx, filename); - if (best_score < score) - { - best_score = score; - best_i = i; - } - } - - if (best_i < 0) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find document handler for file: '%s'", filename); + handler = fz_recognize_document(ctx, filename); + if (!handler) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find document handler for file: %s", filename); - if (dc->handler[best_i]->open) - return dc->handler[best_i]->open(ctx, filename); + if (handler->open) + return handler->open(ctx, filename); file = fz_open_file(ctx, filename); fz_try(ctx) - doc = dc->handler[best_i]->open_with_stream(ctx, file); + doc = handler->open_with_stream(ctx, file); fz_always(ctx) fz_drop_stream(ctx, file); fz_catch(ctx) |