fix: some file didn't have the svn:eol-style native yet

This commit is contained in:
erwin.coumans
2010-03-06 15:23:36 +00:00
parent 4fd48ac691
commit 81f04a4d48
641 changed files with 301123 additions and 301123 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,233 +1,233 @@
/*---------------------------------------------------------------------*
* IFFCheck.C Print out the structure of an IFF-85 file, 11/19/85
* checking for structural errors.
*
* DO NOT USE THIS AS A SKELETAL PROGRAM FOR AN IFF READER!
* See ShowILBM.C for a skeletal example.
*
* Original version was for the Commodore-Amiga computer.
/* This version is compatible with PC, OSX, PS3, Wii, iPhone. 10/26/2008
*----------------------------------------------------------------------*/
#include "iff.h"
#include "stdlib.h" //for exit
/* ---------- IFFCheck -------------------------------------------------*/
/* [TBD] More extensive checking could be done on the IDs encountered in the
* file. Check that the reserved IDs "FOR1".."FOR9", "LIS1".."LIS9", and
* "CAT1".."CAT9" aren't used. Check that reserved IDs aren't used as Form
* types. Check that all IDs are made of 4 printable characters (trailing
* spaces ok). */
typedef struct {
ClientFrame clientFrame;
int levels; /* # groups currently nested within.*/
} Frame;
char MsgOkay[] = { "----- (IFF_OKAY) A good IFF file." };
char MsgEndMark[] = {"----- (END_MARK) How did you get this message??" };
char MsgDone[] = { "----- (IFF_DONE) How did you get this message??" };
char MsgDos[] = { "----- (DOS_ERROR) The DOS gave back an error." };
char MsgNot[] = { "----- (NOT_IFF) not an IFF file." };
char MsgNoFile[] = { "----- (NO_FILE) no such file found." };
char MsgClientError[] = {"----- (CLIENT_ERROR) IFF Checker bug."};
char MsgForm[] = { "----- (BAD_FORM) How did you get this message??" };
char MsgShort[] = { "----- (SHORT_CHUNK) How did you get this message??" };
char MsgBad[] = { "----- (BAD_IFF) a mangled IFF file." };
/* MUST GET THESE IN RIGHT ORDER!!*/
char *IFFPMessages[-LAST_ERROR+1] = {
/*IFF_OKAY*/ MsgOkay,
/*END_MARK*/ MsgEndMark,
/*IFF_DONE*/ MsgDone,
/*DOS_ERROR*/ MsgDos,
/*NOT_IFF*/ MsgNot,
/*NO_FILE*/ MsgNoFile,
/*CLIENT_ERROR*/ MsgClientError,
/*BAD_FORM*/ MsgForm,
/*SHORT_CHUNK*/ MsgShort,
/*BAD_IFF*/ MsgBad
};
/* FORWARD REFERENCES */
extern IFFP GetList(GroupContext*);
extern IFFP GetForm(GroupContext*);
extern IFFP GetProp(GroupContext*);
extern IFFP GetCat (GroupContext*);
void IFFCheck(char *name)
{
IFFP iffp;
BPTR file = fopen(name,"rb");//Open(name, MODE_OLDFILE);
Frame frame;
frame.levels = 0;
frame.clientFrame.getList = GetList;
frame.clientFrame.getForm = GetForm;
frame.clientFrame.getProp = GetProp;
frame.clientFrame.getCat = GetCat ;
printf("----- Checking file '%s' -----\n", name);
if (file == 0)
iffp = NO_FILE;
else
iffp = ReadIFF(file, (ClientFrame *)&frame);
fclose(file);
printf("%s\n", IFFPMessages[-iffp]);
}
int main(int argc, char **argv)
{
if (argc != 1+1) {
printf("Usage: 'iffcheck filename'\n");
exit(0);
}
IFFCheck(argv[1]);
return 0;
}
/* ---------- Put... ---------------------------------------------------*/
void PutLevels(int count)
{
for ( ; count > 0; --count) {
printf(".");
}
}
void PutID(int id)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
//little endian machine
printf("%c%c%c%c ", (char)(id&0x7f) , (char)(id>>8)&0x7f,
(char)(id>>16)&0x7f, (char)(id>>24)&0x7f);
} else
{
//big endian machine
printf("%c%c%c%c ", (char)(id>>24)&0x7f, (char)(id>>16)&0x7f,
(char)(id>>8)&0x7f, (char)(id&0x7f));
}
/* printf("id = %lx", id); */
}
void PutN(long n)
{
printf(" %ld ", n);
}
/* Put something like "...BMHD 14" or "...LIST 14 PLBM". */
void PutHdr(GroupContext *context)
{
PutLevels( ((Frame *)context->clientFrame)->levels );
PutID(context->ckHdr.ckID);
PutN(context->ckHdr.ckSize);
if (context->subtype != NULL_CHUNK)
PutID(context->subtype);
printf("\n");
}
/* ---------- AtLeaf ---------------------------------------------------*/
/* At Leaf chunk. That is, a chunk which does NOT contain other chunks.
* Print "int size".*/
IFFP AtLeaf(GroupContext *context)
{
PutHdr(context);
/* A typical reader would read the chunk's contents, using the "Frame"
* for local data, esp. shared property settings (PROP).*/
/* IFFReadBytes(context, ...buffer, context->ckHdr->ckSize); */
return(IFF_OKAY);
}
/* ---------- GetList --------------------------------------------------*/
/* Handle a LIST chunk. Print "LIST size subTypeID".
* Then dive into it.*/
IFFP GetList(GroupContext *parent)
{
Frame newFrame;
newFrame = *(Frame *)parent->clientFrame; /* copy parent's frame*/
newFrame.levels++;
PutHdr(parent);
return( ReadIList(parent, (ClientFrame *)&newFrame) );
}
/* ---------- GetForm --------------------------------------------------*/
/* Handle a FORM chunk. Print "FORM size subTypeID".
* Then dive into it.*/
IFFP GetForm(GroupContext *parent)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext newptr;
Frame newFrame;
newFrame = *(Frame *)parent->clientFrame; /* copy parent's frame*/
newFrame.levels++;
PutHdr(parent);
iffp = OpenRGroup(parent, &newptr);
CheckIFFP();
newptr.clientFrame = (ClientFrame *)&newFrame;
/* FORM reader for Checker. */
/* LIST, FORM, PROP, CAT already handled by GetF1ChunkHdr. */
do {if ( (iffp = GetF1ChunkHdr(&newptr)) > 0 )
iffp = AtLeaf(&newptr);
} while (iffp >= IFF_OKAY);
CloseRGroup(&newptr);
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- GetProp --------------------------------------------------*/
/* Handle a PROP chunk. Print "PROP size subTypeID".
* Then dive into it.*/
IFFP GetProp(GroupContext *listContext)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext newptr;
PutHdr(listContext);
iffp = OpenRGroup(listContext, &newptr);
CheckIFFP();
/* PROP reader for Checker. */
((Frame *)listContext->clientFrame)->levels++;
do {if ( (iffp = GetPChunkHdr(&newptr)) > 0 )
iffp = AtLeaf(&newptr);
} while (iffp >= IFF_OKAY);
((Frame *)listContext->clientFrame)->levels--;
CloseRGroup(&newptr);
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- GetCat ---------------------------------------------------*/
/* Handle a CAT chunk. Print "CAT size subTypeID".
* Then dive into it.*/
IFFP GetCat(GroupContext *parent)
{
IFFP iffp;
((Frame *)parent->clientFrame)->levels++;
PutHdr(parent);
iffp = ReadICat(parent);
((Frame *)parent->clientFrame)->levels--;
return(iffp);
}
/*---------------------------------------------------------------------*
* IFFCheck.C Print out the structure of an IFF-85 file, 11/19/85
* checking for structural errors.
*
* DO NOT USE THIS AS A SKELETAL PROGRAM FOR AN IFF READER!
* See ShowILBM.C for a skeletal example.
*
* Original version was for the Commodore-Amiga computer.
/* This version is compatible with PC, OSX, PS3, Wii, iPhone. 10/26/2008
*----------------------------------------------------------------------*/
#include "iff.h"
#include "stdlib.h" //for exit
/* ---------- IFFCheck -------------------------------------------------*/
/* [TBD] More extensive checking could be done on the IDs encountered in the
* file. Check that the reserved IDs "FOR1".."FOR9", "LIS1".."LIS9", and
* "CAT1".."CAT9" aren't used. Check that reserved IDs aren't used as Form
* types. Check that all IDs are made of 4 printable characters (trailing
* spaces ok). */
typedef struct {
ClientFrame clientFrame;
int levels; /* # groups currently nested within.*/
} Frame;
char MsgOkay[] = { "----- (IFF_OKAY) A good IFF file." };
char MsgEndMark[] = {"----- (END_MARK) How did you get this message??" };
char MsgDone[] = { "----- (IFF_DONE) How did you get this message??" };
char MsgDos[] = { "----- (DOS_ERROR) The DOS gave back an error." };
char MsgNot[] = { "----- (NOT_IFF) not an IFF file." };
char MsgNoFile[] = { "----- (NO_FILE) no such file found." };
char MsgClientError[] = {"----- (CLIENT_ERROR) IFF Checker bug."};
char MsgForm[] = { "----- (BAD_FORM) How did you get this message??" };
char MsgShort[] = { "----- (SHORT_CHUNK) How did you get this message??" };
char MsgBad[] = { "----- (BAD_IFF) a mangled IFF file." };
/* MUST GET THESE IN RIGHT ORDER!!*/
char *IFFPMessages[-LAST_ERROR+1] = {
/*IFF_OKAY*/ MsgOkay,
/*END_MARK*/ MsgEndMark,
/*IFF_DONE*/ MsgDone,
/*DOS_ERROR*/ MsgDos,
/*NOT_IFF*/ MsgNot,
/*NO_FILE*/ MsgNoFile,
/*CLIENT_ERROR*/ MsgClientError,
/*BAD_FORM*/ MsgForm,
/*SHORT_CHUNK*/ MsgShort,
/*BAD_IFF*/ MsgBad
};
/* FORWARD REFERENCES */
extern IFFP GetList(GroupContext*);
extern IFFP GetForm(GroupContext*);
extern IFFP GetProp(GroupContext*);
extern IFFP GetCat (GroupContext*);
void IFFCheck(char *name)
{
IFFP iffp;
BPTR file = fopen(name,"rb");//Open(name, MODE_OLDFILE);
Frame frame;
frame.levels = 0;
frame.clientFrame.getList = GetList;
frame.clientFrame.getForm = GetForm;
frame.clientFrame.getProp = GetProp;
frame.clientFrame.getCat = GetCat ;
printf("----- Checking file '%s' -----\n", name);
if (file == 0)
iffp = NO_FILE;
else
iffp = ReadIFF(file, (ClientFrame *)&frame);
fclose(file);
printf("%s\n", IFFPMessages[-iffp]);
}
int main(int argc, char **argv)
{
if (argc != 1+1) {
printf("Usage: 'iffcheck filename'\n");
exit(0);
}
IFFCheck(argv[1]);
return 0;
}
/* ---------- Put... ---------------------------------------------------*/
void PutLevels(int count)
{
for ( ; count > 0; --count) {
printf(".");
}
}
void PutID(int id)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
//little endian machine
printf("%c%c%c%c ", (char)(id&0x7f) , (char)(id>>8)&0x7f,
(char)(id>>16)&0x7f, (char)(id>>24)&0x7f);
} else
{
//big endian machine
printf("%c%c%c%c ", (char)(id>>24)&0x7f, (char)(id>>16)&0x7f,
(char)(id>>8)&0x7f, (char)(id&0x7f));
}
/* printf("id = %lx", id); */
}
void PutN(long n)
{
printf(" %ld ", n);
}
/* Put something like "...BMHD 14" or "...LIST 14 PLBM". */
void PutHdr(GroupContext *context)
{
PutLevels( ((Frame *)context->clientFrame)->levels );
PutID(context->ckHdr.ckID);
PutN(context->ckHdr.ckSize);
if (context->subtype != NULL_CHUNK)
PutID(context->subtype);
printf("\n");
}
/* ---------- AtLeaf ---------------------------------------------------*/
/* At Leaf chunk. That is, a chunk which does NOT contain other chunks.
* Print "int size".*/
IFFP AtLeaf(GroupContext *context)
{
PutHdr(context);
/* A typical reader would read the chunk's contents, using the "Frame"
* for local data, esp. shared property settings (PROP).*/
/* IFFReadBytes(context, ...buffer, context->ckHdr->ckSize); */
return(IFF_OKAY);
}
/* ---------- GetList --------------------------------------------------*/
/* Handle a LIST chunk. Print "LIST size subTypeID".
* Then dive into it.*/
IFFP GetList(GroupContext *parent)
{
Frame newFrame;
newFrame = *(Frame *)parent->clientFrame; /* copy parent's frame*/
newFrame.levels++;
PutHdr(parent);
return( ReadIList(parent, (ClientFrame *)&newFrame) );
}
/* ---------- GetForm --------------------------------------------------*/
/* Handle a FORM chunk. Print "FORM size subTypeID".
* Then dive into it.*/
IFFP GetForm(GroupContext *parent)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext newptr;
Frame newFrame;
newFrame = *(Frame *)parent->clientFrame; /* copy parent's frame*/
newFrame.levels++;
PutHdr(parent);
iffp = OpenRGroup(parent, &newptr);
CheckIFFP();
newptr.clientFrame = (ClientFrame *)&newFrame;
/* FORM reader for Checker. */
/* LIST, FORM, PROP, CAT already handled by GetF1ChunkHdr. */
do {if ( (iffp = GetF1ChunkHdr(&newptr)) > 0 )
iffp = AtLeaf(&newptr);
} while (iffp >= IFF_OKAY);
CloseRGroup(&newptr);
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- GetProp --------------------------------------------------*/
/* Handle a PROP chunk. Print "PROP size subTypeID".
* Then dive into it.*/
IFFP GetProp(GroupContext *listContext)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext newptr;
PutHdr(listContext);
iffp = OpenRGroup(listContext, &newptr);
CheckIFFP();
/* PROP reader for Checker. */
((Frame *)listContext->clientFrame)->levels++;
do {if ( (iffp = GetPChunkHdr(&newptr)) > 0 )
iffp = AtLeaf(&newptr);
} while (iffp >= IFF_OKAY);
((Frame *)listContext->clientFrame)->levels--;
CloseRGroup(&newptr);
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- GetCat ---------------------------------------------------*/
/* Handle a CAT chunk. Print "CAT size subTypeID".
* Then dive into it.*/
IFFP GetCat(GroupContext *parent)
{
IFFP iffp;
((Frame *)parent->clientFrame)->levels++;
PutHdr(parent);
iffp = ReadICat(parent);
((Frame *)parent->clientFrame)->levels--;
return(iffp);
}

View File

@@ -1,236 +1,236 @@
/*
Test read and write IFF-85, Interchange Format File
Copyright (c) 2008 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* IFF Support routines for writing IFF-85 files. 12/02/85
* (IFF is Interchange Format File.)
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
*/
#include <stdio.h>
#include "iff.h"
IFFP MyReadICat(GroupContext *parent)
{
printf("Found and skipped a CAT\n");
return 0;
}
IFFP MySkipGroup( GroupContext * )
{
printf("Found and skipped a LIST\n");
return 0;
}
typedef UBYTE Masking; /* Choice of masking technique.*/
typedef UBYTE Compression; /* Choice of compression algorithm applied to
/* A BitMapHeader is stored in a BMHD chunk. */
typedef struct {
UWORD w, h; /* raster width & height in pixels */
WORD x, y; /* position for this image */
UBYTE nPlanes; /* # source bitplanes */
Masking masking; /* masking technique */
Compression compression; /* compression algoithm */
UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
UWORD transparentColor; /* transparent "color number" */
UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
WORD pageWidth, pageHeight; /* source "page" size in pixels */
} BitMapHeader;
#define bufSz 512
BYTE bodyBuffer[bufSz];
static void btSwap(char* a, char* b)
{
char tmp = *a;
*a = *b;
*b = tmp;
};
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_BODY MakeID('B','O','D','Y')
#define ID_DYNAWORLD MakeID('B','T','D','W')
#define ID_RIGIDBODY MakeID('B','T','R','B')
#define ID_SID MakeID('S','I','D',' ')
#define ID_MASS MakeID('M','A','S','S')
#define ID_SHAPE MakeID('S','H','A','P')
#define ID_COLOBJ MakeID('C','O','B','J')
#define ID_CUBE MakeID('C','U','B','E')
#define ID_DIMENSIONS MakeID('D','I','M','E')
IFFP MyProcessGroup(GroupContext *parent)
{
/*compilerBug register*/ IFFP iffp;
GroupContext rigidbodyContext;
BitMapHeader bmHeader;
bool foundBMHD = false;
if (parent->subtype != ID_ILBM)
return(IFF_OKAY); /* just continue scaning the file */
iffp = OpenRGroup(parent, &rigidbodyContext);
CheckIFFP();
do {
iffp = GetFChunkHdr(&rigidbodyContext);
if (iffp == ID_BMHD) {
printf("found ID_BMHD\n");
foundBMHD = true;
iffp = IFFReadBytes(&rigidbodyContext, (BYTE *)&bmHeader, (long)sizeof(BitMapHeader));
//do endian swap
bmHeader.w = endianSwap16(bmHeader.w);
bmHeader.h = endianSwap16(bmHeader.h);
bmHeader.pageWidth = endianSwap16(bmHeader.pageWidth);
bmHeader.pageHeight = endianSwap16(bmHeader.pageHeight);
}
else if (iffp == ID_CMAP) {
printf("found ID_CMAP\n");
// ilbmFrame.nColorRegs = maxColorReg; /* we have room for this many */
// iffp = GetCMAP(
// &rigidbodyContext, (WORD *)&ilbmFrame.colorMap, &ilbmFrame.nColorRegs);
}
else if (iffp == ID_BODY)
{
printf("found ID_BODY\n");
if (!foundBMHD)
return BAD_FORM;
// if (!ilbmFrame.foundBMHD) return(BAD_FORM); /* No BMHD chunk! */
int moreBytes = ChunkMoreBytes(&rigidbodyContext);
while (moreBytes>0)
{
int curRead = moreBytes > bufSz? bufSz : moreBytes;
//read
iffp = IFFReadBytes(&rigidbodyContext, bodyBuffer, curRead);
moreBytes -= curRead;
}
printf("remaining=%d\n",moreBytes);
if (iffp == IFF_OKAY)
iffp = IFF_DONE; /* Eureka */
// nPlanes = MIN(ilbmFrame.bmHdr.nPlanes, EXDepth);
}
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(&rigidbodyContext);
return(iffp);
}
#define CkErr(expression) {if (ifferr == IFF_OKAY) ifferr = (expression);}
int main(int argc, char* argv[])
{
FILE* file = 0;
{
//Create and write an IFF file from scratch
file = fopen("test.iff","wb");
GroupContext fileContext;
GroupContext catContext;
IFFP ifferr=0;
ifferr = OpenWIFF(file, &fileContext, szNotYetKnown) ;
//ifferr = StartWGroup(&fileContext, CAT, szNotYetKnown, ID_DYNAWORLD, &catContext);
ifferr = StartWGroup(&fileContext, LIST, szNotYetKnown, ID_DYNAWORLD, &catContext);
{
GroupContext rigidbodyPropContext;
ifferr = StartWGroup(&catContext, PROP, szNotYetKnown, ID_MASS, &rigidbodyPropContext);
float mass = 0.1f;
PutCk(&rigidbodyPropContext, ID_MASS, 4,(char*)&mass);
ifferr = EndWGroup(&rigidbodyPropContext) ;
for (int i=0;i<3;i++)
{
GroupContext rigidbodyContext;
ifferr = StartWGroup(&catContext, FORM, szNotYetKnown, ID_RIGIDBODY, &rigidbodyContext);
char sidbuffer[]="rb1";
float dimensions[3] = {2,2,2};
PutCk(&rigidbodyContext, ID_SID, 3,sidbuffer);
{
GroupContext shapeContext;
ifferr = StartWGroup(&rigidbodyContext, FORM, szNotYetKnown, ID_SHAPE, &shapeContext);
PutCk(&shapeContext, ID_CUBE, 4,(char*)&mass);
PutCk(&shapeContext, ID_DIMENSIONS, sizeof(dimensions),(char*)&dimensions);
ifferr = EndWGroup(&shapeContext) ;
}
ifferr = EndWGroup(&rigidbodyContext) ;
}
}
ifferr = EndWGroup(&catContext) ;
ifferr = CloseWGroup(&fileContext);
fclose(file);
}
{
//show a very simple way to skim through an ILBM or general IFF file
//for more verbose feedback, use iffcheck.c
IFFP result;
//file = fopen("pe_3000_fall.iff","rb");
file = fopen("test.iff","rb");
ClientFrame clientFrame;
clientFrame.getList = MySkipGroup;
clientFrame.getProp = MySkipGroup;
clientFrame.getForm = MyProcessGroup;
clientFrame.getCat = MyReadICat ;
result = ReadIFF(file,&clientFrame);
fclose(file);
}
return 0;
}
/*
Test read and write IFF-85, Interchange Format File
Copyright (c) 2008 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* IFF Support routines for writing IFF-85 files. 12/02/85
* (IFF is Interchange Format File.)
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
*/
#include <stdio.h>
#include "iff.h"
IFFP MyReadICat(GroupContext *parent)
{
printf("Found and skipped a CAT\n");
return 0;
}
IFFP MySkipGroup( GroupContext * )
{
printf("Found and skipped a LIST\n");
return 0;
}
typedef UBYTE Masking; /* Choice of masking technique.*/
typedef UBYTE Compression; /* Choice of compression algorithm applied to
/* A BitMapHeader is stored in a BMHD chunk. */
typedef struct {
UWORD w, h; /* raster width & height in pixels */
WORD x, y; /* position for this image */
UBYTE nPlanes; /* # source bitplanes */
Masking masking; /* masking technique */
Compression compression; /* compression algoithm */
UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
UWORD transparentColor; /* transparent "color number" */
UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
WORD pageWidth, pageHeight; /* source "page" size in pixels */
} BitMapHeader;
#define bufSz 512
BYTE bodyBuffer[bufSz];
static void btSwap(char* a, char* b)
{
char tmp = *a;
*a = *b;
*b = tmp;
};
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_BODY MakeID('B','O','D','Y')
#define ID_DYNAWORLD MakeID('B','T','D','W')
#define ID_RIGIDBODY MakeID('B','T','R','B')
#define ID_SID MakeID('S','I','D',' ')
#define ID_MASS MakeID('M','A','S','S')
#define ID_SHAPE MakeID('S','H','A','P')
#define ID_COLOBJ MakeID('C','O','B','J')
#define ID_CUBE MakeID('C','U','B','E')
#define ID_DIMENSIONS MakeID('D','I','M','E')
IFFP MyProcessGroup(GroupContext *parent)
{
/*compilerBug register*/ IFFP iffp;
GroupContext rigidbodyContext;
BitMapHeader bmHeader;
bool foundBMHD = false;
if (parent->subtype != ID_ILBM)
return(IFF_OKAY); /* just continue scaning the file */
iffp = OpenRGroup(parent, &rigidbodyContext);
CheckIFFP();
do {
iffp = GetFChunkHdr(&rigidbodyContext);
if (iffp == ID_BMHD) {
printf("found ID_BMHD\n");
foundBMHD = true;
iffp = IFFReadBytes(&rigidbodyContext, (BYTE *)&bmHeader, (long)sizeof(BitMapHeader));
//do endian swap
bmHeader.w = endianSwap16(bmHeader.w);
bmHeader.h = endianSwap16(bmHeader.h);
bmHeader.pageWidth = endianSwap16(bmHeader.pageWidth);
bmHeader.pageHeight = endianSwap16(bmHeader.pageHeight);
}
else if (iffp == ID_CMAP) {
printf("found ID_CMAP\n");
// ilbmFrame.nColorRegs = maxColorReg; /* we have room for this many */
// iffp = GetCMAP(
// &rigidbodyContext, (WORD *)&ilbmFrame.colorMap, &ilbmFrame.nColorRegs);
}
else if (iffp == ID_BODY)
{
printf("found ID_BODY\n");
if (!foundBMHD)
return BAD_FORM;
// if (!ilbmFrame.foundBMHD) return(BAD_FORM); /* No BMHD chunk! */
int moreBytes = ChunkMoreBytes(&rigidbodyContext);
while (moreBytes>0)
{
int curRead = moreBytes > bufSz? bufSz : moreBytes;
//read
iffp = IFFReadBytes(&rigidbodyContext, bodyBuffer, curRead);
moreBytes -= curRead;
}
printf("remaining=%d\n",moreBytes);
if (iffp == IFF_OKAY)
iffp = IFF_DONE; /* Eureka */
// nPlanes = MIN(ilbmFrame.bmHdr.nPlanes, EXDepth);
}
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(&rigidbodyContext);
return(iffp);
}
#define CkErr(expression) {if (ifferr == IFF_OKAY) ifferr = (expression);}
int main(int argc, char* argv[])
{
FILE* file = 0;
{
//Create and write an IFF file from scratch
file = fopen("test.iff","wb");
GroupContext fileContext;
GroupContext catContext;
IFFP ifferr=0;
ifferr = OpenWIFF(file, &fileContext, szNotYetKnown) ;
//ifferr = StartWGroup(&fileContext, CAT, szNotYetKnown, ID_DYNAWORLD, &catContext);
ifferr = StartWGroup(&fileContext, LIST, szNotYetKnown, ID_DYNAWORLD, &catContext);
{
GroupContext rigidbodyPropContext;
ifferr = StartWGroup(&catContext, PROP, szNotYetKnown, ID_MASS, &rigidbodyPropContext);
float mass = 0.1f;
PutCk(&rigidbodyPropContext, ID_MASS, 4,(char*)&mass);
ifferr = EndWGroup(&rigidbodyPropContext) ;
for (int i=0;i<3;i++)
{
GroupContext rigidbodyContext;
ifferr = StartWGroup(&catContext, FORM, szNotYetKnown, ID_RIGIDBODY, &rigidbodyContext);
char sidbuffer[]="rb1";
float dimensions[3] = {2,2,2};
PutCk(&rigidbodyContext, ID_SID, 3,sidbuffer);
{
GroupContext shapeContext;
ifferr = StartWGroup(&rigidbodyContext, FORM, szNotYetKnown, ID_SHAPE, &shapeContext);
PutCk(&shapeContext, ID_CUBE, 4,(char*)&mass);
PutCk(&shapeContext, ID_DIMENSIONS, sizeof(dimensions),(char*)&dimensions);
ifferr = EndWGroup(&shapeContext) ;
}
ifferr = EndWGroup(&rigidbodyContext) ;
}
}
ifferr = EndWGroup(&catContext) ;
ifferr = CloseWGroup(&fileContext);
fclose(file);
}
{
//show a very simple way to skim through an ILBM or general IFF file
//for more verbose feedback, use iffcheck.c
IFFP result;
//file = fopen("pe_3000_fall.iff","rb");
file = fopen("test.iff","rb");
ClientFrame clientFrame;
clientFrame.getList = MySkipGroup;
clientFrame.getProp = MySkipGroup;
clientFrame.getForm = MyProcessGroup;
clientFrame.getCat = MyReadICat ;
result = ReadIFF(file,&clientFrame);
fclose(file);
}
return 0;
}

View File

@@ -1,370 +1,370 @@
/*----------------------------------------------------------------------*
* IFFR.C Support routines for reading IFF-85 files. 11/15/85
* (IFF is Interchange Format File.)
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* Original version was for the Commodore-Amiga computer.
* This version is compatible with PC, OSX, PS3, Wii, iPhone. 10/26/2008
*----------------------------------------------------------------------*/
#include "iff.h"
/* #include "DF1:iff/gio.h" */
/* #define OFFSET_BEGINNING OFFSET_BEGINING */
/** Manx expects INTs as 16 bits, This wont matter on LAttice ***/
/* ---------- Read -----------------------------------------------------*/
extern int PutID(); /** Added as a diagnostic aid, will remove later ***/
/* ---------- OpenRIFF --------------------------------------------------*/
IFFP OpenRIFF(BPTR file0, GroupContext *new0,ClientFrame *clientFrame)
{
register BPTR file = file0;
register GroupContext *newtmp = new0;
IFFP iffp = IFF_OKAY;
newtmp->parent = NL; /* "whole file" has no parent.*/
newtmp->clientFrame = clientFrame;
newtmp->file = file;
newtmp->position = 0;
newtmp->ckHdr.ckID = newtmp->subtype = NULL_CHUNK;
newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;
/* Set newtmp->bound. AmigaDOS specific code.*/
if (file <= 0) return(NO_FILE);
Seek(file, 0L, OFFSET_END); /* Seek to end of file.*/
newtmp->bound = ftell(file);//Seek(file, 0L, OFFSET_CURRENT); /* Pos'n == #bytes in file.*/
if (newtmp->bound < 0) return(DOS_ERROR); /* DOS being absurd.*/
Seek(file, 0L, OFFSET_BEGINNING); /* Go to file start.*/
/* Would just do this if Amiga DOS maintained fh_End: */
/* newtmp->bound = (FileHandle *)BADDR(file)->fh_End; */
if ( newtmp->bound < (long)sizeof(ChunkHeader) )
iffp = NOT_IFF;
return(iffp);
}
/* ---------- OpenRGroup -----------------------------------------------*/
IFFP OpenRGroup(GroupContext* parent0,GroupContext* new0)
{
register GroupContext *parent = parent0;
register GroupContext *newtmp = new0;
IFFP iffp = IFF_OKAY;
newtmp->parent = parent;
newtmp->clientFrame = parent->clientFrame;
newtmp->file = parent->file;
newtmp->position = parent->position;
newtmp->bound = parent->position + ChunkMoreBytes(parent);
newtmp->ckHdr.ckID = newtmp->subtype = NULL_CHUNK;
newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;
if ( newtmp->bound > parent->bound || IS_ODD(newtmp->bound) )
iffp = BAD_IFF;
return(iffp);
}
/* ---------- CloseRGroup -----------------------------------------------*/
IFFP CloseRGroup(GroupContext *context)
{
register int position;
if (context->parent == NL) {
} /* Context for whole file.*/
else {
position = context->position;
context->parent->bytesSoFar += position - context->parent->position;
context->parent->position = position;
}
return(IFF_OKAY);
}
/* ---------- SkipFwd --------------------------------------------------*/
/* Skip over bytes in a context. Won't go backwards.*/
/* Updates context->position but not context->bytesSoFar.*/
/* This implementation is AmigaDOS specific.*/
IFFP SkipFwd(GroupContext *context,int bytes)
{
IFFP iffp = IFF_OKAY;
if (bytes > 0) {
if (-1 == Seek(context->file, bytes, OFFSET_CURRENT))
iffp = BAD_IFF; /* Ran out of bytes before chunk complete.*/
else
context->position += bytes;
}
return(iffp);
}
short int endianSwap16(short int val)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
}
return val;
}
int endianSwap32(int val)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
}
return val;
}
/* ---------- GetChunkHdr ----------------------------------------------*/
int GetChunkHdr(GroupContext *context0)
{
register GroupContext *context = context0;
register IFFP iffp;
int remaining;
/* Skip remainder of previous chunk & padding. */
iffp = SkipFwd(context,
ChunkMoreBytes(context) + IS_ODD(context->ckHdr.ckSize));
CheckIFFP();
/* Set up to read the newtmp header. */
context->ckHdr.ckID = BAD_IFF; /* Until we know it's okay, mark it BAD.*/
context->subtype = NULL_CHUNK;
context->bytesSoFar = 0;
/* Generate a psuedo-chunk if at end-of-context. */
remaining = context->bound - context->position;
if (remaining == 0 ) {
context->ckHdr.ckSize = 0;
context->ckHdr.ckID = END_MARK;
}
/* BAD_IFF if not enough bytes in the context for a ChunkHeader.*/
else if ((long)sizeof(ChunkHeader) > remaining) {
context->ckHdr.ckSize = remaining;
}
/* Read the chunk header (finally). */
else {
switch (Read(context->file,
&context->ckHdr, (long)sizeof(ChunkHeader)))
{
case -1: return(context->ckHdr.ckID = DOS_ERROR);
case 0: return(context->ckHdr.ckID = BAD_IFF);
}
//swap endian-ness of ckSize on little endian machines
context->ckHdr.ckSize = endianSwap32(context->ckHdr.ckSize);
/*** $$$ ***
PutID(context->ckHdr.ckID);
printf("\n");
printf("id = %lx\n", context->ckHdr.ckID);
**/
/* Check: Top level chunk must be LIST or FORM or CAT. */
if (context->parent == NL) {
if (context->ckHdr.ckID != FORM &&
context->ckHdr.ckID != LIST &&
context->ckHdr.ckID != CAT )
return(context->ckHdr.ckID = NOT_IFF);
}
/* Update the context. */
context->position += (long)sizeof(ChunkHeader);
remaining -= (long)sizeof(ChunkHeader);
/* Non-positive int values are illegal and used for error codes.*/
/* We could check for other illegal IDs...*/
if (context->ckHdr.ckID <= 0 )
context->ckHdr.ckID = BAD_IFF;
/* Check: ckSize negative or larger than # bytes left in context? */
else if (context->ckHdr.ckSize < 0 ||
context->ckHdr.ckSize > remaining) {
context->ckHdr.ckSize = remaining;
context->ckHdr.ckID = BAD_IFF;
}
/* Automatically read the LIST, FORM, PROP, or CAT subtype int */
else {
if (context->ckHdr.ckID == LIST ||
context->ckHdr.ckID == FORM ||
context->ckHdr.ckID == PROP ||
context->ckHdr.ckID == CAT) {
iffp = IFFReadBytes(context, (BYTE *)&context->subtype,
(long)sizeof(int));
if (iffp != IFF_OKAY )
context->ckHdr.ckID = iffp;
}
}
}
return(context->ckHdr.ckID);
}
/* ---------- IFFReadBytes ---------------------------------------------*/
IFFP IFFReadBytes(GroupContext *context,BYTE *buffer, int nBytes)
{
register IFFP iffp = IFF_OKAY;
if (nBytes < 0)
iffp = CLIENT_ERROR;
else if (nBytes > ChunkMoreBytes(context))
iffp = SHORT_CHUNK;
else if (nBytes > 0 )
switch ( Read(context->file, buffer, nBytes) ) {
case -1: {iffp = DOS_ERROR; break; }
case 0: {iffp = BAD_IFF; break; }
default: {
context->position += nBytes;
context->bytesSoFar += nBytes;
}
}
return(iffp);
}
/* ---------- SkipGroup ------------------------------------------------*/
IFFP SkipGroup( GroupContext* context)
{
return 0;
} /* Nothing to do, thanks to GetChunkHdr */
/* ---------- ReadIFF --------------------------------------------------*/
IFFP ReadIFF(BPTR file,ClientFrame *clientFrame)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext context;
iffp = OpenRIFF(file, &context,clientFrame);
context.clientFrame = clientFrame;
if (iffp == IFF_OKAY) {
iffp = GetChunkHdr(&context);
if (iffp == FORM)
iffp = (*clientFrame->getForm)(&context);
else if (iffp == LIST)
iffp = (*clientFrame->getList)(&context);
else if (iffp == CAT)
iffp = (*clientFrame->getCat)(&context);
}
CloseRGroup(&context);
if (iffp > 0 ) /* Make sure we don't return an int.*/
iffp = NOT_IFF; /* GetChunkHdr should've caught this.*/
return(iffp);
}
/* ---------- ReadIList ------------------------------------------------*/
IFFP ReadIList(GroupContext *parent,ClientFrame *clientFrame)
{
GroupContext listContext;
IFFP iffp;
BOOL propOk = TRUE;
iffp = OpenRGroup(parent, &listContext);
CheckIFFP();
/* One special case test lets us handle CATs as well as LISTs.*/
if (parent->ckHdr.ckID == CAT)
propOk = FALSE;
else
listContext.clientFrame = clientFrame;
do {
iffp = GetChunkHdr(&listContext);
if (iffp == PROP) {
if (propOk)
iffp = (*clientFrame->getProp)(&listContext);
else
iffp = BAD_IFF;
}
else if (iffp == FORM)
iffp = (*clientFrame->getForm)(&listContext);
else if (iffp == LIST)
iffp = (*clientFrame->getList)(&listContext);
else if (iffp == CAT)
iffp = (*clientFrame->getList)(&listContext);
if (listContext.ckHdr.ckID != PROP)
propOk = FALSE; /* No PROPs allowed after this point.*/
} while (iffp == IFF_OKAY);
CloseRGroup(&listContext);
if (iffp > 0 ) /* Only chunk types above are allowed in a LIST/CAT.*/
iffp = BAD_IFF;
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- ReadICat -------------------------------------------------*/
/* By special arrangement with the ReadIList implement'n, this is trivial.*/
IFFP ReadICat(GroupContext *parent)
{
return( ReadIList(parent, parent->clientFrame));//NL) );
}
/* ---------- GetFChunkHdr ---------------------------------------------*/
int GetFChunkHdr(GroupContext *context)
{
register int id;
id = GetChunkHdr(context);
if (id == PROP)
context->ckHdr.ckID = id = BAD_IFF;
return(id);
}
/* ---------- GetF1ChunkHdr ---------------------------------------------*/
int GetF1ChunkHdr(GroupContext *context)
{
register int id;
register ClientFrame *clientFrame = context->clientFrame;
id = GetChunkHdr(context);
if (id == PROP)
id = BAD_IFF;
else if (id == FORM)
id = (*clientFrame->getForm)(context);
else if (id == LIST)
id = (*clientFrame->getForm)(context);
else if (id == CAT)
id = (*clientFrame->getCat)(context);
return(context->ckHdr.ckID = id);
}
/* ---------- GetPChunkHdr ---------------------------------------------*/
int GetPChunkHdr(GroupContext *context)
{
register int id;
id = GetChunkHdr(context);
if (id == LIST || id == FORM || id == PROP || id == CAT )
id = context->ckHdr.ckID = BAD_IFF;
return(id);
}
/*----------------------------------------------------------------------*
* IFFR.C Support routines for reading IFF-85 files. 11/15/85
* (IFF is Interchange Format File.)
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* Original version was for the Commodore-Amiga computer.
* This version is compatible with PC, OSX, PS3, Wii, iPhone. 10/26/2008
*----------------------------------------------------------------------*/
#include "iff.h"
/* #include "DF1:iff/gio.h" */
/* #define OFFSET_BEGINNING OFFSET_BEGINING */
/** Manx expects INTs as 16 bits, This wont matter on LAttice ***/
/* ---------- Read -----------------------------------------------------*/
extern int PutID(); /** Added as a diagnostic aid, will remove later ***/
/* ---------- OpenRIFF --------------------------------------------------*/
IFFP OpenRIFF(BPTR file0, GroupContext *new0,ClientFrame *clientFrame)
{
register BPTR file = file0;
register GroupContext *newtmp = new0;
IFFP iffp = IFF_OKAY;
newtmp->parent = NL; /* "whole file" has no parent.*/
newtmp->clientFrame = clientFrame;
newtmp->file = file;
newtmp->position = 0;
newtmp->ckHdr.ckID = newtmp->subtype = NULL_CHUNK;
newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;
/* Set newtmp->bound. AmigaDOS specific code.*/
if (file <= 0) return(NO_FILE);
Seek(file, 0L, OFFSET_END); /* Seek to end of file.*/
newtmp->bound = ftell(file);//Seek(file, 0L, OFFSET_CURRENT); /* Pos'n == #bytes in file.*/
if (newtmp->bound < 0) return(DOS_ERROR); /* DOS being absurd.*/
Seek(file, 0L, OFFSET_BEGINNING); /* Go to file start.*/
/* Would just do this if Amiga DOS maintained fh_End: */
/* newtmp->bound = (FileHandle *)BADDR(file)->fh_End; */
if ( newtmp->bound < (long)sizeof(ChunkHeader) )
iffp = NOT_IFF;
return(iffp);
}
/* ---------- OpenRGroup -----------------------------------------------*/
IFFP OpenRGroup(GroupContext* parent0,GroupContext* new0)
{
register GroupContext *parent = parent0;
register GroupContext *newtmp = new0;
IFFP iffp = IFF_OKAY;
newtmp->parent = parent;
newtmp->clientFrame = parent->clientFrame;
newtmp->file = parent->file;
newtmp->position = parent->position;
newtmp->bound = parent->position + ChunkMoreBytes(parent);
newtmp->ckHdr.ckID = newtmp->subtype = NULL_CHUNK;
newtmp->ckHdr.ckSize = newtmp->bytesSoFar = 0;
if ( newtmp->bound > parent->bound || IS_ODD(newtmp->bound) )
iffp = BAD_IFF;
return(iffp);
}
/* ---------- CloseRGroup -----------------------------------------------*/
IFFP CloseRGroup(GroupContext *context)
{
register int position;
if (context->parent == NL) {
} /* Context for whole file.*/
else {
position = context->position;
context->parent->bytesSoFar += position - context->parent->position;
context->parent->position = position;
}
return(IFF_OKAY);
}
/* ---------- SkipFwd --------------------------------------------------*/
/* Skip over bytes in a context. Won't go backwards.*/
/* Updates context->position but not context->bytesSoFar.*/
/* This implementation is AmigaDOS specific.*/
IFFP SkipFwd(GroupContext *context,int bytes)
{
IFFP iffp = IFF_OKAY;
if (bytes > 0) {
if (-1 == Seek(context->file, bytes, OFFSET_CURRENT))
iffp = BAD_IFF; /* Ran out of bytes before chunk complete.*/
else
context->position += bytes;
}
return(iffp);
}
short int endianSwap16(short int val)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
}
return val;
}
int endianSwap32(int val)
{
long int i = 1;
const char *p = (const char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
{
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
}
return val;
}
/* ---------- GetChunkHdr ----------------------------------------------*/
int GetChunkHdr(GroupContext *context0)
{
register GroupContext *context = context0;
register IFFP iffp;
int remaining;
/* Skip remainder of previous chunk & padding. */
iffp = SkipFwd(context,
ChunkMoreBytes(context) + IS_ODD(context->ckHdr.ckSize));
CheckIFFP();
/* Set up to read the newtmp header. */
context->ckHdr.ckID = BAD_IFF; /* Until we know it's okay, mark it BAD.*/
context->subtype = NULL_CHUNK;
context->bytesSoFar = 0;
/* Generate a psuedo-chunk if at end-of-context. */
remaining = context->bound - context->position;
if (remaining == 0 ) {
context->ckHdr.ckSize = 0;
context->ckHdr.ckID = END_MARK;
}
/* BAD_IFF if not enough bytes in the context for a ChunkHeader.*/
else if ((long)sizeof(ChunkHeader) > remaining) {
context->ckHdr.ckSize = remaining;
}
/* Read the chunk header (finally). */
else {
switch (Read(context->file,
&context->ckHdr, (long)sizeof(ChunkHeader)))
{
case -1: return(context->ckHdr.ckID = DOS_ERROR);
case 0: return(context->ckHdr.ckID = BAD_IFF);
}
//swap endian-ness of ckSize on little endian machines
context->ckHdr.ckSize = endianSwap32(context->ckHdr.ckSize);
/*** $$$ ***
PutID(context->ckHdr.ckID);
printf("\n");
printf("id = %lx\n", context->ckHdr.ckID);
**/
/* Check: Top level chunk must be LIST or FORM or CAT. */
if (context->parent == NL) {
if (context->ckHdr.ckID != FORM &&
context->ckHdr.ckID != LIST &&
context->ckHdr.ckID != CAT )
return(context->ckHdr.ckID = NOT_IFF);
}
/* Update the context. */
context->position += (long)sizeof(ChunkHeader);
remaining -= (long)sizeof(ChunkHeader);
/* Non-positive int values are illegal and used for error codes.*/
/* We could check for other illegal IDs...*/
if (context->ckHdr.ckID <= 0 )
context->ckHdr.ckID = BAD_IFF;
/* Check: ckSize negative or larger than # bytes left in context? */
else if (context->ckHdr.ckSize < 0 ||
context->ckHdr.ckSize > remaining) {
context->ckHdr.ckSize = remaining;
context->ckHdr.ckID = BAD_IFF;
}
/* Automatically read the LIST, FORM, PROP, or CAT subtype int */
else {
if (context->ckHdr.ckID == LIST ||
context->ckHdr.ckID == FORM ||
context->ckHdr.ckID == PROP ||
context->ckHdr.ckID == CAT) {
iffp = IFFReadBytes(context, (BYTE *)&context->subtype,
(long)sizeof(int));
if (iffp != IFF_OKAY )
context->ckHdr.ckID = iffp;
}
}
}
return(context->ckHdr.ckID);
}
/* ---------- IFFReadBytes ---------------------------------------------*/
IFFP IFFReadBytes(GroupContext *context,BYTE *buffer, int nBytes)
{
register IFFP iffp = IFF_OKAY;
if (nBytes < 0)
iffp = CLIENT_ERROR;
else if (nBytes > ChunkMoreBytes(context))
iffp = SHORT_CHUNK;
else if (nBytes > 0 )
switch ( Read(context->file, buffer, nBytes) ) {
case -1: {iffp = DOS_ERROR; break; }
case 0: {iffp = BAD_IFF; break; }
default: {
context->position += nBytes;
context->bytesSoFar += nBytes;
}
}
return(iffp);
}
/* ---------- SkipGroup ------------------------------------------------*/
IFFP SkipGroup( GroupContext* context)
{
return 0;
} /* Nothing to do, thanks to GetChunkHdr */
/* ---------- ReadIFF --------------------------------------------------*/
IFFP ReadIFF(BPTR file,ClientFrame *clientFrame)
{
/*CompilerBug register*/ IFFP iffp;
GroupContext context;
iffp = OpenRIFF(file, &context,clientFrame);
context.clientFrame = clientFrame;
if (iffp == IFF_OKAY) {
iffp = GetChunkHdr(&context);
if (iffp == FORM)
iffp = (*clientFrame->getForm)(&context);
else if (iffp == LIST)
iffp = (*clientFrame->getList)(&context);
else if (iffp == CAT)
iffp = (*clientFrame->getCat)(&context);
}
CloseRGroup(&context);
if (iffp > 0 ) /* Make sure we don't return an int.*/
iffp = NOT_IFF; /* GetChunkHdr should've caught this.*/
return(iffp);
}
/* ---------- ReadIList ------------------------------------------------*/
IFFP ReadIList(GroupContext *parent,ClientFrame *clientFrame)
{
GroupContext listContext;
IFFP iffp;
BOOL propOk = TRUE;
iffp = OpenRGroup(parent, &listContext);
CheckIFFP();
/* One special case test lets us handle CATs as well as LISTs.*/
if (parent->ckHdr.ckID == CAT)
propOk = FALSE;
else
listContext.clientFrame = clientFrame;
do {
iffp = GetChunkHdr(&listContext);
if (iffp == PROP) {
if (propOk)
iffp = (*clientFrame->getProp)(&listContext);
else
iffp = BAD_IFF;
}
else if (iffp == FORM)
iffp = (*clientFrame->getForm)(&listContext);
else if (iffp == LIST)
iffp = (*clientFrame->getList)(&listContext);
else if (iffp == CAT)
iffp = (*clientFrame->getList)(&listContext);
if (listContext.ckHdr.ckID != PROP)
propOk = FALSE; /* No PROPs allowed after this point.*/
} while (iffp == IFF_OKAY);
CloseRGroup(&listContext);
if (iffp > 0 ) /* Only chunk types above are allowed in a LIST/CAT.*/
iffp = BAD_IFF;
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
/* ---------- ReadICat -------------------------------------------------*/
/* By special arrangement with the ReadIList implement'n, this is trivial.*/
IFFP ReadICat(GroupContext *parent)
{
return( ReadIList(parent, parent->clientFrame));//NL) );
}
/* ---------- GetFChunkHdr ---------------------------------------------*/
int GetFChunkHdr(GroupContext *context)
{
register int id;
id = GetChunkHdr(context);
if (id == PROP)
context->ckHdr.ckID = id = BAD_IFF;
return(id);
}
/* ---------- GetF1ChunkHdr ---------------------------------------------*/
int GetF1ChunkHdr(GroupContext *context)
{
register int id;
register ClientFrame *clientFrame = context->clientFrame;
id = GetChunkHdr(context);
if (id == PROP)
id = BAD_IFF;
else if (id == FORM)
id = (*clientFrame->getForm)(context);
else if (id == LIST)
id = (*clientFrame->getForm)(context);
else if (id == CAT)
id = (*clientFrame->getCat)(context);
return(context->ckHdr.ckID = id);
}
/* ---------- GetPChunkHdr ---------------------------------------------*/
int GetPChunkHdr(GroupContext *context)
{
register int id;
id = GetChunkHdr(context);
if (id == LIST || id == FORM || id == PROP || id == CAT )
id = context->ckHdr.ckID = BAD_IFF;
return(id);
}