home *** CD-ROM | disk | FTP | other *** search
- #include "iff.h"
-
- extern void *IntuitionBase,*GfxBase,*DiskfontBase;
-
- /* READILBM.C : NewZAP support routines - (c) 1986 John Hodgson */
-
- #define DISK_ERR 1 /* error processing */
- #define IFF_ERR 2
- #define OUT_OF_MEM 3
- #define EXPAND_ERR 4
- #define BAD_MODE 5
-
- #define MakeID(a,b,c,d) ((a)<<24L | (b)<<16L | (c)<<8 | (d))
-
- #define ID_FORM MakeID('F','O','R','M')
- #define ID_ILBM MakeID('I','L','B','M')
- #define ID_BMHD MakeID('B','M','H','D')
- #define ID_CAMG MakeID('C','A','M','G')
- #define ID_CMAP MakeID('C','M','A','P')
- #define ID_BODY MakeID('B','O','D','Y')
-
- #define cmpByteRun1 1
-
- #define ROUNDODDUP(a) (((a)+1)&(~1L))
-
- typedef struct {
- long ckID,ckSize;
- } Chunk;
-
- typedef struct {
- short w,h,x,y;
- char nPlanes,masking,compression,pad1;
- short transparentColor;
- char xAspect, yAspect;
- short pageWidth,pageHeight;
- } BitMapHeader;
-
- short Mode;
- unsigned char *pdiskptr;
-
- #define SafeRead(a,b,c) if (ReadNEW(a,b,c)==-1L) \
- { CloseNEW(a); return(DISK_ERR); }
-
- void *AllocMem(),*AllocRaster();
-
- /************************************************************************
- * *
- * 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 TRUE 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 masking, CATS/LISTS/PROPS. *
- * All other graphics (compressed or not) supported. *
- ************************************************************************/
-
- void *OpenNEW(name,accessMode)
- unsigned char *name;
- long accessMode;
- {
- struct FileHandle *Open();
-
- if (!Mode) return(Open(name,accessMode));
-
- pdiskptr=name; /* initialize pseudo-disk RAM ptr */
- return(pdiskptr);
- }
-
- long ReadNEW(file,buffer,length)
- struct FileHandle *file;
- char *buffer;
- long length;
- {
- long Read();
-
- if (!Mode) return(Read(file,buffer,length));
-
- movmem(pdiskptr,buffer,(unsigned int)length);
- pdiskptr+=length;
-
- return(length);
- }
-
- long SeekNEW(file,position,tmode)
- struct FileHandle *file;
- long position,tmode;
- {
- long Seek();
-
- if (!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(file)
- struct FileHandle *file;
- {
- if (!Mode) Close(file);
- }
-
- /* tag : core routines live here! */
-
- ReadILBM(fspec,mode,picmap)
- char *fspec; /* AmigaDOS filename */
- short mode;
- struct PicMap *picmap;
- {
- struct FileHandle *fp;
- Chunk header;
- BitMapHeader bmhd;
- unsigned char colormap[MAXCOLORS][3],*bufstart,*sourcebuf;
- short i;
- long id;
-
- Mode=mode;
- setmem(picmap,sizeof(*picmap),0L);
-
- if (!(fp=OpenNEW(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: SafeRead(fp,&colormap[0][0],(long)header.ckSize);
-
- for (i=0;i<header.ckSize/3;i++)
- picmap->colormap[i]=colormap[i][2]>>4 |
- colormap[i][1] & 0xf0 |
- (colormap[i][0] & 0xf0)<<4;
- 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 if decompression */
-
- if (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);
-
- /* if we -REALLY- need a blank page, zero after allocating! */
-
- for (i=0;i<bmhd.nPlanes;i++)
- if (!(picmap->BitMap.Planes[i]=AllocRaster((long)bmhd.w,(long)bmhd.h))) {
- FreeBitMap(&picmap->BitMap);
- return(OUT_OF_MEM);
- }
-
- i=Expand(&bmhd,bufstart,&picmap->BitMap);
-
- if (!Mode) FreeMem(bufstart,(long)header.ckSize);
-
- return(i); /* error if unpacking prob */
- }
-
- FreeBitMap(bitmap)
- 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]) FreeRaster(
- bitmap->Planes[i],(long)bitmap->BytesPerRow*8,(long)bitmap->Rows);
- }
-
- setmem(bitmap,sizeof(bitmap),0L); /* prevent dbl-dealloc errs */
- }
-
- Expand(bmhd,sourcebuf,bitmap) /* Fast line decompress/deinterleave */
- BitMapHeader *bmhd;
- register char *sourcebuf;
- struct BitMap *bitmap;
- {
- register char n,*destbuf; /* in order of preferred allocation */
- register short plane,rowlen,rowbytes,i;
-
- rowlen=(bmhd->w)>>3;
-
- for (i=0;i<bmhd->h;i++) /* process n lines/screen */
- for (plane=0;plane<bmhd->nPlanes;plane++) { /* process n planes/line */
- 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;
- movmem(sourcebuf,destbuf,(unsigned int)n);
- rowbytes-=n; destbuf+=n; sourcebuf+=n;
- }
- else { /* compressed block? expand n duplicate bytes */
- n=-n+1;
- setmem(destbuf,(unsigned int)n,(unsigned int)*sourcebuf);
- rowbytes -=n; sourcebuf++; destbuf+=n;
- }
-
- } /* finish unpacking line */
- if (rowbytes) return(EXPAND_ERR); /* shouldn't be any left over! */
- }
- else { /* uncompressed? just copy */
- movmem(sourcebuf,destbuf,(unsigned int)rowlen);
- sourcebuf+=rowlen; destbuf+=rowlen;
- }
- } /* finish interleaved planes, lines */
-
- return(0); /* good result! */
- }
-