summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/context.h6
-rw-r--r--include/mupdf/fitz/document.h23
-rw-r--r--include/mupdf/fitz/system.h2
-rw-r--r--include/mupdf/pdf/document.h2
-rw-r--r--platform/win32/libmupdf.vcproj8
-rw-r--r--platform/x11/pdfapp.c2
-rw-r--r--scripts/cmapdump.c13
-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
17 files changed, 296 insertions, 57 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h
index bb171b3f..c6adbb3f 100644
--- a/include/mupdf/fitz/context.h
+++ b/include/mupdf/fitz/context.h
@@ -18,6 +18,7 @@ typedef struct fz_aa_context_s fz_aa_context;
typedef struct fz_locks_context_s fz_locks_context;
typedef struct fz_store_s fz_store;
typedef struct fz_glyph_cache_s fz_glyph_cache;
+typedef struct fz_document_handler_context_s fz_document_handler_context;
typedef struct fz_context_s fz_context;
struct fz_alloc_context_s
@@ -107,6 +108,7 @@ struct fz_context_s
fz_aa_context *aa;
fz_store *store;
fz_glyph_cache *glyph_cache;
+ fz_document_handler_context *handler;
};
/*
@@ -416,6 +418,10 @@ void fz_new_aa_context(fz_context *ctx);
void fz_free_aa_context(fz_context *ctx);
void fz_copy_aa_context(fz_context *dst, fz_context *src);
+void fz_new_document_handler_context(fz_context *ctx);
+void fz_drop_document_handler_context(fz_context *ctx);
+fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx);
+
/* Default allocator */
extern fz_alloc_context fz_alloc_default;
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h
index 887ca151..cda8870a 100644
--- a/include/mupdf/fitz/document.h
+++ b/include/mupdf/fitz/document.h
@@ -13,6 +13,7 @@
Document interface
*/
typedef struct fz_document_s fz_document;
+typedef struct fz_document_handler_s fz_document_handler;
typedef struct fz_page_s fz_page;
typedef struct fz_annot_s fz_annot;
@@ -60,6 +61,28 @@ struct fz_document_s
fz_document_rebind_fn *rebind;
};
+typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const char *filename);
+typedef fz_document *(fz_document_open_with_stream_fn)(fz_context *ctx, fz_stream *stream);
+typedef int (fz_document_recognize_fn)(fz_context *ctx, const char *magic);
+
+struct fz_document_handler_s
+{
+ fz_document_recognize_fn *recognize;
+ fz_document_open_fn *open;
+ fz_document_open_with_stream_fn *open_with_stream;
+};
+
+extern fz_document_handler pdf_document_handler;
+extern fz_document_handler pdf_no_run_document_handler;
+extern fz_document_handler xps_document_handler;
+extern fz_document_handler cbz_document_handler;
+extern fz_document_handler img_document_handler;
+
+void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler);
+
+void fz_register_document_handlers(fz_context *ctx);
+void fz_register_no_run_document_handlers(fz_context *ctx);
+
/*
fz_open_document: Open a PDF, XPS or CBZ document.
diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h
index 1decfda6..2f4868f2 100644
--- a/include/mupdf/fitz/system.h
+++ b/include/mupdf/fitz/system.h
@@ -355,4 +355,6 @@ static inline float my_atan2f(float o, float a)
#define atan2f(x,y) my_atan2f((x),(y))
#endif
+int fz_strcasecmp(const char *a, const char *b);
+
#endif
diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h
index 73b3692d..8c71d88b 100644
--- a/include/mupdf/pdf/document.h
+++ b/include/mupdf/pdf/document.h
@@ -308,4 +308,6 @@ fz_device *pdf_page_write(pdf_document *doc, pdf_page *page);
void pdf_finish_edit(pdf_document *doc);
+int pdf_recognize(fz_context *doc, const char *magic);
+
#endif
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index 74f6df79..e8dc6fc6 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -434,6 +434,10 @@
>
</File>
<File
+ RelativePath="..\..\source\fitz\document-all.c"
+ >
+ </File>
+ <File
RelativePath="..\..\source\fitz\document.c"
>
</File>
@@ -989,6 +993,10 @@
>
</File>
<File
+ RelativePath="..\..\source\fitz\document-no-run.c"
+ >
+ </File>
+ <File
RelativePath="..\..\include\mupdf\fitz\document.h"
>
</File>
diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c
index 10a44573..e9349526 100644
--- a/platform/x11/pdfapp.c
+++ b/platform/x11/pdfapp.c
@@ -192,6 +192,8 @@ void pdfapp_open_progressive(pdfapp_t *app, char *filename, int reload, int bps)
{
pdf_document *idoc;
+ fz_register_document_handlers(ctx);
+
#ifdef HAVE_CURL
if (!strncmp(filename, "http://", 7))
{
diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c
index 88f1f800..a9e5de18 100644
--- a/scripts/cmapdump.c
+++ b/scripts/cmapdump.c
@@ -246,3 +246,16 @@ fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx)
{
return NULL;
}
+
+void fz_new_document_handler_context(fz_context *ctx)
+{
+}
+
+void fz_drop_document_handler_context(fz_context *ctx)
+{
+}
+
+fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx)
+{
+ return NULL;
+}
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
+};