This is outfile.c in view mode; [Download] [Up]
/* outfile.c
* RasMol2 Molecular Graphics
* Roger Sayle, August 1995
* Version 2.6
*/
#define OUTFILE
#include "rasmol.h"
#ifdef IBMPC
#include <windows.h>
#include <malloc.h>
#endif
#ifdef APPLEMAC
#include <Types.h>
#include <Errors.h>
#ifdef __CONDITIONALMACROS__
#include <Printing.h>
#else
#include <PrintTraps.h>
#endif
#endif
#ifndef sun386
#include <stdlib.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include "outfile.h"
#include "molecule.h"
#include "command.h"
#include "abstree.h"
#include "transfor.h"
#include "render.h"
#include "repres.h"
#include "graphics.h"
#include "pixutils.h"
#include "script.h"
#ifdef EIGHTBIT
#define RComp(x) (RLut[LutInv[x]])
#define GComp(x) (GLut[LutInv[x]])
#define BComp(x) (BLut[LutInv[x]])
#else
#define RComp(x) (((x)>>16)&0xff)
#define GComp(x) (((x)>>8)&0xff)
#define BComp(x) ((x)&0xff)
#endif
#ifdef INVERT
#define InvertY(y) (y)
#else
#define InvertY(y) (-(y))
#endif
/* Sun rasterfile.h macro defns */
#define RAS_MAGIC 0x59a66a95
#define RAS_RLE 0x80
#define RT_STANDARD 1
#define RT_BYTE_ENCODED 2
#define RMT_NONE 0
#define RMT_EQUAL_RGB 1
/* Standard A4 size page: 8.267x11.811 inches */
/* U.S. Normal size page: 8.500x11.000 inches */
#define PAGEHIGH (11.811*72.0)
#define PAGEWIDE (8.267*72.0)
#define BORDER 0.90
/* Compression Ratio 0<x<127 */
#define EPSFCompRatio 32
#define Round(x) ((int)(x))
#define PSBond 0x00
#define PSHBond 0x01
#define PSSSBond 0x02
#define PSAtom 0x03
#define PSRibbon 0x04
#define PSMonit 0x05
typedef void __far* PSItemPtr;
#if defined(IBMPC) || defined(APPLEMAC)
static short __far *ABranch;
static short __far *DBranch;
static short __far *Hash;
static Byte __far *Node;
#else
static short ABranch[4096];
static short DBranch[4096];
static short Hash[256];
static Byte Node[4096];
#endif
/* Apple PICT macros */
#define PICTcliprgn 0x0001
#define PICTpicversion 0x0011
#define PICTpackbitsrect 0x0098
#define PICTdirectbitsrect 0x009a
#define PICTendofpict 0x00ff
#define PICTheaderop 0x0c00
typedef struct {
Byte len;
Byte ch;
} BMPPacket;
static BMPPacket BMPBuffer[10];
static int BMPCount,BMPTotal;
static int BMPPad;
static int GIFClrCode;
static int GIFEOFCode;
static short RLELineSize;
static Card RLEFileSize;
static int RLEEncode;
static int RLEOutput;
static int RLELength;
static int RLEPixel;
static int RLEChar;
static Byte Buffer[256];
static Byte LutInv[256];
static int LineLength;
static FILE *OutFile;
static Card BitBuffer;
static int BitBufLen;
static int PacketLen;
static int CodeSize;
static Real LineWidth;
static int VectSolid;
static int VectCol;
/* Macros for commonly used loops */
#define ForEachAtom for(chain=Database->clist;chain;chain=chain->cnext) \
for(group=chain->glist;group;group=group->gnext) \
for(aptr=group->alist;aptr;aptr=aptr->anext)
#define ForEachBond for(bptr=Database->blist;bptr;bptr=bptr->bnext)
#define ForEachBack for(chain=Database->clist;chain;chain=chain->cnext) \
for(bptr=chain->blist;bptr;bptr=bptr->bnext)
#ifdef APPLEMAC
/* External RasMac Function Declaration! */
void SetFileInfo( char*, OSType, OSType, short );
#endif
static void FatalOutputError( ptr )
char *ptr;
{
if( CommandActive ) WriteChar('\n');
WriteString("Output Error: Unable to create file `");
WriteString( ptr ); WriteString("'!\n");
CommandActive = False;
}
/* Integer Output Routines */
#ifdef FUNCPROTO
static void WriteLSBLong( Card );
static void WriteMSBLong( Card );
#endif
static void WriteByte( val )
int val;
{
putc( val, OutFile );
}
static void WriteLSBShort( val )
int val;
{
putc( val&0xff, OutFile );
putc( (val>>8)&0xff, OutFile );
}
static void WriteMSBShort( val )
int val;
{
putc( (val>>8)&0xff, OutFile );
putc( val&0xff, OutFile );
}
static void WriteLSBLong( val )
Card val;
{
putc((int)(val&0xff),OutFile);
putc((int)((val>>8) &0xff),OutFile);
putc((int)((val>>16)&0xff),OutFile);
putc((int)((val>>24)&0xff),OutFile);
}
static void WriteMSBLong( val )
Card val;
{
putc((int)((val>>24)&0xff),OutFile);
putc((int)((val>>16)&0xff),OutFile);
putc((int)((val>>8) &0xff),OutFile);
putc((int)(val&0xff),OutFile);
}
static void CalcInvColourMap()
{
#ifdef EIGHTBIT
register int i;
for( i=0; i<256; i++ )
if( ULut[i] )
LutInv[Lut[i]] = i;
#endif
}
#ifdef EIGHTBIT
static int CompactColourMap()
{
register Pixel __huge *ptr;
register Long pos, count;
register int i, cols;
CalcInvColourMap();
for( i=0; i<256; i++ )
{ Buffer[i] = 0;
Node[i] = 5;
}
#ifdef IBMPC
ptr = (Pixel __huge*)GlobalLock(FBufHandle);
#else
ptr = FBuffer;
#endif
cols = 0;
count = (Long)XRange*YRange;
for( pos=0; pos<count; pos++ )
{ i = LutInv[*ptr++];
if( !Buffer[i] )
{ Node[cols++] = i;
Buffer[i] = cols;
}
}
for( i=0; i<256; i++ )
LutInv[i] = Buffer[LutInv[i]]-1;
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( cols );
}
#endif
static void WritePPMWord( i )
int i;
{
if( i>99 )
{ putc((i/100)+'0',OutFile); i %= 100;
putc((i/10) +'0',OutFile); i %= 10;
} else if( i>9 )
{ putc((i/10)+'0',OutFile); i %= 10;
}
putc(i+'0',OutFile);
}
int WritePPMFile( name, raw )
char *name; int raw;
{
register Pixel __huge *ptr;
register int i,col;
register int x,y;
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name, (raw?"wb":"w") );
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
CalcInvColourMap();
fprintf(OutFile,"P%c %d %d 255\n",(raw?'6':'3'),XRange,YRange);
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
if( !raw )
{ col = 0;
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ i = *ptr++;
WritePPMWord((int)RComp(i)); WriteByte(' ');
WritePPMWord((int)GComp(i)); WriteByte(' ');
WritePPMWord((int)BComp(i));
if( ++col == 5 )
{ WriteByte('\n');
col = 0;
} else WriteByte(' ');
}
}
} else
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ i = *ptr++;
putc((int)RComp(i),OutFile);
putc((int)GComp(i),OutFile);
putc((int)BComp(i),OutFile);
}
}
fclose(OutFile);
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'\?\?\?\?','\?\?\?\?',134);
#endif
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( True );
}
static void WriteGIFCode( code )
int code;
{
register int max;
max = (code==GIFEOFCode)? 0 : 7;
BitBuffer |= ((Card)code<<BitBufLen);
BitBufLen += CodeSize;
while( BitBufLen > max )
{
#ifdef IBMPC
Buffer[PacketLen++]=(Byte)(BitBuffer&0xff);
#else
Buffer[PacketLen++]=BitBuffer;
#endif
BitBuffer >>= 8;
BitBufLen -= 8;
if( PacketLen==255 )
{ WriteByte(0xff);
fwrite((char*)Buffer,1,255,OutFile);
PacketLen = 0;
}
}
}
int WriteGIFFile( name )
char *name;
{
register int i,j,cols;
register int pref,next,last;
register int isize, ilast;
register Pixel __huge *ptr;
register short __far *prev;
register int x,y,init;
#ifdef EIGHTBIT
cols = CompactColourMap();
if( cols<2 ) return( False );
for( isize=2; isize<8; isize++ )
if( (1<<isize) >= cols ) break;
cols = 1<<isize;
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
fputs("GIF87a",OutFile);
WriteLSBShort(XRange);
WriteLSBShort(YRange);
WriteByte(0xf0|(isize-1));
WriteByte(0x00);
WriteByte(0x00);
for( j=0; j<cols; j++ )
{ i = Node[j];
WriteByte(RLut[i]);
WriteByte(GLut[i]);
WriteByte(BLut[i]);
}
WriteByte(',');
WriteByte(0x00); WriteByte(0x00);
WriteByte(0x00); WriteByte(0x00);
WriteLSBShort(XRange);
WriteLSBShort(YRange);
WriteByte(0x00); WriteByte(isize);
PacketLen=0;
BitBuffer=0;
BitBufLen=0;
GIFClrCode = (1<<isize);
GIFEOFCode = GIFClrCode+1;
ilast = (GIFClrCode<<1)-GIFEOFCode;
isize++;
CodeSize = isize;
last = ilast;
next = 1;
WriteGIFCode(GIFClrCode);
for( i=0; i<cols; i++ )
Hash[i]=0;
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
/* Avoid Warnings! */
prev = (short __far*)0;
pref = 0;
init = False;
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ if( !init )
{ pref = LutInv[*ptr++];
prev = Hash+pref;
init = True;
continue;
}
i = LutInv[*ptr++];
while( *prev && (Node[*prev] != (Byte)i) )
prev = ABranch+*prev;
if( *prev )
{ pref = *prev+GIFEOFCode;
prev = DBranch+*prev;
} else
{ WriteGIFCode(pref);
if( next==last )
{ if( CodeSize==12 )
{ WriteGIFCode(GIFClrCode);
pref = i; prev = Hash+i;
for( i=0; i<cols; i++ )
Hash[i] = 0;
CodeSize = isize;
last = ilast;
next = 1;
continue;
}
last = (last<<1)+GIFEOFCode;
CodeSize++;
}
*prev = next;
ABranch[next] = 0;
DBranch[next] = 0;
Node[next] = i;
prev = Hash+i;
pref = i;
next++;
}
}
}
WriteGIFCode(pref);
WriteGIFCode(GIFEOFCode);
if( PacketLen )
{ WriteByte(PacketLen);
fwrite((char*)Buffer,1,PacketLen,OutFile);
}
WriteByte(0x00);
WriteByte(';');
fclose(OutFile);
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'\?\?\?\?','GIFf',134);
#endif
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( True );
#else
if( CommandActive ) WriteChar('\n');
WriteString("Output Error: 24 bit GIF files unsupported!\n");
CommandActive = False;
return( False );
#endif
}
static void FlushRastRLE()
{
if( RLEChar==RAS_RLE )
{ if( RLEOutput )
{ WriteByte(RAS_RLE);
WriteByte(RLELength-1);
if( RLELength!=1 )
WriteByte(RAS_RLE);
} else RLEFileSize += (RLELength>1)? 3 : 2;
} else
if( RLEOutput )
{ if( RLELength>2 )
{ WriteByte(RAS_RLE);
WriteByte(RLELength-1);
} else if( RLELength==2 )
WriteByte(RLEChar);
WriteByte(RLEChar);
} else RLEFileSize += MinFun(RLELength,3);
}
static void WriteRastRLECode( val )
int val;
{
if( RLEEncode )
{ if( !RLELength )
{ RLELength = 1;
RLEChar = val;
} else if( (RLEChar!=val) || (RLELength==256) )
{ FlushRastRLE();
RLELength = 1;
RLEChar = val;
} else RLELength++;
} else WriteByte(val);
}
static void WriteRastRLEPad()
{
if( RLEEncode )
{ if( !RLELength || (RLELength==256) )
{ WriteRastRLECode(0x00);
} else RLELength++;
} else WriteByte(0x00);
}
static void WriteRastData( output )
int output;
{
register Pixel __huge *ptr;
register int x,y,pad;
#ifndef EIGHTBIT
register int i;
#endif
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
pad = XRange%2;
RLEOutput = output;
RLEFileSize = 0;
RLELength = 0;
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
#ifndef EIGHTBIT
{ i = *ptr++;
WriteRastRLECode((int)BComp(i));
WriteRastRLECode((int)GComp(i));
WriteRastRLECode((int)RComp(i));
}
#else
WriteRastRLECode((int)LutInv[*ptr++]);
#endif
if( pad ) WriteRastRLEPad();
}
if( RLEEncode && RLELength )
FlushRastRLE();
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
}
int WriteRastFile( name, encode )
char *name;
int encode;
{
register int i,size,cols;
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return(False);
}
WriteMSBLong( RAS_MAGIC );
WriteMSBLong(XRange);
WriteMSBLong(YRange);
RLEEncode = encode;
#ifdef EIGHTBIT
WriteMSBLong(8);
if( encode )
{ WriteRastData(False);
WriteMSBLong(RLEFileSize);
WriteMSBLong(RT_BYTE_ENCODED);
} else
{ size = (XRange%2)? XRange+1 : XRange;
WriteMSBLong(size*YRange);
WriteMSBLong(RT_STANDARD);
}
cols = CompactColourMap();
WriteMSBLong(RMT_EQUAL_RGB);
WriteMSBLong(cols*3);
for( i=0; i<cols; i++ ) WriteByte(RLut[Node[i]]);
for( i=0; i<cols; i++ ) WriteByte(GLut[Node[i]]);
for( i=0; i<cols; i++ ) WriteByte(BLut[Node[i]]);
#else
WriteMSBLong(24);
if( encode )
{ WriteRastData(False);
WriteMSBLong(RLEFileSize);
WriteMSBLong(RT_BYTE_ENCODED);
} else
{ size = XRange*3;
if( size&1 ) size++;
WriteMSBLong((Long)size*YRange);
WriteMSBLong(RT_STANDARD);
}
WriteMSBLong(RMT_NONE);
WriteMSBLong(0);
#endif
WriteRastData(True);
fclose( OutFile );
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'\?\?\?\?','\?\?\?\?',134);
#endif
return( True );
}
static void OutputEPSFByte( val )
int val;
{
static char *hex = "0123456789ABCDEF";
WriteByte( hex[val>>4] );
WriteByte( hex[val&0x0f] );
if( (LineLength+=2) > 72 )
{ WriteByte('\n');
LineLength = 0;
}
}
static void EncodeEPSFPixel( val, col )
int val, col;
{
register int r, g, b;
register int i;
r = RComp(val);
g = GComp(val);
b = BComp(val);
if( col )
{ OutputEPSFByte( r );
OutputEPSFByte( g );
OutputEPSFByte( b );
} else
{ i = (20*r + 32*g + 12*b)>>6;
OutputEPSFByte( i );
}
}
int WriteEPSFFile( name, col, compr )
char *name; int col, compr;
{
register int x, y, i, j;
register int xsize, ysize;
register int xpos, ypos;
register int rotpage;
register Pixel __huge *ptr;
int RLEBuffer[128];
OutFile = fopen(name,"w");
if( !OutFile )
{ FatalOutputError(name);
return(False);
}
CalcInvColourMap();
if( XRange <= YRange )
{ rotpage = False;
xsize = XRange;
ysize = YRange;
} else
{ rotpage = True;
xsize = YRange;
ysize = XRange;
}
if( xsize > (int)(BORDER*PAGEWIDE) )
{ ysize = (int)(ysize*(BORDER*PAGEWIDE)/xsize);
xsize = (int)(BORDER*PAGEWIDE);
}
if( ysize > (int)(BORDER*PAGEHIGH) )
{ xsize = (int)(xsize*(BORDER*PAGEHIGH)/ysize);
ysize = (int)(BORDER*PAGEHIGH);
}
xpos = (int)(PAGEWIDE-xsize)/2;
ypos = (int)(PAGEHIGH-ysize)/2;
fputs("%!PS-Adobe-2.0 EPSF-2.0\n",OutFile);
fputs("%%Creator: RasMol Version 2.6\n",OutFile);
fprintf(OutFile,"%%%%Title: %s\n",name);
fprintf(OutFile,"%%%%BoundingBox: %d %d ",xpos,ypos);
fprintf(OutFile,"%d %d\n",xpos+xsize,ypos+ysize);
fputs("%%Pages: 1\n",OutFile);
fputs("%%EndComments\n",OutFile);
fputs("%%EndProlog\n",OutFile);
fputs("%%Page: 1 1\n",OutFile);
fputs("gsave\n",OutFile);
fputs("10 dict begin\n",OutFile);
fprintf(OutFile,"%d %d translate\n",xpos,ypos);
fprintf(OutFile,"%d %d scale\n",xsize,ysize);
if( rotpage )
{ fputs("0.5 0.5 translate\n",OutFile);
fputs("90 rotate\n",OutFile);
fputs("-0.5 -0.5 translate\n",OutFile);
}
fputc('\n',OutFile);
if( compr )
{ fputs("/rlecount 0 def\n",OutFile);
fputs("/rlebyte 1 string def\n",OutFile);
fprintf(OutFile,"/pixbuf %d string def\n", col?3:1 );
fputs("/reppixel { pixbuf } def\n",OutFile);
fputs("/getpixel { \n",OutFile);
fputs(" currentfile pixbuf readhexstring pop\n",OutFile);
fputs("} def\n\n",OutFile);
if( col )
{ fputs("/colorimage where {\n",OutFile);
fputs(" pop\n",OutFile);
fputs("} {\n",OutFile);
fputs(" /bytebuf 1 string def\n",OutFile);
fputs(" /colorimage { pop pop image } def\n",OutFile);
fputs(" /reppixel { bytebuf } def\n",OutFile);
fputs(" /getpixel {\n",OutFile);
fputs(" currentfile pixbuf readhexstring pop pop\n",OutFile);
fputs(" bytebuf 0\n",OutFile);
fputs(" pixbuf 0 get 20 mul\n",OutFile);
fputs(" pixbuf 1 get 32 mul\n",OutFile);
fputs(" pixbuf 2 get 12 mul\n",OutFile);
fputs(" add add -6 bitshift put bytebuf\n",OutFile);
fputs(" } def\n",OutFile);
fputs("} ifelse\n\n",OutFile);
}
fputs("/rledecode {\n",OutFile);
fputs(" rlecount 0 eq {\n",OutFile);
fputs(" currentfile rlebyte readhexstring pop\n",OutFile);
fprintf(OutFile," 0 get dup %d gt {\n",EPSFCompRatio);
fprintf(OutFile," /rlecount exch %d sub def\n",EPSFCompRatio);
fputs(" /rleflag true def\n",OutFile);
fputs(" } {\n",OutFile);
fputs(" /rlecount exch def\n",OutFile);
fputs(" /rleflag false def\n",OutFile);
fputs(" } ifelse getpixel\n",OutFile);
fputs(" } {\n",OutFile);
fputs(" /rlecount rlecount 1 sub def\n",OutFile);
fputs(" rleflag { reppixel } { getpixel } ifelse\n",OutFile);
fputs(" } ifelse\n",OutFile);
fputs("} def\n",OutFile);
} else if( col )
{ fprintf(OutFile,"/scanbuf %d string def\n",XRange*3);
fputs("/colorimage where {\n",OutFile);
fputs(" pop\n",OutFile);
fputs("} {\n",OutFile);
fputs(" /pixbuf 3 string def\n",OutFile);
fputs(" /bytebuf 1 string def\n",OutFile);
fputs(" /colorimage {\n",OutFile);
fputs(" pop pop pop {\n",OutFile);
fputs(" currentfile pixbuf readhexstring pop pop\n",OutFile);
fputs(" bytebuf 0\n",OutFile);
fputs(" pixbuf 0 get 20 mul\n",OutFile);
fputs(" pixbuf 1 get 32 mul\n",OutFile);
fputs(" pixbuf 2 get 12 mul\n",OutFile);
fputs(" add add -6 bitshift put bytebuf\n",OutFile);
fputs(" } image\n",OutFile);
fputs(" } def\n",OutFile);
fputs("} ifelse\n\n",OutFile);
} else fprintf(OutFile,"/scanbuf %d string def\n\n",XRange);
fprintf(OutFile,"%d %d %d\n",XRange,YRange,8);
fprintf(OutFile,"[%d 0 0 -%d 0 %d]\n",XRange,YRange,YRange);
if( !compr )
{ fputs("{ currentfile scanbuf readhexstring pop }\n",OutFile);
} else fputs("{ rledecode }\n",OutFile);
if( col ) fputs("false 3 color",OutFile);
fputs("image\n",OutFile);
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifndef INVERT
ptr = FBuffer;
#endif
RLELength = 0;
LineLength = 0;
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
{ i = *ptr++;
if( compr )
{ if( RLELength )
{ if( RLEEncode )
{ if( (RLEPixel!=i) || (RLELength==256-EPSFCompRatio) )
{ OutputEPSFByte(RLELength+EPSFCompRatio-1);
EncodeEPSFPixel(RLEPixel,col);
RLEEncode = False;
RLEBuffer[0] = i;
RLELength = 1;
} else RLELength++;
} else if( RLEBuffer[RLELength-1] == i )
{ if( RLELength>1 )
{ OutputEPSFByte(RLELength-2);
for( j=0; j<RLELength-1; j++ )
EncodeEPSFPixel(RLEBuffer[j],col);
}
RLEEncode = True;
RLELength = 2;
RLEPixel = i;
} else if( RLELength == EPSFCompRatio+1 )
{ OutputEPSFByte(EPSFCompRatio);
for( j=0; j<RLELength; j++ )
EncodeEPSFPixel(RLEBuffer[j],col);
RLEEncode = False;
RLEBuffer[0] = i;
RLELength = 1;
} else RLEBuffer[RLELength++] = i;
} else
{ RLEEncode = False;
RLEBuffer[0] = i;
RLELength = 1;
}
} else EncodeEPSFPixel( i, col );
}
}
if( compr && RLELength )
{ if( RLEEncode )
{ OutputEPSFByte(RLELength+EPSFCompRatio-1);
EncodeEPSFPixel(RLEPixel,col);
} else
{ OutputEPSFByte(RLELength-1);
for( j=0; j<RLELength; j++ )
EncodeEPSFPixel(RLEBuffer[j],col);
}
}
if( LineLength )
fputc('\n',OutFile);
fputs("end\n",OutFile);
fputs("grestore\n",OutFile);
fputs("showpage\n",OutFile);
fputs("%%Trailer\n",OutFile);
fputs("%%EOF\n",OutFile);
fclose( OutFile );
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'vgrd','TEXT',134);
#endif
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( True );
}
/* Flush AbsMode buffer */
static void FlushBMPBuffer()
{
if( RLEOutput )
{ WriteByte(0x00);
WriteByte(PacketLen);
fwrite((char*)Buffer,1,PacketLen,OutFile);
if( PacketLen%2 ) WriteByte(0x00);
} else
RLEFileSize += (PacketLen%2)+PacketLen+2;
PacketLen = 0;
}
/* Flush RLEMode buffer */
static void FlushBMPPackets()
{
register int i;
if( PacketLen )
FlushBMPBuffer();
if( RLEOutput )
{ for( i=0; i<BMPCount; i++ )
{ WriteByte(BMPBuffer[i].len);
WriteByte(BMPBuffer[i].ch);
}
} else RLEFileSize += (BMPCount<<1);
BMPCount = BMPTotal = 0;
}
static void ProcessBMPPacket()
{
register int cost;
register int i,j;
BMPBuffer[BMPCount].len = RLELength;
BMPBuffer[BMPCount].ch = RLEChar;
BMPTotal += RLELength;
RLELength = 0;
BMPCount++;
/* RLEMode is more efficient */
if( BMPTotal > BMPCount+5 )
{ FlushBMPPackets();
return;
}
/* Flush AbsMode buffer */
if( PacketLen+BMPTotal>255 )
FlushBMPBuffer();
/* Cannot leave RLEMode */
if( PacketLen+BMPTotal<3 )
return;
/* Determine AbsMode cost */
if( PacketLen )
{ cost = BMPTotal - (PacketLen%2);
cost += (cost%2);
} else cost = (BMPTotal%2)+BMPTotal+2;
/* Put RLE Packets into AbsMode buffer */
if( cost <= (int)(BMPCount<<1) )
{ for( i=0; i<BMPCount; i++ )
for( j=0; j<(int)BMPBuffer[i].len; j++ )
Buffer[PacketLen++] = BMPBuffer[i].ch;
BMPCount = BMPTotal = 0;
}
}
/* Collect pixels into RLE Packets */
static void WriteBMPCode( val )
int val;
{
if( !RLELength )
{ RLELength = 1;
RLEChar = val;
} else
if( (RLEChar!=val) || (RLELength==255) )
{ ProcessBMPPacket();
RLELength = 1;
RLEChar = val;
} else
RLELength++;
}
static void WriteBMPData( output )
int output;
{
register Pixel __huge *ptr;
register int x,y;
RLEOutput = output;
RLEFileSize = 0; BMPCount = 0;
RLELength = 0; BMPTotal = 0;
PacketLen = 0;
#ifdef INVERT
ptr = FBuffer;
#endif
for( y=YRange-1; y>=0; y-- )
{
#ifndef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
WriteBMPCode(LutInv[*ptr++]);
for( x=0; x<BMPPad; x++ )
WriteBMPCode(0x00);
/* Flush RLE codes */
ProcessBMPPacket();
FlushBMPPackets();
if( RLEOutput )
{ /* End of line code */
WriteByte(0x00);
WriteByte(y?0x00:0x01);
} else RLEFileSize += 2;
}
}
int WriteBMPFile( name )
char *name;
{
register Pixel __huge *ptr;
register int x,y,i,raw;
register Card size;
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
#ifdef EIGHTBIT
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
CalcInvColourMap();
/* zero-pad scanlines to long */
BMPPad = XRange%4;
if( BMPPad )
BMPPad = 4-BMPPad;
WriteBMPData(False);
size = (Long)(XRange+BMPPad)*YRange;
if( RLEFileSize<size )
{ size = RLEFileSize;
raw = False;
} else raw = True;
WriteByte('B');
WriteByte('M');
WriteLSBLong(size+1078);
WriteLSBLong((Card)0);
WriteLSBLong((Card)1078);
WriteLSBLong((Card)40);
WriteLSBLong((Card)XRange);
WriteLSBLong((Card)YRange);
WriteByte(0x01); WriteByte(0x00);
WriteByte(0x08); WriteByte(0x00);
WriteLSBLong(raw? (Card)0 : (Card)1);
WriteLSBLong(size);
WriteLSBLong((Card)0);
WriteLSBLong((Card)0);
WriteLSBLong((Card)256);
WriteLSBLong((Card)256);
for( i=0; i<256; i++ )
{ WriteByte(BLut[i]);
WriteByte(GLut[i]);
WriteByte(RLut[i]);
WriteByte(0x00);
}
if( raw )
{
#ifdef INVERT
ptr = FBuffer;
#endif
for( y=YRange-1; y>=0; y-- )
{
#ifndef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
for( x=0; x<XRange; x++ )
WriteByte(LutInv[*ptr++]);
for( x=0; x<BMPPad; x++ )
WriteByte(0x00);
WriteByte(0x00);
WriteByte(y?0x00:0x01);
}
} else
WriteBMPData(True);
fclose(OutFile);
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'\?\?\?\?','\?\?\?\?',134);
#endif
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return(True);
#else
if( CommandActive ) WriteChar('\n');
WriteString("Output Error: 24 bit BMP files unsupported!\n");
CommandActive = False;
return( False );
#endif
}
#ifdef FUNCPROTO
static int FindDepth( PSItemPtr, int );
static void DepthSort( PSItemPtr __far*, char __far*, int );
#endif
static int FindDepth( item, type )
PSItemPtr item; int type;
{
register HBond __far *hbond;
register Atom __far *atom;
register Bond __far *bond;
register int result;
switch( type )
{ case(PSAtom): atom = (Atom __far*)item;
return( atom->z );
case(PSBond): bond = (Bond __far*)item;
result = bond->srcatom->z;
if( result < bond->dstatom->z )
result = bond->dstatom->z;
return( result );
case(PSSSBond):
case(PSHBond): hbond = (HBond __far*)item;
if( (type==PSHBond)? HBondMode : SSBondMode )
{ result = hbond->srcCA->z;
if( result < hbond->dstCA->z )
result = hbond->dstCA->z;
} else
{ result = hbond->src->z;
if( result < hbond->dst->z )
result = hbond->dst->z;
}
return( result );
}
return( 0 );
}
static void DepthSort( data, type, count )
PSItemPtr __far *data;
char __far *type;
int count;
{
register char ttmp;
register void __far *dtmp;
register int i, j, k;
register int depth;
register int temp;
for( i=1; i<count; i++ )
{ dtmp = data[i];
ttmp = type[i];
j = i-1;
depth = FindDepth(dtmp,ttmp);
temp = FindDepth(data[j],type[j]);
while( (depth<temp) || ((depth==temp)&&(ttmp<type[j])) )
if( j-- )
{ temp = FindDepth(data[j],type[j]);
} else break;
j++;
if( j != i )
{ for( k=i; k>j; k-- )
{ data[k] = data[k-1];
type[k] = type[k-1];
}
data[j] = dtmp;
type[j] = ttmp;
}
}
}
#ifdef FUNCPROTO
static int ClipVectSphere( Atom __far* );
static int ClipVectBond( Atom __far*, Atom __far* );
static void WriteVectSphere( PSItemPtr __far*, char __far*, int );
static void WriteVectStick( Atom __far*, Atom __far*, int, int );
static void WriteVectWire( Atom __far*, Atom __far*, int, int );
static Long CountPSItems();
static void FetchPSItems( PSItemPtr __far*, char __far* );
static void WritePSItems( PSItemPtr __far*, char __far*, int );
#endif
static int ClipVectSphere( ptr )
Atom __far *ptr;
{
register int rad;
rad = ptr->irad;
if( ptr->x + rad < 0 ) return( True );
if( ptr->y + rad < 0 ) return( True );
if( ptr->x - rad >= XRange ) return( True );
if( ptr->y - rad >= YRange ) return( True );
return( False );
}
static int ClipVectBond( src, dst )
Atom __far *src;
Atom __far *dst;
{
if( !src || !dst ) return( True );
if( (src->x<0) && (dst->x<0) ) return( True );
if( (src->y<0) && (dst->y<0) ) return( True );
if( (src->x>=XRange) && (dst->x>=XRange) ) return( True );
if( (src->y>=YRange) && (dst->y>=YRange) ) return( True );
return( False );
}
static void WriteVectColour( col )
int col;
{
if( col != VectCol )
{ fprintf(OutFile,"%g ",(Real)RLut[col]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[col]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[col]/255.0);
fputs("setrgbcolor\n",OutFile);
VectCol = col;
}
}
#define MAXSECT 5
typedef struct {
/* Ellipse */
Real ephi,epsi;
Real etheta;
Real ex,ey;
Real erad;
/* Sphere */
Real sphi,spsi;
int sx,sy;
Real srad;
} SphereSect;
static int VectClipContain( x, y )
SphereSect *x; SphereSect *y;
{
if( x->erad != 0.0 )
{ if( y->erad != 0.0 )
/* Simple segment containment test! */
return( ((x->sphi+x->spsi)>=(y->sphi+y->spsi)) &&
((x->sphi-x->spsi)<=(y->sphi-y->spsi)) );
} else if( y->erad == 0.0 )
return( x->srad >= y->srad );
return( False );
}
static void WriteVectSphere( data, type, index )
PSItemPtr __far*data;
char __far *type;
int index;
{
register int ecount, count;
register Atom __far *atm;
register Atom __far *ptr;
register Long dist2,dist3;
register int dx, dy, dz;
register int i,j,k;
register Real b,d,f,g,x;
register Real radf,radb;
register Real phi1,phi2;
register Real temp,psi;
register Real theta;
register SphereSect *sptr;
SphereSect sect[MAXSECT];
ptr = (Atom __far*)data[index];
radf = ptr->radius*Scale;
count = 0;
ecount = 0;
sptr = sect;
for( i=index-1; i>=0; i-- )
{ if( type[i] != PSAtom )
continue;
atm = (Atom __far*)data[i];
/* Atom can't intersect visibly! */
if( atm->z + atm->irad < ptr->z )
continue;
dx = atm->x - ptr->x;
dy = atm->y - ptr->y;
dz = atm->z - ptr->z;
dist2 = (Long)dx*dx + (Long)dy*dy;
dist3 = dist2 + dz*dz;
radb = atm->radius*Scale;
temp = radf + radb;
/* Atoms don't intersect! */
if( dist3 > temp*temp ) continue;
d = sqrt( (double)dist3 );
f = (temp*(radf-radb)+dist3)/(2.0*d);
theta = -dz/d;
if( f>0 )
{ temp = radf*radf;
/* Intersection not visible! */
if( theta*temp > temp-f*f )
continue;
} else if( f < -radf )
return;
x = sqrt( (radf-f)*(radf+f) );
if( dx || dy )
{ g = sqrt( (double)dist2 );
psi = Rad2Deg*atan2(dy,dx);
b = (f*(dz*dz))/(d*g);
if( AbsFun(b)>x )
continue;
phi1 = b + (f*g)/d;
phi1 = Rad2Deg*acos(phi1/radf);
if( phi1!=phi1 ) continue;
phi2 = (d*b)/g;
if( AbsFun(phi2) < x )
{ phi2 = Rad2Deg*acos(phi2/x);
if( phi2!=phi2 ) continue;
if( phi2 > 90.0 )
phi2 = 180.0-phi1;
} else phi2 = 90.0;
sptr->erad = x;
sptr->etheta = -theta;
sptr->ephi = psi;
sptr->epsi = phi2;
temp = f/d;
sptr->ex = ptr->x+temp*dx;
sptr->ey = ptr->y+temp*dy;
sptr->srad = radf;
sptr->sphi = psi;
sptr->spsi = phi1;
sptr->sx = ptr->x;
sptr->sy = ptr->y;
} else
{ x = sqrt( (radf-g)*(radf+g) );
sptr->srad = x;
sptr->erad = 0.0;
sptr->sx = ptr->x;
sptr->sy = ptr->y;
sptr->sphi = 180;
sptr->spsi = -180;
}
/* Optimize Segments */
j = 0;
while( j<count )
if( VectClipContain(sptr,sect+j) )
{ /* Delete Segment sect[j] */
for( k=j; k<count; k++ )
sect[k] = sect[k+1];
count--; sptr--;
} else if( VectClipContain(sect+j,sptr) )
{ break; /* Exclude Segment */
} else j++;
if( j==count )
{ count++; sptr++;
if( sptr->erad != 0.0 )
ecount++;
if( count==MAXSECT )
break;
}
}
if( UseOutLine )
{ temp = (ptr->z-ZOffset)/ImageSize + 1.0;
if( temp != LineWidth )
{ fprintf(OutFile,"%g setlinewidth\n",temp);
LineWidth = temp;
}
}
if( !VectSolid )
{ fputs("[] 0 setdash\n",OutFile);
VectSolid = True;
}
if( count )
{ fputs("gsave\n",OutFile);
fprintf(OutFile,"%%%% %d %d\n",count,ecount);
sptr = sect;
for( i=0; i<count; i++ )
{ if( sptr->erad != 0.0 )
{ fprintf(OutFile,"%g %g %g %g %g %g ClipEllips\n",
sptr->erad,sptr->epsi,sptr->etheta,
sptr->ephi,sptr->ex,sptr->ey);
}
if( (i==count-1) || (sptr->erad==0.0) )
{ fprintf(OutFile,"%g %g %g %d %d ClipSphere\n",sptr->srad,
sptr->sphi+sptr->spsi,sptr->sphi-sptr->spsi,
sptr->sx, sptr->sy );
} else fprintf(OutFile,"%g %g %g %d %d ClipBox\n",
sptr->srad+sptr->srad+2,
sptr->srad+1, sptr->ephi,
sptr->sx, sptr->sy );
sptr++;
}
i = ptr->col + ColourMask;
fprintf(OutFile,"%g ",(Real)RLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[i]/255.0);
fprintf(OutFile,"%g Shade\n",radf);
fputs("grestore\n\n",OutFile);
} else
{ i = ptr->col + ColourMask;
fprintf(OutFile,"%g ",(Real)RLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[i]/255.0);
fprintf(OutFile,"%g %d %d ",radf,ptr->x,ptr->y);
fputs("Sphere\n\n",OutFile);
}
}
static void WriteVectWire( src, dst, col, dash )
Atom __far *src;
Atom __far *dst;
int col, dash;
{
register Atom __far *tmp;
register Real radius;
register Real temp;
register Real dist;
register Real midx, midy;
register Real endx, endy;
register int col1, col2;
register int dx, dy, dz;
register Long dist2;
if( src->z > dst->z )
{ tmp = src;
src = dst;
dst = tmp;
}
if( !col )
{ col1 = src->col;
col2 = dst->col;
} else col1 = col2 = col;
dx = dst->x - src->x;
dy = dst->y - src->y;
dist2 = dx*dx + dy*dy;
dist = sqrt( (double)dist2 );
if( dst->flag & SphereFlag )
{ radius = dst->radius*Scale;
if( dist <= radius ) return;
/* Test for second half obscured! */
if( (col1!=col2) && (0.5*dist < radius) )
col2 = col1;
}
if( src->flag & SphereFlag )
{ radius = src->radius*Scale;
if( dist <= radius ) return;
/* Test for first half obscured! */
if( (col1!=col2) && (0.5*dist < radius) )
col1 = col2;
}
WriteVectColour( col1+ColourMask );
temp = ((src->z-ZOffset)+(dst->z-ZOffset))/ImageSize + 1.0;
if( temp != LineWidth )
{ fprintf(OutFile,"%g setlinewidth\n",temp);
LineWidth = temp;
}
if( dash )
{ if( VectSolid )
{ fputs("[3 3] 0 setdash\n",OutFile);
VectSolid = False;
}
} else
if( !VectSolid )
{ fputs("[] 0 setdash\n",OutFile);
VectSolid = True;
}
if( src->flag & SphereFlag )
{ dz = dst->z - src->z;
dist = sqrt( (double)(dist2 + dz*dz) );
endx = src->x + (radius*dx)/dist;
endy = src->y + (radius*dy)/dist;
fprintf(OutFile,"%g %g ",endx,endy);
} else
fprintf(OutFile,"%d %d ",src->x,src->y);
if( col1 != col2 )
{ midx = 0.5*(src->x + dst->x);
midy = 0.5*(src->y + dst->y);
fprintf(OutFile,"%g %g Wire\n",midx,midy);
WriteVectColour( col2+ColourMask );
fprintf(OutFile,"%g %g ",midx,midy);
}
fprintf(OutFile,"%d %d Wire\n",dst->x,dst->y);
}
static void WriteVectStick( src, dst, col, rad )
Atom __far *src;
Atom __far *dst;
int col, rad;
{
register Atom __far *tmp;
register Real midx, midy;
register Real relx, rely;
register Real endx, endy;
register Real radius, angle;
register Real dist, dist3;
register Real temp, ratio;
register Long dist2;
register int dx, dy, dz;
register int col1, col2;
register int i, inten;
if( !rad )
{ WriteVectWire(src,dst,col,False);
return;
}
if( src->z > dst->z )
{ tmp = src;
src = dst;
dst = tmp;
}
if( !col )
{ col1 = src->col;
col2 = dst->col;
} else col1 = col2 = col;
dx = dst->x - src->x;
dy = dst->y - src->y;
dz = dst->z - src->z;
dist2 = dx*dx + dy*dy;
dist3 = sqrt( (double)(dist2 + dz*dz) );
dist = sqrt( (double)dist2 );
if( dst->flag & SphereFlag )
{ radius = dst->radius*Scale;
if( dist <= radius ) return;
/* Test for nearest half obscured! */
if( (col1!=col2) && (0.5*dist < radius) )
col2 = col1;
}
if( src->flag & SphereFlag )
{ radius = src->radius*Scale;
if( dist <= radius ) return;
/* Test for furthest half obscured! */
if( (col1!=col2) && (0.5*dist < radius) )
col1 = col2;
}
if( !VectSolid )
{ fputs("[] 0 setdash\n",OutFile);
VectSolid = True;
}
temp = ((src->z-ZOffset)+(dst->z-ZOffset))/ImageSize + 1.0;
if( temp != LineWidth )
{ fprintf(OutFile,"%g setlinewidth\n",temp);
LineWidth = temp;
}
radius = rad*Scale;
angle = Rad2Deg*atan2((double)dy,(double)dx);
inten = (int)((dist/dist3)*ColourMask);
if( col1 != col2 )
{ midx = 0.5*(src->x + dst->x);
midy = 0.5*(src->y + dst->y);
relx = (radius*dx)/dist;
rely = (radius*dy)/dist;
fprintf(OutFile,"%g %g moveto\n",midx+rely,midy-relx);
fprintf(OutFile,"%g %g lineto\n",midx-rely,midy+relx);
ratio = dz/dist3;
if( (src->flag&SphereFlag) && (src->radius>rad) )
{ temp = (Scale*src->radius)/dist3;
endx = src->x + temp*dx;
endy = src->y + temp*dy;
fprintf(OutFile,"%g %g %g ",radius,ratio,angle);
fprintf(OutFile,"%g %g StickEnd\n",endx,endy);
} else
{ fprintf(OutFile,"%d %d %g ",src->x,src->y,radius);
fprintf(OutFile,"%g %g arc\n",angle+90,angle-90);
}
fputs("closepath ",OutFile);
i = col1 + inten;
fprintf(OutFile,"%g ",(Real)RLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[i]/255.0);
fputs("setrgbcolor fill\n",OutFile);
fprintf(OutFile,"%d %d %g ",dst->x,dst->y,radius);
fprintf(OutFile,"%g %g arc\n",angle-90,angle+90);
fprintf(OutFile,"%g %g %g ",radius,ratio,angle);
fprintf(OutFile,"%g %g StickEnd\n",midx,midy);
fputs("closepath ",OutFile);
i = col2 + inten;
fprintf(OutFile,"%g ",(Real)RLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[i]/255.0);
fputs("setrgbcolor fill\n",OutFile);
if( UseOutLine )
{ fprintf(OutFile,"%d %d %g ",dst->x,dst->y,radius);
fprintf(OutFile,"%g %g arc\n",angle-90,angle+90);
if( (src->flag&SphereFlag) && (src->radius>rad) )
{ fprintf(OutFile,"%g %g %g ",radius,ratio,angle);
fprintf(OutFile,"%g %g StickEnd\n",endx,endy);
} else
{ fprintf(OutFile,"%d %d %g ",src->x,src->y,radius);
fprintf(OutFile,"%g %g arc\n",angle+90,angle-90);
}
fputs("closepath 0 setgray stroke\n",OutFile);
}
} else /* col1 == col2! */
{ fprintf(OutFile,"%d %d %g ",dst->x,dst->y,radius);
fprintf(OutFile,"%g %g arc\n",angle-90,angle+90);
if( (src->flag&SphereFlag) && (src->radius>rad) )
{ temp = (Scale*src->radius)/dist3;
endx = src->x + temp*dx;
endy = src->y + temp*dy;
ratio = dz/dist3;
fprintf(OutFile,"%g %g %g ",radius,ratio,angle);
fprintf(OutFile,"%g %g StickEnd\n",endx,endy);
} else
{ fprintf(OutFile,"%d %d %g ",src->x,src->y,radius);
fprintf(OutFile,"%g %g arc\n",angle+90,angle-90);
}
i = col1 + inten;
fprintf(OutFile,"%g ",(Real)RLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)GLut[i]/255.0);
fprintf(OutFile,"%g ",(Real)BLut[i]/255.0);
fputs("Stick\n",OutFile);
}
VectCol = 0;
}
static void WriteVectDots()
{
register DotStruct __far *ptr;
register Real x,y,z;
register Real xi,yi;
register int inten;
register int temp;
register int zi;
register int i;
if( LineWidth != 1.0 )
{ fputs("1 setlinewidth\n",OutFile);
LineWidth = 1.0;
}
temp = SlabValue - ZOffset;
for( ptr=DotPtr; ptr; ptr=ptr->next )
for( i=0; i<ptr->count; i++ )
{ x = ptr->xpos[i];
y = ptr->ypos[i];
z = ptr->zpos[i];
xi = (x*MatX[0]+y*MatX[1]+z*MatX[2]) + XOffset;
if( (xi<0.0) || (xi>=XRange) ) continue;
yi = (x*MatY[0]+y*MatY[1]+z*MatY[2]) + YOffset;
if( (yi<0.0) || (yi>=YRange) ) continue;
zi = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2]);
if( UseSlabPlane && (zi>=temp) ) continue;
inten = (ColourDepth*(zi+ImageRadius))/ImageSize;
WriteVectColour( ptr->col[i]+inten );
fprintf(OutFile,"%g %g Dot\n",xi,yi);
}
}
static void WriteVectLabels()
{
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
register Label *label;
auto char buffer[80];
fputs("/Times-Roman",OutFile); /* Courier or Courier-Bold? */
fprintf(OutFile," findfont %d scalefont setfont\n",FontSize<<1);
if( UseLabelCol )
{ if( BackR || BackG || BackB )
{ fprintf(OutFile,"%g %g %g setrgbcolor\n",
LabR/250.0, LabG/250.0, LabB/250.0);
} else fputs("0 setgray\n",OutFile);
} else VectCol = 0;
ForEachAtom
if( aptr->label )
{ if( !UseLabelCol && (aptr->col!=VectCol) )
WriteVectColour( aptr->col );
label = (Label*)aptr->label;
FormatLabel(chain,group,aptr,label->label,buffer);
fprintf(OutFile,"(%s) %d %d Label\n",buffer,aptr->x,aptr->y);
}
}
static Long CountPSItems()
{
register Chain __far *chain;
register Group __far *group;
register HBond __far *hptr;
register Bond __far *bptr;
register Atom __far *aptr;
register Long result;
result = 0;
if( DrawAtoms )
ForEachAtom
if( aptr->flag&SphereFlag )
if( !UseClipping || !ClipVectSphere(aptr) )
result++;
if( DrawBonds )
ForEachBond
if( bptr->flag&DrawBondFlag && (!UseClipping ||
!ClipVectBond(bptr->srcatom,bptr->dstatom)) )
result++;
ForEachBack
if( bptr->flag&DrawBondFlag && (!UseClipping ||
!ClipVectBond(bptr->srcatom,bptr->dstatom)) )
result++;
for( hptr=Database->hlist; hptr; hptr=hptr->hnext )
if( hptr->flag&DrawBondFlag )
{ if( HBondMode )
{ if( !ClipVectBond(hptr->srcCA,hptr->dstCA) )
result++;
} else if( !ClipVectBond(hptr->src,hptr->dst) )
result++;
}
for( hptr=Database->slist; hptr; hptr=hptr->hnext )
if( hptr->flag&DrawBondFlag )
{ if( SSBondMode )
{ if( !ClipVectBond(hptr->srcCA,hptr->dstCA) )
result++;
} else if( !ClipVectBond(hptr->src,hptr->dst) )
result++;
}
return( result );
}
static void FetchPSItems( data, type )
PSItemPtr __far *data;
char __far *type;
{
register Chain __far *chain;
register Group __far *group;
register HBond __far *hptr;
register Bond __far *bptr;
register Atom __far *aptr;
register int i,flag;
i = 0;
if( DrawAtoms )
ForEachAtom
if( aptr->flag&SphereFlag )
if( !UseClipping || !ClipVectSphere(aptr) )
{ type[i] = PSAtom;
data[i++] = aptr;
}
if( DrawBonds )
ForEachBond
if( bptr->flag&DrawBondFlag && (!UseClipping ||
!ClipVectBond(bptr->srcatom,bptr->dstatom)) )
{ type[i] = PSBond;
data[i++] = bptr;
}
ForEachBack
if( bptr->flag&DrawBondFlag && (!UseClipping ||
!ClipVectBond(bptr->srcatom,bptr->dstatom)) )
{ type[i] = PSBond;
data[i++] = bptr;
}
for( hptr=Database->hlist; hptr; hptr=hptr->hnext )
if( hptr->flag&DrawBondFlag )
{ if( HBondMode )
{ flag = !ClipVectBond(hptr->srcCA,hptr->dstCA);
} else flag = !ClipVectBond(hptr->src,hptr->dst);
if( flag )
{ type[i] = PSHBond;
data[i++] = hptr;
}
}
for( hptr=Database->slist; hptr; hptr=hptr->hnext )
if( hptr->flag&DrawBondFlag )
{ if( SSBondMode )
{ flag = !ClipVectBond(hptr->srcCA,hptr->dstCA);
} else flag = !ClipVectBond(hptr->src,hptr->dst);
if( flag )
{ type[i] = PSSSBond;
data[i++] = hptr;
}
}
}
static void WritePSItems( data, type, count )
PSItemPtr __far *data;
char __far *type;
int count;
{
register HBond __far *hbond;
register Bond __far *bond;
register Atom __far *src;
register Atom __far *dst;
register int i;
for( i=0; i<count; i++ )
switch( type[i] )
{ case(PSAtom): WriteVectSphere(data,type,i);
break;
case(PSBond): bond = (Bond __far*)data[i];
src = bond->srcatom;
dst = bond->dstatom;
if( bond->flag & WireFlag )
{ WriteVectWire(src,dst,bond->col,False);
} else if( bond->flag & CylinderFlag )
{ WriteVectStick(src,dst,bond->col,bond->radius);
} else /* bond->flag & DashFlag */
WriteVectWire(src,dst,bond->col,True);
break;
case(PSSSBond):
case(PSHBond): hbond = (HBond __far*)data[i];
if( (type[i]==PSHBond)? HBondMode : SSBondMode )
{ src = hbond->srcCA;
dst = hbond->dstCA;
} else
{ src = hbond->src;
dst = hbond->dst;
}
if( hbond->flag & WireFlag )
{ WriteVectWire(src,dst,hbond->col,True);
} else /* bond->flag & CylinderFlag */
WriteVectStick(src,dst,hbond->col,
hbond->radius);
break;
}
}
int WriteVectPSFile( name )
char *name;
{
register Real ambi;
register Real temp, inten;
register int xsize, ysize;
register int xpos, ypos;
register Long count;
register int i;
PSItemPtr __far *data;
char __far *type;
count = CountPSItems();
if( !count ) return( True );
#ifdef IBMPC
if( count > 16383 )
{ if( CommandActive ) WriteChar('\n');
WriteString("Output Error: Too many PostScript objects!\n");
CommandActive = False;
return( False );
}
#endif
/* Allocate arrays for objects! */
data = (PSItemPtr __far*)_fmalloc((size_t)count*sizeof(PSItemPtr));
type = (char __far*)_fmalloc((size_t)count*sizeof(char));
if( !data || !type )
{ if( CommandActive ) WriteChar('\n');
WriteString("Output Error: Not enough memory to create PostScript!\n");
CommandActive = False;
if( data ) _ffree( data );
if( type ) _ffree( type );
return( False );
}
OutFile = fopen(name,"w");
if( !OutFile )
{ FatalOutputError(name);
return(False);
}
/* Determine the size of the image */
ysize = (int)(YRange*(BORDER*PAGEWIDE)/XRange);
if( ysize > (int)(BORDER*PAGEHIGH) )
{ xsize = (int)(XRange*(BORDER*PAGEHIGH)/YRange);
ysize = (int)(BORDER*PAGEHIGH);
} else xsize = (int)(BORDER*PAGEWIDE);
xpos = (int)(PAGEWIDE-xsize)/2;
ypos = (int)(PAGEHIGH-ysize)/2;
fputs("%!PS-Adobe-2.0 EPSF-2.0\n",OutFile);
fputs("%%Creator: RasMol Version 2.6\n",OutFile);
fprintf(OutFile,"%%%%Title: %s\n",name);
fprintf(OutFile,"%%%%BoundingBox: %d %d ",xpos,ypos);
fprintf(OutFile,"%d %d\n",xpos+xsize,ypos+ysize);
fputs("%%Pages: 1\n",OutFile);
fputs("%%EndComments\n",OutFile);
fputs("%%EndProlog\n",OutFile);
fputs("%%BeginSetup\n",OutFile);
fputs("1 setlinecap 1 setlinejoin [] 0 setdash\n",OutFile);
fputs("1 setlinewidth 0 setgray\n",OutFile);
fputs("%%EndSetup\n",OutFile);
fputs("%%Page: 1 1\n",OutFile);
fputs("gsave\n",OutFile);
fputs("14 dict begin\n\n",OutFile);
fputs("/handleerror { showpage } def\n\n",OutFile);
fputs("/Inten {\n dup 4 index mul exch\n",OutFile);
fputs(" dup 4 index mul exch\n",OutFile);
fputs(" 3 index mul setrgbcolor\n} def\n\n",OutFile);
fputs("/Dot {\n moveto 0 0 rlineto stroke\n} def\n\n",OutFile);
fputs("/Wire {\n moveto lineto stroke\n} def\n\n",OutFile);
#ifdef INVERT
fputs("/Label {\n moveto show\n} def\n\n",OutFile);
#else
fputs("/Label {\n moveto 1 -1 scale\n",OutFile);
fputs(" show mtrx setmatrix\n} def\n\n",OutFile);
#endif
if( UseOutLine )
{ fputs("/Stick {\n closepath gsave setrgbcolor fill\n",OutFile);
fputs(" grestore 0 setgray stroke\n} def\n\n",OutFile);
} else
fputs("/Stick {\n closepath setrgbcolor fill\n} def\n\n",OutFile);
fputs("/StickEnd {\n matrix currentmatrix 6 1 roll\n",OutFile);
fputs(" translate rotate 1 scale\n",OutFile);
fputs(" 0 0 3 2 roll 90 -90 arc\n setmatrix\n} def\n\n",OutFile);
if( UseOutLine )
{ fputs("/Shade {\n closepath gsave clip\n",OutFile);
} else fputs("/Shade {\n closepath clip\n",OutFile);
if( Ambient < 0.99 )
{ ambi = 0.5*Ambient;
fputs(" 45 rotate dup -0.81649658092 mul scale\n",OutFile);
fprintf(OutFile," %g Inten fill\n",ambi);
inten = (1.0-ambi)/31;
for( i=0; i<31; i++ )
{ temp = (Real)(i+1)/32;
fprintf(OutFile," 0 %g ",(Real)i/32);
fprintf(OutFile,"%g 0 360 arc ",sqrt(1.0-temp*temp));
fprintf(OutFile,"%g Inten fill\n",i*inten+ambi);
}
if( UseOutLine )
{ fputs(" grestore 0 setgray stroke",OutFile);
} else fputc(' ',OutFile);
fputs(" pop pop pop\n} def\n\n",OutFile);
} else /* Saturated Colours! */
{ fputs(" pop setrgbcolor fill\n",OutFile);
if( UseOutLine )
fputs(" grestore 0 setgray stroke\n",OutFile);
fputs("} def\n\n",OutFile);
}
fputs("/ClipSphere {\n translate 0 0 5 2 roll arc\n} def\n\n",OutFile);
fputs("/ClipBox {\n translate rotate\n dup lineto dup neg ",OutFile);
fputs("dup\n 0 rlineto 0 exch rlineto 0 rlineto closepath\n",OutFile);
fputs(" clip newpath mtrx setmatrix\n} def\n\n",OutFile);
fputs("/ClipEllips {\n translate rotate 1 scale\n",OutFile);
fputs(" 0 0 4 2 roll dup neg arc\n",OutFile);
fputs(" reversepath mtrx setmatrix\n} def\n\n",OutFile);
fputs("/Sphere {\n gsave\n",OutFile);
fputs(" translate 0 0 2 index 0 360 arc\n",OutFile);
if( UseOutLine )
{ fputs(" gsave Shade grestore\n",OutFile);
fputs(" 0 setgray stroke\n",OutFile);
fputs(" grestore\n} def\n\n",OutFile);
} else
fputs(" Shade grestore\n} def\n\n",OutFile);
#ifdef INVERT
fprintf(OutFile,"%d %d translate\n",xpos,ypos);
fprintf(OutFile,"%g ",(Real)xsize/XRange);
fprintf(OutFile,"%g ",(Real)ysize/YRange);
#else
fprintf(OutFile,"%d %d translate\n",xpos,ypos+ysize);
fprintf(OutFile,"%g ",(Real)xsize/XRange);
fprintf(OutFile,"%g ",(Real)-ysize/YRange);
#endif
fputs("scale\n/mtrx matrix currentmatrix def\n\n",OutFile);
fputs("newpath 0 0 moveto 0 ",OutFile);
fprintf(OutFile,"%d rlineto %d 0 rlineto 0 %d",YRange,XRange,-YRange);
fputs(" rlineto\nclosepath clip ",OutFile);
if( BackR || BackG || BackB )
{ fprintf(OutFile,"%g %g %g",BackR/255.0,BackG/255.0,BackB/255.0);
fputs(" setrgbcolor fill\n\n",OutFile);
} else fputs("newpath\n\n",OutFile);
LineWidth = 1.0;
VectSolid = True;
VectCol = 0;
FetchPSItems(data,type);
if( count>1 )
DepthSort(data,type,(int)count);
WritePSItems(data,type,(int)count);
if( !VectSolid )
{ fputs("[] 0 setdash\n",OutFile);
VectSolid = True;
}
if( DrawDots )
WriteVectDots();
if( DrawLabels )
WriteVectLabels();
fputs("newpath 0 0 moveto 0 ",OutFile);
fprintf(OutFile,"%d rlineto %d 0 rlineto 0 %d",YRange,XRange,-YRange);
fputs(" rlineto\nclosepath 0 setgray 1 setlinewidth stroke\n",OutFile);
fputs("end grestore\nshowpage\n",OutFile);
fputs("%%Trailer\n",OutFile);
fputs("%%EOF\n",OutFile);
fclose( OutFile );
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'vgrd','TEXT',134);
#endif
_ffree( data );
_ffree( type );
return(True);
}
static void FlushPICTBuffer()
{
if( PacketLen )
{ if( RLEOutput )
{ WriteByte(PacketLen-1);
fwrite((char*)Buffer,1,PacketLen,OutFile);
} else RLELineSize += PacketLen+1;
PacketLen = 0;
}
}
static void FlushPICTPacket()
{
register int i;
if( RLELength>2 )
{ FlushPICTBuffer();
if( RLEOutput )
{ WriteByte(257-RLELength);
WriteByte(RLEChar);
} else RLELineSize += 2;
} else
for( i=0; i<RLELength; i++ )
{ Buffer[PacketLen++] = RLEChar;
if( PacketLen == 128 )
FlushPICTBuffer();
}
}
static void WritePICTCode( val )
int val;
{
if( !RLELength )
{ RLEChar = val;
RLELength = 1;
} else if( (val!=RLEChar) || (RLELength==128) )
{ FlushPICTPacket();
RLEChar = val;
RLELength = 1;
} else RLELength++;
}
static void WritePICTData()
{
#ifndef EIGHTBIT
register Pixel data;
#endif
register Pixel __huge *ptr;
register Pixel __huge *tmp;
register int rowbytes;
register int x,y;
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifdef EIGHTBIT
rowbytes = XRange;
#else
rowbytes = XRange*3;
#endif
RLEFileSize = 0;
#ifndef INVERT
ptr = FBuffer;
#endif
for( y=YRange-1; y>=0; y-- )
{
#ifdef INVERT
ptr = FBuffer + (Long)y*XRange;
#endif
RLELineSize = 0;
RLEOutput = False;
PacketLen = 0;
RLELength = 0;
#ifdef EIGHTBIT
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( LutInv[*tmp++] );
#else
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( (int)RComp(*tmp++) );
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( (int)GComp(*tmp++) );
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( (int)BComp(*tmp++) );
#endif
FlushPICTPacket();
FlushPICTBuffer();
#ifdef EIGHTBIT
if( rowbytes > 250 )
{ WriteMSBShort(RLELineSize);
RLEFileSize += (RLELineSize+2);
} else
{ WriteByte(RLELineSize);
RLEFileSize += (RLELineSize+1);
}
#else
WriteMSBShort(RLELineSize);
RLEFileSize += (RLELineSize+2);
#endif
RLEOutput = True;
PacketLen = 0;
RLELength = 0;
#ifdef EIGHTBIT
for( x=0; x<XRange; x++ )
WritePICTCode( LutInv[*ptr++] );
#else
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( (int)RComp(*tmp++) );
tmp = ptr;
for( x=0; x<XRange; x++ )
WritePICTCode( (int)GComp(*tmp++) );
for( x=0; x<XRange; x++ )
WritePICTCode( (int)BComp(*ptr++) );
#endif
FlushPICTPacket();
FlushPICTBuffer();
}
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
}
int WritePICTFile( name )
char *name;
{
#ifdef EIGHTBIT
register int j,r,g,b;
#endif
register int cols;
register int i;
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
#ifdef EIGHTBIT
cols = CompactColourMap();
#endif
/* Write out header */
for( i=0; i<512; i++ )
WriteByte( 0x00 );
WriteMSBShort(0); /* picSize */
WriteMSBShort(0); /* picFrame.top */
WriteMSBShort(0); /* picFrame.left */
WriteMSBShort(YRange); /* picFrame.bottom */
WriteMSBShort(XRange); /* picFrame.right */
WriteMSBShort(PICTpicversion);
WriteMSBShort(0x02FF);
WriteMSBShort(PICTheaderop);
WriteMSBLong((Card)0xffffffff);
WriteMSBShort(0); WriteMSBShort(0);
WriteMSBShort(0); WriteMSBShort(0);
WriteMSBShort(XRange); WriteMSBShort(0);
WriteMSBShort(YRange); WriteMSBShort(0);
WriteMSBLong(0);
WriteMSBShort(PICTcliprgn);
WriteMSBShort(10); /* rgnSize */
WriteMSBShort(0); /* rgnBBox.top */
WriteMSBShort(0); /* rgnBBox.left */
WriteMSBShort(YRange); /* rgnBBox.bottom */
WriteMSBShort(XRange); /* rgnBBox.right */
#ifdef EIGHTBIT
WriteMSBShort(PICTpackbitsrect);
#else
WriteMSBShort(PICTdirectbitsrect);
WriteMSBShort(0x0000); /* baseAddr */
WriteMSBShort(0x00ff);
#endif
i = (XRange*sizeof(Pixel)) | 0x8000;
WriteMSBShort( i ); /* rowBytes */
WriteMSBShort(0); /* bounds.top */
WriteMSBShort(0); /* bounds.left */
WriteMSBShort(YRange); /* bounds.bottom */
WriteMSBShort(XRange); /* bounds.right */
WriteMSBShort(0); /* pmVersion */
#ifdef EIGHTBIT
WriteMSBShort(0); /* packType */
#else
WriteMSBShort(4); /* packType */
#endif
WriteMSBLong(0); /* packSize */
WriteMSBLong(72); /* hRes */
WriteMSBLong(72); /* vRes */
#ifdef EIGHTBIT
WriteMSBShort(0); /* pixelType */
WriteMSBShort(8); /* pixelSize */
WriteMSBShort(1); /* cmpCount */
WriteMSBShort(8); /* cmpSize */
#else
WriteMSBShort(16); /* pixelType */
WriteMSBShort(32); /* pixelSize */
WriteMSBShort(3); /* cmpCount */
WriteMSBShort(8); /* cmpSize */
#endif
WriteMSBLong(0); /* planeBytes */
WriteMSBLong(0); /* pmTable */
WriteMSBLong(0); /* pmReserved */
#ifdef EIGHTBIT
WriteMSBLong(0); /* ctSeed */
WriteMSBShort(0); /* ctFlags */
WriteMSBShort(cols-1); /* ctSize */
for( i=0; i<cols; i++ )
{ WriteMSBShort(i); /* value */
j=Node[i]; r=RLut[j]; g=GLut[j]; b=BLut[j];
WriteMSBShort( (r<<8)|r ); /* rgb.red */
WriteMSBShort( (g<<8)|g ); /* rgb.green */
WriteMSBShort( (b<<8)|b ); /* rgb.blue */
}
#endif
WriteMSBShort(0); /* srcRect.top */
WriteMSBShort(0); /* srcRect.left */
WriteMSBShort(YRange); /* srcRect.bottom */
WriteMSBShort(XRange); /* srcRect.right */
WriteMSBShort(0); /* dstRect.top */
WriteMSBShort(0); /* dstRect.left */
WriteMSBShort(YRange); /* dstRect.bottom */
WriteMSBShort(XRange); /* dstRect.right */
WriteMSBShort(0); /* mode (srcCopy) */
WritePICTData();
if( RLEFileSize & 0x01 ) WriteByte(0x00);
WriteMSBShort(PICTendofpict);
fclose(OutFile);
#ifdef APPLEMAC
SetFileInfo(name,'ttxt','PICT',134);
#endif
return( True );
}
static void FlushIRISBuffer()
{
if( PacketLen )
{ if( RLEOutput )
{ WriteByte(PacketLen|0x80);
fwrite((char*)Buffer,1,PacketLen,OutFile);
} else RLELineSize += PacketLen+1;
PacketLen = 0;
}
}
static void FlushIRISPacket()
{
register int i;
if( RLELength>2 )
{ FlushIRISBuffer();
if( RLEOutput )
{ WriteByte(RLELength);
WriteByte(RLEChar);
} else RLELineSize += 2;
} else
for( i=0; i<RLELength; i++ )
{ Buffer[PacketLen++] = RLEChar;
if( PacketLen == 127 )
FlushIRISBuffer();
}
RLELength = 0;
}
static void WriteIRISCode( val )
int val;
{
if( !RLELength )
{ RLELength = 1;
RLEChar = val;
} else if( (RLEChar!=val) || (RLELength==127) )
{ FlushIRISPacket();
RLELength = 1;
RLEChar = val;
} else RLELength++;
}
int WriteIRISFile( name )
char *name;
{
register Long __far *rowstart;
register short __far *rowsize;
register Pixel __huge *ptr;
register Pixel __huge *tmp;
register int i,min,max;
register int x,y,size;
size = 3*YRange;
/* Allocate RLE encoded row length table */
rowsize = (short __far*)_fmalloc(size*sizeof(short));
rowstart = (Long __far*)_fmalloc(size*sizeof(Long));
if( !rowsize || !rowstart )
{ if( CommandActive ) WriteChar('\n');
WriteString("Output Error: Unable to allocate memory!\n");
if( rowstart ) _ffree(rowstart);
if( rowsize ) _ffree(rowsize);
CommandActive = False;
return( False );
}
#if defined(IBMPC) || defined(APPLEMAC)
OutFile = fopen(name,"wb");
#else
OutFile = fopen(name,"w");
#endif
if( !OutFile )
{ FatalOutputError(name);
return( False );
}
CalcInvColourMap();
#ifdef IBMPC
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
#endif
#ifdef INVERT
ptr = FBuffer;
#endif
max = 0;
min = 255;
RLEFileSize = 512 + 2*size*sizeof(Long);
RLEOutput = False;
PacketLen = 0;
RLELength = 0;
for( y=0; y<YRange; y++ )
{
#ifndef INVERT
ptr = FBuffer + (Long)((YRange-1)-y)*XRange;
#endif
tmp = ptr;
RLELineSize = 0;
/* Red Component */
for( x=0; x<XRange; x++ )
{ i = RComp(*ptr++);
if( i<min ) min=i;
if( i>max ) max=i;
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
rowsize[y] = RLELineSize;
rowstart[y] = RLEFileSize;
RLEFileSize += RLELineSize;
ptr = tmp;
RLELineSize = 0;
/* Green Component */
for( x=0; x<XRange; x++ )
{ i = GComp(*ptr++);
if( i<min ) min=i;
if( i>max ) max=i;
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
i = y+YRange;
rowsize[i] = RLELineSize;
rowstart[i] = RLEFileSize;
RLEFileSize += RLELineSize;
ptr = tmp;
RLELineSize = 0;
/* Blue Component */
for( x=0; x<XRange; x++ )
{ i = BComp(*ptr++);
if( i<min ) min=i;
if( i>max ) max=i;
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
i = y+(YRange<<1);
rowsize[i] = RLELineSize;
rowstart[i] = RLEFileSize;
RLEFileSize += RLELineSize;
}
WriteMSBShort(474); /* imagic */
WriteMSBShort(257); /* type */
WriteMSBShort(3); /* dim */
WriteMSBShort(XRange); /* xsize */
WriteMSBShort(YRange); /* ysize */
WriteMSBShort(3); /* zsize */
WriteMSBLong(min); /* min */
WriteMSBLong(max); /* max */
WriteMSBLong(0); /* wastebytes */
/* name */
fputs("RasMol IRIS RGB format output",OutFile);
for( i=0; i<51; i++ ) WriteByte(0x00);
WriteMSBLong(0); /* colormap */
for( i=0; i<404; i++ ) WriteByte(0x00);
for( i=0; i<size; i++ ) WriteMSBLong(rowstart[i]);
for( i=0; i<size; i++ ) WriteMSBLong(rowsize[i]);
#ifdef INVERT
ptr = FBuffer;
#endif
RLEOutput = True;
for( y=0; y<YRange; y++ )
{
#ifndef INVERT
ptr = FBuffer + (Long)((YRange-1)-y)*XRange;
#endif
tmp = ptr;
/* Red Component */
for( x=0; x<XRange; x++ )
{ i = RComp(*ptr++);
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
ptr = tmp;
/* Green Component */
for( x=0; x<XRange; x++ )
{ i = GComp(*ptr++);
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
ptr = tmp;
/* Blue Component */
for( x=0; x<XRange; x++ )
{ i = BComp(*ptr++);
WriteIRISCode(i);
}
FlushIRISPacket();
FlushIRISBuffer();
}
_ffree( rowstart );
_ffree( rowsize );
fclose( OutFile );
#ifdef APPLEMAC
/* Avoid ANSI trigraph problems! */
SetFileInfo(name,'\?\?\?\?','\?\?\?\?',134);
#endif
#ifdef IBMPC
GlobalUnlock(FBufHandle);
#endif
return( True );
}
void InitialiseOutFile()
{
#if defined(IBMPC) || defined(APPLEMAC)
/* Allocate Tables on FAR Heap */
ABranch = (short __far*)_fmalloc(4096*sizeof(short));
DBranch = (short __far*)_fmalloc(4096*sizeof(short));
Hash = (short __far*)_fmalloc(256*sizeof(short));
Node = (Byte __far*)_fmalloc(4096*sizeof(Byte));
#endif
KinemageFlag = False;
UseOutLine = False;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.