summaryrefslogtreecommitdiff
path: root/source/tools
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-08-29 18:36:14 +0100
committerRobin Watts <robin.watts@artifex.com>2013-08-30 16:25:59 +0100
commit8f248600b2834fb121db4990aa756c40da8ddd0e (patch)
tree5c7e8fe4743637a907a23788f94dd34bb1e84d99 /source/tools
parent3d8bdbcf696cb9d9ab5ec385bc4e5756adf63757 (diff)
downloadmupdf-8f248600b2834fb121db4990aa756c40da8ddd0e.tar.xz
Add simple banding to mudraw.
The most complex part here is to ensure that we can output various bitmaps in bands.
Diffstat (limited to 'source/tools')
-rw-r--r--source/tools/mudraw.c180
1 files changed, 122 insertions, 58 deletions
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;