summaryrefslogtreecommitdiff
path: root/source/cbz
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-01-21 16:42:45 +0100
committerTor Andersson <tor.andersson@artifex.com>2015-02-17 18:05:39 +0100
commitf84a189d5f94250e46d2cbd1a75aba00130e2dd6 (patch)
tree8ee614ab90de1baa8941f91ae4946ed5c2e70721 /source/cbz
parent681039767f2ccc72e236246178893eb0989169c9 (diff)
downloadmupdf-f84a189d5f94250e46d2cbd1a75aba00130e2dd6.tar.xz
Add ctx parameter and remove embedded contexts for API regularity.
Purge several embedded contexts: Remove embedded context in fz_output. Remove embedded context in fz_stream. Remove embedded context in fz_device. Remove fz_rebind_stream (since it is no longer necessary). Remove embedded context in svg_device. Remove embedded context in XML parser. Add ctx argument to fz_document functions. Remove embedded context in fz_document. Remove embedded context in pdf_document. Remove embedded context in pdf_obj. Make fz_page independent of fz_document in the interface. We shouldn't need to pass the document to all functions handling a page. If a page is tied to the source document, it's redundant; otherwise it's just pointless. Fix reference counting oddity in fz_new_image_from_pixmap.
Diffstat (limited to 'source/cbz')
-rw-r--r--source/cbz/mucbz.c205
-rw-r--r--source/cbz/muimg.c187
-rw-r--r--source/cbz/mutiff.c207
3 files changed, 481 insertions, 118 deletions
diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c
index 72b6a185..75148490 100644
--- a/source/cbz/mucbz.c
+++ b/source/cbz/mucbz.c
@@ -1,8 +1,9 @@
-#include "mupdf/cbz.h"
+#include "mupdf/fitz.h"
#define DPI 72.0f
-static void cbz_init_document(cbz_document *doc);
+typedef struct cbz_document_s cbz_document;
+typedef struct cbz_page_s cbz_page;
static const char *cbz_ext_list[] = {
".jpg", ".jpeg", ".png",
@@ -12,13 +13,13 @@ static const char *cbz_ext_list[] = {
struct cbz_page_s
{
+ fz_page super;
fz_image *image;
};
struct cbz_document_s
{
fz_document super;
- fz_context *ctx;
fz_archive *zip;
int page_count;
const char **page;
@@ -73,9 +74,8 @@ cbz_compare_page_names(const void *a, const void *b)
}
static void
-cbz_create_page_list(cbz_document *doc)
+cbz_create_page_list(fz_context *ctx, cbz_document *doc)
{
- fz_context *ctx = doc->ctx;
fz_archive *zip = doc->zip;
int i, k, count;
@@ -92,87 +92,68 @@ cbz_create_page_list(cbz_document *doc)
if (strstr(name, cbz_ext_list[k]))
{
doc->page[doc->page_count++] = name;
-printf("found page %d = '%s'\n", i, name);
break;
}
}
}
qsort((char **)doc->page, doc->page_count, sizeof *doc->page, cbz_compare_page_names);
-
- for (i = 0; i < doc->page_count; ++i)
- printf(" %d = %s\n", i, doc->page[i]);
}
-cbz_document *
-cbz_open_document_with_stream(fz_context *ctx, fz_stream *file)
+static void
+cbz_close_document(fz_context *ctx, cbz_document *doc)
{
- cbz_document *doc;
-
- doc = fz_malloc_struct(ctx, cbz_document);
- cbz_init_document(doc);
- doc->ctx = ctx;
- doc->page_count = 0;
- doc->page = NULL;
-
- fz_try(ctx)
- {
- doc->zip = fz_open_archive_with_stream(ctx, file);
- cbz_create_page_list(doc);
- }
- fz_catch(ctx)
- {
- cbz_close_document(doc);
- fz_rethrow(ctx);
- }
-
- return doc;
+ fz_drop_archive(ctx, doc->zip);
+ fz_free(ctx, (char **)doc->page);
+ fz_free(ctx, doc);
}
-cbz_document *
-cbz_open_document(fz_context *ctx, const char *filename)
+static int
+cbz_count_pages(fz_context *ctx, cbz_document *doc)
{
- fz_stream *file;
- cbz_document *doc;
-
- file = fz_open_file(ctx, filename);
- if (!file)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
+ return doc->page_count;
+}
- fz_try(ctx)
- {
- doc = cbz_open_document_with_stream(ctx, file);
- }
- fz_always(ctx)
- {
- fz_drop_stream(file);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
+static fz_rect *
+cbz_bound_page(fz_context *ctx, cbz_page *page, fz_rect *bbox)
+{
+ fz_image *image = page->image;
+ int xres, yres;
- return doc;
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ bbox->x0 = bbox->y0 = 0;
+ bbox->x1 = image->w * DPI / xres;
+ bbox->y1 = image->h * DPI / yres;
+ return bbox;
}
-void
-cbz_close_document(cbz_document *doc)
+static void
+cbz_run_page(fz_context *ctx, cbz_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
{
- fz_drop_archive(doc->ctx, doc->zip);
- fz_free(doc->ctx, (char **)doc->page);
- fz_free(doc->ctx, doc);
+ fz_matrix local_ctm = *ctm;
+ fz_image *image = page->image;
+ int xres, yres;
+ float w, h;
+
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ w = image->w * DPI / xres;
+ h = image->h * DPI / yres;
+ fz_pre_scale(&local_ctm, w, h);
+ fz_fill_image(ctx, dev, image, &local_ctm, 1);
}
-int
-cbz_count_pages(cbz_document *doc)
+static void
+cbz_drop_page_imp(fz_context *ctx, cbz_page *page)
{
- return doc->page_count;
+ if (!page)
+ return;
+ fz_drop_image(ctx, page->image);
+ fz_free(ctx, page);
}
-cbz_page *
-cbz_load_page(cbz_document *doc, int number)
+static cbz_page *
+cbz_load_page(fz_context *ctx, cbz_document *doc, int number)
{
- fz_context *ctx = doc->ctx;
unsigned char *data = NULL;
cbz_page *page = NULL;
fz_buffer *buf;
@@ -183,65 +164,31 @@ cbz_load_page(cbz_document *doc, int number)
fz_var(data);
fz_var(page);
- buf = fz_read_archive_entry(doc->ctx, doc->zip, doc->page[number]);
+ buf = fz_read_archive_entry(ctx, doc->zip, doc->page[number]);
fz_try(ctx)
{
- page = fz_malloc_struct(ctx, cbz_page);
+ page = fz_new_page(ctx, sizeof *page);
+ page->super.bound_page = (fz_page_bound_page_fn *)cbz_bound_page;
+ page->super.run_page_contents = (fz_page_run_page_contents_fn *)cbz_run_page;
+ page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)cbz_drop_page_imp;
page->image = fz_new_image_from_buffer(ctx, buf);
}
fz_always(ctx)
{
- fz_drop_buffer(doc->ctx, buf);
+ fz_drop_buffer(ctx, buf);
}
fz_catch(ctx)
{
fz_free(ctx, data);
- cbz_free_page(doc, page);
+ cbz_drop_page_imp(ctx, page);
fz_rethrow(ctx);
}
return page;
}
-void
-cbz_free_page(cbz_document *doc, cbz_page *page)
-{
- if (!page)
- return;
- fz_drop_image(doc->ctx, page->image);
- fz_free(doc->ctx, page);
-}
-
-fz_rect *
-cbz_bound_page(cbz_document *doc, cbz_page *page, fz_rect *bbox)
-{
- fz_image *image = page->image;
- int xres, yres;
-
- fz_image_get_sanitised_res(image, &xres, &yres);
- bbox->x0 = bbox->y0 = 0;
- bbox->x1 = image->w * DPI / xres;
- bbox->y1 = image->h * DPI / yres;
- return bbox;
-}
-
-void
-cbz_run_page(cbz_document *doc, cbz_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
-{
- fz_matrix local_ctm = *ctm;
- fz_image *image = page->image;
- int xres, yres;
- float w, h;
-
- fz_image_get_sanitised_res(image, &xres, &yres);
- w = image->w * DPI / xres;
- h = image->h * DPI / yres;
- fz_pre_scale(&local_ctm, w, h);
- fz_fill_image(dev, image, &local_ctm, 1);
-}
-
static int
-cbz_meta(cbz_document *doc, int key, void *ptr, int size)
+cbz_meta(fz_context *ctx, cbz_document *doc, int key, void *ptr, int size)
{
switch (key)
{
@@ -253,25 +200,47 @@ cbz_meta(cbz_document *doc, int key, void *ptr, int size)
}
}
-static void
-cbz_rebind(cbz_document *doc, fz_context *ctx)
+static cbz_document *
+cbz_open_document_with_stream(fz_context *ctx, fz_stream *file)
{
- doc->ctx = ctx;
- fz_rebind_archive(doc->zip, ctx);
-}
+ cbz_document *doc = fz_new_document(ctx, sizeof *doc);
-static void
-cbz_init_document(cbz_document *doc)
-{
- doc->super.refs = 1;
doc->super.close = (fz_document_close_fn *)cbz_close_document;
doc->super.count_pages = (fz_document_count_pages_fn *)cbz_count_pages;
doc->super.load_page = (fz_document_load_page_fn *)cbz_load_page;
- doc->super.bound_page = (fz_document_bound_page_fn *)cbz_bound_page;
- doc->super.run_page_contents = (fz_document_run_page_contents_fn *)cbz_run_page;
- doc->super.free_page = (fz_document_free_page_fn *)cbz_free_page;
doc->super.meta = (fz_document_meta_fn *)cbz_meta;
- doc->super.rebind = (fz_document_rebind_fn *)cbz_rebind;
+
+ fz_try(ctx)
+ {
+ doc->zip = fz_open_archive_with_stream(ctx, file);
+ cbz_create_page_list(ctx, doc);
+ }
+ fz_catch(ctx)
+ {
+ cbz_close_document(ctx, doc);
+ fz_rethrow(ctx);
+ }
+ return doc;
+}
+
+static cbz_document *
+cbz_open_document(fz_context *ctx, const char *filename)
+{
+ fz_stream *file;
+ cbz_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 = cbz_open_document_with_stream(ctx, file);
+ fz_always(ctx)
+ fz_drop_stream(ctx, file);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+
+ return doc;
}
static int
diff --git a/source/cbz/muimg.c b/source/cbz/muimg.c
new file mode 100644
index 00000000..a288a4f4
--- /dev/null
+++ b/source/cbz/muimg.c
@@ -0,0 +1,187 @@
+#include "mupdf/fitz.h"
+
+#define DPI 72.0f
+
+typedef struct img_document_s img_document;
+typedef struct img_page_s img_page;
+
+struct img_page_s
+{
+ fz_page super;
+ fz_image *image;
+};
+
+struct img_document_s
+{
+ fz_document super;
+ fz_image *image;
+};
+
+static void
+img_close_document(fz_context *ctx, img_document *doc)
+{
+ fz_drop_image(ctx, doc->image);
+ fz_free(ctx, doc);
+}
+
+static int
+img_count_pages(fz_context *ctx, img_document *doc)
+{
+ return 1;
+}
+
+static fz_rect *
+img_bound_page(fz_context *ctx, img_page *page, fz_rect *bbox)
+{
+ fz_image *image = (fz_image *)page;
+ int xres, yres;
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ bbox->x0 = bbox->y0 = 0;
+ bbox->x1 = image->w * DPI / xres;
+ bbox->y1 = image->h * DPI / yres;
+ return bbox;
+}
+
+static void
+img_run_page(fz_context *ctx, img_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
+{
+ fz_matrix local_ctm = *ctm;
+ fz_image *image = (fz_image *)page;
+ int xres, yres;
+ float w, h;
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ w = image->w * DPI / xres;
+ h = image->h * DPI / yres;
+ fz_pre_scale(&local_ctm, w, h);
+ fz_fill_image(ctx, dev, image, &local_ctm, 1);
+}
+
+static void
+img_drop_page_imp(fz_context *ctx, img_page *page)
+{
+ fz_drop_image(ctx, page->image);
+}
+
+static img_page *
+img_load_page(fz_context *ctx, img_document *doc, int number)
+{
+ img_page *page;
+
+ if (number != 0)
+ return NULL;
+
+ page = fz_new_page(ctx, sizeof *page);
+
+ page->super.bound_page = (fz_page_bound_page_fn *)img_bound_page;
+ page->super.run_page_contents = (fz_page_run_page_contents_fn *)img_run_page;
+ page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)img_drop_page_imp;
+
+ page->image = fz_keep_image(ctx, doc->image);
+
+ return page;
+}
+
+static int
+img_meta(fz_context *ctx, img_document *doc, int key, void *ptr, int size)
+{
+ switch(key)
+ {
+ case FZ_META_FORMAT_INFO:
+ sprintf((char *)ptr, "IMAGE");
+ return FZ_META_OK;
+ default:
+ return FZ_META_UNKNOWN_KEY;
+ }
+}
+
+static img_document *
+img_new_document(fz_context *ctx, fz_image *image)
+{
+ img_document *doc = fz_new_document(ctx, sizeof *doc);
+
+ doc->super.close = (fz_document_close_fn *)img_close_document;
+ doc->super.count_pages = (fz_document_count_pages_fn *)img_count_pages;
+ doc->super.load_page = (fz_document_load_page_fn *)img_load_page;
+ doc->super.meta = (fz_document_meta_fn *)img_meta;
+
+ doc->image = fz_keep_image(ctx, image);
+
+ return doc;
+}
+
+static img_document *
+img_open_document_with_stream(fz_context *ctx, fz_stream *stm)
+{
+ fz_buffer *buffer = NULL;
+ fz_image *image = NULL;
+ img_document *doc;
+
+ fz_var(buffer);
+ fz_var(image);
+
+ fz_try(ctx)
+ {
+ buffer = fz_read_all(ctx, stm, 1024);
+ image = fz_new_image_from_buffer(ctx, buffer);
+ doc = img_new_document(ctx, image);
+ }
+ fz_always(ctx)
+ {
+ fz_drop_buffer(ctx, buffer);
+ fz_drop_stream(ctx, stm);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+
+ return doc;
+}
+
+static img_document *
+img_open_document(fz_context *ctx, const char *filename)
+{
+ fz_stream *stm;
+ img_document *doc;
+
+ stm = fz_open_file(ctx, filename);
+ if (!stm)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
+
+ fz_try(ctx)
+ doc = img_open_document_with_stream(ctx, stm);
+ fz_always(ctx)
+ fz_drop_stream(ctx, stm);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+
+ return doc;
+}
+
+static int
+img_recognize(fz_context *doc, const char *magic)
+{
+ char *ext = strrchr(magic, '.');
+
+ if (ext)
+ {
+ 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"))
+ 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"))
+ return 100;
+
+ return 0;
+}
+
+fz_document_handler img_document_handler =
+{
+ (fz_document_recognize_fn *)&img_recognize,
+ (fz_document_open_fn *)&img_open_document,
+ (fz_document_open_with_stream_fn *)&img_open_document_with_stream
+};
diff --git a/source/cbz/mutiff.c b/source/cbz/mutiff.c
new file mode 100644
index 00000000..c03cb3b7
--- /dev/null
+++ b/source/cbz/mutiff.c
@@ -0,0 +1,207 @@
+#include "mupdf/fitz.h"
+
+typedef struct tiff_document_s tiff_document;
+typedef struct tiff_page_s tiff_page;
+
+#define DPI 72.0f
+
+struct tiff_page_s
+{
+ fz_page super;
+ fz_image *image;
+};
+
+struct tiff_document_s
+{
+ fz_document super;
+ fz_stream *file;
+ fz_buffer *buffer;
+ int page_count;
+};
+
+static fz_rect *
+tiff_bound_page(fz_context *ctx, tiff_page *page, fz_rect *bbox)
+{
+ fz_image *image = page->image;
+ int xres, yres;
+
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ bbox->x0 = bbox->y0 = 0;
+ bbox->x1 = image->w * DPI / xres;
+ bbox->y1 = image->h * DPI / yres;
+ return bbox;
+}
+
+static void
+tiff_run_page(fz_context *ctx, tiff_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie)
+{
+ fz_matrix local_ctm = *ctm;
+ fz_image *image = page->image;
+ int xres, yres;
+ float w, h;
+
+ fz_image_get_sanitised_res(image, &xres, &yres);
+ w = image->w * DPI / xres;
+ h = image->h * DPI / yres;
+ fz_pre_scale(&local_ctm, w, h);
+ fz_fill_image(ctx, dev, image, &local_ctm, 1);
+}
+
+static void
+tiff_drop_page_imp(fz_context *ctx, tiff_page *page)
+{
+ if (!page)
+ return;
+ fz_drop_image(ctx, page->image);
+ fz_free(ctx, page);
+}
+
+static tiff_page *
+tiff_load_page(fz_context *ctx, tiff_document *doc, int number)
+{
+ fz_pixmap *pixmap = NULL;
+ fz_image *image = NULL;
+ tiff_page *page = NULL;
+
+ if (number < 0 || number >= doc->page_count)
+ return NULL;
+
+ fz_var(pixmap);
+ fz_var(image);
+ fz_var(page);
+
+ fz_try(ctx)
+ {
+ pixmap = fz_load_tiff_subimage(ctx, doc->buffer->data, doc->buffer->len, number);
+ image = fz_new_image_from_pixmap(ctx, pixmap, NULL);
+
+ page = fz_new_page(ctx, sizeof *page);
+ page->super.bound_page = (fz_page_bound_page_fn *)tiff_bound_page;
+ page->super.run_page_contents = (fz_page_run_page_contents_fn *)tiff_run_page;
+ page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)tiff_drop_page_imp;
+ page->image = fz_keep_image(ctx, image);
+ }
+ fz_always(ctx)
+ {
+ fz_drop_image(ctx, image);
+ fz_drop_pixmap(ctx, pixmap);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, page);
+ fz_rethrow(ctx);
+ }
+
+ return page;
+}
+
+static int
+tiff_count_pages(fz_context *ctx, tiff_document *doc)
+{
+ return doc->page_count;
+}
+
+static int
+tiff_meta(fz_context *ctx, 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_close_document(fz_context *ctx, tiff_document *doc)
+{
+ fz_drop_buffer(ctx, doc->buffer);
+ fz_drop_stream(ctx, doc->file);
+ fz_free(ctx, doc);
+}
+
+static tiff_document *
+tiff_open_document_with_stream(fz_context *ctx, fz_stream *file)
+{
+ tiff_document *doc;
+ unsigned char *buf;
+ int len;
+
+ doc = fz_new_document(ctx, sizeof *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.meta = (fz_document_meta_fn *)tiff_meta;
+
+ doc->file = fz_keep_stream(ctx, file);
+ doc->page_count = 0;
+
+ fz_try(ctx)
+ {
+ doc->buffer = fz_read_all(ctx, 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(ctx, doc);
+ fz_rethrow(ctx);
+ }
+
+ return doc;
+}
+
+static 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_drop_stream(ctx, file);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+
+ return doc;
+}
+
+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
+};