|
|
1.1 ! root 1: /* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved. */ ! 2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T. */ ! 3: /* The copyright notice does not imply actual or intended publication. */ ! 4: /* AUTHORS: */ ! 5: /* T. Thompson - ATT-BL HO - first versions */ ! 6: /* Routines for generating PostScript from RLE. */ ! 7: /* The routines at the bottom of this file, which */ ! 8: /* do the actual conversion to postscript, were */ ! 9: /* hacked out of 'sun2ps'. The original header */ ! 10: /* giving credit to its authors is there. */ ! 11: ! 12: /* The 'binary' version of the output is collected in a */ ! 13: /* temporary file, which is then fed back to the routines */ ! 14: /* that generate postscript in a run-length-encoded form. */ ! 15: /* Ideally it should just convert the original run-length */ ! 16: /* encoding directly, but the REAL bottleneck is the */ ! 17: /* PostScript printer, of course. Printing an 800 by 800 */ ! 18: /* pixel image takes 5 minutes. */ ! 19: ! 20: #include <stdio.h> ! 21: #include <math.h> ! 22: #include <string.h> ! 23: #include "CPU.h" ! 24: #include "boole.h" ! 25: #include "limits.h" /* numeric extreme values */ ! 26: #include "Units.h" ! 27: #include "Coord.h" ! 28: #include "pic.h" ! 29: ! 30: FILE *Fp, *tmpfile(); ! 31: int Raswidth; ! 32: int Raslength; ! 33: int Rasbytes; /* bytes per row */ ! 34: int Inv = 0; ! 35: int Aspect = 1; /* if non-zero, retain original aspect ratio */ ! 36: int Land = 0; /* if non-zero, print in landscape mode */ ! 37: char Revbyte[256]; ! 38: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ ! 39: char Revnib[16] = { ! 40: 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 ! 41: }; ! 42: ! 43: void ! 44: POST_start(h) ! 45: PIC_hdr *h; ! 46: { ! 47: int n, v; ! 48: ! 49: /* build a table of reversed bytes */ ! 50: for ( n=0; n<256; n++ ) ! 51: Revbyte[n] = Revnib[(n>>4)&0xf] | Revnib[n&0xf]<<4; ! 52: ! 53: h->bpl = (h->bpl+7)/8; ! 54: Rasbytes = h->bpl; ! 55: Raslength = h->bpl * h->bx.b.y; ! 56: Raswidth = h->bx.b.x; ! 57: postmain(1,NULL,Raswidth,h->bx.b.y); ! 58: #if CPU==SUN ! 59: Fp = tmpfile(); ! 60: #else ! 61: Fp = fopen("tmp.postlib.0","rw"); ! 62: #endif ! 63: } ! 64: ! 65: void ! 66: POST_end() ! 67: { ! 68: int c; ! 69: rewind(Fp); ! 70: (VOID) Encode(Raslength, Inv); ! 71: PrintPostScriptClosing(); ! 72: fclose(Fp); ! 73: } ! 74: ! 75: /* write a full line of picture data, returning status: 1 OK, 0 EOF, -1 ERR */ ! 76: int POST_wline(h,line) ! 77: PIC_hdr *h; ! 78: unsigned char *line; ! 79: { int stat; ! 80: if( (stat=fwrite(line,1,h->bpl,Fp)) == h->bpl) { ! 81: h->seek += h->bpl; ! 82: h->cy++; ! 83: return(1); ! 84: } ! 85: else { /* ERR */ ! 86: err("write to fd%d stat%d",fileno(h->fp),stat); ! 87: if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/); ! 88: else return(-1); ! 89: }; ! 90: } ! 91: ! 92: /****************************************************************************** ! 93: * * ! 94: * File: sun2ps.c * ! 95: * Author: Glenn Boysko * ! 96: * Organization: Case Western Reserve University * ! 97: * EMail: {decvax, sun}!mandrill!boysko * ! 98: * [email protected] * ! 99: * Created: Wed Mar 23 9:25pm * ! 100: * Contents: Sun Rasterfile to PostScript image (using a run-length * ! 101: * encoding scheme.) * ! 102: * * ! 103: * (Adapted from "postimage" filter by J. R. Bammi.) * ! 104: * * ! 105: * @(#)sun2ps.c 1.8 ! 106: ******************************************************************************/ ! 107: ! 108: /* ! 109: * Usage: ! 110: * sun2ps [-s sizex sizey] [-t transx transy] [-r rot] [-l] [-i] [-a] file ... ! 111: * ! 112: * -s sizex sizey = size of postscript image - default 7.5 x 10 inches. ! 113: * -t transx transy = translate image - default 0.5 0.5 inches ! 114: * -r rotate = rotate image - default 0 degress ! 115: * -l = landscape (overrides *all* settings.) ! 116: * -i = inverse image - default no inverse ! 117: * (Inverse enabled implies white on black.) ! 118: * -a = maintain correct aspect ratio - default none. ! 119: * ! 120: */ ! 121: ! 122: /* Sun standard raster file format (as obtained by screendump(1)). ! 123: * ! 124: * Header (8 16-bit quantities) ! 125: * Color Map ! 126: * Image ! 127: * ! 128: */ ! 129: ! 130: /* Header Format: ! 131: * ! 132: * ras_magic (int) Raster Magic number 0x59a66a95 ! 133: * ras_width (int) Width of image in pixels. ! 134: * ras_height (int) Height of image in pixels. ! 135: * ras_depth (int) Bits per pixel. Either 1 or 8 bits. ! 136: * ras_length (int) Length of image in bytes. ! 137: * ras_type (int) Type of file. Assumed to be RT_STANDARD (1) if ! 138: * produced by a screendump command. ! 139: * ras_maptype (int) Type of color map. ! 140: * ras_maplength (int) Length of color map in bytes. ! 141: * ! 142: */ ! 143: ! 144: /* Ras_maplength bytes of Color map data. */ ! 145: ! 146: /* Ras_length bytes of Image data. */ ! 147: ! 148: /* Buffer and Input Modes... */ ! 149: #define LITERAL 0 ! 150: #define COPY 1 ! 151: #define IGNORE 2 ! 152: ! 153: /* Transmission Variables. */ ! 154: int BufCount; ! 155: ! 156: unsigned char Buffer[128], ! 157: CurrByte, ! 158: NextByte, ! 159: *BufferP = Buffer; ! 160: ! 161: /* Diagnostic Variables. */ ! 162: int DiagNLongRuns = 0, ! 163: DiagMaxRunLength = 0, ! 164: DiagNumRuns = 0; ! 165: double DiagSumRunLength = 0; ! 166: ! 167: postmain(argc,argv,width,height) ! 168: int argc; ! 169: char **argv; ! 170: int width, height; ! 171: { ! 172: char *filename; ! 173: double sizex, sizey, transx, transy, rotate; ! 174: ! 175: extern double atof(); ! 176: ! 177: filename = "STDIN"; ! 178: sizex = 7.5; ! 179: sizey = 10.0; ! 180: transx = transy = 0.5; ! 181: rotate = 0.0; ! 182: ! 183: while(--argc > 0) ! 184: { ! 185: ++argv; ! 186: if((*argv)[0] == '-') ! 187: { ! 188: switch((*argv)[1]) ! 189: { ! 190: case 'l': ! 191: case 'L': ! 192: Land = 1; ! 193: break; ! 194: ! 195: case 's': ! 196: case 'S': ! 197: sizex = atof(*++argv); ! 198: sizey = atof(*++argv); ! 199: argc -= 2; ! 200: break; ! 201: ! 202: case 't': ! 203: case 'T': ! 204: transx = atof(*++argv); ! 205: transy = atof(*++argv); ! 206: argc -= 2; ! 207: break; ! 208: ! 209: case 'r': ! 210: case 'R': ! 211: rotate = atof(*++argv); ! 212: argc--; ! 213: break; ! 214: ! 215: case 'I': ! 216: case 'i': ! 217: Inv = 1; ! 218: break; ! 219: ! 220: case 'A': ! 221: case 'a': ! 222: Aspect = 1; ! 223: break; ! 224: ! 225: default: ! 226: fprintf(stderr,"Illegal switch %c - ignored\n", ! 227: (*argv)[1]); ! 228: } ! 229: } ! 230: } ! 231: if (Land) ! 232: { ! 233: transx = 8.0; ! 234: transy = 0.5; ! 235: sizex = 10.0; ! 236: sizey = 7.5; ! 237: rotate = 90.0; ! 238: } ! 239: if (Aspect) { ! 240: if ((sizex / width) < (sizey / height)) { ! 241: sizey = sizex * (height * 1.0 / width); ! 242: } ! 243: else { ! 244: sizex = sizey * (width * 1.0 / height); ! 245: } ! 246: } ! 247: PrintPostScriptRoutines(height, width, 1 /*depth*/ , ! 248: transx, transy, sizex, sizey, rotate); ! 249: } ! 250: ! 251: /****************************************************************************** ! 252: * I/O Routines. * ! 253: ******************************************************************************/ ! 254: int ! 255: gb() /* Get a byte from Fp. */ ! 256: { ! 257: int byte; ! 258: ! 259: if (!feof(Fp)) ! 260: byte = getc(Fp); ! 261: else ! 262: Error("Premature EOF.\n"); ! 263: if (ferror(Fp)) ! 264: Error("I/O Error.\n"); ! 265: return(Revbyte[byte]); ! 266: } ! 267: ! 268: SendHex(Byte) /* Send a Hex char to Stdout. */ ! 269: unsigned char Byte; ! 270: { ! 271: static int LineCount = 0; ! 272: ! 273: printf("%02x", 0xff & Byte); ! 274: if (++LineCount == Rasbytes) ! 275: { ! 276: putchar('\n'); ! 277: LineCount = 0; ! 278: } ! 279: } ! 280: ! 281: int ! 282: SendBuffer(Inv) /* Send a buffer to Stdout. Return BytesSent. */ ! 283: int Inv; ! 284: { ! 285: int i, BytesSent; ! 286: ! 287: if (BufferMode() == LITERAL) ! 288: { ! 289: SendHex( (unsigned char) 0xff & BufCount ); ! 290: for (i = 0; i < BufCount+1; i++) ! 291: { ! 292: SendHex( (Inv) ? Buffer[i] : ~Buffer[i]); ! 293: } ! 294: BytesSent = BufCount+2; ! 295: } ! 296: else if (BufferMode() == COPY) ! 297: { ! 298: SendHex( (unsigned char) 0xff & (0x100 + BufCount) ); ! 299: SendHex( (Inv) ? Buffer[0] : ~Buffer[0]); ! 300: BytesSent = 2; ! 301: DiagRecLRun(mag(BufCount)+1); ! 302: } ! 303: return(BytesSent); ! 304: } ! 305: ! 306: /****************************************************************************** ! 307: * Utility Routines. * ! 308: ******************************************************************************/ ! 309: int ! 310: mag(Byte) /* Magitude of a signed char. */ ! 311: int Byte; ! 312: { ! 313: if (Byte & 0x80) ! 314: { ! 315: /* Signed */ ! 316: Byte = ~(--Byte); ! 317: } ! 318: return( 0xff & Byte ); ! 319: } ! 320: ! 321: /****************************************************************************** ! 322: * Buffer Management Routines. * ! 323: ******************************************************************************/ ! 324: int ! 325: InputMode() ! 326: { ! 327: if (CurrByte == NextByte) ! 328: return(COPY); ! 329: return(LITERAL); ! 330: } ! 331: ! 332: int ! 333: BufferMode() ! 334: { ! 335: if (BufCount >= 0 && BufCount <= 127) ! 336: return(LITERAL); ! 337: else if (BufCount >= -127 && BufCount <= -1) ! 338: return(COPY); ! 339: return(IGNORE); ! 340: } ! 341: ! 342: InitLitMode(NBytes, Inv) ! 343: int *NBytes, Inv; ! 344: { ! 345: BufferP = Buffer; ! 346: BufCount = -1; ! 347: ContLitMode(NBytes, Inv); ! 348: } ! 349: ! 350: ContLitMode(NBytes, Inv) ! 351: int *NBytes, Inv; ! 352: { ! 353: if (BufCount == 127) ! 354: { ! 355: SendBuffer(Inv); ! 356: BufferP = Buffer; ! 357: BufCount = -1; ! 358: } ! 359: *BufferP++ = CurrByte; ! 360: BufCount++; ! 361: CurrByte = NextByte; ! 362: NextByte = (unsigned char) gb(); ! 363: (*NBytes)--; ! 364: } ! 365: ! 366: InitCopyMode(NBytes, Inv) ! 367: int *NBytes, Inv; ! 368: { ! 369: BufferP = Buffer; ! 370: *BufferP++ = CurrByte; ! 371: BufCount = -1; ! 372: CurrByte = (unsigned char) gb(); ! 373: NextByte = (unsigned char) gb(); ! 374: *NBytes -= 2; ! 375: } ! 376: ! 377: ContCopyMode(NBytes, Inv) ! 378: int *NBytes, Inv; ! 379: { ! 380: if (BufCount == -127) ! 381: { ! 382: SendBuffer(Inv); ! 383: InitCopyMode(NBytes, Inv); ! 384: DiagNLongRuns++; ! 385: } ! 386: BufCount--; ! 387: CurrByte = NextByte; ! 388: NextByte = gb(); ! 389: (*NBytes)--; ! 390: } ! 391: ! 392: /****************************************************************************** ! 393: * Encoding Algorithm. * ! 394: ******************************************************************************/ ! 395: int ! 396: Encode(NBytes, Inv) ! 397: int NBytes, Inv; ! 398: { ! 399: int BytesSent = 0; ! 400: ! 401: /* Initialize Buffer, BufCount, NextByte, CurrByte */ ! 402: CurrByte = (unsigned char) gb(); ! 403: NextByte = (unsigned char) gb(); ! 404: if (InputMode() == LITERAL) ! 405: { ! 406: InitLitMode(&NBytes, Inv); ! 407: } ! 408: else ! 409: { ! 410: InitCopyMode(&NBytes, Inv); ! 411: } ! 412: while (NBytes > 3) ! 413: { ! 414: switch(BufferMode()) ! 415: { ! 416: case LITERAL: ! 417: if (InputMode() == COPY) ! 418: { ! 419: BytesSent += SendBuffer(Inv); ! 420: InitCopyMode(&NBytes, Inv); ! 421: } ! 422: else ! 423: { ! 424: ContLitMode(&NBytes, Inv); ! 425: } ! 426: break; ! 427: case COPY: ! 428: if (CurrByte == Buffer[0]) ! 429: { ! 430: ContCopyMode(&NBytes, Inv); ! 431: } ! 432: else ! 433: { ! 434: BytesSent += SendBuffer(Inv); ! 435: if (InputMode() == COPY) ! 436: { ! 437: InitCopyMode(&NBytes, Inv); ! 438: } ! 439: else ! 440: { ! 441: InitLitMode(&NBytes, Inv); ! 442: } ! 443: } ! 444: break; ! 445: default: ! 446: Error("Bad Buffer Mode... Sorry\n"); ! 447: break; ! 448: } ! 449: } ! 450: BytesSent += SendBuffer(Inv); ! 451: /* Send out rem'g 2-3 bytes in LITERAL mode. */ ! 452: Buffer[0] = CurrByte; ! 453: Buffer[1] = NextByte; ! 454: if (NBytes == 3) ! 455: Buffer[2] = gb(); ! 456: BufCount = NBytes-1; ! 457: BytesSent += SendBuffer(Inv); ! 458: return(BytesSent); ! 459: } ! 460: ! 461: /****************************************************************************** ! 462: * Diagnostic Routines. * ! 463: ******************************************************************************/ ! 464: DiagRecLRun(Rlength) ! 465: int Rlength; ! 466: { ! 467: #ifdef DIAGS ! 468: if (Rlength > DiagMaxRunLength) ! 469: DiagMaxRunLength = Rlength; ! 470: DiagSumRunLength += Rlength; ! 471: DiagNumRuns++; ! 472: #endif ! 473: } ! 474: ! 475: Diags() ! 476: { ! 477: #ifdef DIAGS ! 478: fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength); ! 479: fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns); ! 480: fprintf(stderr, "Average Run Length of %d. (%d Runs)\n", ! 481: (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns); ! 482: #endif ! 483: } ! 484: ! 485: /****************************************************************************** ! 486: * PostScript Output Routines. * ! 487: ******************************************************************************/ ! 488: PrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot) ! 489: int ras_h, ras_w, ras_d; ! 490: double tx, ty, sx, sy, rot; ! 491: { ! 492: printf("%%!\n/inch {72 mul} def\n"); ! 493: printf("/bpp %d def\n", ras_d); ! 494: printf("/scanlines %d def\n", ras_h); ! 495: printf("/scansize %d def\n", ras_w); ! 496: printf("/bitmapx\n{"); ! 497: printf(" %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w, ! 498: -ras_h, ras_h); ! 499: printf("{currentfile readrlehexstring pop } image\n} def\n"); ! 500: printf("gsave\n"); ! 501: printf("%f inch %f inch translate\n",tx, ty); ! 502: printf("%f rotate\n", rot ); ! 503: printf("%f inch %f inch scale\n", sx, sy); ! 504: printf("/readrlehexstring\t%% rle_file => decoded_string boolean\n"); ! 505: printf("{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {"); ! 506: printf("\n\t\t0 get dup 128 and 0 eq\n"); ! 507: printf("\t\t{ 1 add /Buffer exch string def\n"); ! 508: printf("\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{"); ! 509: printf(" 256 exch sub /BufCount exch def\n"); ! 510: printf("\t\t\t/Buffer BufCount 1 add string def\n"); ! 511: printf("\t\t\t/RunInt fileptr 1 string readhexstring"); ! 512: printf(" pop 0 get def\n"); ! 513: printf("\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n"); ! 514: printf("\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n"); ! 515: printf("} def\n"); ! 516: printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx); ! 517: printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n", ! 518: sx, sy, sy); ! 519: printf("\tclosepath\n} def\nclipathx clip\n"); ! 520: printf("bitmapx\n"); ! 521: } ! 522: ! 523: PrintPostScriptClosing() ! 524: { ! 525: printf("\ngrestore\n"); ! 526: printf("showpage\n"); ! 527: } ! 528: ! 529: /****************************************************************************** ! 530: * Error Routine. * ! 531: ******************************************************************************/ ! 532: Error(S1, S2, S3) ! 533: char *S1, *S2, *S3; ! 534: { ! 535: fprintf(stderr, S1, S2, S3); ! 536: exit(-1); ! 537: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.