From 2597722d7aa1be523058bc8449120d32768f44b3 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 28 Aug 2012 17:34:23 +0200 Subject: Add fz_open_document_with_stream function. Use a "magic" string for filetype detection: filename or mime-type. --- cbz/mucbz.c | 5 ++--- cbz/mucbz.h | 2 +- fitz/doc_document.c | 58 ++++++++++++++++++++++++++++++++++++++-------------- fitz/fitz.h | 10 +++++++++ pdf/mupdf-internal.h | 2 +- pdf/mupdf.h | 2 +- pdf/pdf_xref.c | 9 ++++---- pdf/pdf_xref_aux.c | 4 ++-- xps/muxps.h | 2 +- xps/xps_zip.c | 5 ++--- 10 files changed, 67 insertions(+), 32 deletions(-) diff --git a/cbz/mucbz.c b/cbz/mucbz.c index df6be18f..8dc08798 100644 --- a/cbz/mucbz.c +++ b/cbz/mucbz.c @@ -285,9 +285,8 @@ cbz_read_zip_dir(cbz_document *doc) } cbz_document * -cbz_open_document_with_stream(fz_stream *file) +cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) { - fz_context *ctx = file->ctx; cbz_document *doc; doc = fz_malloc_struct(ctx, cbz_document); @@ -323,7 +322,7 @@ cbz_open_document(fz_context *ctx, char *filename) fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno)); fz_try(ctx) { - doc = cbz_open_document_with_stream(file); + doc = cbz_open_document_with_stream(ctx, file); } fz_always(ctx) { fz_close(file); } fz_catch(ctx) { diff --git a/cbz/mucbz.h b/cbz/mucbz.h index 080423bf..05288eb3 100644 --- a/cbz/mucbz.h +++ b/cbz/mucbz.h @@ -30,7 +30,7 @@ cbz_document *cbz_open_document(fz_context *ctx, char *filename); fz_open_file_w or fz_open_fd for opening a stream, and fz_close for closing an open stream. */ -cbz_document *cbz_open_document_with_stream(fz_stream *file); +cbz_document *cbz_open_document_with_stream(fz_context *ctx, fz_stream *file); /* cbz_close_document: Closes and frees an opened document. diff --git a/fitz/doc_document.c b/fitz/doc_document.c index 1233aeb9..eb50285b 100644 --- a/fitz/doc_document.c +++ b/fitz/doc_document.c @@ -5,6 +5,11 @@ extern struct pdf_document *pdf_open_document(fz_context *ctx, char *filename); extern struct xps_document *xps_open_document(fz_context *ctx, char *filename); extern struct cbz_document *cbz_open_document(fz_context *ctx, char *filename); +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); + + static inline int fz_tolower(int c) { if (c >= 'A' && c <= 'Z') @@ -23,26 +28,49 @@ static inline int fz_strcasecmp(char *a, char *b) return fz_tolower(*a) - fz_tolower(*b); } +fz_document * +fz_open_document_with_stream(fz_context *ctx, char *magic, fz_stream *stream) +{ + char *ext = strrchr(magic, '.'); + + if (ext) + { + if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels")) + 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 (!strcmp(magic, "cbz") || !strcmp(magic, "application/x-cbz")) + return (fz_document*) cbz_open_document_with_stream(ctx, stream); + if (!strcmp(magic, "xps") || !strcmp(magic, "application/vnd.ms-xpsdocument")) + 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); + + /* last guess: pdf */ + return (fz_document*) pdf_open_document_with_stream(ctx, stream); +} + fz_document * fz_open_document(fz_context *ctx, char *filename) { char *ext = strrchr(filename, '.'); - if (ext && (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels"))) - return (fz_document*) xps_open_document(ctx, filename); - if (ext && !fz_strcasecmp(ext, ".cbz")) - return (fz_document*) cbz_open_document(ctx, filename); -#if 0 - /* We used to only open pdf files if they ended in .pdf. For now, - * until we move to detecting filetypes by their content, we disable - * this code, and assume that any file that hasn't matched an - * extension already, is a PDF. */ - if (ext && !fz_strcasecmp(ext, ".pdf")) - return (fz_document*) pdf_open_document(ctx, filename); - fz_throw(ctx, "unknown document type: '%s'", filename); - return NULL; -#else + + if (ext) + { + if (!fz_strcasecmp(ext, ".xps") || !fz_strcasecmp(ext, ".rels")) + 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); + } + + /* last guess: pdf */ return (fz_document*) pdf_open_document(ctx, filename); -#endif } void diff --git a/fitz/fitz.h b/fitz/fitz.h index b4e7cee4..96cd69a8 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -2142,6 +2142,16 @@ typedef struct fz_page_s fz_page; */ fz_document *fz_open_document(fz_context *ctx, char *filename); +/* + fz_open_document_with_stream: Open a PDF, XPS or CBZ document. + + Open a document using the specified stream object rather than + opening a file on disk. + + magic: a string used to detect document type; either a file name or mime-type. +*/ +fz_document *fz_open_document_with_stream(fz_context *ctx, char *magic, fz_stream *stream); + /* fz_close_document: Close and free an open document. diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index efd9e109..1aca4aa2 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -206,7 +206,7 @@ struct pdf_document_s }; pdf_document *pdf_open_document_no_run(fz_context *ctx, const char *filename); -pdf_document *pdf_open_document_no_run_with_stream(fz_stream *file); +pdf_document *pdf_open_document_no_run_with_stream(fz_context *ctx, fz_stream *file); void pdf_cache_object(pdf_document *doc, int num, int gen); diff --git a/pdf/mupdf.h b/pdf/mupdf.h index 6ebe4437..8e536777 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -167,7 +167,7 @@ pdf_document *pdf_open_document(fz_context *ctx, const char *filename); fz_open_file_w or fz_open_fd for opening a stream, and fz_close for closing an open stream. */ -pdf_document *pdf_open_document_with_stream(fz_stream *file); +pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file); /* pdf_close_document: Closes and frees an opened PDF document. diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index 050a6f53..37cc2081 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -1307,9 +1307,8 @@ static int pdf_meta_shim(fz_document *doc, int key, void *ptr, int size) } static pdf_document * -pdf_new_document(fz_stream *file) +pdf_new_document(fz_context *ctx, fz_stream *file) { - fz_context *ctx = file->ctx; pdf_document *doc = fz_malloc_struct(ctx, pdf_document); doc->super.close = pdf_close_document_shim; @@ -1332,9 +1331,9 @@ pdf_new_document(fz_stream *file) } pdf_document * -pdf_open_document_no_run_with_stream(fz_stream *file) +pdf_open_document_no_run_with_stream(fz_context *ctx, fz_stream *file) { - pdf_document *doc = pdf_new_document(file); + pdf_document *doc = pdf_new_document(ctx, file); pdf_init_document(doc); return doc; } @@ -1350,7 +1349,7 @@ pdf_open_document_no_run(fz_context *ctx, const char *filename) fz_try(ctx) { file = fz_open_file(ctx, filename); - doc = pdf_new_document(file); + doc = pdf_new_document(ctx, file); pdf_init_document(doc); } fz_always(ctx) diff --git a/pdf/pdf_xref_aux.c b/pdf/pdf_xref_aux.c index 907e6f17..bf2fe19b 100644 --- a/pdf/pdf_xref_aux.c +++ b/pdf/pdf_xref_aux.c @@ -15,9 +15,9 @@ static void pdf_run_page_shim(fz_document *doc, fz_page *page, fz_device *dev, f } pdf_document * -pdf_open_document_with_stream(fz_stream *file) +pdf_open_document_with_stream(fz_context *ctx, fz_stream *file) { - pdf_document *doc = pdf_open_document_no_run_with_stream(file); + pdf_document *doc = pdf_open_document_no_run_with_stream(ctx, file); doc->super.run_page = pdf_run_page_shim; return doc; } diff --git a/xps/muxps.h b/xps/muxps.h index 128ed35f..8ec577af 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -45,7 +45,7 @@ xps_document *xps_open_document(fz_context *ctx, char *filename); fz_open_file_w or fz_open_fd for opening a stream, and fz_close for closing an open stream. */ -xps_document *xps_open_document_with_stream(fz_stream *file); +xps_document *xps_open_document_with_stream(fz_context *ctx, fz_stream *file); /* xps_close_document: Closes and frees an opened document. diff --git a/xps/xps_zip.c b/xps/xps_zip.c index 099bbf46..e0d1eae9 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -576,9 +576,8 @@ xps_open_document_with_directory(fz_context *ctx, char *directory) } xps_document * -xps_open_document_with_stream(fz_stream *file) +xps_open_document_with_stream(fz_context *ctx, fz_stream *file) { - fz_context *ctx = file->ctx; xps_document *doc; doc = fz_malloc_struct(ctx, xps_document); @@ -624,7 +623,7 @@ xps_open_document(fz_context *ctx, char *filename) fz_try(ctx) { - doc = xps_open_document_with_stream(file); + doc = xps_open_document_with_stream(ctx, file); } fz_always(ctx) { -- cgit v1.2.3