/** ReadPict.c ************************************************************** * * Read an ILBM raster image file. 01/07/85. * * By Jerry Morrison, Steve Shaw, and Steve Hayes, Electronic Arts. * This software is in the public domain. * * USE THIS AS AN EXAMPLE PROGRAM FOR AN IFF READER. * * The IFF reader portion is essentially a recursive-descent parser. * This program will look into a CAT or LIST to find a FORM ILBM, but it * won't look inside another FORM type for a nested FORM ILBM. * * Modified for HAM images by Martin Hash. 12/20/86. * ****************************************************************************/ #include #include #include "df1:ilbm.h" #include "df1:readpict.h" /* LOCAL CONSTANTS */ /* Define the size of a temporary buffer used in unscrambling the ILBM rows.*/ #define bufSz 512 #define maxColorReg 32 /* EXTERNAL FUNCTIONS */ extern IFFP OpenRGroup(); extern IFFP GetFChunkHdr(); /* LOCAL VARIABLES */ static ILBMFrame iFrame; static BYTE bodyBuffer[bufSz]; static struct BitMap *bitmapptr; /*------------ 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 */ /** GetFoILBM() ************************************************************* * * 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. * ****************************************************************************/ IFFP GetFoILBM( parent ) GroupContext *parent; { IFFP iffp; GroupContext formContext; ILBMFrame ilbmFrame; /* only used for non-clientFrame fields.*/ if (parent->subtype != ID_ILBM) return(IFF_OKAY); /* just continue scaning the file */ ilbmFrame = *(ILBMFrame *)parent->clientFrame; iffp = OpenRGroup(parent, &formContext); CheckIFFP(); do { iffp = GetFChunkHdr(&formContext); if (iffp == ID_BMHD) { ilbmFrame.foundBMHD = TRUE; iffp = GetBMHD(&formContext, &ilbmFrame.bmHdr); } else if (iffp == ID_CMAP) { ilbmFrame.nColorRegs = maxColorReg; iffp = GetCMAP( &formContext, (WORD *)ilbmFrame.colorMap, &ilbmFrame.nColorRegs); } else if (iffp == ID_BODY) { if (!ilbmFrame.foundBMHD) return(BAD_FORM); /* No BMHD chunk! */ iffp = GetBODY( &formContext, bitmapptr, NULL, &ilbmFrame.bmHdr, bodyBuffer, (long)bufSz); if (iffp == IFF_OKAY) iffp = IFF_DONE; /* Eureka */ iFrame = ilbmFrame; } else if (iffp == END_MARK) iffp = BAD_FORM; } 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); } /** ReadPicture() *********************************************************** * * Read a picture from an IFF file, given a file handle open for reading. * Allocates BitMap using (*Allocator)(). * ****************************************************************************/ IFFP ReadPicture( file, bitmap, viewport ) LONG file; struct BitMap *bitmap; struct ViewPort *viewport; { IFFP iffp; iFrame.clientFrame.getList = SkipGroup; iFrame.clientFrame.getProp = SkipGroup; iFrame.clientFrame.getForm = GetFoILBM; 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; bitmapptr = bitmap; iffp = ReadIFF(file, (ClientFrame *)&iFrame); LoadRGB4( viewport, iFrame.colorMap, iFrame.nColorRegs ); return(iffp); }