summaryrefslogtreecommitdiff
path: root/source/fitz/document.c
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2017-03-28 20:14:53 +0800
committerTor Andersson <tor.andersson@artifex.com>2017-04-13 14:13:31 +0200
commit0cd7f2e8397e2caf47f3d46ef635358fa0ba194c (patch)
tree74dd47522cbcd34873121bed2520834613ae9957 /source/fitz/document.c
parent48be72fb64202cb52d5ebe3a4c931aa925276b6d (diff)
downloadmupdf-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/document.c')
-rw-r--r--source/fitz/document.c97
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)