home *** CD-ROM | disk | FTP | other *** search
-
- #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 */
- }
-
-