Return-Path: <tiff-bounces@lists.maptools.org>
Received: from inas008.isp.belgacom.be (localhost [127.0.0.1])
        by inav030.isp.belgacom.be (8.12.11.20060308/8.12.11/Skynet-IN-AV-3.00) with ESMTP id k7VCwKYh017895
        for <joris.at.lebbeke@skynet.be>; Thu, 31 Aug 2006 14:58:20 +0200
        (envelope-from <tiff-bounces@lists.maptools.org>)
Received: from inmx007.isp.belgacom.be (inmx007.isp.belgacom.be [195.238.5.89])
        by inas008.isp.belgacom.be (8.12.11.20060308/8.12.11/Skynet-IN-AS-2.03) with ESMTP id k7VCw9ah002103
        for <joris.at.lebbeke@skynet.be>; Thu, 31 Aug 2006 14:58:09 +0200
        (envelope-from <tiff-bounces@lists.maptools.org>)
Received: from duke.maptools.org (r153.dmsolutions.ca [209.217.116.153] (may be forged))
        by inmx007.isp.belgacom.be (8.12.11.20060308/8.12.11/Skynet-IN-2.32) with ESMTP id k7VCw1Ae008341
        for <joris.at.lebbeke@skynet.be>; Thu, 31 Aug 2006 14:58:02 +0200
        (envelope-from <tiff-bounces@lists.maptools.org>)
Received: from duke.maptools.org (duke.maptools.org [127.0.0.1])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id k7VChZg0018272;
	Thu, 31 Aug 2006 08:44:16 -0400
Received: from mpls-qmqp-03.inet.qwest.net (mpls-qmqp-03.inet.qwest.net
	[63.231.195.114])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id k7VChW2Y018269
	for <tiff@lists.maptools.org>; Thu, 31 Aug 2006 08:43:33 -0400
Received: from mpls-pop-08.inet.qwest.net (mpls-pop-08.inet.qwest.net
	[63.231.195.8])
	by mpls-qmqp-03.inet.qwest.net (Postfix) with QMQP id 83A19621E02
	for <tiff@lists.maptools.org>; Thu, 31 Aug 2006 12:43:32 +0000 (UTC)
Received: from 71-33-166-212.hlrn.qwest.net (HELO ?127.0.0.1?) (71.33.166.212)
	by mpls-pop-08.inet.qwest.net with SMTP; 31 Aug 2006 12:43:31 -0000
Date: Thu, 31 Aug 2006 06:48:00 -0600
Message-ID: <44F6DA80.9030902@qwest.net>
From: "Richard Nolde" <nrichard8@qwest.net>
To: tiff@lists.maptools.org
User-Agent: Thunderbird 1.5.0.5 (Windows/20060719)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------040105040102080802090201"
Subject: [Tiff] Patch for enhanced version of tiff2ps
X-BeenThere: tiff@lists.maptools.org
X-Mailman-Version: 2.1.4
Precedence: list
List-Id: TIFF and libtiff discussion <tiff.lists.maptools.org>
List-Unsubscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=unsubscribe>
List-Archive: <http://lists.maptools.org/mailman/private/tiff>
List-Post: <mailto:tiff@lists.maptools.org>
List-Help: <mailto:tiff-request@lists.maptools.org?subject=help>
List-Subscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=subscribe>
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org
X-UIDL: 000000000023ceae.000019fc
X-MSP-STORE: Thu, 31 Aug 2006 14:58:27 +0200
Status:   

This is a multi-part message in MIME format.
--------------040105040102080802090201
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I recently posted a new version of tiff2ps.c to the bugzilla forum on 
the libtiff site, but I have been advised that members of the tiff list 
might also wish to see it. This version adds support for rotation of 
images by 90,180,270 or "auto" which chooses portrait or landscape 
orientation and rotates the image accordingly to fit the specified page 
size. Added the ability to produce multiple images constrained by a 
maximum width (but not at the same time as using the maximum page height 
already present) from a single image, in effect tiling the image into a 
series of images of that width.  The PlaceImage routine has been 
modified to support image sizes smaller or larger than the physical page 
size while still preserving the aspect ratio. There are still a few 
unsupported combinations in the tiling option, but the code has been in 
production use for over a year at my company.

To save space, I am only including a patch file rather than the entire 
source code here.  I can supply the full source if that would be 
helpful. This patch applies against the version of libtiff distributed 
as an RPM for Linux IA32, or POWER64 (AIX on IBM Pseries) with revisions 
3.7.2 or 3.8.2.  I have seen a bugzilla report that there is a problem 
with the bounding box size not being correctly set in the current 
release, and I do not think that this patch addresses that issue yet.  
Recent testing of this versions suggests that the described bug is still 
present in this patched version but I have not had time to get back to 
it to check.

If my current work on a tiffcrop utility pans out, I may develop an 
option for tiff2ps that actually crops the image before writing it out 
to postscript as this would make for much smaller file sizes with large 
images that are tiled using the -W or -H option. The current code 
appears to rely on the Postscript mask operator to do the masking rather 
than removing the unwanted parts of the image from the file.

As always, comments and corrections are welcome. 

Richard Nolde


--------------040105040102080802090201
Content-Type: text/plain;
 name="tiff2ps.382.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tiff2ps.382.patch"

--- tools/tiff2ps.c.orig	2006-07-14 16:35:54.000000000 -0600
+++ tools/tiff2ps.c	2006-07-21 12:39:45.000000000 -0600
@@ -38,9 +38,27 @@
 
 #include "tiffio.h"
 
+/* #define DEBUG */
 /*
  * Revision history
  *
+ * 2005-June-3
+ *    Richard Nolde: Added support for rotations of 90, 180, 270
+ *    and auto using -r <90|180|270|auto>.  Auto picks the best
+ *    fit for the image on the specified paper size (eg portrait
+ *    or landscape) if -h or -w is specified. Rotation is in
+ *    degrees counterclockwise since that is how Postscript does
+ *    it.  Auto rotates 90 degrees ccw to produce landscape.
+ *
+ *    Added maxPageWidth option using -W flag. MaxPageHeight and
+ *    MaxPageWidth are mutually exclusive since the aspect ratio
+ *    cannot be maintained if you set both.
+ *    Rewrote PlaceImage to allow maxPageHeight and maxPageWidth
+ *    options to work with values smaller or larger than the
+ *    physical paper size and still preserve the aspect ratio.
+ *    This is accomplished by creating multiple pages across
+ *    as well as down if need be.
+ *
  * 2001-Mar-21
  *    I (Bruce A. Mallett) added this revision history comment ;)
  *
@@ -106,6 +124,10 @@
 #define	FALSE	0
 #endif
 
+#define HORIZONTAL 1
+#define VERTICAL   2
+
+
 int	ascii85 = FALSE;		/* use ASCII85 encoding */
 int	interpolate = TRUE;		/* interpolate level2 image */
 int	level2 = FALSE;			/* generate PostScript level 2 */
@@ -115,9 +137,11 @@
 int	PSduplex = FALSE;		/* enable duplex printing */
 int	PStumble = FALSE;		/* enable top edge binding */
 int	PSavoiddeadzone = TRUE;		/* enable avoiding printer deadzone */
-double	maxPageHeight = 0;		/* maximum size to fit on page */
+double	maxPageHeight = 0;		/* maximum height to select from image and print per page */
+double	maxPageWidth  = 0;		/* maximum width  to select from image and print per page */
 double	splitOverlap = 0;		/* amount for split pages to overlag */
-int	rotate = FALSE;			/* rotate image by 180 degrees */
+int	rotate = FALSE;			/* rotate image by angle 90, 180, 270 degrees */
+int	rotation = 0;                   /* optional value for rotation angle */
 char	*filename;			/* input filename */
 int	useImagemask = FALSE;		/* Use imagemask instead of image operator */
 uint16	res_unit = 0;			/* Resolution units: 2 - inches, 3 - cm */
@@ -164,7 +188,7 @@
 	extern int optind;
 	FILE* output = stdout;
 
-	while ((c = getopt(argc, argv, "b:d:h:H:L:i:w:l:o:O:acelmrxyzps1238DT")) != -1)
+	while ((c = getopt(argc, argv, "b:d:h:H:W:L:i:w:l:o:O:r:acelmxyzps1238DT")) != -1)
 		switch (c) {
 		case 'b':
 			bottommargin = atof(optarg);
@@ -195,6 +219,10 @@
 			maxPageHeight = atof(optarg);
 			if (pageHeight==0) pageHeight = maxPageHeight;
 			break;
+		case 'W':
+			maxPageWidth = atof(optarg);
+			if (pageWidth==0) pageWidth = maxPageWidth;
+			break;
 		case 'L':
 			splitOverlap = atof(optarg);
 			break;
@@ -224,6 +252,21 @@
 			break;
 		case 'r':
 			rotate = TRUE;
+                        if (strcmp (optarg, "auto") == 0)
+                          rotation = 0;
+                        else
+ 			  rotation = atoi(optarg);
+                        switch (rotation)
+                          {
+			  case   0:
+                          case  90:
+                          case 180:
+                          case 270:
+			    break;
+			  default:
+                            fprintf (stderr, "Rotation angle must be 90, 180, 270 (degrees ccw) or auto\n");
+			    exit (-2);
+			  }
 			break;
 		case 's':
 			printAll = FALSE;
@@ -463,74 +506,242 @@
  * pagewidth & pageheight are inches
  */
 int
-PlaceImage(FILE *fp, double pagewidth, double pageheight,
-	   double imagewidth, double imageheight, int splitpage,
-	   double lm, double bm, int cnt)
-{
+PlaceImage(TIFF *tif, FILE *fp, int *npages, uint32 w, uint32 h,
+           double pagewidth, double pageheight,
+	   double imagewidth, double imageheight,
+           int splitpage, double lm, double bm, int cnt)
+{
+        int    i       = 0;
+        int    ximages = 0;
+        int    yimages = 0;
+        int    splitaxis = 0;
 	double xtran = 0;
 	double ytran = 0;
 	double xscale = 1;
 	double yscale = 1;
-	double left_offset = lm * PS_UNIT_SIZE;
-	double bottom_offset = bm * PS_UNIT_SIZE;
-	double subimageheight;
-	double splitheight;
-	double overlap;
+	double left_margin    = 0;
+	double bottom_margin  = 0;
+	double left_offset    = lm * PS_UNIT_SIZE;
+	double bottom_offset  = bm * PS_UNIT_SIZE;
+	double splitwidth     = 0;
+	double splitheight    = 0;
+	double subimageheight = 0;
+	double subimagewidth  = 0;
+	double overlap        = 0;
+	double overlapspace   = 0;
 
-	pagewidth *= PS_UNIT_SIZE;
+	pagewidth  *= PS_UNIT_SIZE;
 	pageheight *= PS_UNIT_SIZE;
 
-	if (maxPageHeight==0)
-		splitheight = 0;
-	else
-		splitheight = maxPageHeight * PS_UNIT_SIZE;
-	overlap = splitOverlap * PS_UNIT_SIZE;
+	splitheight = maxPageHeight * PS_UNIT_SIZE;
+	splitwidth  = maxPageWidth  * PS_UNIT_SIZE;
+	overlap     = splitOverlap  * PS_UNIT_SIZE;
+
+#ifdef DEBUG
+        fprintf (stderr, "-------------------------\n");
+	fprintf (stderr, "Page Width: %3.2f, Page Height: %3.2f Image Width: %3.2f Image Height: %3.2f\n",
+                 pagewidth, pageheight, imagewidth, imageheight);
+        fprintf (stderr, "Split Height: %3.2f, Split Width: %3.2f, Overlap: %3.2f, Pagesplits: %d\n", 
+                 splitheight, splitwidth, overlap, splitpage);
+#endif
+        /* These have to be mutually exclusive to maintain the aspect ratio */
+        if (splitheight != 0)
+          splitaxis = VERTICAL;
+        else {
+           if (splitwidth != 0)
+             splitaxis = HORIZONTAL;
+           else {
+             fprintf (stderr, "You must specify either a maximum page height or width\n");
+             return (0);
+           }
+        }
 
-	/*
-	 * WIDTH:
-	 *      if too wide, scrunch to fit
-	 *      else leave it alone
-	 */
-	if (imagewidth <= pagewidth) {
-		xscale = imagewidth;
-	} else {
-		xscale = pagewidth;
-	}
+        if (splitaxis == VERTICAL) {
+  	  if (imageheight <= splitheight) {
+	    /* Simple case, no splitting or scaling for image height */
+	    yscale = imageheight;
+	    ytran = pageheight - imageheight;
+	  } else { /* imageheight > splitheight */
+	      subimageheight = imageheight - ((splitheight - overlap) * splitpage);
+
+              yscale = imageheight * (pageheight / splitheight);
+	      ytran  = pageheight - subimageheight * (pageheight / splitheight);
+	    
+              if (subimageheight > splitheight) {
+	        splitpage++;
+	      } else {
+		  splitpage = 0;
+	          } 
+	  }
+	  bottom_offset += ytran / (cnt?2:1);
+          left_margin = left_offset / (cnt ? 2 : 1);
+
+	  /*
+           * WIDTH: We can't rescale height based on width so we need to make multiple
+           *   pages from each horizontal segment if the image is wider than pagewidth
+           */
+
+          ximages = ceil (imagewidth / pagewidth);
+          overlapspace = (ximages - 1) * overlap;
+#ifdef DEBUG
+	  fprintf (stderr, "Image Width / Page Width: %3.2f, Ximages: %d, Overlap %3.2f, \n", 
+		   (imagewidth / pagewidth), ximages, overlapspace);
 
-	/* 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 (stderr, "Image Width plus overlap: %3.2f Printable width: %3.2f\n", 
+                   imagewidth + overlapspace, ximages * pagewidth);
+#endif
+          if (((imagewidth + overlapspace) * (pageheight / splitheight)) > (ximages * pagewidth)) {
+            ximages++;
+            overlapspace += overlap;
+#ifdef DEBUG
+	    fprintf (stderr, "Adjusted Image Width plus overlap: %3.2f Printable width: %3.2f\n", 
+                   imagewidth + overlapspace, ximages * pagewidth);
+#endif
+	  }
+
+          xscale = (imagewidth + overlapspace) * (pageheight / splitheight);
+	  if (imagewidth <= pagewidth) {
+            left_offset = left_margin;
+            bottom_offset = bottom_margin;
+	    fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
+	    fprintf(fp, "%f %f scale\n", xscale, yscale);
+#ifdef DEBUG
+    	    fprintf (stderr, "Translate: %3.2f,  %3.2f, Scale: %3.2f,  %3.2f\n",
+		   left_offset, bottom_offset, xscale, yscale);
+#endif
+	  } else {
+            for (i = 0; i < ximages; i++) {
+              xtran = i * (pagewidth - ((i > 0) ? overlap : 0));
+	      left_offset = -xtran + left_margin;
+
+ 	      fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
+	      fprintf(fp, "%f %f scale\n", xscale, yscale);
+
+#ifdef DEBUG
+ 	      fprintf (stderr, "Page:   %d\n", *npages);
+    	      fprintf (stderr, "Translate: %3.2f,  %3.2f, Scale: %3.2f,  %3.2f\n",
+		      left_offset, bottom_offset, xscale, yscale);
+#endif
+              if ( i < (ximages - 1)) {
+  	        PSpage(fp, tif, w, h);
+	        fprintf(fp, "end\n");
+	        fprintf(fp, "grestore\n");
+	        fprintf(fp, "showpage\n");
+ 	        (*npages)++;
+	        fprintf(fp, "%%%%Page: %d %d\n", (*npages), (*npages));
+	        fprintf(fp, "gsave\n");
+	        fprintf(fp, "100 dict begin\n");
+	        }
+	    }
+	  }
+        } else {  /* splitaxis is HORIZONTAL */
+          ximages = ceil (imagewidth / splitwidth);
+          overlapspace = (ximages - 1) * overlap;
+#ifdef DEBUG
+	  fprintf (stderr, "Image Width / Split Width: %3.2f, Ximages: %d, Overlap %3.2f, \n", 
+		   (imagewidth / splitwidth), ximages, overlapspace);
+
+	  fprintf (stderr, "Image Width plus overlap: %3.2f Printable width: %3.2f\n", 
+                   imagewidth + overlapspace, ximages * pagewidth);
+#endif
+          if (((imagewidth + overlapspace) * (pagewidth / splitwidth)) > (ximages * pagewidth)) {
+            ximages++;
+            overlapspace += overlap;
+#ifdef DEBUG
+	    fprintf (stderr, "Adjusted Image Width plus overlap: %3.2f Printable width: %3.2f\n", 
+                   imagewidth + overlapspace, ximages * pagewidth);
+#endif
+	  }
+  	  if (ximages == 1) {
+	    /* Simple case, no splitting or scaling for image width */
+	    xscale = imagewidth;
+	    xtran = 0;
+            splitpage = 0;
+	  } else {
+#ifdef DEBUG
+              fprintf (stderr, "Image exceeds requested split width: %3.2f\n", splitwidth);
+#endif
+	      subimagewidth  = imagewidth  - ((splitwidth - overlap) * splitpage);
+
+              xscale = imagewidth * (pagewidth / splitwidth);
+	      xtran  = imagewidth - (subimagewidth * (pagewidth / splitwidth));
+
+              splitheight = pageheight;
+	      subimageheight = imageheight - ((splitheight - overlap) * splitpage);
+#ifdef DEBUG
+	      fprintf (stderr, "\nSubimage height is %3.2f\n", subimageheight);
+#endif
+              yscale = (imageheight + overlapspace);
+	      ytran  = pageheight - subimageheight  + (overlapspace * (pagewidth / splitwidth));
+
+              if (subimageheight > splitheight) {
+	        splitpage++;
+	      } else {
+		  splitpage = 0;
+	          } 
+	  }
+          bottom_margin = bottom_offset / (cnt ? 2 : 1);
+ 	  bottom_offset = bottom_margin + ytran;
+          left_margin = left_offset / (cnt ? 2 : 1);
+#ifdef DEBUG
+          fprintf (stderr, "Imagewidth: %3.2f, Subimage width: %3.2f, Splitpage: %d\n",
+			    imagewidth, subimagewidth, splitpage);
+          fprintf (stderr, "Bottom offset is %3.2f\n", bottom_offset);
+#endif
+	  if (imagewidth <= pagewidth) {
+            left_offset = left_margin;
+            bottom_offset = bottom_margin;
+	    fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
+	    fprintf(fp, "%f %f scale\n", xscale, yscale);
+#ifdef DEBUG
+    	    fprintf (stderr, "Translate: %3.2f,  %3.2f, Scale: %3.2f,  %3.2f\n",
+		   left_offset, bottom_offset, xscale, yscale);
+#endif
+	  } else {
+#ifdef DEBUG
+	      fprintf (stderr, "Image will be spread across %d horizontal images\n", ximages);
+#endif
+              for (i = 0; i < ximages; i++) {
+                xtran = i * (pagewidth - ((i > 0) ? overlap : 0));
+	        left_offset = left_margin - xtran;
+ 	        fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
+	        fprintf(fp, "%f %f scale\n", xscale, yscale);
+#ifdef DEBUG
+ 	        fprintf (stderr, "Page:   %d\n", *npages);
+    	        fprintf (stderr, "Translate: %3.2f,  %3.2f, Scale: %3.2f,  %3.2f\n",
+		      left_offset, bottom_offset, xscale, yscale);
+#endif
+                if ( i < (ximages - 1)) {
+  	          PSpage(fp, tif, w, h);
+	          fprintf(fp, "end\n");
+	          fprintf(fp, "grestore\n");
+	          fprintf(fp, "showpage\n");
+ 	          (*npages)++;
+	          fprintf(fp, "%%%%Page: %d %d\n", (*npages), (*npages));
+	          fprintf(fp, "gsave\n");
+	          fprintf(fp, "100 dict begin\n");
+	        }
+	      }
+	  }
 	}
-	
-	bottom_offset += ytran / (cnt?2:1);
-	if (cnt)
-	    left_offset += xtran / 2;
-	fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
-	fprintf(fp, "%f %f scale\n", xscale, yscale);
+
 	if (rotate)
-	    fputs ("1 1 translate 180 rotate\n", fp);
+	    {
+	    /* fprintf (stderr, "Rotate not supported at this time\n");
+               return 0;
+	    */
+	    if (rotation == 180 )
+              {
+    	      fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
+	      fprintf(fp, "%f %f scale\n", xscale, yscale);
+              }
+            else
+              {
+    	      fprintf(fp, "%f %f translate\n", bottom_offset, left_offset);
+	      fprintf(fp, "%f %f scale\n", yscale, xscale);
+              }
+	    fprintf (fp, "1 1 translate %d rotate\n", rotation);
+            }
 
 	return splitpage;
 }
@@ -541,10 +752,15 @@
 TIFF2PS(FILE* fd, TIFF* tif,
 	double pw, double ph, double lm, double bm, int cnt)
 {
-	uint32 w, h;
-	float ox, oy;
-        double prw, prh;
-	double scale = 1.0;
+	uint32 w = 0, h = 0;
+	float  ox, oy;
+        double maxsource, maxtarget;    /* Used for auto rotations */
+        double hcenter, vcenter;        /* Used for centering */
+        double prw, prh;    /* Original Image width and height in Postscript points */
+	double psw, psh;    /* Scaled image width and height in Postscript points */
+	double xscale, yscale, scale = 1.0;
+	double left_offset = lm * PS_UNIT_SIZE;
+	double bottom_offset = bm * PS_UNIT_SIZE;
 	uint32 subfiletype;
 	uint16* sampleinfo;
 	static int npages = 0;
@@ -554,15 +770,67 @@
 		ox = 0;
 	if (!TIFFGetField(tif, TIFFTAG_YPOSITION, &oy))
 		oy = 0;
-	setupPageState(tif, &w, &h, &prw, &prh);
-
+	/* setupPageState(tif, &w, &h, &prw, &prh); */
 	do {
 		tf_numberstrips = TIFFNumberOfStrips(tif);
 		TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP,
 		    &tf_rowsperstrip);
 		setupPageState(tif, &w, &h, &prw, &prh);
-		if (!npages)
-			PSHead(fd, tif, w, h, prw, prh, ox, oy);
+#ifdef DEBUG
+  	        fprintf (stderr, "\nPixel Width: %4d, Pixel Height: %4d\n"\
+                                 "Original printable area is %3.2f x %3.2f (%3.2f x %3.2f inches)\n",
+                          w, h, prw, prh, prw / 72.0, prh / 72.0);
+#endif
+                if (pw != 0) {
+                    psw = pw * PS_UNIT_SIZE;
+		    if (res_unit == RESUNIT_CENTIMETER)
+			psw *= 2.54F;
+		}
+                else
+                  psw = prw;
+
+                if (ph != 0) {
+                    psh = ph * PS_UNIT_SIZE;
+ 		    if (res_unit == RESUNIT_CENTIMETER)
+			psh *= 2.54F;
+		}
+                else
+                  psh = prh;
+
+                /* auto rotate for best fit */
+                if (rotate && rotation == 0) {
+                  maxsource = (prw >= prh) ? prw : prh;
+                  maxtarget = (psw >= psh) ? psw : psh;
+                  if (((maxsource == prw) && (maxtarget != psw)) ||
+                      ((maxsource == prh) && (maxtarget != psh))) {
+		    rotation = 90;
+		  } 
+		}
+
+                /* scaling depends on rotation and new page size */
+                switch (rotation) {
+                  case   0:  
+                  case 180:
+                    xscale = (psw - left_offset)/prw;
+                    yscale = (psh - bottom_offset)/prh;
+		    if (!npages)
+		      PSHead(fd, tif, w, h, psw, psh, ox, oy);
+                    break;
+		  case  90:
+                  case 270:
+                    xscale = (psw - bottom_offset) /prh;
+                    yscale = (psh - left_offset) /prw;
+		    if (!npages)
+		      PSHead(fd, tif, w, h, psh, psw, oy, ox);
+                    break;
+		}
+#ifdef DEBUG
+                fprintf (stderr, "Adjusted printable area is %6.2f x %6.2f (%3.2f x %3.2f inches)\n",
+                         psw, psh, psw / 72.0, psh / 72.0);
+                fprintf (stderr, "Psw: %6.2f, Prw: %6.2f, X Ratio: %3.2f\n"\
+                                 "Psh: %6.2f, Prh: %6.2f, Y Ratio: %3.2f\n",
+		                  psw, prw, xscale, psh, prh, yscale);
+#endif
 		TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE,
 		    &bitspersample);
 		TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL,
@@ -595,19 +863,6 @@
 			npages++;
 			fprintf(fd, "%%%%Page: %d %d\n", npages, npages);
 			if (!generateEPSF && ( level2 || level3 )) {
-				double psw, psh;
-				if (pw != 0.0) {
-					psw = pw * PS_UNIT_SIZE;
-					if (res_unit == RESUNIT_CENTIMETER)
-						psw *= 2.54F;
-				} else
-					psw=rotate ? prh:prw;
-				if (ph != 0.0) {
-					psh = ph * PS_UNIT_SIZE;
-					if (res_unit == RESUNIT_CENTIMETER)
-						psh *= 2.54F;
-				} else
-					psh=rotate ? prw:prh;
 				fprintf(fd,
 	"1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
 					psw, psh);
@@ -617,15 +872,11 @@
 			}
 			fprintf(fd, "gsave\n");
 			fprintf(fd, "100 dict begin\n");
+                        /* N.B. Setting maxPageHeight also sets ph if not set explicitly */
 			if (pw != 0 || ph != 0) {
-				double psw = pw, psh = ph;
-				if (!psw)
-					psw = prw;
-				if (!psh)
-					psh = prh;
-				if (maxPageHeight) { /* used -H option */
-					split = PlaceImage(fd,psw,psh,prw,prh,
-							   0,lm,bm,cnt);
+				if (maxPageHeight || maxPageWidth)  { /* used -H or -W options */
+				  split = PlaceImage(tif,fd,&npages,w,h,pw,ph,prw,prh,
+				     0,lm,bm,cnt);
 					while( split ) {
 					    PSpage(fd, tif, w, h);
 					    fprintf(fd, "end\n");
@@ -636,37 +887,95 @@
 						    npages, npages);
 					    fprintf(fd, "gsave\n");
 					    fprintf(fd, "100 dict begin\n");
-					    split = PlaceImage(fd,psw,psh,prw,prh,
-							       split,lm,bm,cnt);
-					}
-				} else {
-					double left_offset = lm * PS_UNIT_SIZE;
-					double bottom_offset = bm * PS_UNIT_SIZE;
-					psw *= PS_UNIT_SIZE;
-					psh *= PS_UNIT_SIZE;
-
-					/* NB: maintain image aspect ratio */
-					scale = psw/prw < psh/prh ?
-						psw/prw : psh/prh;
-					if (scale > 1.0)
-						scale = 1.0;
-					if (cnt) {
-						bottom_offset +=
-							(psh - prh * scale) / 2;
-						left_offset +=
-							(psw - prw * scale) / 2;
+					    split = PlaceImage(tif,fd,&npages,w,h,pw,ph,prw,prh,
+						split,lm,bm,cnt);
 					}
-					fprintf(fd, "%f %f translate\n",
-						left_offset, bottom_offset);
-					fprintf(fd, "%f %f scale\n",
-						prw * scale, prh * scale);
-					if (rotate)
-						fputs ("1 1 translate 180 rotate\n", fd);
+				} 
+                                else {
+				    /* NB: maintain image aspect ratio */
+                                    scale = (xscale < yscale) ? xscale : yscale; 
+				    if (scale > 1.0)
+				       	scale = 1.0;
+
+                                    /* Adjust offsets for centering */
+				    if (cnt) {
+                                      switch (rotation) {
+					case   90:
+                                        case  270:
+					    hcenter = (psw - prh * scale) / 2;
+					    vcenter = (psh - prw * scale) / 2;
+                                            break;
+					case    0:
+                                        case  180:
+					default:
+					    hcenter = (psw - prw * scale) / 2;
+					    vcenter = (psh - prh * scale) / 2;
+                                            break;
+				      }
+#ifdef DEBUG                                         
+                                    fprintf (stderr, "Left offset: %5.2f Bottom offset: %5.2f\n", hcenter, vcenter);
+#endif
+				    }
+				  else 
+                                      hcenter = 0.0, vcenter = 0.0;
+#ifdef DEBUG                                         
+				  fprintf (stderr, "Pw/Ph are non-zero: Width scaled: %6.2f, Height scaled: %6.3f Rotation: %d\n",
+                                           prw * scale, prh * scale, rotation);
+			          fprintf (stderr, "Scaling %6.2f %6.2f %d %d translate %d rotate\n",
+                                           prw * scale, prh * scale, 1, 0, rotation);
+#endif
+                                  if (cnt)
+  				     fprintf (fd, "%f %f translate\n", hcenter, vcenter);
+                                  switch (rotation) {
+ 				    case 0:
+				        fprintf (fd, "%f %f scale\n", prw * scale, prh * scale);
+                                        break;
+ 			       	    case 90:
+					fprintf (fd, "%f %f scale\n1 0 translate 90 rotate\n", prh * scale, prw * scale);
+                                        break;
+                                    case 180:
+					fprintf (fd, "%f %f scale\n1 1 translate 180 rotate\n", prw * scale, prh * scale);
+					break;
+				    case 270:
+					fprintf (fd, "%f %f scale\n0 1 translate 270 rotate\n", prh * scale, prw * scale);
+				        break;
+			            default:
+			                fprintf (stderr, "Unsupported angle. No rotation\n");
+					fprintf (fd, "%f %f scale\n", prw * scale, prh * scale);
+                                        break;
+				  }
 				}
 			} else {
-				fprintf(fd, "%f %f scale\n", prw, prh);
-				if (rotate)
-					fputs ("1 1 translate 180 rotate\n", fd);
+			    if (rotate)
+                              {
+			      /* Width and height have already been enchanged for 90/270 rotations */
+#ifdef DEBUG                                         
+			      fprintf (stderr, "Scaling %3.2f %3.2f %d %d translation %d rotatation\n",
+                                       prw, prh, 1, 0, rotation);
+#endif
+			      switch (rotation) {
+			         case   0:
+			             fprintf (fd, "%f %f scale\n", prw, prh);
+				 case  90:
+				     fprintf (fd, "%f %f scale\n1 0 translate 90 rotate\n", prw, prh); 
+                                     break;
+                                 case 180:
+			             fprintf (fd, "%f %f scale\n1 1 translate 180 rotate\n", prw, prh);
+                                     break;
+			         case 270:
+				     fprintf (fd, "%f %f scale\n0 1 translate 270 rotate\n", prw, prh); 
+                                     break;
+			         default:
+			             fprintf (stderr, "Unsupported angle. No rotation\n");
+			             fprintf( fd, "%f %f scale\n", prw, prh);
+                                     break;
+			         }
+			      }
+                            else
+			      {
+			      fprintf (stderr, "No rotation\n");
+			      fprintf (fd, "%f %f scale\n", prw, prh);
+			      }
 			}
 			PSpage(fd, tif, w, h);
 			fprintf(fd, "end\n");
@@ -730,8 +1039,13 @@
 	fprintf(fd, "%%%%DocumentData: Clean7Bit\n");
 	fprintf(fd, "%%%%Origin: %ld %ld\n", (long) ox, (long) oy);
 	/* NB: should use PageBoundingBox */
-	fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
-	    (long) ceil(pw), (long) ceil(ph));
+        if (rotate && (rotation == 90 || rotation == 270))
+ 	  fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
+	    (long) ceil(ph), (long) ceil(pw));
+        else
+          fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
+	    (long) ceil(pw), (long) ceil(ph));         
+
 	fprintf(fd, "%%%%LanguageLevel: %d\n", (level3 ? 3 : (level2 ? 2 : 1)));
 	fprintf(fd, "%%%%Pages: (atend)\n");
 	fprintf(fd, "%%%%EndComments\n");
@@ -2068,6 +2382,7 @@
 " -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",
+" -W #          split image if width is more than # inches",
 " -L #          overLap split images by # inches",
 " -i #          enable/disable (Nz/0) pixel interpolation (default: enable)",
 " -l #          set the left margin to # inches",
@@ -2075,7 +2390,7 @@
 " -o #          convert directory at file offset #",
 " -O file       write PostScript to file instead of standard output",
 " -p            generate regular PostScript",
-" -r            rotate by 180 degrees",
+" -r # or auto  rotate by 90, 180, 270 degrees or auto",
 " -s            generate PostScript for a single image",
 " -T            print pages for top edge binding",
 " -x            override resolution units as centimeters",

--------------040105040102080802090201
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Tiff mailing list: Tiff@lists.maptools.org
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
--------------040105040102080802090201--
