xref: /plan9/sys/src/cmd/postscript/postgif/postgif.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 
2 #include <stdio.h>
3 #include <string.h>
4 #include <signal.h>
5 #include <ctype.h>
6 #ifdef plan9
7 #define	isascii(c)	((unsigned char)(c)<=0177)
8 #endif
9 #include <sys/types.h>
10 #include <fcntl.h>
11 
12 #include "comments.h"
13 #include "gen.h"
14 #include "path.h"
15 #include "ext.h"
16 
17 #define dbprt	if (debug) fprintf
18 
19 char	*optnames = "a:c:fglm:n:o:p:x:y:C:E:DG:IL:P:";
20 char    *prologue = POSTGIF;		/* default PostScript prologue */
21 char    *formfile = FORMFILE;           /* stuff for multiple pages per sheet */
22 int     formsperpage = 1;               /* page images on each piece of paper */
23 int	copies = 1;                     /* and this many copies of each sheet */
24 int     page = 0;                       /* last page we worked on */
25 int     printed = 0;                    /* and the number of pages printed */
26 
27 extern char *malloc();
28 extern void free();
29 extern double atof(), pow();
30 
31 unsigned char ibuf[BUFSIZ];
32 unsigned char *cmap, *gcmap, *lcmap;
33 unsigned char *gmap, *ggmap, *lgmap;
34 unsigned char *pmap;
35 double gamma;
36 float cr = 0.3, cg = 0.59, cb = 0.11;
37 int maplength, gmaplength, lmaplength;
38 int scrwidth, scrheight;
39 int gcolormap, lcolormap;
40 int bitperpixel, background;
41 int imageleft, imagetop;
42 int imagewidth, imageheight;
43 int interlaced, lbitperpixel;
44 int gray = 0;
45 int gammaflag = 0;
46 int negative = 0;
47 int terminate = 0;
48 int codesize, clearcode, endcode, curstblsize, pmindex, byteinibuf, bitsleft;
49 int prefix[4096], suffix[4096], cstbl[4096];
50 int bburx = -32767, bbury = -32767;
51 FILE *fp_in = NULL;
52 FILE *fp_out = stdout;
53 
54 char *
allocate(size)55 allocate(size)
56     int size;
57 {
58     char *p;
59 
60     if ((p = malloc(size)) == NULL) error(FATAL, "not enough memory");
61     return(p);
62 }
63 
64 void
puthex(c,fp)65 puthex(c, fp)
66     unsigned char c;
67     FILE *fp;
68 {
69     static char hextbl[16] = {
70 	'0', '1', '2', '3', '4', '5', '6', '7',
71 	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
72     };
73 
74     putc(hextbl[(c >> 4) & 017], fp);
75     putc(hextbl[c & 017], fp);
76 }
77 
78 void
setcolormap(bp)79 setcolormap(bp)
80     int bp;
81 {
82     int i, entries = 1, scale = 1;
83     unsigned char *p, *q;
84 
85     for (i = 0; i < bp; i++) entries *= 2;
86     for (i = 0; i < 8 - bp; i++) scale *= 2;
87     gcmap = (unsigned char *) allocate(entries*3);
88     ggmap = (unsigned char *) allocate(entries);
89     gmaplength = entries;
90     for (i = 0, p = gcmap, q = ggmap; i < 256; i += scale, p += 3, q++) {
91 	if (negative) {
92 	    *p = 255 - i; p[1] = *p; p[2] = *p;
93 	    *q = *p;
94 	}
95 	else {
96 	    *p = i; p[1] = i; p[2] = i;
97 	    *q = i;
98 	}
99     }
100     if (gammaflag)
101     	for (i = 0, p = gcmap; i < 256; i += scale, p += 3) {
102 	    *p = (unsigned char) (pow((double) *p/256.0, gamma)*256);
103 	    p[1] = *p; p[2] = *p;
104 	}
105 dbprt(stderr,"default color map:\n");
106 for (i = 0; i < entries*3; i += 3)
107 dbprt(stderr, "%d, %d, %d\n", gcmap[i], gcmap[i+1], gcmap[i+2]);
108 }
109 
110 void
readgcolormap(bp)111 readgcolormap(bp)
112     int bp;
113 {
114     int i, entries = 1;
115     unsigned char *p, *q;
116 
117     for (i = 0; i < bp; i++) entries *= 2;
118     gcmap = (unsigned char *) allocate(entries*3);
119     ggmap = (unsigned char *) allocate(entries);
120     gmaplength = entries;
121     fread(gcmap, sizeof(*gcmap), entries*3, fp_in);
122     if (negative)
123 	for (i = 0, p = gcmap; i < entries*3; i++, p++) *p = 255 - *p;
124     for (i = 0, p = gcmap, q = ggmap; i < entries; i++, p += 3, q++)
125 	*q = cr*(int)p[0] + cg*(int)p[1] + cb*(int)p[2] + 0.5;
126     if (gammaflag)
127     	for (i = 0, p = gcmap; i < entries*3; i++, p++)
128 	    *p = (unsigned char) (pow((double) *p/256.0, gamma)*256);
129 dbprt(stderr,"global color map:\n");
130 for (i = 0; i < entries*3; i += 3)
131 dbprt(stderr, "%d, %d, %d\n", gcmap[i], gcmap[i+1], gcmap[i+2]);
132 }
133 
134 void
readlcolormap(bp)135 readlcolormap(bp)
136     int bp;
137 {
138     int i, entries = 1;
139     unsigned char *p, *q;
140 
141     for (i = 0; i < bp; i++) entries *= 2;
142     lcmap = (unsigned char *) allocate(entries*3);
143     lgmap = (unsigned char *) allocate(entries);
144     lmaplength = entries;
145     fread(lcmap, sizeof(*lcmap), entries*3, fp_in);
146     if (negative)
147 	for (i = 0, p = lcmap; i < entries*3; i++, p++) *p = 255 - *p;
148     for (i = 0, p = lcmap, q = lgmap; i < entries; i++, p += 3, q++)
149 	*q = cr*(int)p[0] + cg*(int)p[1] + cb*(int)p[2] + 0.5;
150     if (gammaflag)
151     	for (i = 0, p = lcmap; i < entries*3; i++, p++)
152 	    *p = (unsigned char) (pow((double) *p/256.0, gamma)*256);
153 dbprt(stderr,"local color map:\n");
154 for (i = 0; i < entries*3; i += 3)
155 dbprt(stderr, "%d, %d, %d\n", lcmap[i], lcmap[i+1], lcmap[i+2]);
156 }
157 
158 void
initstbl()159 initstbl()
160 {
161     int i, entries = 1, *p, *s;
162 
163     for (i = 0; i < codesize; i++) entries *= 2;
164     clearcode = entries;
165     endcode = clearcode + 1;
166     for (i = 0, p = prefix, s = suffix; i <= endcode; i++, p++, s++) {
167 	*p = endcode;
168 	*s = i;
169     }
170     curstblsize = endcode + 1;
171     pmindex = 0;
172     byteinibuf = 0;
173     bitsleft = 0;
174 }
175 
176 int
nextbyte()177 nextbyte()
178 {
179     static ibufindex;
180 
181     if (byteinibuf) {
182 	byteinibuf--;
183 	ibufindex++;
184     }
185     else {
186     	fread(ibuf, sizeof(*ibuf), 1, fp_in);
187     	byteinibuf = ibuf[0];
188 dbprt(stderr, "byte count: %d\n", byteinibuf);
189 	if (byteinibuf) fread(ibuf, sizeof(*ibuf), byteinibuf, fp_in);
190 	else error(FATAL, "encounter zero byte count block before end code");
191 	ibufindex = 0;
192 	byteinibuf--;
193 	ibufindex++;
194     }
195     return(ibuf[ibufindex-1]);
196 }
197 
198 int masktbl[25] = {
199     0, 01, 03, 07, 017, 037, 077, 0177, 0377, 0777, 01777, 03777, 07777,
200     017777, 037777, 077777, 0177777, 0377777, 0777777, 01777777, 03777777,
201     07777777, 017777777, 037777777, 077777777
202 };
203 
204 int
getcode()205 getcode()
206 {
207     int cs, c;
208     static int oldc;
209 
210     if (curstblsize < 4096) cs = cstbl[curstblsize];
211     else cs = 12;
212     while (bitsleft < cs) {
213 	oldc = (oldc & masktbl[bitsleft]) | ((nextbyte() & 0377) << bitsleft);
214 	bitsleft += 8;
215     }
216     c = oldc & masktbl[cs];
217     oldc = oldc >> cs;
218     bitsleft -= cs;
219 /* dbprt(stderr, "code: %d %d %d\n", curstblsize, cs, c); */
220     return(c);
221 }
222 
223 void
putcode(c)224 putcode(c)
225     int c;
226 {
227     if (prefix[c] != endcode) {
228 	putcode(prefix[c]);
229 	pmap[pmindex] = suffix[c];
230 	pmindex++;
231     }
232     else {
233    	pmap[pmindex] = suffix[c];
234 	pmindex++;
235     }
236 }
237 
238 int
firstof(c)239 firstof(c)
240     int c;
241 {
242     while (prefix[c] != endcode) c = prefix[c];
243     return(suffix[c]);
244 }
245 
246 void
writeimage()247 writeimage()
248 {
249     int i, j, k;
250 
251 dbprt(stderr, "pmindex: %d\n", pmindex);
252     fputs("save\n", fp_out);
253     fprintf(fp_out, "/codestr %d string def\n", imagewidth);
254     if (!gray) {
255     	fprintf(fp_out, "/colortbl currentfile %d string readhexstring\n",
256 	    maplength*3);
257         for (i = 0; i < maplength; i++) puthex(cmap[i], fp_out);
258         fputs("\n", fp_out);
259         for (i = maplength ; i < maplength*2; i++) puthex(cmap[i], fp_out);
260         fputs("\n", fp_out);
261         for (i = maplength*2 ; i < maplength*3; i++) puthex(cmap[i], fp_out);
262         fputs("\npop def\n", fp_out);
263     	fprintf(fp_out, "/graytbl currentfile %d string readhexstring\n",
264 	    maplength);
265         for (i = 0; i < maplength; i++) puthex(gmap[i], fp_out);
266         fputs("\npop def\n", fp_out);
267     }
268     fprintf(fp_out, "%s %d %d %d %d gifimage\n",
269 	gray ? "true" : "false", imagewidth, imageheight,
270 	scrwidth - imageleft - imagewidth, scrheight - imagetop - imageheight);
271     if (gray) {
272 	if (interlaced) {
273 	    int *iltbl;
274 
275 	    iltbl = (int *) allocate(imageheight*sizeof(int));
276 	    j = 0;
277 	    for (i = 0; i < imageheight; i += 8) {
278 		iltbl[i] = j;
279 		j += imagewidth;
280 	    }
281 dbprt(stderr, "pass1: %d\n", j);
282 	    for (i = 4; i < imageheight; i += 8) {
283 		iltbl[i] = j;
284 		j += imagewidth;
285 	    }
286 dbprt(stderr, "pass2: %d\n", j);
287 	    for (i = 2; i < imageheight; i += 4) {
288 		iltbl[i] = j;
289 		j += imagewidth;
290 	    }
291 dbprt(stderr, "pass3: %d\n", j);
292 	    for (i = 1; i < imageheight; i += 2) {
293 		iltbl[i] = j;
294 		j += imagewidth;
295 	    }
296 dbprt(stderr, "pass4: %d\n", j);
297 
298     	    for (i = 0; i < imageheight; i++) {
299 		k = iltbl[i];
300 	        for (j = 0; j < imagewidth; j++, k++)
301 		    puthex(gmap[pmap[k]], fp_out);
302 	        fputs("\n", fp_out);
303 	    }
304 	}
305 	else {
306     	    for (i = 0, k = 0; i < imageheight; i++) {
307 	        for (j = 0; j < imagewidth; j++, k++)
308 		    puthex(gmap[pmap[k]], fp_out);
309 	        fputs("\n", fp_out);
310 	    }
311     	}
312     }
313     else {
314 	if (interlaced) {
315 	    int *iltbl;
316 
317 	    iltbl = (int *) allocate(imageheight*sizeof(int));
318 	    j = 0;
319 	    for (i = 0; i < imageheight; i += 8) {
320 		iltbl[i] = j;
321 		j += imagewidth;
322 	    }
323 dbprt(stderr, "pass1: %d\n", j);
324 	    for (i = 4; i < imageheight; i += 8) {
325 		iltbl[i] = j;
326 		j += imagewidth;
327 	    }
328 dbprt(stderr, "pass2: %d\n", j);
329 	    for (i = 2; i < imageheight; i += 4) {
330 		iltbl[i] = j;
331 		j += imagewidth;
332 	    }
333 dbprt(stderr, "pass3: %d\n", j);
334 	    for (i = 1; i < imageheight; i += 2) {
335 		iltbl[i] = j;
336 		j += imagewidth;
337 	    }
338 dbprt(stderr, "pass4: %d\n", j);
339 
340     	    for (i = 0; i < imageheight; i++) {
341 		k = iltbl[i];
342 	        for (j = 0; j < imagewidth; j++, k++) puthex(pmap[k], fp_out);
343 	        fputs("\n", fp_out);
344     	    }
345 	}
346 	else {
347     	    for (i = 0, k = 0; i < imageheight; i++) {
348 	        for (j = 0; j < imagewidth; j++, k++) puthex(pmap[k], fp_out);
349 	        fputs("\n", fp_out);
350     	    }
351 	}
352     }
353     fputs("restore\n", fp_out);
354 }
355 
356 void
readimage()357 readimage()
358 {
359     int bytecount, zerobytecount = 0;
360     int code, oldcode;
361 
362     fread(ibuf, sizeof(*ibuf), 9, fp_in);
363     imageleft = ibuf[0] + 256*ibuf[1];
364     imagetop = ibuf[2] + 256*ibuf[3];
365     imagewidth = ibuf[4] + 256*ibuf[5];
366     imageheight = ibuf[6] + 256*ibuf[7];
367     lcolormap = ibuf[8] & 0200;
368     interlaced = ibuf[8] & 0100;
369     lbitperpixel = (ibuf[8] & 07) + 1;
370 dbprt(stderr, "imageleft: %d\n", imageleft);
371 dbprt(stderr, "imagetop: %d\n", imagetop);
372 dbprt(stderr, "imagewidth: %d\n", imagewidth);
373 dbprt(stderr, "imgaeheight: %d\n", imageheight);
374 dbprt(stderr, "lcolormap: %d\n", lcolormap ? 1 : 0);
375 dbprt(stderr, "interlaced: %d\n", interlaced ? 1 : 0);
376 dbprt(stderr, "lbitperpixel: %d\n", lbitperpixel);
377     if (lcolormap) {
378 	readlcolormap(lbitperpixel);
379 	cmap = lcmap;
380 	gmap = lgmap;
381 	maplength = lmaplength;
382     }
383 
384 dbprt(stderr, "start reading raster data\n");
385     fread(ibuf, sizeof(*ibuf), 1, fp_in);
386     codesize = ibuf[0];
387 dbprt(stderr, "codesize: %d\n", codesize);
388     pmap = (unsigned char *) allocate(imagewidth*imageheight);
389     initstbl();
390     while ((code = getcode()) != endcode) {
391 	if (code == clearcode) {
392 	    curstblsize = endcode + 1;
393     	    code = getcode();
394     	    putcode(code);
395     	    oldcode = code;
396 	}
397 	else if (code < curstblsize) {
398 	    putcode(code);
399 	    prefix[curstblsize] = oldcode;
400 	    suffix[curstblsize] = firstof(code);
401 	    curstblsize++;
402 	    oldcode = code;
403 	}
404 	else {
405 	   if (code != curstblsize) error(FATAL, "code out of order");
406 	   prefix[curstblsize] = oldcode;
407 	   suffix[curstblsize] = firstof(oldcode);
408 	   curstblsize++;
409 	   putcode(curstblsize-1);
410 	   oldcode = code;
411 	}
412     }
413 dbprt(stderr, "finish reading raster data\n");
414 
415     /* read the rest of the raster data */
416     do {
417     	fread(ibuf, sizeof(*ibuf), 1, fp_in);
418     	bytecount = ibuf[0];
419 dbprt(stderr, "byte count: %d\n", bytecount);
420 	if (bytecount) fread(ibuf, sizeof(*ibuf), bytecount, fp_in);
421 	else zerobytecount = 1;
422     } while (!zerobytecount);
423 
424     writeimage();
425 
426     if (lcolormap) {
427 	cmap = gcmap;
428 	gmap = ggmap;
429 	maplength = gmaplength;
430 	free(lcmap);
431 	free(lgmap);
432     }
433 }
434 
435 void
readextensionblock()436 readextensionblock()
437 {
438     int functioncode, bytecount, zerobytecount = 0;
439 
440     fread(ibuf, sizeof(*ibuf), 1, fp_in);
441     functioncode = ibuf[0];
442 dbprt(stderr, "function code: %d\n", functioncode);
443     do {
444     	fread(ibuf, sizeof(*ibuf), 1, fp_in);
445     	bytecount = ibuf[0];
446 dbprt(stderr, "byte count: %d\n", bytecount);
447 	if (bytecount) fread(ibuf, sizeof(*ibuf), bytecount, fp_in);
448 	else zerobytecount = 1;
449     } while (!zerobytecount);
450 }
451 
452 void
writebgscr()453 writebgscr()
454 {
455     fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1);
456     fputs("/saveobj save def\n", fp_out);
457     fprintf(fp_out, "%s: %d %d %d %d\n",
458 	"%%PageBoundingBox", 0, 0, scrwidth, scrheight);
459     if (scrwidth > bburx) bburx = scrwidth;
460     if (scrheight > bbury) bbury = scrheight;
461     fprintf(fp_out, "%d %d gifscreen\n", scrwidth, scrheight);
462 }
463 
464 void
writeendscr()465 writeendscr()
466 {
467     if ( fp_out == stdout ) printed++;
468     fputs("showpage\n", fp_out);
469     fputs("saveobj restore\n", fp_out);
470     fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed);
471 }
472 
473 void
redirect(pg)474 redirect(pg)
475     int		pg;			/* next page we're printing */
476 {
477     static FILE	*fp_null = NULL;	/* if output is turned off */
478 
479     if ( pg >= 0 && in_olist(pg) == ON )
480 	fp_out = stdout;
481     else if ( (fp_out = fp_null) == NULL )
482 	fp_out = fp_null = fopen("/dev/null", "w");
483 
484 }
485 
486 void
readgif()487 readgif()
488 {
489     int i, j, k;
490 
491     for (i = 0, j = 1, k = 0; i < 13; i++) {
492 	for (; k < j; k++) cstbl[k] = i;
493 	j *= 2;
494     }
495 
496     fread(ibuf, sizeof(*ibuf), 6, fp_in);
497 dbprt(stderr, "%.6s\n", ibuf);
498     if (strncmp((char *)ibuf, "GIF87a", 6) != 0) {
499     	fread(ibuf, sizeof(*ibuf), 122, fp_in);
500     	fread(ibuf, sizeof(*ibuf), 6, fp_in);
501 dbprt(stderr, "%.6s\n", ibuf);
502     	if (strncmp((char *)ibuf, "GIF87a", 6) != 0)
503 		 error(FATAL, "wrong GIF signature");
504     }
505     fread(ibuf, sizeof(*ibuf), 7, fp_in);
506     scrwidth = ibuf[0] + 256*ibuf[1];
507     scrheight = ibuf[2] + 256*ibuf[3];
508     gcolormap = ibuf[4] & 0200;
509     bitperpixel = (ibuf[4] & 07) + 1;
510     background = ibuf[5];
511 dbprt(stderr, "scrwidth: %d\n", scrwidth);
512 dbprt(stderr, "scrheight: %d\n", scrheight);
513 dbprt(stderr, "gcolormap: %d\n", gcolormap ? 1 : 0);
514 dbprt(stderr, "bitperpixel: %d\n", bitperpixel);
515 dbprt(stderr, "background: %d\n", background);
516     if (ibuf[6] != 0) error(FATAL, "wrong screen descriptor");
517     if (gcolormap) readgcolormap(bitperpixel);
518     else setcolormap(bitperpixel);
519 
520     redirect(++page);
521     writebgscr();
522 
523     cmap = gcmap;
524     gmap = ggmap;
525     maplength = gmaplength;
526 
527     do {
528 	fread(ibuf, sizeof(*ibuf), 1, fp_in);
529 	if (ibuf[0] == ',') readimage();
530 	else if (ibuf[0] == ';') terminate = 1;
531 	else if (ibuf[0] == '!') readextensionblock();
532 	else
533 	error(FATAL, "wrong image separator character or wrong GIF terminator");
534     } while (!terminate);
535 
536     writeendscr();
537 
538     free(gcmap);
539     free(ggmap);
540 }
541 
542 void
init_signals()543 init_signals()
544 {
545 
546     if ( signal(SIGINT, interrupt) == SIG_IGN )  {
547         signal(SIGINT, SIG_IGN);
548         signal(SIGQUIT, SIG_IGN);
549         signal(SIGHUP, SIG_IGN);
550     }
551     else {
552         signal(SIGHUP, interrupt);
553         signal(SIGQUIT, interrupt);
554     }
555 
556     signal(SIGTERM, interrupt);
557 }
558 
559 void
header()560 header()
561 {
562     int         ch;                     /* return value from getopt() */
563     int         old_optind = optind;    /* for restoring optind - should be 1 */
564 
565     while ( (ch = getopt(argc, argv, optnames)) != EOF )
566         if ( ch == 'L' )
567             prologue = optarg;
568         else if ( ch == '?' )
569             error(FATAL, "");
570 
571     optind = old_optind;                /* get ready for option scanning */
572 
573     fprintf(stdout, "%s", CONFORMING);
574     fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION);
575     fprintf(stdout, "%s %s\n", BOUNDINGBOX, ATEND);
576     fprintf(stdout, "%s %s\n", PAGES, ATEND);
577     fprintf(stdout, "%s", ENDCOMMENTS);
578 
579     if ( cat(prologue) == FALSE )
580         error(FATAL, "can't read %s", prologue);
581 
582     fprintf(stdout, "%s", ENDPROLOG);
583     fprintf(stdout, "%s", BEGINSETUP);
584     fprintf(stdout, "mark\n");
585 
586 }
587 
588 void
options()589 options()
590 {
591     int		ch;			/* return value from getopt() */
592 
593     while ( (ch = getopt(argc, argv, optnames)) != EOF )  {
594 	switch ( ch )  {
595 
596 	    case 'a':			/* aspect ratio */
597 		    fprintf(stdout, "/aspectratio %s def\n", optarg);
598 		    break;
599 
600 	    case 'c':			/* copies */
601 		    copies = atoi(optarg);
602 		    fprintf(stdout, "/#copies %s store\n", optarg);
603 		    break;
604 
605 	    case 'f':
606 		    negative = TRUE;
607 		    break;
608 
609 	    case 'g':
610 		    gray = TRUE;
611 		    break;
612 
613 	    case 'l':
614 		    fprintf(stdout, "/alignment true def\n");
615 		    break;
616 
617 	    case 'm':			/* magnification */
618 		    fprintf(stdout, "/magnification %s def\n", optarg);
619 		    break;
620 
621 	    case 'n':			/* forms per page */
622 		    formsperpage = atoi(optarg);
623 		    fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg);
624 		    fprintf(stdout, "/formsperpage %s def\n", optarg);
625 		    break;
626 
627 	    case 'o':			/* output page list */
628 		    out_list(optarg);
629 		    break;
630 
631 	    case 'p':			/* landscape or portrait mode */
632 		    if ( *optarg == 'l' )
633 			fprintf(stdout, "/landscape true def\n");
634 		    else fprintf(stdout, "/landscape false def\n");
635 		    break;
636 
637 	    case 'x':			/* shift things horizontally */
638 		    fprintf(stdout, "/xoffset %s def\n", optarg);
639 		    break;
640 
641 	    case 'y':			/* and vertically on the page */
642 		    fprintf(stdout, "/yoffset %s def\n", optarg);
643 		    break;
644 
645 	    case 'C':			/* copy file straight to output */
646 		    if ( cat(optarg) == FALSE )
647 			error(FATAL, "can't read %s", optarg);
648 		    break;
649 
650 	    case 'E':			/* text font encoding - unnecessary */
651 		    fontencoding = optarg;
652 		    break;
653 
654 	    case 'D':			/* debug flag */
655 		    debug = ON;
656 		    break;
657 
658 	    case 'G':
659 		    gammaflag = ON;
660 		    gamma = atof(optarg);
661 		    break;
662 
663 	    case 'I':			/* ignore FATAL errors */
664 		    ignore = ON;
665 		    break;
666 
667 	    case 'L':			/* PostScript prologue file */
668 		    prologue = optarg;
669 		    break;
670 
671 	    case 'P':			/* PostScript pass through */
672 		    fprintf(stdout, "%s\n", optarg);
673 		    break;
674 
675 	    case '?':			/* don't understand the option */
676 		    error(FATAL, "");
677 		    break;
678 
679 	    default:			/* don't know what to do for ch */
680 		    error(FATAL, "missing case for option %c\n", ch);
681 		    break;
682 
683 	}
684     }
685 
686     argc -= optind;			/* get ready for non-option args */
687     argv += optind;
688 }
689 
690 void
setup()691 setup()
692 {
693     /*setencoding(fontencoding);*/
694     fprintf(stdout, "setup\n");
695 
696     if ( formsperpage > 1 )  {          /* followed by stuff for multiple pages
697 */
698         if ( cat(formfile) == FALSE )
699             error(FATAL, "can't read %s", formfile);
700         fprintf(stdout, "%d setupforms\n", formsperpage);
701     }   /* End if */
702 
703     fprintf(stdout, "%s", ENDSETUP);
704 
705 }
706 
707 void
arguments()708 arguments()
709 {
710     if ( argc < 1 ) {
711 	fp_in = stdin;
712 	readgif();
713     }
714     else  {				/* at least one argument is left */
715 	while ( argc > 0 )  {
716 	    if ( strcmp(*argv, "-") == 0 )
717 		fp_in = stdin;
718 	    else if ( (fp_in = fopen(*argv, "r")) == NULL )
719 		error(FATAL, "can't open %s", *argv);
720 	    readgif();
721 	    if ( fp_in != stdin )
722 		fclose(fp_in);
723 	    argc--;
724 	    argv++;
725 	}
726     }
727 }
728 
729 void
done()730 done()
731 {
732     fprintf(stdout, "%s", TRAILER);
733     fprintf(stdout, "done\n");
734     fprintf(stdout, "%s 0 0 %d %d\n", BOUNDINGBOX, bburx, bbury);
735     fprintf(stdout, "%s %d\n", PAGES, printed);
736 }
737 
main(agc,agv)738 main(agc, agv)
739     int agc;
740     char *agv[];
741 {
742     argc = agc;
743     argv = agv;
744     prog_name = argv[0];
745 
746     init_signals();
747     header();
748     options();
749     setup();
750     arguments();
751     done();
752 
753     exit(0);
754 }
755 
756