1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
5 * Copyright (c) 1988-1997 Sam Leffler
6 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
29 * Modified for use as Evince TIFF ps exporter by
30 * Matthew S. Wilson <msw@rpath.com>
31 * Modifications Copyright (C) 2005 rpath, Inc.
36 #include <stdlib.h> /* for atof */
43 #include <glib/gstdio.h>
51 * I (Bruce A. Mallett) added this revision history comment ;)
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.
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 ...).
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
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
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.
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.
87 * Added "-m" switch to ask tiff2ps to, where possible, use the
88 * "imagemask" operator instead of the "image" operator.
90 * Added the "-i #" switch to allow interpolation to be disabled.
92 * Unrolled a loop or two to improve performance.
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!
105 #define EXP_ASCII85ENCODER
108 * NB: this code assumes uint32 works with printf's %l[ud].
116 struct _TIFF2PSContext
118 char *filename; /* input filename */
119 FILE *fd; /* output file stream */
120 int ascii85; /* use ASCII85 encoding */
121 int interpolate; /* interpolate level2 image */
122 int level2; /* generate PostScript level 2 */
123 int level3; /* generate PostScript level 3 */
124 int generateEPSF; /* generate Encapsulated PostScript */
125 int PSduplex; /* enable duplex printing */
126 int PStumble; /* enable top edge binding */
127 int PSavoiddeadzone; /* enable avoiding printer deadzone */
128 double maxPageHeight; /* maximum size to fit on page */
129 double splitOverlap; /* amount for split pages to overlag */
130 int rotate; /* rotate image by 180 degrees */
131 int useImagemask; /* Use imagemask instead of image operator */
132 uint16 res_unit; /* Resolution units: 2 - inches, 3 - cm */
133 int npages; /* number of pages processed */
135 tsize_t tf_bytesperrow;
136 tsize_t ps_bytesperrow;
137 tsize_t tf_rowsperstrip;
138 tsize_t tf_numberstrips;
141 * ASCII85 Encoding Support.
143 unsigned char ascii85buf[10];
146 uint16 samplesperpixel;
147 uint16 bitspersample;
148 uint16 planarconfiguration;
155 static void PSpage(TIFF2PSContext*, TIFF*, uint32, uint32);
156 static void PSColorContigPreamble(TIFF2PSContext*, uint32, uint32, int);
157 static void PSColorSeparatePreamble(TIFF2PSContext*, uint32, uint32, int);
158 static void PSDataColorContig(TIFF2PSContext*, TIFF*, uint32, uint32, int);
159 static void PSDataColorSeparate(TIFF2PSContext*, TIFF*, uint32, uint32, int);
160 static void PSDataPalette(TIFF2PSContext*, TIFF*, uint32, uint32);
161 static void PSDataBW(TIFF2PSContext*, TIFF*, uint32, uint32);
162 static void Ascii85Init(TIFF2PSContext*);
163 static void Ascii85Put(TIFF2PSContext*, unsigned char);
164 static void Ascii85Flush(TIFF2PSContext*);
165 static void PSHead(TIFF2PSContext*, TIFF*, uint32, uint32,
166 double, double, double, double);
167 static void PSTail(TIFF2PSContext*);
169 #if defined( EXP_ASCII85ENCODER )
170 static int Ascii85EncodeBlock(TIFF2PSContext*, uint8 * ascii85_p,
171 unsigned f_eod, const uint8 * raw_p, int raw_l);
174 TIFF2PSContext* tiff2ps_context_new(const gchar *filename) {
177 ctx = g_new0(TIFF2PSContext, 1);
178 ctx->filename = g_strdup(filename);
179 ctx->fd = g_fopen(ctx->filename, "w");
182 ctx->interpolate = TRUE; /* interpolate level2 image */
183 ctx->PSavoiddeadzone = TRUE; /* enable avoiding printer deadzone */
187 void tiff2ps_context_finalize(TIFF2PSContext *ctx) {
190 g_free(ctx->filename);
195 checkImage(TIFF2PSContext *ctx, TIFF* tif)
197 switch (ctx->photometric) {
198 case PHOTOMETRIC_YCBCR:
199 if ((ctx->compression == COMPRESSION_JPEG
200 || ctx->compression == COMPRESSION_OJPEG)
201 && ctx->planarconfiguration == PLANARCONFIG_CONTIG) {
202 /* can rely on libjpeg to convert to RGB */
203 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE,
205 ctx->photometric = PHOTOMETRIC_RGB;
207 if (ctx->level2 || ctx->level3)
209 TIFFError(ctx->filename, "Can not handle image with %s",
210 "Ctx->PhotometricInterpretation=YCbCr");
214 case PHOTOMETRIC_RGB:
215 if (ctx->alpha && ctx->bitspersample != 8) {
216 TIFFError(ctx->filename,
217 "Can not handle %d-bit/sample RGB image with ctx->alpha",
222 case PHOTOMETRIC_SEPARATED:
223 case PHOTOMETRIC_PALETTE:
224 case PHOTOMETRIC_MINISBLACK:
225 case PHOTOMETRIC_MINISWHITE:
227 case PHOTOMETRIC_LOGL:
228 case PHOTOMETRIC_LOGLUV:
229 if (ctx->compression != COMPRESSION_SGILOG &&
230 ctx->compression != COMPRESSION_SGILOG24) {
231 TIFFError(ctx->filename,
232 "Can not handle %s data with ctx->compression other than SGILog",
233 (ctx->photometric == PHOTOMETRIC_LOGL) ?
238 /* rely on library to convert to RGB/greyscale */
239 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
240 ctx->photometric = (ctx->photometric == PHOTOMETRIC_LOGL) ?
241 PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB;
242 ctx->bitspersample = 8;
244 case PHOTOMETRIC_CIELAB:
247 TIFFError(ctx->filename,
248 "Can not handle image with Ctx->PhotometricInterpretation=%d",
252 switch (ctx->bitspersample) {
257 TIFFError(ctx->filename, "Can not handle %d-bit/sample image",
261 if (ctx->planarconfiguration == PLANARCONFIG_SEPARATE &&
262 ctx->extrasamples > 0)
263 TIFFWarning(ctx->filename, "Ignoring extra samples");
267 #define PS_UNIT_SIZE 72.0F
268 #define PSUNITS(npix,res) ((npix) * (PS_UNIT_SIZE / (res)))
270 static char RGBcolorimage[] = "\
273 dup length 3 idiv string 0 3 0\n\
275 add 2 1 roll 1 sub dup 0 eq {\n\
282 } { 2 1 roll } ifelse\n\
286 /colorimage where {pop} {\n\
287 /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def\n\
292 * Adobe Photoshop requires a comment line of the form:
294 * %ImageData: <cols> <rows> <depth> <main channels> <pad channels>
295 * <block size> <1 for binary|2 for hex> "data start"
297 * It is claimed to be part of some future revision of the EPS spec.
300 PhotoshopBanner(TIFF2PSContext* ctx, uint32 w, uint32 h, int bs, int nc,
303 fprintf(ctx->fd, "%%ImageData: %ld %ld %d %d 0 %d 2 \"",
304 (long) w, (long) h, ctx->bitspersample, nc, bs);
305 fprintf(ctx->fd, startline, nc);
306 fprintf(ctx->fd, "\"\n");
310 * pw : image width in pixels
311 * ph : image height in pixels
312 * pprw : image width in PS units (72 dpi)
313 * pprh : image height in PS units (72 dpi)
316 setupPageState(TIFF2PSContext *ctx, TIFF* tif, uint32* pw, uint32* ph,
317 double* pprw, double* pprh)
319 float xres = 0.0F, yres = 0.0F;
321 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, pw);
322 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ph);
323 if (ctx->res_unit == 0)
324 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &ctx->res_unit);
326 * Calculate printable area.
328 if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)
329 || fabs(xres) < 0.0000001)
331 if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)
332 || fabs(yres) < 0.0000001)
334 switch (ctx->res_unit) {
335 case RESUNIT_CENTIMETER:
336 xres *= 2.54F, yres *= 2.54F;
342 xres *= PS_UNIT_SIZE, yres *= PS_UNIT_SIZE;
345 *pprh = PSUNITS(*ph, yres);
346 *pprw = PSUNITS(*pw, xres);
350 isCCITTCompression(TIFF* tif)
353 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
354 return (compress == COMPRESSION_CCITTFAX3 ||
355 compress == COMPRESSION_CCITTFAX4 ||
356 compress == COMPRESSION_CCITTRLE ||
357 compress == COMPRESSION_CCITTRLEW);
360 static char *hex = "0123456789abcdef";
363 * imagewidth & imageheight are 1/72 inches
364 * pagewidth & pageheight are inches
367 PlaceImage(TIFF2PSContext *ctx, double pagewidth, double pageheight,
368 double imagewidth, double imageheight, int splitpage,
369 double lm, double bm, int cnt)
375 double left_offset = lm * PS_UNIT_SIZE;
376 double bottom_offset = bm * PS_UNIT_SIZE;
377 double subimageheight;
381 pagewidth *= PS_UNIT_SIZE;
382 pageheight *= PS_UNIT_SIZE;
384 if (ctx->maxPageHeight==0)
387 splitheight = ctx->maxPageHeight * PS_UNIT_SIZE;
388 overlap = ctx->splitOverlap * PS_UNIT_SIZE;
392 * if too wide, scrunch to fit
393 * else leave it alone
395 if (imagewidth <= pagewidth) {
402 * if too long, scrunch to fit
403 * if too short, move to top of page
405 if (imageheight <= pageheight) {
406 yscale = imageheight;
407 ytran = pageheight - imageheight;
408 } else if (imageheight > pageheight &&
409 (splitheight == 0 || imageheight <= splitheight)) {
411 } else /* imageheight > splitheight */ {
412 subimageheight = imageheight - (pageheight-overlap)*splitpage;
413 if (subimageheight <= pageheight) {
414 yscale = imageheight;
415 ytran = pageheight - subimageheight;
417 } else if ( subimageheight > pageheight && subimageheight <= splitheight) {
418 yscale = imageheight * pageheight / subimageheight;
421 } else /* sumimageheight > splitheight */ {
422 yscale = imageheight;
423 ytran = pageheight - subimageheight;
428 bottom_offset += ytran / (cnt?2:1);
430 left_offset += xtran / 2;
431 fprintf(ctx->fd, "%f %f translate\n", left_offset, bottom_offset);
432 fprintf(ctx->fd, "%f %f scale\n", xscale, yscale);
434 fputs ("1 1 translate 180 ctx->rotate\n", ctx->fd);
441 tiff2ps_process_page(TIFF2PSContext* ctx, TIFF* tif, double pw, double ph,
442 double lm, double bm, gboolean cnt)
448 double left_offset = lm * PS_UNIT_SIZE;
449 double bottom_offset = bm * PS_UNIT_SIZE;
453 if (!TIFFGetField(tif, TIFFTAG_XPOSITION, &ox))
455 if (!TIFFGetField(tif, TIFFTAG_YPOSITION, &oy))
457 setupPageState(ctx, tif, &w, &h, &prw, &prh);
459 ctx->tf_numberstrips = TIFFNumberOfStrips(tif);
460 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP,
461 &ctx->tf_rowsperstrip);
462 setupPageState(ctx, tif, &w, &h, &prw, &prh);
464 PSHead(ctx, tif, w, h, prw, prh, ox, oy);
465 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE,
466 &ctx->bitspersample);
467 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL,
468 &ctx->samplesperpixel);
469 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG,
470 &ctx->planarconfiguration);
471 TIFFGetField(tif, TIFFTAG_COMPRESSION, &ctx->compression);
472 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
473 &ctx->extrasamples, &sampleinfo);
474 ctx->alpha = (ctx->extrasamples == 1 &&
475 sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
476 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &ctx->photometric)) {
477 switch (ctx->samplesperpixel - ctx->extrasamples) {
479 if (isCCITTCompression(tif))
480 ctx->photometric = PHOTOMETRIC_MINISWHITE;
482 ctx->photometric = PHOTOMETRIC_MINISBLACK;
485 ctx->photometric = PHOTOMETRIC_RGB;
488 ctx->photometric = PHOTOMETRIC_SEPARATED;
492 if (checkImage(ctx, tif)) {
493 ctx->tf_bytesperrow = TIFFScanlineSize(tif);
495 fprintf(ctx->fd, "%%%%Page: %d %d\n", ctx->npages,
497 if (!ctx->generateEPSF && ( ctx->level2 || ctx->level3 )) {
498 double psw = 0.0, psh = 0.0;
500 psw = pw * PS_UNIT_SIZE;
501 if (ctx->res_unit == RESUNIT_CENTIMETER)
504 psw=ctx->rotate ? prh:prw;
506 psh = ph * PS_UNIT_SIZE;
507 if (ctx->res_unit == RESUNIT_CENTIMETER)
510 psh=ctx->rotate ? prw:prh;
512 "1 dict begin /PageSize [ %f %f ] def currentdict end setpagedevice\n",
515 "<<\n /Policies <<\n /PageSize 3\n >>\n>> setpagedevice\n",
518 fprintf(ctx->fd, "gsave\n");
519 fprintf(ctx->fd, "100 dict begin\n");
520 if (pw != 0 || ph != 0) {
525 if (ctx->maxPageHeight) { /* used -H option */
526 split = PlaceImage(ctx,pw,ph,prw,prh,
529 PSpage(ctx, tif, w, h);
530 fprintf(ctx->fd, "end\n");
531 fprintf(ctx->fd, "grestore\n");
532 fprintf(ctx->fd, "showpage\n");
534 fprintf(ctx->fd, "%%%%Page: %d %d\n",
535 ctx->npages, ctx->npages);
536 fprintf(ctx->fd, "gsave\n");
537 fprintf(ctx->fd, "100 dict begin\n");
538 split = PlaceImage(ctx,pw,ph,prw,prh,
545 /* NB: maintain image aspect ratio */
546 scale = pw/prw < ph/prh ?
552 (ph - prh * scale) / 2;
554 (pw - prw * scale) / 2;
556 fprintf(ctx->fd, "%f %f translate\n",
557 left_offset, bottom_offset);
558 fprintf(ctx->fd, "%f %f scale\n",
559 prw * scale, prh * scale);
561 fputs ("1 1 translate 180 ctx->rotate\n", ctx->fd);
564 fprintf(ctx->fd, "%f %f scale\n", prw, prh);
566 fputs ("1 1 translate 180 ctx->rotate\n", ctx->fd);
568 PSpage(ctx, tif, w, h);
569 fprintf(ctx->fd, "end\n");
570 fprintf(ctx->fd, "grestore\n");
571 fprintf(ctx->fd, "showpage\n");
576 static char DuplexPreamble[] = "\
577 %%BeginFeature: *Duplex True\n\
579 /languagelevel where { pop languagelevel } { 1 } ifelse\n\
580 2 ge { 1 dict dup /Duplex true put setpagedevice }\n\
581 { statusdict /setduplex known { statusdict begin setduplex true end } if\n\
587 static char TumblePreamble[] = "\
588 %%BeginFeature: *Tumble True\n\
590 /languagelevel where { pop languagelevel } { 1 } ifelse\n\
591 2 ge { 1 dict dup /Tumble true put setpagedevice }\n\
592 { statusdict /settumble known { statusdict begin true settumble end } if\n\
598 static char AvoidDeadZonePreamble[] = "\
599 gsave newpath clippath pathbbox grestore\n\
600 4 2 roll 2 copy translate\n\
601 exch 3 1 roll sub 3 1 roll sub exch\n\
602 currentpagedevice /PageSize get aload pop\n\
603 exch 3 1 roll div 3 1 roll div abs exch abs\n\
604 2 copy gt { exch } if pop\n\
605 dup 1 lt { dup scale } { pop } ifelse\n\
609 PSHead(TIFF2PSContext *ctx, TIFF *tif, uint32 w, uint32 h,
610 double pw, double ph, double ox, double oy)
614 (void) tif; (void) w; (void) h;
616 fprintf(ctx->fd, "%%!PS-Adobe-3.0%s\n",
617 ctx->generateEPSF ? " EPSF-3.0" : "");
618 fprintf(ctx->fd, "%%%%Creator: Evince\n");
619 fprintf(ctx->fd, "%%%%CreationDate: %s", ctime(&t));
620 fprintf(ctx->fd, "%%%%DocumentData: Clean7Bit\n");
621 fprintf(ctx->fd, "%%%%Origin: %ld %ld\n", (long) ox, (long) oy);
622 /* NB: should use PageBoundingBox */
623 fprintf(ctx->fd, "%%%%BoundingBox: 0 0 %ld %ld\n",
624 (long) ceil(pw), (long) ceil(ph));
625 fprintf(ctx->fd, "%%%%LanguageLevel: %d\n",
626 (ctx->level3 ? 3 : (ctx->level2 ? 2 : 1)));
627 fprintf(ctx->fd, "%%%%Pages: (atend)\n");
628 fprintf(ctx->fd, "%%%%EndComments\n");
629 fprintf(ctx->fd, "%%%%BeginSetup\n");
631 fprintf(ctx->fd, "%s", DuplexPreamble);
633 fprintf(ctx->fd, "%s", TumblePreamble);
634 if (ctx->PSavoiddeadzone && (ctx->level2 || ctx->level3))
635 fprintf(ctx->fd, "%s", AvoidDeadZonePreamble);
636 fprintf(ctx->fd, "%%%%EndSetup\n");
640 PSTail(TIFF2PSContext *ctx)
644 fprintf(ctx->fd, "%%%%Trailer\n");
645 fprintf(ctx->fd, "%%%%Pages: %d\n", ctx->npages);
646 fprintf(ctx->fd, "%%%%EOF\n");
650 checkcmap(TIFF2PSContext* ctx, TIFF* tif, int n,
651 uint16* r, uint16* g, uint16* b)
655 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
657 TIFFWarning(ctx->filename, "Assuming 8-bit colormap");
662 PS_Lvl2colorspace(TIFF2PSContext* ctx, TIFF* tif)
664 uint16 *rmap, *gmap, *bmap;
666 const char * colorspace_p;
668 switch ( ctx->photometric )
670 case PHOTOMETRIC_SEPARATED:
671 colorspace_p = "CMYK";
674 case PHOTOMETRIC_RGB:
675 colorspace_p = "RGB";
679 colorspace_p = "Gray";
683 * Set up PostScript Level 2 colorspace according to
684 * section 4.8 in the PostScript refenence manual.
686 fputs("% PostScript Level 2 only.\n", ctx->fd);
687 if (ctx->photometric != PHOTOMETRIC_PALETTE) {
688 if (ctx->photometric == PHOTOMETRIC_YCBCR) {
691 fprintf(ctx->fd, "/Device%s setcolorspace\n", colorspace_p );
696 * Set up an indexed/palette colorspace
698 num_colors = (1 << ctx->bitspersample);
699 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
700 TIFFError(ctx->filename,
701 "Palette image w/o \"Colormap\" tag");
704 if (checkcmap(ctx, tif, num_colors, rmap, gmap, bmap) == 16) {
706 * Convert colormap to 8-bits values.
708 #define CVT(x) (((x) * 255) / ((1L<<16)-1))
709 for (i = 0; i < num_colors; i++) {
710 rmap[i] = CVT(rmap[i]);
711 gmap[i] = CVT(gmap[i]);
712 bmap[i] = CVT(bmap[i]);
716 fprintf(ctx->fd, "[ /Indexed /DeviceRGB %d", num_colors - 1);
719 fputs("\n<~", ctx->fd);
720 ctx->ascii85breaklen -= 2;
722 fputs(" <", ctx->fd);
723 for (i = 0; i < num_colors; i++) {
725 Ascii85Put(ctx, (unsigned char)rmap[i]);
726 Ascii85Put(ctx, (unsigned char)gmap[i]);
727 Ascii85Put(ctx, (unsigned char)bmap[i]);
729 fputs((i % 8) ? " " : "\n ", ctx->fd);
730 fprintf(ctx->fd, "%02x%02x%02x",
731 rmap[i], gmap[i], bmap[i]);
737 fputs(">\n", ctx->fd);
738 fputs("] setcolorspace\n", ctx->fd);
742 PS_Lvl2ImageDict(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h)
745 uint32 tile_width, tile_height;
746 uint16 predictor, minsamplevalue, maxsamplevalue;
748 char im_h[64], im_x[64], im_y[64];
749 char * imageOp = "image";
751 if ( ctx->useImagemask && (ctx->bitspersample == 1) )
752 imageOp = "imagemask";
754 (void)strcpy(im_x, "0");
755 (void)sprintf(im_y, "%lu", (long) h);
756 (void)sprintf(im_h, "%lu", (long) h);
759 if (TIFFIsTiled(tif)) {
760 repeat_count = TIFFNumberOfTiles(tif);
761 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
762 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
763 if (tile_width > w || tile_height > h ||
764 (w % tile_width) != 0 || (h % tile_height != 0)) {
766 * The tiles does not fit image width and height.
767 * Set up a clip rectangle for the image unit square.
769 fputs("0 0 1 1 rectclip\n", ctx->fd);
771 if (tile_width < w) {
772 fputs("/im_x 0 def\n", ctx->fd);
773 (void)strcpy(im_x, "im_x neg");
775 if (tile_height < h) {
776 fputs("/im_y 0 def\n", ctx->fd);
777 (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
780 repeat_count = ctx->tf_numberstrips;
781 tile_height = ctx->tf_rowsperstrip;
784 if (repeat_count > 1) {
785 fputs("/im_y 0 def\n", ctx->fd);
786 fprintf(ctx->fd, "/im_h %lu def\n",
787 (unsigned long) tile_height);
788 (void)strcpy(im_h, "im_h");
789 (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h);
794 * Output start of exec block
796 fputs("{ % exec\n", ctx->fd);
798 if (repeat_count > 1)
799 fprintf(ctx->fd, "%d { %% repeat\n", repeat_count);
802 * Output filter options and image dictionary.
805 fputs(" /im_stream currentfile /ASCII85Decode filter def\n",
807 fputs(" <<\n", ctx->fd);
808 fputs(" /ImageType 1\n", ctx->fd);
809 fprintf(ctx->fd, " /Width %lu\n", (unsigned long) tile_width);
811 * Workaround for some software that may crash when last strip
812 * of image contains fewer number of scanlines than specified
813 * by the `/Height' variable. So for stripped images with multiple
814 * strips we will set `/Height' as `im_h', because one is
815 * recalculated for each strip - including the (smaller) final strip.
816 * For tiled images and images with only one strip `/Height' will
817 * contain number of scanlines in tile (or image height in case of
818 * one-stripped image).
820 if (TIFFIsTiled(tif) || ctx->tf_numberstrips == 1)
821 fprintf(ctx->fd, " /Height %lu\n", (unsigned long) tile_height);
823 fprintf(ctx->fd, " /Height im_h\n");
825 if (ctx->planarconfiguration == PLANARCONFIG_SEPARATE && ctx->samplesperpixel > 1)
826 fputs(" /MultipleDataSources true\n", ctx->fd);
827 fprintf(ctx->fd, " /ImageMatrix [ %lu 0 0 %ld %s %s ]\n",
828 (unsigned long) w, - (long)h, im_x, im_y);
829 fprintf(ctx->fd, " /BitsPerComponent %d\n", ctx->bitspersample);
830 fprintf(ctx->fd, " /Ctx->Interpolate %s\n", ctx->interpolate ? "true" : "false");
832 switch (ctx->samplesperpixel - ctx->extrasamples) {
834 switch (ctx->photometric) {
835 case PHOTOMETRIC_MINISBLACK:
836 fputs(" /Decode [0 1]\n", ctx->fd);
838 case PHOTOMETRIC_MINISWHITE:
839 switch (ctx->compression) {
840 case COMPRESSION_CCITTRLE:
841 case COMPRESSION_CCITTRLEW:
842 case COMPRESSION_CCITTFAX3:
843 case COMPRESSION_CCITTFAX4:
845 * Manage inverting with /Blackis1 flag
846 * since there migth be uncompressed parts
848 fputs(" /Decode [0 1]\n", ctx->fd);
854 fputs(" /Decode [1 0]\n", ctx->fd);
858 case PHOTOMETRIC_PALETTE:
859 TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE,
861 TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE,
863 fprintf(ctx->fd, " /Decode [%u %u]\n",
864 minsamplevalue, maxsamplevalue);
870 fputs(" /Decode [0 1]\n", ctx->fd);
875 switch (ctx->photometric) {
876 case PHOTOMETRIC_RGB:
877 fputs(" /Decode [0 1 0 1 0 1]\n", ctx->fd);
879 case PHOTOMETRIC_MINISWHITE:
880 case PHOTOMETRIC_MINISBLACK:
885 fputs(" /Decode [0 1 0 1 0 1]\n", ctx->fd);
893 fputs(" /Decode [0 1 0 1 0 1 0 1]\n", ctx->fd);
896 fputs(" /DataSource", ctx->fd);
897 if (ctx->planarconfiguration == PLANARCONFIG_SEPARATE &&
898 ctx->samplesperpixel > 1)
899 fputs(" [", ctx->fd);
901 fputs(" im_stream", ctx->fd);
903 fputs(" currentfile /ASCIIHexDecode filter", ctx->fd);
906 switch (ctx->compression) {
907 case COMPRESSION_NONE: /* 1: uncompressed */
909 case COMPRESSION_CCITTRLE: /* 2: CCITT modified Huffman RLE */
910 case COMPRESSION_CCITTRLEW: /* 32771: #1 w/ word alignment */
911 case COMPRESSION_CCITTFAX3: /* 3: CCITT Group 3 fax encoding */
912 case COMPRESSION_CCITTFAX4: /* 4: CCITT Group 4 fax encoding */
913 fputs("\n\t<<\n", ctx->fd);
914 if (ctx->compression == COMPRESSION_CCITTFAX3) {
917 fputs("\t /EndOfLine true\n", ctx->fd);
918 fputs("\t /EndOfBlock false\n", ctx->fd);
919 if (!TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS,
922 if (g3_options & GROUP3OPT_2DENCODING)
923 fprintf(ctx->fd, "\t /K %s\n", im_h);
924 if (g3_options & GROUP3OPT_UNCOMPRESSED)
925 fputs("\t /Uncompressed true\n", ctx->fd);
926 if (g3_options & GROUP3OPT_FILLBITS)
927 fputs("\t /EncodedByteAlign true\n", ctx->fd);
929 if (ctx->compression == COMPRESSION_CCITTFAX4) {
932 fputs("\t /K -1\n", ctx->fd);
933 TIFFGetFieldDefaulted(tif, TIFFTAG_GROUP4OPTIONS,
935 if (g4_options & GROUP4OPT_UNCOMPRESSED)
936 fputs("\t /Uncompressed true\n", ctx->fd);
938 if (!(tile_width == w && w == 1728U))
939 fprintf(ctx->fd, "\t /Columns %lu\n",
940 (unsigned long) tile_width);
941 fprintf(ctx->fd, "\t /Rows %s\n", im_h);
942 if (ctx->compression == COMPRESSION_CCITTRLE ||
943 ctx->compression == COMPRESSION_CCITTRLEW) {
944 fputs("\t /EncodedByteAlign true\n", ctx->fd);
945 fputs("\t /EndOfBlock false\n", ctx->fd);
947 if (ctx->photometric == PHOTOMETRIC_MINISBLACK)
948 fputs("\t /BlackIs1 true\n", ctx->fd);
949 fprintf(ctx->fd, "\t>> /CCITTFaxDecode filter");
951 case COMPRESSION_LZW: /* 5: Lempel-Ziv & Welch */
952 TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
953 if (predictor == 2) {
954 fputs("\n\t<<\n", ctx->fd);
955 fprintf(ctx->fd, "\t /Predictor %u\n", predictor);
956 fprintf(ctx->fd, "\t /Columns %lu\n",
957 (unsigned long) tile_width);
958 fprintf(ctx->fd, "\t /Colors %u\n", ctx->samplesperpixel);
959 fprintf(ctx->fd, "\t /BitsPerComponent %u\n",
961 fputs("\t>>", ctx->fd);
963 fputs(" /LZWDecode filter", ctx->fd);
965 case COMPRESSION_DEFLATE: /* 5: ZIP */
966 case COMPRESSION_ADOBE_DEFLATE:
968 TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor);
970 fprintf(ctx->fd, "\t %% PostScript Level 3 only.");
971 fputs("\n\t<<\n", ctx->fd);
972 fprintf(ctx->fd, "\t /Predictor %u\n", predictor);
973 fprintf(ctx->fd, "\t /Columns %lu\n",
974 (unsigned long) tile_width);
975 fprintf(ctx->fd, "\t /Colors %u\n", ctx->samplesperpixel);
976 fprintf(ctx->fd, "\t /BitsPerComponent %u\n",
978 fputs("\t>>", ctx->fd);
980 fputs(" /FlateDecode filter", ctx->fd);
982 use_rawdata = FALSE ;
985 case COMPRESSION_PACKBITS: /* 32773: Macintosh RLE */
986 fputs(" /RunLengthDecode filter", ctx->fd);
989 case COMPRESSION_OJPEG: /* 6: !6.0 JPEG */
990 case COMPRESSION_JPEG: /* 7: %JPEG DCT ctx->compression */
993 * Code not tested yet
995 fputs(" /DCTDecode filter", ctx->fd);
1001 case COMPRESSION_NEXT: /* 32766: NeXT 2-bit RLE */
1002 case COMPRESSION_THUNDERSCAN: /* 32809: ThunderScan RLE */
1003 case COMPRESSION_PIXARFILM: /* 32908: Pixar companded 10bit LZW */
1004 case COMPRESSION_JBIG: /* 34661: ISO JBIG */
1005 use_rawdata = FALSE;
1007 case COMPRESSION_SGILOG: /* 34676: SGI LogL or LogLuv */
1008 case COMPRESSION_SGILOG24: /* 34677: SGI 24-bit LogLuv */
1009 use_rawdata = FALSE;
1015 use_rawdata = FALSE;
1018 if (ctx->planarconfiguration == PLANARCONFIG_SEPARATE &&
1019 ctx->samplesperpixel > 1) {
1023 * NOTE: This code does not work yet...
1025 for (i = 1; i < ctx->samplesperpixel; i++)
1026 fputs(" dup", ctx->fd);
1027 fputs(" ]", ctx->fd);
1030 fprintf( ctx->fd, "\n >> %s\n", imageOp );
1032 fputs(" im_stream status { im_stream flushfile } if\n", ctx->fd);
1033 if (repeat_count > 1) {
1034 if (tile_width < w) {
1035 fprintf(ctx->fd, " /im_x im_x %lu add def\n",
1036 (unsigned long) tile_width);
1037 if (tile_height < h) {
1038 fprintf(ctx->fd, " im_x %lu ge {\n",
1040 fputs(" /im_x 0 def\n", ctx->fd);
1041 fprintf(ctx->fd, " /im_y im_y %lu add def\n",
1042 (unsigned long) tile_height);
1043 fputs(" } if\n", ctx->fd);
1046 if (tile_height < h) {
1047 if (tile_width >= w) {
1048 fprintf(ctx->fd, " /im_y im_y %lu add def\n",
1049 (unsigned long) tile_height);
1050 if (!TIFFIsTiled(tif)) {
1051 fprintf(ctx->fd, " /im_h %lu im_y sub",
1053 fprintf(ctx->fd, " dup %lu gt { pop",
1054 (unsigned long) tile_height);
1055 fprintf(ctx->fd, " %lu } if def\n",
1056 (unsigned long) tile_height);
1060 fputs("} repeat\n", ctx->fd);
1063 * End of exec function
1065 fputs("}\n", ctx->fd);
1067 return(use_rawdata);
1073 PS_Lvl2page(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h)
1076 int use_rawdata, tiled_image, breaklen = MAXLINE;
1077 uint32 chunk_no, num_chunks, *bc;
1078 unsigned char *buf_data, *cp;
1079 tsize_t chunk_size, byte_count;
1081 #if defined( EXP_ASCII85ENCODER )
1082 int ascii85_l; /* Length, in bytes, of ascii85_p[] data */
1083 uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */
1086 PS_Lvl2colorspace(ctx, tif);
1087 use_rawdata = PS_Lvl2ImageDict(ctx, tif, w, h);
1089 /* See http://bugzilla.remotesensing.org/show_bug.cgi?id=80 */
1090 #ifdef ENABLE_BROKEN_BEGINENDDATA
1091 fputs("%%BeginData:\n", ctx->fd);
1093 fputs("exec\n", ctx->fd);
1095 tiled_image = TIFFIsTiled(tif);
1097 num_chunks = TIFFNumberOfTiles(tif);
1098 TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc);
1100 num_chunks = TIFFNumberOfStrips(tif);
1101 TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
1105 chunk_size = (tsize_t) bc[0];
1106 for (chunk_no = 1; chunk_no < num_chunks; chunk_no++)
1107 if ((tsize_t) bc[chunk_no] > chunk_size)
1108 chunk_size = (tsize_t) bc[chunk_no];
1111 chunk_size = TIFFTileSize(tif);
1113 chunk_size = TIFFStripSize(tif);
1115 buf_data = (unsigned char *)_TIFFmalloc(chunk_size);
1117 TIFFError(ctx->filename, "Can't alloc %u bytes for %s.",
1118 chunk_size, tiled_image ? "tiles" : "strips");
1122 #if defined( EXP_ASCII85ENCODER )
1123 if ( ctx->ascii85 ) {
1125 * Allocate a buffer to hold the ASCII85 encoded data. Note
1126 * that it is allocated with sufficient room to hold the
1127 * encoded data (5*chunk_size/4) plus the EOD marker (+8)
1128 * and formatting line breaks. The line breaks are more
1129 * than taken care of by using 6*chunk_size/4 rather than
1133 ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 );
1136 _TIFFfree( buf_data );
1138 TIFFError( ctx->filename,
1139 "Cannot allocate ASCII85 encoding buffer." );
1145 TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
1146 for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) {
1153 byte_count = TIFFReadRawTile(tif, chunk_no,
1154 buf_data, chunk_size);
1156 byte_count = TIFFReadRawStrip(tif, chunk_no,
1157 buf_data, chunk_size);
1158 if (fillorder == FILLORDER_LSB2MSB)
1159 TIFFReverseBits(buf_data, byte_count);
1162 byte_count = TIFFReadEncodedTile(tif,
1166 byte_count = TIFFReadEncodedStrip(tif,
1170 if (byte_count < 0) {
1171 TIFFError(ctx->filename, "Can't read %s %d.",
1172 tiled_image ? "tile" : "strip", chunk_no);
1174 Ascii85Put(ctx, '\0');
1177 * For images with ctx->alpha, matte against a white background;
1178 * i.e. Cback * (1 - Aimage) where Cback = 1. We will fill the
1179 * lower part of the buffer with the modified values.
1181 * XXX: needs better solution
1184 int adjust, i, j = 0;
1185 int ncomps = ctx->samplesperpixel - ctx->extrasamples;
1186 for (i = 0; i < byte_count; i+=ctx->samplesperpixel) {
1187 adjust = 255 - buf_data[i + ncomps];
1190 buf_data[j++] = buf_data[i] + adjust;
1193 buf_data[j++] = buf_data[i] + adjust;
1194 buf_data[j++] = buf_data[i+1] + adjust;
1197 buf_data[j++] = buf_data[i] + adjust;
1198 buf_data[j++] = buf_data[i+1] + adjust;
1199 buf_data[j++] = buf_data[i+2] + adjust;
1207 #if defined( EXP_ASCII85ENCODER )
1208 ascii85_l = Ascii85EncodeBlock(ctx, ascii85_p, 1,
1209 buf_data, byte_count);
1211 if ( ascii85_l > 0 )
1212 fwrite( ascii85_p, ascii85_l, 1, ctx->fd );
1214 for (cp = buf_data; byte_count > 0; byte_count--)
1215 Ascii85Put(ctx, *cp++);
1220 for (cp = buf_data; byte_count > 0; byte_count--) {
1221 putc(hex[((*cp)>>4)&0xf], ctx->fd);
1222 putc(hex[(*cp)&0xf], ctx->fd);
1225 if (--breaklen <= 0) {
1226 putc('\n', ctx->fd);
1232 if ( !ctx->ascii85 ) {
1233 if ( ctx->level2 || ctx->level3 )
1234 putc( '>', ctx->fd );
1235 putc('\n', ctx->fd);
1237 #if !defined( EXP_ASCII85ENCODER )
1243 #if defined( EXP_ASCII85ENCODER )
1245 _TIFFfree( ascii85_p );
1247 _TIFFfree(buf_data);
1248 #ifdef ENABLE_BROKEN_BEGINENDDATA
1249 fputs("%%EndData\n", ctx->fd);
1255 PSpage(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h)
1257 char *imageOp = "image";
1259 if ( ctx->useImagemask && (ctx->bitspersample == 1) )
1260 imageOp = "imagemask";
1262 if ((ctx->level2 || ctx->level3) && PS_Lvl2page(ctx, tif, w, h))
1264 ctx->ps_bytesperrow = ctx->tf_bytesperrow - (ctx->extrasamples * ctx->bitspersample / 8)*w;
1265 switch (ctx->photometric) {
1266 case PHOTOMETRIC_RGB:
1267 if (ctx->planarconfiguration == PLANARCONFIG_CONTIG) {
1268 fprintf(ctx->fd, "%s", RGBcolorimage);
1269 PSColorContigPreamble(ctx, w, h, 3);
1270 PSDataColorContig(ctx, tif, w, h, 3);
1272 PSColorSeparatePreamble(ctx, w, h, 3);
1273 PSDataColorSeparate(ctx, tif, w, h, 3);
1276 case PHOTOMETRIC_SEPARATED:
1277 /* XXX should emit CMYKcolorimage */
1278 if (ctx->planarconfiguration == PLANARCONFIG_CONTIG) {
1279 PSColorContigPreamble(ctx, w, h, 4);
1280 PSDataColorContig(ctx, tif, w, h, 4);
1282 PSColorSeparatePreamble(ctx, w, h, 4);
1283 PSDataColorSeparate(ctx, tif, w, h, 4);
1286 case PHOTOMETRIC_PALETTE:
1287 fprintf(ctx->fd, "%s", RGBcolorimage);
1288 PhotoshopBanner(ctx, w, h, 1, 3, "false 3 colorimage");
1289 fprintf(ctx->fd, "/scanLine %ld string def\n",
1290 (long) ctx->ps_bytesperrow * 3L);
1291 fprintf(ctx->fd, "%lu %lu 8\n",
1292 (unsigned long) w, (unsigned long) h);
1293 fprintf(ctx->fd, "[%lu 0 0 -%lu 0 %lu]\n",
1294 (unsigned long) w, (unsigned long) h,
1297 "{currentfile scanLine readhexstring pop} bind\n");
1298 fprintf(ctx->fd, "false 3 colorimage\n");
1299 PSDataPalette(ctx, tif, w, h);
1301 case PHOTOMETRIC_MINISBLACK:
1302 case PHOTOMETRIC_MINISWHITE:
1303 PhotoshopBanner(ctx, w, h, 1, 1, imageOp);
1304 fprintf(ctx->fd, "/scanLine %ld string def\n",
1305 (long) ctx->ps_bytesperrow);
1306 fprintf(ctx->fd, "%lu %lu %d\n",
1307 (unsigned long) w, (unsigned long) h, ctx->bitspersample);
1308 fprintf(ctx->fd, "[%lu 0 0 -%lu 0 %lu]\n",
1309 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1311 "{currentfile scanLine readhexstring pop} bind\n");
1312 fprintf(ctx->fd, "%s\n", imageOp);
1313 PSDataBW(ctx, tif, w, h);
1316 putc('\n', ctx->fd);
1320 PSColorContigPreamble(TIFF2PSContext* ctx, uint32 w, uint32 h, int nc)
1322 ctx->ps_bytesperrow = nc * (ctx->tf_bytesperrow / ctx->samplesperpixel);
1323 PhotoshopBanner(ctx, w, h, 1, nc, "false %d colorimage");
1324 fprintf(ctx->fd, "/line %ld string def\n", (long) ctx->ps_bytesperrow);
1325 fprintf(ctx->fd, "%lu %lu %d\n",
1326 (unsigned long) w, (unsigned long) h, ctx->bitspersample);
1327 fprintf(ctx->fd, "[%lu 0 0 -%lu 0 %lu]\n",
1328 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1329 fprintf(ctx->fd, "{currentfile line readhexstring pop} bind\n");
1330 fprintf(ctx->fd, "false %d colorimage\n", nc);
1334 PSColorSeparatePreamble(TIFF2PSContext* ctx, uint32 w, uint32 h, int nc)
1338 PhotoshopBanner(ctx, w, h, ctx->ps_bytesperrow, nc, "true %d colorimage");
1339 for (i = 0; i < nc; i++)
1340 fprintf(ctx->fd, "/line%d %ld string def\n",
1341 i, (long) ctx->ps_bytesperrow);
1342 fprintf(ctx->fd, "%lu %lu %d\n",
1343 (unsigned long) w, (unsigned long) h, ctx->bitspersample);
1344 fprintf(ctx->fd, "[%lu 0 0 -%lu 0 %lu] \n",
1345 (unsigned long) w, (unsigned long) h, (unsigned long) h);
1346 for (i = 0; i < nc; i++)
1347 fprintf(ctx->fd, "{currentfile line%d readhexstring pop}bind\n", i);
1348 fprintf(ctx->fd, "true %d colorimage\n", nc);
1351 #define DOBREAK(len, howmany, fd) \
1352 if (((len) -= (howmany)) <= 0) { \
1354 (len) = MAXLINE-(howmany); \
1356 #define PUTHEX(c,fd) putc(hex[((c)>>4)&0xf],fd); putc(hex[(c)&0xf],fd)
1359 PSDataColorContig(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h, int nc)
1362 int breaklen = MAXLINE, cc, es = ctx->samplesperpixel - nc;
1363 unsigned char *tf_buf;
1364 unsigned char *cp, c;
1367 tf_buf = (unsigned char *) _TIFFmalloc(ctx->tf_bytesperrow);
1368 if (tf_buf == NULL) {
1369 TIFFError(ctx->filename, "No space for scanline buffer");
1372 for (row = 0; row < h; row++) {
1373 if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
1379 for (; cc < ctx->tf_bytesperrow; cc += ctx->samplesperpixel) {
1380 DOBREAK(breaklen, nc, ctx->fd);
1382 * For images with ctx->alpha, matte against
1383 * a white background; i.e.
1384 * Cback * (1 - Aimage)
1387 adjust = 255 - cp[nc];
1389 case 4: c = *cp++ + adjust; PUTHEX(c,ctx->fd);
1390 case 3: c = *cp++ + adjust; PUTHEX(c,ctx->fd);
1391 case 2: c = *cp++ + adjust; PUTHEX(c,ctx->fd);
1392 case 1: c = *cp++ + adjust; PUTHEX(c,ctx->fd);
1398 for (; cc < ctx->tf_bytesperrow; cc += ctx->samplesperpixel) {
1399 DOBREAK(breaklen, nc, ctx->fd);
1401 case 4: c = *cp++; PUTHEX(c,ctx->fd);
1402 case 3: c = *cp++; PUTHEX(c,ctx->fd);
1403 case 2: c = *cp++; PUTHEX(c,ctx->fd);
1404 case 1: c = *cp++; PUTHEX(c,ctx->fd);
1410 _TIFFfree((char *) tf_buf);
1414 PSDataColorSeparate(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h, int nc)
1417 int breaklen = MAXLINE, cc;
1419 unsigned char *tf_buf;
1420 unsigned char *cp, c;
1423 tf_buf = (unsigned char *) _TIFFmalloc(ctx->tf_bytesperrow);
1424 if (tf_buf == NULL) {
1425 TIFFError(ctx->filename, "No space for scanline buffer");
1428 maxs = (ctx->samplesperpixel > nc ? nc : ctx->samplesperpixel);
1429 for (row = 0; row < h; row++) {
1430 for (s = 0; s < maxs; s++) {
1431 if (TIFFReadScanline(tif, tf_buf, row, s) < 0)
1433 for (cp = tf_buf, cc = 0; cc < ctx->tf_bytesperrow; cc++) {
1434 DOBREAK(breaklen, 1, ctx->fd);
1440 _TIFFfree((char *) tf_buf);
1443 #define PUTRGBHEX(c,fd) \
1444 PUTHEX(rmap[c],fd); PUTHEX(gmap[c],fd); PUTHEX(bmap[c],fd)
1447 PSDataPalette(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h)
1449 uint16 *rmap, *gmap, *bmap;
1451 int breaklen = MAXLINE, cc, nc;
1452 unsigned char *tf_buf;
1453 unsigned char *cp, c;
1456 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
1457 TIFFError(ctx->filename, "Palette image w/o \"Colormap\" tag");
1460 switch (ctx->bitspersample) {
1461 case 8: case 4: case 2: case 1:
1464 TIFFError(ctx->filename, "Depth %d not supported", ctx->bitspersample);
1467 nc = 3 * (8 / ctx->bitspersample);
1468 tf_buf = (unsigned char *) _TIFFmalloc(ctx->tf_bytesperrow);
1469 if (tf_buf == NULL) {
1470 TIFFError(ctx->filename, "No space for scanline buffer");
1473 if (checkcmap(ctx, tif, 1<<ctx->bitspersample, rmap, gmap, bmap) == 16) {
1475 #define CVT(x) ((unsigned short) (((x) * 255) / ((1U<<16)-1)))
1476 for (i = (1<<ctx->bitspersample)-1; i >= 0; i--) {
1477 rmap[i] = CVT(rmap[i]);
1478 gmap[i] = CVT(gmap[i]);
1479 bmap[i] = CVT(bmap[i]);
1483 for (row = 0; row < h; row++) {
1484 if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
1486 for (cp = tf_buf, cc = 0; cc < ctx->tf_bytesperrow; cc++) {
1487 DOBREAK(breaklen, nc, ctx->fd);
1488 switch (ctx->bitspersample) {
1490 c = *cp++; PUTRGBHEX(c, ctx->fd);
1493 c = *cp++; PUTRGBHEX(c&0xf, ctx->fd);
1494 c >>= 4; PUTRGBHEX(c, ctx->fd);
1497 c = *cp++; PUTRGBHEX(c&0x3, ctx->fd);
1498 c >>= 2; PUTRGBHEX(c&0x3, ctx->fd);
1499 c >>= 2; PUTRGBHEX(c&0x3, ctx->fd);
1500 c >>= 2; PUTRGBHEX(c, ctx->fd);
1503 c = *cp++; PUTRGBHEX(c&0x1, ctx->fd);
1504 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1505 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1506 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1507 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1508 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1509 c >>= 1; PUTRGBHEX(c&0x1, ctx->fd);
1510 c >>= 1; PUTRGBHEX(c, ctx->fd);
1515 _TIFFfree((char *) tf_buf);
1519 PSDataBW(TIFF2PSContext* ctx, TIFF* tif, uint32 w, uint32 h)
1521 int breaklen = MAXLINE;
1522 unsigned char* tf_buf;
1524 tsize_t stripsize = TIFFStripSize(tif);
1527 #if defined( EXP_ASCII85ENCODER )
1528 int ascii85_l; /* Length, in bytes, of ascii85_p[] data */
1529 uint8 *ascii85_p = 0; /* Holds ASCII85 encoded data */
1533 tf_buf = (unsigned char *) _TIFFmalloc(stripsize);
1534 memset(tf_buf, 0, stripsize);
1535 if (tf_buf == NULL) {
1536 TIFFError(ctx->filename, "No space for scanline buffer");
1540 #if defined( EXP_ASCII85ENCODER )
1541 if ( ctx->ascii85 ) {
1543 * Allocate a buffer to hold the ASCII85 encoded data. Note
1544 * that it is allocated with sufficient room to hold the
1545 * encoded data (5*stripsize/4) plus the EOD marker (+8)
1546 * and formatting line breaks. The line breaks are more
1547 * than taken care of by using 6*stripsize/4 rather than
1551 ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 );
1554 _TIFFfree( tf_buf );
1556 TIFFError( ctx->filename,
1557 "Cannot allocate ASCII85 encoding buffer." );
1566 for (s = 0; s < TIFFNumberOfStrips(tif); s++) {
1567 int cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize);
1569 TIFFError(ctx->filename, "Can't read strip");
1573 if (ctx->photometric == PHOTOMETRIC_MINISWHITE) {
1574 for (cp += cc; --cp >= tf_buf;)
1579 #if defined( EXP_ASCII85ENCODER )
1582 for (i = 0; i < cc; i+=2) {
1583 adjust = 255 - cp[i + 1];
1584 cp[i / 2] = cp[i] + adjust;
1589 ascii85_l = Ascii85EncodeBlock(ctx, ascii85_p, 1, cp,
1592 if ( ascii85_l > 0 )
1593 fwrite( ascii85_p, ascii85_l, 1, ctx->fd );
1596 Ascii85Put(ctx, *cp++);
1597 #endif /* EXP_ASCII85_ENCODER */
1604 DOBREAK(breaklen, 1, ctx->fd);
1606 * For images with ctx->alpha, matte against
1607 * a white background; i.e.
1608 * Cback * (1 - Aimage)
1611 adjust = 255 - cp[1];
1612 c = *cp++ + adjust; PUTHEX(c,ctx->fd);
1618 DOBREAK(breaklen, 1, ctx->fd);
1625 if ( !ctx->ascii85 )
1627 if ( ctx->level2 || ctx->level3)
1628 fputs(">\n", ctx->fd);
1630 #if !defined( EXP_ASCII85ENCODER )
1635 _TIFFfree( ascii85_p );
1642 Ascii85Init(TIFF2PSContext *ctx)
1644 ctx->ascii85breaklen = 2*MAXLINE;
1645 ctx->ascii85count = 0;
1649 Ascii85Encode(unsigned char* raw, char *buf)
1653 word = (((raw[0]<<8)+raw[1])<<16) + (raw[2]<<8) + raw[3];
1658 q = word / (85L*85*85*85); /* actually only a byte */
1659 buf[0] = (char) (q + '!');
1661 word -= q * (85L*85*85*85); q = word / (85L*85*85);
1662 buf[1] = (char) (q + '!');
1664 word -= q * (85L*85*85); q = word / (85*85);
1665 buf[2] = (char) (q + '!');
1667 w1 = (uint16) (word - q*(85L*85));
1668 buf[3] = (char) ((w1 / 85) + '!');
1669 buf[4] = (char) ((w1 % 85) + '!');
1672 buf[0] = 'z', buf[1] = '\0';
1676 Ascii85Put(TIFF2PSContext *ctx, unsigned char code)
1678 ctx->ascii85buf[ctx->ascii85count++] = code;
1679 if (ctx->ascii85count >= 4) {
1684 for (n = ctx->ascii85count, p = ctx->ascii85buf;
1685 n >= 4; n -= 4, p += 4) {
1687 Ascii85Encode(p, buf);
1688 for (cp = buf; *cp; cp++) {
1690 if (--ctx->ascii85breaklen == 0) {
1691 putc('\n', ctx->fd);
1692 ctx->ascii85breaklen = 2*MAXLINE;
1696 _TIFFmemcpy(ctx->ascii85buf, p, n);
1697 ctx->ascii85count = n;
1702 Ascii85Flush(TIFF2PSContext* ctx)
1704 if (ctx->ascii85count > 0) {
1706 _TIFFmemset(&ctx->ascii85buf[ctx->ascii85count], 0, 3);
1707 Ascii85Encode(ctx->ascii85buf, res);
1708 fwrite(res[0] == 'z' ? "!!!!" : res, ctx->ascii85count + 1, 1, ctx->fd);
1710 fputs("~>\n", ctx->fd);
1712 #if defined( EXP_ASCII85ENCODER)
1714 #define A85BREAKCNTR ctx->ascii85breaklen
1715 #define A85BREAKLEN (2*MAXLINE)
1717 /*****************************************************************************
1719 * Name: Ascii85EncodeBlock( ascii85_p, f_eod, raw_p, raw_l )
1721 * Description: This routine will encode the raw data in the buffer described
1722 * by raw_p and raw_l into ASCII85 format and store the encoding
1723 * in the buffer given by ascii85_p.
1725 * Parameters: ctx - TIFF2PS context
1726 * ascii85_p - A buffer supplied by the caller which will
1727 * contain the encoded ASCII85 data.
1728 * f_eod - Flag: Nz means to end the encoded buffer with
1729 * an End-Of-Data marker.
1730 * raw_p - Pointer to the buffer of data to be encoded
1731 * raw_l - Number of bytes in raw_p[] to be encoded
1733 * Returns: (int) < 0 Error, see errno
1734 * >= 0 Number of bytes written to ascii85_p[].
1736 * Notes: An external variable given by A85BREAKCNTR is used to
1737 * determine when to insert newline characters into the
1738 * encoded data. As each byte is placed into ascii85_p this
1739 * external is decremented. If the variable is decrement to
1740 * or past zero then a newline is inserted into ascii85_p
1741 * and the A85BREAKCNTR is then reset to A85BREAKLEN.
1742 * Note: for efficiency reasons the A85BREAKCNTR variable
1743 * is not actually checked on *every* character
1744 * placed into ascii85_p but often only for every
1747 * THE CALLER IS RESPONSIBLE FOR ENSURING THAT ASCII85_P[] IS
1748 * SUFFICIENTLY LARGE TO THE ENCODED DATA!
1749 * You will need at least 5 * (raw_l/4) bytes plus space for
1750 * newline characters and space for an EOD marker (if
1751 * requested). A safe calculation is to use 6*(raw_l/4) + 8
1752 * to size ascii85_p.
1754 *****************************************************************************/
1756 int Ascii85EncodeBlock( TIFF2PSContext *ctx, uint8 * ascii85_p,
1757 unsigned f_eod, const uint8 * raw_p, int raw_l )
1760 char ascii85[5]; /* Encoded 5 tuple */
1761 int ascii85_l; /* Number of bytes written to ascii85_p[] */
1762 int rc; /* Return code */
1763 uint32 val32; /* Unencoded 4 tuple */
1765 ascii85_l = 0; /* Nothing written yet */
1769 --raw_p; /* Prepare for pre-increment fetches */
1771 for ( ; raw_l > 3; raw_l -= 4 )
1773 val32 = *(++raw_p) << 24;
1774 val32 += *(++raw_p) << 16;
1775 val32 += *(++raw_p) << 8;
1776 val32 += *(++raw_p);
1778 if ( val32 == 0 ) /* Special case */
1780 ascii85_p[ascii85_l] = 'z';
1786 ascii85[4] = (char) ((val32 % 85) + 33);
1789 ascii85[3] = (char) ((val32 % 85) + 33);
1792 ascii85[2] = (char) ((val32 % 85) + 33);
1795 ascii85[1] = (char) ((val32 % 85) + 33);
1796 ascii85[0] = (char) ((val32 / 85) + 33);
1798 _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, sizeof(ascii85) );
1799 rc = sizeof(ascii85);
1804 if ( (A85BREAKCNTR -= rc) <= 0 )
1806 ascii85_p[ascii85_l] = '\n';
1808 A85BREAKCNTR = A85BREAKLEN;
1813 * Output any straggler bytes:
1818 int len; /* Output this many bytes */
1821 val32 = *++raw_p << 24; /* Prime the pump */
1823 if ( --raw_l > 0 ) val32 += *(++raw_p) << 16;
1824 if ( --raw_l > 0 ) val32 += *(++raw_p) << 8;
1828 ascii85[3] = (char) ((val32 % 85) + 33);
1831 ascii85[2] = (char) ((val32 % 85) + 33);
1834 ascii85[1] = (char) ((val32 % 85) + 33);
1835 ascii85[0] = (char) ((val32 / 85) + 33);
1837 _TIFFmemcpy( &ascii85_p[ascii85_l], ascii85, len );
1843 * If requested add an ASCII85 End Of Data marker:
1848 ascii85_p[ascii85_l++] = '~';
1849 ascii85_p[ascii85_l++] = '>';
1850 ascii85_p[ascii85_l++] = '\n';
1853 return ( ascii85_l );
1855 } /* Ascii85EncodeBlock() */
1857 #endif /* EXP_ASCII85ENCODER */
1859 /* vim: set ts=8 sts=8 sw=8 noet: */