summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-02-10 16:54:24 +0000
committerRobin Watts <robin.watts@artifex.com>2014-02-10 17:04:03 +0000
commita4a50269b2c62fddf34445140036e3f61b500d9e (patch)
treee5ab2bf4e75d0b96f0cced8f8e42dde3e564dc54 /source
parent9b9438fa4210b29023f85bb98c73f8f58a7760d5 (diff)
downloadmupdf-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.c1
-rw-r--r--source/fitz/document-no-run.c1
-rw-r--r--source/img/muimage.c7
-rw-r--r--source/tiff/mutiff.c207
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
+};