summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
-rw-r--r--apps/pdfapp.c57
-rw-r--r--apps/pdfapp.h1
-rw-r--r--apps/win_main.c3
-rw-r--r--apps/x11_main.c1
-rw-r--r--cbz/mucbz.c409
-rw-r--r--cbz/mucbz.h21
-rw-r--r--ios/document.c28
-rw-r--r--ios/document.h6
-rw-r--r--ios/main.m1
-rw-r--r--pdf/pdf_stream.c4
-rw-r--r--win32/libmupdf.vcproj12
-rw-r--r--win32/mupdf.vcproj6
13 files changed, 548 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 8d90711b..1b135074 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ GEN := generated
default: all
-CFLAGS += -Ifitz -Ipdf -Ixps -Iscripts
+CFLAGS += -Ifitz -Ipdf -Ixps -Icbz -Iscripts
LIBS += -lfreetype -ljbig2dec -ljpeg -lopenjpeg -lz -lm
include Makerules
@@ -54,6 +54,8 @@ $(OUT)/%.o : pdf/%.c fitz/fitz.h pdf/mupdf.h | $(OUT)
$(CC_CMD)
$(OUT)/%.o : xps/%.c fitz/fitz.h xps/muxps.h | $(OUT)
$(CC_CMD)
+$(OUT)/%.o : cbz/%.c fitz/fitz.h cbz/mucbz.h | $(OUT)
+ $(CC_CMD)
$(OUT)/%.o : apps/%.c fitz/fitz.h pdf/mupdf.h xps/muxps.h | $(OUT)
$(CC_CMD)
$(OUT)/%.o : scripts/%.c | $(OUT)
@@ -61,22 +63,25 @@ $(OUT)/%.o : scripts/%.c | $(OUT)
.PRECIOUS : $(OUT)/%.o # Keep intermediates from chained rules
-# --- Fitz, MuPDF and MuXPS libraries ---
+# --- Fitz, MuPDF, MuXPS and MuCBZ libraries ---
FITZ_LIB := $(OUT)/libfitz.a
MUPDF_LIB := $(OUT)/libmupdf.a
MUXPS_LIB := $(OUT)/libmuxps.a
+MUCBZ_LIB := $(OUT)/libmucbz.a
FITZ_SRC := $(notdir $(wildcard fitz/*.c draw/*.c))
FITZ_SRC := $(filter-out draw_simple_scale.c, $(FITZ_SRC))
MUPDF_SRC := $(notdir $(wildcard pdf/*.c))
MUXPS_SRC := $(notdir $(wildcard xps/*.c))
+MUCBZ_SRC := $(notdir $(wildcard cbz/*.c))
$(FITZ_LIB) : $(addprefix $(OUT)/, $(FITZ_SRC:%.c=%.o))
$(MUPDF_LIB) : $(addprefix $(OUT)/, $(MUPDF_SRC:%.c=%.o))
$(MUXPS_LIB) : $(addprefix $(OUT)/, $(MUXPS_SRC:%.c=%.o))
+$(MUCBZ_LIB) : $(addprefix $(OUT)/, $(MUCBZ_SRC:%.c=%.o))
-libs: $(MUXPS_LIB) $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS)
+libs: $(MUCBZ_LIB) $(MUXPS_LIB) $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS)
# --- Generated CMAP and FONT files ---
@@ -134,7 +139,7 @@ $(XPS_APPS) : $(MUXPS_LIB) $(FITZ_LIB) $(THIRD_LIBS)
$(BUSY_APP) : $(BUSY_LIBS) $(MUPDF_LIB) $(MUXPS_LIB) $(FITZ_LIB) $(THIRD_LIBS)
MUPDF := $(OUT)/mupdf
-$(MUPDF) : $(MUXPS_LIB) $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS)
+$(MUPDF) : $(MUCBZ_LIB) $(MUXPS_LIB) $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS)
ifeq "$(NOX11)" ""
$(MUPDF) : $(addprefix $(OUT)/, x11_main.o x11_image.o pdfapp.o)
$(LINK_CMD) $(X11_LIBS)
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 9a3b9d0f..74479a1c 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -1,6 +1,7 @@
#include "fitz.h"
#include "mupdf.h"
#include "muxps.h"
+#include "mucbz.h"
#include "pdfapp.h"
#include <ctype.h> /* for tolower() */
@@ -189,10 +190,32 @@ static void pdfapp_open_xps(pdfapp_t *app, char *filename, int fd)
app->pagecount = xps_count_pages(app->xps);
}
+static void pdfapp_open_cbz(pdfapp_t *app, char *filename, int fd)
+{
+ fz_stream *file;
+
+ file = fz_open_fd(app->ctx, fd);
+ fz_try(app->ctx)
+ {
+ app->cbz = cbz_open_document_with_stream(file);
+ }
+ fz_catch(app->ctx)
+ {
+ pdfapp_error(app, "cannot open document");
+ }
+ fz_close(file);
+
+ app->doctitle = fz_strdup(app->ctx, filename);
+
+ app->pagecount = cbz_count_pages(app->cbz);
+}
+
void pdfapp_open(pdfapp_t *app, char *filename, int fd, int reload)
{
if (strstr(filename, ".xps") || strstr(filename, ".XPS") || strstr(filename, ".rels"))
pdfapp_open_xps(app, filename, fd);
+ else if (strstr(filename, ".cbz") || strstr(filename, ".CBZ"))
+ pdfapp_open_cbz(app, filename, fd);
else
pdfapp_open_pdf(app, filename, fd);
@@ -254,6 +277,12 @@ void pdfapp_close(pdfapp_t *app)
app->xps = NULL;
}
+ if (app->cbz)
+ {
+ cbz_close_document(app->cbz);
+ app->cbz = NULL;
+ }
+
fz_flush_warnings(app->ctx);
}
@@ -349,6 +378,32 @@ static void pdfapp_loadpage_xps(pdfapp_t *app)
xps_free_page(app->xps, page);
}
+static void pdfapp_loadpage_cbz(pdfapp_t *app)
+{
+ cbz_page *page;
+ fz_device *mdev;
+
+ fz_try(app->ctx)
+ {
+ page = cbz_load_page(app->cbz, app->pageno - 1);
+ }
+ fz_catch(app->ctx)
+ {
+ pdfapp_error(app, "cannot load page");
+ }
+
+ app->page_bbox = cbz_bound_page(app->cbz, page);
+ app->page_links = NULL;
+
+ /* Create display list */
+ app->page_list = fz_new_display_list(app->ctx);
+ mdev = fz_new_list_device(app->ctx, app->page_list);
+ cbz_run_page(app->cbz, page, mdev, fz_identity, NULL);
+ fz_free_device(mdev);
+
+ cbz_free_page(app->cbz, page);
+}
+
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint)
{
char buf[256];
@@ -373,6 +428,8 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
pdfapp_loadpage_pdf(app);
if (app->xps)
pdfapp_loadpage_xps(app);
+ if (app->cbz)
+ pdfapp_loadpage_cbz(app);
/* Zero search hit position */
app->hit = -1;
diff --git a/apps/pdfapp.h b/apps/pdfapp.h
index c1b03be2..2dffb14e 100644
--- a/apps/pdfapp.h
+++ b/apps/pdfapp.h
@@ -32,6 +32,7 @@ struct pdfapp_s
/* current document params */
pdf_document *pdf;
xps_document *xps;
+ cbz_document *cbz;
char *doctitle;
fz_outline *outline;
diff --git a/apps/win_main.c b/apps/win_main.c
index dcc2d0a6..fc929a14 100644
--- a/apps/win_main.c
+++ b/apps/win_main.c
@@ -1,6 +1,7 @@
#include "fitz.h"
#include "mupdf.h"
#include "muxps.h"
+#include "mucbz.h"
#include "pdfapp.h"
#ifndef UNICODE
@@ -110,7 +111,7 @@ int winfilename(wchar_t *buf, int len)
ofn.nMaxFile = len;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = L"MuPDF: Open PDF file";
- ofn.lpstrFilter = L"Documents (*.pdf;*.xps)\0*.xps;*.pdf\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0All Files\0*\0\0";
+ ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz)\0*.cbz;*.xps;*.pdf\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*cbz)\0*.cbz\0All Files\0*\0\0";
ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
return GetOpenFileNameW(&ofn);
}
diff --git a/apps/x11_main.c b/apps/x11_main.c
index 907b843c..6815037a 100644
--- a/apps/x11_main.c
+++ b/apps/x11_main.c
@@ -1,6 +1,7 @@
#include "fitz.h"
#include "mupdf.h"
#include "muxps.h"
+#include "mucbz.h"
#include "pdfapp.h"
#include <X11/Xlib.h>
diff --git a/cbz/mucbz.c b/cbz/mucbz.c
new file mode 100644
index 00000000..4a633bcb
--- /dev/null
+++ b/cbz/mucbz.c
@@ -0,0 +1,409 @@
+#include "fitz.h"
+#include "mucbz.h"
+
+#include <zlib.h>
+
+#include <ctype.h> /* for tolower */
+
+#define ZIP_LOCAL_FILE_SIG 0x04034b50
+#define ZIP_CENTRAL_DIRECTORY_SIG 0x02014b50
+#define ZIP_END_OF_CENTRAL_DIRECTORY_SIG 0x06054b50
+
+#define DPI (72.0f / 144.0f)
+
+static const char *cbz_ext_list[] = {
+ ".jpg", ".jpeg", ".png",
+ ".JPG", ".JPEG", ".PNG",
+ NULL
+};
+
+struct cbz_page_s
+{
+ fz_pixmap *image;
+};
+
+typedef struct cbz_entry_s cbz_entry;
+
+struct cbz_entry_s
+{
+ char *name;
+ int offset;
+};
+
+struct cbz_document_s
+{
+ fz_context *ctx;
+ fz_stream *file;
+ int entry_count;
+ cbz_entry *entry;
+ int page_count;
+ int *page;
+};
+
+static inline int getshort(fz_stream *file)
+{
+ int a = fz_read_byte(file);
+ int b = fz_read_byte(file);
+ return a | b << 8;
+}
+
+static inline int getlong(fz_stream *file)
+{
+ int a = fz_read_byte(file);
+ int b = fz_read_byte(file);
+ int c = fz_read_byte(file);
+ int d = fz_read_byte(file);
+ return a | b << 8 | c << 16 | d << 24;
+}
+
+static void *
+cbz_zip_alloc_items(void *ctx, unsigned int items, unsigned int size)
+{
+ return fz_malloc_array(ctx, items, size);
+}
+
+static void
+cbz_zip_free(void *ctx, void *ptr)
+{
+ fz_free(ctx, ptr);
+}
+
+static unsigned char *
+cbz_read_zip_entry(cbz_document *doc, int offset, int *sizep)
+{
+ fz_context *ctx = doc->ctx;
+ fz_stream *file = doc->file;
+ int sig, method, namelength, extralength;
+ unsigned long csize, usize;
+ unsigned char *cdata;
+ int code;
+
+ fz_seek(file, offset, 0);
+
+ sig = getlong(doc->file);
+ if (sig != ZIP_LOCAL_FILE_SIG)
+ fz_throw(ctx, "wrong zip local file signature (0x%x)", sig);
+
+ (void) getshort(doc->file); /* version */
+ (void) getshort(doc->file); /* general */
+ method = getshort(doc->file);
+ (void) getshort(doc->file); /* file time */
+ (void) getshort(doc->file); /* file date */
+ (void) getlong(doc->file); /* crc-32 */
+ csize = getlong(doc->file); /* csize */
+ usize = getlong(doc->file); /* usize */
+ namelength = getshort(doc->file);
+ extralength = getshort(doc->file);
+
+ fz_seek(file, namelength + extralength, 1);
+
+ cdata = fz_malloc(ctx, csize);
+ fz_try(ctx)
+ {
+ fz_read(file, cdata, csize);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, cdata);
+ fz_rethrow(ctx);
+ }
+
+ if (method == 0)
+ {
+ *sizep = usize;
+ return cdata;
+ }
+
+ if (method == 8)
+ {
+ unsigned char *udata = fz_malloc(ctx, usize);
+ z_stream stream;
+
+ memset(&stream, 0, sizeof stream);
+ stream.zalloc = cbz_zip_alloc_items;
+ stream.zfree = cbz_zip_free;
+ stream.opaque = ctx;
+ stream.next_in = cdata;
+ stream.avail_in = csize;
+ stream.next_out = udata;
+ stream.avail_out = usize;
+
+ fz_try(ctx)
+ {
+ code = inflateInit2(&stream, -15);
+ if (code != Z_OK)
+ fz_throw(ctx, "zlib inflateInit2 error: %s", stream.msg);
+ code = inflate(&stream, Z_FINISH);
+ if (code != Z_STREAM_END) {
+ inflateEnd(&stream);
+ fz_throw(ctx, "zlib inflate error: %s", stream.msg);
+ }
+ code = inflateEnd(&stream);
+ if (code != Z_OK)
+ fz_throw(ctx, "zlib inflateEnd error: %s", stream.msg);
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, cdata);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, udata);
+ fz_rethrow(ctx);
+ }
+
+ *sizep = usize;
+ return udata;
+ }
+
+ fz_throw(ctx, "unknown zip method: %d", method);
+ return NULL; /* not reached */
+}
+
+static int
+cbz_compare_entries(const void *a_, const void *b_)
+{
+ const cbz_entry *a = a_;
+ const cbz_entry *b = b_;
+ return strcmp(a->name, b->name);
+}
+
+static void
+cbz_read_zip_dir_imp(cbz_document *doc, int startoffset)
+{
+ fz_context *ctx = doc->ctx;
+ fz_stream *file = doc->file;
+ int sig, offset, count;
+ int namesize, metasize, commentsize;
+ int i, k;
+
+ fz_seek(file, startoffset, 0);
+
+ sig = getlong(file);
+ if (sig != ZIP_END_OF_CENTRAL_DIRECTORY_SIG)
+ fz_throw(ctx, "wrong zip end of central directory signature (0x%x)", sig);
+
+ (void) getshort(file); /* this disk */
+ (void) getshort(file); /* start disk */
+ (void) getshort(file); /* entries in this disk */
+ count = getshort(file); /* entries in central directory disk */
+ (void) getlong(file); /* size of central directory */
+ offset = getlong(file); /* offset to central directory */
+
+ doc->entry_count = count;
+ doc->entry = fz_malloc_array(ctx, count, sizeof(cbz_entry));
+
+ fz_seek(file, offset, 0);
+
+ for (i = 0; i < count; i++)
+ {
+ cbz_entry *entry = doc->entry + i;
+
+ sig = getlong(doc->file);
+ if (sig != ZIP_CENTRAL_DIRECTORY_SIG)
+ fz_throw(doc->ctx, "wrong zip central directory signature (0x%x)", sig);
+
+ (void) getshort(file); /* version made by */
+ (void) getshort(file); /* version to extract */
+ (void) getshort(file); /* general */
+ (void) getshort(file); /* method */
+ (void) getshort(file); /* last mod file time */
+ (void) getshort(file); /* last mod file date */
+ (void) getlong(file); /* crc-32 */
+ (void) getlong(file); /* csize */
+ (void) getlong(file); /* usize */
+ namesize = getshort(file);
+ metasize = getshort(file);
+ commentsize = getshort(file);
+ (void) getshort(file); /* disk number start */
+ (void) getshort(file); /* int file atts */
+ (void) getlong(file); /* ext file atts */
+ entry->offset = getlong(file);
+
+ entry->name = malloc(namesize + 1);
+ fz_read(file, (unsigned char *)entry->name, namesize);
+ entry->name[namesize] = 0;
+
+ fz_seek(file, metasize, 1);
+ fz_seek(file, commentsize, 1);
+ }
+
+ qsort(doc->entry, count, sizeof(cbz_entry), cbz_compare_entries);
+
+ doc->page_count = 0;
+ doc->page = fz_malloc_array(ctx, count, sizeof(int));
+
+ for (i = 0; i < count; i++)
+ for (k = 0; cbz_ext_list[k]; k++)
+ if (strstr(doc->entry[i].name, cbz_ext_list[k]))
+ doc->page[doc->page_count++] = i;
+}
+
+static void
+cbz_read_zip_dir(cbz_document *doc)
+{
+ fz_stream *file = doc->file;
+ unsigned char buf[512];
+ int filesize, back, maxback;
+ int i, n;
+
+ fz_seek(file, 0, 2);
+ filesize = fz_tell(file);
+
+ maxback = MIN(filesize, 0xFFFF + sizeof buf);
+ back = MIN(maxback, sizeof buf);
+
+ while (back < maxback)
+ {
+ fz_seek(file, filesize - back, 0);
+ n = fz_read(file, buf, sizeof buf);
+ for (i = n - 4; i > 0; i--)
+ {
+ if (!memcmp(buf + i, "PK\5\6", 4))
+ {
+ cbz_read_zip_dir_imp(doc, filesize - back + i);
+ return;
+ }
+ }
+ back += sizeof buf - 4;
+ }
+
+ fz_throw(doc->ctx, "cannot find end of central directory");
+}
+
+cbz_document *
+cbz_open_document_with_stream(fz_stream *file)
+{
+ fz_context *ctx = file->ctx;
+ cbz_document *doc;
+
+ doc = fz_malloc_struct(ctx, cbz_document);
+ doc->ctx = ctx;
+ doc->file = fz_keep_stream(file);
+ doc->entry_count = 0;
+ doc->entry = NULL;
+ doc->page_count = 0;
+ doc->page = NULL;
+
+ fz_try(ctx)
+ {
+ cbz_read_zip_dir(doc);
+ }
+ fz_catch(ctx)
+ {
+ cbz_close_document(doc);
+ fz_rethrow(ctx);
+ }
+
+ return doc;
+}
+
+cbz_document *
+cbz_open_document(fz_context *ctx, char *filename)
+{
+ fz_stream *file;
+ cbz_document *doc;
+
+ file = fz_open_file(ctx, filename);
+ if (!file)
+ fz_throw(ctx, "cannot open file '%s': %s", filename, strerror(errno));
+
+ fz_try(ctx) {
+ doc = cbz_open_document_with_stream(file);
+ } fz_always(ctx) {
+ fz_close(file);
+ } fz_catch(ctx) {
+ fz_rethrow(ctx);
+ }
+
+ return doc;
+}
+
+void
+cbz_close_document(cbz_document *doc)
+{
+ int i;
+ fz_context *ctx = doc->ctx;
+ for (i = 0; i < doc->entry_count; i++)
+ fz_free(ctx, doc->entry[i].name);
+ fz_free(ctx, doc->entry);
+ fz_free(ctx, doc->page);
+ fz_close(doc->file);
+ fz_free(ctx, doc);
+}
+
+int
+cbz_count_pages(cbz_document *doc)
+{
+ return doc->page_count;
+}
+
+cbz_page *
+cbz_load_page(cbz_document *doc, int number)
+{
+ fz_context *ctx = doc->ctx;
+ unsigned char *data = NULL;
+ cbz_page *page = NULL;
+ int size;
+
+ if (number < 0 || number >= doc->page_count)
+ return NULL;
+
+ number = doc->page[number];
+
+ fz_var(data);
+ fz_var(page);
+ fz_try(ctx)
+ {
+ page = fz_malloc_struct(doc->ctx, cbz_page);
+ page->image = NULL;
+
+ data = cbz_read_zip_entry(doc, doc->entry[number].offset, &size);
+
+ if (data[0] == 0xff && data[1] == 0xd8)
+ page->image = fz_load_jpeg(ctx, data, size);
+ else if (memcmp(data, "\211PNG\r\n\032\n", 8) == 0)
+ page->image = fz_load_png(ctx, data, size);
+ else
+ fz_throw(ctx, "unknown image format");
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, data);
+ }
+ fz_catch(ctx)
+ {
+ if (page && page->image)
+ fz_drop_pixmap(ctx, page->image);
+ fz_free(ctx, page);
+ fz_rethrow(ctx);
+ }
+
+ return page;
+}
+
+void
+cbz_free_page(cbz_document *doc, cbz_page *page)
+{
+ fz_drop_pixmap(doc->ctx, page->image);
+ fz_free(doc->ctx, page);
+}
+
+fz_rect
+cbz_bound_page(cbz_document *doc, cbz_page *page)
+{
+ fz_pixmap *image = page->image;
+ fz_rect bbox;
+ bbox.x0 = bbox.y0 = 0;
+ bbox.x1 = image->w * DPI;
+ bbox.y1 = image->h * DPI;
+ return bbox;
+}
+
+void
+cbz_run_page(cbz_document *doc, cbz_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie)
+{
+ fz_pixmap *image = page->image;
+ ctm = fz_concat(fz_scale(image->w * DPI, image->h * DPI), ctm);
+ fz_fill_image(dev, image, ctm, 1);
+}
diff --git a/cbz/mucbz.h b/cbz/mucbz.h
new file mode 100644
index 00000000..e18a7474
--- /dev/null
+++ b/cbz/mucbz.h
@@ -0,0 +1,21 @@
+#ifndef _MUCBZ_H_
+#define _MUCBZ_H_
+
+#ifndef _FITZ_H_
+#error "fitz.h must be included before mucbz.h"
+#endif
+
+typedef struct cbz_document_s cbz_document;
+typedef struct cbz_page_s cbz_page;
+
+cbz_document *cbz_open_document(fz_context *ctx, char *filename);
+cbz_document *cbz_open_document_with_stream(fz_stream *file);
+void cbz_close_document(cbz_document *doc);
+
+int cbz_count_pages(cbz_document *doc);
+cbz_page *cbz_load_page(cbz_document *doc, int number);
+fz_rect cbz_bound_page(cbz_document *doc, cbz_page *page);
+void cbz_free_page(cbz_document *doc, cbz_page *page);
+void cbz_run_page(cbz_document *doc, cbz_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+
+#endif
diff --git a/ios/document.c b/ios/document.c
index 9c209046..d17d1392 100644
--- a/ios/document.c
+++ b/ios/document.c
@@ -1,6 +1,7 @@
#include "fitz/fitz.h"
#include "pdf/mupdf.h"
#include "xps/muxps.h"
+#include "cbz/mucbz.h"
#include "document.h"
#include <ctype.h> /* for tolower() */
@@ -21,6 +22,8 @@ open_document(fz_context *ctx, char *filename)
doc->pdf = pdf_open_document(ctx, filename);
else if (strstr(filename, ".xps") || strstr(filename, ".XPS"))
doc->xps = xps_open_document(ctx, filename);
+ else if (strstr(filename, ".cbz") || strstr(filename, ".CBZ"))
+ doc->cbz = cbz_open_document(ctx, filename);
else
fz_throw(ctx, "unknown document format");
}
@@ -77,6 +80,8 @@ count_pages(struct document *doc)
return pdf_count_pages(doc->pdf);
else if (doc->xps)
return xps_count_pages(doc->xps);
+ else if (doc->cbz)
+ return cbz_count_pages(doc->cbz);
else
return 1;
}
@@ -101,6 +106,12 @@ load_page(struct document *doc, int number)
doc->xps_page = NULL;
doc->xps_page = xps_load_page(doc->xps, number);
}
+ if (doc->cbz) {
+ if (doc->cbz_page)
+ cbz_free_page(doc->cbz, doc->cbz_page);
+ doc->cbz_page = NULL;
+ doc->cbz_page = cbz_load_page(doc->cbz, number);
+ }
}
fz_catch (doc->ctx)
{
@@ -122,6 +133,11 @@ measure_page(struct document *doc, int number, float *w, float *h)
*w = bounds.x1 - bounds.x0;
*h = bounds.y1 - bounds.y0;
}
+ else if (doc->cbz_page) {
+ fz_rect bounds = cbz_bound_page(doc->cbz, doc->cbz_page);
+ *w = bounds.x1 - bounds.x0;
+ *h = bounds.y1 - bounds.y0;
+ }
else {
*w = *h = 72;
}
@@ -134,11 +150,12 @@ draw_page(struct document *doc, int number, fz_device *dev, fz_matrix ctm, fz_co
load_page(doc, number);
fz_try (doc->ctx)
{
- if (doc->pdf_page) {
+ if (doc->pdf_page)
pdf_run_page(doc->pdf, doc->pdf_page, dev, ctm, cookie);
- } else if (doc->xps_page) {
+ else if (doc->xps_page)
xps_run_page(doc->xps, doc->xps_page, dev, ctm, cookie);
- }
+ else if (doc->cbz_page)
+ cbz_run_page(doc->cbz, doc->cbz_page, dev, ctm, cookie);
}
fz_catch (doc->ctx)
{
@@ -264,6 +281,11 @@ close_document(struct document *doc)
xps_free_page(doc->xps, doc->xps_page);
xps_close_document(doc->xps);
}
+ if (doc->cbz) {
+ if (doc->cbz_page)
+ cbz_free_page(doc->cbz, doc->cbz_page);
+ cbz_close_document(doc->cbz);
+ }
fz_flush_warnings(doc->ctx);
fz_free(doc->ctx, doc);
}
diff --git a/ios/document.h b/ios/document.h
index 5e3c740e..0003070e 100644
--- a/ios/document.h
+++ b/ios/document.h
@@ -13,14 +13,20 @@
#error "muxps.h must be included before document.h"
#endif
+#ifndef _MUCBZ_H_
+#error "mucbz.h must be included before document.h"
+#endif
+
struct document
{
fz_context *ctx;
pdf_document *pdf;
xps_document *xps;
+ cbz_document *cbz;
int number;
pdf_page *pdf_page;
xps_page *xps_page;
+ cbz_page *cbz_page;
fz_bbox hit_bbox[500];
int hit_count;
};
diff --git a/ios/main.m b/ios/main.m
index 582d4e88..1ed6246c 100644
--- a/ios/main.m
+++ b/ios/main.m
@@ -7,6 +7,7 @@
#include "fitz/fitz.h"
#include "pdf/mupdf.h"
#include "xps/muxps.h"
+#include "cbz/mucbz.h"
#include "document.h"
diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c
index 8a1caa9c..322fe3b7 100644
--- a/pdf/pdf_stream.c
+++ b/pdf/pdf_stream.c
@@ -51,10 +51,8 @@ pdf_stream_has_crypt(fz_context *ctx, fz_obj *stm)
static fz_stream *
build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int num, int gen)
{
- char *s;
fz_context *ctx = chain->ctx;
-
- s = fz_to_name(f);
+ char *s = fz_to_name(f);
int predictor = fz_to_int(fz_dict_gets(p, "Predictor"));
int columns = fz_to_int(fz_dict_gets(p, "Columns"));
diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj
index 180e8837..b34426c0 100644
--- a/win32/libmupdf.vcproj
+++ b/win32/libmupdf.vcproj
@@ -623,6 +623,18 @@
>
</File>
</Filter>
+ <Filter
+ Name="cbz"
+ >
+ <File
+ RelativePath="..\cbz\mucbz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\cbz\mucbz.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
diff --git a/win32/mupdf.vcproj b/win32/mupdf.vcproj
index c61cb34d..3bbc83a9 100644
--- a/win32/mupdf.vcproj
+++ b/win32/mupdf.vcproj
@@ -39,7 +39,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps"
+ AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps;..\cbz"
PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -113,7 +113,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps"
+ AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps;..\cbz"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
WarningLevel="3"
@@ -185,7 +185,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps"
+ AdditionalIncludeDirectories="..\fitz;..\pdf;..\xps;..\cbz"
PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;MEMENTO=1;DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"