home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * tiff2.c: Frame concept ILBM scanner.
- * Alpha Concept Prototype.
- *
- * All the code needed for an ILBM reader, except the stuff to process the
- * ILBM itself. New one with a twist - the "frame" idea.
- *
- * Managing all the interactions of end of context and properties and
- * data chunks is kind of a hassle to get right without groking all the
- * complexities of recursive data structures and parsing, etc. Frames
- * are an idea to make things a little easier. The client just creates
- * a frame structure and a couple of handlers for dealing with them in
- * a generic way. Then the client just has to fill in the details of the
- * frame by handling data chunks himself. At the end of the context,
- * the client gets handed a completed frame and he can go about his
- * business without concern for what got partly done or whatever.
- *
- * NOTE: This sucker ain't, like, totally done.
- *
- * Stuart Ferguson 8901.02
- * ewhac (Updated to 1.4 Beta) 8912.06
- * Latticeification 9005.31
- */
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <utility/hooks.h>
- #include <libraries/iffparse.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include "iffparse_protos.h"
- #include "iffparse.p"
-
- #define ID_ILBM MAKE_ID('I','L','B','M')
- #define ID_BODY MAKE_ID('B','O','D','Y')
- #define ID_BMHD MAKE_ID('B','M','H','D')
- #define ID_CMAP MAKE_ID('C','M','A','P')
- #define ID_CAMG MAKE_ID('C','A','M','G')
- #define ID_CRNG MAKE_ID('C','R','N','G')
-
-
- /*
- * Forward function declarations. (I hate ANSI.)
- */
- struct Frame *FindFrame (struct IFFHandle *, LONG);
- LONG MakeFrame (struct IFFHandle *, LONG, struct Frame *(*)(), LONG (*)());
- LONG __saveds __asm EnterFrame (register __a0 struct Hook *, register __a2 struct IFFHandle *, register __a1 LONG *);
- LONG __saveds __asm FramePurge (register __a0 struct Hook *, register __a2 struct LocalContextItem *, register __a1 LONG *);
- void DisplayILBM (struct ILBMframe *);
- void ProcessBody (struct IFFHandle *, struct ILBMframe *);
- void ProcessCycle (struct IFFHandle *, struct ILBMframe *);
- static struct ILBMframe *CreateILBMframe (struct IFFHandle *);
- static LONG FreeILBMframe (struct ILBMframe *);
-
- static long ilbmprops[] = {
- ID_ILBM, ID_BMHD,
- ID_ILBM, ID_CMAP,
- ID_ILBM, ID_CAMG
- };
-
- static long ilbmstops[] = {
- ID_ILBM, ID_BODY,
- ID_ILBM, ID_CRNG,
- };
-
-
- #define MAXCRNG 8
-
- /*
- * The "Frame" for a complete ILBM. This stupid one will just be the
- * sizes of each chunk (just to show that it works).
- */
- struct ILBMframe {
- LONG bmhd,body,cmap,camg;
- int ncrng;
- LONG crng[MAXCRNG];
- };
-
-
- struct Library *IFFParseBase;
-
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- struct IFFHandle *iff;
- struct ContextNode *top;
- struct ILBMframe *fr;
- long error;
- int foundilbm = 0;
-
- if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) {
- puts ("Cannot open library.");
- goto die;
- }
-
- /*
- * Create IFF file and open a DOS stream on it.
- */
- if (!(iff = AllocIFF())) {
- puts ("AllocIFF() failed.");
- goto die;
- }
-
- if (!(iff -> iff_Stream = Open (argv[1], MODE_OLDFILE))) {
- puts ("File open failed.");
- goto die;
- }
- InitIFFasDOS (iff);
-
- /*
- * Declare frame handlers for the ILBM format.
- */
- if (error = MakeFrame (iff, ID_ILBM, CreateILBMframe, FreeILBMframe))
- goto err;
-
- /*
- * Declare property, collection and stop chunks.
- * (You still have to do this because YOU handle the data.)
- */
- if (error = PropChunks (iff, ilbmprops, 3L))
- goto err;
- if (error = StopChunks (iff, ilbmstops, 2L))
- goto err;
-
- if (error = OpenIFF (iff, IFFF_READ))
- goto err;
-
- error = 0;
- while (!error) {
- /*
- * ParseIFF() will return on BODY and CRNG chunks
- * or when the frame is filled. In any case, we
- * should nab a frame for this context (even if
- * it's really NULL).
- */
- error = ParseIFF (iff, IFFPARSE_SCAN);
- fr = (struct ILBMframe *) FindFrame (iff, ID_ILBM);
-
- /*
- * At end of context, do something with the finished frame.
- * This code will scan and do the same thing with all the
- * ILBM FORM's in the file.
- */
- if (error == IFFERR_EOC) {
- foundilbm = 1;
- DisplayILBM (fr);
- error = 0;
- continue;
- }
-
- /*
- * Other errors are real and possibily nasty errors.
- */
- if (error)
- break;
-
- /*
- * We've hit data. Switch and decode.
- * Make sure it's inside a FORM, otherwise storing
- * data into the frame (if there even is one) is wrong.
- */
- top = CurrentChunk (iff);
- if (ParentChunk (top) -> cn_ID == ID_FORM)
- switch (top -> cn_ID) {
- case ID_BODY:
- ProcessBody (iff, fr);
- break;
- case ID_CRNG:
- ProcessCycle (iff, fr);
- break;
- }
- }
- err:
- if (error == IFFERR_EOF) {
- if (foundilbm)
- puts ("File scan complete.");
- else
- puts ("Failed to find a FORM ILBM.");
- } else
- printf ("File scan aborted (%ld)\n", error);
-
- die:
- if (iff) {
- CloseIFF (iff);
- if (iff -> iff_Stream)
- Close (iff -> iff_Stream);
- FreeIFF (iff);
- }
-
- if (IFFParseBase) CloseLibrary (IFFParseBase);
- }
-
-
- /*
- * Just show that something happened.
- */
- void
- DisplayILBM (fr)
- struct ILBMframe *fr;
- {
- int i;
-
- printf ("A Picture: BMHD:%ld, CMAP:%ld, CAMG:%ld, BODY:%ld\n",
- fr -> bmhd, fr -> cmap, fr -> camg, fr -> body);
- if (fr -> ncrng) {
- for (i = 0; i < fr -> ncrng; i++)
- printf ("CRNG:%ld ", fr -> crng[i]);
- printf ("\n");
- } else
- printf ("No CRNG chunks.\n");
- }
-
-
- /*
- * Process a BODY chunk in an ILBM. Just get the sizes of the various
- * properties and data for now.
- */
- void
- ProcessBody (iff, fr)
- struct IFFHandle *iff;
- struct ILBMframe *fr;
- {
- register struct StoredProperty *sp;
-
- printf ("Body.\n");
-
- if (sp = FindProp (iff, ID_ILBM, ID_BMHD))
- fr -> bmhd = sp -> sp_Size;
-
- if (sp = FindProp (iff, ID_ILBM, ID_CMAP))
- fr -> cmap = sp -> sp_Size;
-
- if (sp = FindProp (iff, ID_ILBM, ID_CAMG))
- fr -> camg = sp -> sp_Size;
-
- fr -> body = CurrentChunk (iff) -> cn_Size;
- }
-
-
- void
- ProcessCycle (iff, fr)
- struct IFFHandle *iff;
- struct ILBMframe *fr;
- {
- printf ("Cycle.\n");
-
- fr -> crng[fr -> ncrng ++] = CurrentChunk (iff) -> cn_Size;
- }
-
-
- /*
- * Demi-handler to create a new frame and init to default values.
- * The IFF is provided in case any default values are there.
- */
- static struct ILBMframe *
- CreateILBMframe (iff)
- struct IFFHandle *iff;
- {
- struct ILBMframe *f;
-
- if (!(f = (struct ILBMframe *) AllocMem ((LONG) sizeof (*f), 0L)))
- return NULL;
- printf ("Creating new frame: %lx\n", f);
-
- f -> bmhd = f -> body = f -> cmap = f -> camg = -1;
- f -> ncrng = 0;
- return f;
- }
-
-
- /*
- * Client call-back to free up his frame. Deletes frame and all
- * associated memory.
- */
- static LONG
- FreeILBMframe (f)
- struct ILBMframe *f;
- {
- printf ("Freeing frame: %lx\n", f);
- FreeMem (f, (LONG) sizeof (*f));
- return (0);
- }
-
-
- /*
- * ====
- * This stuff would be in the library to make the Frame management
- * capability available to all.
- * ====
- */
-
- struct FrameDescriptor {
- struct Frame *(*fd_Create)();
- LONG (*fd_Delete)();
- };
-
- struct FrameInstance {
- struct Frame *fi_Frame;
- struct IFFHandle *fi_iff; /* We need this pointer */
- };
-
- #define IFFLCI_FRAMEDESC MAKE_ID('f','d','e','s')
- #define IFFLCI_FRAME MAKE_ID('f','r','a','m')
-
- /*
- * Declare the handlers for a frame. Client provides functions for
- * creating and deleting frames and the library will call them at the
- * appropriate times (entering and exiting the specified FORM). These
- * function vectors get stored in a frame descriptor which will be
- * used by the generic entry and exit handlers.
- */
- LONG
- MakeFrame (iff, type, create_f, delete_f)
- struct IFFHandle *iff;
- LONG type;
- struct Frame *(*create_f)();
- LONG (*delete_f)();
- {
- register struct LocalContextItem *lci;
- register struct FrameDescriptor *fd;
- register LONG error;
- static struct Hook EnterHook = {
- { NULL },
- (ULONG (*)()) EnterFrame,
- NULL,
- NULL
- };
-
- if (!(lci = AllocLocalItem (type, 0L, IFFLCI_FRAMEDESC,
- (long) sizeof (*fd))))
- return (IFFERR_NOMEM);
-
- fd = (struct FrameDescriptor *) LocalItemData (lci);
- fd -> fd_Create = create_f;
- fd -> fd_Delete = delete_f;
-
- if (error = StoreLocalItem (iff, lci, IFFSLI_TOP))
- goto fail;
- if (error = EntryHandler
- (iff, type, ID_FORM, IFFSLI_TOP, &EnterHook, (APTR)iff))
- goto fail;
- if (error = StopOnExit (iff, type, ID_FORM))
- goto fail;
- return (0);
-
- fail:
- FreeLocalItem (lci);
- return (error);
- }
-
-
- /*
- * Returns the current frame for the given context.
- */
- struct Frame *
- FindFrame (iff, type)
- struct IFFHandle *iff;
- LONG type;
- {
- struct LocalContextItem *lci;
-
- if (!(lci = FindLocalItem (iff, type, 0L, IFFLCI_FRAME)))
- return (NULL);
-
- return (((struct FrameInstance *) LocalItemData (lci)) -> fi_Frame);
- }
-
-
- /*
- * On entering the FORM associated with a frame, create a new
- * frame and store it for this context.
- */
- LONG __saveds __asm
- EnterFrame (
- register __a0 struct Hook *hook,
- register __a2 struct IFFHandle *iff,
- register __a1 LONG *cmd
- )
- {
- struct LocalContextItem *lci;
- struct ContextNode *cn;
- struct FrameInstance *fi;
- struct FrameDescriptor *fd;
- LONG error, type;
- static struct Hook PurgeHook = {
- { NULL },
- (ULONG (*)()) FramePurge,
- NULL,
- NULL
- };
-
- cn = CurrentChunk (iff);
- type = cn -> cn_Type;
-
- if (!(lci = FindLocalItem (iff, type, 0L, IFFLCI_FRAMEDESC))) {
- puts ("It's where you thought.");
- return (IFFERR_NOSCOPE);
- }
-
- fd = (struct FrameDescriptor *) LocalItemData (lci);
-
- if (!(lci = AllocLocalItem (type, 0L, IFFLCI_FRAME,
- (LONG) sizeof (*fi))))
- return (IFFERR_NOMEM);
- fi = (struct FrameInstance *) LocalItemData (lci);
-
- fi -> fi_iff = iff;
- if (!(fi -> fi_Frame = (*(fd -> fd_Create)) (iff))) {
- error = IFFERR_NOMEM;
- goto fail;
- }
- SetLocalItemPurge (lci, &PurgeHook);
-
- if (error = StoreLocalItem (iff, lci, IFFSLI_TOP))
- goto fail;
- return (0);
-
- fail:
- FreeLocalItem (lci);
- return (error);
- }
-
-
- /* What's this, Stu?
- *
- * Hmmm.. What's what? <whistle, whistle ...>
- *
- static LONG
- ExitFrame (hook, iff, cn)
- struct Hook *hook;
- struct IFFHandle *iff;
- LONG *cmd;
- {
- }
- *
- */
-
-
- LONG __saveds __asm
- FramePurge (
- register __a0 struct Hook *hook,
- register __a2 struct LocalContextItem *lci,
- register __a1 LONG *cmd
- )
- {
- struct FrameInstance *fi;
- struct FrameDescriptor *fd;
-
- fi = (struct FrameInstance *) LocalItemData (lci);
-
- fd = (struct FrameDescriptor *) LocalItemData (FindLocalItem
- (fi -> fi_iff, lci -> lci_Type, 0L, IFFLCI_FRAMEDESC));
-
- (*(fd -> fd_Delete)) (fi -> fi_Frame);
-
- FreeLocalItem (lci);
- return (0);
- }
-
- /*
- * Disable Lattice's default ^C trap.
- */
- chkabort ()
- {
- return (0);
- }
-
- CXBRK ()
- {
- return (0);
- }
-