diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-02-10 16:54:24 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-02-10 17:04:03 +0000 |
commit | a4a50269b2c62fddf34445140036e3f61b500d9e (patch) | |
tree | e5ab2bf4e75d0b96f0cced8f8e42dde3e564dc54 /source | |
parent | 9b9438fa4210b29023f85bb98c73f8f58a7760d5 (diff) | |
download | mupdf-a4a50269b2c62fddf34445140036e3f61b500d9e.tar.xz |
Bug 695022: Add TIFF format handler
Patch from Thomas Fach-Pedersen. Many thanks!
Add a new format handler that copes with TIFF files. This replaces
the TIFF functionality within the image format handler, and is
better because this copes with multiple images (as one image per
page).
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/document-all.c | 1 | ||||
-rw-r--r-- | source/fitz/document-no-run.c | 1 | ||||
-rw-r--r-- | source/img/muimage.c | 7 | ||||
-rw-r--r-- | source/tiff/mutiff.c | 207 |
4 files changed, 211 insertions, 5 deletions
diff --git a/source/fitz/document-all.c b/source/fitz/document-all.c index 92b1c037..e1eb4a58 100644 --- a/source/fitz/document-all.c +++ b/source/fitz/document-all.c @@ -6,4 +6,5 @@ void fz_register_document_handlers(fz_context *ctx) fz_register_document_handler(ctx, &xps_document_handler); fz_register_document_handler(ctx, &cbz_document_handler); fz_register_document_handler(ctx, &img_document_handler); + fz_register_document_handler(ctx, &tiff_document_handler); } diff --git a/source/fitz/document-no-run.c b/source/fitz/document-no-run.c index b0defe91..2fd608ee 100644 --- a/source/fitz/document-no-run.c +++ b/source/fitz/document-no-run.c @@ -6,4 +6,5 @@ void fz_register_no_run_document_handlers(fz_context *ctx) fz_register_document_handler(ctx, &xps_document_handler); fz_register_document_handler(ctx, &cbz_document_handler); fz_register_document_handler(ctx, &img_document_handler); + fz_register_document_handler(ctx, &tiff_document_handler); } diff --git a/source/img/muimage.c b/source/img/muimage.c index 300d6603..d545068f 100644 --- a/source/img/muimage.c +++ b/source/img/muimage.c @@ -164,16 +164,13 @@ image_recognize(fz_context *doc, const char *magic) { 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")) + !fz_strcasecmp(ext, ".jfif-tbnl") || !fz_strcasecmp(ext, ".jpe")) 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")) + !strcmp(magic, "jpe") || !strcmp(magic, "jfif")) return 100; return 0; diff --git a/source/tiff/mutiff.c b/source/tiff/mutiff.c new file mode 100644 index 00000000..e2772f11 --- /dev/null +++ b/source/tiff/mutiff.c @@ -0,0 +1,207 @@ +#include "mupdf/tiff.h" + +static void tiff_init_document(tiff_document *doc); + +#define DPI 72.0f + +struct tiff_page_s +{ + fz_image *image; +}; + +struct tiff_document_s +{ + fz_document super; + + fz_context *ctx; + fz_stream *file; + fz_buffer *buffer; + int page_count; +}; + +tiff_document * +tiff_open_document_with_stream(fz_context *ctx, fz_stream *file) +{ + tiff_document *doc; + int len; + unsigned char *buf; + + doc = fz_malloc_struct(ctx, tiff_document); + tiff_init_document(doc); + doc->ctx = ctx; + doc->file = fz_keep_stream(file); + doc->page_count = 0; + + fz_try(ctx) + { + doc->buffer = fz_read_all(doc->file, 1024); + len = doc->buffer->len; + buf = doc->buffer->data; + + doc->page_count = fz_load_tiff_subimage_count(ctx, buf, len); + } + fz_catch(ctx) + { + tiff_close_document(doc); + fz_rethrow(ctx); + } + + return doc; +} + +tiff_document * +tiff_open_document(fz_context *ctx, const char *filename) +{ + fz_stream *file; + tiff_document *doc; + + file = fz_open_file(ctx, filename); + if (!file) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); + + fz_try(ctx) + { + doc = tiff_open_document_with_stream(ctx, file); + } + fz_always(ctx) + { + fz_close(file); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } + + return doc; +} + +void +tiff_close_document(tiff_document *doc) +{ + fz_context *ctx = doc->ctx; + fz_drop_buffer(ctx, doc->buffer); + fz_close(doc->file); + fz_free(ctx, doc); +} + +int +tiff_count_pages(tiff_document *doc) +{ + return doc->page_count; +} + +tiff_page * +tiff_load_page(tiff_document *doc, int number) +{ + fz_context *ctx = doc->ctx; + fz_image *mask = NULL; + fz_pixmap *pixmap = NULL; + tiff_page *page = NULL; + + if (number < 0 || number >= doc->page_count) + return NULL; + + fz_var(pixmap); + fz_var(page); + fz_try(ctx) + { + pixmap = fz_load_tiff_subimage(ctx, doc->buffer->data, doc->buffer->len, number); + + page = fz_malloc_struct(ctx, tiff_page); + page->image = fz_new_image_from_pixmap(ctx, pixmap, mask); + } + fz_catch(ctx) + { + tiff_free_page(doc, page); + fz_rethrow(ctx); + } + + return page; +} + +void +tiff_free_page(tiff_document *doc, tiff_page *page) +{ + if (!page) + return; + fz_drop_image(doc->ctx, page->image); + fz_free(doc->ctx, page); +} + +fz_rect * +tiff_bound_page(tiff_document *doc, tiff_page *page, fz_rect *bbox) +{ + fz_image *image = page->image; + bbox->x0 = bbox->y0 = 0; + bbox->x1 = image->w * DPI / image->xres; + bbox->y1 = image->h * DPI / image->yres; + return bbox; +} + +void +tiff_run_page(tiff_document *doc, tiff_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie) +{ + fz_matrix local_ctm = *ctm; + fz_image *image = page->image; + float w = image->w * DPI / image->xres; + float h = image->h * DPI / image->yres; + fz_pre_scale(&local_ctm, w, h); + fz_fill_image(dev, image, &local_ctm, 1); +} + +static int +tiff_meta(tiff_document *doc, int key, void *ptr, int size) +{ + switch (key) + { + case FZ_META_FORMAT_INFO: + sprintf((char *)ptr, "TIFF"); + return FZ_META_OK; + default: + return FZ_META_UNKNOWN_KEY; + } +} + +static void +tiff_rebind(tiff_document *doc, fz_context *ctx) +{ + doc->ctx = ctx; + fz_rebind_stream(doc->file, ctx); +} + +static void +tiff_init_document(tiff_document *doc) +{ + doc->super.close = (fz_document_close_fn *)tiff_close_document; + doc->super.count_pages = (fz_document_count_pages_fn *)tiff_count_pages; + doc->super.load_page = (fz_document_load_page_fn *)tiff_load_page; + doc->super.bound_page = (fz_document_bound_page_fn *)tiff_bound_page; + doc->super.run_page_contents = (fz_document_run_page_contents_fn *)tiff_run_page; + doc->super.free_page = (fz_document_free_page_fn *)tiff_free_page; + doc->super.meta = (fz_document_meta_fn *)tiff_meta; + doc->super.rebind = (fz_document_rebind_fn *)tiff_rebind; +} + +static int +tiff_recognize(fz_context *doc, const char *magic) +{ + 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; + + return 0; +} + +fz_document_handler tiff_document_handler = +{ + (fz_document_recognize_fn *)&tiff_recognize, + (fz_document_open_fn *)&tiff_open_document, + (fz_document_open_with_stream_fn *)&tiff_open_document_with_stream +}; |