home *** CD-ROM | disk | FTP | other *** search
- /* ILBM picture reader etc. for PUZZ M.J.Round January 1990
- Largely copied from 'view.c' by D. John Hodgson.
- */
-
- #define SR(a,b,c) if (Read(a,(char *)b,c)==-1L) return(NULL);
-
- #define MAXWIDTH 376 /* max non-HIRES width */
- #define MAXHEIGHT 242 /* max non-interlaced height (NTSC) */
- #define MAXCOLORS 32 /* max # colors supported */
-
- #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')
-
- typedef struct
- {
- long ckID,ckSize;
- } Chunk;
-
- Chunk header;
- char *bufstart;
- struct BitMap b;
- struct RastPort rp;
- struct RastPort dbuffrastport;
- struct BitMap dbuffbitmap;
-
- extern struct IntuitionBase *IntuitionBase;
- extern struct GfxBase *GfxBase;
- extern BitMapHeader bmhd;
- extern struct TextAttr MyFont;
-
- struct Screen *ReadILBM(BPTR fp)
- {
- struct NewScreen NewScreen;
- struct Screen *screen;
- char colormap[MAXCOLORS][3],*sourcebuf;
- short colorcount;
- long id,ViewModes=0;
-
- SR(fp,&header,(long)sizeof(header));
- if (header.ckID!=ID_FORM) return(NULL);
-
- SR(fp,&id,(long)sizeof(id));
- if (id!=ID_ILBM) return(NULL);
-
- for (;;)
- {
- SR(fp,&header,(long)sizeof(header));
-
- if (header.ckID==ID_BODY) break;
-
- switch(header.ckID)
- {
- case ID_BMHD:
- SR(fp,&bmhd,(long)sizeof(bmhd));
- break;
-
- case ID_CMAP:
- SR(fp,&colormap[0][0],(long)header.ckSize);
- colorcount=header.ckSize/3;
- break;
-
- case ID_CAMG:
- SR(fp,&ViewModes,(long)header.ckSize);
- break;
-
- default:
- Seek(fp,(((header.ckSize)+1)&(~1L)),OFFSET_CURRENT);
-
- }
- }
-
- /* Read planes into RAM for ease of decompression */
-
- sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC);
- if (sourcebuf==0L) return (NULL);
-
- SR(fp,sourcebuf,(long)header.ckSize);
-
- NewScreen.LeftEdge=0; NewScreen.TopEdge=0;
- NewScreen.Width=bmhd.w; NewScreen.Height=bmhd.h;
- NewScreen.Depth=bmhd.nPlanes;
-
- /* make some forced assumptions if CAMG chunk unavailable */
-
- if (!(NewScreen.ViewModes=ViewModes))
- {
- if (bmhd.w>MAXWIDTH) NewScreen.ViewModes|=HIRES;
- if (bmhd.h>MAXHEIGHT) NewScreen.ViewModes|=LACE;
- }
-
- NewScreen.Type=CUSTOMSCREEN;
- NewScreen.Font=&MyFont;
- NewScreen.Gadgets=0L;
-
- screen=OpenScreen(&NewScreen);
-
- while (colorcount--)
- SetRGB4
- (
- &screen->ViewPort,
- (long)colorcount,
- colormap[colorcount][0]>>4L,colormap[colorcount][1]>>4L,
- colormap[colorcount][2]>>4L
- );
-
- return(screen);
- }
-
- void Expand(screen,bmhd) /* Fast line decompress/deinterleave */
- struct Screen *screen;
- BitMapHeader *bmhd;
- {
- register char *sourcebuf;
- register char n,*destbuf; /* in order of preferred allocation */
- register short plane,linelen,rowbytes,i;
-
- sourcebuf = bufstart;
- linelen=bmhd->w/8;
-
- for (i=0;i<bmhd->h;i++) /* process n lines/screen */
- {
- for (plane=0;plane<bmhd->nPlanes;plane++)
- { /* process n planes/line */
- destbuf=(char *)(screen->BitMap.Planes[plane])+linelen*i;
-
- if (bmhd->compression== 1)
- { /* 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
- { /* compr. 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;
- }
- } /* finish interleaved planes, lines */
- }
- }
-
- struct RastPort *getbuffs(int width,int height)
- {
- int i;
-
- InitBitMap(&b,bmhd.nPlanes,bmhd.w,11);
-
- for (i=0; i<bmhd.nPlanes; i++)
- {
- b.Planes[i] = (PLANEPTR)AllocRaster(bmhd.w,11);
- if(b.Planes[i] == NULL)
- {
- while (--i >= 0)
- FreeRaster(b.Planes[i],bmhd.w,11);
-
- return (NULL);
- }
- }
-
- InitRastPort(&rp);
- rp.BitMap = &b;
-
- InitBitMap(&dbuffbitmap,bmhd.nPlanes,width,height);
-
- for (i=0; i<bmhd.nPlanes; i++)
- {
- dbuffbitmap.Planes[i] = (PLANEPTR)AllocRaster(width,height);
- if(dbuffbitmap.Planes[i] == NULL)
- {
- while (--i >= 0)
- FreeRaster(dbuffbitmap.Planes[i],width,height);
-
- return (NULL);
- }
- }
-
- InitRastPort(&dbuffrastport);
- dbuffrastport.BitMap = &dbuffbitmap;
-
- return (&dbuffrastport);
- }
-
- void saveundermenu(struct RastPort *rast)
- {
- ClipBlit
- (
- rast,0,0 /* source posn */
- ,&rp,0,0 /* dest posn */
- ,bmhd.w,11 /* size */
- ,0xc0 /* direct copy */
- );
- }
-
- void drawovermenu(struct RastPort *rast)
- {
- ClipBlit
- (
- &rp,0,0 /* source posn */
- ,rast,0,0 /* dest posn */
- ,bmhd.w,11 /* size */
- ,0xc0 /* direct copy */
- );
- }
-
- void freebuffs(int width,int height)
- {
- int i;
-
- for (i=0; i<bmhd.nPlanes; i++)
- FreeRaster(dbuffbitmap.Planes[i],width,height);
-
- for (i=0; i<bmhd.nPlanes; i++)
- FreeRaster(b.Planes[i],bmhd.w,11);
-
- FreeMem(bufstart,(long)header.ckSize); /* free compressed buffer */
- }
-