
#include <exec/types.h>             /*for type defs*/
#include  <intuition/intuition.h>   /*for screens,windows*/
#include  <stdio.h>                 /*for printf*/
#include  <libraries/dos.h>

char *ilbm = "ILBM";                /*chunk identifiers*/
char *bmhd = "BMHD";
char *cmap = "CMAP";
char *body = "BODY";
char *acbm = "ACBM";
char *abit = "ABIT";

long bytesread;          /*bytes read from file*/
long totalbytes;         /*total bytes on file*/
long icLen;              /*chunk length*/
short iHeight,iWidth;    /*height and width of picture*/
short scrWidth,scrHeight;/*height and width of its screen*/
short iDepth;            /*number of bitplanes*/
short nColors;          /*number of colours*/
short iRowBytes;         /*picture bytes per row*/
short scrRowBytes;       /*pic screen bytes per row*/
UBYTE iCompr;            /*compression flag*/
UBYTE mybuf[120];        /*buffer for headers and short
                          chunks*/
long rLen;               /*bytes read from disc*/
char *tempbuffer;        /*temporary buffer for body chunk*/
long fHandle;            /*file handle*/
short red,gre,blu;        /*temporary colour variables*/
int camgModes;           /*camg modes*/


/****************************************************************************/
/*        readfile(name,bitmap,colourlist) reads an ILBM or ACBM file       */
/*        name is the address of the filename                               */
/*        bitmap is the address of the bitmap structure to be used          */
/*        assuming this bitmap is initialised and the rasters correctly     */
/*        allocated                                                         */
/*        colourlist is a pointer to where the colours are to be stored     */
/*        eg colourlist: ds.w 32 for 32 colours
/*        the program assumes that the file is present, and is ILBM or ACBM  */
/*        and  that the bitmap and colorlist are ok                  */
/****************************************************************************/

_readfile(name,bitmap,colourlist)
char *name;                     /*pointer to filename*/
struct BitMap *bitmap;          /*pointer to bitmap to be used*/
USHORT *colourlist;              /*pointer to list of colours*/
{
openfile(name);  /*open the file and read*/
while (bytesread<totalbytes) readchunk(bitmap,colourlist);
return(0);
}

_test()
{
Delay(500);
return(0);
}
_test2(par)
long par;
{
Delay(par);
return(0);
}

/*open the iff file and read the header.Store the length*/
/*and check for an ILBM or ACBM file*/
openfile(filename)
char *filename;
{
fHandle = Open(filename,1005);
if (fHandle == NULL) return(FALSE);
rLen = Read(fHandle,&mybuf[0],8);
bytesread=rLen;
totalbytes=256*256*mybuf[5]+256*mybuf[6]+mybuf[7];
rLen = Read(fHandle,&mybuf[0],4);
bytesread=bytesread+rLen;
if((strcmp(ilbm,&mybuf)) == NULL) return(0);
if((strcmp(acbm,&mybuf)) == NULL)  return(0);
return (FALSE);
}
readchunk(bitmap,colourlist)
struct BitMap *bitmap;
USHORT *colourlist;
{
rLen = Read(fHandle,&mybuf[0],8);
icLen=mybuf[7]+256*mybuf[6];
bytesread=8+bytesread;
bytesread=icLen+bytesread;
if ((strcmp(bmhd,&mybuf)) == NULL)
 {readbitmapheader(bitmap);return(0);}
if ((strcmp(cmap,&mybuf)) == NULL) {readcmap(colourlist);return(0);}
if ((strcmp(body,&mybuf)) == NULL) {readbody(bitmap);return(0);}
if ((strcmp(abit,&mybuf)) == NULL) {readbody(bitmap);return(0);}
rLen = Read(fHandle,&mybuf[0],icLen);
return(0);
}

readbitmapheader(bitmap)
struct BitMap *bitmap;
{
rLen = Read(fHandle,&mybuf[0],icLen);
scrWidth = mybuf[1] + 256*mybuf[0];    /*screen width*/
scrHeight = mybuf[3] +256*mybuf[2];    /*screen height*/
iDepth = mybuf[8];                     /*bitplanes*/
iCompr = mybuf[10];                    /*compression flag*/
iWidth = mybuf[17] +256*mybuf[16];     /*picture width*/
iHeight =mybuf[19]+256*mybuf[18];      /*picture height*/
iRowBytes = iWidth/8;                  /*picture bytes per row*/
scrRowBytes = scrWidth/8;              /*screen bytes per row*/
nColors = power(2,iDepth);             /*number of colours*/
if (iHeight==200) iHeight=256;
return(0);
}

/*this chunk contains the colour information*/
readcmap(colourlist)
USHORT *colourlist;
{
long i,j,lim;
rLen = Read(fHandle,&mybuf[0],icLen);
lim=(nColors&255);
for (i =0;i<lim;i++)
 {
 j=(i&(nColors-1));
 red = mybuf[j*3];
 gre = mybuf[j*3 + 1];
 blu = mybuf[j*3 + 2];
 *(colourlist+i) = blu/16+gre+red*16;
 }
return(0);
}


/*the abit chunk of an acbm file can be read straight onto*/
/*the raster*/
readabit(bitmap)
struct BitMap *bitmap;
{
int i;
for (i=0;i<iDepth;i++)
rLen = Read(fHandle,bitmap->Planes[i],scrRowBytes*iHeight);
return(0);
}

/*the body chunk of an ilbm file*/
readbody(bitmap)
struct BitMap *bitmap;
{
tempbuffer=AllocMem(icLen,65539);     /*allocate temporary*/
                                      /*buffer*/
rLen = Read(fHandle,tempbuffer,icLen);/*read data*/
if (iCompr>1)                         /*test compression*/
                                      /*flag*/
 printf("Unknown Compression Algorithm  \n");
if (iCompr==0) plainread(bitmap);           /*no compression*/
if (iCompr==1) decode(bitmap);              /*normal compression*/
FreeMem(tempbuffer,icLen);            /*free buffer*/
return(0);
}

/*decode a compressed file*/
/*read the next byte inCode*/
/*if inCode<128 read the next inCode+1 bytes normally*/
/*if inCode>128 the next inCode+1 bytes are the same as the next one*/
decode(bitmap)
struct BitMap *bitmap;
{
USHORT rows,planes,columns;
UBYTE bCnt,inCode,inByte;
UBYTE *place;
UBYTE *scrRow;
place= tempbuffer;
for (rows=0;rows<iHeight;rows++)
 {
  for (planes=0;planes<iDepth;planes++)
  {
  scrRow=bitmap->Planes[planes] + (rows*scrRowBytes);
  bCnt=0;
  while(bCnt<iRowBytes)
   {inCode=*(place);
    place++;
    if (inCode<128)
    {for(columns=0;columns<inCode+1;columns++) *(scrRow+bCnt+columns)=*(place++);
     bCnt=bCnt+inCode+1;
    }
    else if (inCode>128)
    {
     inByte= *(place);
     for(columns=0;columns<257-inCode;columns++) *(scrRow+bCnt+columns)=inByte;
     bCnt=bCnt+257-inCode;
     place++;
    }
   }
  }
 }
return(0);
}
/*no compression, but the bitplanes are interleaved*/
plainread(bitmap)
struct BitMap *bitmap;
{
short rows,planes;
long columns;
char *scrRow;
char *pointer=tempbuffer;
for (rows=0;rows<iHeight;rows++)
 {
  for (planes=0;planes<iDepth;planes++)
  {
  scrRow=bitmap->Planes[planes] + rows*scrRowBytes;
  for (columns=0;columns<iRowBytes;columns++)
  *(scrRow+columns)=*(pointer++);
  }
 }
return(0);
}

/*compare strings*/
strcmp(s,t)
char *s, *t;
{
for (; *s == *t; s++,t++)
if (*s == NULL)
return(0);
return(*s - *t);
}

/*raise x to the power n*/
power(x,n)
int x,n;
{
int i,p;
p=1;
for (i=1;i<=n; ++i)
p = p*x;
return(p);
}
