Annotation of researchv9/X11/src/X.V11R1/clients/xpr/xpr.c, revision 1.1

1.1     ! root        1: #include <X11/copyright.h>
        !             2: 
        !             3: /*
        !             4:  * XPR - process xwd(1) files for the LN03 or LA100 printer
        !             5:  *
        !             6:  * Author: Michael R. Gretzinger, MIT Project Athena
        !             7:  * Copyright (C) 1985, Massachusetts Institute of Technology
        !             8:  *
        !             9:  * Modified by Marvin Solomon, Univeristy of Wisconsin, to handle Apple
        !            10:  * Laserwriter (PostScript) devices (-device ps).
        !            11:  * Also accepts the -compact flag that produces more compact output
        !            12:  * by using run-length encoding on white (1) pixels.
        !            13:  * This version does not (yet) support the following options
        !            14:  *   -append -dump -noff -nosixopt -split
        !            15:  * 
        !            16:  * Changes
        !            17:  * Copyright 1986 by Marvin Solomon and the University of Wisconsin
        !            18:  * 
        !            19:  * Permission to use, copy, modify, and distribute this
        !            20:  * software and its documentation for any purpose and without
        !            21:  * fee is hereby granted, provided that the above copyright
        !            22:  * notice appear in all copies and that both that copyright
        !            23:  * notice and this permission notice appear in supporting
        !            24:  * documentation, and that the names of Marvin Solomon and
        !            25:  * the University of Wisconsin not be used in
        !            26:  * advertising or publicity pertaining to distribution of the
        !            27:  * software without specific, written prior permission.
        !            28:  * Neither Marvin Solomon nor the University of Wisconsin
        !            29:  * makes any representations about the suitability of
        !            30:  * this software for any purpose.  It is provided "as is"
        !            31:  * without express or implied warranty.
        !            32:  * 
        !            33:  */
        !            34: 
        !            35: #ifndef lint
        !            36: static char *rcsid_xpr_c = "$Header: xpr.c,v 1.18 87/09/11 20:02:55 toddb Exp $";
        !            37: #endif
        !            38: 
        !            39: #include <sys/types.h>
        !            40: #include <sys/file.h>
        !            41: #include <sys/uio.h>
        !            42: #include <stdio.h>
        !            43: #include <pwd.h>
        !            44: #include "lncmd.h"
        !            45: #include <X11/Xlib.h>
        !            46: #include "X11/XWDFile.h"
        !            47: 
        !            48: int debug = 0;
        !            49: 
        !            50: enum device {LN01, LN03, LA100, PS};
        !            51: enum orientation {PORTRAIT, LANDSCAPE};
        !            52: 
        !            53: #define W_MAX 2400
        !            54: #define H_MAX 3150
        !            55: #define W_MARGIN 75
        !            56: #define H_MARGIN 37
        !            57: #define W_PAGE 2550
        !            58: #define H_PAGE 3225
        !            59: 
        !            60: #ifdef NOINLINE
        !            61: #define min(x,y) (((x)<(y))?(x):(y))
        !            62: #endif NOINLINE
        !            63: 
        !            64: #define F_PORTRAIT 1
        !            65: #define F_LANDSCAPE 2
        !            66: #define F_DUMP 4
        !            67: #define F_NOSIXOPT 8
        !            68: #define F_APPEND 16
        !            69: #define F_NOFF 32
        !            70: #define F_REPORT 64
        !            71: #define F_COMPACT 128
        !            72: 
        !            73: char *infilename = "stdin";
        !            74: 
        !            75: main(argc, argv)
        !            76: char **argv;
        !            77: {
        !            78:     unsigned long swaptest = 1;
        !            79:     XWDFileHeader win;
        !            80:     register unsigned char (*sixmap)[];
        !            81:     register int i;
        !            82:     register int iw;
        !            83:     register int ih;
        !            84:     register int sixel_count;
        !            85:     char *w_name;
        !            86:     char *filename;
        !            87:     char *output_filename;
        !            88:     int scale, width, height, flags, split;
        !            89:     int left, top;
        !            90:     int top_margin, left_margin;
        !            91:     int hpad;
        !            92:     char *header, *trailer;
        !            93:     enum orientation orientation;
        !            94:     enum device device;
        !            95:     
        !            96:     parse_args (argc, argv, &scale, &width, &height, &left, &top, &device, 
        !            97:                &flags, &split, &header, &trailer);
        !            98: 
        !            99:     /* read in window header */
        !           100:     read(0, &win, sizeof win);
        !           101:     if (*(char *) &swaptest)
        !           102:        _swaplong((char *) &win, sizeof(win));
        !           103: 
        !           104:     if (win.file_version != XWD_FILE_VERSION) {
        !           105:        fprintf(stderr,"xpr: file format version missmatch.\n");
        !           106:        exit(1);
        !           107:     }
        !           108:     if (win.header_size < sizeof(win)) {
        !           109:        fprintf(stderr,"xpr: header size is too small.\n");
        !           110:        exit(1);
        !           111:     }
        !           112: 
        !           113:     if (win.pixmap_depth != 1 && win.pixmap_format != XYPixmap) {
        !           114:         fprintf(stderr,"xpr: image is not in XY format");
        !           115:        exit(1);
        !           116:     }
        !           117: 
        !           118:     if (win.byte_order != win.bitmap_bit_order)
        !           119:         fprintf(stderr,"xpr: image will be incorrect, byte swapping required but not performed.\n");
        !           120: 
        !           121:     w_name = (char *)malloc(win.header_size - sizeof win);
        !           122:     read(0, w_name, win.header_size - sizeof win);
        !           123:     
        !           124:     if(win.ncolors)
        !           125:        read(0,
        !           126:             malloc(win.ncolors * sizeof(XColor)),
        !           127:             win.ncolors * sizeof(XColor));
        !           128: 
        !           129:     /* calculate orientation and scale */
        !           130:     setup_layout(device, win.pixmap_width, win.pixmap_height, flags, width, 
        !           131:                 height, header, trailer, &scale, &orientation);
        !           132: 
        !           133:     if (device == PS) {
        !           134:        iw = win.pixmap_width;
        !           135:        ih = win.pixmap_height;
        !           136:     } else {
        !           137:        /* calculate w and h cell count */
        !           138:        iw = win.pixmap_width;
        !           139:        ih = (win.pixmap_height + 5) / 6;
        !           140:        hpad = (ih * 6) - win.pixmap_height;
        !           141: 
        !           142:        /* build pixcells from input file */
        !           143:        sixel_count = iw * ih;
        !           144:        sixmap = (unsigned char (*)[])malloc(sixel_count);
        !           145:        build_sixmap(iw, ih, sixmap, hpad, &win);
        !           146:     }
        !           147: 
        !           148:     /* output commands and sixel graphics */
        !           149:     if (device == LN03) {
        !           150: /*     ln03_grind_fonts(sixmap, iw, ih, scale, &pixmap); */
        !           151:        ln03_setup(iw, ih, orientation, scale, left, top,
        !           152:                   &left_margin, &top_margin, flags, header, trailer);
        !           153:        ln03_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT), split, 
        !           154:                           scale, top_margin, left_margin);
        !           155:        ln03_finish();
        !           156:     } else if (device == LA100) {
        !           157:        la100_setup(iw, ih, scale);
        !           158:        la100_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT));
        !           159:        la100_finish();
        !           160:     } else if (device == PS) {
        !           161:        ps_setup(iw, ih, orientation, scale, left, top,
        !           162:                   flags, header, trailer, w_name);
        !           163:        ps_output_bits(iw, ih, flags, orientation, &win);
        !           164:        ps_finish();
        !           165:     } else {
        !           166:        fprintf(stderr, "xpr: device not supported\n");
        !           167:     }
        !           168:     
        !           169:     /* print some statistics */
        !           170:     if (flags & F_REPORT) {
        !           171:        fprintf(stderr, "Name: %s\n", w_name);
        !           172:        fprintf(stderr, "Width: %d, Height: %d\n", win.pixmap_width, 
        !           173:                win.pixmap_height);
        !           174:        fprintf(stderr, "Orientation: %s, Scale: %d\n", 
        !           175:                (orientation==PORTRAIT) ? "Portrait" : "Landscape", scale);
        !           176:     }
        !           177:     if (device != PS && (flags & F_DUMP)) dump_sixmap(sixmap, iw, ih);
        !           178: }
        !           179: 
        !           180: parse_args(argc, argv, scale, width, height, left, top, device, flags, 
        !           181:           split, header, trailer)
        !           182: register int argc;
        !           183: register char **argv;
        !           184: int *scale;
        !           185: int *width;
        !           186: int *height;
        !           187: int *left;
        !           188: int *top;
        !           189: enum device *device;
        !           190: int *flags;
        !           191: int *split;
        !           192: char **header;
        !           193: char **trailer;
        !           194: {
        !           195:     register char *output_filename;
        !           196:     register int f;
        !           197:     register int len;
        !           198:     register int pos;
        !           199:     double atof();
        !           200:     int atoi();
        !           201: 
        !           202:     output_filename = NULL;
        !           203:     *device = LN03;    /* default */
        !           204:     *flags = 0;
        !           205:     *split = 1;
        !           206:     *width = -1;
        !           207:     *height = -1;
        !           208:     *top = -1;
        !           209:     *left = -1;
        !           210:     *header = NULL;
        !           211:     *trailer = NULL;
        !           212:     
        !           213:     argc--;
        !           214:     argv++;
        !           215: 
        !           216:     while (argc > 0 && argv[0][0] == '-') {
        !           217:        len = strlen(*argv);
        !           218:        switch (argv[0][1]) {
        !           219:        case 'a':               /* -append <filename> */
        !           220:            if (!bcmp(*argv, "-append", len)) {
        !           221:                argc--; argv++;
        !           222:                output_filename = *argv;
        !           223:                *flags |= F_APPEND;
        !           224:            }
        !           225:            break;
        !           226: 
        !           227:        case 'd':               /* -device {ln03 | la100 | ps | lw} | -dump */
        !           228:            if (len <= 2) {
        !           229:                fprintf(stderr, "xpr: ambiguous option: \"%s\"\n", *argv);
        !           230:                exit(1);
        !           231:            }
        !           232:            if (!bcmp(*argv, "-device", len)) {
        !           233:                argc--; argv++;
        !           234:                len = strlen(*argv);
        !           235:                if (!bcmp(*argv, "ln03", len)) {
        !           236:                    *device = LN03;
        !           237:                } else if (!bcmp(*argv, "la100", len)) {
        !           238:                    *device = LA100;
        !           239:                } else if (!bcmp(*argv, "ps", len)) {
        !           240:                    *device = PS;
        !           241:                } else if (!bcmp(*argv, "lw", len)) {
        !           242:                    *device = PS;
        !           243:                } else {
        !           244:                    fprintf(stderr, 
        !           245:                            "xpr: device \"%s\" not supported\n", *argv);
        !           246:                    exit(1);
        !           247:                }
        !           248:            } else if (!bcmp(*argv, "-dump", len)) {
        !           249:                *flags |= F_DUMP;
        !           250:            }
        !           251:            break;
        !           252: 
        !           253:        case 'h':               /* -height <inches> */
        !           254:            if (len <= 3) {
        !           255:                fprintf(stderr, "xpr: ambiguous option: \"%s\"\n", *argv);
        !           256:                exit(1);
        !           257:            }
        !           258:            if (!bcmp(*argv, "-height", len)) {
        !           259:                argc--; argv++;
        !           260:                *height = (int)(300.0 * atof(*argv));
        !           261:            } else if (!bcmp(*argv, "-header", len)) {
        !           262:                argc--; argv++;
        !           263:                *header = *argv;
        !           264:            }
        !           265:            break;
        !           266: 
        !           267:        case 'l':               /* -landscape | -left <inches> */
        !           268:            if (!bcmp(*argv, "-landscape", len)) {
        !           269:                *flags |= F_LANDSCAPE;
        !           270:            } else if (!bcmp(*argv, "-left", len)) {
        !           271:                argc--; argv++;
        !           272:                *left = (int)(300.0 * atof(*argv));
        !           273:            }
        !           274:            break;
        !           275: 
        !           276:        case 'n':               /* -nosixopt | -noff */
        !           277:            if (len <= 3) {
        !           278:                fprintf(stderr, "xpr: ambiguous option: \"%s\"\n", *argv);
        !           279:                exit(1);
        !           280:            }
        !           281:            if (!bcmp(*argv, "-nosixopt", len)) {
        !           282:                *flags |= F_NOSIXOPT;
        !           283:            } else if (!bcmp(*argv, "-noff", len)) {
        !           284:                *flags |= F_NOFF;
        !           285:            }
        !           286:            break;
        !           287: 
        !           288:        case 'o':               /* -output <filename> */
        !           289:            if (!bcmp(*argv, "-output", len)) {
        !           290:                argc--; argv++;
        !           291:                output_filename = *argv;
        !           292:            }
        !           293:            break;
        !           294: 
        !           295:        case 'p':               /* -portrait */
        !           296:            if (!bcmp(*argv, "-portrait", len)) {
        !           297:                *flags |= F_PORTRAIT;
        !           298:            }
        !           299:            break;
        !           300: 
        !           301:        case 'c':               /* -compact */
        !           302:            if (!bcmp(*argv, "-compact", len)) {
        !           303:                *flags |= F_COMPACT;
        !           304:            }
        !           305:            break;
        !           306: 
        !           307:        case 'r':               /* -report */
        !           308:            if (!bcmp(*argv, "-report", len)) {
        !           309:                *flags |= F_REPORT;
        !           310:            }
        !           311:            break;
        !           312: 
        !           313:        case 's':               /* -scale <scale> | -split <n-pages> */
        !           314:            if (!bcmp(*argv, "-scale", len)) {
        !           315:                argc--; argv++;
        !           316:                *scale = atoi(*argv);
        !           317:            } else if (!bcmp(*argv, "-split", len)) {
        !           318:                argc--; argv++;
        !           319:                *split = atoi(*argv);
        !           320:            }
        !           321:            break;
        !           322: 
        !           323:        case 't':               /* -top <inches> */
        !           324:            if (len <= 2) {
        !           325:                fprintf(stderr, "xpr: ambigous option: \"%s\"\n", *argv);
        !           326:                exit(1);
        !           327:            }
        !           328:            if (!bcmp(*argv, "-top", len)) {
        !           329:                argc--; argv++;
        !           330:                *top = (int)(300.0 * atof(*argv));
        !           331:            } else if (!bcmp(*argv, "-trailer", len)) {
        !           332:                argc--; argv++;
        !           333:                *trailer = *argv;
        !           334:            }
        !           335:            break;
        !           336: 
        !           337:        case 'w':               /* -width <inches> */
        !           338:            if (!bcmp(*argv, "-width", len)) {
        !           339:                argc--; argv++;
        !           340:                *width = (int)(300.0 * atof(*argv));
        !           341:            }
        !           342:            break;
        !           343: 
        !           344:        }
        !           345:        argc--; argv++;
        !           346:     }
        !           347: 
        !           348:     if (argc > 0) {
        !           349:        f = open(*argv, O_RDONLY, 0);
        !           350:        if (f < 0) {
        !           351:            fprintf(stderr, "xpr: error opening \"%s\" for input\n", *argv);
        !           352:            perror("");
        !           353:            exit(1);
        !           354:        }
        !           355:        dup2(f, 0);
        !           356:        close(f);
        !           357:        infilename = *argv;
        !           358: /*     if (output_filename == NULL) {
        !           359:            output_filename = (char *)malloc(strlen(*argv)+10);
        !           360:            build_output_filename(*argv, *device, output_filename);
        !           361:        } */
        !           362:     }
        !           363: 
        !           364:     if (output_filename != NULL) {
        !           365:        if (!(*flags & F_APPEND)) {
        !           366:            f = open(output_filename, O_CREAT|O_WRONLY|O_TRUNC, 0664);
        !           367:        } else {
        !           368:            f = open(output_filename, O_WRONLY, 0);
        !           369:        }
        !           370:        if (f < 0) {
        !           371:            fprintf(stderr, "xpr: error opening \"%s\" for output\n", 
        !           372:                    output_filename);
        !           373:            perror("xpr");
        !           374:            exit(1);
        !           375:        }
        !           376:        if (*flags & F_APPEND) {
        !           377:            pos = lseek(f, 0, 2);          /* get eof position */
        !           378:            if (*flags & F_NOFF) pos -= 3; /* set position before trailing */
        !           379:                                           /*     formfeed and reset */
        !           380:            lseek(f, pos, 0);              /* set pointer */
        !           381:        }
        !           382:        dup2(f, 1);
        !           383:        close(f);
        !           384:     }
        !           385: }
        !           386: 
        !           387: setup_layout(device, win_width, win_height, flags, width, height, 
        !           388:             header, trailer, scale, orientation)
        !           389: enum device device;
        !           390: int win_width;
        !           391: int win_height;
        !           392: int flags;
        !           393: int width;
        !           394: int height;
        !           395: char *header;
        !           396: char *trailer;
        !           397: int *scale;
        !           398: enum orientation *orientation;
        !           399: {
        !           400:     register int w_scale;
        !           401:     register int h_scale;
        !           402:     register int iscale = *scale;
        !           403:     register int w_max;
        !           404:     register int h_max;
        !           405: 
        !           406:     if (header != NULL) win_height += 75;
        !           407:     if (trailer != NULL) win_height += 75;
        !           408: 
        !           409:     /* check maximum width and height; set orientation and scale*/
        !           410:     if (device == LN03 || device == PS) {
        !           411:        if ((win_width < win_height || (flags & F_PORTRAIT)) && 
        !           412:            !(flags & F_LANDSCAPE)) {
        !           413:            *orientation = PORTRAIT;
        !           414:            w_max = (width > 0)? width : W_MAX;
        !           415:            h_max = (height > 0)? height : H_MAX;
        !           416:            w_scale = w_max / win_width;
        !           417:            h_scale = h_max / win_height;
        !           418:            *scale = min(w_scale, h_scale);
        !           419:        } else {
        !           420:            *orientation = LANDSCAPE;
        !           421:            w_max = (width > 0)? width : H_MAX;
        !           422:            h_max = (height > 0)? height : W_MAX;
        !           423:            w_scale = w_max / win_width;
        !           424:            h_scale = h_max / win_height;
        !           425:            *scale = min(w_scale, h_scale);
        !           426:        }
        !           427:     } else {                   /* device == LA100 */
        !           428:        *orientation = PORTRAIT;
        !           429:        *scale = W_MAX / win_width;
        !           430:     }
        !           431:     if (*scale == 0) *scale = 1;
        !           432:     if (*scale > 6) *scale = 6;
        !           433:     if (iscale > 0 && iscale < *scale) *scale = iscale;
        !           434: }
        !           435: 
        !           436: dump_sixmap(sixmap, iw, ih)
        !           437: register unsigned char (*sixmap)[];
        !           438: int iw;
        !           439: int ih;
        !           440: {
        !           441:     register int i, j;
        !           442:     register unsigned char *c;
        !           443: 
        !           444:     c = (unsigned char *)sixmap;
        !           445:     fprintf(stderr, "Sixmap:\n");
        !           446:     for (i = 0; i < ih; i++) {
        !           447:        for (j = 0; j < iw; j++) {
        !           448:            fprintf(stderr, "%02X ", *c++);
        !           449:        }
        !           450:        fprintf(stderr, "\n\n");
        !           451:     }
        !           452: }
        !           453: 
        !           454: build_sixmap(iw, ih, sixmap, hpad, win)
        !           455: int ih;
        !           456: int iw;
        !           457: unsigned char (*sixmap)[];
        !           458: int hpad;
        !           459: XWDFileHeader *win;
        !           460: {
        !           461:     int iwb = win->bytes_per_line;
        !           462:     int iww;
        !           463:     int rsize, cc;
        !           464:     int w, maxw;
        !           465:     struct iovec linevec[6];
        !           466:     unsigned char line[6][500];
        !           467:     register unsigned char *c;
        !           468:     register int i, j, k, m;
        !           469:     register int sixel;
        !           470:     static int mask[] = {~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128};
        !           471: 
        !           472:     c = (unsigned char *)sixmap;
        !           473: 
        !           474:     for (i = 0; i <= 5; i++) {
        !           475:        linevec[i].iov_base = (caddr_t)line[i];
        !           476:        linevec[i].iov_len = iwb;
        !           477:     }
        !           478: 
        !           479:     while (--ih >= 0) {
        !           480:        if (ih > 0 || hpad == 0) {
        !           481:            rsize = iwb * 6;
        !           482:            while (rsize > 0) {
        !           483:                cc = readv(0, linevec, 6);
        !           484:                if (cc == 0) break;
        !           485:                rsize -= cc;
        !           486:            }
        !           487:        } else {
        !           488:            i = 6 - hpad;
        !           489:            rsize = iwb * i;
        !           490:            while (rsize > 0) {
        !           491:                cc = readv(0, linevec, i);
        !           492:                if (cc == 0) break;
        !           493:                rsize -= cc;
        !           494:            }
        !           495:            for (; i < 6; i++)
        !           496:                for (j = 0; j < iwb; j++) line[i][j] = 0xFF;
        !           497:        }
        !           498: 
        !           499:        if (win->bitmap_bit_order == MSBFirst)
        !           500:            for (i = 0; i <= 5; i++)
        !           501:                _swapbits((char *)&line[i][0], iwb);
        !           502: 
        !           503: #ifndef NOINLINE
        !           504:        for (i = 0; i < iw; i++) {
        !           505:            sixel =  extzv(line[0], i, 1);
        !           506:            sixel |= extzv(line[1], i, 1) << 1;
        !           507:            sixel |= extzv(line[2], i, 1) << 2;
        !           508:            sixel |= extzv(line[3], i, 1) << 3;
        !           509:            sixel |= extzv(line[4], i, 1) << 4;
        !           510:            sixel |= extzv(line[5], i, 1) << 5;
        !           511:            *c++ = sixel;
        !           512:        }
        !           513: #else
        !           514:        for (i = 0, w = iw; w > 0; i++) {
        !           515:            for (j = 0; j <= 7; j++) {
        !           516:                m = mask[j];
        !           517:                k = -j;
        !           518:                sixel =  ((line[0][i] & ~m) << k++);
        !           519:                sixel |= ((line[1][i] & ~m) << k++);
        !           520:                sixel |= ((line[2][i] & ~m) << k++);
        !           521:                sixel |= ((line[3][i] & ~m) << k++);
        !           522:                sixel |= ((line[4][i] & ~m) << k++);
        !           523:                sixel |= ((line[5][i] & ~m) << k);
        !           524:                *c++ = sixel;
        !           525:                if (--w == 0) break;
        !           526:            }
        !           527:        }
        !           528: #endif
        !           529:     }
        !           530: }
        !           531: 
        !           532: build_output_filename(name, device, oname)
        !           533: register char *name, *oname;
        !           534: enum device device;
        !           535: {
        !           536:     while (*name && *name != '.') *oname++ = *name++;
        !           537:     switch (device) {
        !           538:     case LN03: bcopy(".ln03", oname, 6); break;
        !           539:     case LA100:        bcopy(".la100", oname, 7); break;
        !           540:     }
        !           541: }
        !           542: 
        !           543: /*
        !           544: ln03_grind_fonts(sixmap, iw, ih, scale, pixmap)
        !           545: unsigned char (*sixmap)[];
        !           546: int iw;
        !           547: int ih;
        !           548: int scale;
        !           549: struct pixmap (**pixmap)[];
        !           550: {
        !           551: }
        !           552: */
        !           553: 
        !           554: ln03_setup(iw, ih, orientation, scale, left, top, left_margin, top_margin, 
        !           555:           flags, header, trailer)
        !           556: int iw;
        !           557: int ih;
        !           558: enum orientation orientation;
        !           559: int scale;
        !           560: int left;
        !           561: int top;
        !           562: int *left_margin;
        !           563: int *top_margin;
        !           564: int flags;
        !           565: char *header;
        !           566: char *trailer;
        !           567: {
        !           568:     register int i;
        !           569:     register int lm, tm, xm;
        !           570:     char fontname[6];
        !           571:     char buf[256];
        !           572:     register char *bp = buf;
        !           573:        
        !           574:     if (!(flags & F_APPEND)) {
        !           575:        sprintf(bp, LN_RIS); bp += 2;
        !           576:        sprintf(bp, LN_SSU, 7); bp += 5;
        !           577:        sprintf(bp, LN_PUM_SET); bp += sizeof LN_PUM_SET - 1;
        !           578:     }
        !           579: 
        !           580:     if (orientation == PORTRAIT) {
        !           581:        lm = (left > 0)? left : (((W_MAX - scale * iw) / 2) + W_MARGIN);
        !           582:        tm = (top > 0)? top : (((H_MAX - scale * ih * 6) / 2) + H_MARGIN);
        !           583:        sprintf(bp, LN_PFS, "?20"); bp += 7;
        !           584:        sprintf(bp, LN_DECOPM_SET); bp += sizeof LN_DECOPM_SET - 1;
        !           585:        sprintf(bp, LN_DECSLRM, lm, W_PAGE - lm); bp += strlen(bp);
        !           586:     } else {
        !           587:        lm = (left > 0)? left : (((H_MAX - scale * iw) / 2) + H_MARGIN);
        !           588:        tm = (top > 0)? top : (((W_MAX - scale * ih * 6) / 2) + W_MARGIN);
        !           589:        sprintf(bp, LN_PFS, "?21"); bp += 7;
        !           590:        sprintf(bp, LN_DECOPM_SET); bp += sizeof LN_DECOPM_SET - 1;
        !           591:        sprintf(bp, LN_DECSLRM, lm, H_PAGE - lm); bp += strlen(bp);
        !           592:     }
        !           593: 
        !           594:     if (header != NULL) {
        !           595:        sprintf(bp, LN_VPA, tm - 100); bp += strlen(bp);
        !           596:        i = strlen(header);
        !           597:        xm = (((scale * iw) - (i * 30)) / 2) + lm;
        !           598:        sprintf(bp, LN_HPA, xm); bp += strlen(bp);
        !           599:        sprintf(bp, LN_SGR, 3); bp += strlen(bp);
        !           600:        bcopy(header, bp, i);
        !           601:        bp += i;
        !           602:     }
        !           603:     if (trailer != NULL) {
        !           604:        sprintf(bp, LN_VPA, tm + (scale * ih * 6) + 75); bp += strlen(bp);
        !           605:        i = strlen(trailer);
        !           606:        xm = (((scale * iw) - (i * 30)) / 2) + lm;
        !           607:        sprintf(bp, LN_HPA, xm); bp += strlen(bp);
        !           608:        sprintf(bp, LN_SGR, 3); bp += strlen(bp);
        !           609:        bcopy(trailer, bp, i);
        !           610:        bp += i;
        !           611:     }
        !           612: 
        !           613:     sprintf(bp, LN_HPA, lm); bp += strlen(bp);
        !           614:     sprintf(bp, LN_VPA, tm); bp += strlen(bp);
        !           615:     sprintf(bp, LN_SIXEL_GRAPHICS, 9, 0, scale); bp += strlen(bp);
        !           616:     sprintf(bp, "\"1;1"); bp += 4; /* Pixel aspect ratio */
        !           617:     write(1, buf, bp-buf);
        !           618:     *top_margin = tm;
        !           619:     *left_margin = lm;
        !           620: }
        !           621: 
        !           622: #define LN03_RESET "\033c"
        !           623: 
        !           624: ln03_finish()
        !           625: {
        !           626:     write(1, LN03_RESET, sizeof LN03_RESET - 1);
        !           627: }
        !           628: 
        !           629: la100_setup(iw, ih, scale)
        !           630: {
        !           631:     unsigned char buf[256];
        !           632:     register unsigned char *bp;
        !           633:     int lm, tm;
        !           634: 
        !           635:     bp = buf;
        !           636:     lm = ((80 - (int)((double)iw / 6.6)) / 2) - 1;
        !           637:     if (lm < 1) lm = 1;
        !           638:     tm = ((66 - (int)((double)ih / 2)) / 2) - 1;
        !           639:     if (tm < 1) tm = 1;
        !           640:     sprintf(bp, "\033[%d;%ds", lm, 81-lm); bp += strlen(bp);
        !           641:     sprintf(bp, "\033[?7l"); bp += 5;
        !           642:     sprintf(bp, "\033[%dd", tm); bp += strlen(bp);
        !           643:     sprintf(bp, "\033[%d`", lm); bp += strlen(bp);
        !           644:     sprintf(bp, "\033P0q"); bp += 4;
        !           645:     write(1, buf, bp-buf);
        !           646: }
        !           647: 
        !           648: #define LA100_RESET "\033[1;80s\033[?7h"
        !           649: 
        !           650: la100_finish()
        !           651: {
        !           652:     write(1, LA100_RESET, sizeof LA100_RESET - 1);
        !           653: }
        !           654: 
        !           655: #define COMMENTVERSION "PS-Adobe-1.0"
        !           656: 
        !           657: #ifdef XPROLOG
        !           658: /* for debugging, get the prolog from a file */
        !           659: dump_prolog(flags) {
        !           660:     char *fname=(flags & F_COMPACT) ? "prolog.compact" : "prolog";
        !           661:     FILE *fi = fopen(fname,"r");
        !           662:     char buf[1024];
        !           663: 
        !           664:     if (fi==NULL) {
        !           665:        perror(fname);
        !           666:        exit(1);
        !           667:     }
        !           668:     while (fgets(buf,1024,fi)) fputs(buf,stdout);
        !           669:     fclose(fi);
        !           670: }
        !           671: 
        !           672: #else XPROLOG
        !           673: /* postscript "programs" to unpack and print the bitmaps being sent */
        !           674: 
        !           675: char *ps_prolog_compact[] = {
        !           676:     "%%Pages: 1",
        !           677:     "%%EndProlog",
        !           678:     "%%Page: 1 1",
        !           679:     "",
        !           680:     "/bitgen",
        !           681:     "  {",
        !           682:     "          /nextpos 0 def",
        !           683:     "          currentfile bufspace readhexstring pop % get a chunk of input",
        !           684:     "          % interpret each byte of the input",
        !           685:     "          {",
        !           686:     "                  flag { % if the previous byte was FF",
        !           687:     "                          /len exch def % this byte is a count",
        !           688:     "                          result",
        !           689:     "                          nextpos",
        !           690:     "                          FFstring 0 len getinterval % grap a chunk of FF's",
        !           691:     "                                  putinterval % and stuff them into the result",
        !           692:     "                          /nextpos nextpos len add def",
        !           693:     "                          /flag false def",
        !           694:     "                  }{ % otherwise",
        !           695:     "                          dup 255 eq { % if this byte is FF",
        !           696:     "                                  /flag true def % just set the flag",
        !           697:     "                                  pop % and toss the FF",
        !           698:     "                          }{ % otherwise",
        !           699:     "                                  % move this byte to the result",
        !           700:     "                                  result nextpos",
        !           701:     "                                          3 -1 roll % roll the current byte back to the top",
        !           702:     "                                          put",
        !           703:     "                                  /nextpos nextpos 1 add def",
        !           704:     "                          } ifelse",
        !           705:     "                  } ifelse",
        !           706:     "          } forall",
        !           707:     "          % trim unused space from end of result",
        !           708:     "          result 0 nextpos getinterval",
        !           709:     "  } def",
        !           710:     "",
        !           711:     "",
        !           712:     "/bitdump % stk: width, height, iscale",
        !           713:     "  % dump a bit image with lower left corner at current origin,",
        !           714:     "  % scaling by iscale (iscale=1 means 1/300 inch per pixel)",
        !           715:     "  {",
        !           716:     "          % read arguments",
        !           717:     "          /iscale exch def",
        !           718:     "          /height exch def",
        !           719:     "          /width exch def",
        !           720:     "",
        !           721:     "          % scale appropriately",
        !           722:     "          width iscale mul height iscale mul scale",
        !           723:     "",
        !           724:     "          % data structures:",
        !           725:     "",
        !           726:     "          % allocate space for one line of input",
        !           727:     "          /bufspace 36 string def",
        !           728:     "",
        !           729:     "          % string of FF's",
        !           730:     "          /FFstring 256 string def",
        !           731:     "          % for all i FFstring[i]=255",
        !           732:     "          0 1 255 { FFstring exch 255 put } for",
        !           733:     "",
        !           734:     "          % 'escape' flag",
        !           735:     "          /flag false def",
        !           736:     "",
        !           737:     "          % space for a chunk of generated bits",
        !           738:     "          /result 1000 string def",
        !           739:     "",
        !           740:     "          % read and dump the image",
        !           741:     "          width height 1 [width 0 0 height neg 0 height]",
        !           742:     "                  { bitgen }",
        !           743:     "                  image",
        !           744:     "  } def",
        !           745:     0
        !           746: };
        !           747: 
        !           748: char *ps_prolog[] = {
        !           749:     "%%Pages: 1",
        !           750:     "%%EndProlog",
        !           751:     "%%Page: 1 1",
        !           752:     "",
        !           753:     "/bitdump % stk: width, height, iscale",
        !           754:     "% dump a bit image with lower left corner at current origin,",
        !           755:     "% scaling by iscale (iscale=1 means 1/300 inch per pixel)",
        !           756:     "{",
        !           757:     "  % read arguments",
        !           758:     "  /iscale exch def",
        !           759:     "  /height exch def",
        !           760:     "  /width exch def",
        !           761:     "",
        !           762:     "  % scale appropriately",
        !           763:     "  width iscale mul height iscale mul scale",
        !           764:     "",
        !           765:     "  % allocate space for one scanline of input",
        !           766:     "  /picstr % picstr holds one scan line",
        !           767:     "          width 7 add 8 idiv % width of image in bytes = ceiling(width/8)",
        !           768:     "          string",
        !           769:     "          def",
        !           770:     "",
        !           771:     "  % read and dump the image",
        !           772:     "  width height 1 [width 0 0 height neg 0 height]",
        !           773:     "  { currentfile picstr readhexstring pop }",
        !           774:     "  image",
        !           775:     "} def",
        !           776:     0
        !           777: };
        !           778: 
        !           779: dump_prolog(flags) {
        !           780:     char **p = (flags & F_COMPACT) ? ps_prolog_compact : ps_prolog;
        !           781:     while (*p) printf("%s\n",*p++);
        !           782: }
        !           783: #endif XPROLOG
        !           784: 
        !           785: #define PAPER_WIDTH 85*30 /* 8.5 inches */
        !           786: #define PAPER_LENGTH 11*300 /* 11 inches */
        !           787: 
        !           788: static int
        !           789: points(n)
        !           790: {
        !           791:     /* scale n from pixels (1/300 inch) to points (1/72 inch) */
        !           792:     n *= 72;
        !           793:     return n/300;
        !           794: }
        !           795: 
        !           796: static char *
        !           797: escape(s)
        !           798: char *s;
        !           799: {
        !           800:     /* make a version of s in which control characters are deleted and
        !           801:      * special characters are escaped.
        !           802:      */
        !           803:     static char buf[200];
        !           804:     char *p = buf;
        !           805: 
        !           806:     for (;*s;s++) {
        !           807:        if (*s < ' ' || *s > 0176) continue;
        !           808:        if (*s==')' || *s=='(' || *s == '\\') {
        !           809:            sprintf(p,"\\%03o",*s);
        !           810:            p += 4;
        !           811:        }
        !           812:        else *p++ = *s;
        !           813:     }
        !           814:     *p = 0;
        !           815:     return buf;
        !           816: }
        !           817: 
        !           818: /* ARGSUSED */
        !           819: ps_setup(iw, ih, orientation, scale, left, top, 
        !           820:           flags, header, trailer, name)
        !           821: int iw;
        !           822: int ih;
        !           823: enum orientation orientation;
        !           824: int scale;
        !           825: int left;
        !           826: int top;
        !           827: int flags;
        !           828: char *header;
        !           829: char *trailer;
        !           830: char *name;
        !           831: {
        !           832:     char    hostname[256];
        !           833:     struct passwd  *pswd;
        !           834:     long    clock;
        !           835:     int lm, bm; /* left (bottom) margin (paper in portrait orientation) */
        !           836: 
        !           837:     printf ("%%!%s\n", COMMENTVERSION);
        !           838:     pswd = getpwuid (getuid ());
        !           839:     (void) gethostname (hostname, sizeof hostname);
        !           840:     printf ("%%%%Creator: %s:%s (%s)\n", hostname,
        !           841:            pswd->pw_name, pswd->pw_gecos);
        !           842:     printf ("%%%%Title: %s (%s)\n", infilename,name);
        !           843:     printf ("%%%%CreationDate: %s",
        !           844:                (time (&clock), ctime (&clock)));
        !           845:     printf ("%%%%EndComments\n");
        !           846: 
        !           847:     dump_prolog(flags);
        !           848: 
        !           849:     if (orientation==PORTRAIT) {
        !           850:        lm = (left > 0)? left : ((PAPER_WIDTH - scale * iw) / 2);
        !           851:        bm = (top > 0)? (PAPER_LENGTH - top - scale * ih)
        !           852:                : ((PAPER_LENGTH - scale * ih) / 2);
        !           853:        if (header || trailer) {
        !           854:            printf("gsave\n");
        !           855:            printf("/Times-Roman findfont 15 scalefont setfont\n");
        !           856:            /* origin at bottom left corner of image */
        !           857:            printf("%d %d translate\n",points(lm),points(bm));
        !           858:            if (header) {
        !           859:                char *label = escape(header);
        !           860:                printf("%d (%s) stringwidth pop sub 2 div %d moveto\n",
        !           861:                    points(iw*scale), label, points(ih*scale) + 10);
        !           862:                printf("(%s) show\n",label);
        !           863:            }
        !           864:            if (trailer) {
        !           865:                char *label = escape(trailer);
        !           866:                printf("%d (%s) stringwidth pop sub 2 div -20 moveto\n",
        !           867:                    points(iw*scale), label);
        !           868:                printf("(%s) show\n",label);
        !           869:            }
        !           870:            printf("grestore\n");
        !           871:        }
        !           872:        /* set resolution to device units (300/inch) */
        !           873:        printf("72 300 div dup scale\n");
        !           874:        /* move to lower left corner of image */
        !           875:        printf("%d %d translate\n",lm,bm);
        !           876:        /* dump the bitmap */
        !           877:        printf("%d %d %d bitdump\n",iw,ih,scale);
        !           878:     } else { /* orientation == LANDSCAPE */
        !           879:        /* calculate margins */
        !           880:        lm = (top > 0)? (PAPER_WIDTH - top - scale * ih)
        !           881:                : ((PAPER_WIDTH - scale * ih) / 2);
        !           882:        bm = (left > 0)? (PAPER_LENGTH - left - scale * iw)
        !           883:                : ((PAPER_LENGTH - scale * iw) / 2);
        !           884: 
        !           885:        if (header || trailer) {
        !           886:            printf("gsave\n");
        !           887:            printf("/Times-Roman findfont 15 scalefont setfont\n");
        !           888:            /* origin at top left corner of image */
        !           889:            printf("%d %d translate\n",points(lm),points(bm + scale * iw));
        !           890:            /* rotate to print the titles */
        !           891:            printf("-90 rotate\n");
        !           892:            if (header) {
        !           893:                char *label = escape(header);
        !           894:                printf("%d (%s) stringwidth pop sub 2 div %d moveto\n",
        !           895:                    points(iw*scale), label, points(ih*scale) + 10);
        !           896:                printf("(%s) show\n",label);
        !           897:            }
        !           898:            if (trailer) {
        !           899:                char *label = escape(trailer);
        !           900:                printf("%d (%s) stringwidth pop sub 2 div -20 moveto\n",
        !           901:                    points(iw*scale), label);
        !           902:                printf("(%s) show\n",label);
        !           903:            }
        !           904:            printf("grestore\n");
        !           905:        }
        !           906:        /* set resolution to device units (300/inch) */
        !           907:        printf("72 300 div dup scale\n");
        !           908:        /* move to lower left corner of image */
        !           909:        printf("%d %d translate\n",lm,bm);
        !           910:        /* dump the bitmap */
        !           911:        printf("%d %d %d bitdump\n",ih,iw,scale);
        !           912:     }
        !           913: }
        !           914: 
        !           915: char *ps_epilog[] = {
        !           916:        "",
        !           917:        "showpage",
        !           918:        "%%Trailer",
        !           919:        0
        !           920: };
        !           921: 
        !           922: ps_finish()
        !           923: {
        !           924:        char **p = ps_epilog;
        !           925: 
        !           926:        while (*p) printf("%s\n",*p++);
        !           927: }
        !           928: 
        !           929: ln03_alter_background(sixmap, iw, ih)
        !           930: unsigned char (*sixmap)[];
        !           931: int iw;
        !           932: int ih;
        !           933: {
        !           934:     register int size;
        !           935:     register unsigned char *c, *stopc;
        !           936:     register unsigned char *startc;
        !           937:     register int n;
        !           938: 
        !           939:     c = (unsigned char *)sixmap;
        !           940:     stopc = c + (iw * ih);
        !           941:     n = 0;
        !           942:     while (c < stopc) {
        !           943:        switch (*c) {
        !           944:        case 0x08: case 0x11: case 0x04: case 0x22:
        !           945:        case 0x20: case 0x21: case 0x24: case 0x00:
        !           946:            if (n == 0) startc = c;
        !           947:            n++;
        !           948:            break;
        !           949: 
        !           950:        default:
        !           951:            if (n >= 2) {
        !           952:                while (n-- > 0) *startc++ = 0x00;
        !           953:            } else {
        !           954:                n = 0;
        !           955:            }
        !           956:            break;
        !           957:        }
        !           958:        c++;
        !           959:     }
        !           960: }
        !           961: 
        !           962: ln03_output_sixels(sixmap, iw, ih, nosixopt, split, scale, top_margin, 
        !           963:                   left_margin)
        !           964: unsigned char (*sixmap)[];
        !           965: int iw;
        !           966: int ih;
        !           967: int nosixopt;
        !           968: int split;
        !           969: int top_margin;
        !           970: int left_margin;
        !           971: {
        !           972:     unsigned char *buf;
        !           973:     register unsigned char *bp;
        !           974:     int i;
        !           975:     int j;
        !           976:     register int k;
        !           977:     register unsigned char *c;
        !           978:     register int lastc;
        !           979:     register int count;
        !           980:     char snum[6];
        !           981:     register char *snp;
        !           982: 
        !           983:     bp = (unsigned char *)malloc(iw*ih+512);
        !           984:     buf = bp;
        !           985:     count = 0;
        !           986:     lastc = -1;
        !           987:     c = (unsigned char *)sixmap;
        !           988:     split = ih / split;                /* number of lines per page */
        !           989: 
        !           990:     iw--;                      /* optimization */
        !           991:     for (i = 0; i < ih; i++) {
        !           992:        for (j = 0; j <= iw; j++) {
        !           993:            if (!nosixopt) {
        !           994:                if (*c == lastc && j < iw) {
        !           995:                    count++;
        !           996:                    c++;
        !           997:                    continue;
        !           998:                }
        !           999:                if (count >= 3) {
        !          1000:                    bp--;
        !          1001:                    count++;
        !          1002:                    *bp++ = '!';
        !          1003:                    snp = snum;
        !          1004:                    while (count > 0) {
        !          1005:                        k = count / 10;
        !          1006:                        *snp++ = count - (k * 10) + '0';
        !          1007:                        count = k;
        !          1008:                    }
        !          1009:                    while (--snp >= snum) *bp++ = *snp;
        !          1010:                    *bp++ = (~lastc & 0x3F) + 0x3F;
        !          1011:                } else if (count > 0) {
        !          1012:                    lastc = (~lastc & 0x3F) + 0x3F;
        !          1013:                    do {
        !          1014:                        *bp++ = lastc;
        !          1015:                    } while (--count > 0);
        !          1016:                }
        !          1017:            }
        !          1018:            lastc = *c++;
        !          1019:            *bp++ = (~lastc & 0x3F) + 0x3F;
        !          1020:        }
        !          1021:        *bp++ = '-';            /* New line */
        !          1022:        lastc = -1;
        !          1023:        if ((i % split) == 0 && i != 0) {
        !          1024:            sprintf(bp, LN_ST); bp += sizeof LN_ST - 1;
        !          1025:            *bp++ = '\f';
        !          1026:            sprintf(bp, LN_VPA, top_margin + (i * 6 * scale)); bp += strlen(bp);
        !          1027:            sprintf(bp, LN_HPA, left_margin); bp += strlen(bp);
        !          1028:            sprintf(bp, LN_SIXEL_GRAPHICS, 9, 0, scale); bp += strlen(bp);
        !          1029:            sprintf(bp, "\"1;1"); bp += 4;
        !          1030:        }
        !          1031:     }
        !          1032: 
        !          1033:     sprintf(bp, LN_ST); bp += sizeof LN_ST - 1;
        !          1034:     *bp++ = '\f';
        !          1035:     write(1, buf, bp-buf);
        !          1036: }
        !          1037: 
        !          1038: la100_output_sixels(sixmap, iw, ih)
        !          1039: unsigned char (*sixmap)[];
        !          1040: int iw;
        !          1041: int ih;
        !          1042: {
        !          1043:     unsigned char *buf;
        !          1044:     register unsigned char *bp;
        !          1045:     int i;
        !          1046:     register int j, k;
        !          1047:     register unsigned char *c;
        !          1048:     register int lastc;
        !          1049:     register int count;
        !          1050:     char snum[6];
        !          1051: 
        !          1052:     bp = (unsigned char *)malloc(iw*ih+512);
        !          1053:     buf = bp;
        !          1054:     count = 0;
        !          1055:     lastc = -1;
        !          1056:     c = (unsigned char *)sixmap;
        !          1057: 
        !          1058:     for (i = 0; i < ih; i++) {
        !          1059:        for (j = 0; j < iw; j++) {
        !          1060:            if (*c == lastc && (j+1) < iw) {
        !          1061:                count++;
        !          1062:                c++;
        !          1063:                continue;
        !          1064:            }
        !          1065:            if (count >= 2) {
        !          1066:                bp -= 2;
        !          1067:                count = 2 * (count + 1);
        !          1068:                *bp++ = '!';
        !          1069:                k = 0;
        !          1070:                while (count > 0) {
        !          1071:                    snum[k++] = (count % 10) + '0';
        !          1072:                    count /= 10;
        !          1073:                }
        !          1074:                while (--k >= 0) *bp++ = snum[k];
        !          1075:                *bp++ = (~lastc & 0x3F) + 0x3F;
        !          1076:                count = 0;
        !          1077:            } else if (count > 0) {
        !          1078:                lastc = (~lastc & 0x3F) + 0x3F;
        !          1079:                do {
        !          1080:                    *bp++ = lastc;
        !          1081:                    *bp++ = lastc;
        !          1082:                } while (--count > 0);
        !          1083:            }
        !          1084:            lastc = (~*c & 0x3F) + 0x3F;
        !          1085:            *bp++ = lastc;
        !          1086:            *bp++ = lastc;
        !          1087:            lastc = *c++;
        !          1088:        }
        !          1089:        *bp++ = '-';            /* New line */
        !          1090:        lastc = -1;
        !          1091:     }
        !          1092: 
        !          1093:     sprintf(bp, LN_ST); bp += sizeof LN_ST - 1;
        !          1094:     *bp++ = '\f';
        !          1095:     write(1, buf, bp-buf);
        !          1096: }
        !          1097: 
        !          1098: #define LINELEN 72 /* number of CHARS (bytes*2) per line of bitmap output */
        !          1099: char *obuf; /* buffer to contain entire rotated bit map */
        !          1100: 
        !          1101: ps_output_bits(iw, ih, flags, orientation, win)
        !          1102: int iw;
        !          1103: int ih;
        !          1104: int flags;
        !          1105: XWDFileHeader *win;
        !          1106: enum orientation orientation;
        !          1107: {
        !          1108:     int iwb = win->bytes_per_line;
        !          1109:     register int i;
        !          1110:     int n,bytes;
        !          1111:     unsigned char *buffer;
        !          1112:     register int ocount=0;
        !          1113:     extern char hex1[],hex2[];
        !          1114:     static char hex[] = "0123456789abcdef";
        !          1115: 
        !          1116:     buffer = (unsigned char *)malloc((unsigned)(iwb + 3));
        !          1117:     if (orientation == LANDSCAPE) {
        !          1118:        /* read in and rotate the entire image */
        !          1119:        /* The Postscript language has a rotate operator, but using it
        !          1120:         * seem to make printing (at least on the Apple Laserwriter
        !          1121:         * take about 10 times as long (40 minutes for a 1024x864 full-screen
        !          1122:         * dump)!  Therefore, we rotate the image here.
        !          1123:         */
        !          1124:        int ocol = ih;
        !          1125:        int owidth = (ih+31)/32; /* width of rotated image, in bytes */
        !          1126:        int oheight = (iw+31)/32; /* height of rotated image, in scanlines */
        !          1127:        register char *p, *q;
        !          1128:        owidth *= 4;
        !          1129:        oheight *= 32;
        !          1130: 
        !          1131:        /* Allocate buffer for the entire rotated image (output).
        !          1132:         * Owidth and Oheight are rounded up to a multiple of 32 bits,
        !          1133:         * to avoid special cases at the boundaries
        !          1134:         */
        !          1135:        obuf = (char *)malloc((unsigned)(owidth*oheight));
        !          1136:        if (obuf==0) {
        !          1137:            fprintf(stderr,"xpr: cannot allocate %d bytes\n",owidth*oheight);
        !          1138:            exit(1);
        !          1139:        }
        !          1140:        bzero(obuf,owidth*oheight);
        !          1141: 
        !          1142:        for (i=0;i<ih;i++) {
        !          1143:            n = read(0,(char *)buffer,iwb);
        !          1144:            if (n<0) {
        !          1145:                perror("read");
        !          1146:                exit(1);
        !          1147:            }
        !          1148:            if (n==0) {
        !          1149:                fprintf(stderr,"xpr: premature end of file\n");
        !          1150:                exit(1);
        !          1151:            }
        !          1152:            if (win->bitmap_bit_order == MSBFirst)
        !          1153:                _swapbits((char *)buffer, iwb);
        !          1154:            ps_bitrot(buffer,iw,--ocol,owidth);
        !          1155:        }
        !          1156:        q = &obuf[iw*owidth];
        !          1157:        bytes = (ih+7)/8;
        !          1158:        for (p=obuf;p<q;p+=owidth)
        !          1159:            ocount = ps_putbuf((unsigned char *)p,bytes,ocount,flags&F_COMPACT);
        !          1160:     }
        !          1161:     else {
        !          1162:        for (i=0;i<ih;i++) {
        !          1163:            n = read(0,(char *)buffer,iwb);
        !          1164:            if (n<0) {
        !          1165:                perror("read");
        !          1166:                exit(1);
        !          1167:            }
        !          1168:            if (n==0) {
        !          1169:                fprintf(stderr,"xpr: premature end of file\n");
        !          1170:                exit(1);
        !          1171:            }
        !          1172:            if (win->bitmap_bit_order == MSBFirst)
        !          1173:                _swapbits((char *)buffer, iwb);
        !          1174:            ocount = ps_putbuf(buffer,iwb,ocount,flags&F_COMPACT);
        !          1175:        }
        !          1176:     }
        !          1177:     if (flags & F_COMPACT) {
        !          1178:        if (ocount) {
        !          1179:            /* pad to an integral number of lines */
        !          1180:            while (ocount++ < LINELEN)
        !          1181:                /* for debugging, pad with a "random" value */
        !          1182:                putchar(hex[ocount&15]);
        !          1183:            putchar('\n');
        !          1184:        }
        !          1185:     }
        !          1186: }
        !          1187: 
        !          1188: /* Dump some bytes in hex, with bits in each byte reversed
        !          1189:  * Ocount is number of chacters that have been written to the current
        !          1190:  * output line.  It's new value is returned as the result of the function.
        !          1191:  * Ocount is ignored (and the return value is meaningless) if compact==0.
        !          1192:  */
        !          1193: int
        !          1194: ps_putbuf(s, n, ocount, compact)
        !          1195: register unsigned char *s;     /* buffer to dump */
        !          1196: register int n;                        /* number of BITS to dump */
        !          1197: register int ocount;           /* position on output line for next char */
        !          1198: int compact;                   /* if non-zero, do compaction (see below) */
        !          1199: {
        !          1200:     register int ffcount = 0;
        !          1201:     extern char hex1[],hex2[];
        !          1202:     static char hex[] = "0123456789abcdef";
        !          1203: #define PUT(c) { putchar(c); if (++ocount>=LINELEN) \
        !          1204:        { putchar('\n'); ocount=0; }}
        !          1205: 
        !          1206:     if (compact) {
        !          1207:        /* The following loop puts out the bits of the image in hex,
        !          1208:         * compressing runs of white space (represented by one bits)
        !          1209:         * according the the following simple algorithm:  A run of n
        !          1210:         * 'ff' bytes (i.e., bytes with value 255--all ones), where
        !          1211:         * 1<=n<=255, is represented by a single 'ff' byte followed by a
        !          1212:         * byte containing n.
        !          1213:         * On a typical dump of a full screen pretty much covered by
        !          1214:         * black-on-white text windows, this compression decreased the
        !          1215:         * size of the file from 223 Kbytes to 63 Kbytes.
        !          1216:         * Of course, another factor of two could be saved by sending
        !          1217:         * the bytes 'as is' rather than in hex, using some sort of
        !          1218:         * escape convention to avoid problems with control characters.
        !          1219:         * Another popular encoding is to pack three bytes into 4 'sixels'
        !          1220:         * as in the LN03, etc, but I'm too lazy to write the necessary
        !          1221:         * PostScript code to unpack fancier representations.
        !          1222:         */
        !          1223:        while (n--) {
        !          1224:            if (*s == 0xff) {
        !          1225:                if (++ffcount == 255) {
        !          1226:                    PUT('f'); PUT('f');
        !          1227:                    PUT('f'); PUT('f');
        !          1228:                    ffcount = 0;
        !          1229:                }
        !          1230:            }
        !          1231:            else {
        !          1232:                if (ffcount) {
        !          1233:                    PUT('f'); PUT('f');
        !          1234:                    PUT(hex[ffcount >> 4]);
        !          1235:                    PUT(hex[ffcount & 0xf]);
        !          1236:                    ffcount = 0;
        !          1237:                }
        !          1238:                PUT(hex1[*s]);
        !          1239:                PUT(hex2[*s]);
        !          1240:            }
        !          1241:            s++;
        !          1242:        }
        !          1243:        if (ffcount) {
        !          1244:            PUT('f'); PUT('f');
        !          1245:                PUT(hex[ffcount >> 4]);
        !          1246:            PUT(hex[ffcount & 0xf]);
        !          1247:            ffcount = 0;
        !          1248:        }
        !          1249:     }
        !          1250:     else { /* no compaction: just dump the image in hex (bits reversed) */
        !          1251:        while (n--) {
        !          1252:            putchar(hex1[*s]);
        !          1253:            putchar(hex2[*s++]);
        !          1254:        }
        !          1255:        putchar('\n');
        !          1256:     }
        !          1257:     return ocount;
        !          1258: }
        !          1259: 
        !          1260: ps_bitrot(s,n,col,owidth)
        !          1261: unsigned char *s;
        !          1262: register int n;
        !          1263: int col;
        !          1264: register int owidth;
        !          1265: /* s points to a chunk of memory and n is its width in bits.
        !          1266:  * The algorithm is, roughly,
        !          1267:  *    for (i=0;i<n;i++) {
        !          1268:  *        OR the ith bit of s into the ith row of the
        !          1269:  *        (col)th column of obuf
        !          1270:  *    }
        !          1271:  * Assume VAX bit and byte ordering for s:
        !          1272:  *     The ith bit of s is s[j]&(1<<k) where i=8*j+k.
        !          1273:  *     It can also be retrieved as t[j]&(1<<k), where t=(int*)s and i=32*j+k.
        !          1274:  * Also assume VAX bit and byte ordering for each row of obuf.
        !          1275:  * Ps_putbuf() takes care of converting to Motorola 68000 byte and bit
        !          1276:  * ordering.  The following code is very carefully tuned to yield a very
        !          1277:  * tight loop on the VAX, since it easily dominates the entire running
        !          1278:  * time of this program.  In particular, iwordp is declared last, since
        !          1279:  * there aren't enough registers, and iwordp is referenced only once
        !          1280:  * every 32 times through the loop.
        !          1281:  */
        !          1282: {
        !          1283:     register int mask = 1<<(col%32);
        !          1284:     register int iword; /* current input word (*iwordp) */
        !          1285:     register int b = 0; /* number of bits in iword left to examine */
        !          1286:     register char *opos = obuf + (col/32)*4;
        !          1287:        /* pointer to word of obuf to receive next output bit */
        !          1288:     register int *iwordp = (int *) s; /* pointer to next word of s */
        !          1289: 
        !          1290:     while (--n>=0) {
        !          1291:        if (--b < 0) {
        !          1292:            iword = *iwordp++;
        !          1293:            b = 31;
        !          1294:        }
        !          1295:        if (iword & 1) {
        !          1296:            *(int *)opos |= mask;
        !          1297:        }
        !          1298:        opos += owidth;
        !          1299:        iword >>= 1;
        !          1300:     }
        !          1301: }
        !          1302: 
        !          1303: /* mapping tables to map a byte in to the hex representation of its
        !          1304:  * bit-reversal
        !          1305:  */
        !          1306: char hex1[]="084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
        !          1307: 084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
        !          1308: 084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f\
        !          1309: 084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f084c2a6e195d3b7f";
        !          1310: 
        !          1311: char hex2[]="000000000000000088888888888888884444444444444444cccccccccccccccc\
        !          1312: 2222222222222222aaaaaaaaaaaaaaaa6666666666666666eeeeeeeeeeeeeeee\
        !          1313: 111111111111111199999999999999995555555555555555dddddddddddddddd\
        !          1314: 3333333333333333bbbbbbbbbbbbbbbb7777777777777777ffffffffffffffff";
        !          1315: 

unix.superglobalmegacorp.com

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