diff options
-rw-r--r-- | include/mupdf/fitz/output-png.h | 8 | ||||
-rw-r--r-- | include/mupdf/fitz/output-pnm.h | 6 | ||||
-rw-r--r-- | source/fitz/pixmap.c | 346 | ||||
-rw-r--r-- | source/tools/mudraw.c | 180 |
4 files changed, 372 insertions, 168 deletions
diff --git a/include/mupdf/fitz/output-png.h b/include/mupdf/fitz/output-png.h index 9cf63f6f..47a67c49 100644 --- a/include/mupdf/fitz/output-png.h +++ b/include/mupdf/fitz/output-png.h @@ -27,4 +27,12 @@ void fz_output_png(fz_output *out, const fz_pixmap *pixmap, int savealpha); */ fz_buffer *fz_image_as_png(fz_context *ctx, fz_image *image, int w, int h); +typedef struct fz_png_output_context_s fz_png_output_context; + +fz_png_output_context *fz_output_png_header(fz_output *out, int w, int h, int n, int savealpha); + +void fz_output_png_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *samples, int savealpha, fz_png_output_context *poc); + +void fz_output_png_trailer(fz_output *out, fz_png_output_context *poc); + #endif diff --git a/include/mupdf/fitz/output-pnm.h b/include/mupdf/fitz/output-pnm.h index 8094aedb..42d2e9f7 100644 --- a/include/mupdf/fitz/output-pnm.h +++ b/include/mupdf/fitz/output-pnm.h @@ -14,6 +14,9 @@ */ void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); +void fz_output_pnm_header(fz_output *out, int w, int h, int n); +void fz_output_pnm_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *p); + /* fz_write_pam: Save a pixmap as a pam @@ -21,6 +24,9 @@ void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); */ void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); +void fz_output_pam_header(fz_output *out, int w, int h, int n, fz_colorspace *cs, int savealpha); +void fz_output_pam_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *sp, int savealpha); + /* fz_write_pbm: Save a bitmap as a pbm diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index 7391c17e..6444d7a9 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -432,52 +432,64 @@ fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma) */ void -fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) +fz_output_pnm_header(fz_output *out, int w, int h, int n) { - FILE *fp; - unsigned char *p; - int len; + fz_context *ctx = out->ctx; - if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4) + if (n != 1 && n != 2 && n != 4) fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm"); - fp = fopen(filename, "wb"); - if (!fp) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); + if (n == 1 || n == 2) + fz_printf(out, "P5\n"); + if (n == 4) + fz_printf(out, "P6\n"); + fz_printf(out, "%d %d\n", w, h); + fz_printf(out, "255\n"); +} + +void +fz_output_pnm_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *p) +{ + int len; + int start = band * bandheight; + int end = start + bandheight; - if (pixmap->n == 1 || pixmap->n == 2) - fprintf(fp, "P5\n"); - if (pixmap->n == 4) - fprintf(fp, "P6\n"); - fprintf(fp, "%d %d\n", pixmap->w, pixmap->h); - fprintf(fp, "255\n"); + if (end > h) + end = h; + end -= start; - len = pixmap->w * pixmap->h; - p = pixmap->samples; + len = w * end; - switch (pixmap->n) + switch (n) { case 1: - fwrite(p, 1, len, fp); + fz_write(out, p, len); break; case 2: while (len--) { - putc(p[0], fp); + fz_putc(out, p[0]); p += 2; } break; case 4: while (len--) { - putc(p[0], fp); - putc(p[1], fp); - putc(p[2], fp); + fz_putc(out, p[0]); + fz_putc(out, p[1]); + fz_putc(out, p[2]); p += 4; } } +} - fclose(fp); +void +fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) +{ + fz_output *out = fz_new_output_to_filename(ctx, filename); + fz_output_pnm_header(out, pixmap->w, pixmap->h, pixmap->n); + fz_output_pnm_band(out, pixmap->w, pixmap->h, pixmap->n, 0, pixmap->h, pixmap->samples); + fz_close_output(out); } /* @@ -485,50 +497,64 @@ fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename) */ void -fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) +fz_output_pam_header(fz_output *out, int w, int h, int n, fz_colorspace *cs, int savealpha) { - unsigned char *sp; - int y, w, k; - FILE *fp; - - int sn = pixmap->n; - int dn = pixmap->n; + int sn = n; + int dn = n; if (!savealpha && dn > 1) dn--; - fp = fopen(filename, "wb"); - if (!fp) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); - - fprintf(fp, "P7\n"); - fprintf(fp, "WIDTH %d\n", pixmap->w); - fprintf(fp, "HEIGHT %d\n", pixmap->h); - fprintf(fp, "DEPTH %d\n", dn); - fprintf(fp, "MAXVAL 255\n"); - if (pixmap->colorspace) - fprintf(fp, "# COLORSPACE %s\n", pixmap->colorspace->name); + fz_printf(out, "P7\n"); + fz_printf(out, "WIDTH %d\n", w); + fz_printf(out, "HEIGHT %d\n", h); + fz_printf(out, "DEPTH %d\n", dn); + fz_printf(out, "MAXVAL 255\n"); + if (cs) + fz_printf(out, "# COLORSPACE %s\n", cs->name); switch (dn) { - case 1: fprintf(fp, "TUPLTYPE GRAYSCALE\n"); break; - case 2: if (sn == 2) fprintf(fp, "TUPLTYPE GRAYSCALE_ALPHA\n"); break; - case 3: if (sn == 4) fprintf(fp, "TUPLTYPE RGB\n"); break; - case 4: if (sn == 4) fprintf(fp, "TUPLTYPE RGB_ALPHA\n"); break; + case 1: fz_printf(out, "TUPLTYPE GRAYSCALE\n"); break; + case 2: if (sn == 2) fz_printf(out, "TUPLTYPE GRAYSCALE_ALPHA\n"); break; + case 3: if (sn == 4) fz_printf(out, "TUPLTYPE RGB\n"); break; + case 4: if (sn == 4) fz_printf(out, "TUPLTYPE RGB_ALPHA\n"); break; } - fprintf(fp, "ENDHDR\n"); + fz_printf(out, "ENDHDR\n"); +} - sp = pixmap->samples; - for (y = 0; y < pixmap->h; y++) +void +fz_output_pam_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *sp, int savealpha) +{ + int y, x, k; + int start = band * bandheight; + int end = start + bandheight; + int sn = n; + int dn = n; + if (!savealpha && dn > 1) + dn--; + + if (end > h) + end = h; + end -= start; + + for (y = 0; y < end; y++) { - w = pixmap->w; - while (w--) + x = w; + while (x--) { for (k = 0; k < dn; k++) - putc(sp[k], fp); + fz_putc(out, sp[k]); sp += sn; } } +} - fclose(fp); +void +fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) +{ + fz_output *out = fz_new_output_to_filename(ctx, filename); + fz_output_pam_header(out, pixmap->w, pixmap->h, pixmap->n, pixmap->colorspace, savealpha); + fz_output_pam_band(out, pixmap->w, pixmap->h, pixmap->n, 0, pixmap->h, pixmap->samples, savealpha); + fz_close_output(out); } /* @@ -560,25 +586,20 @@ static void putchunk(char *tag, unsigned char *data, int size, fz_output *out) void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) { - FILE *fp = fopen(filename, "wb"); - fz_output *out = NULL; + fz_output *out = fz_new_output_to_filename(ctx, filename); + fz_png_output_context *poc = NULL; - if (!fp) - { - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno)); - } - - fz_var(out); + fz_var(poc); fz_try(ctx) { - out = fz_new_output_with_file(ctx, fp); - fz_output_png(out, pixmap, savealpha); + poc = fz_output_png_header(out, pixmap->w, pixmap->h, pixmap->n, savealpha); + fz_output_png_band(out, pixmap->w, pixmap->h, pixmap->n, 0, pixmap->h, pixmap->samples, savealpha, poc); } fz_always(ctx) { + fz_output_png_trailer(out, poc); fz_close_output(out); - fclose(fp); } fz_catch(ctx) { @@ -589,30 +610,59 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha) void fz_output_png(fz_output *out, const fz_pixmap *pixmap, int savealpha) { - static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; - unsigned char head[13]; - unsigned char *udata = NULL; - unsigned char *cdata = NULL; - unsigned char *sp, *dp; - uLong usize, csize; - int y, x, k, sn, dn; - int color; - int err; + fz_png_output_context *poc; fz_context *ctx; - if (!out || !pixmap) + if (!out) return; ctx = out->ctx; + poc = fz_output_png_header(out, pixmap->w, pixmap->h, pixmap->n, savealpha); + + fz_try(ctx) + { + fz_output_png_band(out, pixmap->w, pixmap->h, pixmap->n, 0, pixmap->h, pixmap->samples, savealpha, poc); + } + fz_always(ctx) + { + fz_output_png_trailer(out, poc); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } +} - fz_var(udata); - fz_var(cdata); +struct fz_png_output_context_s +{ + unsigned char *udata; + unsigned char *cdata; + uLong usize, csize; + z_stream stream; +}; - if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4) +fz_png_output_context * +fz_output_png_header(fz_output *out, int w, int h, int n, int savealpha) +{ + static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + unsigned char head[13]; + fz_context *ctx; + int color; + int sn, dn; + fz_png_output_context *poc; + + if (!out) + return NULL; + + ctx = out->ctx; + + if (n != 1 && n != 2 && n != 4) fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as png"); - sn = pixmap->n; - dn = pixmap->n; + poc = fz_malloc_struct(ctx, fz_png_output_context); + + sn = n; + dn = n; if (!savealpha && dn > 1) dn--; @@ -625,25 +675,76 @@ fz_output_png(fz_output *out, const fz_pixmap *pixmap, int savealpha) case 4: color = 6; break; } - usize = (pixmap->w * dn + 1) * pixmap->h; - csize = compressBound(usize); - fz_try(ctx) - { - udata = fz_malloc(ctx, usize); - cdata = fz_malloc(ctx, csize); - } - fz_catch(ctx) + big32(head+0, w); + big32(head+4, h); + head[8] = 8; /* depth */ + head[9] = color; + head[10] = 0; /* compression */ + head[11] = 0; /* filter */ + head[12] = 0; /* interlace */ + + fz_write(out, pngsig, 8); + putchunk("IHDR", head, 13, out); + + return poc; +} + +void +fz_output_png_band(fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *sp, int savealpha, fz_png_output_context *poc) +{ + unsigned char *dp; + int y, x, k, sn, dn, err, finalband; + fz_context *ctx; + + if (!out || !sp || !poc) + return; + + ctx = out->ctx; + + if (n != 1 && n != 2 && n != 4) + fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as png"); + + band *= bandheight; + finalband = (band+bandheight >= h); + if (finalband) + bandheight = h - band; + + sn = n; + dn = n; + if (!savealpha && dn > 1) + dn--; + + if (poc->udata == NULL) { - fz_free(ctx, udata); - fz_rethrow(ctx); + poc->usize = (w * dn + 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); + if (err != Z_OK) + fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); } - sp = pixmap->samples; - dp = udata; - for (y = 0; y < pixmap->h; y++) + dp = poc->udata; + for (y = 0; y < bandheight; y++) { *dp++ = 1; /* sub prediction filter */ - for (x = 0; x < pixmap->w; x++) + for (x = 0; x < w; x++) { for (k = 0; k < dn; k++) { @@ -657,31 +758,56 @@ fz_output_png(fz_output *out, const fz_pixmap *pixmap, int savealpha) } } - err = compress(cdata, &csize, udata, usize); - if (err != Z_OK) + poc->stream.next_in = (Bytef*)poc->udata; + poc->stream.avail_in = (uInt)(dp - poc->udata); + do { - fz_free(ctx, udata); - fz_free(ctx, cdata); - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot compress image data"); + poc->stream.next_out = poc->cdata; + poc->stream.avail_out = (uInt)poc->csize; + + if (!finalband) + { + err = deflate(&poc->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); + if (err != Z_STREAM_END) + fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err); + } + + if (poc->stream.next_out != poc->cdata) + putchunk("IDAT", poc->cdata, poc->stream.next_out - poc->cdata, out); } + while (poc->stream.avail_out == 0); +} - big32(head+0, pixmap->w); - big32(head+4, pixmap->h); - head[8] = 8; /* depth */ - head[9] = color; - head[10] = 0; /* compression */ - head[11] = 0; /* filter */ - head[12] = 0; /* interlace */ +void +fz_output_png_trailer(fz_output *out, fz_png_output_context *poc) +{ + unsigned char block[1]; + int err; + fz_context *ctx; - fz_write(out, pngsig, 8); - putchunk("IHDR", head, 13, out); - putchunk("IDAT", cdata, csize, out); - putchunk("IEND", head, 0, out); + if (!out || !poc) + return; + + ctx = out->ctx; - fz_free(ctx, udata); - fz_free(ctx, cdata); + err = deflateEnd(&poc->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("IEND", block, 0, out); } + fz_buffer * fz_image_as_png(fz_context *ctx, fz_image *image, int w, int h) { diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 7a6ad478..34801f51 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -154,6 +154,7 @@ static int ignore_errors = 0; static int output_format; static int append = 0; static int out_cs = CS_UNSET; +static int bandheight = 0; static int memtrace_current = 0; static int memtrace_peak = 0; static int memtrace_total = 0; @@ -190,6 +191,7 @@ static void usage(void) "\t-f -\tfit width and/or height exactly (ignore aspect)\n" "\t-c -\tcolorspace {mono,gray,grayalpha,rgb,rgba}\n" "\t-b -\tnumber of bits of antialiasing (0 to 8)\n" + "\t-B -\tmaximum bandheight (pgm, ppm, pam output only)\n" "\t-g\trender in grayscale\n" "\t-m\tshow timing information\n" "\t-M\tshow memory use summary\n" @@ -574,8 +576,11 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_irect ibounds; fz_pixmap *pix = NULL; int w, h; + fz_output *output_file = NULL; + fz_png_output_context *poc = NULL; fz_var(pix); + fz_var(poc); fz_bound_page(doc, page, &bounds); zoom = resolution / 72; @@ -637,82 +642,111 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_rect_from_irect(&tbounds, &ibounds); /* TODO: banded rendering and multi-page ppm */ - fz_try(ctx) { int savealpha = (out_cs == CS_RGBA || out_cs == CS_GRAYALPHA); + fz_irect band_ibounds = ibounds; + int band, bands = 1; + char filename_buf[512]; + int totalheight = ibounds.y1 - ibounds.y0; + int drawheight = totalheight; - pix = fz_new_pixmap_with_bbox(ctx, colorspace, &ibounds); - fz_pixmap_set_resolution(pix, resolution); - - if (savealpha) - fz_clear_pixmap(ctx, pix); - else - fz_clear_pixmap_with_value(ctx, pix, 255); - - dev = fz_new_draw_device(ctx, pix); - if (list) - fz_run_display_list(list, dev, &ctm, &tbounds, &cookie); - else - fz_run_page(doc, page, dev, &ctm, &cookie); - fz_free_device(dev); - dev = NULL; - - if (invert) - fz_invert_pixmap(ctx, pix); - if (gamma_value != 1) - fz_gamma_pixmap(ctx, pix, gamma_value); + if (bandheight != 0) + { + /* Banded rendering; we'll only render to a + * given height at a time. */ + drawheight = bandheight; + if (totalheight > bandheight) + band_ibounds.y1 = band_ibounds.y0 + bandheight; + bands = (totalheight + bandheight-1)/bandheight; + tbounds.y1 = tbounds.y0 + bandheight + 2; + } - if (savealpha) - fz_unmultiply_pixmap(ctx, pix); + pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds); + fz_pixmap_set_resolution(pix, resolution); if (output) { - char buf[512]; - sprintf(buf, output, pagenum); + sprintf(filename_buf, output, pagenum); + output_file = fz_new_output_to_filename(ctx, filename_buf); if (output_format == OUT_PGM || output_format == OUT_PPM || output_format == OUT_PNM) - fz_write_pnm(ctx, pix, buf); + fz_output_pnm_header(output_file, pix->w, totalheight, pix->n); else if (output_format == OUT_PAM) - fz_write_pam(ctx, pix, buf, savealpha); + fz_output_pam_header(output_file, pix->w, totalheight, pix->n, pix->colorspace, savealpha); else if (output_format == OUT_PNG) - fz_write_png(ctx, pix, buf, savealpha); - else if (output_format == OUT_PWG) + poc = fz_output_png_header(output_file, pix->w, totalheight, pix->n, savealpha); + } + + for (band = 0; band < bands; band++) + { + if (savealpha) + fz_clear_pixmap(ctx, pix); + else + fz_clear_pixmap_with_value(ctx, pix, 255); + + dev = fz_new_draw_device(ctx, pix); + if (list) + fz_run_display_list(list, dev, &ctm, &tbounds, &cookie); + else + fz_run_page(doc, page, dev, &ctm, &cookie); + fz_free_device(dev); + dev = NULL; + + if (invert) + fz_invert_pixmap(ctx, pix); + if (gamma_value != 1) + fz_gamma_pixmap(ctx, pix, gamma_value); + + if (savealpha) + fz_unmultiply_pixmap(ctx, pix); + + if (output) { - if (strstr(output, "%d") != NULL) - append = 0; - if (out_cs == CS_MONO) + if (output_format == OUT_PGM || output_format == OUT_PPM || output_format == OUT_PNM) + fz_output_pnm_band(output_file, pix->w, totalheight, pix->n, band, drawheight, pix->samples); + else if (output_format == OUT_PAM) + fz_output_pam_band(output_file, pix->w, totalheight, pix->n, band, drawheight, pix->samples, savealpha); + else if (output_format == OUT_PNG) + fz_output_png_band(output_file, pix->w, totalheight, pix->n, band, drawheight, pix->samples, savealpha, poc); + else if (output_format == OUT_PWG) { - fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); - fz_write_pwg_bitmap(ctx, bit, buf, append, NULL); - fz_drop_bitmap(ctx, bit); + if (strstr(output, "%d") != NULL) + append = 0; + if (out_cs == CS_MONO) + { + fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); + fz_write_pwg_bitmap(ctx, bit, filename_buf, append, NULL); + fz_drop_bitmap(ctx, bit); + } + else + fz_write_pwg(ctx, pix, filename_buf, append, NULL); + append = 1; } - else - fz_write_pwg(ctx, pix, buf, append, NULL); - append = 1; - } - else if (output_format == OUT_PCL) - { - fz_pcl_options options; - - fz_pcl_preset(ctx, &options, "ljet4"); - - if (strstr(output, "%d") != NULL) - append = 0; - if (out_cs == CS_MONO) + else if (output_format == OUT_PCL) { + fz_pcl_options options; + + fz_pcl_preset(ctx, &options, "ljet4"); + + if (strstr(output, "%d") != NULL) + append = 0; + if (out_cs == CS_MONO) + { + fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); + fz_write_pcl_bitmap(ctx, bit, filename_buf, append, &options); + fz_drop_bitmap(ctx, bit); + } + else + fz_write_pcl(ctx, pix, filename_buf, append, &options); + append = 1; + } + else if (output_format == OUT_PBM) { fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); - fz_write_pcl_bitmap(ctx, bit, buf, append, &options); + fz_write_pbm(ctx, bit, filename_buf); fz_drop_bitmap(ctx, bit); } - else - fz_write_pcl(ctx, pix, buf, append, &options); - append = 1; - } - else if (output_format == OUT_PBM) { - fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); - fz_write_pbm(ctx, bit, buf); - fz_drop_bitmap(ctx, bit); } + ctm.f -= drawheight; } if (showmd5) @@ -728,9 +762,17 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) } fz_always(ctx) { + if (output) + { + if (output_format == OUT_PNG) + fz_output_png_trailer(output_file, poc); + } + fz_free_device(dev); dev = NULL; fz_drop_pixmap(ctx, pix); + if (output_file) + fz_close_output(output_file); } fz_catch(ctx) { @@ -929,7 +971,7 @@ int main(int argc, char **argv) fz_var(doc); - while ((c = fz_getopt(argc, argv, "lo:F:p:r:R:b:c:dgmtx5G:Iw:h:fij:M")) != -1) + while ((c = fz_getopt(argc, argv, "lo:F:p:r:R:b:c:dgmtx5G:Iw:h:fij:MB:")) != -1) { switch (c) { @@ -939,6 +981,7 @@ int main(int argc, char **argv) case 'r': resolution = atof(fz_optarg); res_specified = 1; break; case 'R': rotation = atof(fz_optarg); break; case 'b': alphabits = atoi(fz_optarg); break; + case 'B': bandheight = atoi(fz_optarg); break; case 'l': showoutline++; break; case 'm': showtime++; break; case 'M': showmemory++; break; @@ -986,6 +1029,12 @@ int main(int argc, char **argv) fz_set_aa_level(ctx, alphabits); /* Determine output type */ + if (bandheight < 0) + { + fprintf(stderr, "Bandheight must be > 0\n"); + exit(1); + } + output_format = OUT_PNG; if (format) { @@ -1023,6 +1072,21 @@ int main(int argc, char **argv) } } + if (bandheight) + { + if (output_format != OUT_PAM && output_format != OUT_PGM && output_format != OUT_PPM && output_format != OUT_PNM && output_format != OUT_PNG) + { + fprintf(stderr, "Banded operation only possible with PAM, PGM, PPM, PNM and PNG outputs\n"); + exit(1); + } + if (showmd5) + { + fprintf(stderr, "Banded operation not compatible with MD5\n"); + exit(1); + } + + } + { int i, j; |