home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Header: ras2ps.c,v 2.1 89/05/09 14:19:40 billr Exp $
- */
- /*
- * ras2ps - convert Sun raster file to RLL Postscript file
- *
- * Based on the sun2ps program by Glenn Boysko and modified slightly
- * by Bill Randle, Tektronix, Inc.
- * Original source of unknown copyright status; modifications Copyright
- * 1989, Tektronix, Inc.
- */
- #include "ct.h" /* for the NO_PRINTER #define */
- #ifndef NO_PRINTER
- /******************************************************************************
- * *
- * 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.8
- ******************************************************************************/
-
- /* 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, after line padding.
- * 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 <pixrect/pixrect_hs.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;
-
- FILE *ofile;
-
- /* Diagnostic Variables. */
- int DiagNLongRuns = 0,
- DiagMaxRunLength = 0,
- DiagNumRuns = 0;
- double DiagSumRunLength = 0;
-
- ras2ps(infile, outfile)
- FILE *infile, *outfile;
- {
- double sizex, sizey, transx, transy, rotate;
- struct rasterfile rh;
- int i, BS, pad,inv;
-
-
- extern double atof();
-
- sizex = 7.5;
- sizey = 10.0;
- transx = transy = 0.5;
- inv = 0;
- ofile = outfile;
-
- if (pr_load_header(infile, &rh) != 0)
- 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 */
- if (rh.ras_maptype != RMT_NONE && rh.ras_maplength > 0)
- pr_load_colormap(infile, &rh, NULL);
-
- if ( pad = 16 - (rh.ras_width%16) ) {
- rh.ras_width += pad;
- #ifdef EXTRADIAGS
- fprintf(stderr, "Ras_width changed to %d\n",rh.ras_width);
- #endif
- }
-
- PrintPostScriptRoutines(rh.ras_height, rh.ras_width, rh.ras_depth,
- transx, transy, sizex, sizey, rotate);
-
- BS = Encode(infile, 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(infile);
-
- PrintPostScriptClosing();
- fclose(outfile);
- }
-
- /******************************************************************************
- * 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;
-
- fprintf(ofile, "%02x", 0xff & Byte);
- if (++LineCount == 16)
- {
- fputc('\n', ofile);
- 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 > 3)
- {
- 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-3 bytes in LITERAL mode. */
- Buffer[0] = CurrByte;
- Buffer[1] = NextByte;
- if (NBytes == 3)
- Buffer[2] = gb(Fp);
- BufCount = NBytes-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;
- {
- fprintf(ofile, "%%!\n/inch {72 mul} def\n");
- fprintf(ofile, "/bpp %d def\n", ras_d);
- fprintf(ofile, "/scanlines %d def\n", ras_h);
- fprintf(ofile, "/scansize %d def\n", ras_w);
- fprintf(ofile, "/bitmapx\n{");
- fprintf(ofile, " %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w,
- -ras_h, ras_h);
- fprintf(ofile, "{currentfile readrlehexstring pop } image\n} def\n");
- fprintf(ofile, "gsave\n");
- fprintf(ofile, "%f inch %f inch translate\n",tx, ty);
- fprintf(ofile, "%f rotate\n", rot );
- fprintf(ofile, "%f inch %f inch scale\n", sx, sy);
- fprintf(ofile, "/readrlehexstring\t%% rle_file => decoded_string boolean\n");
- fprintf(ofile, "{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
- fprintf(ofile, "\n\t\t0 get dup 128 and 0 eq\n");
- fprintf(ofile, "\t\t{ 1 add /Buffer exch string def\n");
- fprintf(ofile, "\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
- fprintf(ofile, " 256 exch sub /BufCount exch def\n");
- fprintf(ofile, "\t\t\t/Buffer BufCount 1 add string def\n");
- fprintf(ofile, "\t\t\t/RunInt fileptr 1 string readhexstring");
- fprintf(ofile, " pop 0 get def\n");
- fprintf(ofile, "\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
- fprintf(ofile, "\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
- fprintf(ofile, "} def\n");
- fprintf(ofile, "/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
- fprintf(ofile, " lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
- sx, sy, sy);
- fprintf(ofile, "\tclosepath\n} def\nclipathx clip\n");
- fprintf(ofile, "bitmapx\n");
- }
-
- PrintPostScriptClosing()
- {
- fprintf(ofile, "\ngrestore\n");
- fprintf(ofile, "showpage\n");
- }
-
- /******************************************************************************
- * Error Routine. *
- ******************************************************************************/
- Error(S1)
- char *S1;
- {
- *(S1 + strlen(S1)) = '\0'; /* delete trailing \n */
- err_rpt(S1, FATAL);
- }
- #endif /* NO_PRINTER */
-