summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
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
+};