|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.