home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * *
- * File: sun2ps.c *
- * Author: Glenn Boysko *
- * Organization: Case Western Reserve University *
- * EMail: {decvax, sun}!mandrill!boysko *
- * boysko@mandrill.cwru.edu *
- * Created: Wed Mar 23 9:25pm *
- * Contents: Sun Rasterfile to PostScript image (using a run-length *
- * encoding scheme.) *
- * *
- * (Adapted from "postimage" filter by J. R. Bammi.) *
- * *
- * @(#)sun2ps.c 1.7
- ******************************************************************************/
-
- /*
- * Usage:
- * sun2ps [-s sizex sizey] [-t transx transy] [-r rot] [-l] [-i] [-a] file ...
- *
- * -s sizex sizey = size of postscript image - default 7.5 x 10 inches.
- * -t transx transy = translate image - default 0.5 0.5 inches
- * -r rotate = rotate image - default 0 degress
- * -l = landscape (overrides *all* settings.)
- * -i = inverse image - default no inverse
- * (Inverse enabled implies white on black.)
- * -a = maintain correct aspect ratio - default none.
- *
- */
-
- /* Sun standard raster file format (as obtained by screendump(1)).
- *
- * Header (8 16-bit quantities)
- * Color Map
- * Image
- *
- */
-
- /* Header Format:
- *
- * ras_magic (int) Raster Magic number 0x59a66a95
- * ras_width (int) Width of image in pixels.
- * ras_height (int) Height of image in pixels.
- * ras_depth (int) Bits per pixel. Either 1 or 8 bits.
- * ras_length (int) Length of image in bytes.
- * ras_type (int) Type of file. Assumed to be RT_STANDARD (1) if
- * produced by a screendump command.
- * ras_maptype (int) Type of color map.
- * ras_maplength (int) Length of color map in bytes.
- *
- */
-
- /* Ras_maplength bytes of Color map data. */
-
- /* Ras_length bytes of Image data. */
-
- #include <stdio.h>
- #include <rasterfile.h>
-
- /* Buffer and Input Modes... */
- #define LITERAL 0
- #define COPY 1
- #define IGNORE 2
-
- /* Transmission Variables. */
- int BufCount;
-
- unsigned char Buffer[128],
- CurrByte,
- NextByte,
- *BufferP = Buffer;
-
- /* Diagnostic Variables. */
- int DiagNLongRuns = 0,
- DiagMaxRunLength = 0,
- DiagNumRuns = 0;
- double DiagSumRunLength = 0;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- FILE *fp, *fopen();
- int land, inv, aspect;
- char *filename;
- double sizex, sizey, transx, transy, rotate;
-
- extern double atof();
-
- fp = stdin;
- aspect = 0;
- land = 0;
- filename = "STDIN";
- sizex = 7.5;
- sizey = 10.0;
- transx = 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 'A':
- case 'a':
- aspect = 1;
- 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;
- }
- }
- if (land)
- {
- transx = 8.0;
- transy = 0.5;
- sizex = 10.0;
- sizey = 7.5;
- rotate = 90.0;
- }
- process(fp, aspect, inv, filename, sizex, sizey, transx, transy, rotate);
- }
-
- process(Fp, aspect, inv, filename, sizex, sizey, transx, transy, rotate)
- FILE *Fp;
- int inv, aspect;
- double sizex, sizey, transx, transy, rotate;
- char *filename;
- {
- struct rasterfile rh;
- int i, BS;
-
- if (fread((char *) (&rh), sizeof(rh), 1, Fp) != 1)
- {
- Error("Can't read rasterfile header\n");
- }
-
- #ifdef EXTRADIAGS
- fprintf(stderr, "Ras_width = %d, Ras_height = %d, Ras_depth = %d\n",
- rh.ras_width, rh.ras_height, rh.ras_depth);
- fprintf(stderr, "Ras_length = %d, Ras_type = %d, Ras_maplength = %d\n",
- rh.ras_length, rh.ras_type, rh.ras_maplength);
- #endif
-
- if (rh.ras_magic != RAS_MAGIC)
- {
- Error("Input file is not a Sun Rasterfile!\n");
- }
-
- if (rh.ras_type != RT_STANDARD)
- {
- Error("Input file is not in Sun Standard Rasterfile format.\n");
- }
-
- /* Scan off color table */
- for (i=0; i < rh.ras_maplength; i++)
- {
- gb(Fp);
- }
-
- if (aspect)
- {
- if ((sizex / rh.ras_width) < (sizey / rh.ras_height))
- {
- sizey = sizex * (rh.ras_height * 1.0 / rh.ras_width);
- }
- else
- {
- sizex = sizey * (rh.ras_width * 1.0 / rh.ras_height);
- }
-
- }
-
- PrintPostScriptRoutines(rh.ras_height, rh.ras_width, rh.ras_depth,
- transx, transy, sizex, sizey, rotate);
-
- BS = Encode(Fp, rh.ras_length, inv);
-
- #ifdef DIAGS
- fprintf(stderr, "Encoded %d bytes into %d. (Ratio=%d%%)\n",
- rh.ras_length, BS, 100 - (100 * BS) / rh.ras_length);
- Diags();
- #endif
- fclose(Fp);
-
- PrintPostScriptClosing();
- }
-
- /******************************************************************************
- * I/O Routines. *
- ******************************************************************************/
- int
- gb(Fp) /* Get a byte from Fp. */
- FILE *Fp;
- {
- int byte;
-
- if (!feof(Fp))
- byte = getc(Fp);
- else
- Error("Premature EOF.\n");
- if (ferror(Fp))
- Error("I/O Error.\n");
- return(byte);
- }
-
- int
- gw(Fp) /* Get a word (int) from Fp. */
- FILE *Fp;
- {
- int word;
-
- if (!feof(Fp))
- word = getw(Fp);
- else
- Error("Premature EOF.\n");
- if (ferror(Fp))
- Error("I/O Error.\n");
- return(word);
- }
-
- SendHex(Byte) /* Send a Hex char to Stdout. */
- unsigned char Byte;
- {
- static int LineCount = 0;
-
- printf("%02x", 0xff & Byte);
- if (++LineCount == 16)
- {
- putchar('\n');
- LineCount = 0;
- }
- }
-
- int
- SendBuffer(Inv) /* Send a buffer to Stdout. Return BytesSent. */
- int Inv;
- {
- int i, BytesSent;
-
- if (BufferMode() == LITERAL)
- {
- SendHex( (unsigned char) 0xff & BufCount );
- for (i = 0; i < BufCount+1; i++)
- {
- SendHex( (Inv) ? Buffer[i] : ~Buffer[i]);
- }
- BytesSent = BufCount+2;
- }
- else if (BufferMode() == COPY)
- {
- SendHex( (unsigned char) 0xff & (0x100 + BufCount) );
- SendHex( (Inv) ? Buffer[0] : ~Buffer[0]);
- BytesSent = 2;
- DiagRecLRun(mag(BufCount)+1);
- }
- return(BytesSent);
- }
-
- /******************************************************************************
- * Utility Routines. *
- ******************************************************************************/
- int
- mag(Byte) /* Magitude of a signed char. */
- int Byte;
- {
- if (Byte & 0x80)
- {
- /* Signed */
- Byte = ~(--Byte);
- }
- return( 0xff & Byte );
- }
-
- /******************************************************************************
- * Buffer Management Routines. *
- ******************************************************************************/
- int
- InputMode()
- {
- if (CurrByte == NextByte)
- return(COPY);
- return(LITERAL);
- }
-
- int
- BufferMode()
- {
- if (BufCount >= 0 && BufCount <= 127)
- return(LITERAL);
- else if (BufCount >= -127 && BufCount <= -1)
- return(COPY);
- return(IGNORE);
- }
-
- InitLitMode(Fp, NBytes, Inv)
- FILE *Fp;
- int *NBytes, Inv;
- {
- BufferP = Buffer;
- BufCount = -1;
- ContLitMode(Fp, NBytes, Inv);
- }
-
- ContLitMode(Fp, NBytes, Inv)
- FILE *Fp;
- int *NBytes, Inv;
- {
- if (BufCount == 127)
- {
- SendBuffer(Inv);
- BufferP = Buffer;
- BufCount = -1;
- }
- *BufferP++ = CurrByte;
- BufCount++;
- CurrByte = NextByte;
- NextByte = (unsigned char) gb(Fp);
- (*NBytes)--;
- }
-
- InitCopyMode(Fp, NBytes, Inv)
- FILE *Fp;
- int *NBytes, Inv;
- {
- BufferP = Buffer;
- *BufferP++ = CurrByte;
- BufCount = -1;
- CurrByte = (unsigned char) gb(Fp);
- NextByte = (unsigned char) gb(Fp);
- *NBytes -= 2;
- }
-
- ContCopyMode(Fp, NBytes, Inv)
- FILE *Fp;
- int *NBytes, Inv;
- {
- if (BufCount == -127)
- {
- SendBuffer(Inv);
- InitCopyMode(Fp, NBytes, Inv);
- DiagNLongRuns++;
- }
- BufCount--;
- CurrByte = NextByte;
- NextByte = gb(Fp);
- (*NBytes)--;
- }
-
- /******************************************************************************
- * Encoding Algorithm. *
- ******************************************************************************/
- int
- Encode(Fp, NBytes, Inv)
- FILE *Fp;
- int NBytes, Inv;
- {
- int BytesSent = 0;
-
- /* Initialize Buffer, BufCount, NextByte, CurrByte */
- CurrByte = (unsigned char) gb(Fp);
- NextByte = (unsigned char) gb(Fp);
- if (InputMode() == LITERAL)
- {
- InitLitMode(Fp, &NBytes, Inv);
- }
- else
- {
- InitCopyMode(Fp, &NBytes, Inv);
- }
- while (NBytes > 2)
- {
- switch(BufferMode())
- {
- case LITERAL:
- if (InputMode() == COPY)
- {
- BytesSent += SendBuffer(Inv);
- InitCopyMode(Fp, &NBytes, Inv);
- }
- else
- {
- ContLitMode(Fp, &NBytes, Inv);
- }
- break;
- case COPY:
- if (CurrByte == Buffer[0])
- {
- ContCopyMode(Fp, &NBytes, Inv);
- }
- else
- {
- BytesSent += SendBuffer(Inv);
- if (InputMode() == COPY)
- {
- InitCopyMode(Fp, &NBytes, Inv);
- }
- else
- {
- InitLitMode(Fp, &NBytes, Inv);
- }
- }
- break;
- default:
- Error("Bad Buffer Mode... Sorry\n");
- break;
- }
- }
- BytesSent += SendBuffer(Inv);
- /* Send out rem'g 2 bytes in LITERAL mode. */
- Buffer[0] = CurrByte;
- Buffer[1] = NextByte;
- BufCount = 1;
- BytesSent += SendBuffer(Inv);
- return(BytesSent);
- }
-
- /******************************************************************************
- * Diagnostic Routines. *
- ******************************************************************************/
- DiagRecLRun(Rlength)
- int Rlength;
- {
- #ifdef DIAGS
- if (Rlength > DiagMaxRunLength)
- DiagMaxRunLength = Rlength;
- DiagSumRunLength += Rlength;
- DiagNumRuns++;
- #endif
- }
-
- Diags()
- {
- #ifdef DIAGS
- fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength);
- fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns);
- fprintf(stderr, "Average Run Length of %d. (%d Runs)\n",
- (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns);
- #endif
- }
-
- /******************************************************************************
- * PostScript Output Routines. *
- ******************************************************************************/
- PrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot)
- int ras_h, ras_w, ras_d;
- double tx, ty, sx, sy, rot;
- {
- printf("%%!\n/inch {72 mul} def\n");
- printf("/bpp %d def\n", ras_d);
- printf("/scanlines %d def\n", ras_h);
- printf("/scansize %d def\n", ras_w);
- printf("/bitmapx\n{");
- printf(" %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w,
- -ras_h, ras_h);
- printf("{currentfile readrlehexstring pop } image\n} def\n");
- printf("gsave\n");
- printf("%f inch %f inch translate\n",tx, ty);
- printf("%f rotate\n", rot );
- printf("%f inch %f inch scale\n", sx, sy);
- printf("/readrlehexstring\t%% rle_file => decoded_string boolean\n");
- printf("{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
- printf("\n\t\t0 get dup 128 and 0 eq\n");
- printf("\t\t{ 1 add /Buffer exch string def\n");
- printf("\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
- printf(" 256 exch sub /BufCount exch def\n");
- printf("\t\t\t/Buffer BufCount 1 add string def\n");
- printf("\t\t\t/RunInt fileptr 1 string readhexstring");
- printf(" pop 0 get def\n");
- printf("\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
- printf("\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
- printf("} def\n");
- printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
- printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
- sx, sy, sy);
- printf("\tclosepath\n} def\nclipathx clip\n");
- printf("bitmapx\n");
- }
-
- PrintPostScriptClosing()
- {
- printf("\ngrestore\n");
- printf("showpage\n");
- }
-
- /******************************************************************************
- * Error Routine. *
- ******************************************************************************/
- Error(S1, S2, S3)
- char *S1, *S2, *S3;
- {
- fprintf(stderr, S1, S2, S3);
- exit(-1);
- }
-