braner@batcomputer.tn.cornell.edu (braner) (12/06/86)
/* * Compressed ST screen (monochrome) to Postscript filter. * * By Moshe Braner, 861116. * * Postscript stuff from: * Cwru standard bitmap image to PostScript filter, * by J. R. Bammi. * * WARNING: assumes ASCII. * * Usage: * * cbw2ps [-s xsize ysize] [-t transx transy] [-r rot] [-l] [-i] file * * -s xsize ysize = size of postscript image - default 8.533 x 5.333" * -1 = 1 dot per pixel - 2.133 x 1.333 inches * -2 = 2 dots per pixel - 4.267 x 2.667 * -3 = 3 dots per pixel - 6.4 x 4 * -4 = 4 dots per pixel - 8.533 x 5.333 (default) * -5 = 5 dots per pixel - 10.67 x 6.667 * -t transx transy = translate image - default 0.25 0.5 inches * -r rotate = rotate image - default 0 degrees * -l = landscape (== -r 90) - default portrait * -i = inverse image - default no inverse */ #include <stdio.h> #define OK 0 #define ERROR -1 FILE *fp, *fopen(); char scrn[32000]; /* virtual screen buffer */ char *scrnptr; /* target address for next decoded byte */ long chksum; /* chksum on input file */ int rows; int cols; int row; int col; int bferr = 0; main(argc,argv) int argc; char **argv; { int land, inv; char *filename; double sizex, sizey, transx, transy, rotate; extern double atof(); fp = stdin; land = 0; inv = 0; filename = "STDIN"; sizex = 8.533333; sizey = 5.333333; transx = 0.25; transy = 0.5; rotate = 0.0; while(--argc > 0) { ++argv; if((*argv)[0] == '-') { switch((*argv)[1]) { case 'l': case 'L': land = 1; break; case 's': case 'S': sizex = atof(*++argv); sizey = atof(*++argv); argc -= 2; break; case 't': case 'T': transx = atof(*++argv); transy = atof(*++argv); argc -= 2; break; case 'r': case 'R': rotate = atof(*++argv); argc--; break; case 'I': case 'i': inv = 1; break; case '1': sizex = 2.133333; sizey = 1.333333; break; case '2': sizex = 4.26667; sizey = 2.66667; break; case '3': sizex = 6.4; sizey = 4.0; break; case '4': sizex = 8.533333; sizey = 5.333333; break; case '5': sizex = 10.66667; sizey = 6.66667; break; default: fprintf(stderr, "Illegal switch \'%c\' - ignored\n", (*argv)[1]); } } else { if((fp = fopen(*argv, "r")) == (FILE *)NULL) { fprintf(stderr,"Cannot open %s\n",*argv); exit(1); } filename = *argv; } } process(land,inv,filename,sizex,sizey,transx,transy,rotate); } process(land, inv, filename, sizex, sizey, transx, transy, rotate) int land, inv; char *filename; double sizex, sizey, transx, transy, rotate; { int bpp, xmax, ymax, junk; register long i; long bytes, origsum; register unsigned int c, s, out, mask; register int j, bpb, shift, k; extern unsigned int decode3(); c = fgetb() - 0x10; chksum = ((long) c)&0x03; if (c != 2) { fprintf(stderr, "%s not a monochrome image!\n",filename); exit(1); } bpp = 1; ymax = 400; xmax = 640; /* Scan off color table */ c = decode3(); chksum += ((long) c)&0xFFFF; if ((c & 0x01) == 1) inv = (! inv); for(i = 0; i < 15; i++) chksum += ((long) decode3())&0xFFFF; /* decode the image itself */ rows = 400; cols = 80; row = 0; col = 0; scrnptr = scrn; while ((c=fgetb()) != ERROR) { if (c > 0x0F) s = reps(c); else s = uniq(c); if (s != OK) break; } /* read original checksum */ origsum = (((long) decode3())&0xFFFF) << 16; origsum += ((long) decode3())&0xFFFF; if (bferr) { fprintf(stderr,"Error while reading %s\n", filename); exit(3); } else if (chksum != origsum) { fprintf(stderr,"Checksum doesn't fit!\n"); exit(3); } fclose(fp); /* Put out header */ printf("%%!\n/inch {72 mul} def\n"); printf("/picstr 1 string def\n"); printf("/bpp %d def\n",bpp); printf("/scanlines %d def\n",ymax); printf("/scansize %d def\n", xmax); printf("/bitmapx\n{"); printf(" %d %d %d [%d 0 0 %d 0 %d]", xmax, ymax, bpp, xmax,-ymax,ymax); printf(" {currentfile picstr readhexstring pop} image\n} def\n"); printf("gsave\n"); printf("%f inch %f inch translate\n",transx, transy); printf("%f rotate\n", (land == 1)? 90.0+rotate : rotate ); printf("%f inch %f inch scale\n", sizex, sizey); printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f 0 inch", sizex); printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n", sizex, sizey, sizey); printf("\tclosepath } def\nclipathx clip\n"); printf("bitmapx\n"); /* put out bit map data */ scrnptr = scrn; k = 0; for (i=0; i<32000; i++) { out = *scrnptr++; printf ("%02x", (unsigned int)(((inv == 1)? ~out : out) & (unsigned int)0x00ff)); if (++k & 16) { putchar('\n'); k = 0; } else putchar(' '); } printf("grestore\n"); printf("showpage\n"); } /* * Read a byte from the input file, translate it. * Skip control chars and white space, etc. */ int fgetb() { register int c; again: if (bferr) return (ERROR); c = getc(fp); if (c == EOF) bferr = 1; if (c < ',' || c > 'z') goto again; if (c < 'a') return (c - ' '); if (c < 'm') return (c - 'a'); if (c < 'v') return (c - 0x55); return (c - 0x3B); } /* * Decode one (16-bit) word out of 3 bytes of the input file. */ unsigned int decode3() { register unsigned int c; register unsigned int dummy; /* avoid a Megamax bug */ c = (fgetb() << 12); c |= (fgetb() << 6); c |= fgetb(); return (c); } /* * Put a decoded byte into the screen buffer. */ int putbyte(b) int b; { *scrnptr = (char) b; scrnptr += cols; if (++row >= rows) { if (++col >= cols) { return (ERROR); } scrnptr = scrn + col; row = 0; } return (OK); } /* * Handle a pair of decoded screen bytes. */ int putword(w) register unsigned int w; { register unsigned int dummy; /* avoid a Megamax bug */ chksum += ((long) w)&0xFFFF; if (putbyte((w>>8) & 0xFF) == ERROR) return (ERROR); return (putbyte(w & 0xFF)); } /* * Decode 2 screen bytes. */ int uniq(c) register unsigned int c; { register unsigned int dummy; /* avoid a Megamax bug */ c <<= 12; c |= (fgetb() << 6); c |= fgetb(); if (bferr) return (ERROR); return (putword(c)); } /* * Decode a 4-byte repetition code. */ int reps(b) register unsigned int b; { register unsigned int c; b = ((b-0x10) << 2); c = fgetb(); b |= (c >> 4); c <<= 12; c |= (fgetb() << 6); c |= fgetb(); if (bferr) return (ERROR); while (b--) { if (putword(c) == ERROR) return (ERROR); } return (OK); }