|
|
1.1 ! root 1: /* ! 2: * ! 3: * postdmd - PostScript translator for DMD bitmap files. ! 4: * ! 5: * A simple program that can be used to print DMD bitmaps on PostScript printers. ! 6: * Much of the code was borrowed from abm, which was written by Guy Riddle. ! 7: * ! 8: * Although the program supports two different input bitmap formats, by far the ! 9: * most important is the Eighth (and Ninth) Edition bitfile format. A bitmap in ! 10: * the bitfile format begins with a 10 byte header with the first two bytes set to ! 11: * zero. The next 8 bytes set the x and y coordinates of the bitmap's origin and ! 12: * corner (ie. the upper left and lower right corners). The compressed raster data ! 13: * follows the header and consists of control bytes followed an appropriate number ! 14: * of data bytes. Control bytes (ie. n) less than 127 means read the next 2*n bytes ! 15: * of raster data directly from the input file, while if n is larger than 128 we ! 16: * read two bytes from the input file and replicate the bytes n-128 times. After ! 17: * each scan line is recovered it's exclusive-or'd with the preceeding line to ! 18: * generate the real raster data. ! 19: * ! 20: * After each raster line is recovered postdmd encodes it in a slightly different ! 21: * format that's designed to be unpacked by a PostScript procedure that's defined ! 22: * in the prologue. By default no exclusive-or'ing is done and packing of pattern ! 23: * data can be based on any number of bytes rather than just the next two bytes. ! 24: * By default 6 byte patterns are used, but any number can be selected with the -b ! 25: * option. A non-positive argument (eg. -b0) disables all pattern encoding. Larger ! 26: * patterns increase the size of the output file, but reduce the work load that's ! 27: * forced on the PostScript interpreter. The default choices I've made (ie. 6 byte ! 28: * patterns and no exclusive-or'ing) do a decent balancing job across currently ! 29: * available PostScript printers. Larger patterns (eg. -b16) increase the output ! 30: * file size, but may be appropriate if you're running at a high baud rate (eg. ! 31: * 19.2KB), while smaller patter size (eg. -b4) may help if you've got a printer ! 32: * with a fast processor (eg. a PS-810). ! 33: * ! 34: * The encoding produced by the program (and decoded on the printer) looks like, ! 35: * ! 36: * bytes patterns count ! 37: * ! 38: * where bytes and count are decimal integers and patterns is a hex string. Bytes ! 39: * is the number of bytes represented by the hex patterns and count is the number ! 40: * of additional times the patterns should be repeated. For example, ! 41: * ! 42: * 2 FFFF 4 ! 43: * 5 FFFFFFFFFF 1 ! 44: * 10 FFFFFFFFFFFFFFFFFFFF 0 ! 45: * ! 46: * all represent 10 consecutive bytes of ones. Scanlines are terminated by a 0 on ! 47: * a line by itself. ! 48: * ! 49: * The PostScript prologue is copied from *prologue before any of the input files ! 50: * are translated. The program expects that the following PostScript procedures ! 51: * are defined in that file: ! 52: * ! 53: * setup ! 54: * ! 55: * mark ... setup - ! 56: * ! 57: * Handles special initialization stuff that depends on how this program ! 58: * was called. Expects to find a mark followed by key/value pairs on the ! 59: * stack. The def operator is applied to each pair up to the mark, then ! 60: * the default state is set up. ! 61: * ! 62: * pagesetup ! 63: * ! 64: * page pagesetup - ! 65: * ! 66: * Does whatever is needed to set things up for the next page. Expects ! 67: * to find the current page number on the stack. ! 68: * ! 69: * bitmap ! 70: * ! 71: * v8format flip scanlength scanlines bitmap - ! 72: * ! 73: * Prints the bitmap that's read from standard input. The bitmap consists ! 74: * of scanlines lines, each of which includes scanlength pixels. If ! 75: * v8format is true the picture is assumed to be an Eighth Edition bitmap, ! 76: * and the exclusive-or'ing will be done on the printer. ! 77: * ! 78: * done ! 79: * ! 80: * done ! 81: * ! 82: * Makes sure the last page is printed. Only needed when we're printing ! 83: * more than one page on each sheet of paper. ! 84: * ! 85: * Many default values, like the magnification and orientation, are defined in ! 86: * the prologue, which is where they belong. If they're changed (by options), an ! 87: * appropriate definition is made after the prologue is added to the output file. ! 88: * The -P option passes arbitrary PostScript through to the output file. Among ! 89: * other things it can be used to set (or change) values that can't be accessed by ! 90: * other options. ! 91: * ! 92: */ ! 93: ! 94: #include <stdio.h> ! 95: #include <signal.h> ! 96: #include <ctype.h> ! 97: #include <fcntl.h> ! 98: ! 99: #include "comments.h" /* PostScript file structuring comments */ ! 100: #include "gen.h" /* general purpose definitions */ ! 101: #include "path.h" /* for the prologue */ ! 102: #include "ext.h" /* external variable declarations */ ! 103: ! 104: char *optnames = "a:b:c:fm:n:o:p:ux:y:A:C:E:J:L:P:DI"; ! 105: ! 106: char *prologue = POSTDMD; /* default PostScript prologue */ ! 107: char *formfile = FORMFILE; /* stuff for multiple pages per sheet */ ! 108: ! 109: int bbox[2] = {0, 0}; /* upper right coordinates only */ ! 110: ! 111: int formsperpage = 1; /* page images on each piece of paper */ ! 112: int copies = 1; /* and this many copies of each sheet */ ! 113: ! 114: int bytespp = 6; /* bytes per pattern - on output */ ! 115: int flip = FALSE; /* ones complement the bitmap */ ! 116: int v8undo = TRUE; /* xor'ing done on host if TRUE */ ! 117: int v8format = FALSE; /* for Eighth Edition bitmaps */ ! 118: ! 119: int page = 0; /* last page we worked on */ ! 120: int printed = 0; /* and the number of pages printed */ ! 121: ! 122: int patterns; /* 16 bit patterns per scan line */ ! 123: int scanlines; /* lines in the bitmap */ ! 124: int patcount = 0; /* should be patterns * scanlines */ ! 125: ! 126: char *raster = NULL; /* next raster line */ ! 127: char *prevrast = NULL; /* and the previous one - v8format */ ! 128: char *rptr; /* next free byte in raster */ ! 129: char *eptr; /* one past the last byte in raster */ ! 130: ! 131: FILE *fp_in = NULL; /* read from this file */ ! 132: FILE *fp_out = stdout; /* and write stuff here */ ! 133: FILE *fp_acct = NULL; /* for accounting data */ ! 134: ! 135: /*****************************************************************************/ ! 136: ! 137: main(agc, agv) ! 138: ! 139: int agc; ! 140: char *agv[]; ! 141: ! 142: { ! 143: ! 144: /* ! 145: * ! 146: * A simple program that translates DMD bitmap files into PostScript. There can ! 147: * be more than one bitmap per file, but none can be split across input files. ! 148: * Each bitmap goes on a page by itself. ! 149: * ! 150: */ ! 151: ! 152: argc = agc; /* other routines may want them */ ! 153: argv = agv; ! 154: ! 155: prog_name = argv[0]; /* really just for error messages */ ! 156: ! 157: init_signals(); /* sets up interrupt handling */ ! 158: header(); /* PostScript header comments */ ! 159: options(); /* handle the command line options */ ! 160: setup(); /* for PostScript */ ! 161: arguments(); /* followed by each input file */ ! 162: done(); /* print the last page etc. */ ! 163: account(); /* job accounting data */ ! 164: ! 165: exit(x_stat); /* not much could be wrong */ ! 166: ! 167: } /* End of main */ ! 168: ! 169: /*****************************************************************************/ ! 170: ! 171: init_signals() ! 172: ! 173: { ! 174: ! 175: /* ! 176: * ! 177: * Make sure we handle interrupts. ! 178: * ! 179: */ ! 180: ! 181: if ( signal(SIGINT, interrupt) == SIG_IGN ) { ! 182: signal(SIGINT, SIG_IGN); ! 183: signal(SIGQUIT, SIG_IGN); ! 184: signal(SIGHUP, SIG_IGN); ! 185: } else { ! 186: signal(SIGHUP, interrupt); ! 187: signal(SIGQUIT, interrupt); ! 188: } /* End else */ ! 189: ! 190: signal(SIGTERM, interrupt); ! 191: ! 192: } /* End of init_signals */ ! 193: ! 194: /*****************************************************************************/ ! 195: ! 196: header() ! 197: ! 198: { ! 199: ! 200: int ch; /* return value from getopt() */ ! 201: int old_optind = optind; /* for restoring optind - should be 1 */ ! 202: ! 203: /* ! 204: * ! 205: * Scans the option list looking for things, like the prologue file, that we need ! 206: * right away but could be changed from the default. Doing things this way is an ! 207: * attempt to conform to Adobe's latest file structuring conventions. In particular ! 208: * they now say there should be nothing executed in the prologue, and they have ! 209: * added two new comments that delimit global initialization calls. Once we know ! 210: * where things really are we write out the job header, follow it by the prologue, ! 211: * and then add the ENDPROLOG and BEGINSETUP comments. ! 212: * ! 213: */ ! 214: ! 215: while ( (ch = getopt(argc, argv, optnames)) != EOF ) ! 216: if ( ch == 'L' ) ! 217: prologue = optarg; ! 218: else if ( ch == '?' ) ! 219: error(FATAL, ""); ! 220: ! 221: optind = old_optind; /* get ready for option scanning */ ! 222: ! 223: fprintf(stdout, "%s", CONFORMING); ! 224: fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION); ! 225: fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND); ! 226: fprintf(stdout, "%s %s\n", PAGES, ATEND); ! 227: fprintf(stdout, "%s", ENDCOMMENTS); ! 228: ! 229: if ( cat(prologue) == FALSE ) ! 230: error(FATAL, "can't read %s", prologue); ! 231: ! 232: fprintf(stdout, "%s", ENDPROLOG); ! 233: fprintf(stdout, "%s", BEGINSETUP); ! 234: fprintf(stdout, "mark\n"); ! 235: ! 236: } /* End of header */ ! 237: ! 238: /*****************************************************************************/ ! 239: ! 240: options() ! 241: ! 242: { ! 243: ! 244: int ch; /* return value from getopt() */ ! 245: ! 246: /* ! 247: * ! 248: * Reads and processes the command line options. Added the -P option so arbitrary ! 249: * PostScript code can be passed through. Expect it could be useful for changing ! 250: * definitions in the prologue for which options have not been defined. ! 251: * ! 252: */ ! 253: ! 254: while ( (ch = getopt(argc, argv, optnames)) != EOF ) { ! 255: switch ( ch ) { ! 256: case 'a': /* aspect ratio */ ! 257: fprintf(stdout, "/aspectratio %s def\n", optarg); ! 258: break; ! 259: ! 260: case 'b': /* bytes per pattern */ ! 261: bytespp = atoi(optarg); ! 262: break; ! 263: ! 264: case 'c': /* copies */ ! 265: copies = atoi(optarg); ! 266: fprintf(stdout, "/#copies %s store\n", optarg); ! 267: break; ! 268: ! 269: case 'f': /* ones complement - sort of */ ! 270: flip = TRUE; ! 271: break; ! 272: ! 273: case 'm': /* magnification */ ! 274: fprintf(stdout, "/magnification %s def\n", optarg); ! 275: break; ! 276: ! 277: case 'n': /* forms per page */ ! 278: formsperpage = atoi(optarg); ! 279: fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg); ! 280: fprintf(stdout, "/formsperpage %s def\n", optarg); ! 281: break; ! 282: ! 283: case 'o': /* output page list */ ! 284: out_list(optarg); ! 285: break; ! 286: ! 287: case 'p': /* landscape or portrait mode */ ! 288: if ( *optarg == 'l' ) ! 289: fprintf(stdout, "/landscape true def\n"); ! 290: else fprintf(stdout, "/landscape false def\n"); ! 291: break; ! 292: ! 293: case 'u': /* don't undo Eighth Edition bitmaps */ ! 294: v8undo = FALSE; ! 295: break; ! 296: ! 297: case 'x': /* shift things horizontally */ ! 298: fprintf(stdout, "/xoffset %s def\n", optarg); ! 299: break; ! 300: ! 301: case 'y': /* and vertically on the page */ ! 302: fprintf(stdout, "/yoffset %s def\n", optarg); ! 303: break; ! 304: ! 305: case 'A': /* force job accounting */ ! 306: case 'J': ! 307: if ( (fp_acct = fopen(optarg, "a")) == NULL ) ! 308: error(FATAL, "can't open accounting file %s", optarg); ! 309: break; ! 310: ! 311: case 'C': /* copy file straight to output */ ! 312: if ( cat(optarg) == FALSE ) ! 313: error(FATAL, "can't read %s", optarg); ! 314: break; ! 315: ! 316: case 'E': /* text font encoding - unnecessary */ ! 317: fontencoding = optarg; ! 318: break; ! 319: ! 320: case 'L': /* PostScript prologue file */ ! 321: prologue = optarg; ! 322: break; ! 323: ! 324: case 'P': /* PostScript pass through */ ! 325: fprintf(stdout, "%s\n", optarg); ! 326: break; ! 327: ! 328: case 'R': /* special global or page level request */ ! 329: saverequest(optarg); ! 330: break; ! 331: ! 332: case 'D': /* debug flag */ ! 333: debug = ON; ! 334: break; ! 335: ! 336: case 'I': /* ignore FATAL errors */ ! 337: ignore = ON; ! 338: break; ! 339: ! 340: case '?': /* don't understand the option */ ! 341: error(FATAL, ""); ! 342: break; ! 343: ! 344: default: /* don't know what to do for ch */ ! 345: error(FATAL, "missing case for option %c\n", ch); ! 346: break; ! 347: } /* End switch */ ! 348: } /* End while */ ! 349: ! 350: argc -= optind; /* get ready for non-option args */ ! 351: argv += optind; ! 352: ! 353: } /* End of options */ ! 354: ! 355: /*****************************************************************************/ ! 356: ! 357: setup() ! 358: ! 359: { ! 360: ! 361: /* ! 362: * ! 363: * Handles things that must be done after the options are read but before the ! 364: * input files are processed. ! 365: * ! 366: */ ! 367: ! 368: writerequest(0, stdout); /* global requests eg. manual feed */ ! 369: setencoding(fontencoding); /* unnecessary */ ! 370: fprintf(stdout, "setup\n"); ! 371: ! 372: if ( formsperpage > 1 ) { /* followed by stuff for multiple pages */ ! 373: if ( cat(formfile) == FALSE ) ! 374: error(FATAL, "can't read %s", formfile); ! 375: fprintf(stdout, "%d setupforms\n", formsperpage); ! 376: } /* End if */ ! 377: ! 378: fprintf(stdout, "%s", ENDSETUP); ! 379: ! 380: } /* End of setup */ ! 381: ! 382: /*****************************************************************************/ ! 383: ! 384: arguments() ! 385: ! 386: { ! 387: ! 388: FILE *fp; /* next input file */ ! 389: ! 390: /* ! 391: * ! 392: * Makes sure all the non-option command line arguments are processed. If we get ! 393: * here and there aren't any arguments left, or if '-' is one of the input files ! 394: * we'll process stdin. ! 395: * ! 396: */ ! 397: ! 398: if ( argc < 1 ) ! 399: bitmap(stdin); ! 400: else { /* at least one argument is left */ ! 401: while ( argc > 0 ) { ! 402: if ( strcmp(*argv, "-") == 0 ) ! 403: fp = stdin; ! 404: else if ( (fp = fopen(*argv, "r")) == NULL ) ! 405: error(FATAL, "can't open %s", *argv); ! 406: bitmap(fp); ! 407: if ( fp != stdin ) ! 408: fclose(fp); ! 409: argc--; ! 410: argv++; ! 411: } /* End while */ ! 412: } /* End else */ ! 413: ! 414: } /* End of arguments */ ! 415: ! 416: /*****************************************************************************/ ! 417: ! 418: done() ! 419: ! 420: { ! 421: ! 422: /* ! 423: * ! 424: * Finished with all the input files, so mark the end of the pages with a TRAILER ! 425: * comment, make sure the last page prints, and add things like the PAGES comment ! 426: * that can only be determined after all the input files have been read. ! 427: * ! 428: */ ! 429: ! 430: fprintf(stdout, "%s", TRAILER); ! 431: fprintf(stdout, "done\n"); ! 432: fprintf(stdout, "%s 0 0 %d %d\n", BOUNDINGBOX, (bbox[0]*72+100)/100, (bbox[1]*72+100)/100); ! 433: fprintf(stdout, "%s %d\n", PAGES, printed); ! 434: ! 435: } /* End of done */ ! 436: ! 437: /*****************************************************************************/ ! 438: ! 439: account() ! 440: ! 441: { ! 442: ! 443: /* ! 444: * ! 445: * Writes an accounting record to *fp_acct provided it's not NULL. Accounting is ! 446: * requested using the -A or -J options. ! 447: * ! 448: */ ! 449: ! 450: if ( fp_acct != NULL ) ! 451: fprintf(fp_acct, " print %d\n copies %d\n", printed, copies); ! 452: ! 453: } /* End of account */ ! 454: ! 455: /*****************************************************************************/ ! 456: ! 457: bitmap(fp) ! 458: ! 459: FILE *fp; /* next input file */ ! 460: ! 461: { ! 462: ! 463: int count; /* pattern repeats this many times */ ! 464: long total; /* expect this many patterns */ ! 465: ! 466: /* ! 467: * ! 468: * Reads all the bitmaps from the next input file, translates each one into ! 469: * PostScript, and arranges to have one bitmap printed on each page. Multiple ! 470: * bitmaps per input file work. ! 471: * ! 472: */ ! 473: ! 474: fp_in = fp; /* everyone reads from this file */ ! 475: ! 476: while ( dimensions() == TRUE ) { ! 477: patcount = 0; ! 478: total = scanlines * patterns; ! 479: ! 480: bbox[0] = MAX(bbox[0], patterns*16); /* for BoundingBox comment */ ! 481: bbox[1] = MAX(bbox[1], scanlines); ! 482: ! 483: redirect(++page); ! 484: fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1); ! 485: fprintf(fp_out, "/saveobj save def\n"); ! 486: writerequest(printed+1, fp_out); ! 487: ! 488: fprintf(fp_out, "%s ", (v8format == TRUE && v8undo == FALSE) ? "true" : "false"); ! 489: fprintf(fp_out, "%s ", (flip == TRUE) ? "true" : "false"); ! 490: fprintf(fp_out, "%d %d bitmap\n", patterns * 16, scanlines); ! 491: ! 492: while ( patcount != total && (count = getc(fp)) != EOF ) { ! 493: addrast(count); ! 494: patcount += (count & 0177); ! 495: if ( patcount % patterns == 0 ) ! 496: putrast(); ! 497: } /* End while */ ! 498: ! 499: if ( debug == ON ) ! 500: fprintf(stderr, "patterns = %d, scanlines = %d, patcount = %d\n", patterns, scanlines, patcount); ! 501: ! 502: if ( total != patcount ) ! 503: error(FATAL, "bitmap format error"); ! 504: ! 505: if ( fp_out == stdout ) printed++; ! 506: ! 507: fprintf(fp_out, "showpage\n"); ! 508: fprintf(fp_out, "saveobj restore\n"); ! 509: fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed); ! 510: } /* End while */ ! 511: ! 512: } /* End of bitmap */ ! 513: ! 514: /*****************************************************************************/ ! 515: ! 516: dimensions() ! 517: ! 518: { ! 519: ! 520: int ox, oy; /* coordinates of the origin */ ! 521: int cx, cy; /* and right corner of the bitmap */ ! 522: int i; /* loop index */ ! 523: ! 524: /* ! 525: * ! 526: * Determines the dimensions and type of the next bitmap. Eighth edition bitmaps ! 527: * have a zero in the first 16 bits. If valid dimensions are read TRUE is returned ! 528: * to the caller. Changed so the check of whether we're done (by testing scanlines ! 529: * or patterns) comes before the malloc(). ! 530: * ! 531: */ ! 532: ! 533: if ( (scanlines = getint()) == 0 ) { ! 534: ox = getint(); ! 535: oy = getint(); ! 536: cx = getint(); ! 537: cy = getint(); ! 538: scanlines = cy - oy; ! 539: patterns = (cx - ox + 15) / 16; ! 540: v8format = TRUE; ! 541: } else patterns = getint(); ! 542: ! 543: if ( scanlines <= 0 || patterns <= 0 ) /* done - don't do the malloc() */ ! 544: return(FALSE); ! 545: ! 546: if ( raster != NULL ) free(raster); ! 547: if ( prevrast != NULL ) free(prevrast); ! 548: ! 549: if ( (rptr = raster = (char *) malloc(patterns * 2)) == NULL ) ! 550: error(FATAL, "no memory"); ! 551: ! 552: if ( (prevrast = (char *) malloc(patterns * 2)) == NULL ) ! 553: error(FATAL, "no memory"); ! 554: ! 555: for ( i = 0; i < patterns * 2; i++ ) ! 556: *(prevrast+i) = 0377; ! 557: ! 558: eptr = rptr + patterns * 2; ! 559: ! 560: return(TRUE); ! 561: ! 562: } /* End of dimensions */ ! 563: ! 564: /*****************************************************************************/ ! 565: ! 566: addrast(count) ! 567: ! 568: int count; /* repeat count for next pattern */ ! 569: ! 570: { ! 571: ! 572: int size; /* number of bytes in next pattern */ ! 573: int l, h; /* high and low bytes */ ! 574: int i, j; /* loop indices */ ! 575: ! 576: /* ! 577: * ! 578: * Reads the input file and adds the appropriate number of bytes to the output ! 579: * raster line. If count has bit 7 on, one 16 bit pattern is read and repeated ! 580: * count & 0177 times. If bit 7 is off, count is the number of patterns read from ! 581: * fp_in - each one repeated once. ! 582: * ! 583: */ ! 584: ! 585: if ( count & 0200 ) { ! 586: size = 1; ! 587: count &= 0177; ! 588: } else { ! 589: size = count; ! 590: count = 1; ! 591: } /* End else */ ! 592: ! 593: for ( i = size; i > 0; i-- ) { ! 594: if ( (l = getc(fp_in)) == EOF || (h = getc(fp_in)) == EOF ) ! 595: return; ! 596: for ( j = count; j > 0; j-- ) { ! 597: *rptr++ = l; ! 598: *rptr++ = h; ! 599: } /* End for */ ! 600: } /* End for */ ! 601: ! 602: } /* End of addrast */ ! 603: ! 604: /*****************************************************************************/ ! 605: ! 606: putrast() ! 607: ! 608: { ! 609: ! 610: char *p1, *p2; /* starting and ending patterns */ ! 611: int n; /* set to bytes per pattern */ ! 612: int i; /* loop index */ ! 613: ! 614: /* ! 615: * ! 616: * Takes the scanline that's been saved in *raster, encodes it according to the ! 617: * value that's been assigned to bytespp, and writes the result to *fp_out. Each ! 618: * line in the output bitmap is terminated by a 0 on a line by itself. ! 619: * ! 620: */ ! 621: ! 622: n = (bytespp <= 0) ? 2 * patterns : bytespp; ! 623: ! 624: if ( v8format == TRUE && v8undo == TRUE ) ! 625: for ( i = 0; i < patterns * 2; i++ ) ! 626: *(raster+i) = (*(prevrast+i) ^= *(raster+i)); ! 627: ! 628: for ( p1 = raster, p2 = raster + n; p1 < eptr; p1 = p2 ) ! 629: if ( patncmp(p1, n) == TRUE ) { ! 630: while ( patncmp(p2, n) == TRUE ) p2 += n; ! 631: p2 += n; ! 632: fprintf(fp_out, "%d ", n); ! 633: for ( i = 0; i < n; i++, p1++ ) ! 634: fprintf(fp_out, "%.2X", ((int) *p1) & 0377); ! 635: fprintf(fp_out, " %d\n", (p2 - p1) / n); ! 636: } else { ! 637: while ( p2 < eptr && patncmp(p2, n) == FALSE ) p2 += n; ! 638: if ( p2 > eptr ) p2 = eptr; ! 639: fprintf(fp_out, "%d ", p2 - p1); ! 640: while ( p1 < p2 ) ! 641: fprintf(fp_out, "%.2X", ((int) *p1++) & 0377); ! 642: fprintf(fp_out, " 0\n"); ! 643: } /* End else */ ! 644: ! 645: fprintf(fp_out, "0\n"); ! 646: ! 647: rptr = raster; ! 648: ! 649: } /* End of putrast */ ! 650: ! 651: /*****************************************************************************/ ! 652: ! 653: patncmp(p1, n) ! 654: ! 655: char *p1; /* first patterns starts here */ ! 656: int n; /* and extends this many bytes */ ! 657: ! 658: { ! 659: ! 660: char *p2; /* address of the second pattern */ ! 661: ! 662: /* ! 663: * ! 664: * Compares the two n byte patterns *p1 and *(p1+n). FALSE is returned if they're ! 665: * different or extend past the end of the current raster line. ! 666: * ! 667: */ ! 668: ! 669: p2 = p1 + n; ! 670: ! 671: for ( ; n > 0; n--, p1++, p2++ ) ! 672: if ( p2 >= eptr || *p1 != *p2 ) ! 673: return(FALSE); ! 674: ! 675: return(TRUE); ! 676: ! 677: } /* End of patncmp */ ! 678: ! 679: /*****************************************************************************/ ! 680: ! 681: getint() ! 682: ! 683: { ! 684: ! 685: int h, l; /* high and low bytes */ ! 686: ! 687: /* ! 688: * ! 689: * Reads the next two bytes from *fp_in and returns the resulting integer. ! 690: * ! 691: */ ! 692: ! 693: if ( (l = getc(fp_in)) == EOF || (h = getc(fp_in)) == EOF ) ! 694: return(-1); ! 695: ! 696: return((h & 0377) << 8 | (l & 0377)); ! 697: ! 698: } /* End of getint */ ! 699: ! 700: /*****************************************************************************/ ! 701: ! 702: redirect(pg) ! 703: ! 704: int pg; /* next page we're printing */ ! 705: ! 706: { ! 707: ! 708: static FILE *fp_null = NULL; /* if output is turned off */ ! 709: ! 710: /* ! 711: * ! 712: * If we're not supposed to print page pg, fp_out will be directed to /dev/null, ! 713: * otherwise output goes to stdout. ! 714: * ! 715: */ ! 716: ! 717: if ( pg >= 0 && in_olist(pg) == ON ) ! 718: fp_out = stdout; ! 719: else if ( (fp_out = fp_null) == NULL ) ! 720: fp_out = fp_null = fopen("/dev/null", "w"); ! 721: ! 722: } /* End of redirect */ ! 723: ! 724: /*****************************************************************************/ ! 725:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.