diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/bitmap.c | 94 | ||||
-rw-r--r-- | source/fitz/output-pcl.c | 280 | ||||
-rw-r--r-- | source/fitz/output-png.c | 146 | ||||
-rw-r--r-- | source/fitz/output-pnm.c | 112 | ||||
-rw-r--r-- | source/fitz/output-ps.c | 135 | ||||
-rw-r--r-- | source/fitz/output.c | 48 | ||||
-rw-r--r-- | source/tools/mudraw.c | 79 | ||||
-rw-r--r-- | source/tools/muraster.c | 57 |
8 files changed, 567 insertions, 384 deletions
diff --git a/source/fitz/bitmap.c b/source/fitz/bitmap.c index dc2645ec..46cfa533 100644 --- a/source/fitz/bitmap.c +++ b/source/fitz/bitmap.c @@ -303,72 +303,81 @@ fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit) memset(bit->samples, 0, bit->stride * bit->h); } -void -fz_write_pbm_header(fz_context *ctx, fz_output *out, int w, int h) +static void +pbm_write_header(fz_context *ctx, fz_band_writer *writer) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + fz_printf(ctx, out, "P4\n%d %d\n", w, h); } -void -fz_write_pkm_header(fz_context *ctx, fz_output *out, int w, int h) +static void +pkm_write_header(fz_context *ctx, fz_band_writer *writer) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + fz_printf(ctx, out, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE CMYK\nENDHDR\n", w, h); } void fz_write_bitmap_as_pbm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) { - fz_write_pbm_header(ctx, out, bitmap->w, bitmap->h); + fz_band_writer *writer = fz_new_pbm_band_writer(ctx, out); - fz_write_pbm_band(ctx, out, bitmap); + fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 1); + fz_write_band(ctx, writer, bitmap->stride, 0, bitmap->h, bitmap->samples); + fz_write_trailer(ctx, writer); + fz_drop_band_writer(ctx, writer); } void fz_write_bitmap_as_pkm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) { - fz_write_pkm_header(ctx, out, bitmap->w, bitmap->h); + fz_band_writer *writer = fz_new_pkm_band_writer(ctx, out); - fz_write_pkm_band(ctx, out, bitmap); + fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, 0, 0, 1); + fz_write_band(ctx, writer, bitmap->stride, 0, bitmap->h, bitmap->samples); + fz_write_trailer(ctx, writer); + fz_drop_band_writer(ctx, writer); } -void -fz_write_pbm_band(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) +static void +pbm_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int bandheight, const unsigned char *p) { - unsigned char *p; - int h, bytestride; + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; + int bytestride; - if (bitmap->n != 1) + if (n != 1) fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components in bitmap"); - if (!out) - return; - - p = bitmap->samples; - h = bitmap->h; - bytestride = (bitmap->w + 7) >> 3; + bytestride = (w + 7) >> 3; while (h--) { fz_write(ctx, out, p, bytestride); - p += bitmap->stride; + p += stride; } } -void -fz_write_pkm_band(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) +static void +pkm_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int bandheight, const unsigned char *p) { - unsigned char *p; - int w, h, bytestride; + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; + int bytestride; - if (bitmap->n != 4) + if (n != 4) fz_throw(ctx, FZ_ERROR_GENERIC, "wrong number of color components in bitmap"); - if (!out) - return; - - p = bitmap->samples; - h = bitmap->h; - w = bitmap->w; - bytestride = bitmap->stride - (w>>1); + bytestride = stride - (w>>1); while (h--) { int ww = w-1; @@ -383,6 +392,27 @@ fz_write_pkm_band(fz_context *ctx, fz_output *out, fz_bitmap *bitmap) } } +fz_band_writer *fz_new_pbm_band_writer(fz_context *ctx, fz_output *out) +{ + fz_band_writer *writer = fz_new_band_writer(ctx, fz_band_writer, out); + + writer->header = pbm_write_header; + writer->band = pbm_write_band; + + return writer; +} + + +fz_band_writer *fz_new_pkm_band_writer(fz_context *ctx, fz_output *out) +{ + fz_band_writer *writer = fz_new_band_writer(ctx, fz_band_writer, out); + + writer->header = pkm_write_header; + writer->band = pkm_write_band; + + return writer; +} + void fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename) { diff --git a/source/fitz/output-pcl.c b/source/fitz/output-pcl.c index c0858299..96e7c973 100644 --- a/source/fitz/output-pcl.c +++ b/source/fitz/output-pcl.c @@ -680,22 +680,27 @@ delta_compression(unsigned char *curr, unsigned char *prev, unsigned char *comp, void fz_write_pixmap_as_pcl(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pcl_options *pcl) { - fz_color_pcl_output_context *pcoc; + fz_band_writer *writer; if (!pixmap || !out) return; - pcoc = fz_write_color_pcl_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->xres, pixmap->yres, 0, pcl); + writer = fz_new_color_pcl_band_writer(ctx, out, pcl); fz_try(ctx) - fz_write_color_pcl_band(ctx, out, pcoc, pixmap->w, pixmap->h, pixmap->n, pixmap->stride, 0, 0, pixmap->samples); + { + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, 0, pixmap->samples); + fz_write_trailer(ctx, writer); + } fz_always(ctx) - fz_write_color_pcl_trailer(ctx, out, pcoc); + fz_drop_band_writer(ctx, writer); fz_catch(ctx) fz_rethrow(ctx); } -struct fz_color_pcl_output_context_s +typedef struct color_pcl_band_writer_s { + fz_band_writer super; fz_pcl_options options; unsigned char *linebuf; unsigned char *compbuf; @@ -703,42 +708,32 @@ struct fz_color_pcl_output_context_s unsigned char *curr; int fill; int seed_valid; -}; +} color_pcl_band_writer; -fz_color_pcl_output_context *fz_write_color_pcl_header(fz_context *ctx, fz_output *out, int w, int h, int n, int xres, int yres, int pagenum, const fz_pcl_options *options) +static void +color_pcl_write_header(fz_context *ctx, fz_band_writer *writer_) { - fz_color_pcl_output_context *pcoc = fz_malloc_struct(ctx, fz_color_pcl_output_context); - - if (!out) - return NULL; + color_pcl_band_writer *writer = (color_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int n = writer->super.n; + int xres = writer->super.xres; + int yres = writer->super.yres; if (n != 4) fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be rgb to write as pcl"); - if (options) - pcoc->options = *options; - else - fz_pcl_preset(ctx, &pcoc->options, "generic"); + writer->linebuf = fz_malloc(ctx, w * 3 * 2); + writer->compbuf = fz_malloc(ctx, 32767); + writer->prev = writer->linebuf; + writer->curr = writer->linebuf + w * 3; + writer->fill = 0; + writer->seed_valid = 0; - fz_try(ctx) - { - pcoc->linebuf = fz_malloc(ctx, w * 3 * 2); - pcoc->compbuf = fz_malloc(ctx, 32767); - pcoc->prev = pcoc->linebuf; - pcoc->curr = pcoc->linebuf + w * 3; - pcoc->fill = 0; - pcoc->seed_valid = 0; - } - fz_catch(ctx) - { - fz_free(ctx, pcoc->linebuf); - fz_free(ctx, pcoc->compbuf); - fz_rethrow(ctx); - } - - guess_paper_size(&pcoc->options, w, h, xres, yres); + guess_paper_size(&writer->options, w, h, xres, yres); - pcl_header(ctx, out, &pcoc->options, 1, xres, yres, w, h); + pcl_header(ctx, out, &writer->options, 1, xres, yres, w, h); /* Raster presentation */ /* Print in orientation of the logical page */ @@ -773,28 +768,28 @@ fz_color_pcl_output_context *fz_write_color_pcl_header(fz_context *ctx, fz_outpu /* Now output the actual bitmap */ /* Adaptive Compression */ fz_printf(ctx, out, "\033*b5M"); - - return pcoc; } -void fz_write_color_pcl_band(fz_context *ctx, fz_output *out, fz_color_pcl_output_context *pcoc, int w, int h, int n, int stride, int band_start, int bandheight, unsigned char *sp) +static void +color_pcl_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_start, int bandheight, const unsigned char *sp) { + color_pcl_band_writer *writer = (color_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; int y, ss, ds, seed_valid, fill; unsigned char *prev; unsigned char *curr; unsigned char *comp; - if (!out || !pcoc) - return; - ds = w * 3; ss = w * 4; - prev = pcoc->prev; - curr = pcoc->curr; - fill = pcoc->fill; - comp = pcoc->compbuf; - seed_valid = pcoc->seed_valid; + prev = writer->prev; + curr = writer->curr; + fill = writer->fill; + comp = writer->compbuf; + seed_valid = writer->seed_valid; if (band_start+bandheight >= h) bandheight = h - band_start; @@ -904,30 +899,53 @@ void fz_write_color_pcl_band(fz_context *ctx, fz_output *out, fz_color_pcl_outpu } } - pcoc->prev = prev; - pcoc->curr = curr; - pcoc->fill = fill; - pcoc->compbuf = comp; - pcoc->seed_valid = seed_valid; + writer->prev = prev; + writer->curr = curr; + writer->fill = fill; + writer->compbuf = comp; + writer->seed_valid = seed_valid; } -void fz_write_color_pcl_trailer(fz_context *ctx, fz_output *out, fz_color_pcl_output_context *pcoc) +static void +color_pcl_write_trailer(fz_context *ctx, fz_band_writer *writer_) { - if (!pcoc) - return; + color_pcl_band_writer *writer = (color_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; - if (pcoc->fill) + if (writer->fill) { - fz_printf(ctx, out, "\033*b%dW", pcoc->fill); - fz_write(ctx, out, pcoc->compbuf, pcoc->fill); + fz_printf(ctx, out, "\033*b%dW", writer->fill); + fz_write(ctx, out, writer->compbuf, writer->fill); } /* End Raster Graphics */ fz_printf(ctx, out, "\033*rC"); +} + +static void +color_pcl_drop_band_writer(fz_context *ctx, fz_band_writer *writer_) +{ + color_pcl_band_writer *writer = (color_pcl_band_writer *)writer_; + + fz_free(ctx, writer->compbuf); + fz_free(ctx, writer->linebuf); +} + +fz_band_writer *fz_new_color_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options) +{ + color_pcl_band_writer *writer = fz_new_band_writer(ctx, color_pcl_band_writer, out); + + writer->super.header = color_pcl_write_header; + writer->super.band = color_pcl_write_band; + writer->super.trailer = color_pcl_write_trailer; + writer->super.drop = color_pcl_drop_band_writer; + + if (options) + writer->options = *options; + else + fz_pcl_preset(ctx, &writer->options, "generic"); - fz_free(ctx, pcoc->compbuf); - fz_free(ctx, pcoc->linebuf); - fz_free(ctx, pcoc); + return &writer->super; } /* @@ -941,7 +959,7 @@ void fz_write_color_pcl_trailer(fz_context *ctx, fz_output *out, fz_color_pcl_ou * where N is the original byte count (end_row - row). */ int -mode2compress(unsigned char *out, unsigned char *in, int in_len) +mode2compress(unsigned char *out, const unsigned char *in, int in_len) { int x; int out_len = 0; @@ -1050,81 +1068,79 @@ void wind(void) void fz_write_bitmap_as_pcl(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pcl_options *pcl) { - fz_mono_pcl_output_context *pcoc; + fz_band_writer *writer; if (!bitmap || !out) return; - pcoc = fz_write_mono_pcl_header(ctx, out, bitmap->w, bitmap->h, bitmap->xres, bitmap->yres, 0, pcl); + writer = fz_new_mono_pcl_band_writer(ctx, out, pcl); fz_try(ctx) - fz_write_mono_pcl_band(ctx, out, pcoc, bitmap); + { + fz_write_header(ctx, writer, bitmap->w, bitmap->h, 1, 0, bitmap->xres, bitmap->yres, 0); + fz_write_band(ctx, writer, bitmap->stride, 0, bitmap->h, bitmap->samples); + fz_write_trailer(ctx, writer); + } fz_always(ctx) - fz_write_mono_pcl_trailer(ctx, out, pcoc); + fz_drop_band_writer(ctx, writer); fz_catch(ctx) fz_rethrow(ctx); } -struct fz_mono_pcl_output_context_s +typedef struct mono_pcl_band_writer_s { + fz_band_writer super; fz_pcl_options options; unsigned char *prev; unsigned char *mode2buf; unsigned char *mode3buf; int top_of_page; int num_blank_lines; -}; +} mono_pcl_band_writer; -fz_mono_pcl_output_context *fz_write_mono_pcl_header(fz_context *ctx, fz_output *out, int w, int h, int xres, int yres, int pagenum, const fz_pcl_options *options) +static void +mono_pcl_write_header(fz_context *ctx, fz_band_writer *writer_) { - fz_mono_pcl_output_context *pcoc = fz_malloc_struct(ctx, fz_mono_pcl_output_context); + mono_pcl_band_writer *writer = (mono_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int xres = writer->super.xres; + int yres = writer->super.yres; int line_size; int max_mode_2_size; int max_mode_3_size; - if (!out) - return NULL; - - if (options) - pcoc->options = *options; - else - fz_pcl_preset(ctx, &pcoc->options, "generic"); - line_size = (w + 7)/8; max_mode_2_size = line_size + (line_size/127) + 1; max_mode_3_size = line_size + (line_size/8) + 1; - fz_try(ctx) - { - pcoc->prev = fz_calloc(ctx, line_size, sizeof(unsigned char)); - pcoc->mode2buf = fz_calloc(ctx, max_mode_2_size, sizeof(unsigned char)); - pcoc->mode3buf = fz_calloc(ctx, max_mode_3_size, sizeof(unsigned char)); - pcoc->num_blank_lines = 0; - pcoc->top_of_page = 1; - } - fz_catch(ctx) - { - fz_free(ctx, pcoc->prev); - fz_free(ctx, pcoc->mode2buf); - fz_free(ctx, pcoc->mode3buf); - fz_rethrow(ctx); - } + writer->prev = fz_calloc(ctx, line_size, sizeof(unsigned char)); + writer->mode2buf = fz_calloc(ctx, max_mode_2_size, sizeof(unsigned char)); + writer->mode3buf = fz_calloc(ctx, max_mode_3_size, sizeof(unsigned char)); + writer->num_blank_lines = 0; + writer->top_of_page = 1; - guess_paper_size(&pcoc->options, w, h, xres, yres); + guess_paper_size(&writer->options, w, h, xres, yres); - if (pcoc->options.features & HACK__IS_A_OCE9050) + if (writer->options.features & HACK__IS_A_OCE9050) { /* Enter HPGL/2 mode, begin plot, Initialise (start plot), Enter PCL mode */ fz_puts(ctx, out, "\033%1BBPIN;\033%1A"); } - pcl_header(ctx, out, &pcoc->options, 1, xres, yres, w, h); - return pcoc; + pcl_header(ctx, out, &writer->options, 1, xres, yres, w, h); } -void fz_write_mono_pcl_band(fz_context *ctx, fz_output *out, fz_mono_pcl_output_context *poc, const fz_bitmap *bitmap) +static void +mono_pcl_write_band(fz_context *ctx, fz_band_writer *writer_, int ss, int band_start, int bandheight, const unsigned char *data) { - unsigned char *data, *out_data; - int y, ss, rmask, line_size; + mono_pcl_band_writer *writer = (mono_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int yres = writer->super.yres; + const unsigned char *out_data; + int y, rmask, line_size; int num_blank_lines; int compression = -1; unsigned char *prev = NULL; @@ -1133,23 +1149,18 @@ void fz_write_mono_pcl_band(fz_context *ctx, fz_output *out, fz_mono_pcl_output_ int out_count; const fz_pcl_options *pcl; - if (!out || !bitmap) - return; - - num_blank_lines = poc->num_blank_lines; - rmask = ~0 << (-bitmap->w & 7); - line_size = (bitmap->w + 7)/8; - prev = poc->prev; - mode2buf = poc->mode2buf; - mode3buf = poc->mode3buf; - pcl = &poc->options; + num_blank_lines = writer->num_blank_lines; + rmask = ~0 << (-w & 7); + line_size = (w + 7)/8; + prev = writer->prev; + mode2buf = writer->mode2buf; + mode3buf = writer->mode3buf; + pcl = &writer->options; /* Transfer raster graphics. */ - data = bitmap->samples; - ss = bitmap->stride; - for (y = 0; y < bitmap->h; y++, data += ss) + for (y = 0; y < h; y++, data += ss) { - unsigned char *end_data = data + line_size; + const unsigned char *end_data = data + line_size; if ((end_data[-1] & rmask) == 0) { @@ -1166,9 +1177,9 @@ void fz_write_mono_pcl_band(fz_context *ctx, fz_output *out, fz_mono_pcl_output_ /* We've reached a non-blank line. */ /* Put out a spacing command if necessary. */ - if (poc->top_of_page) + if (writer->top_of_page) { - poc->top_of_page = 0; + writer->top_of_page = 0; /* We're at the top of a page. */ if (pcl->features & PCL_ANY_SPACING) { @@ -1232,7 +1243,7 @@ void fz_write_mono_pcl_band(fz_context *ctx, fz_output *out, fz_mono_pcl_output_ } } else if (pcl->features & PCL3_SPACING) - fz_printf(ctx, out, "\033*p+%dY", num_blank_lines * bitmap->yres); + fz_printf(ctx, out, "\033*p+%dY", num_blank_lines * yres); else fz_printf(ctx, out, "\033*b%dY", num_blank_lines); /* Clear the seed row (only matters for mode 3 compression). */ @@ -1284,27 +1295,50 @@ void fz_write_mono_pcl_band(fz_context *ctx, fz_output *out, fz_mono_pcl_output_ fz_write(ctx, out, out_data, out_count); } - poc->num_blank_lines = num_blank_lines; + writer->num_blank_lines = num_blank_lines; } -void fz_write_mono_pcl_trailer(fz_context *ctx, fz_output *out, fz_mono_pcl_output_context *pcoc) +static void +mono_pcl_write_trailer(fz_context *ctx, fz_band_writer *writer_) { - if (!pcoc || !out) - return; + mono_pcl_band_writer *writer = (mono_pcl_band_writer *)writer_; + fz_output *out = writer->super.out; /* end raster graphics and eject page */ fz_puts(ctx, out, "\033*rB\f"); - if (pcoc->options.features & HACK__IS_A_OCE9050) + if (writer->options.features & HACK__IS_A_OCE9050) { /* Pen up, pen select, advance full page, reset */ fz_puts(ctx, out, "\033%1BPUSP0PG;\033E"); } +} + +static void +mono_pcl_drop_band_writer(fz_context *ctx, fz_band_writer *writer_) +{ + mono_pcl_band_writer *writer = (mono_pcl_band_writer *)writer_; + + fz_free(ctx, writer->prev); + fz_free(ctx, writer->mode2buf); + fz_free(ctx, writer->mode3buf); +} + +fz_band_writer *fz_new_mono_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options) +{ + mono_pcl_band_writer *writer = fz_new_band_writer(ctx, mono_pcl_band_writer, out); + + writer->super.header = mono_pcl_write_header; + writer->super.band = mono_pcl_write_band; + writer->super.trailer = mono_pcl_write_trailer; + writer->super.drop = mono_pcl_drop_band_writer; + + if (options) + writer->options = *options; + else + fz_pcl_preset(ctx, &writer->options, "generic"); - fz_free(ctx, pcoc->prev); - fz_free(ctx, pcoc->mode2buf); - fz_free(ctx, pcoc->mode3buf); - fz_free(ctx, pcoc); + return &writer->super; } void diff --git a/source/fitz/output-png.c b/source/fitz/output-png.c index d5e0b48f..620fa811 100644 --- a/source/fitz/output-png.c +++ b/source/fitz/output-png.c @@ -30,18 +30,20 @@ void fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename) { fz_output *out = fz_new_output_with_path(ctx, filename, 0); - fz_png_output_context *poc = NULL; + fz_band_writer *writer = NULL; - fz_var(poc); + fz_var(writer); fz_try(ctx) { - poc = fz_write_png_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); - fz_write_png_band(ctx, out, poc, pixmap->stride, 0, pixmap->h, pixmap->samples); + writer = fz_new_png_band_writer(ctx, out); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); } fz_always(ctx) { - fz_write_png_trailer(ctx, out, poc); + fz_drop_band_writer(ctx, writer); fz_drop_output(ctx, out); } fz_catch(ctx) @@ -53,20 +55,22 @@ fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename) void fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap) { - fz_png_output_context *poc; + fz_band_writer *writer; if (!out) return; - poc = fz_write_png_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); + writer = fz_new_png_band_writer(ctx, out); fz_try(ctx) { - fz_write_png_band(ctx, out, poc, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); } fz_always(ctx) { - fz_write_png_trailer(ctx, out, poc); + fz_drop_band_writer(ctx, writer); } fz_catch(ctx) { @@ -74,28 +78,27 @@ fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap) } } -struct fz_png_output_context_s +typedef struct png_band_writer_s { + fz_band_writer super; unsigned char *udata; unsigned char *cdata; uLong usize, csize; z_stream stream; - int w; - int h; - int n; - int alpha; -}; +} png_band_writer; -fz_png_output_context * -fz_write_png_header(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha) +static void +png_write_header(fz_context *ctx, fz_band_writer *writer_) { + png_band_writer *writer = (png_band_writer *)(void *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int n = writer->super.n; + int alpha = writer->super.alpha; static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; unsigned char head[13]; int color; - fz_png_output_context *poc; - - if (!out) - return NULL; /* Treat alpha only as greyscale */ if (n == 1 && alpha) @@ -109,12 +112,6 @@ fz_write_png_header(fz_context *ctx, fz_output *out, int w, int h, int n, int al fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as png"); } - poc = fz_malloc_struct(ctx, fz_png_output_context); - poc->w = w; - poc->h = h; - poc->n = n; - poc->alpha = alpha; - big32(head+0, w); big32(head+4, h); head[8] = 8; /* depth */ @@ -125,55 +122,42 @@ fz_write_png_header(fz_context *ctx, fz_output *out, int w, int h, int n, int al fz_write(ctx, out, pngsig, 8); putchunk(ctx, out, "IHDR", head, 13); - - return poc; } -void -fz_write_png_band(fz_context *ctx, fz_output *out, fz_png_output_context *poc, int stride, int band_start, int bandheight, unsigned char *sp) +static void +png_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_start, int bandheight, const unsigned char *sp) { + png_band_writer *writer = (png_band_writer *)(void *)writer_; + fz_output *out = writer->super.out; unsigned char *dp; int y, x, k, err, finalband; int w, h, n; - if (!out || !sp || !poc) - return; - - w = poc->w; - h = poc->h; - n = poc->n; + w = writer->super.w; + h = writer->super.h; + n = writer->super.n; finalband = (band_start+bandheight >= h); if (finalband) bandheight = h - band_start; - if (poc->udata == NULL) + if (writer->udata == NULL) { - poc->usize = (w * n + 1) * bandheight; + writer->usize = (w * n + 1) * bandheight; /* Sadly the bound returned by compressBound is just for a * single usize chunk; if you compress a sequence of them * the buffering can result in you suddenly getting a block * larger than compressBound outputted in one go, even if you * take all the data out each time. */ - poc->csize = compressBound(poc->usize); - fz_try(ctx) - { - poc->udata = fz_malloc(ctx, poc->usize); - poc->cdata = fz_malloc(ctx, poc->csize); - } - fz_catch(ctx) - { - fz_free(ctx, poc->udata); - poc->udata = NULL; - poc->cdata = NULL; - fz_rethrow(ctx); - } - err = deflateInit(&poc->stream, Z_DEFAULT_COMPRESSION); + writer->csize = compressBound(writer->usize); + writer->udata = fz_malloc(ctx, writer->usize); + writer->cdata = fz_malloc(ctx, writer->csize); + err = deflateInit(&writer->stream, Z_DEFAULT_COMPRESSION); if (err != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); } - dp = poc->udata; + dp = writer->udata; stride -= w*n; for (y = 0; y < bandheight; y++) { @@ -193,52 +177,68 @@ fz_write_png_band(fz_context *ctx, fz_output *out, fz_png_output_context *poc, i sp += stride; } - poc->stream.next_in = (Bytef*)poc->udata; - poc->stream.avail_in = (uInt)(dp - poc->udata); + writer->stream.next_in = (Bytef*)writer->udata; + writer->stream.avail_in = (uInt)(dp - writer->udata); do { - poc->stream.next_out = poc->cdata; - poc->stream.avail_out = (uInt)poc->csize; + writer->stream.next_out = writer->cdata; + writer->stream.avail_out = (uInt)writer->csize; if (!finalband) { - err = deflate(&poc->stream, Z_NO_FLUSH); + err = deflate(&writer->stream, Z_NO_FLUSH); if (err != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); } else { - err = deflate(&poc->stream, Z_FINISH); + err = deflate(&writer->stream, Z_FINISH); if (err != Z_STREAM_END) fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); } - if (poc->stream.next_out != poc->cdata) - putchunk(ctx, out, "IDAT", poc->cdata, poc->stream.next_out - poc->cdata); + if (writer->stream.next_out != writer->cdata) + putchunk(ctx, out, "IDAT", writer->cdata, writer->stream.next_out - writer->cdata); } - while (poc->stream.avail_out == 0); + while (writer->stream.avail_out == 0); } -void -fz_write_png_trailer(fz_context *ctx, fz_output *out, fz_png_output_context *poc) +static void +png_write_trailer(fz_context *ctx, fz_band_writer *writer_) { + png_band_writer *writer = (png_band_writer *)(void *)writer_; + fz_output *out = writer->super.out; unsigned char block[1]; int err; - if (!out || !poc) - return; - - err = deflateEnd(&poc->stream); + err = deflateEnd(&writer->stream); if (err != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); - fz_free(ctx, poc->cdata); - fz_free(ctx, poc->udata); - fz_free(ctx, poc); - putchunk(ctx, out, "IEND", block, 0); } +static void +png_drop_band_writer(fz_context *ctx, fz_band_writer *writer_) +{ + png_band_writer *writer = (png_band_writer *)(void *)writer_; + + fz_free(ctx, writer->cdata); + fz_free(ctx, writer->udata); +} + +fz_band_writer *fz_new_png_band_writer(fz_context *ctx, fz_output *out) +{ + png_band_writer *writer = fz_new_band_writer(ctx, png_band_writer, out); + + writer->super.header = png_write_header; + writer->super.band = png_write_band; + writer->super.trailer = png_write_trailer; + writer->super.drop = png_drop_band_writer; + + return &writer->super; +} + /* We use an auxiliary function to do pixmap_as_png, as it can enable us to * drop pix early in the case where we have to convert, potentially saving * us having to have 2 copies of the pixmap and a buffer open at once. */ diff --git a/source/fitz/output-pnm.c b/source/fitz/output-pnm.c index 2d1acd23..b5796ab2 100644 --- a/source/fitz/output-pnm.c +++ b/source/fitz/output-pnm.c @@ -3,10 +3,15 @@ /* * Write pixmap to PNM file (without alpha channel) */ - -void -fz_write_pnm_header(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha) +static void +pnm_write_header(fz_context *ctx, fz_band_writer *writer) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; + int alpha = writer->alpha; + n -= alpha; if (n != 1 && n != 3) fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm"); @@ -19,9 +24,14 @@ fz_write_pnm_header(fz_context *ctx, fz_output *out, int w, int h, int n, int al fz_printf(ctx, out, "255\n"); } -void -fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha, int stride, int band_start, int bandheight, unsigned char *p) +static void +pnm_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int bandheight, const unsigned char *p) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; + int alpha = writer->alpha; char buffer[2*3*4*5*6]; /* Buffer must be a multiple of 2 and 3 at least. */ int len; int end = band_start + bandheight; @@ -29,9 +39,6 @@ fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alph if (n-alpha != 1 && n-alpha != 3) fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm"); - if (!out) - return; - if (end > h) end = h; end -= band_start; @@ -96,29 +103,63 @@ fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alph } } +fz_band_writer *fz_new_pnm_band_writer(fz_context *ctx, fz_output *out) +{ + fz_band_writer *writer = fz_new_band_writer(ctx, fz_band_writer, out); + + writer->header = pnm_write_header; + writer->band = pnm_write_band; + + return writer; +} + void fz_write_pixmap_as_pnm(fz_context *ctx, fz_output *out, fz_pixmap *pixmap) { - fz_write_pnm_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); - fz_write_pnm_band(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_band_writer *writer = fz_new_pnm_band_writer(ctx, out); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); + fz_drop_band_writer(ctx, writer); } void fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) { + fz_band_writer *writer = NULL; fz_output *out = fz_new_output_with_path(ctx, filename, 0); - fz_write_pnm_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); - fz_write_pnm_band(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->stride, 0, pixmap->h, pixmap->samples); - fz_drop_output(ctx, out); + + fz_var(writer); + + fz_try(ctx) + { + writer = fz_new_pnm_band_writer(ctx, out); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); + } + fz_always(ctx) + { + fz_drop_band_writer(ctx, writer); + fz_drop_output(ctx, out); + } + fz_catch(ctx) + fz_rethrow(ctx); } /* * Write pixmap to PAM file (with or without alpha channel) */ -void -fz_write_pam_header(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha) +static void +pam_write_header(fz_context *ctx, fz_band_writer *writer) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; + int alpha = writer->alpha; + fz_printf(ctx, out, "P7\n"); fz_printf(ctx, out, "WIDTH %d\n", w); fz_printf(ctx, out, "HEIGHT %d\n", h); @@ -137,15 +178,16 @@ fz_write_pam_header(fz_context *ctx, fz_output *out, int w, int h, int n, int al fz_printf(ctx, out, "ENDHDR\n"); } -void -fz_write_pam_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha, int stride, int band_start, int bandheight, unsigned char *sp) +static void +pam_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int bandheight, const unsigned char *sp) { + fz_output *out = writer->out; + int w = writer->w; + int h = writer->h; + int n = writer->n; int y; int end = band_start + bandheight; - if (!out) - return; - if (end > h) end = h; end -= band_start; @@ -157,24 +199,46 @@ fz_write_pam_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alph } } +fz_band_writer *fz_new_pam_band_writer(fz_context *ctx, fz_output *out) +{ + fz_band_writer *writer = fz_new_band_writer(ctx, fz_band_writer, out); + + writer->header = pam_write_header; + writer->band = pam_write_band; + + return writer; +} + void fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap) { - fz_write_pam_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); - fz_write_pam_band(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_band_writer *writer = fz_new_pam_band_writer(ctx, out); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); + fz_drop_band_writer(ctx, writer); } void fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename) { + fz_band_writer *writer = NULL; fz_output *out = fz_new_output_with_path(ctx, filename, 0); + + fz_var(writer); + fz_try(ctx) { - fz_write_pam_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha); - fz_write_pam_band(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->stride, 0, pixmap->h, pixmap->samples); + writer = fz_new_pam_band_writer(ctx, out); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, 0, 0, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); } fz_always(ctx) + { + fz_drop_band_writer(ctx, writer); fz_drop_output(ctx, out); + } fz_catch(ctx) fz_rethrow(ctx); } diff --git a/source/fitz/output-ps.c b/source/fitz/output-ps.c index d183adf6..6e63110c 100644 --- a/source/fitz/output-ps.c +++ b/source/fitz/output-ps.c @@ -2,14 +2,15 @@ #include <zlib.h> -struct fz_ps_output_context_s +typedef struct ps_band_writer_s { + fz_band_writer super; z_stream stream; int input_size; unsigned char *input; int output_size; unsigned char *output; -}; +} ps_band_writer; void fz_write_ps_file_header(fz_context *ctx, fz_output *out) @@ -39,20 +40,35 @@ void fz_write_ps_file_trailer(fz_context *ctx, fz_output *out, int pages) fz_printf(ctx, out, "%%%%Trailer\n%%%%Pages: %d\n%%%%EOF\n", pages); } -fz_ps_output_context *fz_write_ps_header(fz_context *ctx, fz_output *out, int w, int h, int n, int xres, int yres, int pagenum) +static void +ps_write_header(fz_context *ctx, fz_band_writer *writer_) { + ps_band_writer *writer = (ps_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int n = writer->super.n; + int alpha = writer->super.alpha; + int xres = writer->super.xres; + int yres = writer->super.yres; + int pagenum = writer->super.pagenum; int w_points = (w * 72 + (xres>>1)) / xres; int h_points = (h * 72 + (yres>>1)) / yres; float sx = w/(float)w_points; float sy = h/(float)h_points; - fz_ps_output_context *psoc; int err; - psoc = fz_malloc_struct(ctx, fz_ps_output_context); - err = deflateInit(&psoc->stream, Z_DEFAULT_COMPRESSION); + if (alpha != 0) + fz_throw(ctx, FZ_ERROR_GENERIC, "Postscript output cannot have alpha"); + + writer->super.w = w; + writer->super.h = h; + writer->super.n = n; + + err = deflateInit(&writer->stream, Z_DEFAULT_COMPRESSION); if (err != Z_OK) { - fz_free(ctx, psoc); + fz_free(ctx, writer); fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); } @@ -90,49 +106,54 @@ fz_ps_output_context *fz_write_ps_header(fz_context *ctx, fz_output *out, int w, ">>\n" "image\n" , w, h, sx, sy, h); - - return psoc; } -void fz_write_ps_trailer(fz_context *ctx, fz_output *out, fz_ps_output_context *psoc) +static void +ps_write_trailer(fz_context *ctx, fz_band_writer *writer_) { - if (psoc) - { - int err; + ps_band_writer *writer = (ps_band_writer *)writer_; + fz_output *out = writer->super.out; + int err; - psoc->stream.next_in = NULL; - psoc->stream.avail_in = 0; - psoc->stream.next_out = (Bytef*)psoc->output; - psoc->stream.avail_out = (uInt)psoc->output_size; + writer->stream.next_in = NULL; + writer->stream.avail_in = 0; + writer->stream.next_out = (Bytef*)writer->output; + writer->stream.avail_out = (uInt)writer->output_size; - err = deflate(&psoc->stream, Z_FINISH); - if (err != Z_STREAM_END) - fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); + err = deflate(&writer->stream, Z_FINISH); + if (err != Z_STREAM_END) + fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); - fz_write(ctx, out, psoc->output, psoc->output_size - psoc->stream.avail_out); - fz_free(ctx, psoc->input); - fz_free(ctx, psoc->output); - fz_free(ctx, psoc); - } + fz_write(ctx, out, writer->output, writer->output_size - writer->stream.avail_out); fz_printf(ctx, out, "\nshowpage\n%%%%PageTrailer\n%%%%EndPageTrailer\n\n"); +} +static void +ps_drop_band_writer(fz_context *ctx, fz_band_writer *writer_) +{ + ps_band_writer *writer = (ps_band_writer *)writer_; + + fz_free(ctx, writer->input); + fz_free(ctx, writer->output); } void fz_write_pixmap_as_ps(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap) { - fz_ps_output_context *psoc; + fz_band_writer *writer; fz_write_ps_file_header(ctx, out); - psoc = fz_write_ps_header(ctx, out, pixmap->w, pixmap->h, pixmap->n, pixmap->xres, pixmap->yres, 1); + writer = fz_new_ps_band_writer(ctx, out); fz_try(ctx) { - fz_write_ps_band(ctx, out, psoc, pixmap->w, pixmap->h, pixmap->n, pixmap->stride, 0, 0, pixmap->samples); + fz_write_header(ctx, writer, pixmap->w, pixmap->h, pixmap->n, pixmap->alpha, pixmap->xres, pixmap->yres, 1); + fz_write_band(ctx, writer, pixmap->stride, 0, pixmap->h, pixmap->samples); + fz_write_trailer(ctx, writer); } fz_always(ctx) { - fz_write_ps_trailer(ctx, out, psoc); + fz_drop_band_writer(ctx, writer); } fz_catch(ctx) { @@ -153,8 +174,14 @@ void fz_save_pixmap_as_ps(fz_context *ctx, fz_pixmap *pixmap, char *filename, in fz_rethrow(ctx); } -void fz_write_ps_band(fz_context *ctx, fz_output *out, fz_ps_output_context *psoc, int w, int h, int n, int stride, int band_start, int bandheight, unsigned char *samples) +static void +ps_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_start, int bandheight, const unsigned char *samples) { + ps_band_writer *writer = (ps_band_writer *)writer_; + fz_output *out = writer->super.out; + int w = writer->super.w; + int h = writer->super.h; + int n = writer->super.n; int x, y, i, err; int required_input; int required_output; @@ -164,25 +191,25 @@ void fz_write_ps_band(fz_context *ctx, fz_output *out, fz_ps_output_context *pso bandheight = h - band_start; required_input = w*(n-1)*bandheight; - required_output = (int)deflateBound(&psoc->stream, required_input); + required_output = (int)deflateBound(&writer->stream, required_input); - if (psoc->input == NULL || psoc->input_size < required_input) + if (writer->input == NULL || writer->input_size < required_input) { - fz_free(ctx, psoc->input); - psoc->input = NULL; - psoc->input = fz_malloc(ctx, required_input); - psoc->input_size = required_input; + fz_free(ctx, writer->input); + writer->input = NULL; + writer->input = fz_malloc(ctx, required_input); + writer->input_size = required_input; } - if (psoc->output == NULL || psoc->output_size < required_output) + if (writer->output == NULL || writer->output_size < required_output) { - fz_free(ctx, psoc->output); - psoc->output = NULL; - psoc->output = fz_malloc(ctx, required_output); - psoc->output_size = required_output; + fz_free(ctx, writer->output); + writer->output = NULL; + writer->output = fz_malloc(ctx, required_output); + writer->output_size = required_output; } - o = psoc->input; + o = writer->input; for (y = 0; y < bandheight; y++) { for (x = 0; x < w; x++) @@ -194,14 +221,26 @@ void fz_write_ps_band(fz_context *ctx, fz_output *out, fz_ps_output_context *pso samples += stride - w*n; } - psoc->stream.next_in = (Bytef*)psoc->input; - psoc->stream.avail_in = required_input; - psoc->stream.next_out = (Bytef*)psoc->output; - psoc->stream.avail_out = (uInt)psoc->output_size; + writer->stream.next_in = (Bytef*)writer->input; + writer->stream.avail_in = required_input; + writer->stream.next_out = (Bytef*)writer->output; + writer->stream.avail_out = (uInt)writer->output_size; - err = deflate(&psoc->stream, Z_NO_FLUSH); + err = deflate(&writer->stream, Z_NO_FLUSH); if (err != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); - fz_write(ctx, out, psoc->output, psoc->output_size - psoc->stream.avail_out); + fz_write(ctx, out, writer->output, writer->output_size - writer->stream.avail_out); +} + +fz_band_writer *fz_new_ps_band_writer(fz_context *ctx, fz_output *out) +{ + fz_band_writer *writer = fz_new_band_writer(ctx, fz_band_writer, out); + + writer->header = ps_write_header; + writer->band = ps_write_band; + writer->trailer = ps_write_trailer; + writer->drop = ps_drop_band_writer; + + return writer; } diff --git a/source/fitz/output.c b/source/fitz/output.c index 0fc4fc09..d5dfb47e 100644 --- a/source/fitz/output.c +++ b/source/fitz/output.c @@ -292,3 +292,51 @@ fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename) fz_catch(ctx) fz_rethrow(ctx); } + +fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_output *out) +{ + fz_band_writer *writer = fz_calloc(ctx, size, 1); + + assert(size >= sizeof(*writer)); + + writer->out = out; + + return writer; +} + +void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum) +{ + if (writer == NULL || writer->band == NULL) + return; + writer->w = w; + writer->h = h; + writer->n = n; + writer->alpha = alpha; + writer->xres = xres; + writer->yres = yres; + writer->pagenum = pagenum; + writer->header(ctx, writer); +} + +void fz_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int band_height, const unsigned char *samples) +{ + if (writer == NULL || writer->band == NULL) + return; + writer->band(ctx, writer, stride, band_start, band_height, samples); +} + +void fz_write_trailer(fz_context *ctx, fz_band_writer *writer) +{ + if (writer == NULL || writer->trailer == NULL) + return; + writer->trailer(ctx, writer); +} + +void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer) +{ + if (writer == NULL) + return; + if (writer->drop != NULL) + writer->drop(ctx, writer); + fz_free(ctx, writer); +} diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 1b5300d9..4708516a 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -760,17 +760,11 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in fz_irect ibounds; fz_pixmap *pix = NULL; int w, h; - fz_png_output_context *poc = NULL; - fz_ps_output_context *psoc = NULL; - fz_mono_pcl_output_context *pmcoc = NULL; - fz_color_pcl_output_context *pccoc = NULL; + fz_band_writer *bander = NULL; fz_bitmap *bit = NULL; fz_var(pix); - fz_var(poc); - fz_var(psoc); - fz_var(pmcoc); - fz_var(pccoc); + fz_var(bander); fz_var(bit); fz_bound_page(ctx, page, &bounds); @@ -878,24 +872,26 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in if (output) { if (output_format == OUT_PGM || output_format == OUT_PPM || output_format == OUT_PNM) - fz_write_pnm_header(ctx, out, pix->w, totalheight, pix->n, pix->alpha); + bander = fz_new_pnm_band_writer(ctx, out); else if (output_format == OUT_PAM) - fz_write_pam_header(ctx, out, pix->w, totalheight, pix->n, pix->alpha); + bander = fz_new_pam_band_writer(ctx, out); else if (output_format == OUT_PNG) - poc = fz_write_png_header(ctx, out, pix->w, totalheight, pix->n, pix->alpha); + bander = fz_new_png_band_writer(ctx, out); else if (output_format == OUT_PBM) - fz_write_pbm_header(ctx, out, pix->w, totalheight); + bander = fz_new_pbm_band_writer(ctx, out); else if (output_format == OUT_PKM) - fz_write_pkm_header(ctx, out, pix->w, totalheight); + bander = fz_new_pkm_band_writer(ctx, out); else if (output_format == OUT_PS) - psoc = fz_write_ps_header(ctx, out, pix->w, totalheight, pix->n, pix->xres, pix->yres, ++output_pagenum); + bander = fz_new_ps_band_writer(ctx, out); else if (output_format == OUT_PCL) { if (out_cs == CS_MONO) - pmcoc = fz_write_mono_pcl_header(ctx, out, pix->w, totalheight, pix->xres, pix->yres, ++output_pagenum, NULL); + bander = fz_new_mono_pcl_band_writer(ctx, out, NULL); else - pccoc = fz_write_color_pcl_header(ctx, out, pix->w, totalheight, pix->n, pix->xres, pix->yres, ++output_pagenum, NULL); + bander = fz_new_color_pcl_band_writer(ctx, out, NULL); } + if (bander) + fz_write_header(ctx, bander, pix->w, totalheight, pix->n, pix->alpha, pix->xres, pix->yres, ++output_pagenum); } for (band = 0; band < bands; band++) @@ -915,43 +911,14 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in if (output) { - if (output_format == OUT_PGM || output_format == OUT_PPM || output_format == OUT_PNM) - fz_write_pnm_band(ctx, out, pix->w, totalheight, pix->n, pix->alpha, pix->stride, band * bandheight, drawheight, pix->samples); - else if (output_format == OUT_PAM) - fz_write_pam_band(ctx, out, pix->w, totalheight, pix->n, pix->alpha, pix->stride, band * bandheight, drawheight, pix->samples); - else if (output_format == OUT_PNG) - fz_write_png_band(ctx, out, poc, pix->stride, band * bandheight, drawheight, pix->samples); + if (bander) + fz_write_band(ctx, bander, bit ? bit->stride : pix->stride, band * bandheight, drawheight, bit ? bit->samples : pix->samples); else if (output_format == OUT_PWG) fz_write_pixmap_as_pwg(ctx, out, pix, NULL); - else if (output_format == OUT_PCL) - { - if (out_cs == CS_MONO) - { - fz_write_mono_pcl_band(ctx, out, pmcoc, bit); - fz_drop_bitmap(ctx, bit); - bit = NULL; - } - else - fz_write_color_pcl_band(ctx, out, pccoc, pix->w, totalheight, pix->n, pix->stride, band * bandheight, drawheight, pix->samples); - } - else if (output_format == OUT_PS) - fz_write_ps_band(ctx, out, psoc, pix->w, totalheight, pix->n, pix->stride, band * bandheight, drawheight, pix->samples); - else if (output_format == OUT_PBM) - { - fz_write_pbm_band(ctx, out, bit); - fz_drop_bitmap(ctx, bit); - bit = NULL; - } - else if (output_format == OUT_PKM) - { - fz_write_pkm_band(ctx, out, bit); - fz_drop_bitmap(ctx, bit); - bit = NULL; - } else if (output_format == OUT_TGA) - { fz_write_pixmap_as_tga(ctx, out, pix); - } + fz_drop_bitmap(ctx, bit); + bit = NULL; } if (num_workers > 0 && band + num_workers < bands) @@ -982,21 +949,13 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in /* Any page level trailers go here */ if (output) { - if (output_format == OUT_PNG) - fz_write_png_trailer(ctx, out, poc); - if (output_format == OUT_PS) - fz_write_ps_trailer(ctx, out, psoc); - if (output_format == OUT_PCL) - { - if (out_cs == CS_MONO) - fz_write_mono_pcl_trailer(ctx, out, pmcoc); - else - fz_write_color_pcl_trailer(ctx, out, pccoc); - } + if (bander) + fz_write_trailer(ctx, bander); } } fz_always(ctx) { + fz_drop_band_writer(ctx, bander); fz_drop_bitmap(ctx, bit); bit = NULL; if (num_workers > 0) diff --git a/source/tools/muraster.c b/source/tools/muraster.c index 07c64b72..a2fc7204 100644 --- a/source/tools/muraster.c +++ b/source/tools/muraster.c @@ -604,6 +604,12 @@ typedef struct render_details * will start at the maximum value, and may drop to 0 * if we have problems with memory. */ int num_workers; + + /* The band writer to output the page */ + fz_band_writer *bander; + + /* Number of components in image */ + int n; } render_details; enum @@ -784,6 +790,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds, 0); fz_set_pixmap_resolution(ctx, pix, x_resolution, y_resolution); } + fz_write_header(ctx, render->bander, pix->w, total_height, pix->n, pix->alpha, pix->xres, pix->yres, pagenum); for (band = 0; band < bands; band++) { @@ -818,22 +825,9 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de { /* If we get any errors while outputting the bands, retrying won't help. */ errors_are_fatal = 1; - if (output_format == OUT_PGM || output_format == OUT_PPM) - fz_write_pnm_band(ctx, out, pix->w, total_height, pix->n, pix->alpha, pix->stride, band_start, draw_height, pix->samples); - else if (output_format == OUT_PAM) - fz_write_pam_band(ctx, out, pix->w, total_height, pix->n, pix->alpha, pix->stride, band_start, draw_height, pix->samples); - else if (output_format == OUT_PBM) - { - fz_write_pbm_band(ctx, out, bit); - fz_drop_bitmap(ctx, bit); - bit = NULL; - } - else if (output_format == OUT_PKM) - { - fz_write_pkm_band(ctx, out, bit); - fz_drop_bitmap(ctx, bit); - bit = NULL; - } + fz_write_band(ctx, render->bander, bit ? bit->stride : pix->stride, band_start, draw_height, bit ? bit->samples : pix->samples); + fz_drop_bitmap(ctx, bit); + bit = NULL; errors_are_fatal = 0; } @@ -899,14 +893,7 @@ static int try_render_page(fz_context *ctx, int pagenum, fz_cookie *cookie, int { int w = render->ibounds.x1 - render->ibounds.x0; int h = render->ibounds.y1 - render->ibounds.y0; - if (output_format == OUT_PGM || output_format == OUT_PPM) - fz_write_pnm_header(ctx, out, w, h, output_format == OUT_PGM ? 1 : 3, 0); - else if (output_format == OUT_PAM) - fz_write_pam_header(ctx, out, w, h, 4, 0); - else if (output_format == OUT_PBM) - fz_write_pbm_header(ctx, out, w, h); - else if (output_format == OUT_PKM) - fz_write_pkm_header(ctx, out, w, h); + fz_write_header(ctx, render->bander, w, h, render->n, 0, 0, 0, 0); } fz_catch(ctx) { @@ -960,6 +947,7 @@ static int try_render_page(fz_context *ctx, int pagenum, fz_cookie *cookie, int fz_drop_page(ctx, render->page); fz_drop_display_list(ctx, render->list); + fz_drop_band_writer(ctx, render->bander); if (showtime) { @@ -1175,6 +1163,27 @@ initialise_banding(fz_context *ctx, render_details *render, int color) render->band_height_multiple = reps; render->bands_rendered = 0; + + if (output_format == OUT_PGM || output_format == OUT_PPM) + { + render->bander = fz_new_pnm_band_writer(ctx, out); + render->n = OUT_PGM ? 1 : 3; + } + else if (output_format == OUT_PAM) + { + render->bander = fz_new_pam_band_writer(ctx, out); + render->n = 4; + } + else if (output_format == OUT_PBM) + { + render->bander = fz_new_pbm_band_writer(ctx, out); + render->n = 1; + } + else if (output_format == OUT_PKM) + { + render->bander = fz_new_pkm_band_writer(ctx, out); + render->n = 4; + } } static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) |