diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2017-03-22 14:38:35 +0100 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2017-03-23 17:09:19 -0400 |
commit | 031c7035652d3c967321c9c308dea7cfb1c0e6fa (patch) | |
tree | 58e1d638c18e935e7c98f0ec13034376582fc721 /source/fitz | |
parent | 185d530d3b3a6f8be63dd7cfc3f2b7784066707c (diff) | |
download | mupdf-031c7035652d3c967321c9c308dea7cfb1c0e6fa.tar.xz |
Add generic pixmap document writer.
Allow mutool convert to output all image formats we can write.
Add sanity checks for pbm and pkm writers.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/bitmap.c | 64 | ||||
-rw-r--r-- | source/fitz/halftone.c | 5 | ||||
-rw-r--r-- | source/fitz/output-cbz.c | 79 | ||||
-rw-r--r-- | source/fitz/output-png.c | 71 | ||||
-rw-r--r-- | source/fitz/output-pnm.c | 4 | ||||
-rw-r--r-- | source/fitz/writer.c | 19 |
6 files changed, 155 insertions, 87 deletions
diff --git a/source/fitz/bitmap.c b/source/fitz/bitmap.c index 9db6a1df..9780b1dd 100644 --- a/source/fitz/bitmap.c +++ b/source/fitz/bitmap.c @@ -326,21 +326,41 @@ pkm_write_header(fz_context *ctx, fz_band_writer *writer) void fz_write_bitmap_as_pbm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) { - fz_band_writer *writer = fz_new_pbm_band_writer(ctx, out); + fz_band_writer *writer; - fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 0); - fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples); - fz_drop_band_writer(ctx, writer); + if (bitmap->n != 1) + fz_throw(ctx, FZ_ERROR_GENERIC, "bitmap must be monochrome to save as PBM"); + + writer = fz_new_pbm_band_writer(ctx, out); + fz_try(ctx) + { + fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 0); + fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples); + } + fz_always(ctx) + fz_drop_band_writer(ctx, writer); + fz_catch(ctx) + fz_rethrow(ctx); } void fz_write_bitmap_as_pkm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) { - fz_band_writer *writer = fz_new_pkm_band_writer(ctx, out); + fz_band_writer *writer; + + if (bitmap->n != 4) + fz_throw(ctx, FZ_ERROR_GENERIC, "bitmap must be CMYK to save as PKM"); - fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 0); - fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples); - fz_drop_band_writer(ctx, writer); + writer = fz_new_pkm_band_writer(ctx, out); + fz_try(ctx) + { + fz_write_header(ctx, writer, bitmap->w, bitmap->h, 4, 0, 0, 0, 0); + fz_write_band(ctx, writer, bitmap->stride, bitmap->h, bitmap->samples); + } + fz_always(ctx) + fz_drop_band_writer(ctx, writer); + fz_catch(ctx) + fz_rethrow(ctx); } static void @@ -421,7 +441,7 @@ fz_band_writer *fz_new_pkm_band_writer(fz_context *ctx, fz_output *out) } void -fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename) +fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, const char *filename) { fz_output *out = fz_new_output_with_path(ctx, filename, 0); fz_try(ctx) @@ -433,7 +453,7 @@ fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename) } void -fz_save_bitmap_as_pkm(fz_context *ctx, fz_bitmap *bitmap, char *filename) +fz_save_bitmap_as_pkm(fz_context *ctx, fz_bitmap *bitmap, const char *filename) { fz_output *out = fz_new_output_with_path(ctx, filename, 0); fz_try(ctx) @@ -444,6 +464,30 @@ fz_save_bitmap_as_pkm(fz_context *ctx, fz_bitmap *bitmap, char *filename) fz_rethrow(ctx); } +void +fz_save_pixmap_as_pbm(fz_context *ctx, fz_pixmap *pixmap, const char *filename) +{ + fz_bitmap *bitmap = fz_new_bitmap_from_pixmap(ctx, pixmap, NULL); + fz_try(ctx) + fz_save_bitmap_as_pbm(ctx, bitmap, filename); + fz_always(ctx) + fz_drop_bitmap(ctx, bitmap); + fz_catch(ctx) + fz_rethrow(ctx); +} + +void +fz_save_pixmap_as_pkm(fz_context *ctx, fz_pixmap *pixmap, const char *filename) +{ + fz_bitmap *bitmap = fz_new_bitmap_from_pixmap(ctx, pixmap, NULL); + fz_try(ctx) + fz_save_bitmap_as_pkm(ctx, bitmap, filename); + fz_always(ctx) + fz_drop_bitmap(ctx, bitmap); + fz_catch(ctx) + fz_rethrow(ctx); +} + void fz_bitmap_details(fz_bitmap *bit, int *w, int *h, int *n, int *stride) { if (!bit) diff --git a/source/fitz/halftone.c b/source/fitz/halftone.c index f0705790..58153fcf 100644 --- a/source/fitz/halftone.c +++ b/source/fitz/halftone.c @@ -528,7 +528,8 @@ fz_bitmap *fz_new_bitmap_from_pixmap_band(fz_context *ctx, fz_pixmap *pix, fz_ha if (!pix) return NULL; - assert(pix->alpha == 0); + if (pix->alpha != 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap may not have alpha channel to convert to bitmap"); fz_var(ht_line); fz_var(out); @@ -544,7 +545,7 @@ fz_bitmap *fz_new_bitmap_from_pixmap_band(fz_context *ctx, fz_pixmap *pix, fz_ha thresh = &do_threshold_4; break; default: - assert(!"Unsupported number of components"); + fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or CMYK to convert to bitmap"); return NULL; } diff --git a/source/fitz/output-cbz.c b/source/fitz/output-cbz.c index 43be16cb..7268a805 100644 --- a/source/fitz/output-cbz.c +++ b/source/fitz/output-cbz.c @@ -87,3 +87,82 @@ fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options) return (fz_document_writer*)wri; } + +/* generic image file output writer */ + +typedef struct fz_pixmap_writer_s fz_pixmap_writer; + +struct fz_pixmap_writer_s +{ + fz_document_writer super; + fz_draw_options options; + fz_pixmap *pixmap; + void (*save)(fz_context *ctx, fz_pixmap *pix, const char *filename); + int count; + char *path; +}; + +static fz_device * +pixmap_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) +{ + fz_pixmap_writer *wri = (fz_pixmap_writer*)wri_; + return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, &wri->pixmap); +} + +static void +pixmap_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) +{ + fz_pixmap_writer *wri = (fz_pixmap_writer*)wri_; + char path[PATH_MAX]; + + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + + wri->count += 1; + + fz_format_output_path(ctx, path, sizeof path, wri->path, wri->count); + wri->save(ctx, wri->pixmap, path); + fz_drop_pixmap(ctx, wri->pixmap); + wri->pixmap = NULL; +} + +static void +pixmap_drop_writer(fz_context *ctx, fz_document_writer *wri_) +{ + fz_pixmap_writer *wri = (fz_pixmap_writer*)wri_; + fz_drop_pixmap(ctx, wri->pixmap); + fz_free(ctx, wri->path); +} + +fz_document_writer * +fz_new_pixmap_writer(fz_context *ctx, const char *path, const char *options, + const char *default_path, int n, + void (*save)(fz_context *ctx, fz_pixmap *pix, const char *filename)) +{ + fz_pixmap_writer *wri; + + wri = fz_malloc_struct(ctx, fz_pixmap_writer); + wri->super.begin_page = pixmap_begin_page; + wri->super.end_page = pixmap_end_page; + wri->super.drop_writer = pixmap_drop_writer; + + fz_try(ctx) + { + fz_parse_draw_options(ctx, &wri->options, options); + wri->path = fz_strdup(ctx, path ? path : default_path); + wri->save = save; + switch (n) + { + case 1: wri->options.colorspace = fz_device_gray(ctx); break; + case 3: wri->options.colorspace = fz_device_rgb(ctx); break; + case 4: wri->options.colorspace = fz_device_cmyk(ctx); break; + } + } + fz_catch(ctx) + { + fz_free(ctx, wri); + fz_rethrow(ctx); + } + + return (fz_document_writer*)wri; +} diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c index de5500c9..c8972b25 100644 --- a/source/fitz/output-png.c +++ b/source/fitz/output-png.c @@ -299,74 +299,3 @@ fz_new_buffer_from_pixmap_as_png(fz_context *ctx, fz_pixmap *pix) { return png_from_pixmap(ctx, pix, 0); } - -/* PNG output writer */ - -typedef struct fz_png_writer_s fz_png_writer; - -struct fz_png_writer_s -{ - fz_document_writer super; - fz_draw_options options; - fz_pixmap *pixmap; - int count; - char *path; -}; - -const char *fz_png_write_options_usage = ""; - -static fz_device * -png_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) -{ - fz_png_writer *wri = (fz_png_writer*)wri_; - return fz_new_draw_device_with_options(ctx, &wri->options, mediabox, &wri->pixmap); -} - -static void -png_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) -{ - fz_png_writer *wri = (fz_png_writer*)wri_; - char path[PATH_MAX]; - - fz_close_device(ctx, dev); - fz_drop_device(ctx, dev); - - wri->count += 1; - - fz_format_output_path(ctx, path, sizeof path, wri->path, wri->count); - fz_save_pixmap_as_png(ctx, wri->pixmap, path); - fz_drop_pixmap(ctx, wri->pixmap); - wri->pixmap = NULL; -} - -static void -png_drop_writer(fz_context *ctx, fz_document_writer *wri_) -{ - fz_png_writer *wri = (fz_png_writer*)wri_; - fz_drop_pixmap(ctx, wri->pixmap); - fz_free(ctx, wri->path); -} - -fz_document_writer * -fz_new_png_writer(fz_context *ctx, const char *path, const char *options) -{ - fz_png_writer *wri; - - wri = fz_malloc_struct(ctx, fz_png_writer); - wri->super.begin_page = png_begin_page; - wri->super.end_page = png_end_page; - wri->super.drop_writer = png_drop_writer; - - fz_try(ctx) - { - fz_parse_draw_options(ctx, &wri->options, options); - wri->path = fz_strdup(ctx, path ? path : "out-%04d.png"); - } - fz_catch(ctx) - { - fz_free(ctx, wri); - fz_rethrow(ctx); - } - - return (fz_document_writer*)wri; -} diff --git a/source/fitz/output-pnm.c b/source/fitz/output-pnm.c index dbc521b7..455a5358 100644 --- a/source/fitz/output-pnm.c +++ b/source/fitz/output-pnm.c @@ -129,7 +129,7 @@ fz_write_pixmap_as_pnm(fz_context *ctx, fz_output *out, fz_pixmap *pixmap) } void -fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) +fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, const char *filename) { fz_band_writer *writer = NULL; fz_output *out = fz_new_output_with_path(ctx, filename, 0); @@ -226,7 +226,7 @@ fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap) } void -fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename) +fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, const char *filename) { fz_band_writer *writer = NULL; fz_output *out = fz_new_output_with_path(ctx, filename, 0); diff --git a/source/fitz/writer.c b/source/fitz/writer.c index 6ef40ffb..3c53f633 100644 --- a/source/fitz/writer.c +++ b/source/fitz/writer.c @@ -65,11 +65,26 @@ fz_new_document_writer(fz_context *ctx, const char *path, const char *format, co if (!fz_strcasecmp(format, "pdf")) return fz_new_pdf_writer(ctx, path, options); #endif - if (!fz_strcasecmp(format, "png")) - return fz_new_png_writer(ctx, path, options); if (!fz_strcasecmp(format, "svg")) return fz_new_svg_writer(ctx, path, options); + if (!fz_strcasecmp(format, "png")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.png", 0, fz_save_pixmap_as_png); + if (!fz_strcasecmp(format, "tga")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.tga", 0, fz_save_pixmap_as_tga); + if (!fz_strcasecmp(format, "pam")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.pam", 0, fz_save_pixmap_as_pam); + if (!fz_strcasecmp(format, "pnm")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.pnm", 0, fz_save_pixmap_as_pnm); + if (!fz_strcasecmp(format, "pgm")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.pgm", 1, fz_save_pixmap_as_pnm); + if (!fz_strcasecmp(format, "ppm")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.ppm", 3, fz_save_pixmap_as_pnm); + if (!fz_strcasecmp(format, "pbm")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.pbm", 1, fz_save_pixmap_as_pbm); + if (!fz_strcasecmp(format, "pkm")) + return fz_new_pixmap_writer(ctx, path, options, "out-%04.pkm", 4, fz_save_pixmap_as_pkm); + fz_throw(ctx, FZ_ERROR_GENERIC, "unknown output document format: %s", format); } |