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