7 #define isascii(c) ((unsigned char)(c)<=0177)
17 #define dbprt if (debug) fprintf
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 */
27 extern char *malloc();
29 extern double atof(), pow();
31 unsigned char ibuf[BUFSIZ];
32 unsigned char *cmap, *gcmap, *lcmap;
33 unsigned char *gmap, *ggmap, *lgmap;
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;
48 int codesize, clearcode, endcode, curstblsize, pmindex, byteinibuf, bitsleft;
49 int prefix[4096], suffix[4096], cstbl[4096];
50 int bburx = -32767, bbury = -32767;
52 FILE *fp_out = stdout;
60 if ((p = malloc(size)) == NULL) error(FATAL, "not enough memory");
69 static char hextbl[16] = {
70 '0', '1', '2', '3', '4', '5', '6', '7',
71 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
74 putc(hextbl[(c >> 4) & 017], fp);
75 putc(hextbl[c & 017], fp);
82 int i, entries = 1, scale = 1;
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);
90 for (i = 0, p = gcmap, q = ggmap; i < 256; i += scale, p += 3, q++) {
92 *p = 255 - i; p[1] = *p; p[2] = *p;
96 *p = i; p[1] = i; p[2] = i;
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;
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]);
115 unsigned char *p, *q;
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);
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;
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]);
139 unsigned char *p, *q;
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);
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;
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]);
161 int i, entries = 1, *p, *s;
163 for (i = 0; i < codesize; i++) entries *= 2;
165 endcode = clearcode + 1;
166 for (i = 0, p = prefix, s = suffix; i <= endcode; i++, p++, s++) {
170 curstblsize = endcode + 1;
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");
195 return(ibuf[ibufindex-1]);
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
210 if (curstblsize < 4096) cs = cstbl[curstblsize];
212 while (bitsleft < cs) {
213 oldc = (oldc & masktbl[bitsleft]) | ((nextbyte() & 0377) << bitsleft);
216 c = oldc & masktbl[cs];
219 /* dbprt(stderr, "code: %d %d %d\n", curstblsize, cs, c); */
227 if (prefix[c] != endcode) {
229 pmap[pmindex] = suffix[c];
233 pmap[pmindex] = suffix[c];
242 while (prefix[c] != endcode) c = prefix[c];
251 dbprt(stderr, "pmindex: %d\n", pmindex);
252 fputs("save\n", fp_out);
253 fprintf(fp_out, "/codestr %d string def\n", imagewidth);
255 fprintf(fp_out, "/colortbl currentfile %d string readhexstring\n",
257 for (i = 0; i < maplength; i++) puthex(cmap[i], fp_out);
259 for (i = maplength ; i < maplength*2; i++) puthex(cmap[i], 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",
265 for (i = 0; i < maplength; i++) puthex(gmap[i], fp_out);
266 fputs("\npop def\n", fp_out);
268 fprintf(fp_out, "%s %d %d %d %d gifimage\n",
269 gray ? "true" : "false", imagewidth, imageheight,
270 scrwidth - imageleft - imagewidth, scrheight - imagetop - imageheight);
275 iltbl = (int *) allocate(imageheight*sizeof(int));
277 for (i = 0; i < imageheight; i += 8) {
281 dbprt(stderr, "pass1: %d\n", j);
282 for (i = 4; i < imageheight; i += 8) {
286 dbprt(stderr, "pass2: %d\n", j);
287 for (i = 2; i < imageheight; i += 4) {
291 dbprt(stderr, "pass3: %d\n", j);
292 for (i = 1; i < imageheight; i += 2) {
296 dbprt(stderr, "pass4: %d\n", j);
298 for (i = 0; i < imageheight; i++) {
300 for (j = 0; j < imagewidth; j++, k++)
301 puthex(gmap[pmap[k]], fp_out);
306 for (i = 0, k = 0; i < imageheight; i++) {
307 for (j = 0; j < imagewidth; j++, k++)
308 puthex(gmap[pmap[k]], fp_out);
317 iltbl = (int *) allocate(imageheight*sizeof(int));
319 for (i = 0; i < imageheight; i += 8) {
323 dbprt(stderr, "pass1: %d\n", j);
324 for (i = 4; i < imageheight; i += 8) {
328 dbprt(stderr, "pass2: %d\n", j);
329 for (i = 2; i < imageheight; i += 4) {
333 dbprt(stderr, "pass3: %d\n", j);
334 for (i = 1; i < imageheight; i += 2) {
338 dbprt(stderr, "pass4: %d\n", j);
340 for (i = 0; i < imageheight; i++) {
342 for (j = 0; j < imagewidth; j++, k++) puthex(pmap[k], fp_out);
347 for (i = 0, k = 0; i < imageheight; i++) {
348 for (j = 0; j < imagewidth; j++, k++) puthex(pmap[k], fp_out);
353 fputs("restore\n", fp_out);
359 int bytecount, zerobytecount = 0;
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);
378 readlcolormap(lbitperpixel);
381 maplength = lmaplength;
384 dbprt(stderr, "start reading raster data\n");
385 fread(ibuf, sizeof(*ibuf), 1, fp_in);
387 dbprt(stderr, "codesize: %d\n", codesize);
388 pmap = (unsigned char *) allocate(imagewidth*imageheight);
390 while ((code = getcode()) != endcode) {
391 if (code == clearcode) {
392 curstblsize = endcode + 1;
397 else if (code < curstblsize) {
399 prefix[curstblsize] = oldcode;
400 suffix[curstblsize] = firstof(code);
405 if (code != curstblsize) error(FATAL, "code out of order");
406 prefix[curstblsize] = oldcode;
407 suffix[curstblsize] = firstof(oldcode);
409 putcode(curstblsize-1);
413 dbprt(stderr, "finish reading raster data\n");
415 /* read the rest of the raster data */
417 fread(ibuf, sizeof(*ibuf), 1, fp_in);
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);
429 maplength = gmaplength;
438 int functioncode, bytecount, zerobytecount = 0;
440 fread(ibuf, sizeof(*ibuf), 1, fp_in);
441 functioncode = ibuf[0];
442 dbprt(stderr, "function code: %d\n", functioncode);
444 fread(ibuf, sizeof(*ibuf), 1, fp_in);
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);
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);
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);
475 int pg; /* next page we're printing */
477 static FILE *fp_null = NULL; /* if output is turned off */
479 if ( pg >= 0 && in_olist(pg) == ON )
481 else if ( (fp_out = fp_null) == NULL )
482 fp_out = fp_null = fopen("/dev/null", "w");
491 for (i = 0, j = 1, k = 0; i < 13; i++) {
492 for (; k < j; k++) cstbl[k] = i;
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");
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);
525 maplength = gmaplength;
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();
533 error(FATAL, "wrong image separator character or wrong GIF terminator");
534 } while (!terminate);
546 if ( signal(SIGINT, interrupt) == SIG_IGN ) {
547 signal(SIGINT, SIG_IGN);
548 signal(SIGQUIT, SIG_IGN);
549 signal(SIGHUP, SIG_IGN);
552 signal(SIGHUP, interrupt);
553 signal(SIGQUIT, interrupt);
556 signal(SIGTERM, interrupt);
562 int ch; /* return value from getopt() */
563 int old_optind = optind; /* for restoring optind - should be 1 */
565 while ( (ch = getopt(argc, argv, optnames)) != EOF )
568 else if ( ch == '?' )
571 optind = old_optind; /* get ready for option scanning */
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);
579 if ( cat(prologue) == FALSE )
580 error(FATAL, "can't read %s", prologue);
582 fprintf(stdout, "%s", ENDPROLOG);
583 fprintf(stdout, "%s", BEGINSETUP);
584 fprintf(stdout, "mark\n");
591 int ch; /* return value from getopt() */
593 while ( (ch = getopt(argc, argv, optnames)) != EOF ) {
596 case 'a': /* aspect ratio */
597 fprintf(stdout, "/aspectratio %s def\n", optarg);
600 case 'c': /* copies */
601 copies = atoi(optarg);
602 fprintf(stdout, "/#copies %s store\n", optarg);
614 fprintf(stdout, "/alignment true def\n");
617 case 'm': /* magnification */
618 fprintf(stdout, "/magnification %s def\n", optarg);
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);
627 case 'o': /* output page list */
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");
637 case 'x': /* shift things horizontally */
638 fprintf(stdout, "/xoffset %s def\n", optarg);
641 case 'y': /* and vertically on the page */
642 fprintf(stdout, "/yoffset %s def\n", optarg);
645 case 'C': /* copy file straight to output */
646 if ( cat(optarg) == FALSE )
647 error(FATAL, "can't read %s", optarg);
650 case 'E': /* text font encoding - unnecessary */
651 fontencoding = optarg;
654 case 'D': /* debug flag */
660 gamma = atof(optarg);
663 case 'I': /* ignore FATAL errors */
667 case 'L': /* PostScript prologue file */
671 case 'P': /* PostScript pass through */
672 fprintf(stdout, "%s\n", optarg);
675 case '?': /* don't understand the option */
679 default: /* don't know what to do for ch */
680 error(FATAL, "missing case for option %c\n", ch);
686 argc -= optind; /* get ready for non-option args */
693 /*setencoding(fontencoding);*/
694 fprintf(stdout, "setup\n");
696 if ( formsperpage > 1 ) { /* followed by stuff for multiple pages
698 if ( cat(formfile) == FALSE )
699 error(FATAL, "can't read %s", formfile);
700 fprintf(stdout, "%d setupforms\n", formsperpage);
703 fprintf(stdout, "%s", ENDSETUP);
714 else { /* at least one argument is left */
716 if ( strcmp(*argv, "-") == 0 )
718 else if ( (fp_in = fopen(*argv, "r")) == NULL )
719 error(FATAL, "can't open %s", *argv);
721 if ( fp_in != stdin )
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);