]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/fax2ps.c
   4  * Copyright (c) 1991-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   7  * Permission to use, copy, modify, distribute, and sell this software and  
   8  * its documentation for any purpose is hereby granted without fee, provided 
   9  * that (i) the above copyright notices and this permission notice appear in 
  10  * all copies of the software and related documentation, and (ii) the names of 
  11  * Sam Leffler and Silicon Graphics may not be used in any advertising or 
  12  * publicity relating to the software without the specific, prior written 
  13  * permission of Sam Leffler and Silicon Graphics. 
  15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  
  16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  
  17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
  19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 
  20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 
  21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  
  23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  
  26 #include "tif_config.h" 
  44 float   defxres 
= 204.;         /* default x resolution (pixels/inch) */ 
  45 float   defyres 
= 98.;          /* default y resolution (lines/inch) */ 
  46 const float half 
= 0.5; 
  47 const float points 
= 72.0; 
  48 float   pageWidth 
= 0;          /* image page width (inches) */ 
  49 float   pageHeight 
= 0;         /* image page length (inches) */ 
  50 int     scaleToPage 
= 0;        /* if true, scale raster to page dimensions */ 
  51 int     totalPages 
= 0;         /* total # pages printed */ 
  52 int     row
;                    /* current output row */ 
  53 int     maxline 
= 512;          /* max output line of PostScript */ 
  56  * Turn a bit-mapped scanline into the appropriate sequence 
  57  * of PostScript characters to be rendered. 
  59  * Original version written by Bret D. Whissel, 
  60  * Florida State University Meteorology Department 
  64 printruns(unsigned char* buf
, uint32
* runs
, uint32
* erun
, uint32 lastx
) 
  70         { 'd', 'n', 512 }, { 'e', 'o', 256 }, { 'f', 'p', 128 }, 
  71         { 'g', 'q',  64 }, { 'h', 'r',  32 }, { 'i', 's',  16 }, 
  72         { 'j', 't',   8 }, { 'k', 'u',   4 }, { 'l', 'v',   2 }, 
  76         " !\"#$&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abc"; 
  77     int colormode 
= 1;          /* 0 for white, 1 for black */ 
  84     printf("%d m(", row
++); 
  89             if (x
+runlength 
> lastx
) 
  90                 runlength 
= runs
[-1] = lastx
-x
; 
  92             if (!colormode 
&& runs 
== erun
)      
  93                 break;          /* don't bother printing the final white run */ 
  96          * If a runlength is greater than 6 pixels, then spit out 
  97          * black or white characters until the runlength drops to 
  98          * 6 or less.  Once a runlength is <= 6, then combine black 
  99          * and white runlengths until a 6-pixel pattern is obtained. 
 100          * Then write out the special character.  Six-pixel patterns 
 101          * were selected since 64 patterns is the largest power of 
 102          * two less than the 92 "easily printable" PostScript 
 103          * characters (i.e., no escape codes or octal chars). 
 106         while (runlength 
> 6) { /* Run is greater than six... */ 
 107             if (runlength 
>= WBarr
[l
].width
) { 
 112                 putchar(colormode 
? WBarr
[l
].black 
: WBarr
[l
].white
), n
--; 
 113                 runlength 
-= WBarr
[l
].width
; 
 117         while (runlength 
> 0 && runlength 
<= 6) { 
 121                 if (runlength 
<= bitsleft
) { 
 123                         t 
|= ((1 << runlength
)-1) << (bitsleft
-runlength
); 
 124                     bitsleft 
-= runlength
; 
 131                         if (x
+runlength 
> lastx
) 
 132                             runlength 
= runs
[-1] = lastx
-x
; 
 135                 } else {                /* runlength exceeds bits left */ 
 137                         t 
|= ((1 << bitsleft
)-1); 
 138                     runlength 
-= bitsleft
; 
 146             putchar(svalue
[t
]), n
--; 
 153  * Create a special PostScript font for printing FAX documents.  By taking 
 154  * advantage of the font-cacheing mechanism, a substantial speed-up in  
 155  * rendering time is realized.  
 160     static const char* fontPrologue
[] = { 
 161         "/newfont 10 dict def newfont begin /FontType 3 def /FontMatrix [1", 
 162         "0 0 1 0 0] def /FontBBox [0 0 512 1] def /Encoding 256 array def", 
 163         "0 1 31{Encoding exch /255 put}for 120 1 255{Encoding exch /255", 
 164         "put}for Encoding 37 /255 put Encoding 40 /255 put Encoding 41 /255", 
 165         "put Encoding 92 /255 put /count 0 def /ls{Encoding exch count 3", 
 166         "string cvs cvn put /count count 1 add def}def 32 1 36{ls}for", 
 167         "38 1 39{ls}for 42 1 91{ls}for 93 1 99{ls}for /count 100", 
 168         "def 100 1 119{ls}for /CharDict 5 dict def CharDict begin /white", 
 169         "{dup 255 eq{pop}{1 dict begin 100 sub neg 512 exch bitshift", 
 170         "/cw exch def cw 0 0 0 cw 1 setcachedevice end}ifelse}def /black", 
 171         "{dup 255 eq{pop}{1 dict begin 110 sub neg 512 exch bitshift", 
 172         "/cw exch def cw 0 0 0 cw 1 setcachedevice 0 0 moveto cw 0 rlineto", 
 173         "0 1 rlineto cw neg 0 rlineto closepath fill end}ifelse}def /numbuild", 
 174         "{dup 255 eq{pop}{6 0 0 0 6 1 setcachedevice 0 1 5{0 moveto", 
 175         "dup 32 and 32 eq{1 0 rlineto 0 1 rlineto -1 0 rlineto closepath", 
 176         "fill newpath}if 1 bitshift}for pop}ifelse}def /.notdef {}", 
 177         "def /255 {}def end /BuildChar{exch begin dup 110 ge{Encoding", 
 178         "exch get 3 string cvs cvi CharDict /black get}{dup 100 ge {Encoding", 
 179         "exch get 3 string cvs cvi CharDict /white get}{Encoding exch get", 
 180         "3 string cvs cvi CharDict /numbuild get}ifelse}ifelse exec end", 
 181         "}def end /Bitfont newfont definefont 1 scalefont setfont", 
 185     for (i 
= 0; fontPrologue
[i
] != NULL
; i
++) 
 186         fprintf(fd
, "%s\n", fontPrologue
[i
]); 
 190 printTIF(TIFF
* tif
, uint16 pageNumber
) 
 193     uint16 unit
, compression
; 
 194     float xres
, yres
, scale 
= 1.0; 
 196     time_t creation_time
; 
 198     TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &h
); 
 199     TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &w
); 
 200     if (!TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compression
) 
 201         || compression 
< COMPRESSION_CCITTRLE
 
 202         || compression 
> COMPRESSION_CCITT_T6
) 
 204     if (!TIFFGetField(tif
, TIFFTAG_XRESOLUTION
, &xres
) || !xres
) { 
 205         TIFFWarning(TIFFFileName(tif
), 
 206             "No x-resolution, assuming %g dpi", defxres
); 
 209     if (!TIFFGetField(tif
, TIFFTAG_YRESOLUTION
, &yres
) || !yres
) { 
 210         TIFFWarning(TIFFFileName(tif
), 
 211             "No y-resolution, assuming %g lpi", defyres
); 
 212         yres 
= defyres
;                                 /* XXX */ 
 214     if (TIFFGetField(tif
, TIFFTAG_RESOLUTIONUNIT
, &unit
) && 
 215       unit 
== RESUNIT_CENTIMETER
) { 
 220         pageWidth 
= w 
/ xres
; 
 222         pageHeight 
= h 
/ yres
; 
 224     printf("%%!PS-Adobe-3.0\n"); 
 225     printf("%%%%Creator: fax2ps\n"); 
 227     printf("%%%%Title: %s\n", file
); 
 229     creation_time 
= time(0); 
 230     printf("%%%%CreationDate: %s", ctime(&creation_time
)); 
 231     printf("%%%%Origin: 0 0\n"); 
 232     printf("%%%%BoundingBox: 0 0 %u %u\n", 
 233         (int)(pageWidth 
* points
), (int)(pageHeight 
* points
)); /* XXX */ 
 234     printf("%%%%Pages: (atend)\n"); 
 235     printf("%%%%EndComments\n"); 
 236     printf("%%%%BeginProlog\n"); 
 238     printf("/d{bind def}def\n"); /* bind and def proc */ 
 239     printf("/m{0 exch moveto}d\n"); 
 240     printf("/s{show}d\n"); 
 241     printf("/p{showpage}d \n"); /* end page */ 
 242     printf("%%%%EndProlog\n"); 
 243     printf("%%%%Page: \"%u\" %u\n", pageNumber
, pageNumber
); 
 244     printf("/$pageTop save def gsave\n"); 
 246         scale 
= pageHeight 
/ (h
/yres
) < pageWidth 
/ (w
/xres
) ? 
 247             pageHeight 
/ (h
/yres
) : pageWidth 
/ (w
/xres
); 
 248     printf("%g %g translate\n", 
 249            points 
* (pageWidth 
- scale
*w
/xres
) * half
, 
 250            points 
* (scale
*h
/yres 
+ (pageHeight 
- scale
*h
/yres
) * half
)); 
 251     printf("%g %g scale\n", points
/xres
*scale
, -points
/yres
*scale
); 
 252     printf("0 setgray\n"); 
 253     TIFFSetField(tif
, TIFFTAG_FAXFILLFUNC
, printruns
); 
 254     ns 
= TIFFNumberOfStrips(tif
); 
 256     for (s 
= 0; s 
< ns
; s
++) 
 257         (void) TIFFReadEncodedStrip(tif
, s
, (tdata_t
) NULL
, (tsize_t
) -1); 
 259     printf("grestore $pageTop restore\n"); 
 263 #define GetPageNumber(tif) \ 
 264 TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pn, &ptotal) 
 267 findPage(TIFF
* tif
, uint16 pageNumber
) 
 269     uint16 pn 
= (uint16
) -1; 
 270     uint16 ptotal 
= (uint16
) -1; 
 271     if (GetPageNumber(tif
)) { 
 272         while (pn 
!= pageNumber 
&& TIFFReadDirectory(tif
) && GetPageNumber(tif
)) 
 274         return (pn 
== pageNumber
); 
 276         return (TIFFSetDirectory(tif
, (tdir_t
)(pageNumber
-1))); 
 280 fax2ps(TIFF
* tif
, uint16 npages
, uint16
* pages
, char* filename
) 
 286         if (!GetPageNumber(tif
)) 
 287             fprintf(stderr
, "%s: No page numbers, counting directories.\n", 
 289         for (i 
= 0; i 
< npages
; i
++) { 
 290             if (findPage(tif
, pages
[i
])) 
 291                 printTIF(tif
, pages
[i
]); 
 293                 fprintf(stderr
, "%s: No page number %d\n", filename
, pages
[i
]); 
 296         uint16 pageNumber 
= 0; 
 298             printTIF(tif
, pageNumber
++); 
 299         while (TIFFReadDirectory(tif
)); 
 306 pcompar(const void* va
, const void* vb
) 
 308     const int* pa 
= (const int*) va
; 
 309     const int* pb 
= (const int*) vb
; 
 313 static  void usage(int code
); 
 316 main(int argc
, char** argv
) 
 320     uint16 
*pages 
= NULL
, npages 
= 0, pageNumber
; 
 321     int c
, dowarnings 
= 0;              /* if 1, enable library warnings */ 
 324     while ((c 
= getopt(argc
, argv
, "l:p:x:y:W:H:wS")) != -1) 
 326         case 'H':               /* page height */ 
 327             pageHeight 
= (float)atof(optarg
); 
 329         case 'S':               /* scale to page */ 
 332         case 'W':               /* page width */ 
 333             pageWidth 
= (float)atof(optarg
); 
 335         case 'p':               /* print specific page */ 
 336             pageNumber 
= (uint16
)atoi(optarg
); 
 338                 pages 
= (uint16
*) realloc(pages
, (npages
+1)*sizeof(uint16
)); 
 340                 pages 
= (uint16
*) malloc(sizeof(uint16
)); 
 341             pages
[npages
++] = pageNumber
; 
 347             defxres 
= (float)atof(optarg
); 
 350             defyres 
= (float)atof(optarg
); 
 353             maxline 
= atoi(optarg
); 
 359         qsort(pages
, npages
, sizeof(uint16
), pcompar
); 
 361         TIFFSetWarningHandler(0); 
 364             tif 
= TIFFOpen(argv
[optind
], "r"); 
 366                 fax2ps(tif
, npages
, pages
, argv
[optind
]); 
 369                 fprintf(stderr
, "%s: Can not open, or not a TIFF file.\n", 
 371         } while (++optind 
< argc
); 
 379             fprintf(stderr
, "Could not create temporary file, exiting.\n"); 
 383         while ((n 
= read(fileno(stdin
), buf
, sizeof (buf
))) > 0) 
 384             write(fileno(fd
), buf
, n
); 
 385         lseek(fileno(fd
), 0, SEEK_SET
); 
 386 #if defined(_WIN32) && defined(USE_WIN32_FILEIO) 
 387         tif 
= TIFFFdOpen(_get_osfhandle(fileno(fd
)), "temp", "r"); 
 389         tif 
= TIFFFdOpen(fileno(fd
), "temp", "r"); 
 392             fax2ps(tif
, npages
, pages
, "<stdin>"); 
 395             fprintf(stderr
, "Can not open, or not a TIFF file.\n"); 
 398     printf("%%%%Trailer\n"); 
 399     printf("%%%%Pages: %u\n", totalPages
); 
 406 "usage: fax2ps [options] [input.tif ...]", 
 407 "where options are:", 
 408 " -w            suppress warning messages", 
 409 " -l chars      set maximum output line length for generated PostScript", 
 410 " -p page#      select page to print (can use multiple times)", 
 411 " -x xres       set default horizontal resolution of input data (dpi)", 
 412 " -y yres       set default vertical resolution of input data (lpi)", 
 413 " -S            scale output to page size", 
 414 " -W width      set output page width (inches), default is 8.5", 
 415 " -H height     set output page height (inches), default is 11", 
 426         fprintf(stderr
, "%s\n\n", TIFFGetVersion()); 
 427         for (i 
= 0; stuff
[i
] != NULL
; i
++) 
 428                 fprintf(stderr
, "%s\n", stuff
[i
]); 
 432 /* vim: set ts=8 sts=8 sw=8 noet: */