home *** CD-ROM | disk | FTP | other *** search
- #include <functions.h>
- #include "iff.h"
-
- extern void *IntuitionBase,*GfxBase,*DiskfontBase;
-
- /* READILBM.C : based on NewZAP's READILBM.C
- (c) 1986,1990,1991 Dallas J. Hodgson
-
- Loads bitmaps into MEMF_PUBLIC
- */
-
- LoadMode Mode;
- unsigned char *pdiskptr;
-
- /************************************************************************
- * *
- * Routine name(s) : ReadILBM() *
- * Author : D. John Hodgson *
- * Environment : Aztec "C", default *
- * *
- * ReadILBM attempts to read an IFF file into an user-supplied *
- * bitmap. Returns FALSE if successful. Brushes supported. *
- * *
- * OPTIONS : Filespec reflects user-supplied pointer to IFF file in *
- * RAM if mode argument is non-zero. Otherwise, disk. *
- * *
- * LIMITATIONS : Bare-bones ILBM; no CATS/LISTS/PROPS. *
- * All other graphics (compressed or not) supported. *
- ************************************************************************/
-
- BPTR OpenNEW(unsigned char *name,long accessMode)
- {
- if (Mode==DISK_MODE) return(Open((char *)name,accessMode));
-
- pdiskptr=name; /* initialize pseudo-disk RAM ptr */
- return((BPTR)pdiskptr);
- }
-
- long ReadNEW(BPTR file,char *buffer,long length)
- {
- if (Mode==DISK_MODE) return(Read(file,buffer,length));
-
- movmem(pdiskptr,buffer,(unsigned int)length);
- pdiskptr+=length;
-
- return(length);
- }
-
- long SeekNEW(BPTR file,long position,long tmode)
- {
- if (Mode==DISK_MODE) return(Seek(file,position,tmode));
-
- /* Note : RAM seek only supports one mode : OFFSET_CURRENT! */
- if (tmode!=OFFSET_CURRENT) return(BAD_MODE);
-
- pdiskptr+=position;
-
- return((long)pdiskptr-position); /* Seek() returns previous position! */
- }
-
- void CloseNEW(BPTR file)
- {
- if (Mode==DISK_MODE) Close(file);
- }
-
- ReadILBM(char *fspec,LoadMode mode,struct PicMap *picmap)
- {
- BPTR fp;
- Chunk header;
- BitMapHeader bmhd;
- unsigned char *tmp,*bufstart,*sourcebuf;
- UWORD i,color;
- long id;
-
- Mode=mode;
- memset(picmap,0,sizeof(*picmap));
-
- if (!(fp=OpenNEW((unsigned char *)fspec,MODE_OLDFILE))) return(DISK_ERR);
-
- SafeRead(fp,&header,(long)sizeof(header));
- if (header.ckID!=ID_FORM) { CloseNEW(fp); return(IFF_ERR); }
-
- SafeRead(fp,&id,(long)sizeof(id));
- if (id!=ID_ILBM) { CloseNEW(fp); return(IFF_ERR); }
-
- for (;;) {
- SafeRead(fp,&header,(long)sizeof(header));
-
- if (header.ckID==ID_BODY) break;
-
- switch(header.ckID) {
- case ID_BMHD: SafeRead(fp,&bmhd,(long)sizeof(bmhd));
-
- /* force WORD boundary for all pics */
- bmhd.w=(bmhd.w + 0xf) & 0xfff0;
-
- break;
-
- case ID_CMAP: tmp=picmap->palette;
- SafeRead(fp,tmp,(long)header.ckSize);
-
- for (i=0;i<header.ckSize/3;i++) {
-
- color = (*tmp++ & 0xf0) << 4;
- color |= (*tmp++ & 0xf0);
- color |= *tmp++ >> 4;
-
- picmap->colormap[i]=color;
- }
-
- break;
-
- case ID_CAMG: SafeRead(fp,&picmap->ViewModes,(long)header.ckSize);
- break;
-
- default: SeekNEW(fp,ROUNDODDUP(header.ckSize),OFFSET_CURRENT);
- }
- }
-
- /* make some forced assumptions if CAMG chunk unavailable */
-
- if (!picmap->ViewModes) {
- if (bmhd.w>LOWIDTH) picmap->ViewModes=HIRES;
- if (bmhd.h>LOHEIGHT) picmap->ViewModes|=LACE;
- }
-
- /* Read planes into RAM for ease of decompression */
-
- if (Mode==RAM_MODE) sourcebuf=bufstart=pdiskptr; /* memory-resident IFF? */
- else { /* disk-resident IFF? */
- if (!(sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC)))
- return(OUT_OF_MEM);
- SafeRead(fp,sourcebuf,(long)header.ckSize); CloseNEW(fp);
- }
-
- InitBitMap(&picmap->BitMap,(long)bmhd.nPlanes,(long)bmhd.w,(long)bmhd.h);
-
- /* note that we're not necessarily allocating CHIP_MEM here! */
-
- for (i=0;i<bmhd.nPlanes;i++)
- if (!(picmap->BitMap.Planes[i]=AllocMem(RASSIZE(bmhd.w,bmhd.h),MEMF_PUBLIC))) {
- FreeBitMap(&picmap->BitMap);
- FreeMem(bufstart,(long)header.ckSize);
- return(OUT_OF_MEM);
- }
-
- i=Expand(&bmhd,bufstart,&picmap->BitMap);
-
- if (Mode==DISK_MODE) FreeMem(bufstart,(long)header.ckSize);
-
- return(i); /* error if unpacking prob */
- }
-
- void FreeBitMap(struct BitMap *bitmap)
- {
- short i;
-
- /* take into acct partially allocated maps (due to error) */
-
- for (i=0;i<bitmap->Depth;i++) {
- if (bitmap->Planes[i]) FreeMem(
- bitmap->Planes[i],bitmap->BytesPerRow*bitmap->Rows);
- }
-
- memset(bitmap,0,sizeof(bitmap)); /* prevent dbl-dealloc errs */
- }
-
- /* Fast line decompress/deinterleave : NEW VERSION */
-
- Expand(BitMapHeader *bmhd,register unsigned char *sourcebuf,struct BitMap *bitmap)
- {
- register char n,*destbuf; /* in order of preferred allocation */
- register short plane,rowlen,rowbytes,i;
- short planes=bmhd->nPlanes,maskplane = -1;
-
- /* This routine now supports mask (stencil) planes and brushes. The only
- thing it doesn't support is "trimming" the right edge of brushes to
- the background color if they're not exactly modulo 16 wide. DPaint III
- doesn't bother either, if you try to load a brush as a screen. */
-
- rowlen=((bmhd->w +15) & 0xFFF0) >> 3; /* round widths up to word boundary */
-
- /* For deinterleaving purposes, decompress (but don't store)
- any mask planes (if present). */
-
- if (bmhd->masking==mskHasMask) {
- maskplane=planes;
- planes++;
- }
-
- for (i=0;i<bmhd->h;i++) /* process n lines/screen */
- for (plane=0;plane<planes;plane++) { /* process n planes/line */
-
- if (plane!=maskplane) destbuf=(char *)(bitmap->Planes[plane])+rowlen*i;
-
- if (bmhd->compression==cmpByteRun1) { /* compressed screen? */
- rowbytes=rowlen;
-
- while (rowbytes>0) { /* unpack until 1 scan-line complete */
- n=*sourcebuf++; /* fetch block run marker */
-
- /* uncompressed block? copy n bytes verbatim */
- if (n>=0) {
- ++n;
- if (plane!=maskplane) {
- movmem(sourcebuf,destbuf,(unsigned int)n);
- destbuf+=n;
- }
- rowbytes-=n; sourcebuf+=n;
- }
- else { /* compressed block? expand n duplicate bytes */
- n=-n+1;
- if (plane!=maskplane) {
- memset(destbuf,(int)(*sourcebuf),(int)n);
- destbuf+=n;
- }
- rowbytes -=n; sourcebuf++;
- }
-
- } /* finish unpacking line */
- if (rowbytes) return(EXPAND_ERR); /* shouldn't be any left over! */
- }
- else { /* uncompressed? just copy */
- if (plane!=maskplane) {
- movmem(sourcebuf,destbuf,(unsigned int)rowlen);
- destbuf+=rowlen;
- }
- sourcebuf+=rowlen;
- }
- } /* finish interleaved planes, lines */
-
- return(0); /* good result! */
- }
-