From 68db2175993fd9e97da8585515ddffdfb0511d07 Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Fri, 21 Jun 2002 10:24:40 +0000 Subject: [PATCH] New functionality for tiff2ps utility: splitting long images in several pages. See http://bugzilla.remotesensing.org/show_bug.cgi?id=142 for explanation. Patch granted by John Williams . --- man/tiff2ps.1 | 32 +++++++++++- tools/tiff2ps.c | 135 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 150 insertions(+), 17 deletions(-) diff --git a/man/tiff2ps.1 b/man/tiff2ps.1 index 766babbb..09695166 100644 --- a/man/tiff2ps.1 +++ b/man/tiff2ps.1 @@ -1,4 +1,4 @@ -.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiff2ps.1,v 1.3 2002-05-10 10:45:43 dron Exp $ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiff2ps.1,v 1.4 2002-06-21 10:24:40 dron Exp $ .\" .\" Copyright (c) 1988-1997 Sam Leffler .\" Copyright (c) 1991-1997 Silicon Graphics, Inc. @@ -113,11 +113,23 @@ Force the generation of Encapsulated \*(Ps. .B \-h Specify the vertical size of the printed area (in inches). .TP +.B \-H +Specify the maximum height of image (in inches). Images with larger sizes will +be splitted in several pages. Option +.B \-L +may be used for specifying size of splitted images overlapping. +.TP .B \-i Enable/disable pixel interpolation. This option requires a single numeric value: zero to disable pixel interpolation and non-zero to enable. The default is enabled. .TP +.B \-L +Specify the size of overlapping for splitted images (in inches). Used in +conjuction with +.B \-H +option. +.TP .B \-m Where possible render using the .B imagemask @@ -179,6 +191,24 @@ tiff2ps -d 1 foo.tif .fi .RE (notice that directories are numbered starting at zero.) +.PP +If you have a long image, it may be splitted in several pages: +.RS +.nf +tiff2ps -h11 -w8.5 -H14 -L.5 foo.tif > foo.ps +.fi +.RE +The page size is set to 8.5x11 by +.B \-w +and +.B \-h +options. We will accept a small amount of vertical compression, so +.B \-H +set to 14. Any pages between 11 and 14 inches will be fit onto one page. +Pages longer than 14 inches are cut off at 11 and continued on the next +page. The +.B \-L.5 +option says to repeat a half inch on the next page (to improve readability). .SH BUGS Because \*(Ps does not support the notion of a colormap, 8-bit palette images produce 24-bit \*(Ps images. diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c index 0b337df4..04c9a108 100644 --- a/tools/tiff2ps.c +++ b/tools/tiff2ps.c @@ -1,4 +1,4 @@ -/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiff2ps.c,v 1.7 2002-06-02 11:41:23 dron Exp $ */ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiff2ps.c,v 1.8 2002-06-21 10:24:40 dron Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -107,6 +107,8 @@ int generateEPSF = TRUE; /* generate Encapsulated PostScript */ int PSduplex = FALSE; /* enable duplex printing */ int PStumble = FALSE; /* enable top edge binding */ int PSavoiddeadzone = TRUE; /* enable avoiding printer deadzone */ +float maxPageHeight = 0; /* maximum size to fit on page */ +float splitOverlap = 0; /* amount for split pages to overlag */ char *filename; /* input filename */ int useImagemask = FALSE; /* Use imagemask instead of image operator */ uint16 res_unit = 0; /* Resolution units: 1 - inches, 2 - cm*/ @@ -150,7 +152,7 @@ main(int argc, char* argv[]) extern int optind; FILE* output = stdout; - while ((c = getopt(argc, argv, "h:i:w:d:o:O:acemnzps128DT")) != -1) + while ((c = getopt(argc, argv, "h:H:L:i:w:d:o:O:acemnzps128DT")) != -1) switch (c) { case 'd': dirnum = atoi(optarg); @@ -170,6 +172,13 @@ main(int argc, char* argv[]) case 'h': pageHeight = atof(optarg); break; + case 'H': + maxPageHeight = atof(optarg); + if (pageHeight==0) pageHeight = maxPageHeight; + break; + case 'L': + splitOverlap = atof(optarg); + break; case 'm': useImagemask = TRUE; break; @@ -362,6 +371,12 @@ PhotoshopBanner(FILE* fd, uint32 w, uint32 h, int bs, int nc, char* startline) fprintf(fd, "\"\n"); } +/* + * pw : image width in pixels + * ph : image height in pixels + * pprw : image width in PS units (72 dpi) + * pprh : image height in PS units (72 dpi) + */ static void setupPageState(TIFF* tif, uint32* pw, uint32* ph, float* pprw, float* pprh) { @@ -410,6 +425,75 @@ static tsize_t tf_rowsperstrip; static tsize_t tf_numberstrips; static char *hex = "0123456789abcdef"; +/* + * imagewidth & imageheight are 1/72 inches + * pagewidth & pageheight are inches + */ +int +PlaceImage(FILE *fp, float pagewidth, float pageheight, + float imagewidth, float imageheight, int splitpage) +{ + float xtran = 0; + float ytran = 0; + float xscale = 1; + float yscale = 1; + float subimageheight; + float splitheight; + float overlap; + + pagewidth *= PS_UNIT_SIZE; + pageheight *= PS_UNIT_SIZE; + + if (maxPageHeight==0) + splitheight = 0; + else + splitheight = maxPageHeight * PS_UNIT_SIZE; + overlap = splitOverlap * PS_UNIT_SIZE; + + /* + * WIDTH: + * if too wide, scrunch to fit + * else leave it alone + */ + if (imagewidth <= pagewidth) { + xscale = imagewidth; + } else { + xscale = pagewidth; + } + + /* HEIGHT: + * if too long, scrunch to fit + * if too short, move to top of page + */ + if (imageheight <= pageheight) { + yscale = imageheight; + ytran = pageheight - imageheight; + } else if (imageheight > pageheight && + (splitheight == 0 || imageheight <= splitheight)) { + yscale = pageheight; + } else /* imageheight > splitheight */ { + subimageheight = imageheight - (pageheight-overlap)*splitpage; + if (subimageheight <= pageheight) { + yscale = imageheight; + ytran = pageheight - subimageheight; + splitpage = 0; + } else if ( subimageheight > pageheight && subimageheight <= splitheight) { + yscale = imageheight * pageheight / subimageheight; + ytran = 0; + splitpage = 0; + } else /* sumimageheight > splitheight */ { + yscale = imageheight; + ytran = pageheight - subimageheight; + splitpage++; + } + } + + fprintf(fp,"%f %f translate\n",xtran,ytran); + fprintf(fp,"%f %f scale\n",xscale,yscale); + + return splitpage; +} + /* returns the sequence number of the page processed */ int @@ -421,6 +505,7 @@ TIFF2PS(FILE* fd, TIFF* tif, float pw, float ph) uint32 subfiletype; uint16* sampleinfo; static int npages = 0; + int split; if (!TIFFGetField(tif, TIFFTAG_XPOSITION, &ox)) ox = 0; @@ -469,14 +554,30 @@ TIFF2PS(FILE* fd, TIFF* tif, float pw, float ph) fprintf(fd, "gsave\n"); fprintf(fd, "100 dict begin\n"); if (pw != 0 && ph != 0) { - /* NB: maintain image aspect ratio */ - scale = (pw*PS_UNIT_SIZE/prw) < (ph*PS_UNIT_SIZE/prh) ? - (pw*PS_UNIT_SIZE/prw) : - (ph*PS_UNIT_SIZE/prh); - if (scale > 1.0) - scale = 1.0; - fprintf(fd, "0 %f translate\n", ph*PS_UNIT_SIZE-prh*scale); - fprintf(fd, "%f %f scale\n", prw*scale, prh*scale); + if (maxPageHeight) { /* used -H option */ + split = PlaceImage(fd,pw,ph,prw,prh,0); + while( split ) { + PSpage(fd, tif, w, h); + fprintf(fd, "end\n"); + fprintf(fd, "grestore\n"); + fprintf(fd, "showpage\n"); + npages++; + fprintf(fd, "%%%%Page: %d %d\n", npages, npages); + fprintf(fd, "gsave\n"); + fprintf(fd, "100 dict begin\n"); + split = PlaceImage(fd,pw,ph,prw,prh,split); + } + } else { + /* NB: maintain image aspect ratio */ + scale = (pw*PS_UNIT_SIZE/prw) < (ph*PS_UNIT_SIZE/prh) ? + (pw*PS_UNIT_SIZE/prw) : + (ph*PS_UNIT_SIZE/prh); + if (scale > 1.0) + scale = 1.0; + fprintf(fd, "0 %f translate\n", + ph*PS_UNIT_SIZE-prh*scale); + fprintf(fd, "%f %f scale\n", prw*scale, prh*scale); + } } else fprintf(fd, "%f %f scale\n", prw, prh); PSpage(fd, tif, w, h); @@ -961,8 +1062,8 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h) tsize_t chunk_size, byte_count; #if defined( EXP_ASCII85ENCODER ) - int ascii85_l; /* Length, in bytes, of ascii85_p[] data */ - uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */ + int ascii85_l; /* Length, in bytes, of ascii85_p[] data */ + uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */ #endif PS_Lvl2colorspace(fd, tif); @@ -1370,8 +1471,8 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) tstrip_t s; #if defined( EXP_ASCII85ENCODER ) - int ascii85_l; /* Length, in bytes, of ascii85_p[] data */ - uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */ + int ascii85_l; /* Length, in bytes, of ascii85_p[] data */ + uint8 *ascii85_p = 0; /* Holds ASCII85 encoded data */ #endif (void) w; (void) h; @@ -1772,21 +1873,23 @@ char* stuff[] = { " -1 generate PostScript Level I (default)", " -2 generate PostScript Level II", " -8 disable use of ASCII85 encoding with PostScript Level II", +" -a convert all directories in file (default is first)", " -n override resolution units as inches", " -c override resolution units as centimeters", " -d # convert directory number #", " -D enable duplex printing (two pages per sheet of paper)", " -e generate Encapsulated PostScript (EPS)", " -h # assume printed page height is # inches (default 11)", +" -w # assume printed page width is # inches (default 8.5)", +" -H # split image if height is more than # inches", +" -L # overLap split images by # inches", " -i # enable/disable (Nz/0) pixel interpolation (default: enable)", " -m use \"imagemask\" operator instead of \"image\"", " -o # convert directory at file offset #", " -O file write PostScript to file instead of standard output", -" -a convert all directories in file (default is first)", " -p generate regular PostScript", " -s generate PostScript for a single image", " -T print pages for top edge binding", -" -w # assume printed page width is # inches (default 8.5)", " -z enable printing in the deadzone (only for PostScript Level II)", NULL };