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