diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2015-01-21 16:42:45 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2015-02-17 18:05:39 +0100 |
commit | f84a189d5f94250e46d2cbd1a75aba00130e2dd6 (patch) | |
tree | 8ee614ab90de1baa8941f91ae4946ed5c2e70721 /source/cbz/muimg.c | |
parent | 681039767f2ccc72e236246178893eb0989169c9 (diff) | |
download | mupdf-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/muimg.c')
-rw-r--r-- | source/cbz/muimg.c | 187 |
1 files changed, 187 insertions, 0 deletions
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 +}; |