summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--include/mupdf/fitz/document.h1
-rw-r--r--include/mupdf/tiff.h51
-rw-r--r--platform/android/jni/Core.mk4
-rw-r--r--platform/win32/libmupdf.vcproj8
-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
9 files changed, 280 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index d94d6b69..be650cc3 100644
--- a/Makefile
+++ b/Makefile
@@ -65,6 +65,7 @@ ALL_DIR += $(OUT)/pdf $(OUT)/pdf/js
ALL_DIR += $(OUT)/xps
ALL_DIR += $(OUT)/cbz
ALL_DIR += $(OUT)/img
+ALL_DIR += $(OUT)/tiff
ALL_DIR += $(OUT)/tools
ALL_DIR += $(OUT)/platform/x11
ALL_DIR += $(OUT)/platform/x11/curl
@@ -80,18 +81,21 @@ PDF_SRC := $(wildcard source/pdf/*.c)
XPS_SRC := $(wildcard source/xps/*.c)
CBZ_SRC := $(wildcard source/cbz/*.c)
IMG_SRC := $(wildcard source/img/*.c)
+TIFF_SRC := $(wildcard source/tiff/*.c)
FITZ_SRC_HDR := $(wildcard source/fitz/*.h)
PDF_SRC_HDR := $(wildcard source/pdf/*.h)
XPS_SRC_HDR := $(wildcard source/xps/*.h)
CBZ_SRC_HDR := $(wildcard source/cbz/*.h)
IMG_SRC_HDR := $(wildcard source/img/*.h)
+TIFF_SRC_HDR := $(wildcard source/tiff/*.h)
FITZ_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(FITZ_SRC))))
PDF_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(PDF_SRC))))
XPS_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(XPS_SRC))))
CBZ_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(CBZ_SRC))))
IMG_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(IMG_SRC))))
+TIFF_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(TIFF_SRC))))
PDF_JS_JSCORE_OBJ := $(OUT)/pdf/js/pdf-js.o $(OUT)/pdf/js/pdf-jsimp-jscore.o
PDF_JS_V8_OBJ := $(OUT)/pdf/js/pdf-js.o $(OUT)/pdf/js/pdf-jsimp-cpp.o $(OUT)/pdf/js/pdf-jsimp-v8.o
@@ -102,6 +106,7 @@ $(PDF_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
$(XPS_OBJ) : $(FITZ_HDR) $(XPS_HDR) $(XPS_SRC_HDR)
$(CBZ_OBJ) : $(FITZ_HDR) $(CBZ_HDR) $(CBZ_SRC_HDR)
$(IMG_OBJ) : $(FITZ_HDR) $(IMG_HDR) $(IMG_SRC_HDR)
+$(TIFF_OBJ) : $(FITZ_HDR) $(IMG_HDR) $(TIFF_SRC_HDR)
$(PDF_JS_JSCORE_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
$(PDF_JS_V8_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
@@ -112,7 +117,7 @@ $(PDF_JS_NONE_OBJ) := $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
MUPDF_LIB := $(OUT)/libmupdf.a
MUPDF_JS_NONE_LIB := $(OUT)/libmupdf-js-none.a
-$(MUPDF_LIB) : $(FITZ_OBJ) $(PDF_OBJ) $(XPS_OBJ) $(CBZ_OBJ) $(IMG_OBJ)
+$(MUPDF_LIB) : $(FITZ_OBJ) $(PDF_OBJ) $(XPS_OBJ) $(CBZ_OBJ) $(IMG_OBJ) $(TIFF_OBJ)
$(MUPDF_JS_NONE_LIB) : $(PDF_JS_NONE_OBJ)
ifeq "$(V8_PRESENT)" "yes"
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h
index cda8870a..a3d0b244 100644
--- a/include/mupdf/fitz/document.h
+++ b/include/mupdf/fitz/document.h
@@ -77,6 +77,7 @@ 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;
+extern fz_document_handler tiff_document_handler;
void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler);
diff --git a/include/mupdf/tiff.h b/include/mupdf/tiff.h
new file mode 100644
index 00000000..1304e4b2
--- /dev/null
+++ b/include/mupdf/tiff.h
@@ -0,0 +1,51 @@
+#ifndef MUPDF_TIFF_H
+#define MUPDF_TIFF_H
+
+#include "mupdf/fitz.h"
+
+typedef struct tiff_document_s tiff_document;
+typedef struct tiff_page_s tiff_page;
+
+/*
+ tiff_open_document: Open a document.
+
+ Open a document for reading so the library is able to locate
+ objects and pages inside the file.
+
+ The returned tiff_document should be used when calling most
+ other functions. Note that it wraps the context, so those
+ functions implicitly get access to the global state in
+ context.
+
+ filename: a path to a file as it would be given to open(2).
+*/
+tiff_document *tiff_open_document(fz_context *ctx, const char *filename);
+
+/*
+ tiff_open_document_with_stream: Opens a document.
+
+ Same as tiff_open_document, but takes a stream instead of a
+ filename to locate the document to open. Increments the
+ reference count of the stream. See fz_open_file,
+ fz_open_file_w or fz_open_fd for opening a stream, and
+ fz_close for closing an open stream.
+*/
+tiff_document *tiff_open_document_with_stream(fz_context *ctx, fz_stream *file);
+
+/*
+ tiff_close_document: Closes and frees an opened document.
+
+ The resource store in the context associated with tiff_document
+ is emptied.
+
+ Does not throw exceptions.
+*/
+void tiff_close_document(tiff_document *doc);
+
+int tiff_count_pages(tiff_document *doc);
+tiff_page *tiff_load_page(tiff_document *doc, int number);
+fz_rect *tiff_bound_page(tiff_document *doc, tiff_page *page, fz_rect *rect);
+void tiff_free_page(tiff_document *doc, tiff_page *page);
+void tiff_run_page(tiff_document *doc, tiff_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie);
+
+#endif
diff --git a/platform/android/jni/Core.mk b/platform/android/jni/Core.mk
index 336d82d9..58ac8477 100644
--- a/platform/android/jni/Core.mk
+++ b/platform/android/jni/Core.mk
@@ -31,6 +31,7 @@ LOCAL_C_INCLUDES := \
../../source/xps \
../../source/cbz \
../../source/img \
+ ../../source/tiff \
../../scripts/freetype \
../../scripts/jpeg \
../../scripts/openjpeg \
@@ -51,7 +52,8 @@ LOCAL_SRC_FILES := \
$(wildcard $(MY_ROOT)/source/pdf/*.c) \
$(wildcard $(MY_ROOT)/source/xps/*.c) \
$(wildcard $(MY_ROOT)/source/cbz/*.c) \
- $(wildcard $(MY_ROOT)/source/img/*.c)
+ $(wildcard $(MY_ROOT)/source/img/*.c) \
+ $(wildcard $(MY_ROOT)/source/tiff/*.c)
ifdef MEMENTO
LOCAL_SRC_FILES += $(MY_ROOT)/fitz/memento.c
endif
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index e8dc6fc6..2c80d712 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -1122,6 +1122,14 @@
</File>
</Filter>
</Filter>
+ <Filter
+ Name="tiff"
+ >
+ <File
+ RelativePath="..\..\source\tiff\mutiff.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
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
+};