From 0cd7f2e8397e2caf47f3d46ef635358fa0ba194c Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Tue, 28 Mar 2017 20:14:53 +0800 Subject: 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. --- source/cbz/mucbz.c | 41 ++++++++++----------- source/cbz/muimg.c | 82 ++++++++++++++++++++++-------------------- source/cbz/mutiff.c | 31 ++++++++-------- source/fitz/document.c | 97 +++++++++++++++++++++++++++++++------------------- source/gprf/gprf-doc.c | 28 ++++++++------- source/html/epub-doc.c | 22 ++++++++---- source/html/html-doc.c | 38 +++++++++++--------- source/pdf/pdf-xref.c | 28 +++++++-------- source/svg/svg-doc.c | 28 ++++++++------- source/xps/xps-doc.c | 31 +++++++++------- 10 files changed, 238 insertions(+), 188 deletions(-) (limited to 'source') diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c index a557a9c7..3a19c174 100644 --- a/source/cbz/mucbz.c +++ b/source/cbz/mucbz.c @@ -217,28 +217,29 @@ cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) return &doc->super; } -static int -cbz_recognize(fz_context *ctx, const char *magic) -{ - char *ext = strrchr(magic, '.'); - if ((ext && !fz_strcasecmp(ext, ".cbz")) || !strcmp(magic, "cbz") || - !strcmp(magic, "application/x-cbz")) - return 100; - if ((ext && !fz_strcasecmp(ext, ".zip")) || !strcmp(magic, "zip") || - !strcmp(magic, "application/zip")) - return 100; - if ((ext && !fz_strcasecmp(ext, ".tar")) || !strcmp(magic, "tar") || - !strcmp(magic, "application/x-tar")) - return 100; - if ((ext && !fz_strcasecmp(ext, ".cbt")) || !strcmp(magic, "cbt") || - !strcmp(magic, "application/x-cbt")) - return 100; - return 0; -} +static const char *cbz_extensions[] = +{ + "cbt", + "cbz", + "tar", + "zip", + NULL +}; + +static const char *cbz_mimetypes[] = +{ + "application/x-cbt", + "application/x-cbz", + "application/x-tar", + "application/zip", + NULL +}; fz_document_handler cbz_document_handler = { - cbz_recognize, NULL, - cbz_open_document_with_stream + NULL, + cbz_open_document_with_stream, + cbz_extensions, + cbz_mimetypes }; diff --git a/source/cbz/muimg.c b/source/cbz/muimg.c index 4c590f52..088dee22 100644 --- a/source/cbz/muimg.c +++ b/source/cbz/muimg.c @@ -130,49 +130,53 @@ img_open_document_with_stream(fz_context *ctx, fz_stream *stm) return &doc->super; } -static int -img_recognize(fz_context *doc, const char *magic) +static const char *img_extensions[] = { - char *ext = strrchr(magic, '.'); + "bmp", + "gif", + "hdp", + "j2k", + "jfif", + "jfif-tbnl", + "jp2", + "jpe", + "jpeg", + "jpg", + "jpx", + "jxr", + "pam", + "pbm", + "pgm", + "png", + "pnm", + "ppm", + "wdp", + NULL +}; - 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, ".gif") || !fz_strcasecmp(ext, ".bmp") || - !fz_strcasecmp(ext, ".jpx") || !fz_strcasecmp(ext, ".jp2") || - !fz_strcasecmp(ext, ".j2k") || !fz_strcasecmp(ext, ".wdp") || - !fz_strcasecmp(ext, ".hdp") || !fz_strcasecmp(ext, ".jxr") || - !fz_strcasecmp(ext, ".pbm") || !fz_strcasecmp(ext, ".pgm") || - !fz_strcasecmp(ext, ".ppm") || !fz_strcasecmp(ext, ".pam") || - !fz_strcasecmp(ext, ".pnm")) - 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, "gif") || !strcmp(magic, "image/gif") || - !strcmp(magic, "bmp") || !strcmp(magic, "image/bmp") || - !strcmp(magic, "jpx") || !strcmp(magic, "image/jpx") || - !strcmp(magic, "jp2") || !strcmp(magic, "image/jp2") || - !strcmp(magic, "j2k") || !strcmp(magic, "wdp") || - !strcmp(magic, "hdp") || !strcmp(magic, "image/vnd.ms-photo") || - !strcmp(magic, "jxr") || !strcmp(magic, "image/jxr") || - !strcmp(magic, "pbm") || !strcmp(magic, "image/x-portable-bitmap") || - !strcmp(magic, "pgm") || !strcmp(magic, "image/x-portable-greymap") || - !strcmp(magic, "ppm") || !strcmp(magic, "image/x-portable-pixmap") || - !strcmp(magic, "pam") || !strcmp(magic, "image/x-portable-arbitrarymap") || - !strcmp(magic, "pnm")) - return 100; - - return 0; -} +static const char *img_mimetypes[] = +{ + "image/bmp", + "image/gif", + "image/jp2", + "image/jpeg", + "image/jpx", + "image/jxr", + "image/pjpeg", + "image/png", + "image/vnd.ms-photo", + "image/x-portable-arbitrarymap", + "image/x-portable-bitmap", + "image/x-portable-greymap", + "image/x-portable-pixmap", + NULL +}; fz_document_handler img_document_handler = { - img_recognize, NULL, - img_open_document_with_stream + NULL, + img_open_document_with_stream, + img_extensions, + img_mimetypes }; diff --git a/source/cbz/mutiff.c b/source/cbz/mutiff.c index 637f4e3a..06c7a837 100644 --- a/source/cbz/mutiff.c +++ b/source/cbz/mutiff.c @@ -143,26 +143,25 @@ tiff_open_document_with_stream(fz_context *ctx, fz_stream *file) return &doc->super; } -static int -tiff_recognize(fz_context *doc, const char *magic) +static const char *tiff_extensions[] = { - char *ext = strrchr(magic, '.'); - - if (ext) - { - if (!fz_strcasecmp(ext, ".tiff") || !fz_strcasecmp(ext, ".tif")) - return 100; - } - if (!strcmp(magic, "tif") || !strcmp(magic, "image/tiff") || - !strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff")) - return 100; + "tif", + "tiff", + NULL +}; - return 0; -} +static const char *tiff_mimetypes[] = +{ + "image/tiff", + "image/x-tiff", + NULL +}; fz_document_handler tiff_document_handler = { - tiff_recognize, NULL, - tiff_open_document_with_stream + NULL, + tiff_open_document_with_stream, + tiff_extensions, + tiff_mimetypes }; 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) diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c index faeb8e2f..53816a15 100644 --- a/source/gprf/gprf-doc.c +++ b/source/gprf/gprf-doc.c @@ -990,22 +990,24 @@ gprf_open_document(fz_context *ctx, const char *filename) return doc; } -static int -gprf_recognize(fz_context *doc, const char *magic) -{ - char *ext = strrchr(magic, '.'); - if (ext) - if (!fz_strcasecmp(ext, ".gproof")) - return 100; - if (!strcmp(magic, "application/ghostproof")) - return 100; - return 0; -} +static const char *gprf_extensions[] = +{ + "gproof", + NULL +}; + +static const char *gprf_mimetypes[] = +{ + "application/x-ghostproof", + NULL +}; fz_document_handler gprf_document_handler = { - gprf_recognize, + NULL, gprf_open_document, - gprf_open_document_with_stream + gprf_open_document_with_stream, + gprf_extensions, + gprf_mimetypes }; #endif diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c index 44903d99..c43ef8b1 100644 --- a/source/html/epub-doc.c +++ b/source/html/epub-doc.c @@ -519,20 +519,28 @@ epub_open_document(fz_context *ctx, const char *filename) static int epub_recognize(fz_context *doc, const char *magic) { - char *ext = strrchr(magic, '.'); - if (ext) - if (!fz_strcasecmp(ext, ".epub")) - return 100; if (strstr(magic, "META-INF/container.xml") || strstr(magic, "META-INF\\container.xml")) return 200; - if (!strcmp(magic, "application/epub+zip")) - return 100; return 0; } +static const char *epub_extensions[] = +{ + "epub", + NULL +}; + +static const char *epub_mimetypes[] = +{ + "application/epub+zip", + NULL +}; + fz_document_handler epub_document_handler = { epub_recognize, epub_open_document, - epub_open_document_with_stream + epub_open_document_with_stream, + epub_extensions, + epub_mimetypes }; diff --git a/source/html/html-doc.c b/source/html/html-doc.c index ba765350..1cf3dca5 100644 --- a/source/html/html-doc.c +++ b/source/html/html-doc.c @@ -197,26 +197,30 @@ htdoc_open_document(fz_context *ctx, const char *filename) return (fz_document*)doc; } -static int -htdoc_recognize(fz_context *doc, const char *magic) -{ - char *ext = strrchr(magic, '.'); +static const char *htdoc_extensions[] = +{ + "fb2", + "htm", + "html", + "xhtml", + "xml", + NULL +}; - if (ext) - { - if (!fz_strcasecmp(ext, ".xml") || !fz_strcasecmp(ext, ".xhtml") || - !fz_strcasecmp(ext, ".html") || !fz_strcasecmp(ext, ".htm") || - !fz_strcasecmp(ext, ".fb2")) - return 100; - } - if (!strcmp(magic, "application/html+xml") || !strcmp(magic, "application/xml") || !strcmp(magic, "text/xml")) - return 100; - return 0; -} +static const char *htdoc_mimetypes[] = +{ + "application/html+xml", + "application/x-fictionbook", + "application/xml", + "text/xml", + NULL +}; fz_document_handler html_document_handler = { - htdoc_recognize, + NULL, htdoc_open_document, - htdoc_open_document_with_stream + htdoc_open_document_with_stream, + htdoc_extensions, + htdoc_mimetypes }; diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 14da300d..e24da9a1 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -2738,27 +2738,25 @@ pdf_document *pdf_create_document(fz_context *ctx) return doc; } -int -pdf_recognize(fz_context *doc, const char *magic) +static const char *pdf_extensions[] = { - char *ext = strrchr(magic, '.'); - - if (ext) - { - if (!fz_strcasecmp(ext, ".pdf")) - return 100; - } - if (!strcmp(magic, "pdf") || !strcmp(magic, "application/pdf")) - return 100; + "pdf", + NULL +}; - return 1; -} +static const char *pdf_mimetypes[] = +{ + "application/pdf", + NULL +}; fz_document_handler pdf_document_handler = { - pdf_recognize, + NULL, (fz_document_open_fn *) pdf_open_document, - (fz_document_open_with_stream_fn *) pdf_open_document_with_stream + (fz_document_open_with_stream_fn *) pdf_open_document_with_stream, + pdf_extensions, + pdf_mimetypes }; void pdf_mark_xref(fz_context *ctx, pdf_document *doc) diff --git a/source/svg/svg-doc.c b/source/svg/svg-doc.c index c7f8add8..2a9f061e 100644 --- a/source/svg/svg-doc.c +++ b/source/svg/svg-doc.c @@ -121,16 +121,6 @@ svg_open_document_with_stream(fz_context *ctx, fz_stream *file) return doc; } -static int -svg_recognize(fz_context *ctx, const char *magic) -{ - char *ext = strrchr(magic, '.'); - if (ext && !fz_strcasecmp(ext, ".svg")) - return 100; - if (!strcmp(magic, "svg") || !strcmp(magic, "image/svg+xml")) - return 100; - return 0; -} fz_display_list * fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, float *w, float *h) @@ -170,9 +160,23 @@ fz_new_image_from_svg(fz_context *ctx, fz_buffer *buf) return image; } +static const char *svg_extensions[] = +{ + "svg", + NULL +}; + +static const char *svg_mimetypes[] = +{ + "image/svg+xml", + NULL +}; + fz_document_handler svg_document_handler = { - svg_recognize, NULL, - svg_open_document_with_stream + NULL, + svg_open_document_with_stream, + svg_extensions, + svg_mimetypes }; diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c index 5c91a591..23ecf17c 100644 --- a/source/xps/xps-doc.c +++ b/source/xps/xps-doc.c @@ -465,26 +465,31 @@ xps_load_page(fz_context *ctx, xps_document *doc, int number) static int xps_recognize(fz_context *ctx, const char *magic) { - char *ext = strrchr(magic, '.'); - - if (ext) - { - if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".oxps")) - return 100; - } if (strstr(magic, "/_rels/.rels") || strstr(magic, "\\_rels\\.rels")) return 100; - if (!strcmp(magic, "xps") || !strcmp(magic, "oxps") || - !strcmp(magic, "application/vnd.ms-xpsdocument") || - !strcmp(magic, "application/xps") || - !strcmp(magic, "application/oxps")) - return 100; return 0; } +static const char *xps_extensions[] = +{ + "oxps", + "xps", + NULL +}; + +static const char *xps_mimetypes[] = +{ + "application/oxps", + "application/vnd.ms-xpsdocument", + "application/xps", + NULL +}; + fz_document_handler xps_document_handler = { xps_recognize, (fz_document_open_fn *) xps_open_document, - (fz_document_open_with_stream_fn *) xps_open_document_with_stream + (fz_document_open_with_stream_fn *) xps_open_document_with_stream, + xps_extensions, + xps_mimetypes }; -- cgit v1.2.3