xref: /libtiff-4.0.7/tools/tiff2ps.c (revision bb96a66b)
1 /* $Id: tiff2ps.c,v 1.47 2011-04-09 16:53:08 bfriesen Exp $ */
2 
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  *
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  */
26 
27 #include "tif_config.h"
28 
29 #include <stdio.h>
30 #include <stdlib.h>			/* for atof */
31 #include <math.h>
32 #include <time.h>
33 #include <string.h>
34 
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 
39 #ifdef NEED_LIBPORT
40 # include "libport.h"
41 #endif
42 
43 #include "tiffio.h"
44 
45 /*
46  * Revision history
47  *
48  * 2010-Sep-17
49  *    Richard Nolde: Reinstate code from Feb 2009 that never got
50  *    accepted into CVS with major modifications to handle -H and -W
51  *    options. Replaced original PlaceImage function with several
52  *    new functions that make support for multiple output pages
53  *    from a single image easier to understand. Added additional
54  *    warning messages for incompatible command line options.
55  *    Add new command line options to specify PageOrientation
56  *    Document Structuring Comment for landscape or portrait
57  *    and code to determine the values from ouput width and height
58  *    if not specified on the command line.
59  *    Add new command line option to specify document creator
60  *    as an alterntive to the string "tiff2ps" following model
61  *    of patch submitted by Thomas Jarosch for specifiying a
62  *    document title which is also supported now.
63  *
64  * 2009-Feb-11
65  *    Richard Nolde: Added support for rotations of 90, 180, 270
66  *    and auto using -r <90|180|270|auto>.  Auto picks the best
67  *    fit for the image on the specified paper size (eg portrait
68  *    or landscape) if -h or -w is specified. Rotation is in
69  *    degrees counterclockwise since that is how Postscript does
70  *    it. The auto opption rotates the image 90 degrees ccw to
71  *    produce landscape if that is a better fit than portait.
72  *
73  *    Cleaned up code in TIFF2PS and broke into smaller functions
74  *    to simplify rotations.
75  *
76  *    Identified incompatible options and returned errors, eg
77  *    -i for imagemask operator is only available for Level2 or
78  *    Level3 Postscript in the current implmentation since there
79  *    is a difference in the way the operands are called for Level1
80  *    and there is no function to provide the Level1 version.
81  *    -H was not handled properly if -h and/or -w were specified.
82  *    It should only clip the masked images if the scaled image
83  *    exceeds the maxPageHeight specified with -H.
84  *
85  *    New design allows for all of the following combinations:
86  *    Conversion of TIFF to Postscript with optional rotations
87  *    of 90, 180, 270, or auto degrees counterclockwise
88  *    Conversion of TIFF to Postscript with entire image scaled
89  *    to maximum of values spedified with -h or -w while
90  *    maintaining aspect ratio. Same rotations apply.
91  *    Conversion of TIFF to Postscript with clipping of output
92  *    viewport to height specified with -H, producing multiple
93  *    pages at this height and original width as needed.
94  *    Same rotations apply.
95  *    Conversion of TIFF to Postscript with image scaled to
96  *    maximum specified by -h and -w and the resulting scaled
97  *    image is presented in an output viewport clipped by -H height.
98  *    The same rotations apply.
99  *
100  *    Added maxPageWidth option using -W flag. MaxPageHeight and
101  *    MaxPageWidth are mutually exclusive since the aspect ratio
102  *    cannot be maintained if you set both.
103  *    Rewrote PlaceImage to allow maxPageHeight and maxPageWidth
104  *    options to work with values smaller or larger than the
105  *    physical paper size and still preserve the aspect ratio.
106  *    This is accomplished by creating multiple pages across
107  *    as well as down if need be.
108  *
109  * 2001-Mar-21
110  *    I (Bruce A. Mallett) added this revision history comment ;)
111  *
112  *    Fixed PS_Lvl2page() code which outputs non-ASCII85 raw
113  *    data.  Moved test for when to output a line break to
114  *    *after* the output of a character.  This just serves
115  *    to fix an eye-nuisance where the first line of raw
116  *    data was one character shorter than subsequent lines.
117  *
118  *    Added an experimental ASCII85 encoder which can be used
119  *    only when there is a single buffer of bytes to be encoded.
120  *    This version is much faster at encoding a straight-line
121  *    buffer of data because it can avoid a lot of the loop
122  *    overhead of the byte-by-byte version.  To use this version
123  *    you need to define EXP_ASCII85ENCODER (experimental ...).
124  *
125  *    Added bug fix given by Michael Schmidt to PS_Lvl2page()
126  *    in which an end-of-data marker ('>') was not being output
127  *    when producing non-ASCII85 encoded PostScript Level 2
128  *    data.
129  *
130  *    Fixed PS_Lvl2colorspace() so that it no longer assumes that
131  *    a TIFF having more than 2 planes is a CMYK.  This routine
132  *    no longer looks at the samples per pixel but instead looks
133  *    at the "photometric" value.  This change allows support of
134  *    CMYK TIFFs.
135  *
136  *    Modified the PostScript L2 imaging loop so as to test if
137  *    the input stream is still open before attempting to do a
138  *    flushfile on it.  This was done because some RIPs close
139  *    the stream after doing the image operation.
140  *
141  *    Got rid of the realloc() being done inside a loop in the
142  *    PSRawDataBW() routine.  The code now walks through the
143  *    byte-size array outside the loop to determine the largest
144  *    size memory block that will be needed.
145  *
146  *    Added "-m" switch to ask tiff2ps to, where possible, use the
147  *    "imagemask" operator instead of the "image" operator.
148  *
149  *    Added the "-i #" switch to allow interpolation to be disabled.
150  *
151  *    Unrolled a loop or two to improve performance.
152  */
153 
154 /*
155  * Define EXP_ASCII85ENCODER if you want to use an experimental
156  * version of the ASCII85 encoding routine.  The advantage of
157  * using this routine is that tiff2ps will convert to ASCII85
158  * encoding at between 3 and 4 times the speed as compared to
159  * using the old (non-experimental) encoder.  The disadvantage
160  * is that you will be using a new (and unproven) encoding
161  * routine.  So user beware, you have been warned!
162  */
163 
164 #define	EXP_ASCII85ENCODER
165 
166 /*
167  * NB: this code assumes uint32 works with printf's %l[ud].
168  */
169 #ifndef TRUE
170 #define	TRUE	1
171 #define	FALSE	0
172 #endif
173 
174 int	ascii85 = FALSE;		/* use ASCII85 encoding */
175 int	interpolate = TRUE;		/* interpolate level2 image */
176 int	level2 = FALSE;			/* generate PostScript level 2 */
177 int	level3 = FALSE;			/* generate PostScript level 3 */
178 int	printAll = FALSE;		/* print all images in file */
179 int	generateEPSF = TRUE;		/* generate Encapsulated PostScript */
180 int	PSduplex = FALSE;		/* enable duplex printing */
181 int	PStumble = FALSE;		/* enable top edge binding */
182 int	PSavoiddeadzone = TRUE;		/* enable avoiding printer deadzone */
183 double	maxPageHeight = 0;		/* maximum height to select from image and print per page */
184 double	maxPageWidth  = 0;		/* maximum width  to select from image and print per page */
185 double	splitOverlap = 0;		/* amount for split pages to overlag */
186 int	rotation = 0;                   /* optional value for rotation angle */
187 int     auto_rotate = 0;                /* rotate image for best fit on the page */
188 char	*filename = NULL;		/* input filename */
189 char    *title = NULL;                  /* optional document title string */
190 char    *creator = NULL;                /* optional document creator string */
191 char    pageOrientation[12];            /* set optional PageOrientation DSC to Landscape or Portrait */
192 int	useImagemask = FALSE;		/* Use imagemask instead of image operator */
193 uint16	res_unit = 0;			/* Resolution units: 2 - inches, 3 - cm */
194 
195 /*
196  * ASCII85 Encoding Support.
197  */
198 unsigned char ascii85buf[10];
199 int	ascii85count;
200 int	ascii85breaklen;
201 
202 int	TIFF2PS(FILE*, TIFF*, double, double, double, double, int);
203 void	PSpage(FILE*, TIFF*, uint32, uint32);
204 void	PSColorContigPreamble(FILE*, uint32, uint32, int);
205 void	PSColorSeparatePreamble(FILE*, uint32, uint32, int);
206 void	PSDataColorContig(FILE*, TIFF*, uint32, uint32, int);
207 void	PSDataColorSeparate(FILE*, TIFF*, uint32, uint32, int);
208 void	PSDataPalette(FILE*, TIFF*, uint32, uint32);
209 void	PSDataBW(FILE*, TIFF*, uint32, uint32);
210 void	PSRawDataBW(FILE*, TIFF*, uint32, uint32);
211 void	Ascii85Init(void);
212 void	Ascii85Put(unsigned char code, FILE* fd);
213 void	Ascii85Flush(FILE* fd);
214 void    PSHead(FILE*, double, double, double, double);
215 void	PSTail(FILE*, int);
216 int     psStart(FILE *, int, int, int *, double *, double, double, double,
217                 double, double, double, double, double, double, double);
218 int     psPageSize(FILE *, int, double, double, double, double, double, double);
219 int     psRotateImage(FILE *, int, double, double, double, double);
220 int     psMaskImage(FILE *, TIFF *, int, int, int *, double, double,
221 		    double, double, double, double, double, double, double);
222 int     psScaleImage(FILE *, double, int, int, double, double, double, double,
223                      double, double);
224 int     get_viewport (double, double, double, double, double *, double *, int);
225 int     exportMaskedImage(FILE *, double, double, double, double, int, int,
226 			  double, double, double, int, int);
227 
228 #if	defined( EXP_ASCII85ENCODER)
229 tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw_p, tsize_t raw_l );
230 #endif
231 
232 static	void usage(int);
233 
234 int
235 main(int argc, char* argv[])
236 {
237 	int dirnum = -1, c, np = 0;
238 	int centered = 0;
239 	double bottommargin = 0;
240 	double leftmargin = 0;
241 	double pageWidth = 0;
242 	double pageHeight = 0;
243 	uint32 diroff = 0;
244 	extern char *optarg;
245 	extern int optind;
246 	FILE* output = stdout;
247 
248         pageOrientation[0] = '\0';
249 
250 	while ((c = getopt(argc, argv, "b:d:h:H:W:L:i:w:l:o:O:P:C:r:t:acemxyzps1238DT")) != -1)
251 		switch (c) {
252 		case 'b':
253 			bottommargin = atof(optarg);
254 			break;
255 		case 'c':
256 			centered = 1;
257 			break;
258                 case 'C':
259                         creator = optarg;
260                         break;
261 		case 'd': /* without -a, this only processes one image at this IFD */
262 			dirnum = atoi(optarg);
263 			break;
264 		case 'D':
265 			PSduplex = TRUE;
266 			break;
267 		case 'i':
268 			interpolate = atoi(optarg) ? TRUE:FALSE;
269 			break;
270 		case 'T':
271 			PStumble = TRUE;
272 			break;
273 		case 'e':
274                         PSavoiddeadzone = FALSE;
275 			generateEPSF = TRUE;
276 			break;
277 		case 'h':
278 			pageHeight = atof(optarg);
279 			break;
280 		case 'H':
281 			maxPageHeight = atof(optarg);
282 			break;
283 		case 'W':
284 			maxPageWidth = atof(optarg);
285 			break;
286 		case 'L':
287 			splitOverlap = atof(optarg);
288 			break;
289 		case 'm':
290 			useImagemask = TRUE;
291 			break;
292 		case 'o':
293 		        switch (optarg[0])
294                           {
295                           case '0':
296                           case '1':
297                           case '2':
298                           case '3':
299                           case '4':
300                           case '5':
301                           case '6':
302                           case '7':
303                           case '8':
304                           case '9': diroff = (uint32) strtoul(optarg, NULL, 0);
305 			          break;
306                           default: TIFFError ("-o", "Offset must be a numeric value.");
307 			    exit (1);
308 			  }
309 			break;
310 		case 'O':		/* XXX too bad -o is already taken */
311 			output = fopen(optarg, "w");
312 			if (output == NULL) {
313 				fprintf(stderr,
314 				    "%s: %s: Cannot open output file.\n",
315 				    argv[0], optarg);
316 				exit(-2);
317 			}
318 			break;
319 		case 'P':
320                         switch (optarg[0])
321                           {
322                           case 'l':
323                           case 'L': strcpy (pageOrientation, "Landscape");
324 			            break;
325                           case 'p':
326                           case 'P': strcpy (pageOrientation, "Portrait");
327 			            break;
328                           default: TIFFError ("-P", "Page orientation must be Landscape or Portrait");
329 			           exit (-1);
330 			  }
331 			break;
332 		case 'l':
333 			leftmargin = atof(optarg);
334 			break;
335 		case 'a': /* removed fall through to generate warning below, R Nolde 09-01-2010 */
336 			printAll = TRUE;
337 			break;
338 		case 'p':
339 			generateEPSF = FALSE;
340 			break;
341 		case 'r':
342                         if (strcmp (optarg, "auto") == 0)
343 			  {
344                           rotation = 0;
345                           auto_rotate = TRUE;
346                           }
347                         else
348 			  {
349  			  rotation = atoi(optarg);
350                           auto_rotate = FALSE;
351 			  }
352                         switch (rotation)
353                           {
354 			  case   0:
355                           case  90:
356                           case 180:
357                           case 270:
358 			    break;
359 			  default:
360                             fprintf (stderr, "Rotation angle must be 90, 180, 270 (degrees ccw) or auto\n");
361 			    exit (-1);
362 			  }
363 			break;
364 		case 's':
365 			printAll = FALSE;
366 			break;
367                 case 't':
368                         title = optarg;
369                         break;
370 		case 'w':
371 			pageWidth = atof(optarg);
372 			break;
373 		case 'z':
374 			PSavoiddeadzone = FALSE;
375 			break;
376 		case '1':
377 			level2 = FALSE;
378 			level3 = FALSE;
379 			ascii85 = FALSE;
380 			break;
381 		case '2':
382 			level2 = TRUE;
383 			ascii85 = TRUE;			/* default to yes */
384 			break;
385 		case '3':
386 			level3 = TRUE;
387 			ascii85 = TRUE;			/* default to yes */
388 			break;
389 		case '8':
390 			ascii85 = FALSE;
391 			break;
392 		case 'x':
393 			res_unit = RESUNIT_CENTIMETER;
394 			break;
395 		case 'y':
396 			res_unit = RESUNIT_INCH;
397 			break;
398 		case '?':
399 			usage(-1);
400 		}
401 
402         if (useImagemask == TRUE)
403           {
404 	  if ((level2 == FALSE) && (level3 == FALSE))
405             {
406 	    TIFFError ("-m "," imagemask operator requres Postscript Level2 or Level3");
407 	    exit (1);
408             }
409           }
410 
411         if (pageWidth && (maxPageWidth > pageWidth))
412 	  {
413 	  TIFFError ("-W", "Max viewport width cannot exceed page width");
414 	  exit (1);
415           }
416 
417 	if (pageHeight && (maxPageHeight > pageHeight))
418 	  {
419 	  TIFFError ("-H", "Max viewport height cannot exceed page height");
420 	  exit (1);
421           }
422 
423         /* auto rotate requires a specified page width and height */
424         if (auto_rotate == TRUE)
425           {
426 	  if ((pageWidth == 0) || (pageHeight == 0))
427 	    TIFFWarning ("-r auto", " requires page height and width specified with -h and -w");
428 
429           if ((maxPageWidth > 0) || (maxPageHeight > 0))
430             {
431 	    TIFFError ("-r auto", " is incompatible with maximum page width/height specified by -H or -W");
432             exit (1);
433             }
434           }
435         if ((maxPageWidth > 0) && (maxPageHeight > 0))
436             {
437 	    TIFFError ("-H and -W", " Use only one of -H or -W to define a viewport");
438             exit (1);
439             }
440 
441         if ((generateEPSF == TRUE) && (printAll == TRUE))
442           {
443 	  TIFFError(" -e and -a", "Warning: Cannot generate Encapsulated Postscript for multiple images");
444 	  generateEPSF = FALSE;
445           }
446 
447         if ((generateEPSF == TRUE) && (PSduplex == TRUE))
448           {
449 	  TIFFError(" -e and -D", "Warning: Encapsulated Postscript does not support Duplex option");
450 	  PSduplex = FALSE;
451           }
452 
453         if ((generateEPSF == TRUE) && (PStumble == TRUE))
454           {
455 	  TIFFError(" -e and -T", "Warning: Encapsulated Postscript does not support Top Edge Binding option");
456 	  PStumble = FALSE;
457           }
458 
459         if ((generateEPSF == TRUE) && (PSavoiddeadzone == TRUE))
460 	  PSavoiddeadzone = FALSE;
461 
462 	for (; argc - optind > 0; optind++) {
463 		TIFF* tif = TIFFOpen(filename = argv[optind], "r");
464 		if (tif != NULL) {
465 			if (dirnum != -1
466                             && !TIFFSetDirectory(tif, (tdir_t)dirnum))
467 				return (-1);
468 			else if (diroff != 0 &&
469 			    !TIFFSetSubDirectory(tif, diroff))
470 				return (-1);
471 			np = TIFF2PS(output, tif, pageWidth, pageHeight,
472 				     leftmargin, bottommargin, centered);
473                         if (np < 0)
474                           {
475 			  TIFFError("Error", "Unable to process %s", filename);
476                           }
477 			TIFFClose(tif);
478 		}
479 	}
480 	if (np)
481 		PSTail(output, np);
482 	else
483 		usage(-1);
484 	if (output != stdout)
485 		fclose(output);
486 	return (0);
487 }
488 
489 static	uint16 samplesperpixel;
490 static	uint16 bitspersample;
491 static	uint16 planarconfiguration;
492 static	uint16 photometric;
493 static	uint16 compression;
494 static	uint16 extrasamples;
495 static	int alpha;
496 
497 static int
498 checkImage(TIFF* tif)
499 {
500 	switch (photometric) {
501 	case PHOTOMETRIC_YCBCR:
502 		if ((compression == COMPRESSION_JPEG || compression == COMPRESSION_OJPEG)
503 			&& planarconfiguration == PLANARCONFIG_CONTIG) {
504 			/* can rely on libjpeg to convert to RGB */
505 			TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE,
506 				     JPEGCOLORMODE_RGB);
507 			photometric = PHOTOMETRIC_RGB;
508 		} else {
509 			if (level2 || level3)
510 				break;
511 			TIFFError(filename, "Can not handle image with %s",
512 			    "PhotometricInterpretation=YCbCr");
513 			return (0);
514 		}
515 		/* fall thru... */
516 	case PHOTOMETRIC_RGB:
517 		if (alpha && bitspersample != 8) {
518 			TIFFError(filename,
519 			    "Can not handle %d-bit/sample RGB image with alpha",
520 			    bitspersample);
521 			return (0);
522 		}
523 		/* fall thru... */
524 	case PHOTOMETRIC_SEPARATED:
525 	case PHOTOMETRIC_PALETTE:
526 	case PHOTOMETRIC_MINISBLACK:
527 	case PHOTOMETRIC_MINISWHITE:
528 		break;
529 	case PHOTOMETRIC_LOGL:
530 	case PHOTOMETRIC_LOGLUV:
531 		if (compression != COMPRESSION_SGILOG &&
532 		    compression != COMPRESSION_SGILOG24) {
533 			TIFFError(filename,
534 		    "Can not handle %s data with compression other than SGILog",
535 			    (photometric == PHOTOMETRIC_LOGL) ?
536 				"LogL" : "LogLuv"
537 			);
538 			return (0);
539 		}
540 		/* rely on library to convert to RGB/greyscale */
541 		TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
542 		photometric = (photometric == PHOTOMETRIC_LOGL) ?
543 		    PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB;
544 		bitspersample = 8;
545 		break;
546 	case PHOTOMETRIC_CIELAB:
547 		/* fall thru... */
548 	default:
549 		TIFFError(filename,
550 		    "Can not handle image with PhotometricInterpretation=%d",
551 		    photometric);
552 		return (0);
553 	}
554 	switch (bitspersample) {
555 	case 1: case 2:
556 	case 4: case 8:
557 	case 16:
558 		break;
559 	default:
560 		TIFFError(filename, "Can not handle %d-bit/sample image",
561 		    bitspersample);
562 		return (0);
563 	}
564 	if (planarconfiguration == PLANARCONFIG_SEPARATE && extrasamples > 0)
565 		TIFFWarning(filename, "Ignoring extra samples");
566 	return (1);
567 }
568 
569 #define PS_UNIT_SIZE	72.0F
570 #define	PSUNITS(npix,res)	((npix) * (PS_UNIT_SIZE / (res)))
571 
572 static	char RGBcolorimage[] = "\
573 /bwproc {\n\
574     rgbproc\n\
575     dup length 3 idiv string 0 3 0\n\
576     5 -1 roll {\n\
577 	add 2 1 roll 1 sub dup 0 eq {\n\
578 	    pop 3 idiv\n\
579 	    3 -1 roll\n\
580 	    dup 4 -1 roll\n\
581 	    dup 3 1 roll\n\
582 	    5 -1 roll put\n\
583 	    1 add 3 0\n\
584 	} { 2 1 roll } ifelse\n\
585     } forall\n\
586     pop pop pop\n\
587 } def\n\
588 /colorimage where {pop} {\n\
589     /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def\n\
590 } ifelse\n\
591 ";
592 
593 /*
594  * Adobe Photoshop requires a comment line of the form:
595  *
596  * %ImageData: <cols> <rows> <depth>  <main channels> <pad channels>
597  *	<block size> <1 for binary|2 for hex> "data start"
598  *
599  * It is claimed to be part of some future revision of the EPS spec.
600  */
601 static void
602 PhotoshopBanner(FILE* fd, uint32 w, uint32 h, int bs, int nc, char* startline)
603 {
604 	fprintf(fd, "%%ImageData: %ld %ld %d %d 0 %d 2 \"",
605 	    (long) w, (long) h, bitspersample, nc, bs);
606 	fprintf(fd, startline, nc);
607 	fprintf(fd, "\"\n");
608 }
609 
610 /*   Convert pixel width and height pw, ph, to points pprw, pprh
611  *   using image resolution and resolution units from TIFF tags.
612  *   pw : image width in pixels
613  *   ph : image height in pixels
614  * pprw : image width in PS units (72 dpi)
615  * pprh : image height in PS units (72 dpi)
616  */
617 static void
618 setupPageState(TIFF* tif, uint32* pw, uint32* ph, double* pprw, double* pprh)
619 {
620 	float xres = 0.0F, yres = 0.0F;
621 
622 	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, pw);
623 	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ph);
624 	if (res_unit == 0)	/* Not specified as command line option */
625 		if (!TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &res_unit))
626 			res_unit = RESUNIT_INCH;
627 	/*
628 	 * Calculate printable area.
629 	 */
630 	if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)
631             || fabs(xres) < 0.0000001)
632 		xres = PS_UNIT_SIZE;
633 	if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)
634             || fabs(yres) < 0.0000001)
635 		yres = PS_UNIT_SIZE;
636 	switch (res_unit) {
637 	case RESUNIT_CENTIMETER:
638 		xres *= 2.54F, yres *= 2.54F;
639 		break;
640 	case RESUNIT_INCH:
641 		break;
642 	case RESUNIT_NONE:	/* Subsequent code assumes we have converted to inches! */
643 		res_unit = RESUNIT_INCH;
644 		break;
645 	default:	/* Last ditch guess for unspecified RESUNIT case
646 			 * check that the resolution is not inches before scaling it.
647 			 * Moved to end of function with additional check, RJN, 08-31-2010
648 			 * if (xres != PS_UNIT_SIZE || yres != PS_UNIT_SIZE)
649 			 * xres *= PS_UNIT_SIZE, yres *= PS_UNIT_SIZE;
650 			 */
651 		break;
652 	}
653 	/* This is a hack to deal with images that have no meaningful Resolution Size
654 	 * but may have x and/or y resolutions of 1 pixel per undefined unit.
655 	 */
656 	if ((xres > 1.0) && (xres != PS_UNIT_SIZE))
657 		*pprw = PSUNITS(*pw, xres);
658 	else
659 		*pprw = PSUNITS(*pw, PS_UNIT_SIZE);
660 	if ((yres > 1.0) && (yres != PS_UNIT_SIZE))
661 		*pprh = PSUNITS(*ph, yres);
662 	else
663 		*pprh = PSUNITS(*ph, PS_UNIT_SIZE);
664 }
665 
666 static int
667 isCCITTCompression(TIFF* tif)
668 {
669     uint16 compress;
670     TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
671     return (compress == COMPRESSION_CCITTFAX3 ||
672 	    compress == COMPRESSION_CCITTFAX4 ||
673 	    compress == COMPRESSION_CCITTRLE ||
674 	    compress == COMPRESSION_CCITTRLEW);
675 }
676 
677 static	tsize_t tf_bytesperrow;
678 static	tsize_t ps_bytesperrow;
679 static	tsize_t	tf_rowsperstrip;
680 static	tsize_t	tf_numberstrips;
681 static	char *hex = "0123456789abcdef";
682 
683 /*
684  * Pagewidth and pageheight are the output size in points,
685  * may refer to values specified with -h and -w, or to
686  * values read from the image if neither -h nor -w are used.
687  * Imagewidth and imageheight are image size in points.
688  * Ximages and Yimages are number of pages across and down.
689  * Only one of maxPageHeight or maxPageWidth can be used.
690  * These are global variables unfortunately.
691  */
692 int get_subimage_count(double pagewidth,  double pageheight,
693 		       double imagewidth, double imageheight,
694 		       int *ximages, int *yimages,
695 		       int rotation, double scale)
696 {
697 	int pages = 1;
698 	double splitheight = 0;  /* Requested Max Height in points */
699 	double splitwidth  = 0;  /* Requested Max Width in points */
700 	double overlap     = 0;  /* Repeated edge width in points */
701 
702 	splitheight = maxPageHeight * PS_UNIT_SIZE;
703 	splitwidth  = maxPageWidth  * PS_UNIT_SIZE;
704 	overlap     = splitOverlap  * PS_UNIT_SIZE;
705 	pagewidth  *= PS_UNIT_SIZE;
706 	pageheight *= PS_UNIT_SIZE;
707 
708 	if ((imagewidth < 1.0) || (imageheight < 1.0))
709 	{
710 		TIFFError("get_subimage_count", "Invalid image width or height");
711 		return (0);
712 	}
713 
714   switch (rotation)
715     {
716     case 0:
717     case 180: if (splitheight > 0) /* -H maxPageHeight */
718                 {
719                if (imageheight > splitheight) /* More than one vertical image segment */
720                  {
721                  if (pagewidth)
722                    *ximages = (int)ceil((scale * imagewidth)  / (pagewidth - overlap));
723                   else
724                    *ximages = 1;
725                  *yimages = (int)ceil((scale * imageheight) / (splitheight - overlap)); /* Max vert pages needed */
726                  }
727                 else
728                  {
729                  if (pagewidth)
730                    *ximages = (int)ceil((scale * imagewidth) / (pagewidth - overlap));    /* Max horz pages needed */
731                   else
732                    *ximages = 1;
733                  *yimages = 1;                                                     /* Max vert pages needed */
734                  }
735                }
736               else
737                {
738                 if (splitwidth > 0) /* -W maxPageWidth */
739                  {
740                  if (imagewidth >splitwidth)
741                    {
742                    *ximages = (int)ceil((scale * imagewidth)  / (splitwidth - overlap));   /* Max horz pages needed */
743                     if (pageheight)
744                      *yimages = (int)ceil((scale * imageheight) / (pageheight - overlap)); /* Max vert pages needed */
745                     else
746                      *yimages = 1;
747                    }
748                   else
749                    {
750                    *ximages = 1;                                                     /* Max vert pages needed */
751                     if (pageheight)
752                      *yimages = (int)ceil((scale * imageheight) / (pageheight - overlap)); /* Max vert pages needed */
753                     else
754                      *yimages = 1;
755                    }
756                  }
757                 else
758                  {
759                  *ximages = 1;
760                  *yimages = 1;
761                  }
762                }
763              break;
764     case 90:
765     case 270: if (splitheight > 0) /* -H maxPageHeight */
766                 {
767                if (imagewidth > splitheight) /* More than one vertical image segment */
768                  {
769                  *yimages = (int)ceil((scale * imagewidth) / (splitheight - overlap)); /* Max vert pages needed */
770                   if (pagewidth)
771                    *ximages = (int)ceil((scale * imageheight) / (pagewidth - overlap));   /* Max horz pages needed */
772                   else
773                    *ximages = 1;
774                  }
775                 else
776                  {
777                  *yimages = 1;                                                     /* Max vert pages needed */
778                   if (pagewidth)
779                    *ximages = (int)ceil((scale * imageheight) / (pagewidth - overlap));    /* Max horz pages needed */
780                   else
781                    *ximages = 1;
782                  }
783                }
784               else
785                {
786                 if (splitwidth > 0) /* -W maxPageWidth */
787                  {
788                  if (imageheight > splitwidth)
789                    {
790                    if (pageheight)
791                      *yimages = (int)ceil((scale * imagewidth) / (pageheight - overlap)); /* Max vert pages needed */
792                     else
793                      *yimages = 1;
794                    *ximages = (int)ceil((scale * imageheight)  / (splitwidth - overlap));   /* Max horz pages needed */
795                    }
796                   else
797                    {
798                    if (pageheight)
799                      *yimages = (int)ceil((scale * imagewidth) / (pageheight - overlap));  /* Max horz pages needed */
800                     else
801                      *yimages = 1;
802                    *ximages = 1;                                                     /* Max vert pages needed */
803                    }
804                  }
805                 else
806                  {
807                  *ximages = 1;
808                  *yimages = 1;
809                  }
810                }
811              break;
812     default:  *ximages = 1;
813              *yimages = 1;
814   }
815   pages = (*ximages) * (*yimages);
816   return (pages);
817   }
818 
819 /* New version of PlaceImage that handles only the translation and rotation
820  * for a single output page.
821  */
822 int exportMaskedImage(FILE *fp, double pagewidth, double pageheight,
823                      double imagewidth, double imageheight,
824                       int row, int column,
825                       double left_offset, double bott_offset,
826                      double scale, int center, int rotation)
827   {
828   double xtran = 0.0;
829   double ytran = 0.0;
830 
831   double xscale = 1.0;
832   double yscale = 1.0;
833 
834   double splitheight    = 0;  /* Requested Max Height in points */
835   double splitwidth     = 0;  /* Requested Max Width in points */
836   double overlap        = 0;  /* Repeated edge width in points */
837   double subimage_height = 0.0;
838 
839   splitheight = maxPageHeight * PS_UNIT_SIZE;
840   splitwidth  = maxPageWidth  * PS_UNIT_SIZE;
841   overlap     = splitOverlap  * PS_UNIT_SIZE;
842   xscale = scale * imagewidth;
843   yscale = scale * imageheight;
844 
845   if ((xscale < 0.0) || (yscale < 0.0))
846     {
847     TIFFError("exportMaskedImage", "Invalid parameters.");
848     return (-1);
849     }
850 
851   /* If images are cropped to a vewport with -H or -W, the output pages are shifted to
852    * the top of each output page rather than the Postscript default lower edge.
853    */
854   switch (rotation)
855     {
856     case 0:
857     case 180: if (splitheight > 0) /* -H maxPageHeight */
858                 {
859                if (splitheight < imageheight) /* More than one vertical image segments */
860                  {
861                  xtran = -1.0 * column * (pagewidth - overlap);
862                   subimage_height = imageheight - ((splitheight - overlap) * row);
863                  ytran  = pageheight - subimage_height * (pageheight / splitheight);
864                   }
865                 else  /* Only one page in vertical direction */
866                  {
867                  xtran = -1.0 * column * (pagewidth - overlap);
868                   ytran = splitheight - imageheight;
869                  }
870                }
871               else
872                {
873                 if (splitwidth > 0) /* maxPageWidth */
874                  {
875                  if (splitwidth < imagewidth)
876                    {
877                    xtran = -1.0  * column * splitwidth;
878                    ytran = -1.0 * row * (pageheight - overlap);
879                     }
880                   else /* Only one page in horizontal direction */
881                    {
882                     ytran = -1.0 * row * (pageheight - overlap);
883                     xtran = 0;
884                    }
885                  }
886                 else    /* Simple case, no splitting */
887                  {
888                  ytran = pageheight - imageheight;
889                  xtran = 0;
890                   }
891                 }
892               bott_offset += ytran / (center ? 2 : 1);
893               left_offset += xtran / (center ? 2 : 1);
894               break;
895     case  90:
896     case 270:  if (splitheight > 0) /* -H maxPageHeight */
897                 {
898                if (splitheight < imagewidth) /* More than one vertical image segments */
899                  {
900                  xtran = -1.0 * column * (pageheight - overlap);
901                  /* Commented code places image at bottom of page instead of top.
902                      ytran = -1.0 * row * splitheight;
903                    */
904                   if (row == 0)
905                     ytran = -1.0 * (imagewidth - splitheight);
906                   else
907                     ytran = -1.0 * (imagewidth - (splitheight - overlap) * (row + 1));
908                   }
909                 else  /* Only one page in vertical direction */
910                  {
911                   xtran = -1.0 * column * (pageheight - overlap);
912                   ytran = splitheight - imagewidth;
913                  }
914 		}
915               else
916                {
917                 if (splitwidth > 0) /* maxPageWidth */
918                  {
919                  if (splitwidth < imageheight)
920                    {
921                     xtran = -1.0  * column * splitwidth;
922                     ytran = -1.0 * row * (pagewidth - overlap);
923                     }
924                   else /* Only one page in horizontal direction */
925                    {
926                     ytran = -1.0 * row * (pagewidth - overlap);
927                     xtran = 0;
928                    }
929                  }
930                 else    /* Simple case, no splitting */
931                  {
932                  ytran = pageheight - imageheight;
933                  xtran = 0; /* pagewidth  - imagewidth; */
934                   }
935                 }
936               bott_offset += ytran / (center ? 2 : 1);
937               left_offset += xtran / (center ? 2 : 1);
938               break;
939     default:  xtran = 0;
940              ytran = 0;
941     }
942 
943   switch (rotation)
944     {
945     case   0: fprintf(fp, "%f %f translate\n", left_offset, bott_offset);
946               fprintf(fp, "%f %f scale\n", xscale, yscale);
947              break;
948     case 180: fprintf(fp, "%f %f translate\n", left_offset, bott_offset);
949               fprintf(fp, "%f %f scale\n1 1 translate 180 rotate\n",  xscale, yscale);
950               break;
951     case  90: fprintf(fp, "%f %f translate\n", left_offset, bott_offset);
952               fprintf(fp, "%f %f scale\n1 0 translate 90 rotate\n", yscale, xscale);
953               break;
954     case 270: fprintf(fp, "%f %f translate\n", left_offset, bott_offset);
955               fprintf(fp, "%f %f scale\n0 1 translate 270 rotate\n", yscale, xscale);
956               break;
957     default:  TIFFError ("exportMaskedImage", "Unsupported rotation angle %d. No rotation", rotation);
958              fprintf( fp, "%f %f scale\n", xscale, yscale);
959               break;
960     }
961 
962   return (0);
963   }
964 
965 /* Rotate an image without scaling or clipping */
966 int  psRotateImage (FILE * fd, int rotation, double pswidth, double psheight,
967                     double left_offset, double bottom_offset)
968   {
969   if ((left_offset != 0.0) || (bottom_offset != 0))
970     fprintf (fd, "%f %f translate\n", left_offset, bottom_offset);
971 
972   /* Exchange width and height for 90/270 rotations */
973   switch (rotation)
974     {
975     case   0: fprintf (fd, "%f %f scale\n", pswidth, psheight);
976               break;
977     case  90: fprintf (fd, "%f %f scale\n1 0 translate 90 rotate\n", psheight, pswidth);
978               break;
979     case 180: fprintf (fd, "%f %f scale\n1 1 translate 180 rotate\n", pswidth, psheight);
980               break;
981     case 270: fprintf (fd, "%f %f scale\n0 1 translate 270 rotate\n", psheight, pswidth);
982               break;
983     default:  TIFFError ("psRotateImage", "Unsupported rotation %d.", rotation);
984              fprintf( fd, "%f %f scale\n", pswidth, psheight);
985               return (1);
986     }
987   return (0);
988   }
989 
990 /* Scale and rotate an image to a single output page. */
991 int psScaleImage(FILE * fd, double scale, int rotation, int center,
992                  double reqwidth, double reqheight, double pswidth, double psheight,
993                  double left_offset, double bottom_offset)
994   {
995   double hcenter = 0.0, vcenter = 0.0;
996 
997   /* Adjust offsets for centering */
998   if (center)
999     {
1000     switch (rotation)
1001       {
1002       case   90: vcenter = (reqheight - pswidth * scale) / 2;
1003                 hcenter = (reqwidth - psheight * scale) / 2;
1004                  fprintf (fd, "%f %f translate\n", hcenter, vcenter);
1005                  fprintf (fd, "%f %f scale\n1 0 translate 90 rotate\n", psheight * scale, pswidth * scale);
1006                  break;
1007       case  180: hcenter = (reqwidth - pswidth * scale) / 2;
1008                 vcenter = (reqheight - psheight * scale) / 2;
1009                  fprintf (fd, "%f %f translate\n", hcenter, vcenter);
1010                  fprintf (fd, "%f %f scale\n1 1 translate 180 rotate\n", pswidth * scale, psheight * scale);
1011                  break;
1012       case  270: vcenter = (reqheight - pswidth * scale) / 2;
1013                 hcenter = (reqwidth - psheight * scale) / 2;
1014                  fprintf (fd, "%f %f translate\n", hcenter, vcenter);
1015                  fprintf (fd, "%f %f scale\n0 1 translate 270 rotate\n", psheight * scale, pswidth * scale);
1016                  break;
1017       case    0:
1018       default:   hcenter = (reqwidth - pswidth * scale) / 2;
1019                 vcenter = (reqheight - psheight * scale) / 2;
1020                  fprintf (fd, "%f %f translate\n", hcenter, vcenter);
1021                  fprintf (fd, "%f %f scale\n", pswidth * scale, psheight * scale);
1022                  break;
1023       }
1024     }
1025   else  /* Not centered */
1026     {
1027     switch (rotation)
1028       {
1029       case 0:   fprintf (fd, "%f %f translate\n", left_offset ? left_offset : 0.0,
1030                          bottom_offset ? bottom_offset : reqheight - (psheight * scale));
1031                 fprintf (fd, "%f %f scale\n", pswidth * scale, psheight * scale);
1032                 break;
1033       case 90:  fprintf (fd, "%f %f translate\n", left_offset ? left_offset : 0.0,
1034                          bottom_offset ? bottom_offset : reqheight - (pswidth * scale));
1035                 fprintf (fd, "%f %f scale\n1 0 translate 90 rotate\n", psheight * scale, pswidth * scale);
1036                 break;
1037       case 180: fprintf (fd, "%f %f translate\n", left_offset ? left_offset : 0.0,
1038                          bottom_offset ? bottom_offset : reqheight - (psheight * scale));
1039                 fprintf (fd, "%f %f scale\n1 1 translate 180 rotate\n", pswidth * scale, psheight * scale);
1040                 break;
1041       case 270: fprintf (fd, "%f %f translate\n", left_offset ? left_offset : 0.0,
1042                          bottom_offset ? bottom_offset : reqheight - (pswidth * scale));
1043                 fprintf (fd, "%f %f scale\n0 1 translate 270 rotate\n", psheight * scale, pswidth * scale);
1044                 break;
1045       default:  TIFFError ("psScaleImage", "Unsupported rotation  %d", rotation);
1046                fprintf (fd, "%f %f scale\n", pswidth * scale, psheight * scale);
1047                 return (1);
1048       }
1049     }
1050 
1051   return (0);
1052   }
1053 
1054 /* This controls the visible portion of the page which is displayed.
1055  * N.B. Setting maxPageHeight no longer sets pageheight if not set explicitly
1056  */
1057 int psPageSize (FILE * fd, int rotation, double pgwidth, double pgheight,
1058                 double reqwidth, double reqheight, double pswidth, double psheight)
1059   {
1060   double xscale = 1.0, yscale = 1.0, scale = 1.0;
1061   double splitheight;
1062   double splitwidth;
1063   double new_width;
1064   double new_height;
1065 
1066   splitheight = maxPageHeight * PS_UNIT_SIZE;
1067   splitwidth  = maxPageWidth  * PS_UNIT_SIZE;
1068 
1069   switch (rotation)
1070     {
1071     case   0:
1072     case 180: if ((splitheight > 0) || (splitwidth > 0))
1073                 {
1074                if (pgwidth != 0 || pgheight != 0)
1075                   {
1076                  xscale = reqwidth / (splitwidth ? splitwidth : pswidth);
1077                  yscale = reqheight / (splitheight ? splitheight : psheight);
1078                   scale = (xscale < yscale) ? xscale : yscale;
1079                   }
1080                 new_width = splitwidth ? splitwidth : scale * pswidth;
1081                 new_height = splitheight ? splitheight : scale * psheight;
1082                 if (strlen(pageOrientation))
1083                   fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1084                 else
1085                   fprintf (fd, "%%%%PageOrientation: %s\n", (new_width > new_height) ? "Landscape" : "Portrait");
1086                 fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)new_width, (long)new_height);
1087                 fprintf (fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1088                        new_width, new_height);
1089                 }
1090              else /* No viewport defined with -H or -W */
1091                 {
1092                 if ((pgwidth == 0) && (pgheight == 0)) /* Image not scaled */
1093                   {
1094                   if (strlen(pageOrientation))
1095                     fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1096                   else
1097                     fprintf (fd, "%%%%PageOrientation: %s\n", (pswidth > psheight) ? "Landscape" : "Portrait");
1098                  fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)pswidth, (long)psheight);
1099                   fprintf(fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1100                           pswidth, psheight);
1101                   }
1102                else /* Image scaled */
1103                   {
1104                   if (strlen(pageOrientation))
1105                     fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1106                   else
1107                     fprintf (fd, "%%%%PageOrientation: %s\n", (reqwidth > reqheight) ? "Landscape" : "Portrait");
1108                  fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)reqwidth, (long)reqheight);
1109                   fprintf(fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1110                            reqwidth, reqheight);
1111                   }
1112                 }
1113              break;
1114     case  90:
1115     case 270: if ((splitheight > 0) || (splitwidth > 0))
1116                {
1117                if (pgwidth != 0 || pgheight != 0)
1118                   {
1119                  xscale = reqwidth / (splitwidth ? splitwidth : pswidth);
1120                  yscale = reqheight / (splitheight ? splitheight : psheight);
1121                   scale = (xscale < yscale) ? xscale : yscale;
1122                   }
1123                 new_width = splitwidth ? splitwidth : scale * psheight;
1124                 new_height = splitheight ? splitheight : scale * pswidth;
1125 
1126                 if (strlen(pageOrientation))
1127                   fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1128                 else
1129                   fprintf (fd, "%%%%PageOrientation: %s\n", (new_width > new_height) ? "Landscape" : "Portrait");
1130                 fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)new_width, (long)new_height);
1131                 fprintf (fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1132                        new_width, new_height);
1133                 }
1134               else
1135                 {
1136                 if ((pgwidth == 0) && (pgheight == 0)) /* Image not scaled */
1137                   {
1138                   if (strlen(pageOrientation))
1139                     fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1140                   else
1141                     fprintf (fd, "%%%%PageOrientation: %s\n", (psheight > pswidth) ? "Landscape" : "Portrait");
1142                  fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)psheight, (long)pswidth);
1143                   fprintf(fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1144                          psheight, pswidth);
1145                   }
1146                else /* Image scaled */
1147                   {
1148                   if (strlen(pageOrientation))
1149                     fprintf (fd, "%%%%PageOrientation: %s\n", pageOrientation);
1150                   else
1151                     fprintf (fd, "%%%%PageOrientation: %s\n", (reqwidth > reqheight) ? "Landscape" : "Portrait");
1152                  fprintf (fd, "%%%%PageBoundingBox: 0 0 %ld %ld\n", (long)reqwidth, (long)reqheight);
1153                   fprintf(fd, "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
1154                           reqwidth, reqheight);
1155                   }
1156                }
1157              break;
1158     default:  TIFFError ("psPageSize", "Invalid rotation %d", rotation);
1159       return (1);
1160     }
1161   fputs("<<\n  /Policies <<\n    /PageSize 3\n  >>\n>> setpagedevice\n", fd);
1162 
1163   return (0);
1164   } /* end psPageSize */
1165 
1166 /* Mask an image as a series of pages, each only showing a section defined
1167  * by the maxPageHeight or maxPageWidth options.
1168  */
1169 int psMaskImage(FILE *fd, TIFF *tif, int rotation, int center,
1170                 int *npages, double pixwidth, double pixheight,
1171                double left_margin, double bottom_margin,
1172                 double pgwidth, double pgheight,
1173                double pswidth, double psheight, double scale)
1174   {
1175   int i, j;
1176   int ximages = 1, yimages = 1;
1177   int pages = *npages;
1178   double view_width = 0;
1179   double view_height = 0;
1180 
1181   if (get_viewport (pgwidth, pgheight, pswidth, psheight, &view_width, &view_height, rotation))
1182     {
1183     TIFFError ("get_viewport", "Unable to set image viewport");
1184     return (-1);
1185     }
1186 
1187   if (get_subimage_count(pgwidth, pgheight, pswidth, psheight,
1188                         &ximages, &yimages, rotation, scale) < 1)
1189     {
1190     TIFFError("get_subimage_count", "Invalid image count: %d columns, %d rows", ximages, yimages);
1191     return (-1);
1192     }
1193 
1194   for (i = 0; i < yimages; i++)
1195     {
1196     for (j = 0; j < ximages; j++)
1197        {
1198        pages++;
1199        *npages = pages;
1200        fprintf(fd, "%%%%Page: %d %d\n", pages, pages);
1201 
1202        /* Write out the PageSize info for non EPS files */
1203        if (!generateEPSF && ( level2 || level3 ))
1204          {
1205          if (psPageSize(fd, rotation, pgwidth, pgheight,
1206                         view_width, view_height, pswidth, psheight))
1207            return (-1);
1208         }
1209        fprintf(fd, "gsave\n");
1210        fprintf(fd, "100 dict begin\n");
1211        if (exportMaskedImage(fd, view_width, view_height, pswidth, psheight,
1212                             i, j, left_margin, bottom_margin,
1213                             scale, center, rotation))
1214         {
1215         TIFFError("exportMaskedImage", "Invalid image parameters.");
1216         return (-1);
1217         }
1218        PSpage(fd, tif, pixwidth, pixheight);
1219        fprintf(fd, "end\n");
1220        fprintf(fd, "grestore\n");
1221        fprintf(fd, "showpage\n");
1222        }
1223     }
1224 
1225   return (pages);
1226   }
1227 
1228 /* Compute scale factor and write out file header */
1229 int psStart(FILE *fd, int npages, int auto_rotate, int *rotation, double *scale,
1230             double ox, double oy, double pgwidth, double pgheight,
1231            double reqwidth, double reqheight, double pswidth, double psheight,
1232            double left_offset, double bottom_offset)
1233   {
1234   double maxsource = 0.0;    /* Used for auto rotations */
1235   double maxtarget = 0.0;
1236   double xscale = 1.0, yscale = 1.0;
1237   double splitheight;
1238   double splitwidth;
1239   double view_width = 0.0, view_height = 0.0;
1240   double page_width = 0.0, page_height = 0.0;
1241 
1242   /* Splitheight and splitwidth are in inches */
1243   splitheight = maxPageHeight * PS_UNIT_SIZE;
1244   splitwidth  = maxPageWidth * PS_UNIT_SIZE;
1245 
1246   page_width = pgwidth * PS_UNIT_SIZE;
1247   page_height = pgheight * PS_UNIT_SIZE;
1248 
1249   /* If user has specified a page width and height and requested the
1250    * image to be auto-rotated to fit on that media, we match the
1251    * longest dimension of the image to the longest dimension of the
1252    * target media but we have to ignore auto rotate if user specified
1253    * maxPageHeight since this makes life way too complicated. */
1254   if (auto_rotate)
1255     {
1256     if ((splitheight != 0) || (splitwidth != 0))
1257       {
1258       TIFFError ("psStart", "Auto-rotate is incompatible with page splitting ");
1259       return (1);
1260       }
1261 
1262     /* Find longest edges in image and output media */
1263     maxsource = (pswidth >= psheight) ? pswidth : psheight;
1264     maxtarget = (reqwidth >= reqheight) ? reqwidth : reqheight;
1265 
1266     if (((maxsource == pswidth) && (maxtarget != reqwidth)) ||
1267         ((maxsource == psheight) && (maxtarget != reqheight)))
1268       {  /* optimal orientaion does not match input orientation */
1269       *rotation = 90;
1270       xscale = (reqwidth - left_offset)/psheight;
1271       yscale = (reqheight - bottom_offset)/pswidth;
1272       }
1273     else /* optimal orientaion matches input orientation */
1274       {
1275       xscale = (reqwidth - left_offset)/pswidth;
1276       yscale = (reqheight - bottom_offset)/psheight;
1277       }
1278     *scale = (xscale < yscale) ? xscale : yscale;
1279 
1280     /* Do not scale image beyound original size */
1281     if (*scale > 1.0)
1282       *scale = 1.0;
1283 
1284     /* Set the size of the displayed image to requested page size
1285      * and optimal orientation.
1286      */
1287     if (!npages)
1288       PSHead(fd, reqwidth, reqheight, ox, oy);
1289 
1290     return (0);
1291     }
1292 
1293   /* N.B. If pgwidth or pgheight are set from maxPageHeight/Width,
1294    * we have a problem with the tests below under splitheight.
1295    */
1296 
1297   switch (*rotation)  /* Auto rotate has NOT been specified */
1298     {
1299     case   0:
1300     case 180: if ((splitheight != 0)  || (splitwidth != 0))
1301                 {  /* Viewport clipped to maxPageHeight or maxPageWidth */
1302                 if ((page_width != 0) || (page_height != 0)) /* Image scaled */
1303                   {
1304                  xscale = (reqwidth  - left_offset) / (page_width ? page_width : pswidth);
1305                  yscale = (reqheight - bottom_offset) / (page_height ? page_height : psheight);
1306                   *scale = (xscale < yscale) ? xscale : yscale;
1307                   /*
1308                   if (*scale > 1.0)
1309                     *scale = 1.0;
1310                    */
1311                  }
1312                 else       /* Image clipped but not scaled */
1313                  *scale = 1.0;
1314 
1315                 view_width = splitwidth ? splitwidth : *scale * pswidth;
1316                 view_height = splitheight ? splitheight: *scale * psheight;
1317                }
1318               else   /* Viewport not clipped to maxPageHeight or maxPageWidth */
1319                 {
1320                 if ((page_width != 0) || (page_height != 0))
1321                   {   /* Image scaled  */
1322                   xscale = (reqwidth - left_offset) / pswidth;
1323                   yscale = (reqheight - bottom_offset) / psheight;
1324 
1325                   view_width = reqwidth;
1326                   view_height = reqheight;
1327                  }
1328                 else
1329                   {  /* Image not scaled  */
1330                   xscale = (pswidth - left_offset)/pswidth;
1331                   yscale = (psheight - bottom_offset)/psheight;
1332 
1333                   view_width = pswidth;
1334                   view_height = psheight;
1335                  }
1336                }
1337              break;
1338     case  90:
1339     case 270: if ((splitheight != 0) || (splitwidth != 0))
1340                 {  /* Viewport clipped to maxPageHeight or maxPageWidth */
1341                 if ((page_width != 0) || (page_height != 0)) /* Image scaled */
1342                   {
1343                  xscale = (reqwidth - left_offset)/ psheight;
1344                  yscale = (reqheight - bottom_offset)/ pswidth;
1345                   *scale = (xscale < yscale) ? xscale : yscale;
1346                   /*
1347                   if (*scale > 1.0)
1348                     *scale = 1.0;
1349                  */
1350                  }
1351                 else  /* Image clipped but not scaled */
1352                  *scale = 1.0;
1353                 view_width = splitwidth ? splitwidth : *scale * psheight;
1354                 view_height = splitheight ? splitheight : *scale * pswidth;
1355                }
1356               else /* Viewport not clipped to maxPageHeight or maxPageWidth */
1357                 {
1358                 if ((page_width != 0) || (page_height != 0)) /* Image scaled */
1359                   {
1360                   xscale = (reqwidth - left_offset) / psheight;
1361                   yscale = (reqheight - bottom_offset) / pswidth;
1362 
1363                  view_width = reqwidth;
1364                  view_height = reqheight;
1365                  }
1366                 else
1367                   {
1368                   xscale = (pswidth  - left_offset)/ psheight;
1369                  yscale = (psheight  - bottom_offset)/ pswidth;
1370 
1371                  view_width = psheight;
1372                  view_height = pswidth;
1373                   }
1374                 }
1375               break;
1376     default:  TIFFError ("psPageSize", "Invalid rotation %d", *rotation);
1377               return (1);
1378     }
1379 
1380   if (!npages)
1381     PSHead(fd, (page_width ? page_width : view_width), (page_height ? page_height : view_height), ox, oy);
1382 
1383   *scale = (xscale < yscale) ? xscale : yscale;
1384   if (*scale > 1.0)
1385     *scale = 1.0;
1386 
1387   return (0);
1388   }
1389 
1390 int get_viewport (double pgwidth, double pgheight, double pswidth, double psheight,
1391                   double *view_width, double *view_height, int rotation)
1392   {
1393   /* Only one of maxPageHeight or maxPageWidth can be specified */
1394   if (maxPageHeight != 0)   /* Clip the viewport to maxPageHeight on each page */
1395     {
1396     *view_height = maxPageHeight * PS_UNIT_SIZE;
1397     /*
1398      * if (res_unit == RESUNIT_CENTIMETER)
1399      * *view_height /= 2.54F;
1400      */
1401     }
1402   else
1403     {
1404     if (pgheight != 0) /* User has set PageHeight with -h flag */
1405       {
1406       *view_height = pgheight * PS_UNIT_SIZE; /* Postscript size for Page Height in inches */
1407       /* if (res_unit == RESUNIT_CENTIMETER)
1408        *  *view_height /= 2.54F;
1409        */
1410       }
1411     else /* If no width or height are specified, use the original size from image */
1412       switch (rotation)
1413         {
1414         default:
1415         case   0:
1416         case 180: *view_height = psheight;
1417                  break;
1418         case  90:
1419         case 270: *view_height = pswidth;
1420                  break;
1421        }
1422     }
1423 
1424   if (maxPageWidth != 0)   /* Clip the viewport to maxPageWidth on each page */
1425     {
1426     *view_width = maxPageWidth * PS_UNIT_SIZE;
1427     /* if (res_unit == RESUNIT_CENTIMETER)
1428      *  *view_width /= 2.54F;
1429      */
1430     }
1431   else
1432     {
1433     if (pgwidth != 0)  /* User has set PageWidth with -w flag */
1434       {
1435       *view_width = pgwidth * PS_UNIT_SIZE; /* Postscript size for Page Width in inches */
1436       /* if (res_unit == RESUNIT_CENTIMETER)
1437        * *view_width /= 2.54F;
1438        */
1439       }
1440     else  /* If no width or height are specified, use the original size from image */
1441       switch (rotation)
1442         {
1443         default:
1444         case   0:
1445         case 180: *view_width = pswidth;
1446                  break;
1447         case  90:
1448         case 270: *view_width = psheight; /* (*view_height / psheight) * psheight; */
1449                  break;
1450        }
1451     }
1452 
1453   return (0);
1454   }
1455 
1456 /* pgwidth and pgheight specify page width and height in inches from -h and -w flags
1457  * lm and bm are the LeftMargin and BottomMargin in inches
1458  * center causes the image to be centered on the page if the paper size is
1459  * larger than the image size
1460  * returns the sequence number of the page processed or -1 on error
1461  */
1462 
1463 int TIFF2PS(FILE* fd, TIFF* tif, double pgwidth, double pgheight, double lm, double bm, int center)
1464   {
1465   uint32 pixwidth = 0, pixheight = 0;  /* Image width and height in pixels */
1466   double ox = 0.0, oy = 0.0;  /* Offset from current Postscript origin */
1467   double pswidth, psheight;   /* Original raw image width and height in points */
1468   double view_width, view_height; /* Viewport width and height in points */
1469   double scale = 1.0;
1470   double left_offset = lm * PS_UNIT_SIZE;
1471   double bottom_offset = bm * PS_UNIT_SIZE;
1472   uint32 subfiletype;
1473   uint16* sampleinfo;
1474   static int npages = 0;
1475 
1476   if (!TIFFGetField(tif, TIFFTAG_XPOSITION, &ox))
1477      ox = 0;
1478   if (!TIFFGetField(tif, TIFFTAG_YPOSITION, &oy))
1479      oy = 0;
1480 
1481   /* Consolidated all the tag information into one code segment, Richard Nolde */
1482   do {
1483      tf_numberstrips = TIFFNumberOfStrips(tif);
1484      TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &tf_rowsperstrip);
1485      TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
1486      TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
1487      TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfiguration);
1488      TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
1489      TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
1490      alpha = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
1491      if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric))
1492        {
1493        switch (samplesperpixel - extrasamples)
1494              {
1495             case 1: if (isCCITTCompression(tif))
1496                       photometric = PHOTOMETRIC_MINISWHITE;
1497                     else
1498                        photometric = PHOTOMETRIC_MINISBLACK;
1499                     break;
1500             case 3: photometric = PHOTOMETRIC_RGB;
1501                     break;
1502             case 4: photometric = PHOTOMETRIC_SEPARATED;
1503                     break;
1504             }
1505        }
1506 
1507      /* Read image tags for width and height in pixels pixwidth, pixheight,
1508       * and convert to points pswidth, psheight
1509       */
1510      setupPageState(tif, &pixwidth, &pixheight, &pswidth, &psheight);
1511      view_width = pswidth;
1512      view_height = psheight;
1513 
1514      if (get_viewport (pgwidth, pgheight, pswidth, psheight, &view_width, &view_height, rotation))
1515        {
1516        TIFFError("get_viewport", "Unable to set image viewport");
1517        return (1);
1518        }
1519 
1520      /* Write the Postscript file header with Bounding Box and Page Size definitions */
1521      if (psStart(fd, npages, auto_rotate, &rotation, &scale, ox, oy,
1522                 pgwidth, pgheight, view_width, view_height, pswidth, psheight,
1523                  left_offset, bottom_offset))
1524        return (-1);
1525 
1526      if (checkImage(tif))  /* Aborts if unsupported image parameters */
1527        {
1528        tf_bytesperrow = TIFFScanlineSize(tif);
1529 
1530        /* Set viewport clipping and scaling options */
1531        if ((maxPageHeight) || (maxPageWidth)  || (pgwidth != 0) || (pgheight != 0))
1532          {
1533         if ((maxPageHeight) || (maxPageWidth)) /* used -H or -W  option */
1534            {
1535           if (psMaskImage(fd, tif, rotation, center, &npages, pixwidth, pixheight,
1536                           left_offset, bottom_offset, pgwidth, pgheight,
1537                            pswidth, psheight, scale) < 0)
1538             return (-1);
1539           }
1540          else  /* N.B. Setting maxPageHeight no longer sets pgheight */
1541            {
1542            if (pgwidth != 0 || pgheight != 0)
1543              {
1544              /* User did not specify a maxium page height or width using -H or -W flag
1545               * but did use -h or -w flag to scale to a specific size page.
1546               */
1547              npages++;
1548              fprintf(fd, "%%%%Page: %d %d\n", npages, npages);
1549 
1550              if (!generateEPSF && ( level2 || level3 ))
1551                {
1552               /* Write out the PageSize info for non EPS files */
1553               if (psPageSize(fd, rotation, pgwidth, pgheight,
1554                               view_width, view_height, pswidth, psheight))
1555                 return (-1);
1556                }
1557              fprintf(fd, "gsave\n");
1558              fprintf(fd, "100 dict begin\n");
1559              if (psScaleImage(fd, scale, rotation, center, view_width, view_height,
1560                               pswidth, psheight, left_offset, bottom_offset))
1561               return (-1);
1562 
1563              PSpage(fd, tif, pixwidth, pixheight);
1564              fprintf(fd, "end\n");
1565              fprintf(fd, "grestore\n");
1566              fprintf(fd, "showpage\n");
1567             }
1568           }
1569         }
1570        else  /* Simple rotation: user did not use -H, -W, -h or -w */
1571          {
1572          npages++;
1573          fprintf(fd, "%%%%Page: %d %d\n", npages, npages);
1574 
1575          if (!generateEPSF && ( level2 || level3 ))
1576            {
1577           /* Write out the PageSize info for non EPS files */
1578           if (psPageSize(fd, rotation, pgwidth, pgheight,
1579                           view_width, view_height, pswidth, psheight))
1580            return (-1);
1581          }
1582          fprintf(fd, "gsave\n");
1583          fprintf(fd, "100 dict begin\n");
1584         if (psRotateImage(fd, rotation, pswidth, psheight, left_offset, bottom_offset))
1585            return (-1);
1586 
1587          PSpage(fd, tif, pixwidth, pixheight);
1588          fprintf(fd, "end\n");
1589          fprintf(fd, "grestore\n");
1590          fprintf(fd, "showpage\n");
1591          }
1592        }
1593   if (generateEPSF)
1594     break;
1595   TIFFGetFieldDefaulted(tif, TIFFTAG_SUBFILETYPE, &subfiletype);
1596   } while (((subfiletype & FILETYPE_PAGE) || printAll) && TIFFReadDirectory(tif));
1597 
1598 return(npages);
1599 }
1600 
1601 static char DuplexPreamble[] = "\
1602 %%BeginFeature: *Duplex True\n\
1603 systemdict begin\n\
1604   /languagelevel where { pop languagelevel } { 1 } ifelse\n\
1605   2 ge { 1 dict dup /Duplex true put setpagedevice }\n\
1606   { statusdict /setduplex known { statusdict begin setduplex true end } if\n\
1607   } ifelse\n\
1608 end\n\
1609 %%EndFeature\n\
1610 ";
1611 
1612 static char TumblePreamble[] = "\
1613 %%BeginFeature: *Tumble True\n\
1614 systemdict begin\n\
1615   /languagelevel where { pop languagelevel } { 1 } ifelse\n\
1616   2 ge { 1 dict dup /Tumble true put setpagedevice }\n\
1617   { statusdict /settumble known { statusdict begin true settumble end } if\n\
1618   } ifelse\n\
1619 end\n\
1620 %%EndFeature\n\
1621 ";
1622 
1623 static char AvoidDeadZonePreamble[] = "\
1624 gsave newpath clippath pathbbox grestore\n\
1625   4 2 roll 2 copy translate\n\
1626   exch 3 1 roll sub 3 1 roll sub exch\n\
1627   currentpagedevice /PageSize get aload pop\n\
1628   exch 3 1 roll div 3 1 roll div abs exch abs\n\
1629   2 copy gt { exch } if pop\n\
1630   dup 1 lt { dup scale } { pop } ifelse\n\
1631 ";
1632 
1633 void
1634 PSHead(FILE *fd, double pagewidth, double pageheight, double xoff, double yoff)
1635 {
1636 	time_t t;
1637 
1638 	t = time(0);
1639 	fprintf(fd, "%%!PS-Adobe-3.0%s\n", generateEPSF ? " EPSF-3.0" : "");
1640 	fprintf(fd, "%%%%Creator: %s\n", creator ? creator : "tiff2ps");
1641         fprintf(fd, "%%%%Title: %s\n", title ? title : filename);
1642 	fprintf(fd, "%%%%CreationDate: %s", ctime(&t));
1643 	fprintf(fd, "%%%%DocumentData: Clean7Bit\n");
1644 	/* NB: should use PageBoundingBox for each page instead of BoundingBox *
1645          * PageBoundingBox DSC added in PSPageSize function, R Nolde 09-01-2010
1646          */
1647 	fprintf(fd, "%%%%Origin: %ld %ld\n", (long) xoff, (long) yoff);
1648         fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
1649 	       (long) ceil(pagewidth), (long) ceil(pageheight));
1650 
1651 	fprintf(fd, "%%%%LanguageLevel: %d\n", (level3 ? 3 : (level2 ? 2 : 1)));
1652         if (generateEPSF == TRUE)
1653 	  fprintf(fd, "%%%%Pages: 1 1\n");
1654         else
1655 	  fprintf(fd, "%%%%Pages: (atend)\n");
1656 	fprintf(fd, "%%%%EndComments\n");
1657         if (generateEPSF == FALSE)
1658           {
1659   	  fprintf(fd, "%%%%BeginSetup\n");
1660 	  if (PSduplex)
1661 		fprintf(fd, "%s", DuplexPreamble);
1662 	  if (PStumble)
1663 		fprintf(fd, "%s", TumblePreamble);
1664 	  if (PSavoiddeadzone && (level2 || level3))
1665 		fprintf(fd, "%s", AvoidDeadZonePreamble);
1666 	  fprintf(fd, "%%%%EndSetup\n");
1667 	  }
1668 }
1669 
1670 void
1671 PSTail(FILE *fd, int npages)
1672 {
1673 	fprintf(fd, "%%%%Trailer\n");
1674         if (generateEPSF == FALSE)
1675 	  fprintf(fd, "%%%%Pages: %d\n", npages);
1676 	fprintf(fd, "%%%%EOF\n");
1677 }
1678 
1679 static int
1680 checkcmap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b)
1681 {
1682 	(void) tif;
1683 	while (n-- > 0)
1684 		if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
1685 			return (16);
1686 	TIFFWarning(filename, "Assuming 8-bit colormap");
1687 	return (8);
1688 }
1689 
1690 static void
1691 PS_Lvl2colorspace(FILE* fd, TIFF* tif)
1692 {
1693 	uint16 *rmap, *gmap, *bmap;
1694 	int i, num_colors;
1695 	const char * colorspace_p;
1696 
1697 	switch ( photometric )
1698 	{
1699 	case PHOTOMETRIC_SEPARATED:
1700 		colorspace_p = "CMYK";
1701 		break;
1702 
1703 	case PHOTOMETRIC_RGB:
1704 		colorspace_p = "RGB";
1705 		break;
1706 
1707 	default:
1708 		colorspace_p = "Gray";
1709 	}
1710 
1711 	/*
1712 	 * Set up PostScript Level 2 colorspace according to
1713 	 * section 4.8 in the PostScript refenence manual.
1714 	 */
1715 	fputs("% PostScript Level 2 only.\n", fd);
1716 	if (photometric != PHOTOMETRIC_PALETTE) {
1717 		if (photometric == PHOTOMETRIC_YCBCR) {
1718 		    /* MORE CODE HERE */
1719 		}
1720 		fprintf(fd, "/Device%s setcolorspace\n", colorspace_p );
1721 		return;
1722 	}
1723 
1724 	/*
1725 	 * Set up an indexed/palette colorspace
1726 	 */
1727 	num_colors = (1 << bitspersample);
1728 	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
1729 		TIFFError(filename,
1730 			"Palette image w/o \"Colormap\" tag");
1731 		return;
1732 	}
1733 	if (checkcmap(tif, num_colors, rmap, gmap, bmap) == 16) {
1734 		/*
1735 		 * Convert colormap to 8-bits values.
1736 		 */
1737 #define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
1738 		for (i = 0; i < num_colors; i++) {
1739 			rmap[i] = CVT(rmap[i]);
1740 			gmap[i] = CVT(gmap[i]);
1741 			bmap[i] = CVT(bmap[i]);
1742 		}
1743 #undef CVT
1744 	}
1745 	fprintf(fd, "[ /Indexed /DeviceRGB %d", num_colors - 1);
1746 	if (ascii85) {
1747 		Ascii85Init();
1748 		fputs("\n<~", fd);
1749 		ascii85breaklen -= 2;
1750 	} else
1751 		fputs(" <", fd);
1752 	for (i = 0; i < num_colors; i++) {
1753 		if (ascii85) {
1754 			Ascii85Put((unsigned char)rmap[i], fd);
1755 			Ascii85Put((unsigned char)gmap[i], fd);
1756 			Ascii85Put((unsigned char)bmap[i], fd);
1757 		} else {
1758 			fputs((i % 8) ? " " : "\n  ", fd);
1759 			fprintf(fd, "%02x%02x%02x",
1760 			    rmap[i], gmap[i], bmap[i]);
1761 		}
1762 	}
1763 	if (ascii85)
1764 		Ascii85Flush(fd);
1765 	else
1766 		fputs(">\n", fd);
1767 	fputs("] setcolorspace\n", fd);
1768 }
1769 
1770 static int
1771 PS_Lvl2ImageDict(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1772 {
1773 	int use_rawdata;
1774 	uint32 tile_width, tile_height;
1775 	uint16 predictor, minsamplevalue, maxsamplevalue;
1776 	int repeat_count;
1777 	char im_h[64], im_x[64], im_y[64];
1778 	char * imageOp = "image";
1779 
1780 	if ( useImagemask && (bitspersample == 1) )
1781 		imageOp = "imagemask";
1782 
1783 	(void)strcpy(im_x, "0");
1784 	(void)sprintf(im_y, "%lu", (long) h);
1785 	(void)sprintf(im_h, "%lu", (long) h);
1786 	tile_width = w;
1787 	tile_height = h;
1788 	if (TIFFIsTiled(tif)) {
1789 		repeat_count = TIFFNumberOfTiles(tif);
1790 		TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
1791 		TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
1792 		if (tile_width > w || tile_height > h ||
1793 		    (w % tile_width) != 0 || (h % tile_height != 0)) {
1794 			/*
1795 			 * The tiles does not fit image width and height.
1796 			 * Set up a clip rectangle for the image unit square.
1797 			 */
1798 			fputs("0 0 1 1 rectclip\n", fd);
1799 		}
1800 		if (tile_width < w) {
1801 			fputs("/im_x 0 def\n", fd);
1802 			(void)strcpy(im_x, "im_x neg");
1803 		}
1804 		if (tile_height < h) {
1805 			fputs("/im_y 0 def\n", fd);
1806 			(void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
1807 		}
1808 	} else {
1809 		repeat_count = tf_numberstrips;
1810 		tile_height = tf_rowsperstrip;
1811 		if (tile_height > h)
1812 			tile_height = h;
1813 		if (repeat_count > 1) {
1814 			fputs("/im_y 0 def\n", fd);
1815 			fprintf(fd, "/im_h %lu def\n",
1816 			    (unsigned long) tile_height);
1817 			(void)strcpy(im_h, "im_h");
1818 			(void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
1819 		}
1820 	}
1821 
1822 	/*
1823 	 * Output start of exec block
1824 	 */
1825 	fputs("{ % exec\n", fd);
1826 
1827 	if (repeat_count > 1)
1828 		fprintf(fd, "%d { %% repeat\n", repeat_count);
1829 
1830 	/*
1831 	 * Output filter options and image dictionary.
1832 	 */
1833 	if (ascii85)
1834 		fputs(" /im_stream currentfile /ASCII85Decode filter def\n",
1835 		    fd);
1836 	fputs(" <<\n", fd);
1837 	fputs("  /ImageType 1\n", fd);
1838 	fprintf(fd, "  /Width %lu\n", (unsigned long) tile_width);
1839 	/*
1840 	 * Workaround for some software that may crash when last strip
1841 	 * of image contains fewer number of scanlines than specified
1842 	 * by the `/Height' variable. So for stripped images with multiple
1843 	 * strips we will set `/Height' as `im_h', because one is
1844 	 * recalculated for each strip - including the (smaller) final strip.
1845 	 * For tiled images and images with only one strip `/Height' will
1846 	 * contain number of scanlines in tile (or image height in case of
1847 	 * one-stripped image).
1848 	 */
1849 	if (TIFFIsTiled(tif) || tf_numberstrips == 1)
1850 		fprintf(fd, "  /Height %lu\n", (unsigned long) tile_height);
1851 	else
1852 		fprintf(fd, "  /Height im_h\n");
1853 
1854 	if (planarconfiguration == PLANARCONFIG_SEPARATE && samplesperpixel > 1)
1855 		fputs("  /MultipleDataSources true\n", fd);
1856 	fprintf(fd, "  /ImageMatrix [ %lu 0 0 %ld %s %s ]\n",
1857 	    (unsigned long) w, - (long)h, im_x, im_y);
1858 	fprintf(fd, "  /BitsPerComponent %d\n", bitspersample);
1859 	fprintf(fd, "  /Interpolate %s\n", interpolate ? "true" : "false");
1860 
1861 	switch (samplesperpixel - extrasamples) {
1862 	case 1:
1863 		switch (photometric) {
1864 		case PHOTOMETRIC_MINISBLACK:
1865 			fputs("  /Decode [0 1]\n", fd);
1866 			break;
1867 		case PHOTOMETRIC_MINISWHITE:
1868 			switch (compression) {
1869 			case COMPRESSION_CCITTRLE:
1870 			case COMPRESSION_CCITTRLEW:
1871 			case COMPRESSION_CCITTFAX3:
1872 			case COMPRESSION_CCITTFAX4:
1873 				/*
1874 				 * Manage inverting with /Blackis1 flag
1875 				 * since there migth be uncompressed parts
1876 				 */
1877 				fputs("  /Decode [0 1]\n", fd);
1878 				break;
1879 			default:
1880 				/*
1881 				 * ERROR...
1882 				 */
1883 				fputs("  /Decode [1 0]\n", fd);
1884 				break;
1885 			}
1886 			break;
1887 		case PHOTOMETRIC_PALETTE:
1888 			TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE,
1889 			    &minsamplevalue);
1890 			TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE,
1891 			    &maxsamplevalue);
1892 			fprintf(fd, "  /Decode [%u %u]\n",
1893 				    minsamplevalue, maxsamplevalue);
1894 			break;
1895 		default:
1896 			/*
1897 			 * ERROR ?
1898 			 */
1899 			fputs("  /Decode [0 1]\n", fd);
1900 			break;
1901 		}
1902 		break;
1903 	case 3:
1904 		switch (photometric) {
1905 		case PHOTOMETRIC_RGB:
1906 			fputs("  /Decode [0 1 0 1 0 1]\n", fd);
1907 			break;
1908 		case PHOTOMETRIC_MINISWHITE:
1909 		case PHOTOMETRIC_MINISBLACK:
1910 		default:
1911 			/*
1912 			 * ERROR??
1913 			 */
1914 			fputs("  /Decode [0 1 0 1 0 1]\n", fd);
1915 			break;
1916 		}
1917 		break;
1918 	case 4:
1919 		/*
1920 		 * ERROR??
1921 		 */
1922 		fputs("  /Decode [0 1 0 1 0 1 0 1]\n", fd);
1923 		break;
1924 	}
1925 	fputs("  /DataSource", fd);
1926 	if (planarconfiguration == PLANARCONFIG_SEPARATE &&
1927 	    samplesperpixel > 1)
1928 		fputs(" [", fd);
1929 	if (ascii85)
1930 		fputs(" im_stream", fd);
1931 	else
1932 		fputs(" currentfile /ASCIIHexDecode filter", fd);
1933 
1934 	use_rawdata = TRUE;
1935 	switch (compression) {
1936 	case COMPRESSION_NONE:		/* 1: uncompressed */
1937 		break;
1938 	case COMPRESSION_CCITTRLE:	/* 2: CCITT modified Huffman RLE */
1939 	case COMPRESSION_CCITTRLEW:	/* 32771: #1 w/ word alignment */
1940 	case COMPRESSION_CCITTFAX3:	/* 3: CCITT Group 3 fax encoding */
1941 	case COMPRESSION_CCITTFAX4:	/* 4: CCITT Group 4 fax encoding */
1942 		fputs("\n\t<<\n", fd);
1943 		if (compression == COMPRESSION_CCITTFAX3) {
1944 			uint32 g3_options;
1945 
1946 			fputs("\t /EndOfLine true\n", fd);
1947 			fputs("\t /EndOfBlock false\n", fd);
1948 			if (!TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS,
1949 					    &g3_options))
1950 				g3_options = 0;
1951 			if (g3_options & GROUP3OPT_2DENCODING)
1952 				fprintf(fd, "\t /K %s\n", im_h);
1953 			if (g3_options & GROUP3OPT_UNCOMPRESSED)
1954 				fputs("\t /Uncompressed true\n", fd);
1955 			if (g3_options & GROUP3OPT_FILLBITS)
1956 				fputs("\t /EncodedByteAlign true\n", fd);
1957 		}
1958 		if (compression == COMPRESSION_CCITTFAX4) {
1959 			uint32 g4_options;
1960 
1961 			fputs("\t /K -1\n", fd);
1962 			TIFFGetFieldDefaulted(tif, TIFFTAG_GROUP4OPTIONS,
1963 					       &g4_options);
1964 			if (g4_options & GROUP4OPT_UNCOMPRESSED)
1965 				fputs("\t /Uncompressed true\n", fd);
1966 		}
1967 		if (!(tile_width == w && w == 1728U))
1968 			fprintf(fd, "\t /Columns %lu\n",
1969 			    (unsigned long) tile_width);
1970 		fprintf(fd, "\t /Rows %s\n", im_h);
1971 		if (compression == COMPRESSION_CCITTRLE ||
1972 		    compression == COMPRESSION_CCITTRLEW) {
1973 			fputs("\t /EncodedByteAlign true\n", fd);
1974 			fputs("\t /EndOfBlock false\n", fd);
1975 		}
1976 		if (photometric == PHOTOMETRIC_MINISBLACK)
1977 			fputs("\t /BlackIs1 true\n", fd);
1978 		fprintf(fd, "\t>> /CCITTFaxDecode filter");
1979 		break;
1980 	case COMPRESSION_LZW:	/* 5: Lempel-Ziv & Welch */
1981 		TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
1982 		if (predictor == 2) {
1983 			fputs("\n\t<<\n", fd);
1984 			fprintf(fd, "\t /Predictor %u\n", predictor);
1985 			fprintf(fd, "\t /Columns %lu\n",
1986 			    (unsigned long) tile_width);
1987 			fprintf(fd, "\t /Colors %u\n", samplesperpixel);
1988 			fprintf(fd, "\t /BitsPerComponent %u\n",
1989 			    bitspersample);
1990 			fputs("\t>>", fd);
1991 		}
1992 		fputs(" /LZWDecode filter", fd);
1993 		break;
1994 	case COMPRESSION_DEFLATE:	/* 5: ZIP */
1995 	case COMPRESSION_ADOBE_DEFLATE:
1996 		if ( level3 ) {
1997 			 TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
1998 			 if (predictor > 1) {
1999 				fprintf(fd, "\t %% PostScript Level 3 only.");
2000 				fputs("\n\t<<\n", fd);
2001 				fprintf(fd, "\t /Predictor %u\n", predictor);
2002 				fprintf(fd, "\t /Columns %lu\n",
2003 					(unsigned long) tile_width);
2004 				fprintf(fd, "\t /Colors %u\n", samplesperpixel);
2005 					fprintf(fd, "\t /BitsPerComponent %u\n",
2006 					bitspersample);
2007 				fputs("\t>>", fd);
2008 			 }
2009 			 fputs(" /FlateDecode filter", fd);
2010 		} else {
2011 			use_rawdata = FALSE ;
2012 		}
2013 		break;
2014 	case COMPRESSION_PACKBITS:	/* 32773: Macintosh RLE */
2015 		fputs(" /RunLengthDecode filter", fd);
2016 		use_rawdata = TRUE;
2017 	    break;
2018 	case COMPRESSION_OJPEG:		/* 6: !6.0 JPEG */
2019 	case COMPRESSION_JPEG:		/* 7: %JPEG DCT compression */
2020 #ifdef notdef
2021 		/*
2022 		 * Code not tested yet
2023 		 */
2024 		fputs(" /DCTDecode filter", fd);
2025 		use_rawdata = TRUE;
2026 #else
2027 		use_rawdata = FALSE;
2028 #endif
2029 		break;
2030 	case COMPRESSION_NEXT:		/* 32766: NeXT 2-bit RLE */
2031 	case COMPRESSION_THUNDERSCAN:	/* 32809: ThunderScan RLE */
2032 	case COMPRESSION_PIXARFILM:	/* 32908: Pixar companded 10bit LZW */
2033 	case COMPRESSION_JBIG:		/* 34661: ISO JBIG */
2034 		use_rawdata = FALSE;
2035 		break;
2036 	case COMPRESSION_SGILOG:	/* 34676: SGI LogL or LogLuv */
2037 	case COMPRESSION_SGILOG24:	/* 34677: SGI 24-bit LogLuv */
2038 		use_rawdata = FALSE;
2039 		break;
2040 	default:
2041 		/*
2042 		 * ERROR...
2043 		 */
2044 		use_rawdata = FALSE;
2045 		break;
2046 	}
2047 	if (planarconfiguration == PLANARCONFIG_SEPARATE &&
2048 	    samplesperpixel > 1) {
2049 		uint16 i;
2050 
2051 		/*
2052 		 * NOTE: This code does not work yet...
2053 		 */
2054 		for (i = 1; i < samplesperpixel; i++)
2055 			fputs(" dup", fd);
2056 		fputs(" ]", fd);
2057 	}
2058 
2059 	fprintf( fd, "\n >> %s\n", imageOp );
2060 	if (ascii85)
2061 		fputs(" im_stream status { im_stream flushfile } if\n", fd);
2062 	if (repeat_count > 1) {
2063 		if (tile_width < w) {
2064 			fprintf(fd, " /im_x im_x %lu add def\n",
2065 			    (unsigned long) tile_width);
2066 			if (tile_height < h) {
2067 				fprintf(fd, " im_x %lu ge {\n",
2068 				    (unsigned long) w);
2069 				fputs("  /im_x 0 def\n", fd);
2070 				fprintf(fd, " /im_y im_y %lu add def\n",
2071 				    (unsigned long) tile_height);
2072 				fputs(" } if\n", fd);
2073 			}
2074 		}
2075 		if (tile_height < h) {
2076 			if (tile_width >= w) {
2077 				fprintf(fd, " /im_y im_y %lu add def\n",
2078 				    (unsigned long) tile_height);
2079 				if (!TIFFIsTiled(tif)) {
2080 					fprintf(fd, " /im_h %lu im_y sub",
2081 					    (unsigned long) h);
2082 					fprintf(fd, " dup %lu gt { pop",
2083 					    (unsigned long) tile_height);
2084 					fprintf(fd, " %lu } if def\n",
2085 					    (unsigned long) tile_height);
2086 				}
2087 			}
2088 		}
2089 		fputs("} repeat\n", fd);
2090 	}
2091 	/*
2092 	 * End of exec function
2093 	 */
2094 	fputs("}\n", fd);
2095 
2096 	return(use_rawdata);
2097 }
2098 
2099 /* Flip the byte order of buffers with 16 bit samples */
2100 static void
2101 PS_FlipBytes(unsigned char* buf, tsize_t count)
2102 {
2103 	int i;
2104 	unsigned char temp;
2105 
2106 	if (count <= 0 || bitspersample <= 8) {
2107 		return;
2108 	}
2109 
2110 	count--;
2111 
2112 	for (i = 0; i < count; i += 2) {
2113 		temp = buf[i];
2114 		buf[i] = buf[i + 1];
2115 		buf[i + 1] = temp;
2116 	}
2117 }
2118 
2119 #define MAXLINE		36
2120 
2121 int
2122 PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
2123 {
2124 	uint16 fillorder;
2125 	int use_rawdata, tiled_image, breaklen = MAXLINE;
2126 	uint32 chunk_no, num_chunks;
2127         uint64 *bc;
2128 	unsigned char *buf_data, *cp;
2129 	tsize_t chunk_size, byte_count;
2130 
2131 #if defined( EXP_ASCII85ENCODER )
2132 	tsize_t			ascii85_l;	/* Length, in bytes, of ascii85_p[] data */
2133 	uint8		*	ascii85_p = 0;	/* Holds ASCII85 encoded data */
2134 #endif
2135 
2136 	PS_Lvl2colorspace(fd, tif);
2137 	use_rawdata = PS_Lvl2ImageDict(fd, tif, w, h);
2138 
2139 /* See http://bugzilla.remotesensing.org/show_bug.cgi?id=80 */
2140 #ifdef ENABLE_BROKEN_BEGINENDDATA
2141 	fputs("%%BeginData:\n", fd);
2142 #endif
2143 	fputs("exec\n", fd);
2144 
2145 	tiled_image = TIFFIsTiled(tif);
2146 	if (tiled_image) {
2147 		num_chunks = TIFFNumberOfTiles(tif);
2148 		TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc);
2149 	} else {
2150 		num_chunks = TIFFNumberOfStrips(tif);
2151 		TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
2152 	}
2153 
2154 	if (use_rawdata) {
2155 		chunk_size = (tsize_t) bc[0];
2156 		for (chunk_no = 1; chunk_no < num_chunks; chunk_no++)
2157 			if ((tsize_t) bc[chunk_no] > chunk_size)
2158 				chunk_size = (tsize_t) bc[chunk_no];
2159 	} else {
2160 		if (tiled_image)
2161 			chunk_size = TIFFTileSize(tif);
2162 		else
2163 			chunk_size = TIFFStripSize(tif);
2164 	}
2165 	buf_data = (unsigned char *)_TIFFmalloc(chunk_size);
2166 	if (!buf_data) {
2167 		TIFFError(filename, "Can't alloc %lu bytes for %s.",
2168 			(unsigned long) chunk_size, tiled_image ? "tiles" : "strips");
2169 		return(FALSE);
2170 	}
2171 
2172 #if defined( EXP_ASCII85ENCODER )
2173 	if ( ascii85 ) {
2174 	    /*
2175 	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
2176 	     * that it is allocated with sufficient room to hold the
2177 	     * encoded data (5*chunk_size/4) plus the EOD marker (+8)
2178 	     * and formatting line breaks.  The line breaks are more
2179 	     * than taken care of by using 6*chunk_size/4 rather than
2180 	     * 5*chunk_size/4.
2181 	     */
2182 
2183 	    ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 );
2184 
2185 	    if ( !ascii85_p ) {
2186 		_TIFFfree( buf_data );
2187 
2188 		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
2189 		return ( FALSE );
2190 	    }
2191 	}
2192 #endif
2193 
2194 	TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
2195 	for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) {
2196 		if (ascii85)
2197 			Ascii85Init();
2198 		else
2199 			breaklen = MAXLINE;
2200 		if (use_rawdata) {
2201 			if (tiled_image)
2202 				byte_count = TIFFReadRawTile(tif, chunk_no,
2203 						  buf_data, chunk_size);
2204 			else
2205 				byte_count = TIFFReadRawStrip(tif, chunk_no,
2206 						  buf_data, chunk_size);
2207 			if (fillorder == FILLORDER_LSB2MSB)
2208 			    TIFFReverseBits(buf_data, byte_count);
2209 		} else {
2210 			if (tiled_image)
2211 				byte_count = TIFFReadEncodedTile(tif,
2212 						chunk_no, buf_data,
2213 						chunk_size);
2214 			else
2215 				byte_count = TIFFReadEncodedStrip(tif,
2216 						chunk_no, buf_data,
2217 						chunk_size);
2218 		}
2219 		if (byte_count < 0) {
2220 			TIFFError(filename, "Can't read %s %d.",
2221 				tiled_image ? "tile" : "strip", chunk_no);
2222 			if (ascii85)
2223 				Ascii85Put('\0', fd);
2224 		}
2225 		/*
2226 		 * for 16 bits, the two bytes must be most significant
2227 		 * byte first
2228 		 */
2229 		if (bitspersample == 16 && !TIFFIsBigEndian(tif)) {
2230 			PS_FlipBytes(buf_data, byte_count);
2231 		}
2232 		/*
2233 		 * For images with alpha, matte against a white background;
2234 		 * i.e. Cback * (1 - Aimage) where Cback = 1. We will fill the
2235 		 * lower part of the buffer with the modified values.
2236 		 *
2237 		 * XXX: needs better solution
2238 		 */
2239 		if (alpha) {
2240 			int adjust, i, j = 0;
2241 			int ncomps = samplesperpixel - extrasamples;
2242 			for (i = 0; i < byte_count; i+=samplesperpixel) {
2243 				adjust = 255 - buf_data[i + ncomps];
2244 				switch (ncomps) {
2245 					case 1:
2246 						buf_data[j++] = buf_data[i] + adjust;
2247 						break;
2248 					case 2:
2249 						buf_data[j++] = buf_data[i] + adjust;
2250 						buf_data[j++] = buf_data[i+1] + adjust;
2251 						break;
2252 					case 3:
2253 						buf_data[j++] = buf_data[i] + adjust;
2254 						buf_data[j++] = buf_data[i+1] + adjust;
2255 						buf_data[j++] = buf_data[i+2] + adjust;
2256 						break;
2257 				}
2258 			}
2259 			byte_count -= j;
2260 		}
2261 
2262 		if (ascii85) {
2263 #if defined( EXP_ASCII85ENCODER )
2264 			ascii85_l = Ascii85EncodeBlock(ascii85_p, 1, buf_data, byte_count );
2265 
2266 			if ( ascii85_l > 0 )
2267 				fwrite( ascii85_p, ascii85_l, 1, fd );
2268 #else
2269 			for (cp = buf_data; byte_count > 0; byte_count--)
2270 				Ascii85Put(*cp++, fd);
2271 #endif
2272 		}
2273 		else
2274 		{
2275 			for (cp = buf_data; byte_count > 0; byte_count--) {
2276 				putc(hex[((*cp)>>4)&0xf], fd);
2277 				putc(hex[(*cp)&0xf], fd);
2278 				cp++;
2279 
2280 				if (--breaklen <= 0) {
2281 					putc('\n', fd);
2282 					breaklen = MAXLINE;
2283 				}
2284 			}
2285 		}
2286 
2287 		if ( !ascii85 ) {
2288 			if ( level2 || level3 )
2289 				putc( '>', fd );
2290 			putc('\n', fd);
2291 		}
2292 #if !defined( EXP_ASCII85ENCODER )
2293 		else
2294 			Ascii85Flush(fd);
2295 #endif
2296 	}
2297 
2298 #if defined( EXP_ASCII85ENCODER )
2299 	if ( ascii85_p )
2300 	    _TIFFfree( ascii85_p );
2301 #endif
2302 
2303 	_TIFFfree(buf_data);
2304 #ifdef ENABLE_BROKEN_BEGINENDDATA
2305 	fputs("%%EndData\n", fd);
2306 #endif
2307 	return(TRUE);
2308 }
2309 
2310 void
2311 PSpage(FILE* fd, TIFF* tif, uint32 w, uint32 h)
2312 {
2313 	char	*	imageOp = "image";
2314 
2315 	if ( useImagemask && (bitspersample == 1) )
2316 		imageOp = "imagemask";
2317 
2318 	if ((level2 || level3) && PS_Lvl2page(fd, tif, w, h))
2319 		return;
2320 	ps_bytesperrow = tf_bytesperrow - (extrasamples * bitspersample / 8)*w;
2321 	switch (photometric) {
2322 	case PHOTOMETRIC_RGB:
2323 		if (planarconfiguration == PLANARCONFIG_CONTIG) {
2324 			fprintf(fd, "%s", RGBcolorimage);
2325 			PSColorContigPreamble(fd, w, h, 3);
2326 			PSDataColorContig(fd, tif, w, h, 3);
2327 		} else {
2328 			PSColorSeparatePreamble(fd, w, h, 3);
2329 			PSDataColorSeparate(fd, tif, w, h, 3);
2330 		}
2331 		break;
2332 	case PHOTOMETRIC_SEPARATED:
2333 		/* XXX should emit CMYKcolorimage */
2334 		if (planarconfiguration == PLANARCONFIG_CONTIG) {
2335 			PSColorContigPreamble(fd, w, h, 4);
2336 			PSDataColorContig(fd, tif, w, h, 4);
2337 		} else {
2338 			PSColorSeparatePreamble(fd, w, h, 4);
2339 			PSDataColorSeparate(fd, tif, w, h, 4);
2340 		}
2341 		break;
2342 	case PHOTOMETRIC_PALETTE:
2343 		fprintf(fd, "%s", RGBcolorimage);
2344 		PhotoshopBanner(fd, w, h, 1, 3, "false 3 colorimage");
2345 		fprintf(fd, "/scanLine %ld string def\n",
2346 		    (long) ps_bytesperrow * 3L);
2347 		fprintf(fd, "%lu %lu 8\n",
2348 		    (unsigned long) w, (unsigned long) h);
2349 		fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
2350 		    (unsigned long) w, (unsigned long) h, (unsigned long) h);
2351 		fprintf(fd, "{currentfile scanLine readhexstring pop} bind\n");
2352 		fprintf(fd, "false 3 colorimage\n");
2353 		PSDataPalette(fd, tif, w, h);
2354 		break;
2355 	case PHOTOMETRIC_MINISBLACK:
2356 	case PHOTOMETRIC_MINISWHITE:
2357 		PhotoshopBanner(fd, w, h, 1, 1, imageOp);
2358 		fprintf(fd, "/scanLine %ld string def\n",
2359 		    (long) ps_bytesperrow);
2360 		fprintf(fd, "%lu %lu %d\n",
2361 		    (unsigned long) w, (unsigned long) h, bitspersample);
2362 		fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
2363 		    (unsigned long) w, (unsigned long) h, (unsigned long) h);
2364 		fprintf(fd,
2365 		    "{currentfile scanLine readhexstring pop} bind\n");
2366 		fprintf(fd, "%s\n", imageOp);
2367 		PSDataBW(fd, tif, w, h);
2368 		break;
2369 	}
2370 	putc('\n', fd);
2371 }
2372 
2373 void
2374 PSColorContigPreamble(FILE* fd, uint32 w, uint32 h, int nc)
2375 {
2376 	ps_bytesperrow = nc * (tf_bytesperrow / samplesperpixel);
2377 	PhotoshopBanner(fd, w, h, 1, nc, "false %d colorimage");
2378 	fprintf(fd, "/line %ld string def\n", (long) ps_bytesperrow);
2379 	fprintf(fd, "%lu %lu %d\n",
2380 	    (unsigned long) w, (unsigned long) h, bitspersample);
2381 	fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
2382 	    (unsigned long) w, (unsigned long) h, (unsigned long) h);
2383 	fprintf(fd, "{currentfile line readhexstring pop} bind\n");
2384 	fprintf(fd, "false %d colorimage\n", nc);
2385 }
2386 
2387 void
2388 PSColorSeparatePreamble(FILE* fd, uint32 w, uint32 h, int nc)
2389 {
2390 	int i;
2391 
2392 	PhotoshopBanner(fd, w, h, ps_bytesperrow, nc, "true %d colorimage");
2393 	for (i = 0; i < nc; i++)
2394 		fprintf(fd, "/line%d %ld string def\n",
2395 		    i, (long) ps_bytesperrow);
2396 	fprintf(fd, "%lu %lu %d\n",
2397 	    (unsigned long) w, (unsigned long) h, bitspersample);
2398 	fprintf(fd, "[%lu 0 0 -%lu 0 %lu] \n",
2399 	    (unsigned long) w, (unsigned long) h, (unsigned long) h);
2400 	for (i = 0; i < nc; i++)
2401 		fprintf(fd, "{currentfile line%d readhexstring pop}bind\n", i);
2402 	fprintf(fd, "true %d colorimage\n", nc);
2403 }
2404 
2405 #define	DOBREAK(len, howmany, fd) \
2406 	if (((len) -= (howmany)) <= 0) {	\
2407 		putc('\n', fd);			\
2408 		(len) = MAXLINE-(howmany);	\
2409 	}
2410 #define	PUTHEX(c,fd)	putc(hex[((c)>>4)&0xf],fd); putc(hex[(c)&0xf],fd)
2411 
2412 void
2413 PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
2414 {
2415 	uint32 row;
2416 	int breaklen = MAXLINE, es = samplesperpixel - nc;
2417 	tsize_t cc;
2418 	unsigned char *tf_buf;
2419 	unsigned char *cp, c;
2420 
2421 	(void) w;
2422 	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
2423 	if (tf_buf == NULL) {
2424 		TIFFError(filename, "No space for scanline buffer");
2425 		return;
2426 	}
2427 	for (row = 0; row < h; row++) {
2428 		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
2429 			break;
2430 		cp = tf_buf;
2431 		/*
2432 		 * for 16 bits, the two bytes must be most significant
2433 		 * byte first
2434 		 */
2435 		if (bitspersample == 16 && !HOST_BIGENDIAN) {
2436 			PS_FlipBytes(cp, tf_bytesperrow);
2437 		}
2438 		if (alpha) {
2439 			int adjust;
2440 			cc = 0;
2441 			for (; cc < tf_bytesperrow; cc += samplesperpixel) {
2442 				DOBREAK(breaklen, nc, fd);
2443 				/*
2444 				 * For images with alpha, matte against
2445 				 * a white background; i.e.
2446 				 *    Cback * (1 - Aimage)
2447 				 * where Cback = 1.
2448 				 */
2449 				adjust = 255 - cp[nc];
2450 				switch (nc) {
2451 				case 4: c = *cp++ + adjust; PUTHEX(c,fd);
2452 				case 3: c = *cp++ + adjust; PUTHEX(c,fd);
2453 				case 2: c = *cp++ + adjust; PUTHEX(c,fd);
2454 				case 1: c = *cp++ + adjust; PUTHEX(c,fd);
2455 				}
2456 				cp += es;
2457 			}
2458 		} else {
2459 			cc = 0;
2460 			for (; cc < tf_bytesperrow; cc += samplesperpixel) {
2461 				DOBREAK(breaklen, nc, fd);
2462 				switch (nc) {
2463 				case 4: c = *cp++; PUTHEX(c,fd);
2464 				case 3: c = *cp++; PUTHEX(c,fd);
2465 				case 2: c = *cp++; PUTHEX(c,fd);
2466 				case 1: c = *cp++; PUTHEX(c,fd);
2467 				}
2468 				cp += es;
2469 			}
2470 		}
2471 	}
2472 	_TIFFfree((char *) tf_buf);
2473 }
2474 
2475 void
2476 PSDataColorSeparate(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
2477 {
2478 	uint32 row;
2479 	int breaklen = MAXLINE;
2480 	tsize_t cc;
2481 	tsample_t s, maxs;
2482 	unsigned char *tf_buf;
2483 	unsigned char *cp, c;
2484 
2485 	(void) w;
2486 	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
2487 	if (tf_buf == NULL) {
2488 		TIFFError(filename, "No space for scanline buffer");
2489 		return;
2490 	}
2491 	maxs = (samplesperpixel > nc ? nc : samplesperpixel);
2492 	for (row = 0; row < h; row++) {
2493 		for (s = 0; s < maxs; s++) {
2494 			if (TIFFReadScanline(tif, tf_buf, row, s) < 0)
2495 				break;
2496 			for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
2497 				DOBREAK(breaklen, 1, fd);
2498 				c = *cp++;
2499 				PUTHEX(c,fd);
2500 			}
2501 		}
2502 	}
2503 	_TIFFfree((char *) tf_buf);
2504 }
2505 
2506 #define	PUTRGBHEX(c,fd) \
2507 	PUTHEX(rmap[c],fd); PUTHEX(gmap[c],fd); PUTHEX(bmap[c],fd)
2508 
2509 void
2510 PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
2511 {
2512 	uint16 *rmap, *gmap, *bmap;
2513 	uint32 row;
2514 	int breaklen = MAXLINE, nc;
2515 	tsize_t cc;
2516 	unsigned char *tf_buf;
2517 	unsigned char *cp, c;
2518 
2519 	(void) w;
2520 	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
2521 		TIFFError(filename, "Palette image w/o \"Colormap\" tag");
2522 		return;
2523 	}
2524 	switch (bitspersample) {
2525 	case 8:	case 4: case 2: case 1:
2526 		break;
2527 	default:
2528 		TIFFError(filename, "Depth %d not supported", bitspersample);
2529 		return;
2530 	}
2531 	nc = 3 * (8 / bitspersample);
2532 	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
2533 	if (tf_buf == NULL) {
2534 		TIFFError(filename, "No space for scanline buffer");
2535 		return;
2536 	}
2537 	if (checkcmap(tif, 1<<bitspersample, rmap, gmap, bmap) == 16) {
2538 		int i;
2539 #define	CVT(x)		((unsigned short) (((x) * 255) / ((1U<<16)-1)))
2540 		for (i = (1<<bitspersample)-1; i >= 0; i--) {
2541 			rmap[i] = CVT(rmap[i]);
2542 			gmap[i] = CVT(gmap[i]);
2543 			bmap[i] = CVT(bmap[i]);
2544 		}
2545 #undef CVT
2546 	}
2547 	for (row = 0; row < h; row++) {
2548 		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
2549 			break;
2550 		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
2551 			DOBREAK(breaklen, nc, fd);
2552 			switch (bitspersample) {
2553 			case 8:
2554 				c = *cp++; PUTRGBHEX(c, fd);
2555 				break;
2556 			case 4:
2557 				c = *cp++; PUTRGBHEX(c&0xf, fd);
2558 				c >>= 4;   PUTRGBHEX(c, fd);
2559 				break;
2560 			case 2:
2561 				c = *cp++; PUTRGBHEX(c&0x3, fd);
2562 				c >>= 2;   PUTRGBHEX(c&0x3, fd);
2563 				c >>= 2;   PUTRGBHEX(c&0x3, fd);
2564 				c >>= 2;   PUTRGBHEX(c, fd);
2565 				break;
2566 			case 1:
2567 				c = *cp++; PUTRGBHEX(c&0x1, fd);
2568 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2569 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2570 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2571 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2572 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2573 				c >>= 1;   PUTRGBHEX(c&0x1, fd);
2574 				c >>= 1;   PUTRGBHEX(c, fd);
2575 				break;
2576 			}
2577 		}
2578 	}
2579 	_TIFFfree((char *) tf_buf);
2580 }
2581 
2582 void
2583 PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
2584 {
2585 	int breaklen = MAXLINE;
2586 	unsigned char* tf_buf;
2587 	unsigned char* cp;
2588 	tsize_t stripsize = TIFFStripSize(tif);
2589 	tstrip_t s;
2590 
2591 #if defined( EXP_ASCII85ENCODER )
2592 	tsize_t	ascii85_l;		/* Length, in bytes, of ascii85_p[] data */
2593 	uint8	*ascii85_p = 0;		/* Holds ASCII85 encoded data */
2594 #endif
2595 
2596 	(void) w; (void) h;
2597 	tf_buf = (unsigned char *) _TIFFmalloc(stripsize);
2598         memset(tf_buf, 0, stripsize);
2599 	if (tf_buf == NULL) {
2600 		TIFFError(filename, "No space for scanline buffer");
2601 		return;
2602 	}
2603 
2604 #if defined( EXP_ASCII85ENCODER )
2605 	if ( ascii85 ) {
2606 	    /*
2607 	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
2608 	     * that it is allocated with sufficient room to hold the
2609 	     * encoded data (5*stripsize/4) plus the EOD marker (+8)
2610 	     * and formatting line breaks.  The line breaks are more
2611 	     * than taken care of by using 6*stripsize/4 rather than
2612 	     * 5*stripsize/4.
2613 	     */
2614 
2615 	    ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 );
2616 
2617 	    if ( !ascii85_p ) {
2618 		_TIFFfree( tf_buf );
2619 
2620 		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
2621 		return;
2622 	    }
2623 	}
2624 #endif
2625 
2626 	if (ascii85)
2627 		Ascii85Init();
2628 
2629 	for (s = 0; s < TIFFNumberOfStrips(tif); s++) {
2630 		tmsize_t cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize);
2631 		if (cc < 0) {
2632 			TIFFError(filename, "Can't read strip");
2633 			break;
2634 		}
2635 		cp = tf_buf;
2636 		if (photometric == PHOTOMETRIC_MINISWHITE) {
2637 			for (cp += cc; --cp >= tf_buf;)
2638 				*cp = ~*cp;
2639 			cp++;
2640 		}
2641 		/*
2642 		 * for 16 bits, the two bytes must be most significant
2643 		 * byte first
2644 		 */
2645 		if (bitspersample == 16 && !HOST_BIGENDIAN) {
2646 			PS_FlipBytes(cp, cc);
2647 		}
2648 		if (ascii85) {
2649 #if defined( EXP_ASCII85ENCODER )
2650 			if (alpha) {
2651 				int adjust, i;
2652 				for (i = 0; i < cc; i+=2) {
2653 					adjust = 255 - cp[i + 1];
2654 				    cp[i / 2] = cp[i] + adjust;
2655 				}
2656 				cc /= 2;
2657 			}
2658 
2659 			ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, cp, cc );
2660 
2661 			if ( ascii85_l > 0 )
2662 			    fwrite( ascii85_p, ascii85_l, 1, fd );
2663 #else
2664 			while (cc-- > 0)
2665 				Ascii85Put(*cp++, fd);
2666 #endif /* EXP_ASCII85_ENCODER */
2667 		} else {
2668 			unsigned char c;
2669 
2670 			if (alpha) {
2671 				int adjust;
2672 				while (cc-- > 0) {
2673 					DOBREAK(breaklen, 1, fd);
2674 					/*
2675 					 * For images with alpha, matte against
2676 					 * a white background; i.e.
2677 					 *    Cback * (1 - Aimage)
2678 					 * where Cback = 1.
2679 					 */
2680 					adjust = 255 - cp[1];
2681 					c = *cp++ + adjust; PUTHEX(c,fd);
2682 					cp++, cc--;
2683 				}
2684 			} else {
2685 				while (cc-- > 0) {
2686 					c = *cp++;
2687 					DOBREAK(breaklen, 1, fd);
2688 					PUTHEX(c, fd);
2689 				}
2690 			}
2691 		}
2692 	}
2693 
2694 	if ( !ascii85 )
2695 	{
2696 	    if ( level2 || level3)
2697 		fputs(">\n", fd);
2698 	}
2699 #if !defined( EXP_ASCII85ENCODER )
2700 	else
2701 	    Ascii85Flush(fd);
2702 #else
2703 	if ( ascii85_p )
2704 	    _TIFFfree( ascii85_p );
2705 #endif
2706 
2707 	_TIFFfree(tf_buf);
2708 }
2709 
2710 void
2711 PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
2712 {
2713 	uint64 *bc;
2714 	uint32 bufsize;
2715 	int breaklen = MAXLINE;
2716 	tmsize_t cc;
2717 	uint16 fillorder;
2718 	unsigned char *tf_buf;
2719 	unsigned char *cp, c;
2720 	tstrip_t s;
2721 
2722 #if defined( EXP_ASCII85ENCODER )
2723 	tsize_t 		ascii85_l;		/* Length, in bytes, of ascii85_p[] data */
2724 	uint8		*	ascii85_p = 0;		/* Holds ASCII85 encoded data */
2725 #endif
2726 
2727 	(void) w; (void) h;
2728 	TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
2729 	TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
2730 
2731 	/*
2732 	 * Find largest strip:
2733 	 */
2734 
2735 	bufsize = (uint32) bc[0];
2736 
2737 	for ( s = 0; ++s < (tstrip_t)tf_numberstrips; ) {
2738 		if ( bc[s] > bufsize )
2739 			bufsize = (uint32) bc[s];
2740 	}
2741 
2742 	tf_buf = (unsigned char*) _TIFFmalloc(bufsize);
2743 	if (tf_buf == NULL) {
2744 		TIFFError(filename, "No space for strip buffer");
2745 		return;
2746 	}
2747 
2748 #if defined( EXP_ASCII85ENCODER )
2749 	if ( ascii85 ) {
2750 	    /*
2751 	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
2752 	     * that it is allocated with sufficient room to hold the
2753 	     * encoded data (5*bufsize/4) plus the EOD marker (+8)
2754 	     * and formatting line breaks.  The line breaks are more
2755 	     * than taken care of by using 6*bufsize/4 rather than
2756 	     * 5*bufsize/4.
2757 	     */
2758 
2759 	    ascii85_p = _TIFFmalloc( (bufsize+(bufsize/2)) + 8 );
2760 
2761 	    if ( !ascii85_p ) {
2762 		_TIFFfree( tf_buf );
2763 
2764 		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
2765 		return;
2766 	    }
2767 	}
2768 #endif
2769 
2770 	for (s = 0; s < (tstrip_t) tf_numberstrips; s++) {
2771 		cc = TIFFReadRawStrip(tif, s, tf_buf, (tmsize_t) bc[s]);
2772 		if (cc < 0) {
2773 			TIFFError(filename, "Can't read strip");
2774 			break;
2775 		}
2776 		if (fillorder == FILLORDER_LSB2MSB)
2777 			TIFFReverseBits(tf_buf, cc);
2778 		if (!ascii85) {
2779 			for (cp = tf_buf; cc > 0; cc--) {
2780 				DOBREAK(breaklen, 1, fd);
2781 				c = *cp++;
2782 				PUTHEX(c, fd);
2783 			}
2784 			fputs(">\n", fd);
2785 			breaklen = MAXLINE;
2786 		} else {
2787 			Ascii85Init();
2788 #if defined( EXP_ASCII85ENCODER )
2789 			ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, tf_buf, cc );
2790 
2791 			if ( ascii85_l > 0 )
2792 				fwrite( ascii85_p, ascii85_l, 1, fd );
2793 #else
2794 			for (cp = tf_buf; cc > 0; cc--)
2795 				Ascii85Put(*cp++, fd);
2796 			Ascii85Flush(fd);
2797 #endif	/* EXP_ASCII85ENCODER */
2798 		}
2799 	}
2800 	_TIFFfree((char *) tf_buf);
2801 
2802 #if defined( EXP_ASCII85ENCODER )
2803 	if ( ascii85_p )
2804 		_TIFFfree( ascii85_p );
2805 #endif
2806 }
2807 
2808 void
2809 Ascii85Init(void)
2810 {
2811 	ascii85breaklen = 2*MAXLINE;
2812 	ascii85count = 0;
2813 }
2814 
2815 static char*
2816 Ascii85Encode(unsigned char* raw)
2817 {
2818 	static char encoded[6];
2819 	uint32 word;
2820 
2821 	word = (((raw[0]<<8)+raw[1])<<16) + (raw[2]<<8) + raw[3];
2822 	if (word != 0L) {
2823 		uint32 q;
2824 		uint16 w1;
2825 
2826 		q = word / (85L*85*85*85);	/* actually only a byte */
2827 		encoded[0] = (char) (q + '!');
2828 
2829 		word -= q * (85L*85*85*85); q = word / (85L*85*85);
2830 		encoded[1] = (char) (q + '!');
2831 
2832 		word -= q * (85L*85*85); q = word / (85*85);
2833 		encoded[2] = (char) (q + '!');
2834 
2835 		w1 = (uint16) (word - q*(85L*85));
2836 		encoded[3] = (char) ((w1 / 85) + '!');
2837 		encoded[4] = (char) ((w1 % 85) + '!');
2838 		encoded[5] = '\0';
2839 	} else
2840 		encoded[0] = 'z', encoded[1] = '\0';
2841 	return (encoded);
2842 }
2843 
2844 void
2845 Ascii85Put(unsigned char code, FILE* fd)
2846 {
2847 	ascii85buf[ascii85count++] = code;
2848 	if (ascii85count >= 4) {
2849 		unsigned char* p;
2850 		int n;
2851 
2852 		for (n = ascii85count, p = ascii85buf; n >= 4; n -= 4, p += 4) {
2853 			char* cp;
2854 			for (cp = Ascii85Encode(p); *cp; cp++) {
2855 				putc(*cp, fd);
2856 				if (--ascii85breaklen == 0) {
2857 					putc('\n', fd);
2858 					ascii85breaklen = 2*MAXLINE;
2859 				}
2860 			}
2861 		}
2862 		_TIFFmemcpy(ascii85buf, p, n);
2863 		ascii85count = n;
2864 	}
2865 }
2866 
2867 void
2868 Ascii85Flush(FILE* fd)
2869 {
2870 	if (ascii85count > 0) {
2871 		char* res;
2872 		_TIFFmemset(&ascii85buf[ascii85count], 0, 3);
2873 		res = Ascii85Encode(ascii85buf);
2874 		fwrite(res[0] == 'z' ? "!!!!" : res, ascii85count + 1, 1, fd);
2875 	}
2876 	fputs("~>\n", fd);
2877 }
2878 #if	defined( EXP_ASCII85ENCODER)
2879 
2880 #define A85BREAKCNTR    ascii85breaklen
2881 #define A85BREAKLEN     (2*MAXLINE)
2882 
2883 /*****************************************************************************
2884 *
2885 * Name:         Ascii85EncodeBlock( ascii85_p, f_eod, raw_p, raw_l )
2886 *
2887 * Description:  This routine will encode the raw data in the buffer described
2888 *               by raw_p and raw_l into ASCII85 format and store the encoding
2889 *               in the buffer given by ascii85_p.
2890 *
2891 * Parameters:   ascii85_p   -   A buffer supplied by the caller which will
2892 *                               contain the encoded ASCII85 data.
2893 *               f_eod       -   Flag: Nz means to end the encoded buffer with
2894 *                               an End-Of-Data marker.
2895 *               raw_p       -   Pointer to the buffer of data to be encoded
2896 *               raw_l       -   Number of bytes in raw_p[] to be encoded
2897 *
2898 * Returns:      (int)   <   0   Error, see errno
2899 *                       >=  0   Number of bytes written to ascii85_p[].
2900 *
2901 * Notes:        An external variable given by A85BREAKCNTR is used to
2902 *               determine when to insert newline characters into the
2903 *               encoded data.  As each byte is placed into ascii85_p this
2904 *               external is decremented.  If the variable is decrement to
2905 *               or past zero then a newline is inserted into ascii85_p
2906 *               and the A85BREAKCNTR is then reset to A85BREAKLEN.
2907 *                   Note:  for efficiency reasons the A85BREAKCNTR variable
2908 *                          is not actually checked on *every* character
2909 *                          placed into ascii85_p but often only for every
2910 *                          5 characters.
2911 *
2912 *               THE CALLER IS RESPONSIBLE FOR ENSURING THAT ASCII85_P[] IS
2913 *               SUFFICIENTLY LARGE TO THE ENCODED DATA!
2914 *                   You will need at least 5 * (raw_l/4) bytes plus space for
2915 *                   newline characters and space for an EOD marker (if
2916 *                   requested).  A safe calculation is to use 6*(raw_l/4) + 8
2917 *                   to size ascii85_p.
2918 *
2919 *****************************************************************************/
2920 
2921 tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw_p, tsize_t raw_l )
2922 
2923 {
2924     char                        ascii85[5];     /* Encoded 5 tuple */
2925     tsize_t                     ascii85_l;      /* Number of bytes written to ascii85_p[] */
2926     int                         rc;             /* Return code */
2927     uint32                      val32;          /* Unencoded 4 tuple */
2928 
2929     ascii85_l = 0;                              /* Nothing written yet */
2930 
2931     if ( raw_p )
2932     {
2933         --raw_p;                                /* Prepare for pre-increment fetches */
2934 
2935         for ( ; raw_l > 3; raw_l -= 4 )
2936         {
2937             val32  = *(++raw_p) << 24;
2938             val32 += *(++raw_p) << 16;
2939             val32 += *(++raw_p) <<  8;
2940             val32 += *(++raw_p);
2941 
2942             if ( val32 == 0 )                   /* Special case */
2943             {
2944                 ascii85_p[ascii85_l] = 'z';
2945                 rc = 1;
2946             }
2947 
2948             else
2949             {
2950                 ascii85[4] = (char) ((val32 % 85) + 33);
2951                 val32 /= 85;
2952 
2953                 ascii85[3] = (char) ((val32 % 85) + 33);
2954                 val32 /= 85;
2955 
2956                 ascii85[2] = (char) ((val32 % 85) + 33);
2957                 val32 /= 85;
2958 
2959                 ascii85[1] = (char) ((val32 % 85) + 33);
2960                 ascii85[0] = (char) ((val32 / 85) + 33);
2961 
2962                 _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, sizeof(ascii85) );
2963                 rc = sizeof(ascii85);
2964             }
2965 
2966             ascii85_l += rc;
2967 
2968             if ( (A85BREAKCNTR -= rc) <= 0 )
2969             {
2970                 ascii85_p[ascii85_l] = '\n';
2971                 ++ascii85_l;
2972                 A85BREAKCNTR = A85BREAKLEN;
2973             }
2974         }
2975 
2976         /*
2977          * Output any straggler bytes:
2978          */
2979 
2980         if ( raw_l > 0 )
2981         {
2982             tsize_t         len;                /* Output this many bytes */
2983 
2984             len = raw_l + 1;
2985             val32 = *++raw_p << 24;             /* Prime the pump */
2986 
2987             if ( --raw_l > 0 )  val32 += *(++raw_p) << 16;
2988             if ( --raw_l > 0 )  val32 += *(++raw_p) <<  8;
2989 
2990             val32 /= 85;
2991 
2992             ascii85[3] = (char) ((val32 % 85) + 33);
2993             val32 /= 85;
2994 
2995             ascii85[2] = (char) ((val32 % 85) + 33);
2996             val32 /= 85;
2997 
2998             ascii85[1] = (char) ((val32 % 85) + 33);
2999             ascii85[0] = (char) ((val32 / 85) + 33);
3000 
3001             _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, len );
3002             ascii85_l += len;
3003         }
3004     }
3005 
3006     /*
3007      * If requested add an ASCII85 End Of Data marker:
3008      */
3009 
3010     if ( f_eod )
3011     {
3012         ascii85_p[ascii85_l++] = '~';
3013         ascii85_p[ascii85_l++] = '>';
3014         ascii85_p[ascii85_l++] = '\n';
3015     }
3016 
3017     return ( ascii85_l );
3018 
3019 }   /* Ascii85EncodeBlock() */
3020 
3021 #endif	/* EXP_ASCII85ENCODER */
3022 
3023 
3024 char* stuff[] = {
3025 "usage: tiff2ps [options] input.tif ...",
3026 "where options are:",
3027 " -1            generate PostScript Level 1 (default)",
3028 " -2            generate PostScript Level 2",
3029 " -3            generate PostScript Level 3",
3030 " -8            disable use of ASCII85 encoding with PostScript Level 2/3",
3031 " -a            convert all directories in file (default is first), Not EPS",
3032 " -b #          set the bottom margin to # inches",
3033 " -c            center image (-b and -l still add to this)",
3034 " -d #          set initial directory to # counting from zero",
3035 " -D            enable duplex printing (two pages per sheet of paper)",
3036 " -e            generate Encapsulated PostScript (EPS) (implies -z)",
3037 " -h #          set printed page height to # inches (no default)",
3038 " -w #          set printed page width to # inches (no default)",
3039 " -H #          split image if height is more than # inches",
3040 " -P L or P     set optional PageOrientation DSC comment to Landscape or Portrait",
3041 " -W #          split image if width is more than # inches",
3042 " -L #          overLap split images by # inches",
3043 " -i #          enable/disable (Nz/0) pixel interpolation (default: enable)",
3044 " -l #          set the left margin to # inches",
3045 " -m            use \"imagemask\" operator instead of \"image\"",
3046 " -o #          convert directory at file offset # bytes",
3047 " -O file       write PostScript to file instead of standard output",
3048 " -p            generate regular PostScript",
3049 " -r # or auto  rotate by 90, 180, 270 degrees or auto",
3050 " -s            generate PostScript for a single image",
3051 " -t name       set postscript document title. Otherwise the filename is used",
3052 " -T            print pages for top edge binding",
3053 " -x            override resolution units as centimeters",
3054 " -y            override resolution units as inches",
3055 " -z            enable printing in the deadzone (only for PostScript Level 2/3)",
3056 NULL
3057 };
3058 
3059 static void
3060 usage(int code)
3061 {
3062 	char buf[BUFSIZ];
3063 	int i;
3064 
3065 	setbuf(stderr, buf);
3066         fprintf(stderr, "%s\n\n", TIFFGetVersion());
3067 	for (i = 0; stuff[i] != NULL; i++)
3068 		fprintf(stderr, "%s\n", stuff[i]);
3069 	exit(code);
3070 }
3071 
3072