Annotation of researchv10no/cmd/post.src/postdmd/postdmd.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.