Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/fitz.h"
2
3
typedef struct tiff_document_s tiff_document;
4
typedef struct tiff_page_s tiff_page;
5
6
#define DPI 72.0f
7
8
struct tiff_page_s
9
{
10
fz_page super;
11
fz_image *image;
12
};
13
14
struct tiff_document_s
15
{
16
fz_document super;
17
fz_buffer *buffer;
18
int page_count;
19
};
20
21
static fz_rect *
22
tiff_bound_page(fz_context *ctx, tiff_page *page, fz_rect *bbox)
23
{
24
fz_image *image = page->image;
25
int xres, yres;
26
27
fz_image_get_sanitised_res(image, &xres, &yres);
28
bbox->x0 = bbox->y0 = 0;
29
bbox->x1 = image->w * DPI / xres;
30
bbox->y1 = image->h * DPI / yres;
31
return bbox;
32
}
33
34
static void
35
tiff_run_page(fz_context *ctx, tiff_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
36
{
37
fz_matrix local_ctm = *ctm;
38
fz_image *image = page->image;
39
int xres, yres;
40
float w, h;
41
42
fz_image_get_sanitised_res(image, &xres, &yres);
43
w = image->w * DPI / xres;
44
h = image->h * DPI / yres;
45
fz_pre_scale(&local_ctm, w, h);
46
fz_fill_image(ctx, dev, image, &local_ctm, 1);
47
}
48
49
static void
50
tiff_drop_page_imp(fz_context *ctx, tiff_page *page)
51
{
52
if (!page)
53
return;
54
fz_drop_image(ctx, page->image);
55
}
56
57
static tiff_page *
58
tiff_load_page(fz_context *ctx, tiff_document *doc, int number)
59
{
60
fz_pixmap *pixmap = NULL;
61
fz_image *image = NULL;
62
tiff_page *page = NULL;
63
64
if (number < 0 || number >= doc->page_count)
65
return NULL;
66
67
fz_var(pixmap);
68
fz_var(image);
69
fz_var(page);
70
71
fz_try(ctx)
72
{
73
pixmap = fz_load_tiff_subimage(ctx, doc->buffer->data, doc->buffer->len, number);
74
image = fz_new_image_from_pixmap(ctx, pixmap, NULL);
75
76
page = fz_new_page(ctx, sizeof *page);
77
page->super.bound_page = (fz_page_bound_page_fn *)tiff_bound_page;
78
page->super.run_page_contents = (fz_page_run_page_contents_fn *)tiff_run_page;
79
page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)tiff_drop_page_imp;
80
page->image = fz_keep_image(ctx, image);
81
}
82
fz_always(ctx)
83
{
84
fz_drop_image(ctx, image);
85
fz_drop_pixmap(ctx, pixmap);
86
}
87
fz_catch(ctx)
88
{
89
fz_free(ctx, page);
90
fz_rethrow(ctx);
91
}
92
93
return page;
94
}
95
96
static int
97
tiff_count_pages(fz_context *ctx, tiff_document *doc)
98
{
99
return doc->page_count;
100
}
101
102
static int
103
tiff_lookup_metadata(fz_context *ctx, tiff_document *doc, const char *key, char *buf, int size)
104
{
105
if (!strcmp(key, "format"))
106
return fz_strlcpy(buf, "TIFF", size);
107
return -1;
108
}
109
110
static void
111
tiff_close_document(fz_context *ctx, tiff_document *doc)
112
{
113
fz_drop_buffer(ctx, doc->buffer);
114
fz_free(ctx, doc);
115
}
116
117
static tiff_document *
118
tiff_open_document_with_stream(fz_context *ctx, fz_stream *file)
119
{
120
tiff_document *doc;
121
122
doc = fz_new_document(ctx, sizeof *doc);
123
124
doc->super.close = (fz_document_close_fn *)tiff_close_document;
125
doc->super.count_pages = (fz_document_count_pages_fn *)tiff_count_pages;
126
doc->super.load_page = (fz_document_load_page_fn *)tiff_load_page;
127
doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)tiff_lookup_metadata;
128
129
fz_try(ctx)
130
{
131
doc->buffer = fz_read_all(ctx, file, 1024);
132
doc->page_count = fz_load_tiff_subimage_count(ctx, doc->buffer->data, doc->buffer->len);
133
}
134
fz_catch(ctx)
135
{
136
tiff_close_document(ctx, doc);
137
fz_rethrow(ctx);
138
}
139
140
return doc;
141
}
142
143
static tiff_document *
144
tiff_open_document(fz_context *ctx, const char *filename)
145
{
146
fz_stream *file;
147
tiff_document *doc;
148
149
file = fz_open_file(ctx, filename);
150
151
fz_try(ctx)
152
doc = tiff_open_document_with_stream(ctx, file);
153
fz_always(ctx)
154
fz_drop_stream(ctx, file);
155
fz_catch(ctx)
156
fz_rethrow(ctx);
157
158
return doc;
159
}
160
161
static int
162
tiff_recognize(fz_context *doc, const char *magic)
163
{
164
char *ext = strrchr(magic, '.');
165
166
if (ext)
167
{
168
if (!fz_strcasecmp(ext, ".tiff") || !fz_strcasecmp(ext, ".tif"))
169
return 100;
170
}
171
if (!strcmp(magic, "tif") || !strcmp(magic, "image/tiff") ||
172
!strcmp(magic, "tiff") || !strcmp(magic, "image/x-tiff"))
173
return 100;
174
175
return 0;
176
}
177
178
fz_document_handler tiff_document_handler =
179
{
180
(fz_document_recognize_fn *)&tiff_recognize,
181
(fz_document_open_fn *)&tiff_open_document,
182
(fz_document_open_with_stream_fn *)&tiff_open_document_with_stream
183
};
184
185