]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/fax2ps.c
3 * Copyright (c) 1991-1997 Sam Leffler
4 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 #include "tif_config.h"
51 float defxres
= 204.; /* default x resolution (pixels/inch) */
52 float defyres
= 98.; /* default y resolution (lines/inch) */
53 const float half
= 0.5;
54 const float points
= 72.0;
55 float pageWidth
= 0; /* image page width (inches) */
56 float pageHeight
= 0; /* image page length (inches) */
57 int scaleToPage
= 0; /* if true, scale raster to page dimensions */
58 int totalPages
= 0; /* total # pages printed */
59 int row
; /* current output row */
60 int maxline
= 512; /* max output line of PostScript */
63 * Turn a bit-mapped scanline into the appropriate sequence
64 * of PostScript characters to be rendered.
66 * Original version written by Bret D. Whissel,
67 * Florida State University Meteorology Department
71 printruns(unsigned char* buf
, uint32
* runs
, uint32
* erun
, uint32 lastx
)
77 { 'd', 'n', 512 }, { 'e', 'o', 256 }, { 'f', 'p', 128 },
78 { 'g', 'q', 64 }, { 'h', 'r', 32 }, { 'i', 's', 16 },
79 { 'j', 't', 8 }, { 'k', 'u', 4 }, { 'l', 'v', 2 },
83 " !\"#$&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abc";
84 int colormode
= 1; /* 0 for white, 1 for black */
91 printf("%d m(", row
++);
96 if (x
+runlength
> lastx
)
97 runlength
= runs
[-1] = lastx
-x
;
99 if (!colormode
&& runs
== erun
)
100 break; /* don't bother printing the final white run */
103 * If a runlength is greater than 6 pixels, then spit out
104 * black or white characters until the runlength drops to
105 * 6 or less. Once a runlength is <= 6, then combine black
106 * and white runlengths until a 6-pixel pattern is obtained.
107 * Then write out the special character. Six-pixel patterns
108 * were selected since 64 patterns is the largest power of
109 * two less than the 92 "easily printable" PostScript
110 * characters (i.e., no escape codes or octal chars).
113 while (runlength
> 6) { /* Run is greater than six... */
114 if (runlength
>= WBarr
[l
].width
) {
119 putchar(colormode
? WBarr
[l
].black
: WBarr
[l
].white
), n
--;
120 runlength
-= WBarr
[l
].width
;
124 while (runlength
> 0 && runlength
<= 6) {
128 if (runlength
<= bitsleft
) {
130 t
|= ((1 << runlength
)-1) << (bitsleft
-runlength
);
131 bitsleft
-= runlength
;
138 if (x
+runlength
> lastx
)
139 runlength
= runs
[-1] = lastx
-x
;
142 } else { /* runlength exceeds bits left */
144 t
|= ((1 << bitsleft
)-1);
145 runlength
-= bitsleft
;
153 putchar(svalue
[t
]), n
--;
160 * Create a special PostScript font for printing FAX documents. By taking
161 * advantage of the font-cacheing mechanism, a substantial speed-up in
162 * rendering time is realized.
167 static const char* fontPrologue
[] = {
168 "/newfont 10 dict def newfont begin /FontType 3 def /FontMatrix [1",
169 "0 0 1 0 0] def /FontBBox [0 0 512 1] def /Encoding 256 array def",
170 "0 1 31{Encoding exch /255 put}for 120 1 255{Encoding exch /255",
171 "put}for Encoding 37 /255 put Encoding 40 /255 put Encoding 41 /255",
172 "put Encoding 92 /255 put /count 0 def /ls{Encoding exch count 3",
173 "string cvs cvn put /count count 1 add def}def 32 1 36{ls}for",
174 "38 1 39{ls}for 42 1 91{ls}for 93 1 99{ls}for /count 100",
175 "def 100 1 119{ls}for /CharDict 5 dict def CharDict begin /white",
176 "{dup 255 eq{pop}{1 dict begin 100 sub neg 512 exch bitshift",
177 "/cw exch def cw 0 0 0 cw 1 setcachedevice end}ifelse}def /black",
178 "{dup 255 eq{pop}{1 dict begin 110 sub neg 512 exch bitshift",
179 "/cw exch def cw 0 0 0 cw 1 setcachedevice 0 0 moveto cw 0 rlineto",
180 "0 1 rlineto cw neg 0 rlineto closepath fill end}ifelse}def /numbuild",
181 "{dup 255 eq{pop}{6 0 0 0 6 1 setcachedevice 0 1 5{0 moveto",
182 "dup 32 and 32 eq{1 0 rlineto 0 1 rlineto -1 0 rlineto closepath",
183 "fill newpath}if 1 bitshift}for pop}ifelse}def /.notdef {}",
184 "def /255 {}def end /BuildChar{exch begin dup 110 ge{Encoding",
185 "exch get 3 string cvs cvi CharDict /black get}{dup 100 ge {Encoding",
186 "exch get 3 string cvs cvi CharDict /white get}{Encoding exch get",
187 "3 string cvs cvi CharDict /numbuild get}ifelse}ifelse exec end",
188 "}def end /Bitfont newfont definefont 1 scalefont setfont",
192 for (i
= 0; fontPrologue
[i
] != NULL
; i
++)
193 fprintf(fd
, "%s\n", fontPrologue
[i
]);
197 printTIF(TIFF
* tif
, uint16 pageNumber
)
200 uint16 unit
, compression
;
201 float xres
, yres
, scale
= 1.0;
203 time_t creation_time
;
205 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &h
);
206 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &w
);
207 if (!TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compression
)
208 || compression
< COMPRESSION_CCITTRLE
209 || compression
> COMPRESSION_CCITT_T6
)
211 if (!TIFFGetField(tif
, TIFFTAG_XRESOLUTION
, &xres
) || !xres
) {
212 TIFFWarning(TIFFFileName(tif
),
213 "No x-resolution, assuming %g dpi", defxres
);
216 if (!TIFFGetField(tif
, TIFFTAG_YRESOLUTION
, &yres
) || !yres
) {
217 TIFFWarning(TIFFFileName(tif
),
218 "No y-resolution, assuming %g lpi", defyres
);
219 yres
= defyres
; /* XXX */
221 if (TIFFGetField(tif
, TIFFTAG_RESOLUTIONUNIT
, &unit
) &&
222 unit
== RESUNIT_CENTIMETER
) {
227 pageWidth
= w
/ xres
;
229 pageHeight
= h
/ yres
;
231 printf("%%!PS-Adobe-3.0\n");
232 printf("%%%%Creator: fax2ps\n");
234 printf("%%%%Title: %s\n", file
);
236 creation_time
= time(0);
237 printf("%%%%CreationDate: %s", ctime(&creation_time
));
238 printf("%%%%Origin: 0 0\n");
239 printf("%%%%BoundingBox: 0 0 %u %u\n",
240 (int)(pageWidth
* points
), (int)(pageHeight
* points
)); /* XXX */
241 printf("%%%%Pages: (atend)\n");
242 printf("%%%%EndComments\n");
243 printf("%%%%BeginProlog\n");
245 printf("/d{bind def}def\n"); /* bind and def proc */
246 printf("/m{0 exch moveto}d\n");
247 printf("/s{show}d\n");
248 printf("/p{showpage}d \n"); /* end page */
249 printf("%%%%EndProlog\n");
250 printf("%%%%Page: \"%u\" %u\n", pageNumber
, pageNumber
);
251 printf("/$pageTop save def gsave\n");
253 scale
= pageHeight
/ (h
/yres
) < pageWidth
/ (w
/xres
) ?
254 pageHeight
/ (h
/yres
) : pageWidth
/ (w
/xres
);
255 printf("%g %g translate\n",
256 points
* (pageWidth
- scale
*w
/xres
) * half
,
257 points
* (scale
*h
/yres
+ (pageHeight
- scale
*h
/yres
) * half
));
258 printf("%g %g scale\n", points
/xres
*scale
, -points
/yres
*scale
);
259 printf("0 setgray\n");
260 TIFFSetField(tif
, TIFFTAG_FAXFILLFUNC
, printruns
);
261 ns
= TIFFNumberOfStrips(tif
);
263 for (s
= 0; s
< ns
; s
++)
264 (void) TIFFReadEncodedStrip(tif
, s
, (tdata_t
) NULL
, (tsize_t
) -1);
266 printf("grestore $pageTop restore\n");
270 #define GetPageNumber(tif) \
271 TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pn, &ptotal)
274 findPage(TIFF
* tif
, uint16 pageNumber
)
276 uint16 pn
= (uint16
) -1;
277 uint16 ptotal
= (uint16
) -1;
278 if (GetPageNumber(tif
)) {
279 while (pn
!= (pageNumber
-1) && TIFFReadDirectory(tif
) && GetPageNumber(tif
))
281 return (pn
== (pageNumber
-1));
283 return (TIFFSetDirectory(tif
, (tdir_t
)(pageNumber
-1)));
287 fax2ps(TIFF
* tif
, uint16 npages
, uint16
* pages
, char* filename
)
293 if (!GetPageNumber(tif
))
294 fprintf(stderr
, "%s: No page numbers, counting directories.\n",
296 for (i
= 0; i
< npages
; i
++) {
297 if (findPage(tif
, pages
[i
]))
298 printTIF(tif
, pages
[i
]);
300 fprintf(stderr
, "%s: No page number %d\n", filename
, pages
[i
]);
303 uint16 pageNumber
= 0;
305 printTIF(tif
, pageNumber
++);
306 while (TIFFReadDirectory(tif
));
313 pcompar(const void* va
, const void* vb
)
315 const int* pa
= (const int*) va
;
316 const int* pb
= (const int*) vb
;
320 static void usage(int code
);
323 main(int argc
, char** argv
)
327 uint16
*pages
= NULL
, npages
= 0, pageNumber
;
328 int c
, dowarnings
= 0; /* if 1, enable library warnings */
331 while ((c
= getopt(argc
, argv
, "l:p:x:y:W:H:wS")) != -1)
333 case 'H': /* page height */
334 pageHeight
= (float)atof(optarg
);
336 case 'S': /* scale to page */
339 case 'W': /* page width */
340 pageWidth
= (float)atof(optarg
);
342 case 'p': /* print specific page */
343 pageNumber
= (uint16
)atoi(optarg
);
345 pages
= (uint16
*) realloc(pages
, (npages
+1)*sizeof(uint16
));
347 pages
= (uint16
*) malloc(sizeof(uint16
));
348 pages
[npages
++] = pageNumber
;
354 defxres
= (float)atof(optarg
);
357 defyres
= (float)atof(optarg
);
360 maxline
= atoi(optarg
);
366 qsort(pages
, npages
, sizeof(uint16
), pcompar
);
368 TIFFSetWarningHandler(0);
371 tif
= TIFFOpen(argv
[optind
], "r");
373 fax2ps(tif
, npages
, pages
, argv
[optind
]);
376 fprintf(stderr
, "%s: Can not open, or not a TIFF file.\n",
378 } while (++optind
< argc
);
386 fprintf(stderr
, "Could not obtain temporary file.\n");
389 #if defined(HAVE_SETMODE) && defined(O_BINARY)
390 setmode(fileno(stdin
), O_BINARY
);
392 while ((n
= read(fileno(stdin
), buf
, sizeof (buf
))) > 0)
393 write(fileno(fd
), buf
, n
);
394 lseek(fileno(fd
), 0, SEEK_SET
);
395 #if defined(_WIN32) && defined(USE_WIN32_FILEIO)
396 tif
= TIFFFdOpen(_get_osfhandle(fileno(fd
)), "temp", "r");
398 tif
= TIFFFdOpen(fileno(fd
), "temp", "r");
401 fax2ps(tif
, npages
, pages
, "<stdin>");
404 fprintf(stderr
, "Can not open, or not a TIFF file.\n");
407 printf("%%%%Trailer\n");
408 printf("%%%%Pages: %u\n", totalPages
);
415 "usage: fax2ps [options] [input.tif ...]",
416 "where options are:",
417 " -w suppress warning messages",
418 " -l chars set maximum output line length for generated PostScript",
419 " -p page# select page to print (can use multiple times)",
420 " -x xres set default horizontal resolution of input data (dpi)",
421 " -y yres set default vertical resolution of input data (lpi)",
422 " -S scale output to page size",
423 " -W width set output page width (inches), default is 8.5",
424 " -H height set output page height (inches), default is 11",
435 fprintf(stderr
, "%s\n\n", TIFFGetVersion());
436 for (i
= 0; stuff
[i
] != NULL
; i
++)
437 fprintf(stderr
, "%s\n", stuff
[i
]);
441 /* vim: set ts=8 sts=8 sw=8 noet: */