home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume17
/
calentool
/
part09
/
ras2ps.c
Wrap
C/C++ Source or Header
|
1991-04-07
|
12KB
|
453 lines
/*
* $Header: ras2ps.c,v 2.3 89/12/15 17:18:07 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;
rotate = 0.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 */