diff options
Diffstat (limited to 'source/cbz')
-rw-r--r-- | source/cbz/mucbz.c | 197 | ||||
-rw-r--r-- | source/cbz/muimg.c | 183 | ||||
-rw-r--r-- | source/cbz/mutiff.c | 188 |
3 files changed, 457 insertions, 111 deletions
diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c index e72412fb..c85cca45 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,89 +92,70 @@ 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(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]); + qsort((char **)doc->page, doc->page_count, sizeof *doc->page, cbz_compare_page_names); } -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_close(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_close_archive(doc->ctx, doc->zip); - fz_free(doc->ctx, 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); } -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; if (number < 0 || number >= doc->page_count) return NULL; @@ -182,58 +163,31 @@ cbz_load_page(cbz_document *doc, int number) fz_var(data); fz_var(page); - fz_buffer *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; - bbox->x0 = bbox->y0 = 0; - bbox->x1 = image->w * DPI / image->xres; - bbox->y1 = image->h * DPI / image->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; - 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 -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) { @@ -245,24 +199,45 @@ 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.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); + + 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..169fec95 --- /dev/null +++ b/source/cbz/muimg.c @@ -0,0 +1,183 @@ +#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 = 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 +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 = 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 +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_image(ctx, image); + fz_drop_buffer(ctx, buffer); + } + 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); + + 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..3a30cc79 --- /dev/null +++ b/source/cbz/mutiff.c @@ -0,0 +1,188 @@ +#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_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); +} + +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_free(ctx, doc); +} + +static tiff_document * +tiff_open_document_with_stream(fz_context *ctx, fz_stream *file) +{ + tiff_document *doc; + + 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; + + fz_try(ctx) + { + doc->buffer = fz_read_all(ctx, file, 1024); + doc->page_count = fz_load_tiff_subimage_count(ctx, doc->buffer->data, doc->buffer->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); + + 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 +}; |