home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
applications
/
xlispstat
/
src
/
src1.lzh
/
Amiga
/
ilbmw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-05
|
5KB
|
153 lines
/*----------------------------------------------------------------------*
* ILBMW.C Support routines for writing ILBM files. 1/23/86
* (IFF is Interchange Format File.)
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* This version for the Commodore-Amiga computer.
*----------------------------------------------------------------------*/
#define FDwAT
#include <iff/packer.h>
#include <iff/ilbm.h>
#include <intuition/intuition.h>
/*---------- InitBMHdr -------------------------------------------------*/
IFFP InitBMHdr(bmHdr0,bitmap,masking,compression,transparentColor,
w,h,pageWidth,pageHeight)
BitMapHeader *bmHdr0; struct BitMap *bitmap;
WORD masking; /* Masking */
WORD compression; /* Compression */
WORD transparentColor; /* UWORD */
WORD pageWidth, pageHeight;
int w,h;{
register BitMapHeader *bmHdr=bmHdr0;
bmHdr->w=RowBytes(w)<<3; /* even number of bytes */
bmHdr->h=h;
bmHdr->x=0;
bmHdr->y=0;
bmHdr->nPlanes=bitmap->Depth;
bmHdr->masking=masking;
bmHdr->compression=compression;
bmHdr->pad1=0;
bmHdr->transparentColor=transparentColor;
bmHdr->xAspect=bmHdr->yAspect=1;
bmHdr->pageWidth=pageWidth;
bmHdr->pageHeight=pageHeight;
if(pageWidth==320)
switch(pageHeight){
case 200: bmHdr->xAspect=x320x200Aspect;
bmHdr->yAspect=y320x200Aspect; break;
case 400: bmHdr->xAspect=x320x400Aspect;
bmHdr->yAspect=y320x400Aspect; break;}
else if(pageWidth==640)
switch(pageHeight){
case 200: bmHdr->xAspect=x640x200Aspect;
bmHdr->yAspect=y640x200Aspect; break;
case 400: bmHdr->xAspect=x640x400Aspect;
bmHdr->yAspect=y640x400Aspect; break;}
return(IS_ODD(w)?CLIENT_ERROR:IFF_OKAY);}
/*---------- PutCMAP ---------------------------------------------------*/
IFFP PutCMAP(context,colorMap,depth)
GroupContext *context;
WORD *colorMap;
UBYTE depth;{
register LONG nColorRegs;
IFFP iffp;
ColorRegister colorReg;
if(depth>MaxAmDepth)depth=MaxAmDepth;
nColorRegs=1<<depth;
iffp=PutCkHdr(context,ID_CMAP,nColorRegs*sizeofColorRegister);
CheckIFFP();
for(;nColorRegs;--nColorRegs){
colorReg.red=(*colorMap>>4)&0xf0;
colorReg.green=(*colorMap)&0xf0;
colorReg.blue =(*colorMap<<4)&0xf0;
iffp=IFFWriteBytes(context,(BYTE *)&colorReg,sizeofColorRegister);
CheckIFFP();
++colorMap;}
iffp=PutCkEnd(context);
return(iffp);}
/*---------- PutBODY ---------------------------------------------------*/
/* NOTE: This implementation could be a LOT faster if it used more of the
* supplied buffer. It would make far fewer calls to IFFWriteBytes (and
* therefore to DOS Write). */
IFFP PutBODY(window,context,bitmap,mask,bmHdr,buffer,bufsize)
struct Window *window;
GroupContext *context;
struct BitMap *bitmap;
BYTE *mask;
BitMapHeader *bmHdr;
BYTE *buffer;
LONG bufsize;{
IFFP iffp;
LONG rowBytes=bitmap->BytesPerRow,rstart,readrow,rb;
int dstDepth=bmHdr->nPlanes;
Compression compression=bmHdr->compression;
int planeCnt; /* number of bit planes including mask */
register int iPlane,iRow,i,sh1,sh2,sh;
register LONG packedRowBytes;
BYTE *buf,*b;
unsigned char buf1[80];
BYTE *planes[MaxAmDepth + 1],*pl; /* array of ptrs to planes & mask */
if(bufsize<MaxPackedSize(rowBytes)|| /* Must buffer a comprsd row*/
compression>cmpByteRun1|| /* bad arg */
/* bitmap->Rows!=bmHdr->h|| inconsistent */
/* rowBytes!=RowBytes(bmHdr->w)|| inconsistent*/
bitmap->Depth<dstDepth|| /* inconsistent */
dstDepth>MaxAmDepth) /* too many for this routine*/
return(CLIENT_ERROR);
planeCnt=dstDepth+(mask==NULL?0:1);
/* Copy the ptrs to bit & mask planes into local array "planes" */
for(iPlane=0;iPlane<dstDepth;iPlane++){
planes[iPlane]=(BYTE *)bitmap->Planes[iPlane];}
if(mask!=NULL)planes[dstDepth]=mask;
readrow=RowBytes(bmHdr->w);
rb=(readrow<<3)-bmHdr->w;
rstart=(window->LeftEdge+bmHdr->x)>>3;
sh=(window->LeftEdge+bmHdr->x)%8;
sh2=rb-sh;
if(sh2<0)sh2+=16;
if(sh2<9)sh1=0;
else {
sh1=sh2-8; sh2=8;}
/* Write out a BODY chunk header */
iffp=PutCkHdr(context,ID_BODY,szNotYetKnown);
CheckIFFP();
/* Write out the BODY contents */
for(iRow=0;iRow<bmHdr->h;iRow++){
for(iPlane=0;iPlane<planeCnt;iPlane++){
/* Write next row.*/
pl=planes[iPlane]+rowBytes*(iRow+window->TopEdge+bmHdr->y);
for(i=0;i<readrow;i++)buf1[i]=pl[i+rstart];
buf1[0]<<=sh; buf1[0]>>=sh;
buf1[readrow-2]>>=sh1; buf1[readrow-2]<<=sh1;
buf1[readrow-1]>>=sh2; buf1[readrow-1]<<=sh2;
if(compression==cmpNone){
iffp=IFFWriteBytes(context,buf1,readrow);}
/* Compress and write next row.*/
else{
buf=buffer; b=&buf1[0];
packedRowBytes=PackRow(&b,&buf,readrow);
iffp=IFFWriteBytes(context,buffer,packedRowBytes);}
CheckIFFP();}}
/* Finish the chunk */
iffp=PutCkEnd(context);
return(iffp);}