]> git.saurik.com Git - wxWidgets.git/blame - src/tiff/tools/tiff2ps.c
Also update focus rect when changing selection in single selection mode, fixes #11332
[wxWidgets.git] / src / tiff / tools / tiff2ps.c
CommitLineData
8414a40c
VZ
1/* $Id$ */
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#include "tiffio.h"
40
41/*
42 * Revision history
43 *
44 * 2001-Mar-21
45 * I (Bruce A. Mallett) added this revision history comment ;)
46 *
47 * Fixed PS_Lvl2page() code which outputs non-ASCII85 raw
48 * data. Moved test for when to output a line break to
49 * *after* the output of a character. This just serves
50 * to fix an eye-nuisance where the first line of raw
51 * data was one character shorter than subsequent lines.
52 *
53 * Added an experimental ASCII85 encoder which can be used
54 * only when there is a single buffer of bytes to be encoded.
55 * This version is much faster at encoding a straight-line
56 * buffer of data because it can avoid alot of the loop
57 * overhead of the byte-by-bye version. To use this version
58 * you need to define EXP_ASCII85ENCODER (experimental ...).
59 *
60 * Added bug fix given by Michael Schmidt to PS_Lvl2page()
61 * in which an end-of-data marker ('>') was not being output
62 * when producing non-ASCII85 encoded PostScript Level 2
63 * data.
64 *
65 * Fixed PS_Lvl2colorspace() so that it no longer assumes that
66 * a TIFF having more than 2 planes is a CMYK. This routine
67 * no longer looks at the samples per pixel but instead looks
68 * at the "photometric" value. This change allows support of
69 * CMYK TIFFs.
70 *
71 * Modified the PostScript L2 imaging loop so as to test if
72 * the input stream is still open before attempting to do a
73 * flushfile on it. This was done because some RIPs close
74 * the stream after doing the image operation.
75 *
76 * Got rid of the realloc() being done inside a loop in the
77 * PSRawDataBW() routine. The code now walks through the
78 * byte-size array outside the loop to determine the largest
79 * size memory block that will be needed.
80 *
81 * Added "-m" switch to ask tiff2ps to, where possible, use the
82 * "imagemask" operator instead of the "image" operator.
83 *
84 * Added the "-i #" switch to allow interpolation to be disabled.
85 *
86 * Unrolled a loop or two to improve performance.
87 */
88
89/*
90 * Define EXP_ASCII85ENCODER if you want to use an experimental
91 * version of the ASCII85 encoding routine. The advantage of
92 * using this routine is that tiff2ps will convert to ASCII85
93 * encoding at between 3 and 4 times the speed as compared to
94 * using the old (non-experimental) encoder. The disadvantage
95 * is that you will be using a new (and unproven) encoding
96 * routine. So user beware, you have been warned!
97 */
98
99#define EXP_ASCII85ENCODER
100
101/*
102 * NB: this code assumes uint32 works with printf's %l[ud].
103 */
104#ifndef TRUE
105#define TRUE 1
106#define FALSE 0
107#endif
108
109int ascii85 = FALSE; /* use ASCII85 encoding */
110int interpolate = TRUE; /* interpolate level2 image */
111int level2 = FALSE; /* generate PostScript level 2 */
112int level3 = FALSE; /* generate PostScript level 3 */
113int printAll = FALSE; /* print all images in file */
114int generateEPSF = TRUE; /* generate Encapsulated PostScript */
115int PSduplex = FALSE; /* enable duplex printing */
116int PStumble = FALSE; /* enable top edge binding */
117int PSavoiddeadzone = TRUE; /* enable avoiding printer deadzone */
118double maxPageHeight = 0; /* maximum size to fit on page */
119double splitOverlap = 0; /* amount for split pages to overlag */
120int rotate = FALSE; /* rotate image by 180 degrees */
121char *filename; /* input filename */
122int useImagemask = FALSE; /* Use imagemask instead of image operator */
123uint16 res_unit = 0; /* Resolution units: 2 - inches, 3 - cm */
124
125/*
126 * ASCII85 Encoding Support.
127 */
128unsigned char ascii85buf[10];
129int ascii85count;
130int ascii85breaklen;
131
132int TIFF2PS(FILE*, TIFF*, double, double, double, double, int);
133void PSpage(FILE*, TIFF*, uint32, uint32);
134void PSColorContigPreamble(FILE*, uint32, uint32, int);
135void PSColorSeparatePreamble(FILE*, uint32, uint32, int);
136void PSDataColorContig(FILE*, TIFF*, uint32, uint32, int);
137void PSDataColorSeparate(FILE*, TIFF*, uint32, uint32, int);
138void PSDataPalette(FILE*, TIFF*, uint32, uint32);
139void PSDataBW(FILE*, TIFF*, uint32, uint32);
140void PSRawDataBW(FILE*, TIFF*, uint32, uint32);
141void Ascii85Init(void);
142void Ascii85Put(unsigned char code, FILE* fd);
143void Ascii85Flush(FILE* fd);
144void PSHead(FILE*, TIFF*, uint32, uint32, double, double, double, double);
145void PSTail(FILE*, int);
146
147#if defined( EXP_ASCII85ENCODER)
148int Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw_p, int raw_l );
149#endif
150
151static void usage(int);
152
153int
154main(int argc, char* argv[])
155{
156 int dirnum = -1, c, np = 0;
157 int centered = 0;
158 double bottommargin = 0;
159 double leftmargin = 0;
160 double pageWidth = 0;
161 double pageHeight = 0;
162 uint32 diroff = 0;
163 extern char *optarg;
164 extern int optind;
165 FILE* output = stdout;
166
167 while ((c = getopt(argc, argv, "b:d:h:H:L:i:w:l:o:O:acelmrxyzps1238DT")) != -1)
168 switch (c) {
169 case 'b':
170 bottommargin = atof(optarg);
171 break;
172 case 'c':
173 centered = 1;
174 break;
175 case 'd':
176 dirnum = atoi(optarg);
177 break;
178 case 'D':
179 PSduplex = TRUE;
180 break;
181 case 'i':
182 interpolate = atoi(optarg) ? TRUE:FALSE;
183 break;
184 case 'T':
185 PStumble = TRUE;
186 break;
187 case 'e':
188 PSavoiddeadzone = FALSE;
189 generateEPSF = TRUE;
190 break;
191 case 'h':
192 pageHeight = atof(optarg);
193 break;
194 case 'H':
195 maxPageHeight = atof(optarg);
196 if (pageHeight==0) pageHeight = maxPageHeight;
197 break;
198 case 'L':
199 splitOverlap = atof(optarg);
200 break;
201 case 'm':
202 useImagemask = TRUE;
203 break;
204 case 'o':
205 diroff = (uint32) strtoul(optarg, NULL, 0);
206 break;
207 case 'O': /* XXX too bad -o is already taken */
208 output = fopen(optarg, "w");
209 if (output == NULL) {
210 fprintf(stderr,
211 "%s: %s: Cannot open output file.\n",
212 argv[0], optarg);
213 exit(-2);
214 }
215 break;
216 case 'l':
217 leftmargin = atof(optarg);
218 break;
219 case 'a':
220 printAll = TRUE;
221 /* fall thru... */
222 case 'p':
223 generateEPSF = FALSE;
224 break;
225 case 'r':
226 rotate = TRUE;
227 break;
228 case 's':
229 printAll = FALSE;
230 break;
231 case 'w':
232 pageWidth = atof(optarg);
233 break;
234 case 'z':
235 PSavoiddeadzone = FALSE;
236 break;
237 case '1':
238 level2 = FALSE;
239 level3 = FALSE;
240 ascii85 = FALSE;
241 break;
242 case '2':
243 level2 = TRUE;
244 ascii85 = TRUE; /* default to yes */
245 break;
246 case '3':
247 level3 = TRUE;
248 ascii85 = TRUE; /* default to yes */
249 break;
250 case '8':
251 ascii85 = FALSE;
252 break;
253 case 'x':
254 res_unit = RESUNIT_CENTIMETER;
255 break;
256 case 'y':
257 res_unit = RESUNIT_INCH;
258 break;
259 case '?':
260 usage(-1);
261 }
262 for (; argc - optind > 0; optind++) {
263 TIFF* tif = TIFFOpen(filename = argv[optind], "r");
264 if (tif != NULL) {
265 if (dirnum != -1
266 && !TIFFSetDirectory(tif, (tdir_t)dirnum))
267 return (-1);
268 else if (diroff != 0 &&
269 !TIFFSetSubDirectory(tif, diroff))
270 return (-1);
271 np = TIFF2PS(output, tif, pageWidth, pageHeight,
272 leftmargin, bottommargin, centered);
273 TIFFClose(tif);
274 }
275 }
276 if (np)
277 PSTail(output, np);
278 else
279 usage(-1);
280 if (output != stdout)
281 fclose(output);
282 return (0);
283}
284
285static uint16 samplesperpixel;
286static uint16 bitspersample;
287static uint16 planarconfiguration;
288static uint16 photometric;
289static uint16 compression;
290static uint16 extrasamples;
291static int alpha;
292
293static int
294checkImage(TIFF* tif)
295{
296 switch (photometric) {
297 case PHOTOMETRIC_YCBCR:
298 if ((compression == COMPRESSION_JPEG || compression == COMPRESSION_OJPEG)
299 && planarconfiguration == PLANARCONFIG_CONTIG) {
300 /* can rely on libjpeg to convert to RGB */
301 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE,
302 JPEGCOLORMODE_RGB);
303 photometric = PHOTOMETRIC_RGB;
304 } else {
305 if (level2 || level3)
306 break;
307 TIFFError(filename, "Can not handle image with %s",
308 "PhotometricInterpretation=YCbCr");
309 return (0);
310 }
311 /* fall thru... */
312 case PHOTOMETRIC_RGB:
313 if (alpha && bitspersample != 8) {
314 TIFFError(filename,
315 "Can not handle %d-bit/sample RGB image with alpha",
316 bitspersample);
317 return (0);
318 }
319 /* fall thru... */
320 case PHOTOMETRIC_SEPARATED:
321 case PHOTOMETRIC_PALETTE:
322 case PHOTOMETRIC_MINISBLACK:
323 case PHOTOMETRIC_MINISWHITE:
324 break;
325 case PHOTOMETRIC_LOGL:
326 case PHOTOMETRIC_LOGLUV:
327 if (compression != COMPRESSION_SGILOG &&
328 compression != COMPRESSION_SGILOG24) {
329 TIFFError(filename,
330 "Can not handle %s data with compression other than SGILog",
331 (photometric == PHOTOMETRIC_LOGL) ?
332 "LogL" : "LogLuv"
333 );
334 return (0);
335 }
336 /* rely on library to convert to RGB/greyscale */
337 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
338 photometric = (photometric == PHOTOMETRIC_LOGL) ?
339 PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB;
340 bitspersample = 8;
341 break;
342 case PHOTOMETRIC_CIELAB:
343 /* fall thru... */
344 default:
345 TIFFError(filename,
346 "Can not handle image with PhotometricInterpretation=%d",
347 photometric);
348 return (0);
349 }
350 switch (bitspersample) {
351 case 1: case 2:
352 case 4: case 8:
353 break;
354 default:
355 TIFFError(filename, "Can not handle %d-bit/sample image",
356 bitspersample);
357 return (0);
358 }
359 if (planarconfiguration == PLANARCONFIG_SEPARATE && extrasamples > 0)
360 TIFFWarning(filename, "Ignoring extra samples");
361 return (1);
362}
363
364#define PS_UNIT_SIZE 72.0F
365#define PSUNITS(npix,res) ((npix) * (PS_UNIT_SIZE / (res)))
366
367static char RGBcolorimage[] = "\
368/bwproc {\n\
369 rgbproc\n\
370 dup length 3 idiv string 0 3 0\n\
371 5 -1 roll {\n\
372 add 2 1 roll 1 sub dup 0 eq {\n\
373 pop 3 idiv\n\
374 3 -1 roll\n\
375 dup 4 -1 roll\n\
376 dup 3 1 roll\n\
377 5 -1 roll put\n\
378 1 add 3 0\n\
379 } { 2 1 roll } ifelse\n\
380 } forall\n\
381 pop pop pop\n\
382} def\n\
383/colorimage where {pop} {\n\
384 /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def\n\
385} ifelse\n\
386";
387
388/*
389 * Adobe Photoshop requires a comment line of the form:
390 *
391 * %ImageData: <cols> <rows> <depth> <main channels> <pad channels>
392 * <block size> <1 for binary|2 for hex> "data start"
393 *
394 * It is claimed to be part of some future revision of the EPS spec.
395 */
396static void
397PhotoshopBanner(FILE* fd, uint32 w, uint32 h, int bs, int nc, char* startline)
398{
399 fprintf(fd, "%%ImageData: %ld %ld %d %d 0 %d 2 \"",
400 (long) w, (long) h, bitspersample, nc, bs);
401 fprintf(fd, startline, nc);
402 fprintf(fd, "\"\n");
403}
404
405/*
406 * pw : image width in pixels
407 * ph : image height in pixels
408 * pprw : image width in PS units (72 dpi)
409 * pprh : image height in PS units (72 dpi)
410 */
411static void
412setupPageState(TIFF* tif, uint32* pw, uint32* ph, double* pprw, double* pprh)
413{
414 float xres = 0.0F, yres = 0.0F;
415
416 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, pw);
417 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ph);
418 if (res_unit == 0)
419 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
420 /*
421 * Calculate printable area.
422 */
423 if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)
424 || fabs(xres) < 0.0000001)
425 xres = PS_UNIT_SIZE;
426 if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)
427 || fabs(yres) < 0.0000001)
428 yres = PS_UNIT_SIZE;
429 switch (res_unit) {
430 case RESUNIT_CENTIMETER:
431 xres *= 2.54F, yres *= 2.54F;
432 break;
433 case RESUNIT_INCH:
434 break;
435 case RESUNIT_NONE:
436 default:
437 xres *= PS_UNIT_SIZE, yres *= PS_UNIT_SIZE;
438 break;
439 }
440 *pprh = PSUNITS(*ph, yres);
441 *pprw = PSUNITS(*pw, xres);
442}
443
444static int
445isCCITTCompression(TIFF* tif)
446{
447 uint16 compress;
448 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
449 return (compress == COMPRESSION_CCITTFAX3 ||
450 compress == COMPRESSION_CCITTFAX4 ||
451 compress == COMPRESSION_CCITTRLE ||
452 compress == COMPRESSION_CCITTRLEW);
453}
454
455static tsize_t tf_bytesperrow;
456static tsize_t ps_bytesperrow;
457static tsize_t tf_rowsperstrip;
458static tsize_t tf_numberstrips;
459static char *hex = "0123456789abcdef";
460
461/*
462 * imagewidth & imageheight are 1/72 inches
463 * pagewidth & pageheight are inches
464 */
465int
466PlaceImage(FILE *fp, double pagewidth, double pageheight,
467 double imagewidth, double imageheight, int splitpage,
468 double lm, double bm, int cnt)
469{
470 double xtran = 0;
471 double ytran = 0;
472 double xscale = 1;
473 double yscale = 1;
474 double left_offset = lm * PS_UNIT_SIZE;
475 double bottom_offset = bm * PS_UNIT_SIZE;
476 double subimageheight;
477 double splitheight;
478 double overlap;
479
480 pagewidth *= PS_UNIT_SIZE;
481 pageheight *= PS_UNIT_SIZE;
482
483 if (maxPageHeight==0)
484 splitheight = 0;
485 else
486 splitheight = maxPageHeight * PS_UNIT_SIZE;
487 overlap = splitOverlap * PS_UNIT_SIZE;
488
489 /*
490 * WIDTH:
491 * if too wide, scrunch to fit
492 * else leave it alone
493 */
494 if (imagewidth <= pagewidth) {
495 xscale = imagewidth;
496 } else {
497 xscale = pagewidth;
498 }
499
500 /* HEIGHT:
501 * if too long, scrunch to fit
502 * if too short, move to top of page
503 */
504 if (imageheight <= pageheight) {
505 yscale = imageheight;
506 ytran = pageheight - imageheight;
507 } else if (imageheight > pageheight &&
508 (splitheight == 0 || imageheight <= splitheight)) {
509 yscale = pageheight;
510 } else /* imageheight > splitheight */ {
511 subimageheight = imageheight - (pageheight-overlap)*splitpage;
512 if (subimageheight <= pageheight) {
513 yscale = imageheight;
514 ytran = pageheight - subimageheight;
515 splitpage = 0;
516 } else if ( subimageheight > pageheight && subimageheight <= splitheight) {
517 yscale = imageheight * pageheight / subimageheight;
518 ytran = 0;
519 splitpage = 0;
520 } else /* sumimageheight > splitheight */ {
521 yscale = imageheight;
522 ytran = pageheight - subimageheight;
523 splitpage++;
524 }
525 }
526
527 bottom_offset += ytran / (cnt?2:1);
528 if (cnt)
529 left_offset += xtran / 2;
530 fprintf(fp, "%f %f translate\n", left_offset, bottom_offset);
531 fprintf(fp, "%f %f scale\n", xscale, yscale);
532 if (rotate)
533 fputs ("1 1 translate 180 rotate\n", fp);
534
535 return splitpage;
536}
537
538
539/* returns the sequence number of the page processed */
540int
541TIFF2PS(FILE* fd, TIFF* tif,
542 double pw, double ph, double lm, double bm, int cnt)
543{
544 uint32 w, h;
545 float ox, oy;
546 double prw, prh;
547 double scale = 1.0;
548 uint32 subfiletype;
549 uint16* sampleinfo;
550 static int npages = 0;
551 int split;
552
553 if (!TIFFGetField(tif, TIFFTAG_XPOSITION, &ox))
554 ox = 0;
555 if (!TIFFGetField(tif, TIFFTAG_YPOSITION, &oy))
556 oy = 0;
557 setupPageState(tif, &w, &h, &prw, &prh);
558
559 do {
560 tf_numberstrips = TIFFNumberOfStrips(tif);
561 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP,
562 &tf_rowsperstrip);
563 setupPageState(tif, &w, &h, &prw, &prh);
564 if (!npages)
565 PSHead(fd, tif, w, h, prw, prh, ox, oy);
566 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE,
567 &bitspersample);
568 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL,
569 &samplesperpixel);
570 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG,
571 &planarconfiguration);
572 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
573 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
574 &extrasamples, &sampleinfo);
575 alpha = (extrasamples == 1 &&
576 sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
577 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
578 switch (samplesperpixel - extrasamples) {
579 case 1:
580 if (isCCITTCompression(tif))
581 photometric = PHOTOMETRIC_MINISWHITE;
582 else
583 photometric = PHOTOMETRIC_MINISBLACK;
584 break;
585 case 3:
586 photometric = PHOTOMETRIC_RGB;
587 break;
588 case 4:
589 photometric = PHOTOMETRIC_SEPARATED;
590 break;
591 }
592 }
593 if (checkImage(tif)) {
594 tf_bytesperrow = TIFFScanlineSize(tif);
595 npages++;
596 fprintf(fd, "%%%%Page: %d %d\n", npages, npages);
597 if (!generateEPSF && ( level2 || level3 )) {
598 double psw, psh;
599 if (pw != 0.0) {
600 psw = pw * PS_UNIT_SIZE;
601 if (res_unit == RESUNIT_CENTIMETER)
602 psw *= 2.54F;
603 } else
604 psw=rotate ? prh:prw;
605 if (ph != 0.0) {
606 psh = ph * PS_UNIT_SIZE;
607 if (res_unit == RESUNIT_CENTIMETER)
608 psh *= 2.54F;
609 } else
610 psh=rotate ? prw:prh;
611 fprintf(fd,
612 "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
613 psw, psh);
614 fputs(
615 "<<\n /Policies <<\n /PageSize 3\n >>\n>> setpagedevice\n",
616 fd);
617 }
618 fprintf(fd, "gsave\n");
619 fprintf(fd, "100 dict begin\n");
620 if (pw != 0 || ph != 0) {
621 double psw = pw, psh = ph;
622 if (!psw)
623 psw = prw;
624 if (!psh)
625 psh = prh;
626 if (maxPageHeight) { /* used -H option */
627 split = PlaceImage(fd,psw,psh,prw,prh,
628 0,lm,bm,cnt);
629 while( split ) {
630 PSpage(fd, tif, w, h);
631 fprintf(fd, "end\n");
632 fprintf(fd, "grestore\n");
633 fprintf(fd, "showpage\n");
634 npages++;
635 fprintf(fd, "%%%%Page: %d %d\n",
636 npages, npages);
637 fprintf(fd, "gsave\n");
638 fprintf(fd, "100 dict begin\n");
639 split = PlaceImage(fd,psw,psh,prw,prh,
640 split,lm,bm,cnt);
641 }
642 } else {
643 double left_offset = lm * PS_UNIT_SIZE;
644 double bottom_offset = bm * PS_UNIT_SIZE;
645 psw *= PS_UNIT_SIZE;
646 psh *= PS_UNIT_SIZE;
647
648 /* NB: maintain image aspect ratio */
649 scale = psw/prw < psh/prh ?
650 psw/prw : psh/prh;
651 if (scale > 1.0)
652 scale = 1.0;
653 if (cnt) {
654 bottom_offset +=
655 (psh - prh * scale) / 2;
656 left_offset +=
657 (psw - prw * scale) / 2;
658 }
659 fprintf(fd, "%f %f translate\n",
660 left_offset, bottom_offset);
661 fprintf(fd, "%f %f scale\n",
662 prw * scale, prh * scale);
663 if (rotate)
664 fputs ("1 1 translate 180 rotate\n", fd);
665 }
666 } else {
667 fprintf(fd, "%f %f scale\n", prw, prh);
668 if (rotate)
669 fputs ("1 1 translate 180 rotate\n", fd);
670 }
671 PSpage(fd, tif, w, h);
672 fprintf(fd, "end\n");
673 fprintf(fd, "grestore\n");
674 fprintf(fd, "showpage\n");
675 }
676 if (generateEPSF)
677 break;
678 TIFFGetFieldDefaulted(tif, TIFFTAG_SUBFILETYPE, &subfiletype);
679 } while (((subfiletype & FILETYPE_PAGE) || printAll) &&
680 TIFFReadDirectory(tif));
681
682 return(npages);
683}
684
685
686static char DuplexPreamble[] = "\
687%%BeginFeature: *Duplex True\n\
688systemdict begin\n\
689 /languagelevel where { pop languagelevel } { 1 } ifelse\n\
690 2 ge { 1 dict dup /Duplex true put setpagedevice }\n\
691 { statusdict /setduplex known { statusdict begin setduplex true end } if\n\
692 } ifelse\n\
693end\n\
694%%EndFeature\n\
695";
696
697static char TumblePreamble[] = "\
698%%BeginFeature: *Tumble True\n\
699systemdict begin\n\
700 /languagelevel where { pop languagelevel } { 1 } ifelse\n\
701 2 ge { 1 dict dup /Tumble true put setpagedevice }\n\
702 { statusdict /settumble known { statusdict begin true settumble end } if\n\
703 } ifelse\n\
704end\n\
705%%EndFeature\n\
706";
707
708static char AvoidDeadZonePreamble[] = "\
709gsave newpath clippath pathbbox grestore\n\
710 4 2 roll 2 copy translate\n\
711 exch 3 1 roll sub 3 1 roll sub exch\n\
712 currentpagedevice /PageSize get aload pop\n\
713 exch 3 1 roll div 3 1 roll div abs exch abs\n\
714 2 copy gt { exch } if pop\n\
715 dup 1 lt { dup scale } { pop } ifelse\n\
716";
717
718void
719PSHead(FILE *fd, TIFF *tif, uint32 w, uint32 h,
720 double pw, double ph, double ox, double oy)
721{
722 time_t t;
723
724 (void) tif; (void) w; (void) h;
725 t = time(0);
726 fprintf(fd, "%%!PS-Adobe-3.0%s\n", generateEPSF ? " EPSF-3.0" : "");
727 fprintf(fd, "%%%%Creator: tiff2ps\n");
728 fprintf(fd, "%%%%Title: %s\n", filename);
729 fprintf(fd, "%%%%CreationDate: %s", ctime(&t));
730 fprintf(fd, "%%%%DocumentData: Clean7Bit\n");
731 fprintf(fd, "%%%%Origin: %ld %ld\n", (long) ox, (long) oy);
732 /* NB: should use PageBoundingBox */
733 fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
734 (long) ceil(pw), (long) ceil(ph));
735 fprintf(fd, "%%%%LanguageLevel: %d\n", (level3 ? 3 : (level2 ? 2 : 1)));
736 fprintf(fd, "%%%%Pages: (atend)\n");
737 fprintf(fd, "%%%%EndComments\n");
738 fprintf(fd, "%%%%BeginSetup\n");
739 if (PSduplex)
740 fprintf(fd, "%s", DuplexPreamble);
741 if (PStumble)
742 fprintf(fd, "%s", TumblePreamble);
743 if (PSavoiddeadzone && (level2 || level3))
744 fprintf(fd, "%s", AvoidDeadZonePreamble);
745 fprintf(fd, "%%%%EndSetup\n");
746}
747
748void
749PSTail(FILE *fd, int npages)
750{
751 fprintf(fd, "%%%%Trailer\n");
752 fprintf(fd, "%%%%Pages: %d\n", npages);
753 fprintf(fd, "%%%%EOF\n");
754}
755
756static int
757checkcmap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b)
758{
759 (void) tif;
760 while (n-- > 0)
761 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
762 return (16);
763 TIFFWarning(filename, "Assuming 8-bit colormap");
764 return (8);
765}
766
767static void
768PS_Lvl2colorspace(FILE* fd, TIFF* tif)
769{
770 uint16 *rmap, *gmap, *bmap;
771 int i, num_colors;
772 const char * colorspace_p;
773
774 switch ( photometric )
775 {
776 case PHOTOMETRIC_SEPARATED:
777 colorspace_p = "CMYK";
778 break;
779
780 case PHOTOMETRIC_RGB:
781 colorspace_p = "RGB";
782 break;
783
784 default:
785 colorspace_p = "Gray";
786 }
787
788 /*
789 * Set up PostScript Level 2 colorspace according to
790 * section 4.8 in the PostScript refenence manual.
791 */
792 fputs("% PostScript Level 2 only.\n", fd);
793 if (photometric != PHOTOMETRIC_PALETTE) {
794 if (photometric == PHOTOMETRIC_YCBCR) {
795 /* MORE CODE HERE */
796 }
797 fprintf(fd, "/Device%s setcolorspace\n", colorspace_p );
798 return;
799 }
800
801 /*
802 * Set up an indexed/palette colorspace
803 */
804 num_colors = (1 << bitspersample);
805 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
806 TIFFError(filename,
807 "Palette image w/o \"Colormap\" tag");
808 return;
809 }
810 if (checkcmap(tif, num_colors, rmap, gmap, bmap) == 16) {
811 /*
812 * Convert colormap to 8-bits values.
813 */
814#define CVT(x) (((x) * 255) / ((1L<<16)-1))
815 for (i = 0; i < num_colors; i++) {
816 rmap[i] = CVT(rmap[i]);
817 gmap[i] = CVT(gmap[i]);
818 bmap[i] = CVT(bmap[i]);
819 }
820#undef CVT
821 }
822 fprintf(fd, "[ /Indexed /DeviceRGB %d", num_colors - 1);
823 if (ascii85) {
824 Ascii85Init();
825 fputs("\n<~", fd);
826 ascii85breaklen -= 2;
827 } else
828 fputs(" <", fd);
829 for (i = 0; i < num_colors; i++) {
830 if (ascii85) {
831 Ascii85Put((unsigned char)rmap[i], fd);
832 Ascii85Put((unsigned char)gmap[i], fd);
833 Ascii85Put((unsigned char)bmap[i], fd);
834 } else {
835 fputs((i % 8) ? " " : "\n ", fd);
836 fprintf(fd, "%02x%02x%02x",
837 rmap[i], gmap[i], bmap[i]);
838 }
839 }
840 if (ascii85)
841 Ascii85Flush(fd);
842 else
843 fputs(">\n", fd);
844 fputs("] setcolorspace\n", fd);
845}
846
847static int
848PS_Lvl2ImageDict(FILE* fd, TIFF* tif, uint32 w, uint32 h)
849{
850 int use_rawdata;
851 uint32 tile_width, tile_height;
852 uint16 predictor, minsamplevalue, maxsamplevalue;
853 int repeat_count;
854 char im_h[64], im_x[64], im_y[64];
855 char * imageOp = "image";
856
857 if ( useImagemask && (bitspersample == 1) )
858 imageOp = "imagemask";
859
860 (void)strcpy(im_x, "0");
861 (void)sprintf(im_y, "%lu", (long) h);
862 (void)sprintf(im_h, "%lu", (long) h);
863 tile_width = w;
864 tile_height = h;
865 if (TIFFIsTiled(tif)) {
866 repeat_count = TIFFNumberOfTiles(tif);
867 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
868 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
869 if (tile_width > w || tile_height > h ||
870 (w % tile_width) != 0 || (h % tile_height != 0)) {
871 /*
872 * The tiles does not fit image width and height.
873 * Set up a clip rectangle for the image unit square.
874 */
875 fputs("0 0 1 1 rectclip\n", fd);
876 }
877 if (tile_width < w) {
878 fputs("/im_x 0 def\n", fd);
879 (void)strcpy(im_x, "im_x neg");
880 }
881 if (tile_height < h) {
882 fputs("/im_y 0 def\n", fd);
883 (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
884 }
885 } else {
886 repeat_count = tf_numberstrips;
887 tile_height = tf_rowsperstrip;
888 if (tile_height > h)
889 tile_height = h;
890 if (repeat_count > 1) {
891 fputs("/im_y 0 def\n", fd);
892 fprintf(fd, "/im_h %lu def\n",
893 (unsigned long) tile_height);
894 (void)strcpy(im_h, "im_h");
895 (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
896 }
897 }
898
899 /*
900 * Output start of exec block
901 */
902 fputs("{ % exec\n", fd);
903
904 if (repeat_count > 1)
905 fprintf(fd, "%d { %% repeat\n", repeat_count);
906
907 /*
908 * Output filter options and image dictionary.
909 */
910 if (ascii85)
911 fputs(" /im_stream currentfile /ASCII85Decode filter def\n",
912 fd);
913 fputs(" <<\n", fd);
914 fputs(" /ImageType 1\n", fd);
915 fprintf(fd, " /Width %lu\n", (unsigned long) tile_width);
916 /*
917 * Workaround for some software that may crash when last strip
918 * of image contains fewer number of scanlines than specified
919 * by the `/Height' variable. So for stripped images with multiple
920 * strips we will set `/Height' as `im_h', because one is
921 * recalculated for each strip - including the (smaller) final strip.
922 * For tiled images and images with only one strip `/Height' will
923 * contain number of scanlines in tile (or image height in case of
924 * one-stripped image).
925 */
926 if (TIFFIsTiled(tif) || tf_numberstrips == 1)
927 fprintf(fd, " /Height %lu\n", (unsigned long) tile_height);
928 else
929 fprintf(fd, " /Height im_h\n");
930
931 if (planarconfiguration == PLANARCONFIG_SEPARATE && samplesperpixel > 1)
932 fputs(" /MultipleDataSources true\n", fd);
933 fprintf(fd, " /ImageMatrix [ %lu 0 0 %ld %s %s ]\n",
934 (unsigned long) w, - (long)h, im_x, im_y);
935 fprintf(fd, " /BitsPerComponent %d\n", bitspersample);
936 fprintf(fd, " /Interpolate %s\n", interpolate ? "true" : "false");
937
938 switch (samplesperpixel - extrasamples) {
939 case 1:
940 switch (photometric) {
941 case PHOTOMETRIC_MINISBLACK:
942 fputs(" /Decode [0 1]\n", fd);
943 break;
944 case PHOTOMETRIC_MINISWHITE:
945 switch (compression) {
946 case COMPRESSION_CCITTRLE:
947 case COMPRESSION_CCITTRLEW:
948 case COMPRESSION_CCITTFAX3:
949 case COMPRESSION_CCITTFAX4:
950 /*
951 * Manage inverting with /Blackis1 flag
952 * since there migth be uncompressed parts
953 */
954 fputs(" /Decode [0 1]\n", fd);
955 break;
956 default:
957 /*
958 * ERROR...
959 */
960 fputs(" /Decode [1 0]\n", fd);
961 break;
962 }
963 break;
964 case PHOTOMETRIC_PALETTE:
965 TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE,
966 &minsamplevalue);
967 TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE,
968 &maxsamplevalue);
969 fprintf(fd, " /Decode [%u %u]\n",
970 minsamplevalue, maxsamplevalue);
971 break;
972 default:
973 /*
974 * ERROR ?
975 */
976 fputs(" /Decode [0 1]\n", fd);
977 break;
978 }
979 break;
980 case 3:
981 switch (photometric) {
982 case PHOTOMETRIC_RGB:
983 fputs(" /Decode [0 1 0 1 0 1]\n", fd);
984 break;
985 case PHOTOMETRIC_MINISWHITE:
986 case PHOTOMETRIC_MINISBLACK:
987 default:
988 /*
989 * ERROR??
990 */
991 fputs(" /Decode [0 1 0 1 0 1]\n", fd);
992 break;
993 }
994 break;
995 case 4:
996 /*
997 * ERROR??
998 */
999 fputs(" /Decode [0 1 0 1 0 1 0 1]\n", fd);
1000 break;
1001 }
1002 fputs(" /DataSource", fd);
1003 if (planarconfiguration == PLANARCONFIG_SEPARATE &&
1004 samplesperpixel > 1)
1005 fputs(" [", fd);
1006 if (ascii85)
1007 fputs(" im_stream", fd);
1008 else
1009 fputs(" currentfile /ASCIIHexDecode filter", fd);
1010
1011 use_rawdata = TRUE;
1012 switch (compression) {
1013 case COMPRESSION_NONE: /* 1: uncompressed */
1014 break;
1015 case COMPRESSION_CCITTRLE: /* 2: CCITT modified Huffman RLE */
1016 case COMPRESSION_CCITTRLEW: /* 32771: #1 w/ word alignment */
1017 case COMPRESSION_CCITTFAX3: /* 3: CCITT Group 3 fax encoding */
1018 case COMPRESSION_CCITTFAX4: /* 4: CCITT Group 4 fax encoding */
1019 fputs("\n\t<<\n", fd);
1020 if (compression == COMPRESSION_CCITTFAX3) {
1021 uint32 g3_options;
1022
1023 fputs("\t /EndOfLine true\n", fd);
1024 fputs("\t /EndOfBlock false\n", fd);
1025 if (!TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS,
1026 &g3_options))
1027 g3_options = 0;
1028 if (g3_options & GROUP3OPT_2DENCODING)
1029 fprintf(fd, "\t /K %s\n", im_h);
1030 if (g3_options & GROUP3OPT_UNCOMPRESSED)
1031 fputs("\t /Uncompressed true\n", fd);
1032 if (g3_options & GROUP3OPT_FILLBITS)
1033 fputs("\t /EncodedByteAlign true\n", fd);
1034 }
1035 if (compression == COMPRESSION_CCITTFAX4) {
1036 uint32 g4_options;
1037
1038 fputs("\t /K -1\n", fd);
1039 TIFFGetFieldDefaulted(tif, TIFFTAG_GROUP4OPTIONS,
1040 &g4_options);
1041 if (g4_options & GROUP4OPT_UNCOMPRESSED)
1042 fputs("\t /Uncompressed true\n", fd);
1043 }
1044 if (!(tile_width == w && w == 1728U))
1045 fprintf(fd, "\t /Columns %lu\n",
1046 (unsigned long) tile_width);
1047 fprintf(fd, "\t /Rows %s\n", im_h);
1048 if (compression == COMPRESSION_CCITTRLE ||
1049 compression == COMPRESSION_CCITTRLEW) {
1050 fputs("\t /EncodedByteAlign true\n", fd);
1051 fputs("\t /EndOfBlock false\n", fd);
1052 }
1053 if (photometric == PHOTOMETRIC_MINISBLACK)
1054 fputs("\t /BlackIs1 true\n", fd);
1055 fprintf(fd, "\t>> /CCITTFaxDecode filter");
1056 break;
1057 case COMPRESSION_LZW: /* 5: Lempel-Ziv & Welch */
1058 TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
1059 if (predictor == 2) {
1060 fputs("\n\t<<\n", fd);
1061 fprintf(fd, "\t /Predictor %u\n", predictor);
1062 fprintf(fd, "\t /Columns %lu\n",
1063 (unsigned long) tile_width);
1064 fprintf(fd, "\t /Colors %u\n", samplesperpixel);
1065 fprintf(fd, "\t /BitsPerComponent %u\n",
1066 bitspersample);
1067 fputs("\t>>", fd);
1068 }
1069 fputs(" /LZWDecode filter", fd);
1070 break;
1071 case COMPRESSION_DEFLATE: /* 5: ZIP */
1072 case COMPRESSION_ADOBE_DEFLATE:
1073 if ( level3 ) {
1074 TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
1075 if (predictor > 1) {
1076 fprintf(fd, "\t %% PostScript Level 3 only.");
1077 fputs("\n\t<<\n", fd);
1078 fprintf(fd, "\t /Predictor %u\n", predictor);
1079 fprintf(fd, "\t /Columns %lu\n",
1080 (unsigned long) tile_width);
1081 fprintf(fd, "\t /Colors %u\n", samplesperpixel);
1082 fprintf(fd, "\t /BitsPerComponent %u\n",
1083 bitspersample);
1084 fputs("\t>>", fd);
1085 }
1086 fputs(" /FlateDecode filter", fd);
1087 } else {
1088 use_rawdata = FALSE ;
1089 }
1090 break;
1091 case COMPRESSION_PACKBITS: /* 32773: Macintosh RLE */
1092 fputs(" /RunLengthDecode filter", fd);
1093 use_rawdata = TRUE;
1094 break;
1095 case COMPRESSION_OJPEG: /* 6: !6.0 JPEG */
1096 case COMPRESSION_JPEG: /* 7: %JPEG DCT compression */
1097#ifdef notdef
1098 /*
1099 * Code not tested yet
1100 */
1101 fputs(" /DCTDecode filter", fd);
1102 use_rawdata = TRUE;
1103#else
1104 use_rawdata = FALSE;
1105#endif
1106 break;
1107 case COMPRESSION_NEXT: /* 32766: NeXT 2-bit RLE */
1108 case COMPRESSION_THUNDERSCAN: /* 32809: ThunderScan RLE */
1109 case COMPRESSION_PIXARFILM: /* 32908: Pixar companded 10bit LZW */
1110 case COMPRESSION_JBIG: /* 34661: ISO JBIG */
1111 use_rawdata = FALSE;
1112 break;
1113 case COMPRESSION_SGILOG: /* 34676: SGI LogL or LogLuv */
1114 case COMPRESSION_SGILOG24: /* 34677: SGI 24-bit LogLuv */
1115 use_rawdata = FALSE;
1116 break;
1117 default:
1118 /*
1119 * ERROR...
1120 */
1121 use_rawdata = FALSE;
1122 break;
1123 }
1124 if (planarconfiguration == PLANARCONFIG_SEPARATE &&
1125 samplesperpixel > 1) {
1126 uint16 i;
1127
1128 /*
1129 * NOTE: This code does not work yet...
1130 */
1131 for (i = 1; i < samplesperpixel; i++)
1132 fputs(" dup", fd);
1133 fputs(" ]", fd);
1134 }
1135
1136 fprintf( fd, "\n >> %s\n", imageOp );
1137 if (ascii85)
1138 fputs(" im_stream status { im_stream flushfile } if\n", fd);
1139 if (repeat_count > 1) {
1140 if (tile_width < w) {
1141 fprintf(fd, " /im_x im_x %lu add def\n",
1142 (unsigned long) tile_width);
1143 if (tile_height < h) {
1144 fprintf(fd, " im_x %lu ge {\n",
1145 (unsigned long) w);
1146 fputs(" /im_x 0 def\n", fd);
1147 fprintf(fd, " /im_y im_y %lu add def\n",
1148 (unsigned long) tile_height);
1149 fputs(" } if\n", fd);
1150 }
1151 }
1152 if (tile_height < h) {
1153 if (tile_width >= w) {
1154 fprintf(fd, " /im_y im_y %lu add def\n",
1155 (unsigned long) tile_height);
1156 if (!TIFFIsTiled(tif)) {
1157 fprintf(fd, " /im_h %lu im_y sub",
1158 (unsigned long) h);
1159 fprintf(fd, " dup %lu gt { pop",
1160 (unsigned long) tile_height);
1161 fprintf(fd, " %lu } if def\n",
1162 (unsigned long) tile_height);
1163 }
1164 }
1165 }
1166 fputs("} repeat\n", fd);
1167 }
1168 /*
1169 * End of exec function
1170 */
1171 fputs("}\n", fd);
1172
1173 return(use_rawdata);
1174}
1175
1176#define MAXLINE 36
1177
1178int
1179PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1180{
1181 uint16 fillorder;
1182 int use_rawdata, tiled_image, breaklen = MAXLINE;
1183 uint32 chunk_no, num_chunks, *bc;
1184 unsigned char *buf_data, *cp;
1185 tsize_t chunk_size, byte_count;
1186
1187#if defined( EXP_ASCII85ENCODER )
1188 int ascii85_l; /* Length, in bytes, of ascii85_p[] data */
1189 uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */
1190#endif
1191
1192 PS_Lvl2colorspace(fd, tif);
1193 use_rawdata = PS_Lvl2ImageDict(fd, tif, w, h);
1194
1195/* See http://bugzilla.remotesensing.org/show_bug.cgi?id=80 */
1196#ifdef ENABLE_BROKEN_BEGINENDDATA
1197 fputs("%%BeginData:\n", fd);
1198#endif
1199 fputs("exec\n", fd);
1200
1201 tiled_image = TIFFIsTiled(tif);
1202 if (tiled_image) {
1203 num_chunks = TIFFNumberOfTiles(tif);
1204 TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc);
1205 } else {
1206 num_chunks = TIFFNumberOfStrips(tif);
1207 TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
1208 }
1209
1210 if (use_rawdata) {
1211 chunk_size = (tsize_t) bc[0];
1212 for (chunk_no = 1; chunk_no < num_chunks; chunk_no++)
1213 if ((tsize_t) bc[chunk_no] > chunk_size)
1214 chunk_size = (tsize_t) bc[chunk_no];
1215 } else {
1216 if (tiled_image)
1217 chunk_size = TIFFTileSize(tif);
1218 else
1219 chunk_size = TIFFStripSize(tif);
1220 }
1221 buf_data = (unsigned char *)_TIFFmalloc(chunk_size);
1222 if (!buf_data) {
1223 TIFFError(filename, "Can't alloc %u bytes for %s.",
1224 chunk_size, tiled_image ? "tiles" : "strips");
1225 return(FALSE);
1226 }
1227
1228#if defined( EXP_ASCII85ENCODER )
1229 if ( ascii85 ) {
1230 /*
1231 * Allocate a buffer to hold the ASCII85 encoded data. Note
1232 * that it is allocated with sufficient room to hold the
1233 * encoded data (5*chunk_size/4) plus the EOD marker (+8)
1234 * and formatting line breaks. The line breaks are more
1235 * than taken care of by using 6*chunk_size/4 rather than
1236 * 5*chunk_size/4.
1237 */
1238
1239 ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 );
1240
1241 if ( !ascii85_p ) {
1242 _TIFFfree( buf_data );
1243
1244 TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
1245 return ( FALSE );
1246 }
1247 }
1248#endif
1249
1250 TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
1251 for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) {
1252 if (ascii85)
1253 Ascii85Init();
1254 else
1255 breaklen = MAXLINE;
1256 if (use_rawdata) {
1257 if (tiled_image)
1258 byte_count = TIFFReadRawTile(tif, chunk_no,
1259 buf_data, chunk_size);
1260 else
1261 byte_count = TIFFReadRawStrip(tif, chunk_no,
1262 buf_data, chunk_size);
1263 if (fillorder == FILLORDER_LSB2MSB)
1264 TIFFReverseBits(buf_data, byte_count);
1265 } else {
1266 if (tiled_image)
1267 byte_count = TIFFReadEncodedTile(tif,
1268 chunk_no, buf_data,
1269 chunk_size);
1270 else
1271 byte_count = TIFFReadEncodedStrip(tif,
1272 chunk_no, buf_data,
1273 chunk_size);
1274 }
1275 if (byte_count < 0) {
1276 TIFFError(filename, "Can't read %s %d.",
1277 tiled_image ? "tile" : "strip", chunk_no);
1278 if (ascii85)
1279 Ascii85Put('\0', fd);
1280 }
1281 /*
1282 * For images with alpha, matte against a white background;
1283 * i.e. Cback * (1 - Aimage) where Cback = 1. We will fill the
1284 * lower part of the buffer with the modified values.
1285 *
1286 * XXX: needs better solution
1287 */
1288 if (alpha) {
1289 int adjust, i, j = 0;
1290 int ncomps = samplesperpixel - extrasamples;
1291 for (i = 0; i < byte_count; i+=samplesperpixel) {
1292 adjust = 255 - buf_data[i + ncomps];
1293 switch (ncomps) {
1294 case 1:
1295 buf_data[j++] = buf_data[i] + adjust;
1296 break;
1297 case 2:
1298 buf_data[j++] = buf_data[i] + adjust;
1299 buf_data[j++] = buf_data[i+1] + adjust;
1300 break;
1301 case 3:
1302 buf_data[j++] = buf_data[i] + adjust;
1303 buf_data[j++] = buf_data[i+1] + adjust;
1304 buf_data[j++] = buf_data[i+2] + adjust;
1305 break;
1306 }
1307 }
1308 byte_count -= j;
1309 }
1310
1311 if (ascii85) {
1312#if defined( EXP_ASCII85ENCODER )
1313 ascii85_l = Ascii85EncodeBlock(ascii85_p, 1, buf_data, byte_count );
1314
1315 if ( ascii85_l > 0 )
1316 fwrite( ascii85_p, ascii85_l, 1, fd );
1317#else
1318 for (cp = buf_data; byte_count > 0; byte_count--)
1319 Ascii85Put(*cp++, fd);
1320#endif
1321 }
1322 else
1323 {
1324 for (cp = buf_data; byte_count > 0; byte_count--) {
1325 putc(hex[((*cp)>>4)&0xf], fd);
1326 putc(hex[(*cp)&0xf], fd);
1327 cp++;
1328
1329 if (--breaklen <= 0) {
1330 putc('\n', fd);
1331 breaklen = MAXLINE;
1332 }
1333 }
1334 }
1335
1336 if ( !ascii85 ) {
1337 if ( level2 || level3 )
1338 putc( '>', fd );
1339 putc('\n', fd);
1340 }
1341#if !defined( EXP_ASCII85ENCODER )
1342 else
1343 Ascii85Flush(fd);
1344#endif
1345 }
1346
1347#if defined( EXP_ASCII85ENCODER )
1348 if ( ascii85_p )
1349 _TIFFfree( ascii85_p );
1350#endif
1351
1352 _TIFFfree(buf_data);
1353#ifdef ENABLE_BROKEN_BEGINENDDATA
1354 fputs("%%EndData\n", fd);
1355#endif
1356 return(TRUE);
1357}
1358
1359void
1360PSpage(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1361{
1362 char * imageOp = "image";
1363
1364 if ( useImagemask && (bitspersample == 1) )
1365 imageOp = "imagemask";
1366
1367 if ((level2 || level3) && PS_Lvl2page(fd, tif, w, h))
1368 return;
1369 ps_bytesperrow = tf_bytesperrow - (extrasamples * bitspersample / 8)*w;
1370 switch (photometric) {
1371 case PHOTOMETRIC_RGB:
1372 if (planarconfiguration == PLANARCONFIG_CONTIG) {
1373 fprintf(fd, "%s", RGBcolorimage);
1374 PSColorContigPreamble(fd, w, h, 3);
1375 PSDataColorContig(fd, tif, w, h, 3);
1376 } else {
1377 PSColorSeparatePreamble(fd, w, h, 3);
1378 PSDataColorSeparate(fd, tif, w, h, 3);
1379 }
1380 break;
1381 case PHOTOMETRIC_SEPARATED:
1382 /* XXX should emit CMYKcolorimage */
1383 if (planarconfiguration == PLANARCONFIG_CONTIG) {
1384 PSColorContigPreamble(fd, w, h, 4);
1385 PSDataColorContig(fd, tif, w, h, 4);
1386 } else {
1387 PSColorSeparatePreamble(fd, w, h, 4);
1388 PSDataColorSeparate(fd, tif, w, h, 4);
1389 }
1390 break;
1391 case PHOTOMETRIC_PALETTE:
1392 fprintf(fd, "%s", RGBcolorimage);
1393 PhotoshopBanner(fd, w, h, 1, 3, "false 3 colorimage");
1394 fprintf(fd, "/scanLine %ld string def\n",
1395 (long) ps_bytesperrow * 3L);
1396 fprintf(fd, "%lu %lu 8\n",
1397 (unsigned long) w, (unsigned long) h);
1398 fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
1399 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1400 fprintf(fd, "{currentfile scanLine readhexstring pop} bind\n");
1401 fprintf(fd, "false 3 colorimage\n");
1402 PSDataPalette(fd, tif, w, h);
1403 break;
1404 case PHOTOMETRIC_MINISBLACK:
1405 case PHOTOMETRIC_MINISWHITE:
1406 PhotoshopBanner(fd, w, h, 1, 1, imageOp);
1407 fprintf(fd, "/scanLine %ld string def\n",
1408 (long) ps_bytesperrow);
1409 fprintf(fd, "%lu %lu %d\n",
1410 (unsigned long) w, (unsigned long) h, bitspersample);
1411 fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
1412 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1413 fprintf(fd,
1414 "{currentfile scanLine readhexstring pop} bind\n");
1415 fprintf(fd, "%s\n", imageOp);
1416 PSDataBW(fd, tif, w, h);
1417 break;
1418 }
1419 putc('\n', fd);
1420}
1421
1422void
1423PSColorContigPreamble(FILE* fd, uint32 w, uint32 h, int nc)
1424{
1425 ps_bytesperrow = nc * (tf_bytesperrow / samplesperpixel);
1426 PhotoshopBanner(fd, w, h, 1, nc, "false %d colorimage");
1427 fprintf(fd, "/line %ld string def\n", (long) ps_bytesperrow);
1428 fprintf(fd, "%lu %lu %d\n",
1429 (unsigned long) w, (unsigned long) h, bitspersample);
1430 fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n",
1431 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1432 fprintf(fd, "{currentfile line readhexstring pop} bind\n");
1433 fprintf(fd, "false %d colorimage\n", nc);
1434}
1435
1436void
1437PSColorSeparatePreamble(FILE* fd, uint32 w, uint32 h, int nc)
1438{
1439 int i;
1440
1441 PhotoshopBanner(fd, w, h, ps_bytesperrow, nc, "true %d colorimage");
1442 for (i = 0; i < nc; i++)
1443 fprintf(fd, "/line%d %ld string def\n",
1444 i, (long) ps_bytesperrow);
1445 fprintf(fd, "%lu %lu %d\n",
1446 (unsigned long) w, (unsigned long) h, bitspersample);
1447 fprintf(fd, "[%lu 0 0 -%lu 0 %lu] \n",
1448 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1449 for (i = 0; i < nc; i++)
1450 fprintf(fd, "{currentfile line%d readhexstring pop}bind\n", i);
1451 fprintf(fd, "true %d colorimage\n", nc);
1452}
1453
1454#define DOBREAK(len, howmany, fd) \
1455 if (((len) -= (howmany)) <= 0) { \
1456 putc('\n', fd); \
1457 (len) = MAXLINE-(howmany); \
1458 }
1459#define PUTHEX(c,fd) putc(hex[((c)>>4)&0xf],fd); putc(hex[(c)&0xf],fd)
1460
1461void
1462PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
1463{
1464 uint32 row;
1465 int breaklen = MAXLINE, cc, es = samplesperpixel - nc;
1466 unsigned char *tf_buf;
1467 unsigned char *cp, c;
1468
1469 (void) w;
1470 tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
1471 if (tf_buf == NULL) {
1472 TIFFError(filename, "No space for scanline buffer");
1473 return;
1474 }
1475 for (row = 0; row < h; row++) {
1476 if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
1477 break;
1478 cp = tf_buf;
1479 if (alpha) {
1480 int adjust;
1481 cc = 0;
1482 for (; cc < tf_bytesperrow; cc += samplesperpixel) {
1483 DOBREAK(breaklen, nc, fd);
1484 /*
1485 * For images with alpha, matte against
1486 * a white background; i.e.
1487 * Cback * (1 - Aimage)
1488 * where Cback = 1.
1489 */
1490 adjust = 255 - cp[nc];
1491 switch (nc) {
1492 case 4: c = *cp++ + adjust; PUTHEX(c,fd);
1493 case 3: c = *cp++ + adjust; PUTHEX(c,fd);
1494 case 2: c = *cp++ + adjust; PUTHEX(c,fd);
1495 case 1: c = *cp++ + adjust; PUTHEX(c,fd);
1496 }
1497 cp += es;
1498 }
1499 } else {
1500 cc = 0;
1501 for (; cc < tf_bytesperrow; cc += samplesperpixel) {
1502 DOBREAK(breaklen, nc, fd);
1503 switch (nc) {
1504 case 4: c = *cp++; PUTHEX(c,fd);
1505 case 3: c = *cp++; PUTHEX(c,fd);
1506 case 2: c = *cp++; PUTHEX(c,fd);
1507 case 1: c = *cp++; PUTHEX(c,fd);
1508 }
1509 cp += es;
1510 }
1511 }
1512 }
1513 _TIFFfree((char *) tf_buf);
1514}
1515
1516void
1517PSDataColorSeparate(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
1518{
1519 uint32 row;
1520 int breaklen = MAXLINE, cc;
1521 tsample_t s, maxs;
1522 unsigned char *tf_buf;
1523 unsigned char *cp, c;
1524
1525 (void) w;
1526 tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
1527 if (tf_buf == NULL) {
1528 TIFFError(filename, "No space for scanline buffer");
1529 return;
1530 }
1531 maxs = (samplesperpixel > nc ? nc : samplesperpixel);
1532 for (row = 0; row < h; row++) {
1533 for (s = 0; s < maxs; s++) {
1534 if (TIFFReadScanline(tif, tf_buf, row, s) < 0)
1535 break;
1536 for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
1537 DOBREAK(breaklen, 1, fd);
1538 c = *cp++;
1539 PUTHEX(c,fd);
1540 }
1541 }
1542 }
1543 _TIFFfree((char *) tf_buf);
1544}
1545
1546#define PUTRGBHEX(c,fd) \
1547 PUTHEX(rmap[c],fd); PUTHEX(gmap[c],fd); PUTHEX(bmap[c],fd)
1548
1549void
1550PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1551{
1552 uint16 *rmap, *gmap, *bmap;
1553 uint32 row;
1554 int breaklen = MAXLINE, cc, nc;
1555 unsigned char *tf_buf;
1556 unsigned char *cp, c;
1557
1558 (void) w;
1559 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
1560 TIFFError(filename, "Palette image w/o \"Colormap\" tag");
1561 return;
1562 }
1563 switch (bitspersample) {
1564 case 8: case 4: case 2: case 1:
1565 break;
1566 default:
1567 TIFFError(filename, "Depth %d not supported", bitspersample);
1568 return;
1569 }
1570 nc = 3 * (8 / bitspersample);
1571 tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
1572 if (tf_buf == NULL) {
1573 TIFFError(filename, "No space for scanline buffer");
1574 return;
1575 }
1576 if (checkcmap(tif, 1<<bitspersample, rmap, gmap, bmap) == 16) {
1577 int i;
1578#define CVT(x) ((unsigned short) (((x) * 255) / ((1U<<16)-1)))
1579 for (i = (1<<bitspersample)-1; i >= 0; i--) {
1580 rmap[i] = CVT(rmap[i]);
1581 gmap[i] = CVT(gmap[i]);
1582 bmap[i] = CVT(bmap[i]);
1583 }
1584#undef CVT
1585 }
1586 for (row = 0; row < h; row++) {
1587 if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
1588 break;
1589 for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
1590 DOBREAK(breaklen, nc, fd);
1591 switch (bitspersample) {
1592 case 8:
1593 c = *cp++; PUTRGBHEX(c, fd);
1594 break;
1595 case 4:
1596 c = *cp++; PUTRGBHEX(c&0xf, fd);
1597 c >>= 4; PUTRGBHEX(c, fd);
1598 break;
1599 case 2:
1600 c = *cp++; PUTRGBHEX(c&0x3, fd);
1601 c >>= 2; PUTRGBHEX(c&0x3, fd);
1602 c >>= 2; PUTRGBHEX(c&0x3, fd);
1603 c >>= 2; PUTRGBHEX(c, fd);
1604 break;
1605 case 1:
1606 c = *cp++; PUTRGBHEX(c&0x1, fd);
1607 c >>= 1; PUTRGBHEX(c&0x1, fd);
1608 c >>= 1; PUTRGBHEX(c&0x1, fd);
1609 c >>= 1; PUTRGBHEX(c&0x1, fd);
1610 c >>= 1; PUTRGBHEX(c&0x1, fd);
1611 c >>= 1; PUTRGBHEX(c&0x1, fd);
1612 c >>= 1; PUTRGBHEX(c&0x1, fd);
1613 c >>= 1; PUTRGBHEX(c, fd);
1614 break;
1615 }
1616 }
1617 }
1618 _TIFFfree((char *) tf_buf);
1619}
1620
1621void
1622PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1623{
1624 int breaklen = MAXLINE;
1625 unsigned char* tf_buf;
1626 unsigned char* cp;
1627 tsize_t stripsize = TIFFStripSize(tif);
1628 tstrip_t s;
1629
1630#if defined( EXP_ASCII85ENCODER )
1631 int ascii85_l; /* Length, in bytes, of ascii85_p[] data */
1632 uint8 *ascii85_p = 0; /* Holds ASCII85 encoded data */
1633#endif
1634
1635 (void) w; (void) h;
1636 tf_buf = (unsigned char *) _TIFFmalloc(stripsize);
1637 memset(tf_buf, 0, stripsize);
1638 if (tf_buf == NULL) {
1639 TIFFError(filename, "No space for scanline buffer");
1640 return;
1641 }
1642
1643#if defined( EXP_ASCII85ENCODER )
1644 if ( ascii85 ) {
1645 /*
1646 * Allocate a buffer to hold the ASCII85 encoded data. Note
1647 * that it is allocated with sufficient room to hold the
1648 * encoded data (5*stripsize/4) plus the EOD marker (+8)
1649 * and formatting line breaks. The line breaks are more
1650 * than taken care of by using 6*stripsize/4 rather than
1651 * 5*stripsize/4.
1652 */
1653
1654 ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 );
1655
1656 if ( !ascii85_p ) {
1657 _TIFFfree( tf_buf );
1658
1659 TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
1660 return;
1661 }
1662 }
1663#endif
1664
1665 if (ascii85)
1666 Ascii85Init();
1667
1668 for (s = 0; s < TIFFNumberOfStrips(tif); s++) {
1669 int cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize);
1670 if (cc < 0) {
1671 TIFFError(filename, "Can't read strip");
1672 break;
1673 }
1674 cp = tf_buf;
1675 if (photometric == PHOTOMETRIC_MINISWHITE) {
1676 for (cp += cc; --cp >= tf_buf;)
1677 *cp = ~*cp;
1678 cp++;
1679 }
1680 if (ascii85) {
1681#if defined( EXP_ASCII85ENCODER )
1682 if (alpha) {
1683 int adjust, i;
1684 for (i = 0; i < cc; i+=2) {
1685 adjust = 255 - cp[i + 1];
1686 cp[i / 2] = cp[i] + adjust;
1687 }
1688 cc /= 2;
1689 }
1690
1691 ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, cp, cc );
1692
1693 if ( ascii85_l > 0 )
1694 fwrite( ascii85_p, ascii85_l, 1, fd );
1695#else
1696 while (cc-- > 0)
1697 Ascii85Put(*cp++, fd);
1698#endif /* EXP_ASCII85_ENCODER */
1699 } else {
1700 unsigned char c;
1701
1702 if (alpha) {
1703 int adjust;
1704 while (cc-- > 0) {
1705 DOBREAK(breaklen, 1, fd);
1706 /*
1707 * For images with alpha, matte against
1708 * a white background; i.e.
1709 * Cback * (1 - Aimage)
1710 * where Cback = 1.
1711 */
1712 adjust = 255 - cp[1];
1713 c = *cp++ + adjust; PUTHEX(c,fd);
1714 cp++, cc--;
1715 }
1716 } else {
1717 while (cc-- > 0) {
1718 c = *cp++;
1719 DOBREAK(breaklen, 1, fd);
1720 PUTHEX(c, fd);
1721 }
1722 }
1723 }
1724 }
1725
1726 if ( !ascii85 )
1727 {
1728 if ( level2 || level3)
1729 fputs(">\n", fd);
1730 }
1731#if !defined( EXP_ASCII85ENCODER )
1732 else
1733 Ascii85Flush(fd);
1734#else
1735 if ( ascii85_p )
1736 _TIFFfree( ascii85_p );
1737#endif
1738
1739 _TIFFfree(tf_buf);
1740}
1741
1742void
1743PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
1744{
1745 uint32 *bc;
1746 uint32 bufsize;
1747 int breaklen = MAXLINE, cc;
1748 uint16 fillorder;
1749 unsigned char *tf_buf;
1750 unsigned char *cp, c;
1751 tstrip_t s;
1752
1753#if defined( EXP_ASCII85ENCODER )
1754 int ascii85_l; /* Length, in bytes, of ascii85_p[] data */
1755 uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */
1756#endif
1757
1758 (void) w; (void) h;
1759 TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
1760 TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
1761
1762 /*
1763 * Find largest strip:
1764 */
1765
1766 bufsize = bc[0];
1767
1768 for ( s = 0; ++s < (tstrip_t)tf_numberstrips; ) {
1769 if ( bc[s] > bufsize )
1770 bufsize = bc[s];
1771 }
1772
1773 tf_buf = (unsigned char*) _TIFFmalloc(bufsize);
1774 if (tf_buf == NULL) {
1775 TIFFError(filename, "No space for strip buffer");
1776 return;
1777 }
1778
1779#if defined( EXP_ASCII85ENCODER )
1780 if ( ascii85 ) {
1781 /*
1782 * Allocate a buffer to hold the ASCII85 encoded data. Note
1783 * that it is allocated with sufficient room to hold the
1784 * encoded data (5*bufsize/4) plus the EOD marker (+8)
1785 * and formatting line breaks. The line breaks are more
1786 * than taken care of by using 6*bufsize/4 rather than
1787 * 5*bufsize/4.
1788 */
1789
1790 ascii85_p = _TIFFmalloc( (bufsize+(bufsize/2)) + 8 );
1791
1792 if ( !ascii85_p ) {
1793 _TIFFfree( tf_buf );
1794
1795 TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
1796 return;
1797 }
1798 }
1799#endif
1800
1801 for (s = 0; s < (tstrip_t) tf_numberstrips; s++) {
1802 cc = TIFFReadRawStrip(tif, s, tf_buf, bc[s]);
1803 if (cc < 0) {
1804 TIFFError(filename, "Can't read strip");
1805 break;
1806 }
1807 if (fillorder == FILLORDER_LSB2MSB)
1808 TIFFReverseBits(tf_buf, cc);
1809 if (!ascii85) {
1810 for (cp = tf_buf; cc > 0; cc--) {
1811 DOBREAK(breaklen, 1, fd);
1812 c = *cp++;
1813 PUTHEX(c, fd);
1814 }
1815 fputs(">\n", fd);
1816 breaklen = MAXLINE;
1817 } else {
1818 Ascii85Init();
1819#if defined( EXP_ASCII85ENCODER )
1820 ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, tf_buf, cc );
1821
1822 if ( ascii85_l > 0 )
1823 fwrite( ascii85_p, ascii85_l, 1, fd );
1824#else
1825 for (cp = tf_buf; cc > 0; cc--)
1826 Ascii85Put(*cp++, fd);
1827 Ascii85Flush(fd);
1828#endif /* EXP_ASCII85ENCODER */
1829 }
1830 }
1831 _TIFFfree((char *) tf_buf);
1832
1833#if defined( EXP_ASCII85ENCODER )
1834 if ( ascii85_p )
1835 _TIFFfree( ascii85_p );
1836#endif
1837}
1838
1839void
1840Ascii85Init(void)
1841{
1842 ascii85breaklen = 2*MAXLINE;
1843 ascii85count = 0;
1844}
1845
1846static char*
1847Ascii85Encode(unsigned char* raw)
1848{
1849 static char encoded[6];
1850 uint32 word;
1851
1852 word = (((raw[0]<<8)+raw[1])<<16) + (raw[2]<<8) + raw[3];
1853 if (word != 0L) {
1854 uint32 q;
1855 uint16 w1;
1856
1857 q = word / (85L*85*85*85); /* actually only a byte */
1858 encoded[0] = (char) (q + '!');
1859
1860 word -= q * (85L*85*85*85); q = word / (85L*85*85);
1861 encoded[1] = (char) (q + '!');
1862
1863 word -= q * (85L*85*85); q = word / (85*85);
1864 encoded[2] = (char) (q + '!');
1865
1866 w1 = (uint16) (word - q*(85L*85));
1867 encoded[3] = (char) ((w1 / 85) + '!');
1868 encoded[4] = (char) ((w1 % 85) + '!');
1869 encoded[5] = '\0';
1870 } else
1871 encoded[0] = 'z', encoded[1] = '\0';
1872 return (encoded);
1873}
1874
1875void
1876Ascii85Put(unsigned char code, FILE* fd)
1877{
1878 ascii85buf[ascii85count++] = code;
1879 if (ascii85count >= 4) {
1880 unsigned char* p;
1881 int n;
1882
1883 for (n = ascii85count, p = ascii85buf; n >= 4; n -= 4, p += 4) {
1884 char* cp;
1885 for (cp = Ascii85Encode(p); *cp; cp++) {
1886 putc(*cp, fd);
1887 if (--ascii85breaklen == 0) {
1888 putc('\n', fd);
1889 ascii85breaklen = 2*MAXLINE;
1890 }
1891 }
1892 }
1893 _TIFFmemcpy(ascii85buf, p, n);
1894 ascii85count = n;
1895 }
1896}
1897
1898void
1899Ascii85Flush(FILE* fd)
1900{
1901 if (ascii85count > 0) {
1902 char* res;
1903 _TIFFmemset(&ascii85buf[ascii85count], 0, 3);
1904 res = Ascii85Encode(ascii85buf);
1905 fwrite(res[0] == 'z' ? "!!!!" : res, ascii85count + 1, 1, fd);
1906 }
1907 fputs("~>\n", fd);
1908}
1909#if defined( EXP_ASCII85ENCODER)
1910\f
1911#define A85BREAKCNTR ascii85breaklen
1912#define A85BREAKLEN (2*MAXLINE)
1913
1914/*****************************************************************************
1915*
1916* Name: Ascii85EncodeBlock( ascii85_p, f_eod, raw_p, raw_l )
1917*
1918* Description: This routine will encode the raw data in the buffer described
1919* by raw_p and raw_l into ASCII85 format and store the encoding
1920* in the buffer given by ascii85_p.
1921*
1922* Parameters: ascii85_p - A buffer supplied by the caller which will
1923* contain the encoded ASCII85 data.
1924* f_eod - Flag: Nz means to end the encoded buffer with
1925* an End-Of-Data marker.
1926* raw_p - Pointer to the buffer of data to be encoded
1927* raw_l - Number of bytes in raw_p[] to be encoded
1928*
1929* Returns: (int) < 0 Error, see errno
1930* >= 0 Number of bytes written to ascii85_p[].
1931*
1932* Notes: An external variable given by A85BREAKCNTR is used to
1933* determine when to insert newline characters into the
1934* encoded data. As each byte is placed into ascii85_p this
1935* external is decremented. If the variable is decrement to
1936* or past zero then a newline is inserted into ascii85_p
1937* and the A85BREAKCNTR is then reset to A85BREAKLEN.
1938* Note: for efficiency reasons the A85BREAKCNTR variable
1939* is not actually checked on *every* character
1940* placed into ascii85_p but often only for every
1941* 5 characters.
1942*
1943* THE CALLER IS RESPONSIBLE FOR ENSURING THAT ASCII85_P[] IS
1944* SUFFICIENTLY LARGE TO THE ENCODED DATA!
1945* You will need at least 5 * (raw_l/4) bytes plus space for
1946* newline characters and space for an EOD marker (if
1947* requested). A safe calculation is to use 6*(raw_l/4) + 8
1948* to size ascii85_p.
1949*
1950*****************************************************************************/
1951
1952int Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw_p, int raw_l )
1953
1954{
1955 char ascii85[5]; /* Encoded 5 tuple */
1956 int ascii85_l; /* Number of bytes written to ascii85_p[] */
1957 int rc; /* Return code */
1958 uint32 val32; /* Unencoded 4 tuple */
1959
1960 ascii85_l = 0; /* Nothing written yet */
1961
1962 if ( raw_p )
1963 {
1964 --raw_p; /* Prepare for pre-increment fetches */
1965
1966 for ( ; raw_l > 3; raw_l -= 4 )
1967 {
1968 val32 = *(++raw_p) << 24;
1969 val32 += *(++raw_p) << 16;
1970 val32 += *(++raw_p) << 8;
1971 val32 += *(++raw_p);
1972
1973 if ( val32 == 0 ) /* Special case */
1974 {
1975 ascii85_p[ascii85_l] = 'z';
1976 rc = 1;
1977 }
1978
1979 else
1980 {
1981 ascii85[4] = (char) ((val32 % 85) + 33);
1982 val32 /= 85;
1983
1984 ascii85[3] = (char) ((val32 % 85) + 33);
1985 val32 /= 85;
1986
1987 ascii85[2] = (char) ((val32 % 85) + 33);
1988 val32 /= 85;
1989
1990 ascii85[1] = (char) ((val32 % 85) + 33);
1991 ascii85[0] = (char) ((val32 / 85) + 33);
1992
1993 _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, sizeof(ascii85) );
1994 rc = sizeof(ascii85);
1995 }
1996
1997 ascii85_l += rc;
1998
1999 if ( (A85BREAKCNTR -= rc) <= 0 )
2000 {
2001 ascii85_p[ascii85_l] = '\n';
2002 ++ascii85_l;
2003 A85BREAKCNTR = A85BREAKLEN;
2004 }
2005 }
2006
2007 /*
2008 * Output any straggler bytes:
2009 */
2010
2011 if ( raw_l > 0 )
2012 {
2013 int len; /* Output this many bytes */
2014
2015 len = raw_l + 1;
2016 val32 = *++raw_p << 24; /* Prime the pump */
2017
2018 if ( --raw_l > 0 ) val32 += *(++raw_p) << 16;
2019 if ( --raw_l > 0 ) val32 += *(++raw_p) << 8;
2020
2021 val32 /= 85;
2022
2023 ascii85[3] = (char) ((val32 % 85) + 33);
2024 val32 /= 85;
2025
2026 ascii85[2] = (char) ((val32 % 85) + 33);
2027 val32 /= 85;
2028
2029 ascii85[1] = (char) ((val32 % 85) + 33);
2030 ascii85[0] = (char) ((val32 / 85) + 33);
2031
2032 _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, len );
2033 ascii85_l += len;
2034 }
2035 }
2036
2037 /*
2038 * If requested add an ASCII85 End Of Data marker:
2039 */
2040
2041 if ( f_eod )
2042 {
2043 ascii85_p[ascii85_l++] = '~';
2044 ascii85_p[ascii85_l++] = '>';
2045 ascii85_p[ascii85_l++] = '\n';
2046 }
2047
2048 return ( ascii85_l );
2049
2050} /* Ascii85EncodeBlock() */
2051
2052#endif /* EXP_ASCII85ENCODER */
2053
2054
2055char* stuff[] = {
2056"usage: tiff2ps [options] input.tif ...",
2057"where options are:",
2058" -1 generate PostScript Level 1 (default)",
2059" -2 generate PostScript Level 2",
2060" -3 generate PostScript Level 3",
2061" -8 disable use of ASCII85 encoding with PostScript Level 2/3",
2062" -a convert all directories in file (default is first)",
2063" -b # set the bottom margin to # inches",
2064" -c center image (-b and -l still add to this)",
2065" -d # convert directory number #",
2066" -D enable duplex printing (two pages per sheet of paper)",
2067" -e generate Encapsulated PostScript (EPS) (implies -z)",
2068" -h # assume printed page height is # inches (default 11)",
2069" -w # assume printed page width is # inches (default 8.5)",
2070" -H # split image if height is more than # inches",
2071" -L # overLap split images by # inches",
2072" -i # enable/disable (Nz/0) pixel interpolation (default: enable)",
2073" -l # set the left margin to # inches",
2074" -m use \"imagemask\" operator instead of \"image\"",
2075" -o # convert directory at file offset #",
2076" -O file write PostScript to file instead of standard output",
2077" -p generate regular PostScript",
2078" -r rotate by 180 degrees",
2079" -s generate PostScript for a single image",
2080" -T print pages for top edge binding",
2081" -x override resolution units as centimeters",
2082" -y override resolution units as inches",
2083" -z enable printing in the deadzone (only for PostScript Level 2/3)",
2084NULL
2085};
2086
2087static void
2088usage(int code)
2089{
2090 char buf[BUFSIZ];
2091 int i;
2092
2093 setbuf(stderr, buf);
2094 fprintf(stderr, "%s\n\n", TIFFGetVersion());
2095 for (i = 0; stuff[i] != NULL; i++)
2096 fprintf(stderr, "%s\n", stuff[i]);
2097 exit(code);
2098}
2099
2100/* vim: set ts=8 sts=8 sw=8 noet: */