|
|
researchv10 Norman
/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved. */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T. */
/* The copyright notice does not imply actual or intended publication. */
/* AUTHORS: */
/* T. Thompson - ATT-BL HO - first versions */
/* Routines for generating PostScript from RLE. */
/* The routines at the bottom of this file, which */
/* do the actual conversion to postscript, were */
/* hacked out of 'sun2ps'. The original header */
/* giving credit to its authors is there. */
/* The 'binary' version of the output is collected in a */
/* temporary file, which is then fed back to the routines */
/* that generate postscript in a run-length-encoded form. */
/* Ideally it should just convert the original run-length */
/* encoding directly, but the REAL bottleneck is the */
/* PostScript printer, of course. Printing an 800 by 800 */
/* pixel image takes 5 minutes. */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "CPU.h"
#include "boole.h"
#include "limits.h" /* numeric extreme values */
#include "Units.h"
#include "Coord.h"
#include "pic.h"
FILE *Fp, *tmpfile();
int Raswidth;
int Raslength;
int Rasbytes; /* bytes per row */
int Inv = 0;
int Aspect = 1; /* if non-zero, retain original aspect ratio */
int Land = 0; /* if non-zero, print in landscape mode */
char Revbyte[256];
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
char Revnib[16] = {
0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
};
void
POST_start(h)
PIC_hdr *h;
{
int n, v;
/* build a table of reversed bytes */
for ( n=0; n<256; n++ )
Revbyte[n] = Revnib[(n>>4)&0xf] | Revnib[n&0xf]<<4;
h->bpl = (h->bpl+7)/8;
Rasbytes = h->bpl;
Raslength = h->bpl * h->bx.b.y;
Raswidth = h->bx.b.x;
postmain(1,NULL,Raswidth,h->bx.b.y);
#if CPU==SUN
Fp = tmpfile();
#else
Fp = fopen("tmp.postlib.0","rw");
#endif
}
void
POST_end()
{
int c;
rewind(Fp);
(VOID) Encode(Raslength, Inv);
PrintPostScriptClosing();
fclose(Fp);
}
/* write a full line of picture data, returning status: 1 OK, 0 EOF, -1 ERR */
int POST_wline(h,line)
PIC_hdr *h;
unsigned char *line;
{ int stat;
if( (stat=fwrite(line,1,h->bpl,Fp)) == h->bpl) {
h->seek += h->bpl;
h->cy++;
return(1);
}
else { /* ERR */
err("write to fd%d stat%d",fileno(h->fp),stat);
if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
else return(-1);
};
}
/******************************************************************************
* *
* File: sun2ps.c *
* Author: Glenn Boysko *
* Organization: Case Western Reserve University *
* EMail: {decvax, sun}!mandrill!boysko *
* [email protected] *
* 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
******************************************************************************/
/*
* 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. */
/* 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;
postmain(argc,argv,width,height)
int argc;
char **argv;
int width, height;
{
char *filename;
double sizex, sizey, transx, transy, rotate;
extern double atof();
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]);
}
}
}
if (Land)
{
transx = 8.0;
transy = 0.5;
sizex = 10.0;
sizey = 7.5;
rotate = 90.0;
}
if (Aspect) {
if ((sizex / width) < (sizey / height)) {
sizey = sizex * (height * 1.0 / width);
}
else {
sizex = sizey * (width * 1.0 / height);
}
}
PrintPostScriptRoutines(height, width, 1 /*depth*/ ,
transx, transy, sizex, sizey, rotate);
}
/******************************************************************************
* I/O Routines. *
******************************************************************************/
int
gb() /* Get a byte from Fp. */
{
int byte;
if (!feof(Fp))
byte = getc(Fp);
else
Error("Premature EOF.\n");
if (ferror(Fp))
Error("I/O Error.\n");
return(Revbyte[byte]);
}
SendHex(Byte) /* Send a Hex char to Stdout. */
unsigned char Byte;
{
static int LineCount = 0;
printf("%02x", 0xff & Byte);
if (++LineCount == Rasbytes)
{
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(NBytes, Inv)
int *NBytes, Inv;
{
BufferP = Buffer;
BufCount = -1;
ContLitMode(NBytes, Inv);
}
ContLitMode(NBytes, Inv)
int *NBytes, Inv;
{
if (BufCount == 127)
{
SendBuffer(Inv);
BufferP = Buffer;
BufCount = -1;
}
*BufferP++ = CurrByte;
BufCount++;
CurrByte = NextByte;
NextByte = (unsigned char) gb();
(*NBytes)--;
}
InitCopyMode(NBytes, Inv)
int *NBytes, Inv;
{
BufferP = Buffer;
*BufferP++ = CurrByte;
BufCount = -1;
CurrByte = (unsigned char) gb();
NextByte = (unsigned char) gb();
*NBytes -= 2;
}
ContCopyMode(NBytes, Inv)
int *NBytes, Inv;
{
if (BufCount == -127)
{
SendBuffer(Inv);
InitCopyMode(NBytes, Inv);
DiagNLongRuns++;
}
BufCount--;
CurrByte = NextByte;
NextByte = gb();
(*NBytes)--;
}
/******************************************************************************
* Encoding Algorithm. *
******************************************************************************/
int
Encode(NBytes, Inv)
int NBytes, Inv;
{
int BytesSent = 0;
/* Initialize Buffer, BufCount, NextByte, CurrByte */
CurrByte = (unsigned char) gb();
NextByte = (unsigned char) gb();
if (InputMode() == LITERAL)
{
InitLitMode(&NBytes, Inv);
}
else
{
InitCopyMode(&NBytes, Inv);
}
while (NBytes > 3)
{
switch(BufferMode())
{
case LITERAL:
if (InputMode() == COPY)
{
BytesSent += SendBuffer(Inv);
InitCopyMode(&NBytes, Inv);
}
else
{
ContLitMode(&NBytes, Inv);
}
break;
case COPY:
if (CurrByte == Buffer[0])
{
ContCopyMode(&NBytes, Inv);
}
else
{
BytesSent += SendBuffer(Inv);
if (InputMode() == COPY)
{
InitCopyMode(&NBytes, Inv);
}
else
{
InitLitMode(&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();
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;
{
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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.