summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-01-03 16:50:41 +0000
committerRobin Watts <robin.watts@artifex.com>2014-01-07 10:25:42 +0000
commit7f009acebb75ff88c1ee934b03fa2d15f7785b32 (patch)
tree7be547523d730d104c62e4b5d43685dd8bb5bd40 /source
parent016adfa063293281a0896c62bf22e406b09ddf21 (diff)
downloadmupdf-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')
-rw-r--r--source/cbz/mucbz.c23
-rw-r--r--source/fitz/context.c4
-rw-r--r--source/fitz/document-all.c9
-rw-r--r--source/fitz/document-no-run.c9
-rw-r--r--source/fitz/document.c163
-rw-r--r--source/img/muimage.c31
-rw-r--r--source/pdf/pdf-xref-aux.c7
-rw-r--r--source/pdf/pdf-xref.c24
-rw-r--r--source/tools/mudraw.c2
-rw-r--r--source/xps/xps-doc.c25
10 files changed, 240 insertions, 57 deletions
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
+};