mark@umcp-cs.UUCP (09/23/83)
: Run this shell script with "sh" not "csh" PATH=:/bin:/usr/bin:/usr/ucb export PATH all=FALSE if [ $1x = -ax ]; then all=TRUE fi /bin/echo 'Extracting rasterblast.6' sed 's/^X//' <<'//go.sysin dd *' >rasterblast.6 X.TH RASTERBLAST 6L local X.UC 4 X.SH NAME Rasterblast \- Raster graphics for Tektronix 4025 Terminal X.SH SYNOPSIS rasterblast [options] [file1 file2 . . .] X.SH DESCRIPTION X.LP The input files contain graphics information in raster format. The input file is interpreted bit-serial; the high order bit of the first byte is the first bit of the first line of the image, the next bit is the second bit of the first line, and so forth. The program assumes that each line of the image is 80 bytes (640 bits) wide, as this is the width of the Tektronix screen, but this width may be overriden. Output is automagically piped through teksync (see man 6 teksync). X.SH OPTIONS X.IP '-f' Each image gets the full workspace, which is 80 * 8 bits wide and 53 * 14 bits high. The terminal does not have enough graphics capacity to display densly packed graphics on the entire workspace, but most images actually encountered will work nicely. This is the default. X.IP '-h' Each image gets half the workspace, which is 80 * 8 bits wide and 26 * 14 bits high. This is about one screen of data. X.IP '-q' Each image gets one quarter of the workspace, which is 80 * 8 bits wide and 13 * 14 bits high. This is enough for most rastermorph output. X.IP '-e' Each image gets one eighth of the workspace, which is 40 * 8 bits wide and 13 * 14 bits high. This is often enough for rastermorph output. X.IP '-w <n>' Changes the width of input lines to <n>. If n is greater than 80, the image will be truncated. X.IP '-c' Hardcopy. This only works on the Tektronix terminal in the VAX room. REMEMBER: If you are not in the AI group, check with someone who is first, and always log your copies. Always let the hardcopy unit warm up for 5 minutes before using it, and assume the first hardcopy will be bad. X.SH INPUT FILES X.LP If no input files are specified, input for a single image will come from stdin. If input files are specified, they will be blasted onto the tektronix in sequence. If the half, quarter, or eighth screen options (above) are specified, images will be put in successive portions of the screen. If the number of input files is greater than the number of divisions of the workspace, as many as will fit are put in successive workspaces. X.LP If hard copy is specified, a copy will be made of successive workspaces. Thus, if you specified half screen images, hard copy, and three input files, the first two images would go into the workspace, then a hard copy would be made, then the workspace would be cleared; finally the last image would be placed in the workspace and copied. X.SH SEE ALSO X.DL rastermorph troff vcat teksync X.SH DIAGNOSTICS If the file ends with an incomplete line, it is truncated, and an error message is printed. X.SH BUGS If the image is too wide or too tall, the output is silently truncated. X.SH AUTHOR Craig Stanfill University of Maryland X.SH SOURCE FILES Reside in /usr/cam/tektronix/rasterblast //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 rasterblast.6 /bin/echo -n ' '; /bin/ls -ld rasterblast.6 fi /bin/echo 'Extracting rasterblast.c' sed 's/^X//' <<'//go.sysin dd *' >rasterblast.c #include <stdio.h> #define DEFAULTLEN 80 #define LINE 1 #define SPACE 2 #define BIT(bytes, x) (01 & (bytes[(x) / 8]) >> (7 - ((x) % 8))) #define FULL 1 #define HALF 2 #define QUARTER 4 #define EIGHTH 8 #define TRUE 1 #define FALSE 0 FILE *popen(); main(argc, argv) int argc; char **argv; { FILE *output; int count; int size = FULL; int argn = 1; int hardcopy = FALSE; int len = DEFAULTLEN; while ((argn < argc) && (argv[argn][0] == '-')) { if (strcmp("-f", argv[argn]) == 0) size = FULL; else if (strcmp("-h", argv[argn]) == 0) size = HALF; else if (strcmp("-q", argv[argn]) == 0) size = QUARTER; else if (strcmp("-e", argv[argn]) == 0) size = EIGHTH; else if (strcmp("-c", argv[argn]) == 0) hardcopy = TRUE; else if (strcmp("-w", argv[argn]) == 0) { if(1 != sscanf(argv[argn+1], "%d", &len)) { fprintf(stderr, "usage: rasterblast -w <number>\n" ); exit(1); } argn++; } else { fprintf(stderr, "usage: rasterblast"); fprintf(stderr, "[-f][-h][-q][-e] files ...\n"); exit(1); } argn++; } output = popen("/usr/local/teksync", "w"); if(argv[argn][0] == '\000') blast_raster("", 0, size, hardcopy, len, output); for(count = 0; argv[count+argn][0] != '\000'; count++) blast_raster(argv[count+argn], count, size, hardcopy, len, output ); if(hardcopy && ((count % size) != 0)) make_copy(output); pclose(output); } blast_raster(infile, count, size, hardcopy, len, output) FILE *output; char *infile; int count, size, hardcopy; int len; { int x,y; int lastx; int mode; int byte[4000]; FILE *input; graphic(size, count, output); if(infile[0] == '\000') input = stdin; else { if(NULL == (input = fopen(infile, "r"))) { fprintf(stderr, "could not open %s\n", infile); exit(1); } } for (y = 0; !feof(input); y++) { for(x = 0; x < len; x++) byte[x] = 0; for (x = 0; x < len; x++) { byte[x] = getc(input); if ((x != len - 1) && (feof(input))) { fprintf(output, "\033mon\n"); fprintf(output, "Last line too short; truncated\n"); byte[x] = 0; break; } } lastx = 0; mode = SPACE; for (x = 0; x < len * 8; x++) { if ((mode == LINE) && ! BIT(byte, x)) { mode = SPACE; vector(lastx, y, x-1, y, size, output); } else if ((mode == SPACE) && BIT(byte, x)) { mode = LINE; lastx = x; } } if (mode == LINE) vector(lastx, y, len * 8 - 1, y, size, output); } if(hardcopy && ((count % size) == size-1)) make_copy(output); } graphic(size, count, output) int size; int count; FILE *output; { int row, col, height, width; if((count % size) == 0) fprintf(output, "\033wor 30\n"); switch (size) { case HALF: row = (count % 2) * 26 + 1; col = 1; height = 26; width = 80; break; case QUARTER: row = (count % 4) * 13 + 1; col = 1; height = 13; width = 80; break; case EIGHTH: row = ((count / 2) % 4) * 13 + 1; col = (count % 2) * 40 + 1; height = 13; width = 40; break; case FULL: default: row = 1, col = 1; height = 53; width = 80; break; } fprintf(output, "\033gra %d %d %d %d\n", row, row + height - 1, col, col + width - 1 ); fprintf(output, "\033wor\n\033jum %d %d\n\033mon\n", row, col); } vector(x1, y1, x2, y2, size, output) int x1, y1, x2, y2; int size; FILE *output; { int max; switch (size) { case FULL: case HALF: case QUARTER: max = (53 * 14) / size - 8; break; case EIGHTH: max = (53 * 14) / 4 - 8; } fprintf(output, "\033vec %d %d %d %d\n", x1+1, max-y1, x2+1, max-y2); } make_copy(output) FILE *output; { fprintf(output, "\033wor\033jum\n\033hco w\n\033mon\n"); } //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 rasterblast.c /bin/echo -n ' '; /bin/ls -ld rasterblast.c fi /bin/echo 'Extracting rastermorph.6' sed 's/^X//' <<'//go.sysin dd *' >rastermorph.6 X.TH RASTERMORPH 6L X.SH NAME rastermorph \- draw a raster picture on a tek 4025, printer, etc. X.SH SYNOPSIS X.B rastermorph [ options ] <inputraster >outputraster X.SH DESCRIPTION X.I Rastermorph is a program to transform a raster for output on various devices. The raster must be represented by a stream of bytes, with a fixed number of bytes representing each horizontal raster line. The stream is interpreted bit-serial; the high order bit of the first byte is the first bit of the first line of the image, the next bit is the second bit of the first line, and so forth. The three output devices currently supported are the tektronix 4025, the printronix printer in plot mode, and an arbitrary ordinary device. The default settings are correct for sending vcat'ed output from troff to the tektronix or printronix. X.PP Because output from X.I rastermorph with the X.BI \-D tek option is a bit serial byte stream, X.I rastermorph output with the X.BI \-D tek option can be used as new rastermorph input. For example, if file X.I temp was created with the command: X.br X.ti +5 rastermorph -o80 -Dtek < input > temp X.br then the following command causes X.I temp2 to be identical to X.I temp : X.br X.ti +5 rastermorph -i80 -b -v -Dtek < temp > temp2 X.br Other examples are below. X.PP X.SH OPTIONS X.TP X.BI \-D device X.I device is one of 'term', 'tek', or 'print', specifying output in a form suitable for a terminal, a tektronix 4025, or the printronix in plot mode, respectively. Output for a terminal represents 'on' bits with asterisks, 'off' bits with blanks. Output for the tektronix is in the input format expected by X.I rasterblast . X.TP X.BI \-v Turn off skipping of the vcat header. Use this option for non-vcat input. If X.I \-v is not specified, then the following action is taken: the first three bytes in the file are skipped, followed by any characters up to the first zero byte. The character fudge (see the X.I -f option, below) is then applied to the remainder of the input file. X.TP X.BI \-b Turn off skipping of initial input lines of all zero bytes. This skipping is normally applied after the vcat header and character fudge options. X.TP X.BI \-r Give no raster output: only report the number of raster lines in the image. This will include initial empty lines if the X.I -b option is also specified. It never includes trailing empty lines. This option allows an intelligent choice for the X.I \-l argument (see below), which can significantly speed up processing and reduce file space. X.TP X.BI \-f num X.I num is the number of extra characters to fudge from the front of the file. X.B Rastermorph assumes that the input is divided into fixed length records of length specified by the -i option. The -f option is good for shifting a picture left or right. The default is 25. X.TP X.BI \-i num X.I num is the number of characters in each input record. X.I Num times 8 is the horizontal bit resolution of the input raster. The default is 264. X.TP X.BI \-o num X.I num is the number of characters in each output record. X.I Num times 8 is the horizontal bit resolution of the output raster. The default is 80. X.TP X.BI \-l num X.I num is the maximum number of lines in the output. The default is a very large number. Empty lines at the beginning of a picture are automatically skipped (but see the X.I \-b option, above). Use the X.I \-l option to skip trailing empty lines. The X.I -r option is useful for setting X.IR -l . X.SH EXAMPLES X.br X.nf X.na troff -t | /usr/lib/vcat -t | rastermorph -Dtek | rasterblast X.fi X.ad X.sp troff -t | /usr/lib/vcat -t | rastermorph -Dtek >temp rastermorph -r < tekdemo | awk '{print $$3}' > numlines rastermorph -b -v -Dtek -l`cat demolines` < temp > tekdemo rm temp X.sp troff -t | /usr/lib/vcat -t | rastermorph -Dprint | lpr X.SH SEE\ ALSO rasterblast X.br unexpand - to speed up output when outputing to a terminal. X.SH AUTHOR Mark Weiser X.SH BUGS The X.I -f option is intended to be used as a picture shift, but actually is a picture rotate. //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 rastermorph.6 /bin/echo -n ' '; /bin/ls -ld rastermorph.6 fi /bin/echo 'Extracting rastermorph.c' sed 's/^X//' <<'//go.sysin dd *' >rastermorph.c #include <stdio.h> #define TEK 1 #define TERM 2 #define PRINT 3 int outdev=0, num_col_in=264, column_fudge=25, num_col_out=79, max_lines=2000000000, report = 0, blankskip=1, vcat = 1; char *rast; xmain() { printprint(0x1d); printprint(0x50); printprint(0xff); printprint(0xaa); printprint(0); } main(argc,argv) char **argv; { register char c; int foundchar,i,j,k,colmax,rowmax; char *calloc(); for (i=1; i<argc; i++) { if (argv[i][0] == '-') { /* options: i,o,f,l,v,b -b - turns off initial blank line skip. -v - turns off skip of vcat header. -inum - num = number of chars per input line. -onum - num = number of chars per output line. -lnum - num = maximum number of output lines. -fnum - num = number of extra chars to fudge from the front of the file. (This is applied after the first zero char is found.) */ switch(argv[i][1]) { case 'i': { num_col_in = atol(&argv[i][2]); break; } case 'f': { column_fudge = atol(&argv[i][2]); break; } case 'o': { num_col_out = atol(&argv[i][2]) - 1; break; } case 'l': { max_lines = atol(&argv[i][2]); break; } case 'v': { vcat = 0; break; } case 'b': { blankskip = 0; break; } case 'r': { report = 1; break; } case 'D': { if (! strcmp(&argv[i][2],"term")) outdev = TERM; else if (! strcmp(&argv[i][2],"tek")) outdev = TEK; else if (! strcmp(&argv[i][2],"print")) outdev = PRINT; else { fprintf(stderr,"Output device '%s' not recognized.\n",argv[i]); fprintf(stderr,"Please use one of 'tek', 'term', or 'print'.\n"); exit(1); } break; } default: { fprintf(stderr,"Parameter '%s' was ignored.\n",argv[i]); break; } } } else { fprintf(stderr,"Parameter '%s' was ignored.\n",argv[i]); } } if (! outdev) { fprintf(stderr,"Output device not specified: '-Dterm' assumed.\n"); outdev = TERM; } #ifdef DEBUG fprintf(stderr,"outdev %d, num_col_in %d, column_fudge %d, num_col_out %d, max_lines %d.\n",outdev,num_col_in,column_fudge,num_col_out,max_lines); #endif rast=(char *)calloc(num_col_in,sizeof(char)); colmax = 0; if (vcat) { /* Special processing for the vcat header: skip a few chars */ getchar(); getchar(); getchar(); /* look for the end of the nl's */ while ((c=getchar()) != 0) ; ungetc(c,stdin); } for(j=0; j<column_fudge; j++) getchar(); foundchar = 0; if (! blankskip) foundchar = 1; rowmax = -1; for (j=0; j<max_lines; j = foundchar ? j+1 : 0) { colmax = -1; for (i=0; i<num_col_in; i++) { if ((c = getchar()) == EOF) goto done; rast[i] = c; if (c != 0) { if (i > colmax) colmax = i; if (i <= num_col_out) rowmax = j; foundchar = 1; } } if (!report && foundchar) { rasterout(rast,colmax); } } done: if (report) { printf("Picture was %d lines long.\n",rowmax+1); } } rasterout(rast,colmax) char *rast; { int i,k; for (i=0; i<=colmax; i++) { switch(outdev) { case PRINT: { printprint(rast[i]); break; } case TEK: { printf("%c",rast[i]); break; } case TERM: { starprint(rast[i]); break; } } } switch(outdev) { case PRINT: { put_pixel(-1); break; } case TEK: { for (k=colmax+1; k<80; k++) printf("%c",0); break; } case TERM: { printf("\n"); break; } } } printprint(c) char c; { int i; for (i=7; i>=0; i--) { put_pixel((c >> i) & 1); } } int byte=64,count=0; put_pixel(pixel) register int pixel; { if(pixel<0) { if(count)putc(byte,stdout); byte=64; count=0; putc(5,stdout); putc('\n',stdout); return; } byte|=pixel<<(count++); if(count>5) { putc(byte,stdout); byte=64; count=0; } } starprint(c) char c; { int mask; mask = 0x80; for(mask=0x80; mask!=0; mask = mask >> 1) { if ((mask & c) == 0) {printf(" ");} else {printf("*");}; } } char ** malloc2d(first,last,elsize) { char **out,*calloc(); int i; out = (char **)calloc(first,sizeof(char *)); for(i=0; i<first; i++) out[i]=calloc(last,elsize); return(out); } //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 rastermorph.c /bin/echo -n ' '; /bin/ls -ld rastermorph.c fi /bin/echo 'Extracting teksync.6' sed 's/^X//' <<'//go.sysin dd *' >teksync.6 X.TH TEKSYNC 6L local X.UC 4 X.SH DESCRIPTION teksync - synchronize communication with tektronix 4025 terminals. X.SH SYNOPSIS teksync [file] X.SH EXPLANATION The tektronix terminals buffer their input. Under some circumstances, (such as when plotting massive amounts of data), the buffer overflows and the terminal crashes. Teksync prevents this. Input comes from the single argument (defaults to standard input). Output goes to standard output, which must be a terminal. When this is going on, echo is turned off. X.SH AUTHOR Craig Stanfill X.SH BUGS It is not possible to specify the terminal as (for instance) a second argument. I tried to make it work, but it wouldn't. X.SH SEE ALSO tektronix(6), plot(1G) X.SH FILES X/usr/local/lib/teksync.run //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 teksync.6 /bin/echo -n ' '; /bin/ls -ld teksync.6 fi /bin/echo 'Extracting teksync.c' sed 's/^X//' <<'//go.sysin dd *' >teksync.c #include <stdio.h> #define COMMAND_CHAR '\033' #define SYNCFREQUENCY 2000 main(argc, argv) int argc; char *argv[]; { FILE *out,*in,*sync; char c; int charcount; int in_command, in_vec, in_int, intcount; int old1, old2; if (argc == 1) { in = stdin; out= stdout; /* if(!isatty(1)) { printf("teksync must be last element of pipe\n"); exit(1); } */ sync = fopen("/dev/tty", "r"); } else if (argc == 2) { if(NULL == (in = fopen(argv[1], "r"))) { printf("could not open %s\n", argv[1]); exit(1); } out = stdout; if(!isatty(1)) { printf("teksync must be last element of pipe\n"); exit(1); } sync = fopen(ttyname(1), "r"); } else { printf("usage tekwrite [file]\n"); exit(1); } charcount = 0; in_command= 0; while (EOF != (c = getc(in))) { charcount++; if (charcount > SYNCFREQUENCY) { if (!in_command) { fprintf(out, "%crep 00\n", COMMAND_CHAR); while (';' != getc(sync)); charcount = 0; } /* else if (in_vec && ! in_int && (intcount % 2 == 0)) { fprintf(out, "%crep 00\n", COMMAND_CHAR); while (';' != getc(sync)); charcount = 0; fprintf(out, "%cvec %d %d ", COMMAND_CHAR, old2, old1 ); } */ } putc(c, out); switch (c) { case COMMAND_CHAR : in_command = 1;break; case 'V': case 'v': if (in_command == 1) in_command++; else in_command = 5; break; case 'E': case 'e': if (in_command == 2) in_command++; else in_command = 5; break; case 'C': case 'c': if (in_command == 3) { in_vec = 1; in_int = 0; intcount = 0; } else in_command = 5; break; case '\n': case ';': case '\015': in_command = 0; in_vec = 0; break; default: if ( ! in_vec) break; if (('0' <= c) && (c <= '9')) { if ( ! in_int) { in_int = 1; old2 = old1; old1 = 0; } old1 = old1 * 10 + (c - '0'); } else { if (in_int) { in_int = 0; intcount++; } } } } } //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 teksync.c /bin/echo -n ' '; /bin/ls -ld teksync.c fi -- spoken: mark weiser UUCP: {seismo,allegra,brl-bmd}!umcp-cs!mark CSNet: mark@umcp-cs ARPA: mark.umcp-cs@UDel-Relay