summaryrefslogtreecommitdiff
path: root/MovieDecode
diff options
context:
space:
mode:
authorChristian A. Weber <chris@gna.ch>1993-05-24 14:33:03 +0000
committerChristian A. Weber <chris@gna.ch>1993-05-24 14:33:03 +0000
commit361b27b0c30811f3a9bb3ddcc8df690d8269941f (patch)
treed88fb3de8e69193d8897b92eb808712e69f25af3 /MovieDecode
parentb89dfe99a759006aad635ee35817a9ea8b16798d (diff)
downloadiff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.tar.gz
iff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.tar.bz2
iff-library-361b27b0c30811f3a9bb3ddcc8df690d8269941f.zip
Initial checkin
Diffstat (limited to 'MovieDecode')
-rw-r--r--MovieDecode/SimpleTest.c437
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;
+}
+