home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
libraries
/
ilbm
/
c
/
iffinfo.c
next >
Wrap
C/C++ Source or Header
|
1991-02-15
|
11KB
|
342 lines
/* Ilbm.library C application, PicInfo.c:
Set your editor's TAB width to 3
cc +p IFFinfo.c
as -cd IlbmInterface.asm
ln -o IFFinfo IFFinfo.o IlbmInterface.o -lcl32
This program can only be run from the CLI. It takes 1 arg, the name of a
file. This program will then print information about the file. For ILBMs and
ANIMs, it will print out information from the BHMD(s) such as image width,
height, depth, etc. For other IFF files, it will simply print the chunk IDs
as it encounters them. For ANIMs, it will total the number of "frames"
(ILBMs) in the file. Note that the library automatically dives into LISTS
and CATS on our behalf. We don't even have to know that we are inside of a
LIST or CAT.
This is an example of using the library's mid-level routine LoadILBM() with
our own FORM and PROP handlers instead of lib's default routines. This is the
way to go if you need an ANIM reader or some non-ILBM reader/writer. Note
that if our FORMHandler wasn't interested in ILBMs or ANIMs, we wouldn't need
an ILBMFrame, and would use LoadIFF() instead of LoadILBM().
*/
#include "math.h"
#include "functions.h" /* Manx C declarations */
#include "exec/tasks.h"
#include "exec/types.h"
#include "exec/memory.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
/* The ilbm lib C INCLUDE file */
#include "ILBM_Lib.h"
/*-------------------------------defines---------------------------------*/
IFFP myForm();
IFFP myProp();
/* Data for the Dissidents ILBM library */
struct ILBMBase *ILBMBase=0L;
ILBMFrame myILBMFrame; /* Whenever we plan on parsing an ILBM
or ANIM, we need an ILBMFrame */
/* Data for our program */
struct FileHandle *fp = 0;
SHORT numFrames = -1; /* To count the # of frames in an ANIM */
UBYTE handled_anim = 0; /* To tell main() that we found an ANIM */
/*------------------------------start of main()----------------------------*/
main( argc, argv )
LONG argc;
UBYTE *argv[];
{
IFFP Result;
/* LoadILBM() and LoadIFF() need a Vectors structure */
Vectors myVectors;
/* We expect the filename for the first arg. */
if( argc != 2 )
{
printf("USAGE: IFFinfo filename\n");
exit();
}
/* Open the ILBM lib */
if( (ILBMBase=(struct ILBMBase *)OpenLibrary("ilbm.library", 0L)) == NULL )
{
printf("Need the dissidents ilbm.library on boot disk\n");
exit();
}
/* Note that we are using the lib's middle level functions so that we can
install our own handlers for each encountered group and context. Also,
we can parse any IFF FORM, not just ILBMs and ANIMs using this level.
Unlike the lib's high level ILBM functions LoadIFFToWindow() and
SaveWindowToIFF(), the mid level functions don't open the IFF file for us.
We are going to install our own function, myForm(), as the routine
which the library calls whenever it encounters a FORM ID. Our function,
myProp() will be called for non-ILBM PROPS. (Remember, the library
automatically handles all ILBM PROPS by parsing info into a PropILBMFrame.)
We "install" these routines by setting up the appropriate fields in our
Vectors structure. Let's do all this now. */
/* Open the IFF File */
fp = Open( argv[1], MODE_OLDFILE );
if (fp)
{
/* Setup the Vectors structure. (i.e. "install" myForm() and myProp()) */
myVectors.PROPhandler = myProp;
myVectors.FORMhandler = myForm;
myVectors.CHUNKhandler = 0;
myVectors.NonILBMhandler = 0;
/* Don't care about CHUNKhandler or NonILBMhandler as long as we have
our own FORMhandler. */
myILBMFrame.iUserFlags=0;
/* Start parsing the file */
Result=LoadILBM( fp, &myVectors, &myILBMFrame );
/* O.K. we're back. Did we successfully parse as much as we wanted?
Well, our FORM routine should have returned IFF_OKAY if we parsed
the entire file. Otherwise, myForm, myProp, or an internal library
routine knocked us out by returning some other IFFP error code. Let's
get an informative error msg to display.
*/
/* If some error, get the IFFP error message and print it */
if( Result != IFF_OKAY )
{
puts( GetIFFPMsg( Result ) );
}
else /* If it was an ANIM we inspected, show the # of frames */
{
if( handled_anim )
printf("Number of Frames = %d", numFrames+1);
}
/* Close the IFF File */
Close(fp);
}
else printf( "Couldn't open %s. \n", argv[1]);
printf("\n");
/* Close ILBM lib */
if( ILBMBase ) CloseLibrary( ILBMBase );
exit();
} /* end of main() */
/*========= LoadILBM() or LoadIFF() calls me when it finds a FORM ==========*/
IFFP myForm( chunkID, context, vectors, frame, proplist )
PROPList *proplist;
ILBMFrame *frame;
Vectors *vectors;
GroupContext *context;
ID chunkID;
{
register IFFP code = IFF_OKAY;
register ULONG propf;
BitMapHeader bmhdr;
/* Print the FORM ID */
printf("========= FORM %c%c%c%c =========\n",
(char) ((chunkID>>24L) & 0x7F),
(char) ((chunkID>>16L) & 0x7F),
(char) ((chunkID>>8) & 0x7F),
(char) (chunkID & 0x7F) );
/* --------------------- ANIM HEADER ------------------------- */
/* If an ANIM, reset our frame count and ANIM flags of iUserFlags.
Then parse the "frames" (imbedded ILBMs) of the ANIM. Note that
GetF1ChunkHdr actually calls our myForm() routine for each imbedded
ILBM "frame of animation" (i.e. this function is recursive). */
if (chunkID == ID_ANIM)
{
/* set ANIMFLAG of iUserFlags to indicate that we're in an ANIM */
frame->iUserFlags |= ANIMFLAG;
/* clear HANDLED_ANIM to indicate that we aren't successful yet */
handled_anim = 0;
numFrames = -1; /* first frame number will be 0 */
/* Parse each frame of the ANIM */
while (code >= 0)
{
code = GetF1ChunkHdr(context);
}
/* If we didn't get END_MARK back, then an error */
if (code == END_MARK)
{
/* set HANDLED_ANIM to indicate that we successfully handled the ANIM */
handled_anim = 1;
code = IFF_OKAY; /* So that we continue parsing any more FORMs in
the file */
}
}
/* ---------------------- ILBM FORMS (ANIM "frames") -------------------- */
if (chunkID == ID_ILBM )
{
/* Parse an ILBM or an ANIM "frame" (which is also an ILBM) */
/* If there was an ILBM PROP for this group, copy the PROPFrame to our
ILBMFrame.
Note: SearchPROP() can return any kind of frame. Here, it is an
ILBMFrame since chunkID == ID_ILBM. If we needed to reference
anything in the returned pointer, we would have to recast it as
an (ILBMFrame *).
*/
if( !(propf = SearchPROP( chunkID, proplist )) )
CopyILBMProp( propf, frame );
if( frame->iUserFlags & ANIMFLAG )
{
++numFrames; /* 1 more "frame" */
printf( "--- Frame #%d ---\n", numFrames+1 );
}
while( code >= 0 ) /* Negative numbers are errors, 0 means "ok, continue"
and positive numbers are IFF chunk IDs
*/
{
/* Move to the start of the next chunk */
code = GetFChunkHdr( context );
if (code > 0 )
/* Here's a chunk ID. If this were a REAL program, we'd probably
check to see if this is a chunk that we want to parse. If so, we
could get the chunksize from the context structure, read the chunk
into memory, and do something with the data. For example, like
what I did with the BMHD chunk. Or maybe like this:
bytes = ChunkMoreBytes( context );
if( !( memptr = AllocMem( bytes, 0L ) ))
{
code = IFFReadBytes( bytes, context, memptr );
}
*/
{
printf(" %c%c%c%c\n",
(char) ( (code>>24L) & 0x7F),
(char) ( (code>>16L) & 0x7F),
(char) ( (code>>8) & 0x7F),
(char) ( code & 0x7F) );
if( code == ID_BMHD )
{
/* Print out info about the image */
code = GetBMHD(context, &bmhdr);
if( code == IFF_OKAY )
{
printf(" width=%d, height=%d, depth=%d\n",
bmhdr.w, bmhdr.h, bmhdr.nPlanes);
}
}
}
}
}
/* --------------------- Non-ILBM FORMS --------------------- */
else
{
/* A REAL program would normally search the PROPList for any frames
of the same type, and if found extract needed info from it.
See notes in myProp() */
while( code >= 0 )
{
code = GetF1ChunkHdr(context);
if (code > 0)
/* Here's a chunk ID. If this were a REAL program, we'd probably
do something useful with it.
*/
{
printf(" %c%c%c%c\n",
(char) ( (code>>24L) & 0x7F),
(char) ( (code>>16L) & 0x7F),
(char) ( (code>>8) & 0x7F),
(char) ( code & 0x7F) );
}
}
}
/*
As long as we rtn IFF_OKAY, the library will continue parsing the IFF
file (until it gets to the end). If we rtn any other value, the library will
return us back to main() from LoadILBM() with that value. For example, if
we return IFF_DONE, we would return from LoadILBM with IFF_DONE.
Note: the library routines GetFChunkHdr and GetF1ChunkHdr will return
END_MARK when there's no more chunks in this FORM. In that case, we should
know whether we found what we wanted in this FORM. If we did, we return
IFF_OKAY to continue parsing the next FORM (we may be inside of a LIST or
CAT), or IFF_DONE if we want to get out with what we've got. If we didn't
find what we want, we would return IFF_OKAY to continue parsing.
In this example, we're looking for everything, so we always return IFF_OKAY
when GetFChunkHdr or GetF1ChunkHdr returns END_MARK.
*/
if (code == END_MARK)
{
/* Print a double-spaced line inbetween forms */
puts("=============================\n");
code = IFF_OKAY;
}
return( code );
}
/*========= LoadILBM() or LoadIFF() calls me when it finds a PROP ==========*/
IFFP myProp( chunkID, propID, context, vectors, frame, proplist )
PROPList *proplist;
ILBMFrame *frame;
Vectors *vectors;
GroupContext *context;
ID propID;
ID chunkID;
{
/* We only hear about non-ILBM PROPS. If this were a REAL program, we
would probably allocate some PROPFrame that we defined for the passed
propID (an SMUSPropFrame for an ID_SMUS maybe?). Then we would
parse the PROP's chunks just like in the FORMhandler, storing info in
this new PROPFrame. Later, in our FORMHandler, we search the PROPList
for the appropriate ID and retrieve the info. The library automatically
updates the PROPList when it gets to the end of an IFF group so that you
don't have to keep track of which level you're at and which PROPS affect
which chunks. Also, the library frees all PROPFrames that you allocate
with GetPROPStruct() by the time we return to main. */
/* Print the PROP ID */
printf(" PROP %c%c%c%c\n",
(char) ((chunkID>>24L) & 0x7F),
(char) ((chunkID>>16L) & 0x7F),
(char) ((chunkID>>8) & 0x7F),
(char) (chunkID & 0x7F) );
return( IFF_OKAY );
}