diff options
| author | Christian A. Weber <chris@gna.ch> | 1993-05-24 14:33:03 +0000 | 
|---|---|---|
| committer | Christian A. Weber <chris@gna.ch> | 1993-05-24 14:33:03 +0000 | 
| commit | 361b27b0c30811f3a9bb3ddcc8df690d8269941f (patch) | |
| tree | d88fb3de8e69193d8897b92eb808712e69f25af3 /MovieDecode | |
| parent | b89dfe99a759006aad635ee35817a9ea8b16798d (diff) | |
| download | iff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.tar.gz iff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.tar.bz2 iff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.zip | |
Initial checkin
Diffstat (limited to 'MovieDecode')
| -rw-r--r-- | MovieDecode/SimpleTest.c | 437 | 
1 files changed, 437 insertions, 0 deletions
| diff --git a/MovieDecode/SimpleTest.c b/MovieDecode/SimpleTest.c new file mode 100644 index 0000000..6c01395 --- /dev/null +++ b/MovieDecode/SimpleTest.c @@ -0,0 +1,437 @@ +/* +**	$Id: SimpleTest.c,v 1.1 93/05/22 13:42:56 chris Exp $ +**	$Revision: 1.1 $ +** +**	$Filename: MovieDecode/SimpleTest.c $ +**	$Author: chris $ +**	$Date: 93/05/22 13:42:56 $ +** +**	Simple program to test the movie decoder. +**	Usage: SimpleTest <filename> +*/ + +// #define VERBOSE + +#include <proto/exec.h> +#include <exec/memory.h> +#include <proto/graphics.h> +#include <proto/intuition.h> +#include <proto/dos.h> +#include <string.h> + +#include <libraries/iff.h>			/* Not an official CBM file */ + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +#define ID_ANSQ IFFL_MAKE_ID('A','N','S','Q') + +#define MAXFRAMES 1024		/* Max # of frames for animation (test) */ + +struct Library *IFFBase; + + +/**************************************************************************** +**	Prototypes for the MovieDecode functions +*/ + +APTR __asm +InitJDecoder(register __d0 ULONG animtype); + +VOID __asm +FreeJDecoder(register __a0 APTR handle); + +BOOL __asm +ModifyJFrame(register __a0 APTR deltas, +             register __a1 struct BitMap *bm, +             register __a2 APTR handle); + + +#ifdef VERBOSE +/**************************************************************************** +**	Not used. Dump a MOVIE frame in ASCII. Ugly code :) +*/ + +LONG DumpFrame(ULONG *chunk,struct BitMap *bm) +{ +	static WORD	frame = 0; +	int			ok = FALSE; +	UWORD		*ptr = (WORD *)(chunk+2); + +	Printf("\nFrame %ld\n", ++frame); + +	for(;;) +	{ +		WORD bytes, rows, offset; +		bytes=*ptr++; ptr++; rows=*ptr++; + +		if (bytes==1) +		{ +			goto onebyte; +		} +		else if (bytes==2) +		{ +			int entries, i; + +			bytes = *ptr++; + +			if ((bytes!=2) && (bytes!=4) && (bytes!=6)) +			{ +				Printf("Error: Secondary byte count = %ld\n\n", bytes); +				break; +			} +onebyte: +			if ((rows<1) || ((rows>8) && (rows!=16) && (rows!=32))) +			{ +				Printf("Illegal # of rows: %ld\n", rows); +				break; +			} + +			entries = *ptr++; +			Printf("  %ld bytes x %ld rows: %ld times\n", bytes, rows, entries); + +			for (i=0; i<entries; ++i) +			{ +				offset = *ptr++; +				Printf("    %ld: (%ld,%ld)\n", +					offset, offset % bm->BytesPerRow, offset / bm->BytesPerRow); + +				ptr = (void *)(((ULONG)ptr) + bm->Depth * rows * bytes); + +				if ((bytes==1) && (bm->Depth & 1) && (rows & 1)) +					ptr = (void *)(((ULONG)ptr) + 1); +			} +		} +		else if(bytes == 0) +		{ +			PutStr("End of frame\n"); +			ok = TRUE; +			break; +		} +		else +		{ +			Printf("Error: Primary byte count = %ld\n\n", bytes); +			break; +		} +	} +	return ok; +} +#endif + + +/**************************************************************************** +**	Generate the next animation frame +*/ + +LONG MyModifyFrame(ULONG *form, struct BitMap *bm, APTR decoderhandle) +{ +	ULONG *chunk; + +	if (chunk = IFFL_FindChunk(form, ID_ANHD)) +	{ +		int op = ((struct IFFL_ANHD *)(chunk+2))->Operation; + +		if (op=='J') +		{ +			if (chunk = IFFL_FindChunk(form, ID_DLTA)) +			{ +#ifdef VERBOSE +				return DumpFrame(chunk, bm); +#else +				return ModifyJFrame(chunk+2, bm, decoderhandle); +#endif +			} +		} +		else return (LONG)IFFL_ModifyFrame(form, bm);	/* ANIM5... */ +	} +} + + +/**************************************************************************** +**	Load & display an animation +*/ + +void ShowAnim(char *name) +{ +	struct IFFL_BMHD	*bmhd; +	struct BitMap		*bm1 = NULL, *bm2 = NULL; +	struct Screen		*screen = NULL; +	ULONG				*form; +	int					numframes = 0, i, swidth, sheight; +	WORD				*ansq, *anptr; +	ULONG				*seq[MAXFRAMES]; +	APTR				decoderhandle = NULL; +	ULONG				*ifffile; +	BOOL				eor; + + +	/* +	**	Load animation to memory +	*/ +	if (!(ifffile = IFFL_OpenIFF(name, IFFL_MODE_READ))) +	{ +		PutStr("Not an IFF file!\n"); +		goto cleanup; +	} + +	if(*(((ULONG *)ifffile)+2) != ID_ANIM) +	{ +		PutStr("Not an ANIM file!\n"); +		goto cleanup; +	} + +	form = ifffile+3; /* Skip FORM....ANIM */ + +	if (!(bmhd = IFFL_GetBMHD(form))) +	{ +		PutStr("No BMHD\n"); +		goto cleanup; +	} +	Printf("%ld x %ld x %ld ", bmhd->w, bmhd->h, bmhd->nPlanes); + + +	/* +	**	Calculate the screen size. Movie needs at least a 320 x 200 +	**	(or 640 x 400 in hires/interlace) screen. +	*/ +	swidth = bmhd->w; + +	if (swidth < 320) +		swidth = 320; + +	if ((swidth > 400) && (swidth < 640)) +		swidth = 640; + +	sheight = bmhd->h; +	if (sheight < 200) +		sheight = 200; + +	if ((sheight > 300) && (sheight < 400)) +		sheight = 400; + +	Printf("Screen size is %ld x %ld\n", swidth, sheight); + + +	/* +	**	Allocate the two bitmaps +	*/ +	if (!(bm1 = AllocBitMap(swidth, sheight, bmhd->nPlanes, 0/*BMF_DISPLAYABLE*/, NULL))) +	{ +		PutStr("Can't allocate bitmap 1!\n"); +		goto cleanup; +	} + +	if (!(bm2 = AllocBitMap(swidth, sheight, bmhd->nPlanes, 0/*BMF_DISPLAYABLE*/, NULL))) +	{ +		PutStr("Can't allocate bitmap 2!\n"); +		goto cleanup; +	} + + +	/* +	**	Open the screen and set the colors +	*/ +	if (screen = OpenScreenTags(NULL, +			SA_Width, 		swidth, +			SA_Height,		sheight, +			SA_Depth,		bmhd->nPlanes, +			SA_DisplayID,	IFFL_GetViewModes(form), +			SA_BitMap,		bm1, +			SA_Quiet,		TRUE, +			SA_Behind,		TRUE, +			TAG_DONE +	)) +	{ +		UWORD	colortab[256]; +		int		colorcount = IFFL_GetColorTab(form, (WORD *)colortab); + +		LoadRGB4(&screen->ViewPort, colortab, colorcount); +	} +	else +	{ +		PutStr("Can't open screen!"); +		goto cleanup; +	} + + +	/* +	**	Get pointers to all delta FORMs +	*/ +	while (form = IFFL_FindChunk(form, 0L)) +	{ +		UWORD *dlta; + +		if (*form != ID_FORM) break; + +		if (dlta = IFFL_FindChunk(form, ID_DLTA)) +		{ +			if ((dlta[4]==1) || (dlta[4]==2)) +				eor=dlta[5]; +		} +		else PutStr("No delta!"); +		seq[numframes++] = form; + +		if (numframes >= MAXFRAMES-1) +		{ +			PutStr("- Too many frames!"); +			goto cleanup; +		} +	} + + +	/* +	**	Determine the compression type +	*/ +	if (form = IFFL_FindChunk(ifffile, ID_ANSQ)) +	{ +		/* +		**	Initialize the decoder +		*/ +		if (decoderhandle = InitJDecoder((eor?0x10000L:0) | bm1->Depth)) +		{ +			Printf(eor ? "Movie reversible, " : "Movie oneway, "); +			anptr = ansq = (WORD *)(form+2); +		} +		else +		{ +			PutStr("Can't init decoder!\n"); +			goto cleanup; +		} +	} +	else +	{ +		Printf("ANIM format, "); +		ansq = NULL; +	} +	Printf("%ld frames.\n", numframes); + + +	/* +	**	Display the first frame +	*/ +	if (!IFFL_DecodePic(ifffile+3, bm1)) +	{ +		Printf("Decode error: %ld\n", IFFL_IFFError()); +		goto cleanup; +	} + + +	if(bmhd->w < 320) +		ScrollRaster(&screen->RastPort, (bmhd->w-320) / 2, 0, 0, 0, 319, bmhd->h-1); + + +	/* +	**	Display the second frame: copy and modify the first one +	*/ +	BltBitMap(bm1, 0, 0, bm2, 0, 0, screen->Width, screen->Height, 0xc0, 0xff, NULL); +	WaitBlit(); + +	if (!MyModifyFrame(seq[0], bm2, decoderhandle)) +	{ +		PutStr("Can't modify 1st frame\n"); +		goto cleanup; +	} + +	ScreenToFront(screen); + + +	/* +	**	The loop: Play animation 3 times +	*/ +	for(i=0; i<3; ++i) +	{ +		int frame = 1; +		for(;;) +		{ +			struct BitMap *dummy; + +			if (CheckSignal(SIGBREAKF_CTRL_C)) +				goto cleanup; + +			/* +			**	Flip BitMaps +			*/ +			dummy=bm1; bm1=bm2; bm2=dummy; +			screen->BitMap = *bm1;			/* ugly but only a test anyway */ +			MakeScreen(screen); +			RethinkDisplay(); + +#if 01 +			if (ansq) +			{ +				if ((anptr[1]>0) && (anptr[1]<200)) +					Delay(anptr[1]);			/* Wait 'anptr[1]' blanks */ +			} +#endif + +			if (!MyModifyFrame(seq[ansq?anptr[0]:frame], bm2, decoderhandle)) +			{ +				PutStr("Can't decode frame\n"); +				goto cleanup; +			} + +			if (ansq) +			{ +				anptr+=2; +				if (anptr[1] == -1) +				{ +					anptr = ansq+2*(anptr[0]-1); +					break; +				} +			} +			else +			{ +				if (++frame >= numframes) +					break; +			} +		} +	} +	Delay(50);	/* Show the last frame for 1 second */ + +cleanup: +	PutStr("Cleanup...\n"); + +	if (decoderhandle) +		FreeJDecoder(decoderhandle); + +	if (screen) +		CloseScreen(screen); + +	if (bm2) +		FreeBitMap(bm2); + +	if (bm1) +		FreeBitMap(bm1); +} + + +/**************************************************************************** +**	Entry point +*/ + +int main(int argc, char **argv) +{ +	if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39))) +		return RETURN_FAIL; + +	if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))) +		return RETURN_FAIL; + +	if (argc == 2) +	{ +		if (IFFBase = OpenLibrary(IFFNAME, 19)) +		{ +			ShowAnim(argv[1]);		/* Show the animation */ + +			CloseLibrary(IFFBase); +		} +		else PutStr("No iff.library!\n"); +	} +	else PutStr("Usage: SimpleTest <filename>\n"); + +	CloseLibrary((struct Library *)IntuitionBase); +	CloseLibrary((struct Library *)GfxBase); + +	return RETURN_OK; +} + | 
