/*
=====================================================================
iff.h

Ernie Wright  01 Feb 2012

Definitions and function prototypes for the ANIM-J loader.
===================================================================== */

#ifndef IFF_H
#define IFF_H

#include <stdio.h>

#ifndef TRUE
#define TRUE  1
#define FALSE 0
#endif


/* IFF IDs */

#ifdef _WIN32
#define MAKE_ID(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
#else
#define MAKE_ID(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
#endif

#define ID_FORM MAKE_ID('F','O','R','M')
#define ID_ANIM MAKE_ID('A','N','I','M')
#define ID_ILBM MAKE_ID('I','L','B','M')
#define ID_BMHD MAKE_ID('B','M','H','D')
#define ID_CMAP MAKE_ID('C','M','A','P')
#define ID_CAMG MAKE_ID('C','A','M','G')
#define ID_BODY MAKE_ID('B','O','D','Y')
#define ID_ANHD MAKE_ID('A','N','H','D')
#define ID_DLTA MAKE_ID('D','L','T','A')
#define ID_ANSQ MAKE_ID('A','N','S','Q')


/* ReadMovie() error codes */

#define EP       100
#define EPNOMEM  (EP + 0)              // Memory allocation failed.
#define EPNOFILE (EP + 1)              // Attempt to open file failed.
#define EPNOANIM (EP + 2)              // Not an IFF ANIM.
#define EPNOILBM (EP + 3)              // Not an IFF ILBM.
#define EPNOBMHD (EP + 4)              // BMHD chunk not found.
#define EPNOBODY (EP + 5)              // BODY chunk not found.
#define EPPLANES (EP + 6)              // More than 8 planes and not 24.
#define EPDLTACT (EP + 7)              // Failed while counting deltas.
#define EPDLTARD (EP + 8)              // Failed while reading deltas.
#define EPNOANSQ (EP + 9)              // ANSQ chunk not found.
#define EPFRAME1 (EP + 10)             // Frame 1 couldn't be decoded.

/* the ILBM BitmapHeader structure */

typedef struct {
   unsigned short w, h;                //  image width, height in pixels
   short          x, y;                //  image position in destination
   unsigned char  nPlanes;             //  number of bitplanes (depth)
   unsigned char  masking;             //  mask type
   unsigned char  compression;         //  compression algorithm
   unsigned char  pad1;                //  pad char for alignment
   unsigned short transparentColor;    //  a logical color number
   unsigned char  xAspect, yAspect;    //  pixel ratio of width : height
   short          pw, ph;              //  source page size
} BMHD;

#define mskNone     0
#define mskHasMask  1
#define mskHasTransparentColor 2
#define mskLasso    3

#define cmpNone     0
#define cmpByteRun1 1


/* special Commodore-Amiga display modes */

#define CAMG_HAM 0x0800
#define CAMG_EHB 0x0080
#define CAMG_LACE 0x0004


/* entries in the CMAP color table */

typedef struct { unsigned char red, green, blue; } RGBTriple;


/* animation delta */

typedef struct {
   int            size;                // size of the DLTA chunk
   unsigned char *bytes;               // pixel blocks
} DLTA;


/* animation sequence entry */

typedef struct {
   short          dindex;              // index into the delta array
   short          jiffies;             // duration in jiffies (1/60 sec)
} ANSQ;


/* an ANIM-J instance */

typedef struct {
   char          *filename;            // name of the file
   FILE          *fp;                  // file pointer
   unsigned char *rgb[ 3 ];            // 24-bit scanline buffer (3 channels)
   unsigned char *buf;                 // input buffer
   BMHD           bmhd;                // ILBM bitmap header
   unsigned long  camg;                // Amiga display mode
   int            isgray;              // TRUE if grayscale
   int            ncolors;             // number of colors in color table
   RGBTriple     *cmap;                // color table
   unsigned char *body;                // BODY bytes
   unsigned char *bp;                  // pointer into the BODY
   int            rowsize;             // bytes per bitplane row
   unsigned char *front;               // front image buffer
   unsigned char *back;                // back image buffer
   unsigned char *fb;                  // pointer into an image buffer
   DLTA          *delta;               // array of DLTAs
   int            ndeltas;             // number of deltas in delta[]
   ANSQ          *ansq;                // sequence of delta indexes and durations
   int            nansqs;              // number of ANSQs
} MovieInfo;


/* function prototypes */

MovieInfo *ReadMovie( const char *filename, int *result );
int ApplyDelta( MovieInfo *movie, int i );
void GetRow24( MovieInfo *movie, int y );
MovieInfo *FreeMovie( MovieInfo *movie );

#ifdef _WIN32
void revbytes( void *bp, int elsize, int elcount );
#else
#define revbytes( bp, elsize, elcount )
#endif

int unpack( unsigned char **psrc, unsigned char *dst, int rowsize );
int unpack_ro( unsigned char **psrc, int rowsize );
void bitrot_cw( unsigned char *src, int srcstep, unsigned char *dst, int dststep );


#endif
