home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
568b.lha
/
PowerSource_v3.0
/
source.lzh
/
source
/
rim.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
11KB
|
289 lines
/*----------------------------------------------------------------------*
rim.c Version 3.0 - © Copyright 1990-91 Jaba Development
Author : Jan van den Baard
Purpose : reading routines for IFF ILBM images and ColorMaps
*----------------------------------------------------------------------*/
extern struct Screen *MainScreen;
extern struct ge_prefs prefs;
extern struct MemoryChain Memory;
/*
* check to see if there are bit-planes that doesn't contain data
*/
static long check( UBYTE *data, ULONG size )
{
register UBYTE *pointer;
register UCOUNT counter;
pointer = data;
for( counter = 0; counter < size; counter++)
if(*pointer++) return(TRUE);
return(FALSE);
}
/*
* filter out the bit-planes that doesn't contain data
*/
void skip_zero_planes( struct Image *image )
{
UBYTE *data, *planes[8], *data1;
UBYTE depth = 0;
ULONG plane_size;
register USHORT counter,ptc = 0;
plane_size = RASSIZE(image->Width,image->Height);
data = (UBYTE *)image->ImageData;
for(counter = 0; counter < image->Depth; counter++) {
planes[counter] = (UBYTE *)(data + (counter * plane_size));
if(check(planes[counter],plane_size)) depth++;
}
if(depth == image->Depth) return;
if(NOT(data1 = (UBYTE *)
AllocMem((ULONG)depth * plane_size,MEMF_CHIP+MEMF_CLEAR))) return;
for(counter = 0; counter < image->Depth; counter++) {
if(check(planes[counter],plane_size))
CopyMem((char *)planes[counter],(char *)(data1+(ptc++ * plane_size)),plane_size);
}
image->PlanePick = NULL;
for(counter = 0; counter < depth; counter++ )
image->PlanePick |= (1 << counter);
FreeMem(data,(plane_size * image->Depth));
image->Depth = depth;
image->ImageData = (USHORT *)data1;
}
/*
* check to see if the file opened is an IFF ILBM file
*/
static long CheckIFF( BPTR file )
{
struct FORMChunk fchunk;
char *str = NULL;
if(Read(file,(char *)&fchunk,sizeof(struct FORMChunk)) <= 0)
str = "Error during Image Read !";
else if(fchunk.fc_Type != 'FORM')
str = "File is not an IFF FORM !";
else if(fchunk.fc_SubType != 'ILBM')
str = "IFF FORM is not an ILBM !";
if(str) {
enable_window();
Error(str);
return(FALSE);
}
return(TRUE);
}
/*
* read the IFF ILBM file into memory and if no errors occur
* return the pointer to an image structure containing the image
*/
struct Image *ReadImage( UBYTE *ilbmname )
{
struct IFFChunk ichunk;
struct BitMapHeader header;
BPTR infile = NULL;
ULONG length, offset = NULL, unpacked;
struct Image *image = NULL;
ULONG planes_size,ps;
COUNT plane,row;
BYTE *s1,i;
BYTE *source, *dest, *planedata = NULL, *planes[8], byte, byte1;
BOOL GotBODY = FALSE;
char *str;
buisy();
if(NOT(image = (struct Image *)Alloc(&Memory,(ULONG)sizeof(struct Image)))) {
str = "Out of memory !";
goto Err;
}
if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE))) {
str = "Can't open IFF file !";
goto Err;
}
if(NOT CheckIFF(infile)) {
FreeItem(&Memory,image,(long)sizeof(struct Image));
Close(infile);
return(NULL);
}
while(GotBODY == FALSE) {
if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0) {
str = "Error during Image Read !";
}
length = ichunk.ic_Length;
if(length & 1) length++;
switch(ichunk.ic_Type) {
case 'BMHD': if(Read(infile,(char *)&header,length) <= 0) {
str = "Error during Image Read !";
goto Err;
}
image->Width = header.w;
image->Height = header.h;
image->Depth = header.nPlanes;
for(i = 0; i < image->Depth; i++)
image->PlanePick += (1 << i);
image->PlaneOnOff = 0x00;
ps = RASSIZE(image->Width,image->Height);
planes_size = ps * image->Depth;
break;
case 'BODY': GotBODY = TRUE;
if(NOT(planedata = (BYTE *)AllocMem(planes_size,MEMF_CHIP+MEMF_CLEAR))) {
str = "Out of CHIP memory !";
goto Err;
}
for(i = 0; i < image->Depth; i++)
planes[i] = (BYTE *)(planedata + (i * ps));
if(header.compression == 0) {
for(row = 0; row < image->Height; row++) {
for(plane = 0; plane < image->Depth; plane++) {
if(Read(infile,(char *)planes[plane]+offset,
bpr(image->Width)) <= 0) {
str = "Error during Image Read !";
goto Err;
}
}
offset += bpr(image->Width);
}
} else if(header.compression == 1) {
if(NOT(s1 = source = (BYTE *)AllocMem(length,MEMF_PUBLIC+MEMF_CLEAR))) {
str = "Out of memory !";
goto Err;
}
if(Read(infile,(char *)source,length) <= 0) {
FreeMem(source,length);
str = "Error during Image Read !";
goto Err;
}
for(row = 0; row < image->Height; row++) {
for(plane = 0; plane < image->Depth; plane++) {
dest = (BYTE *)planes[plane]+offset;
unpacked = bpr(image->Width);
while(unpacked > 0) {
byte = *source++;
if(byte == 128) {}
else if(byte > 0) {
byte += 1;
unpacked -= byte;
while(--byte >= 0) *dest++ = *source++;
} else {
byte = -byte + 1;
unpacked -= byte;
byte1 = *source++;
while(--byte >= 0) *dest++ = byte1;
}
}
}
offset += bpr(image->Width);
}
FreeMem(s1,length);
} else {
str = "Unknown Image compression !";
goto Err;
}
break;
default: Seek(infile,length,OFFSET_CURRENT); break;
}
}
image->ImageData = (USHORT *)planedata;
if(prefs.skip_zero_planes) skip_zero_planes(image);
Close(infile);
ok();
return(image);
Err:
enable_window();
Error(str);
if(infile) Close(infile);
if(image) FreeItem(&Memory,image,(long)sizeof(struct Image));
if(planedata) FreeMem(planedata,planes_size);
return(NULL);
}
/*
* read and set the CMAP of an IFF ILBM file
*/
void ReadCMAP( UBYTE *ilbmname, UWORD *buffer )
{
struct IFFChunk ichunk;
BPTR infile;
LONG length;
register COUNT reg,i=0;
BOOL GotIt = FALSE, GotCMAP = FALSE;
UBYTE colors[96],count;
buisy();
if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE))) {
enable_window();
Error("Can't open IFF file !");
return;
}
if(NOT CheckIFF(infile)) {
Close(infile);
return;
}
while(GotIt == FALSE) {
if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0) {
enable_window();
Error("Error during CMAP read !");
Close(infile);
return;
}
length = ichunk.ic_Length;
if(length & 1) length++;
switch(ichunk.ic_Type) {
case 'CMAP': GotCMAP = TRUE;
if(Read(infile,(char *)&colors,length) <= 0) {
enable_window();
Error("Error during CMAP read !");
break;
}
if(NOT buffer) {
count = (1 << MainScreen->BitMap.Depth);
for(reg = 0; reg < count; reg++, i += 3) {
SetRGB4(&MainScreen->ViewPort,
reg,
((colors[i] >> 4) & 0x0f),
((colors[i+1] >> 4) & 0x0f),
((colors[i+2] >> 4) & 0x0f));
}
} else {
count = length / 3;
for(reg = 0, i = 0; reg < count; reg++, i += 3) {
buffer[reg] = ((colors[i] << 4) & 0xf00)|
((colors[i+1]) & 0x0f0)|
((colors[i+2] >> 4) & 0x00f);
}
}
break;
case 'BODY': GotIt = TRUE; break;
default: Seek(infile,length,OFFSET_CURRENT); break;
}
}
Close(infile);
if(GotCMAP == FALSE)
{ enable_window();
Error("No CMAP chunk found !");
}
ok();
return;
}