app-text/sile: restrict to lua 5.3+
[sgilles-overlay.git] / app-text / mupdf / files / mupdf-1.12-djvu-support.patch
blob02d905348fe438832fdeae5f8df6c2a3d64149e0
1 From 2e97915a71d1310dfcfd5db7afb70c90adbe4354 Mon Sep 17 00:00:00 2001
2 From: "S. Gilles" <sgilles@math.umd.edu>
3 Date: Mon, 19 Feb 2018 03:26:34 -0500
4 Subject: [PATCH] Support DjVu files
6 The text layer is not supported. It would require modifying djvu_run_page
7 to add in all the fz_fill_text commands, as well as retrieving and parsing
8 the minilisp expressions returned by ddjvuapi.
10 If you really want it, hire me or something. Flexible rates.
11 ---
12 Makefile | 8 ++
13 Makerules | 7 ++
14 Makethird | 5 +
15 include/mupdf/fitz/config.h | 5 +
16 platform/gl/gl-win32.c | 10 +-
17 platform/x11/win_main.c | 8 +-
18 source/djvu/djvu-doc.c | 279 ++++++++++++++++++++++++++++++++++++++++++++
19 source/fitz/document-all.c | 4 +
20 8 files changed, 322 insertions(+), 4 deletions(-)
21 create mode 100644 source/djvu/djvu-doc.c
23 diff --git a/Makefile b/Makefile
24 index 4c293ae..8b1393d 100644
25 --- a/Makefile
26 +++ b/Makefile
27 @@ -28,6 +28,7 @@ LIBS += $(LURATECH_LIBS)
28 LIBS += $(MUJS_LIBS)
29 LIBS += $(OPENJPEG_LIBS)
30 LIBS += $(ZLIB_LIBS)
31 +LIBS += $(DDJVU_LIBS)
33 CFLAGS += $(FREETYPE_CFLAGS)
34 CFLAGS += $(HARFBUZZ_CFLAGS)
35 @@ -40,6 +41,7 @@ CFLAGS += $(LURATECH_CFLAGS)
36 CFLAGS += $(MUJS_CFLAGS)
37 CFLAGS += $(OPENJPEG_CFLAGS)
38 CFLAGS += $(ZLIB_CFLAGS)
39 +CFLAGS += $(DDJVU_CFLAGS)
41 ALL_DIR := $(OUT)/generated
42 ALL_DIR += $(OUT)/scripts
43 @@ -50,6 +52,7 @@ ALL_DIR += $(OUT)/source/svg
44 ALL_DIR += $(OUT)/source/cbz
45 ALL_DIR += $(OUT)/source/html
46 ALL_DIR += $(OUT)/source/gprf
47 +ALL_DIR += $(OUT)/source/djvu
48 ALL_DIR += $(OUT)/source/tools
49 ALL_DIR += $(OUT)/source/helpers
50 ALL_DIR += $(OUT)/source/helpers/mu-threads
51 @@ -135,6 +138,7 @@ SVG_SRC := $(sort $(wildcard source/svg/*.c))
52 CBZ_SRC := $(sort $(wildcard source/cbz/*.c))
53 HTML_SRC := $(sort $(wildcard source/html/*.c))
54 GPRF_SRC := $(sort $(wildcard source/gprf/*.c))
55 +DJVU_SRC := $(sort $(wildcard source/djvu/*.c))
56 THREAD_SRC := $(sort $(wildcard source/helpers/mu-threads/*.c))
58 FITZ_SRC_HDR := $(wildcard source/fitz/*.h)
59 @@ -143,6 +147,7 @@ XPS_SRC_HDR := $(wildcard source/xps/*.h)
60 SVG_SRC_HDR := $(wildcard source/svg/*.h)
61 HTML_SRC_HDR := $(wildcard source/html/*.h)
62 GPRF_SRC_HDR := $(wildcard source/gprf/*.h)
63 +DJVU_SRC_HDR := $(wildcard source/djvu/*.h)
65 FITZ_OBJ := $(FITZ_SRC:%.c=$(OUT)/%.o)
66 PDF_OBJ := $(PDF_SRC:%.c=$(OUT)/%.o)
67 @@ -151,6 +156,7 @@ SVG_OBJ := $(SVG_SRC:%.c=$(OUT)/%.o)
68 CBZ_OBJ := $(CBZ_SRC:%.c=$(OUT)/%.o)
69 HTML_OBJ := $(HTML_SRC:%.c=$(OUT)/%.o)
70 GPRF_OBJ := $(GPRF_SRC:%.c=$(OUT)/%.o)
71 +DJVU_OBJ := $(DJVU_SRC:%.c=$(OUT)/%.o)
72 THREAD_OBJ := $(THREAD_SRC:%.c=$(OUT)/%.o)
74 $(FITZ_OBJ) : $(FITZ_HDR) $(FITZ_SRC_HDR)
75 @@ -162,6 +168,7 @@ $(SVG_OBJ) : $(FITZ_HDR) $(SVG_HDR) $(SVG_SRC_HDR)
76 $(CBZ_OBJ) : $(FITZ_HDR) $(CBZ_HDR) $(CBZ_SRC_HDR)
77 $(HTML_OBJ) : $(FITZ_HDR) $(HTML_HDR) $(HTML_SRC_HDR)
78 $(GPRF_OBJ) : $(FITZ_HDR) $(GPRF_HDR) $(GPRF_SRC_HDR)
79 +$(DJVU_OBJ) : $(FITZ_HDR) $(DJVU_HDR) $(DJVU_SRC_HDR)
80 $(THREAD_OBJ) : $(THREAD_HDR)
82 # --- Generated PDF name tables ---
83 @@ -327,6 +334,7 @@ MUPDF_OBJ := \
84 $(CBZ_OBJ) \
85 $(HTML_OBJ) \
86 $(GPRF_OBJ) \
87 + $(DJVU_OBJ) \
88 $(ICC_OBJ)
90 THIRD_OBJ := \
91 diff --git a/Makerules b/Makerules
92 index 2ddfac0..329c1d4 100644
93 --- a/Makerules
94 +++ b/Makerules
95 @@ -144,6 +144,13 @@ SYS_OPENJPEG_CFLAGS := $(shell pkg-config --cflags libopenjp2)
96 SYS_OPENJPEG_LIBS := $(shell pkg-config --libs libopenjp2)
97 endif
99 +ifeq "$(WANT_DJVU)" "yes"
100 +ifeq "$(shell pkg-config --exists ddjvuapi && echo yes)" "yes"
101 +SYS_DDJVU_CFLAGS = $(shell pkg-config --cflags ddjvuapi)
102 +SYS_DDJVU_LIBS = $(shell pkg-config --libs ddjvuapi)
103 +endif
104 +endif
106 SYS_JBIG2DEC_LIBS := -ljbig2dec
107 SYS_LIBJPEG_LIBS := -ljpeg
108 SYS_ZLIB_LIBS := -lz
109 diff --git a/Makethird b/Makethird
110 index fbc8b7f..32bf5fe 100644
111 --- a/Makethird
112 +++ b/Makethird
113 @@ -578,6 +578,11 @@ else
114 LCMS2_CFLAGS := -DNO_ICC
115 endif
117 +# --- DDJVU ---
119 +DDJVU_CFLAGS := $(SYS_DDJVU_CFLAGS)
120 +DDJVU_LIBS := $(SYS_DDJVU_LIBS)
122 # --- cURL ---
124 ifneq "$(wildcard $(CURL_DIR)/README)" ""
125 diff --git a/include/mupdf/fitz/config.h b/include/mupdf/fitz/config.h
126 index 7fc38c8..ce272aa 100644
127 --- a/include/mupdf/fitz/config.h
128 +++ b/include/mupdf/fitz/config.h
129 @@ -33,6 +33,7 @@
130 /* #define FZ_ENABLE_HTML 1 */
131 /* #define FZ_ENABLE_EPUB 1 */
132 /* #define FZ_ENABLE_GPRF 1 */
133 +/* #define FZ_ENABLE_DJVU 1 */
136 Choose whether to enable JPEG2000 decoding.
137 @@ -156,6 +157,10 @@
138 #define FZ_ENABLE_JPX 1
139 #endif /* FZ_ENABLE_JPX */
141 +#ifndef FZ_ENABLE_DJVU
142 +#define FZ_ENABLE_DJVU 1
143 +#endif /* FZ_ENABLE_DJVU */
145 #ifndef FZ_ENABLE_JS
146 #define FZ_ENABLE_JS 1
147 #endif /* FZ_ENABLE_JS */
148 diff --git a/platform/gl/gl-win32.c b/platform/gl/gl-win32.c
149 index ec5fea9..4f42018 100644
150 --- a/platform/gl/gl-win32.c
151 +++ b/platform/gl/gl-win32.c
152 @@ -16,7 +16,7 @@ void win_install(void)
153 char command_str[2048], argv0[2048];
154 HKEY software, classes, mupdf;
155 HKEY supported_types, shell, open, command;
156 - HKEY dotpdf, dotxps, dotcbz, dotepub, dotfb2;
157 + HKEY dotpdf, dotxps, dotcbz, dotepub, dotfb2, dotdjvu;
158 HKEY pdf_progids, xps_progids, cbz_progids, epub_progids, fb2_progids;
160 GetModuleFileNameA(NULL, argv0, sizeof argv0);
161 @@ -33,6 +33,7 @@ void win_install(void)
162 SET_VALUE(supported_types, ".xps", "");
163 SET_VALUE(supported_types, ".cbz", "");
164 SET_VALUE(supported_types, ".epub", "");
165 + SET_VALUE(supported_types, ".djvu", "");
166 SET_VALUE(supported_types, ".fb2", "");
168 RegCloseKey(supported_types);
169 @@ -53,30 +54,35 @@ void win_install(void)
170 OPEN_KEY(classes, ".xps", &dotxps);
171 OPEN_KEY(classes, ".cbz", &dotcbz);
172 OPEN_KEY(classes, ".epub", &dotepub);
173 + OPEN_KEY(classes, ".djvu", &dotdjvu);
174 OPEN_KEY(classes, ".fb2", &dotfb2);
176 OPEN_KEY(dotpdf, "OpenWithProgids", &pdf_progids);
177 OPEN_KEY(dotxps, "OpenWithProgids", &xps_progids);
178 OPEN_KEY(dotcbz, "OpenWithProgids", &cbz_progids);
179 OPEN_KEY(dotepub, "OpenWithProgids", &epub_progids);
180 + OPEN_KEY(dotdjvu, "OpenWithProgids", &djvu_progids);
181 OPEN_KEY(dotfb2, "OpenWithProgids", &fb2_progids);
183 SET_VALUE(pdf_progids, "MuPDF", "");
184 SET_VALUE(xps_progids, "MuPDF", "");
185 SET_VALUE(cbz_progids, "MuPDF", "");
186 SET_VALUE(epub_progids, "MuPDF", "");
187 + SET_VALUE(djvu_progids, "MuPDF", "");
188 SET_VALUE(fb2_progids, "MuPDF", "");
190 RegCloseKey(pdf_progids);
191 RegCloseKey(xps_progids);
192 RegCloseKey(cbz_progids);
193 RegCloseKey(epub_progids);
194 + RegCloseKey(djvu_progids);
195 RegCloseKey(fb2_progids);
197 RegCloseKey(dotpdf);
198 RegCloseKey(dotxps);
199 RegCloseKey(dotcbz);
200 RegCloseKey(dotepub);
201 + RegCloseKey(dotdjvu);
202 RegCloseKey(dotfb2);
204 RegCloseKey(classes);
205 @@ -94,7 +100,7 @@ int win_open_file(char *buf, int len)
206 ofn.lpstrFile = wbuf;
207 ofn.nMaxFile = 2048;
208 ofn.lpstrTitle = L"MuPDF: Open PDF file";
209 - ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.epub;*.fb2)\0*.pdf;*.xps;*.cbz;*.epub;*.fb2\0All Files\0*\0\0";
210 + ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.djvu;*.epub;*.fb2)\0*.pdf;*.xps;*.cbz;*.djvu;*.epub;*.fb2\0All Files\0*\0\0";
211 ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
212 code = GetOpenFileNameW(&ofn);
213 if (code)
214 diff --git a/platform/x11/win_main.c b/platform/x11/win_main.c
215 index 877f8c7..1621aec 100644
216 --- a/platform/x11/win_main.c
217 +++ b/platform/x11/win_main.c
218 @@ -61,7 +61,7 @@ static char filename[PATH_MAX];
219 void install_app(char *argv0)
221 char buf[512];
222 - HKEY software, classes, mupdf, dotpdf, dotxps, dotepub, dotfb2;
223 + HKEY software, classes, mupdf, dotpdf, dotxps, dotepub, dotdjvu, dotfb2;
224 HKEY shell, open, command, supported_types;
225 HKEY pdf_progids, xps_progids, epub_progids, fb2_progids;
227 @@ -73,6 +73,8 @@ void install_app(char *argv0)
228 OPEN_KEY(dotxps, "OpenWithProgids", xps_progids);
229 OPEN_KEY(classes, ".epub", dotepub);
230 OPEN_KEY(dotepub, "OpenWithProgids", epub_progids);
231 + OPEN_KEY(classes, ".djvu", dotdjvu);
232 + OPEN_KEY(dotepub, "OpenWithProgids", djvu_progids);
233 OPEN_KEY(classes, ".fb2", dotfb2);
234 OPEN_KEY(dotfb2, "OpenWithProgids", fb2_progids);
235 OPEN_KEY(classes, "MuPDF", mupdf);
236 @@ -88,12 +90,14 @@ void install_app(char *argv0)
237 SET_KEY(supported_types, ".pdf", "");
238 SET_KEY(supported_types, ".xps", "");
239 SET_KEY(supported_types, ".epub", "");
240 + SET_KEY(supported_types, ".djvu", "");
241 SET_KEY(pdf_progids, "MuPDF", "");
242 SET_KEY(xps_progids, "MuPDF", "");
243 SET_KEY(epub_progids, "MuPDF", "");
244 SET_KEY(fb2_progids, "MuPDF", "");
246 RegCloseKey(dotfb2);
247 + RegCloseKey(dotdjvu);
248 RegCloseKey(dotepub);
249 RegCloseKey(dotxps);
250 RegCloseKey(dotpdf);
251 @@ -199,7 +203,7 @@ int winfilename(wchar_t *buf, int len)
252 ofn.nMaxFile = len;
253 ofn.lpstrInitialDir = NULL;
254 ofn.lpstrTitle = L"MuPDF: Open PDF file";
255 - ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.epub;*.fb2;*.zip;*.png;*.jpeg;*.tiff)\0*.zip;*.cbz;*.xps;*.epub;*.fb2;*.pdf;*.jpe;*.jpg;*.jpeg;*.jfif;*.tif;*.tiff\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0EPUB Files (*.epub)\0*.epub\0FictionBook 2 Files (*.fb2)\0*.fb2\0Image Files (*.png;*.jpeg;*.tiff)\0*.png;*.jpg;*.jpe;*.jpeg;*.jfif;*.tif;*.tiff\0All Files\0*\0\0";
256 + ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.djvu;*.epub;*.fb2;*.zip;*.png;*.jpeg;*.tiff)\0*.zip;*.cbz;*.xps;*.djvu;*.epub;*.fb2;*.pdf;*.jpe;*.jpg;*.jpeg;*.jfif;*.tif;*.tiff\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0DjVu Files (*.djvu);EPUB Files (*.epub)\0*.epub\0FictionBook 2 Files (*.fb2)\0*.fb2\0Image Files (*.png;*.jpeg;*.tiff)\0*.png;*.jpg;*.jpe;*.jpeg;*.jfif;*.tif;*.tiff\0All Files\0*\0\0";
257 ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
258 return GetOpenFileNameW(&ofn);
260 diff --git a/source/djvu/djvu-doc.c b/source/djvu/djvu-doc.c
261 new file mode 100644
262 index 0000000..c973daa
263 --- /dev/null
264 +++ b/source/djvu/djvu-doc.c
265 @@ -0,0 +1,279 @@
266 +#include <string.h>
268 +#include "mupdf/fitz.h"
270 +#if FZ_ENABLE_DJVU
271 +#include <limits.h>
273 +#include <libdjvu/ddjvuapi.h>
274 +#include <libdjvu/miniexp.h>
276 +/* libdjvu defines this, but so does document.h */
277 +#ifdef inline
278 +#undef inline
279 +#endif
281 +/* XXX: Find a way to do this better */
282 +#define DPI 96.0f
284 +typedef struct djvu_document_s djvu_document;
285 +typedef struct djvu_page_s djvu_page;
287 +struct djvu_document_s
289 + fz_document super;
290 + char *filename;
291 + ddjvu_context_t *ddjvu_ctx;
292 + ddjvu_document_t *ddjvu_doc;
293 + int page_count;
294 + int header_complete;
295 + int want_stream0;
298 +struct djvu_page_s
300 + fz_page super;
301 + fz_image *image;
302 + int width;
303 + int height;
304 + int dpi;
307 +static void
308 +djvu_exhaust_messages(fz_context *ctx, djvu_document *doc)
310 + const ddjvu_message_t *msg;
312 + ddjvu_message_wait(doc->ddjvu_ctx);
314 + while ((msg = ddjvu_message_peek(doc->ddjvu_ctx)))
316 + switch(msg->m_any.tag)
318 + case DDJVU_ERROR:
319 + fz_throw(ctx, FZ_ERROR_GENERIC, "ddjvu: %s", msg->m_error.message);
320 + break;
321 + case DDJVU_NEWSTREAM:
322 + /* I don't particularly like this feature */
323 + printf("ddjvu: newstream\n\turl = %s\n\tname = %s\n\tstreamid = %d\n", msg->m_newstream.url, msg->m_newstream.name, msg->m_newstream.streamid);
324 + if (msg->m_newstream.streamid != 0)
325 + ddjvu_stream_close(doc->ddjvu_doc, msg->m_newstream.streamid, FALSE);
326 + else
327 + doc->want_stream0 = 1;
328 + break;
329 + case DDJVU_DOCINFO:
330 + doc->header_complete = 1;
331 + break;
332 + case DDJVU_PROGRESS:
333 + printf("ddjvu: reports %d%% progress\n", msg->m_progress.percent);
334 + break;
335 + case DDJVU_RELAYOUT:
336 + case DDJVU_PAGEINFO:
337 + case DDJVU_REDISPLAY:
338 + case DDJVU_CHUNK:
339 + case DDJVU_THUMBNAIL:
340 + case DDJVU_INFO:
341 + /* Ignore this chaff */
342 + break;
344 + ddjvu_message_pop(doc->ddjvu_ctx);
348 +static void
349 +djvu_drop_document(fz_context *ctx, fz_document *doc_)
351 + djvu_document *doc = (djvu_document *)doc_;
352 + ddjvu_job_stop(ddjvu_document_job(doc->ddjvu_doc));
353 + ddjvu_document_release(doc->ddjvu_doc);
354 + ddjvu_context_release(doc->ddjvu_ctx);
355 + doc->ddjvu_ctx = NULL;
358 +static int
359 +djvu_count_pages(fz_context *ctx, fz_document *doc_)
361 + djvu_document *doc = (djvu_document *)doc_;
362 + return doc->page_count;
365 +static fz_rect *
366 +djvu_bound_page(fz_context *ctx, fz_page *page_, fz_rect *bbox)
368 + djvu_page *page = (djvu_page *)page_;
369 + bbox->x0 = bbox->y0 = 0;
371 + bbox->x1 = page->width * DPI / page->dpi;
372 + bbox->y1 = page->height * DPI / page->dpi;
373 + return bbox;
376 +static void
377 +djvu_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
379 + fz_matrix local_ctm = *ctm;
380 + djvu_page *page = (djvu_page *)page_;
381 + fz_image *image = page->image;
382 + int xres, yres;
383 + float w, h;
385 + fz_image_resolution(image, &xres, &yres);
386 + w = page->width * DPI / xres;
387 + h = page->height * DPI / yres;
388 + fz_pre_scale(&local_ctm, w, h);
389 + fz_fill_image(ctx, dev, image, &local_ctm, 1, 0);
392 +static void djvu_drop_page(fz_context *ctx, fz_page *page_)
394 + djvu_page *page = (djvu_page *)page_;
395 + fz_drop_image(ctx, page->image);
398 +static djvu_page *
399 +djvu_load_page(fz_context *ctx, fz_document *doc_, int number)
401 + djvu_document *doc = (djvu_document *)doc_;
402 + djvu_page *page = NULL;
403 + ddjvu_status_t ddjvu_ret;
404 + ddjvu_page_t *ddjvu_page;
405 + ddjvu_pageinfo_t info;
406 + fz_colorspace *colorspace;
407 + fz_pixmap *pixmap;
408 + ddjvu_format_t *fmt;
409 + ddjvu_rect_t rect;
410 + char *buf;
412 + if (number < 0 || number >= doc->page_count)
413 + return NULL;
415 + while ((ddjvu_ret = ddjvu_document_get_pageinfo(doc->ddjvu_doc, number, &info)) < DDJVU_JOB_OK)
416 + djvu_exhaust_messages(ctx, doc);
417 + if (ddjvu_ret >= DDJVU_JOB_FAILED)
418 + fz_throw(ctx, FZ_ERROR_GENERIC, "DjVu pageinfo error");
420 + fz_var(page);
421 + fz_var(pixmap);
422 + fz_var(ddjvu_page);
423 + fz_var(colorspace);
424 + fz_var(fmt);
426 + fz_try(ctx)
428 + page = fz_new_derived_page(ctx, djvu_page);
429 + page->super.bound_page = (fz_page_bound_page_fn *)djvu_bound_page;
430 + page->super.run_page_contents = (fz_page_run_page_contents_fn *)djvu_run_page;
431 + page->super.drop_page = (fz_page_drop_page_fn *)djvu_drop_page;
433 + do {
434 + ddjvu_page = ddjvu_page_create_by_pageno(doc->ddjvu_doc, number);
435 + if (ddjvu_page == NULL)
436 + djvu_exhaust_messages(ctx, doc);
437 + } while (ddjvu_page == NULL);
439 + while (!ddjvu_page_decoding_done(ddjvu_page))
440 + djvu_exhaust_messages(ctx, doc);
442 + page->width = info.width;
443 + page->height = info.height;
444 + page->dpi = info.dpi;
446 + rect = (ddjvu_rect_t) {.x = 0, .y = 0, .w = page->width, .h = page->height};
447 + fmt = ddjvu_format_create(DDJVU_FORMAT_RGB24, 0, NULL);
448 + colorspace = fz_device_rgb(ctx);
449 + ddjvu_format_set_row_order(fmt, 1);
450 + buf = fz_calloc(ctx, page->width * 3 * page->height, 1);
451 + ddjvu_page_render(ddjvu_page, DDJVU_RENDER_COLOR, &rect, &rect, fmt, page->width * 3, buf);
452 + pixmap = fz_new_pixmap_with_data(ctx, colorspace, page->width, page->height, 0, 0, page->width * 3, (unsigned char *)buf);
453 + pixmap->flags |= FZ_PIXMAP_FLAG_FREE_SAMPLES;
454 + fz_set_pixmap_resolution(ctx, pixmap, page->dpi, page->dpi);
455 + page->image = fz_new_image_from_pixmap(ctx, pixmap, NULL);
457 + fz_always(ctx)
459 + fz_drop_pixmap(ctx, pixmap);
460 + fz_drop_colorspace(ctx, colorspace);
461 + ddjvu_format_release(fmt);
462 + ddjvu_page_release(ddjvu_page);
464 + fz_catch(ctx)
466 + djvu_drop_page(ctx, (fz_page *)page);
467 + page = NULL;
468 + fz_rethrow(ctx);
470 + return page;
473 +static int
474 +djvu_lookup_metadata(fz_context *ctx, fz_document *doc_, const char *key, char *buf, int size)
476 + if (!strcmp(key, "format"))
477 + return (int)fz_strlcpy(buf, "DjVu", size);
478 + return -1;
481 +static int
482 +djvu_recognize(fz_context *doc, const char *magic)
484 + char *ext = strrchr(magic, '.');
485 + if (ext)
486 + if (!fz_strcasecmp(ext, ".djvu"))
487 + return 50;
488 + if (!strcmp(magic, "image/vnd.djvu") || !strcmp(magic, "image/x.djvu") || !strcmp(magic, "image/x-djvu"))
489 + return 100;
491 + return 1;
494 +static djvu_document *
495 +djvu_open_document(fz_context *ctx, const char *filename)
497 + djvu_document *doc;
498 + doc = fz_new_document_of_size(ctx, sizeof *doc);
499 + doc->super.drop_document = (fz_document_drop_fn *)djvu_drop_document;
500 + doc->super.count_pages = (fz_document_count_pages_fn *)djvu_count_pages;
501 + doc->super.load_page = (fz_document_load_page_fn *)djvu_load_page;
502 + doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)djvu_lookup_metadata;
504 + fz_try(ctx)
506 + doc->filename = fz_strdup(ctx, filename);
508 + fz_catch(ctx)
510 + doc->filename = NULL;
513 + doc->ddjvu_ctx = ddjvu_context_create("mupdf");
514 + doc->ddjvu_doc = ddjvu_document_create_by_filename(doc->ddjvu_ctx, filename, 1);
515 + if (!doc->ddjvu_ctx)
516 + fz_throw(ctx, FZ_ERROR_GENERIC, "DjVU context creation failed");
518 + fz_try(ctx)
520 + while (!doc->header_complete)
521 + djvu_exhaust_messages(ctx, doc);
522 + doc->page_count = ddjvu_document_get_pagenum(doc->ddjvu_doc);
524 + fz_catch(ctx)
526 + fz_rethrow(ctx);
529 + return doc;
532 +static const char *djvu_extensions[] = { "djvu", 0 };
534 +static const char *djvu_mimetypes[] = { "image/vnd.djvu", 0 };
536 +fz_document_handler djvu_document_handler =
538 + (fz_document_recognize_fn *)&djvu_recognize,
539 + (fz_document_open_fn *)&djvu_open_document,
540 + (fz_document_open_with_stream_fn *) NULL,
541 + djvu_extensions,
542 + djvu_mimetypes,
544 +#endif /* FZ_ENABLE_DJVU */
545 diff --git a/source/fitz/document-all.c b/source/fitz/document-all.c
546 index 53969e2..10c444f 100644
547 --- a/source/fitz/document-all.c
548 +++ b/source/fitz/document-all.c
549 @@ -9,6 +9,7 @@ extern fz_document_handler tiff_document_handler;
550 extern fz_document_handler html_document_handler;
551 extern fz_document_handler epub_document_handler;
552 extern fz_document_handler gprf_document_handler;
553 +extern fz_document_handler djvu_document_handler;
555 void fz_register_document_handlers(fz_context *ctx)
557 @@ -39,4 +40,7 @@ void fz_register_document_handlers(fz_context *ctx)
558 #if FZ_ENABLE_GPRF
559 fz_register_document_handler(ctx, &gprf_document_handler);
560 #endif /* FZ_ENABLE_GPRF */
561 +#if FZ_ENABLE_DJVU
562 + fz_register_document_handler(ctx, &djvu_document_handler);
563 +#endif /* FZ_ENABLE_DJVU */
566 2.16.2