home *** CD-ROM | disk | FTP | other *** search
- /** PreLoadAnim.c ***********************************************************
- *
- * Load an ILBM raster image file into memory structures
- * This is a modified version of ReadPict.c dated 23-Jan-86.
- *
- * Modified by Gary Bonham, SPARTA, Inc. 15 Aug 1986
- * Modified by Olaf `Olsen' Barthel, 16-Sep-1991
- *
- ***************************************************************************/
-
- #include <intuition/intuition.h>
- #include <libraries/dosextens.h>
- #include <exec/memory.h>
-
- #include "ilbm.h"
- #include "readpict.h"
- #include "preloadanim.h"
-
- /* This example's max number of planes in a bitmap. Could use MaxAmDepth. */
-
- #define EXDepth 5
- #define maxColorReg (1 << EXDepth)
-
- #define GetANHD(context,anHdr) IFFReadBytes(context,(BYTE *)anHdr,sizeof(AnimationHeader))
-
- STATIC IFFP GetCMAP(GroupContext *ilbmContext,WORD *colorMap,UBYTE *pNColorRegs);
- STATIC IFFP GetPrILBM(GroupContext *parent);
- STATIC IFFP GetLiILBM(GroupContext *parent);
- STATIC IFFP GetFoANIM(GroupContext *parent);
- STATIC IFFP __regargs PreLoadAnimation(BPTR file,ILBMFrame *iFrame);
- VOID ClosePreLoadIFF(VOID);
- BYTE OpenPreLoadIFF(BPTR file);
-
- extern struct Screen *Screen;
- struct IFFfile *IFFfileList;
-
- /*------------ ILBM reader -----------------------------------------------*/
- /* ILBMFrame is our "client frame" for reading FORMs ILBM in an IFF file.
- * We allocate one of these on the stack for every LIST or FORM encountered
- * in the file and use it to hold BMHD & CMAP properties. We also allocate
- * an initial one for the whole file.
- * We allocate a new GroupContext (and initialize it by OpenRIFF or
- * OpenRGroup) for every group (FORM, CAT, LIST, or PROP) encountered. It's
- * just a context for reading (nested) chunks.
- *
- * If we were to scan the entire example file outlined below:
- * reading proc(s) new new
- *
- * --whole file-- ReadPicture+ReadIFF GroupContext ILBMFrame
- * CAT ReadICat GroupContext
- * LIST GetLiILBM+ReadIList GroupContext ILBMFrame
- * PROP ILBM GetPrILBM GroupContext
- * CMAP GetCMAP
- * BMHD GetBMHD
- * FORM ILBM GetFoILBM GroupContext ILBMFrame
- * BODY GetBODY
- * FORM ILBM GetFoILBM GroupContext ILBMFrame
- * BODY GetBODY
- * FORM ILBM GetFoILBM GroupContext ILBMFrame
- */
-
- /* ---------- GetCMAP ------------------------------------------------*/
- /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
- * caller has space to hold. GetCMAP sets to the number actually read.*/
-
- STATIC IFFP
- GetCMAP(GroupContext *ilbmContext,WORD *colorMap,UBYTE *pNColorRegs)
- {
- ColorRegister colorReg;
- LONG nColorRegs;
- IFFP iffp;
-
- nColorRegs = ilbmContext -> ckHdr . ckSize / sizeof(ColorRegister);
-
- if(*pNColorRegs < nColorRegs)
- nColorRegs = *pNColorRegs;
-
- *pNColorRegs = nColorRegs; /* Set to the number actually there.*/
-
- while(nColorRegs--)
- {
- iffp = IFFReadBytes(ilbmContext,(BYTE *)&colorReg,sizeof(ColorRegister));
-
- CheckIFFP();
-
- *colorMap++ = ((UWORD)(colorReg . red >> 4 ) << 8 ) | ((UWORD)(colorReg . green & 0x0F0)) | ((UWORD)(colorReg . blue >> 4));
- }
-
- return(IFF_OKAY);
- }
-
- /** GetPrILBM() *************************************************************
- *
- * Called via ReadPicture to handle every PROP encountered in an IFF file.
- * Reads PROPs ILBM and skips all others.
- *
- ****************************************************************************/
-
- STATIC IFFP
- GetPrILBM(GroupContext *parent)
- {
- IFFP iffp;
- GroupContext propContext;
- ILBMFrame *ilbmFrame = (ILBMFrame *)parent -> clientFrame;
-
- if(parent -> subtype != ID_ILBM)
- return(IFF_OKAY); /* just continue scanning the file */
-
- iffp = OpenRGroup(parent,&propContext);
-
- CheckIFFP();
-
- do
- {
- switch(iffp = GetPChunkHdr(&propContext))
- {
- case ID_BMHD:
- {
- ilbmFrame -> foundBMHD = TRUE;
-
- iffp = GetBMHD(&propContext,&ilbmFrame -> bmHdr);
- break;
- }
-
- case ID_CMAP:
- {
- ilbmFrame -> nColorRegs = maxColorReg;
-
- iffp = GetCMAP(&propContext,(WORD *)&ilbmFrame -> colorMap,&ilbmFrame -> nColorRegs);
- break;
- }
- }
- }
- while(iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
- * subroutine returned IFF_OKAY (no errors).
- */
-
- CloseRGroup(&propContext);
-
- return(iffp == END_MARK ? IFF_OKAY : iffp);
- }
-
- /** GetLiILBM() *************************************************************
- *
- * Called via ReadPicture to handle every LIST encountered in an IFF file.
- *
- ****************************************************************************/
-
- STATIC IFFP
- GetLiILBM(GroupContext *parent)
- {
- ILBMFrame newFrame; /* allocate a new Frame */
-
- newFrame = *(ILBMFrame *)parent -> clientFrame; /* copy parent frame */
-
- return(ReadIList(parent,(ClientFrame *)&newFrame));
- }
-
- /** GetFoANIM() *************************************************************
- *
- * Called via ReadPicture to handle every FORM encountered in an IFF file.
- * Reads FORMs ILBM and skips all others.
- * Inside a FORM ILBM, it stops once it reads a BODY. It complains if it
- * finds no BODY or if it has no BMHD to decode the BODY.
- *
- * Once we find a BODY chunk, we'll allocate the BitMap and read the image.
- *
- ****************************************************************************/
-
- STATIC IFFP
- GetFoANIM(GroupContext *parent)
- {
- IFFP iffp;
- GroupContext formContext;
- ILBMFrame ilbmFrame; /* only used for non-clientFrame fields.*/
-
- /* Handle a non-ILBM FORM. */
-
- if(parent -> subtype != ID_ILBM)
- {
- /* Open a non-ILBM FORM and recursively scan it for ILBMs.*/
-
- iffp = OpenRGroup(parent,&formContext);
-
- CheckIFFP();
-
- do
- {
- iffp = GetF1ChunkHdr(&formContext);
-
- if(iffp == IFF_DONE)
- iffp = IFF_OKAY;
- }
- while(iffp >= IFF_OKAY);
-
- if(iffp == END_MARK)
- iffp = IFF_DONE; /* then continue scanning the file */
-
- CloseRGroup(&formContext);
- return(iffp);
- }
-
- ilbmFrame = *(ILBMFrame *)parent -> clientFrame;
-
- iffp = OpenRGroup(parent,&formContext);
-
- CheckIFFP();
-
- if(!IFFfileList -> lastframe)
- {
- IFFfileList -> lastframe = (struct FrameHD *)AllocMem(sizeof(struct FrameHD),MEMF_PUBLIC|MEMF_CLEAR);
- IFFfileList -> firstframe = IFFfileList -> lastframe;
- }
- else
- {
- if(IFFfileList -> lastframe -> next = (struct FrameHD *)AllocMem(sizeof(struct FrameHD),MEMF_PUBLIC|MEMF_CLEAR))
- IFFfileList -> lastframe -> next -> prev = IFFfileList -> lastframe;
-
- IFFfileList -> lastframe = IFFfileList -> lastframe -> next;
- }
-
- if(!IFFfileList -> lastframe)
- return(END_MARK);
-
- do
- {
- switch(iffp = GetFChunkHdr(&formContext))
- {
- case ID_ANHD:
- {
- ilbmFrame . foundBMHD = TRUE;
-
- if(!(IFFfileList -> lastframe -> anhd = (AnimationHeader *)AllocMem(sizeof(AnimationHeader),MEMF_PUBLIC|MEMF_CLEAR)))
- {
- iffp = DOS_ERROR;
- break;
- }
-
- iffp = GetANHD(&formContext,IFFfileList -> lastframe -> anhd);
- break;
- }
-
- case ID_BMHD:
- {
- ilbmFrame . foundBMHD = TRUE;
-
- if(!(IFFfileList -> lastframe -> bmhd = (BitMapHeader *)AllocMem(sizeof(BitMapHeader),MEMF_PUBLIC|MEMF_CLEAR)))
- {
- iffp = DOS_ERROR;
-
- break;
- }
- else
- {
- iffp = GetBMHD(&formContext,IFFfileList -> lastframe -> bmhd);
-
- if(IFFfileList -> lastframe -> bmhd -> pageHeight < IFFfileList -> lastframe -> bmhd -> h)
- IFFfileList -> lastframe -> bmhd -> pageHeight = IFFfileList -> lastframe -> bmhd -> h;
-
- if(IFFfileList -> lastframe -> bmhd -> pageWidth < IFFfileList -> lastframe -> bmhd -> w)
- IFFfileList -> lastframe -> bmhd -> pageWidth = IFFfileList -> lastframe -> bmhd -> w;
-
- if(IFFfileList -> lastframe -> bmhd -> pageHeight != Screen -> Height || IFFfileList -> lastframe -> bmhd -> pageWidth != Screen -> Width || IFFfileList -> lastframe -> bmhd -> nPlanes != Screen -> RastPort . BitMap -> Depth)
- iffp = DOS_ERROR;
-
- break;
- }
- }
-
- case ID_CAMG:
- {
- ilbmFrame . foundCAMG = TRUE;
-
- if(!(IFFfileList -> lastframe -> camg = (CamgChunk *)AllocMem(sizeof(CamgChunk),MEMF_PUBLIC|MEMF_CLEAR)))
- {
- iffp = DOS_ERROR;
-
- break;
- }
- else
- {
- iffp = GetCAMG(&formContext,IFFfileList -> lastframe -> camg);
- break;
- }
- }
-
- case ID_CMAP:
- {
- IFFfileList -> lastframe -> nColorRegs = maxColorReg; /* we have room for this many */
-
- iffp = GetCMAP(&formContext,&IFFfileList -> lastframe -> cmap[0],&IFFfileList -> lastframe -> nColorRegs);
- break;
- }
-
- case ID_DLTA: /* at this point just read in delta chunk */
- case ID_BODY:
- {
- if(!ilbmFrame . foundBMHD)
- return(BAD_FORM); /* No BMHD chunk! */
-
- if(IFFfileList -> lastframe -> bodylength = formContext . ckHdr . ckSize)
- {
- if(!(IFFfileList -> lastframe -> body = (ULONG *)AllocMem(IFFfileList -> lastframe -> bodylength,MEMF_PUBLIC|MEMF_CLEAR)))
- {
- iffp = END_MARK;
-
- break;
- }
-
- IFFReadBytes(&formContext,(BYTE *)IFFfileList -> lastframe -> body,IFFfileList -> lastframe -> bodylength);
- }
-
- break;
- }
-
- case END_MARK: /* No BODY chunk! */
- {
- iffp = IFF_DONE;
- break;
- }
- }
- }
- while(iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
- * subroutine returned IFF_OKAY (no errors).
- */
-
- if(iffp != IFF_DONE)
- return(iffp);
-
- /* If we get this far, there were no errors. */
-
- CloseRGroup(&formContext);
-
- return(iffp);
- }
-
- STATIC IFFP __regargs
- PreLoadAnimation(BPTR file,ILBMFrame *iFrame)
- {
- iFrame -> clientFrame . getList = GetLiILBM;
- iFrame -> clientFrame . getProp = GetPrILBM;
- iFrame -> clientFrame . getForm = GetFoANIM;
- iFrame -> clientFrame . getCat = ReadICat ;
-
- /* Initialize the top-level client frame's property settings to the
- * program-wide defaults. This example just records that we haven't read
- * any BMHD property or CMAP color registers yet. For the color map, that
- * means the default is to leave the machine's color registers alone.
- * If you want to read a property like GRAB, init it here to (0, 0).
- */
-
- iFrame -> foundBMHD = FALSE;
- iFrame -> nColorRegs = 0;
-
- /* Store a pointer to the client's frame in a global variable so that
- * GetFoILBM can update client's frame when done. Why do we have so
- * many frames & frame pointers floating around causing confusion?
- * Because IFF supports PROPs which apply to all FORMs in a LIST,
- * unless a given FORM overrides some property.
- * When you write code to read several FORMs,
- * it is ssential to maintain a frame at each level of the syntax
- * so that the properties for the LIST don't get overwritten by any
- * properties specified by individual FORMs.
- * We decided it was best to put that complexity into this one-FORM example,
- * so that those who need it later will have a useful starting place.
- */
-
- if(IFFfileList = (struct IFFfile *)AllocMem(sizeof(struct IFFfile),MEMF_PUBLIC|MEMF_CLEAR))
- return(ReadIFF(file,(ClientFrame *)iFrame));
- else
- return(DOS_ERROR);
- }
-
- VOID
- ClosePreLoadIFF()
- {
- if(IFFfileList)
- {
- struct FrameHD *currentframe,*nextframe;
-
- currentframe = IFFfileList -> firstframe;
-
- while(currentframe)
- {
- if(currentframe -> bmhd)
- FreeMem(currentframe -> bmhd,sizeof(BitMapHeader));
-
- if(currentframe -> anhd)
- FreeMem(currentframe -> anhd,sizeof(AnimationHeader));
- if(currentframe -> camg)
- FreeMem(currentframe -> camg,sizeof(CamgChunk));
-
- if(currentframe -> body && currentframe -> bodylength)
- FreeMem(currentframe -> body,currentframe -> bodylength);
-
- nextframe = currentframe -> next;
-
- FreeMem(currentframe,sizeof(struct FrameHD));
-
- currentframe = nextframe;
- }
-
- FreeMem(IFFfileList,sizeof(struct IFFfile));
-
- IFFfileList = NULL;
- }
- }
-
- BYTE
- OpenPreLoadIFF(BPTR file)
- {
- ILBMFrame iframe;
-
- if(PreLoadAnimation(file,&iframe) != IFF_DONE)
- {
- ClosePreLoadIFF();
-
- return(FALSE);
- }
- else
- return(TRUE);
- }
-