home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
145.lha
/
TableCloth
/
tc_iff.c
< prev
Wrap
C/C++ Source or Header
|
1986-11-21
|
5KB
|
206 lines
#include "graphics:tc/tablecloth.h"
extern struct ChunkHeader chunk;
extern BOOL plot;
extern int actual_planes;
long get_chunk(fp)
register FILE *fp;
{
if(!fread(&chunk,(int)CHUNKHEADERSIZE,1,fp))
return(FALSE);
switch (chunk.TYPE)
{
/*
* These are the chunks that we want to deal with:
*
*/
case FORM:
case BMHD:
case CMAP:
case BODY:
case CAMG:
return((long)chunk.TYPE); /* identify the latest IFF structure we encounter */
break;
/*
* These chunks are not dealt with but still flagged as legal chunks:
*
*/
case GRAB:
case DEST:
case SPRT:
case CRNG:
case CCRT:
case DPPV:
return(-1); /* return non-zero since we still want to signal they are valid chunk types */
break;
/*
* If this part is reached, the file is garbled (ie we aren't at the
* beginning of a new chunk):
*
*/
default:
return(0L); /* returns failure on unrecognized chunk type, end-of-file, or any type of error condition */
break;
}
}
BOOL good_pict(fp)
register FILE *fp;
{
char label[5];
/*
* This is only a test for a valid IFF file, not for any particularly
* suitable picture. When this is finished it will support pictures of
* any size and number of colours so we won't be thrown by a loop by
* anything except a mangled file.
*
*/
if (get_chunk(fp) != FORM) return(FALSE); /* must start with this magic number */
/* NB: the "ILBM" is not a chunk and has no size field, just 4 bytes */
fread(label,4,1,fp);
label[4] = 0;
if (strcmp(label,"ILBM")) return(FALSE); /* must say "ILBM" immediately after the form*/
return(TRUE);
}
/*
* Here is the main part. I didn't get a headache writing any other section.
*
* This reads in the actual image data from an IFF file.
*
* The bitmap-header must be already initialized when this is called.
* I somehow doubt that many paint programs save files with their
* chunks in the wrong order... still, if an error is encountered during
* processing it will return with failure.
*
* I have a feeling there must be a more elegant way to do this. If there
* isn't I hope we can hide all the code like this away in a library
* somewhere!
*
* A badly garbled file will confuse this section; not every file read is
* tested for success.
*
*/
BOOL get_body(fp,header,bm) /* the last thing read was the chunk header for BODY */
register FILE *fp;
register struct bmhd *header;
struct BitMap *bm;
{
int i,n;
int plane_offset = 0;
int excess,underflow;
short bm_width = bm->BytesPerRow << 3;
register BOOL plot; /* may want to read data but not display it */
if (header->Compression != cmpNone && header->Compression != cmpByteRun1)
{
puts("Unknown compression.\n");
return(FALSE);
}
if (header->nplanes < actual_planes) actual_planes = header->nplanes;
for (i=0; i < header->h; i++)
{
debug("Beginning new line");
if (i >= bm->Rows)
return(TRUE); /* gone off end of screen, we quit loading now */
else
plot = TRUE; /* must reset for each line */
for (n=0; n < header->nplanes; n++)
{
if (n >= actual_planes) plot = FALSE; /* ignore these planes */
if (!header->Compression) /* no compression */
{
excess = (bm_width < header->w) ? (header->w - bm_width) >> 3 : 0;
if (plot)
fread (bm->Planes[n]+plane_offset, MIN(header->w >> 3, bm_width >> 3), 1, fp);
else
fseek(fp, header->w >> 3, 1);
/* if the picture is smaller than the screen, we read in only what the file thinks is a scanline */
/* if the picture is larger, we read in what the bitmap considers a scanline and skip the extra bytes in the file */
if (excess)
{
debug("Dropping some bytes in the bit-bucket.");
fseek(fp,excess,1);
}
}
else /* decode single compressed line */
{
register UBYTE *dest = bm->Planes[n] + plane_offset;
register char len;
register int so_far;
so_far = MIN(bm->BytesPerRow,header->w >> 3);
/* same deal here; scanlines too large are truncated, those too small are left-justified */
excess = (bm_width < header->w) ? (header->w - bm_width) >> 3 : 0;
while (so_far > 0)
{
if ((len = getc (fp)) >= 0) /* Literal byte copy */
{
so_far -= ++len;
if (plot)
fread (dest, len, 1, fp);
else
fseek(fp, len, 1);
dest += len;
}
else if ((UBYTE) len == 128) /* NOP */
;
else if (len < 0) /* Replication count */
{
UBYTE byte;
len = -len+1;
so_far -= len;
byte = getc (fp);
while (--len >= 0)
{
if (plot)
*dest++ = byte;
else
dest++;
}
}
if (excess)
{
debug("Dropping some bytes in the bit-bucket.");
fseek(fp,excess,1);
}
}
if (so_far)
{
puts("Read wrong number of bytes from line");
return(FALSE);
}
}
}
plane_offset += bm->BytesPerRow; /* drop down a scanline, even if only a partial one was read in */
}
return(TRUE); /* made it through without a hitch */
}