#include #include /* Nice because it includes everything else */ #include #include "smalliff.h" /* Ali T. Ozer, Oct, Nov 1987 */ /* This code to read IFF pictures originally from D. John Hodgson's "view" ** program. LIMITATIONS : no masking, CATS/LISTS/PROPS. CAMG chunks ** are supported. */ /* Original Copyright: ** VIEW.C - tiny ILBM viewer; (c) 1986 DJH */ #define CRead(f,src,sz) if (Read (f, src, sz) == -1L) return (0); int ReadILBM (fp, pic) struct FileHandle *fp; /* An already "Open"ed AmigaDOS file handle */ PicInfoStruct *pic; { unsigned char cmap[MAXCOLORS][3]; ChunkHeader header; ID id; int cnt; CRead(fp, &header, (long)sizeof(ChunkHeader)); if (header.ckID != ID_FORM) return (0); /* Not IFF */ CRead(fp, &id, (long)sizeof(id)); if (id != ID_ILBM) return (0); /* Not ILBM */ while (1) { CRead(fp, &header, (long)sizeof(header)); if (header.ckID == ID_BODY) break; switch(header.ckID) { case ID_BMHD: CRead(fp, &(pic->bmhd), (long) sizeof(BitMapHeader)); break; case ID_CMAP: CRead(fp, &(cmap[0][0]), header.ckSize); pic->colorcount = (UBYTE)(header.ckSize/3); break; case ID_CAMG: CRead(fp, &(pic->viewmodes), header.ckSize); break; default: Seek(fp, WordAlign(header.ckSize), OFFSET_CURRENT); break; } } pic->rawsourcesize = header.ckSize; if ((pic->rawsource = AllocMem (header.ckSize, NULL)) == NULL) return (0); /* Not enough memory */ CRead(fp, pic->rawsource, header.ckSize); /* make some forced assumptions if CAMG chunk unavailable */ if (pic->viewmodes == NULL) { if (pic->bmhd.w > MAXWIDTH) pic->viewmodes |= HIRES; if (pic->bmhd.h > MAXHEIGHT) pic->viewmodes |= LACE; } for (cnt = 0; cnt < pic->colorcount; cnt++) { pic->colortable[cnt] = (((UWORD)cmap[cnt][0]) << 4L) | (((UWORD)cmap[cnt][1])) | (((UWORD)cmap[cnt][2]) >> 4L); }; return (1); } Expand(bm, bmhd, sourcebuf) /* Fast line decompress/deinterleave */ struct BitMap *bm; BitMapHeader *bmhd; register char *sourcebuf; { register char n,*destbuf; /* in order of preferred allocation */ register short plane,rowbytes; short linelen,i,curloc; linelen=bmhd->w/8; curloc = 0; for (i=0;ih;i++) { /* process n lines/screen */ for (plane=0;planenPlanes;plane++) { /* process n planes/line */ destbuf=(char *)(bm->Planes[plane])+curloc; if (bmhd->compression == cmpByteRun1) { /* compressed screen? */ rowbytes=linelen; while (rowbytes) { /* unpack until 1 scan-line complete */ n=*sourcebuf++; /* fetch block run marker */ /* uncompressed block? copy n bytes verbatim */ if (n>=0) { movmem(sourcebuf,destbuf,(unsigned int)++n); rowbytes-=n; destbuf+=n; sourcebuf+=n; } else { /* compressed block? expand n duplicate bytes */ n=-n+1; rowbytes-=n; setmem(destbuf,(unsigned int)n,(unsigned int)*sourcebuf++); destbuf+=n; } } /* finish unpacking line */ } else { /* uncompressed? just copy */ movmem(sourcebuf,destbuf,(unsigned int)linelen); sourcebuf+=linelen; destbuf+=linelen; } } /* finish interleaved planes, lines */ curloc += linelen; } }