ack3d/ack_lib/ACKIFF.C
2019-11-03 13:05:01 -05:00

239 lines
5.9 KiB
C

// This source file contains the functions needed to read in BBM files.
// (c) 1995 ACK Software (Lary Myers)
//=============================================================================
// This function will return a pointer to a buffer that holds the raw image.
// just free the pointer to delete this buffer. After returning, the array
// colordat will hold the adjusted palette of this pic.
//
// Also, this has been modified to only read in form PBM brushes. form ILBM's
// (the "old" type) are not supported. use the "new" deluxe paint .lbm type
// and do not choose "old".
//=============================================================================
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ack3d.h"
#include "ackeng.h"
#include "ackext.h"
#include "iff.h"
extern char rsName[];
unsigned char colordat[768]; /* maximum it can be...256 colors */
unsigned char cplanes[8][80]; /* setting max at 640 pixels width */
/* thats 8 pixels per byte per plane */
unsigned char *pplanes= &cplanes[0][0]; /* for a form pbm */
#define MAX_BUF_POS 4096
int rdbufpos;
int rdSize;
UCHAR rdBuffer[MAX_BUF_POS+2];
short ReadNxtBlock(short handle)
{
short retlen;
retlen = read(handle,rdBuffer,MAX_BUF_POS);
rdbufpos = 0;
return(retlen);
}
//=============================================================================
//
//=============================================================================
void CloseFile(FILE *fp)
{
fclose(fp);
if (rsHandle)
{
rsHandle = open(rsName,O_RDONLY|O_BINARY);
if (rsHandle < 1)
rsHandle = 0;
}
}
unsigned char *AckReadiff(char *picname)
{
FILE *pic;
short handle;
form_chunk fchunk;
ChunkHeader chunk;
BitMapHeader bmhd;
long length;
char value; /* must remain signed, no matter what. ignore any warnings. */
short sofar;
short width,height,planes;
short pixw;
unsigned char *destx, *savedestx;
rdbufpos = MAX_BUF_POS + 1;
rdSize = MAX_BUF_POS;
if (!rsHandle)
{
if ((pic = fopen(picname,"rb")) == NULL)
{
ErrorCode = ERR_BADPICNAME;
return(0L);
}
}
else
{
pic = fdopen(rsHandle,"rb");
if (pic == NULL)
{
ErrorCode = ERR_BADPICNAME;
return(0L);
}
fseek(pic,rbaTable[(ULONG)picname],SEEK_SET);
}
fread(&fchunk,1,sizeof(form_chunk),pic); /* read in the first 12 bytes*/
if (fchunk.type != FORM)
{
CloseFile(pic);
ErrorCode = ERR_INVALIDFORM;
return(0L);
}
if (fchunk.subtype != ID_PBM)
{
CloseFile(pic);
ErrorCode = ERR_NOPBM;
return(0L);
}
/* now lets loop...Because the Chunks can be in any order! */
while(1)
{
fread(&chunk,1,sizeof(ChunkHeader),pic);
chunk.ckSize = ByteFlipLong(chunk.ckSize);
if (chunk.ckSize & 1) chunk.ckSize ++; /* must be word aligned */
if(chunk.ckID == ID_BMHD)
{
fread(&bmhd,1,sizeof(BitMapHeader),pic);
bmhd.w=iffswab(bmhd.w); /* the only things we need. */
bmhd.h=iffswab(bmhd.h);
destx = (unsigned char *)AckMalloc((bmhd.w * bmhd.h)+4);
if ( !destx )
{
CloseFile(pic);
ErrorCode = ERR_NOMEMORY;
return(0L);
}
savedestx = destx;
destx[0] = bmhd.w%256;
destx[1] = bmhd.w/256;
destx[2] = bmhd.h%256;
destx[3] = bmhd.h/256;
destx += 4;
continue;
}
if(chunk.ckID == ID_CMAP)
{
short i;
unsigned char r,g;
fread(colordat,1,chunk.ckSize,pic);
for (i=0;i<768;i++)
{
r = colordat[i]; /* r,g do not stand for red and green */
g = r >> 2;
colordat[i] = g;
}
continue;
}
if(chunk.ckID == ID_BODY)
{
for(height = 0; height<bmhd.h; height ++)
{
unsigned char *dest;
dest = (unsigned char *)&(pplanes[0]); /* point at first char */
sofar = bmhd.w; /* number of bytes = 8 */
if (sofar&1) sofar++;
while (sofar)
{
if (bmhd.compression)
{
value=fgetc(pic); /* get the next byte */
if (value > 0)
{
short len;
len = value +1;
sofar -= len;
if(!(fread(dest,len,1,pic)))
{
CloseFile(pic);
ErrorCode = ERR_BADPICFILE;
AckFree(savedestx);
return(0L);
}
dest +=len;
}
else
{
short count;
count = -value; /* get amount to dup */
count ++;
sofar -= count;
value=fgetc(pic);
while (--count >= 0) *dest++ = value;
}
}
else
{
fread(dest,sofar,1,pic); /* just throw on plane */
sofar = 0;
}
}
if (sofar < 0)
{
CloseFile(pic);
}
_fmemcpy(destx,pplanes,bmhd.w);
destx += bmhd.w;
}
break; /* leave if we've unpacked the BODY*/
}
fseek(pic,chunk.ckSize,SEEK_CUR);
}
CloseFile(pic);
return((unsigned char *)savedestx);
}
long ByteFlipLong(long NUMBER)
{
/* Hey, I didn;t write this function!!! */
long Y, T;
short I;
T = NUMBER;
Y=0;for (I=0;I<4;I++){Y = Y | (T & 0xFF);if (I<3) {Y = Y << 8;T = T >> 8;}}
return(Y);
}
short iffswab(unsigned short number)
{
unsigned short xx1,xx2;
unsigned short result;
xx1 = number <<8; xx2 = number >>8; result = xx1|xx2;
return(result);
}
// **** End of Source ****