diff options
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; +} + |