/**************************************************
 *
 * IFF.c
 *
 *   IFF file manipulation code
 *
 *    Copyright(c), 1990, 1991 Lloyd B. Eldred
 *                           & Fredrick R Homan
 **************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "fi_IFF.h"

extern UBYTE VERBOSE, TERSE,COMMENT;  /* Yuck, global variables... */
UBYTE ANIM_FLAG=FALSE;

/*****************************************************************/
/*    IFF Groups                                                 */
/*****************************************************************/

void IFF_FORM(picfile,size)
FILE *picfile;
LONG size;
{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;
       
   LONG sizem4;
      
   if(VERBOSE) printf("  Group FORM (data chunk)\n");
   
   sizem4 = size - 4;
   
   IFF_ID(picfile,chunk.text_ID);
   
   switch (chunk.long_ID){
      case ID_ILBM :
            IFF_ILBM(picfile,sizem4);
            break;
      case ID_ANIM :
            IFF_ANIM(picfile,sizem4);
            break;
      case ID_SMUS :
            IFF_SMUS(picfile,sizem4);
            break;
      case ID_8SVX :
            IFF_8SVX(picfile,sizem4);
            break;
      case ID_ANBM :
            IFF_ANBM(picfile,sizem4);
            break;
      case ID_ACBM :
            IFF_ACBM(picfile,sizem4);
            break;
      case ID_FTXT :
            IFF_FTXT(picfile,sizem4);
            break;
      case ID_AIFF :
            IFF_AIFF(picfile,sizem4);
            break;
      case ID_BANK :
            IFF_BANK(picfile,sizem4);
            break;
      case ID_HEAD :
            IFF_HEAD(picfile,sizem4);
            break;
      case ID_MIDI :
            IFF_MIDI(picfile,sizem4);
            break;
      case ID_PGTB : 
            IFF_PGTB(picfile,sizem4);
            break;
      case ID_SYTH :
            IFF_SYTH(picfile,sizem4);
            break;
      case ID_WORD :
            IFF_WORD(picfile,sizem4);
            break;
      case ID_C100 :
            IFF_C100(picfile,sizem4);
            break;
      case ID_PDEF :
            IFF_PDEF(picfile,sizem4);
            break;
/*
      case ID_RGB4 :
            IFF_RGB4(picfile,sizem4);
            break;
*/
      case ID_SHAK :
            IFF_SHAK(picfile,sizem4);
            break;
      case ID_VDEO :
            IFF_VDEO(picfile,sizem4);
            break;
      case ID_SAMP :
            IFF_SAMP(picfile,sizem4);
            break;
      case ID_TDDD :
            IFF_TDDD(picfile,sizem4);
            break;
      case ID_SC3D :
            IFF_SC3D(picfile,sizem4);
            break;
      case ID_TEXT :
            IFF_TEXT(picfile,sizem4);
            break;
      case ID_FNTR :
            IFF_FNTR(picfile,sizem4);
            break;
      case ID_FNTV :
            IFF_FNTV(picfile,sizem4);
            break;
      case ID_GSCR :
            IFF_GSCR(picfile,sizem4);
            break;
      case ID_PLBM :
            IFF_PLBM(picfile,sizem4);
            break;
      case ID_USCR :
            IFF_USCR(picfile,sizem4);
            break;
      case ID_UVOX :
            IFF_UVOX(picfile,sizem4);
            break;
      case ID_ARC :
            IFF_ARC(picfile,sizem4);
            break;
      default:
            if(VERBOSE) printf("  Type: %4s\n",chunk.text_ID);
            if(TERSE) printf(" %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,sizem4);

      } /* end of switch */

   if(VERBOSE) printf("  At end of current FORM.\n");      
}

void IFF_PROP(picfile,size)
FILE *picfile;
LONG size;
{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;
   LONG sizem4;
      
   if(VERBOSE) printf("  Group PROP (property setting chunk)\n");

   sizem4 = size - 4;
   
   IFF_ID(picfile,chunk.text_ID);

   switch (chunk.long_ID){
      case ID_ILBM :
            IFF_ILBM(picfile,sizem4);
            break;
      case ID_ANIM :
            IFF_ANIM(picfile,sizem4);
            break;
      case ID_SMUS :
            IFF_SMUS(picfile,sizem4);
            break;
      case ID_8SVX :
            IFF_8SVX(picfile,sizem4);
            break;
      case ID_ANBM :
            IFF_ANBM(picfile,sizem4);
            break;
      case ID_ACBM :
            IFF_ACBM(picfile,sizem4);
            break;
      case ID_FTXT :
            IFF_FTXT(picfile,sizem4);
            break;
      case ID_AIFF :
            IFF_AIFF(picfile,sizem4);
            break;
      case ID_BANK :
            IFF_BANK(picfile,sizem4);
            break;
      case ID_HEAD :
            IFF_HEAD(picfile,sizem4);
            break;
      case ID_MIDI :
            IFF_MIDI(picfile,sizem4);
            break;
      case ID_PGTB : 
            IFF_PGTB(picfile,sizem4);
            break;
      case ID_SYTH :
            IFF_SYTH(picfile,sizem4);
            break;
      case ID_WORD :
            IFF_WORD(picfile,sizem4);
            break;
      case ID_C100 :
            IFF_C100(picfile,sizem4);
            break;
      case ID_PDEF :
            IFF_PDEF(picfile,sizem4);
            break;
/*
      case ID_RGB4 :
            IFF_RGB4(picfile,sizem4);
            break;
*/
      case ID_SHAK :
            IFF_SHAK(picfile,sizem4);
            break;
      case ID_VDEO :
            IFF_VDEO(picfile,sizem4);
            break;
      case ID_SAMP :
            IFF_SAMP(picfile,sizem4);
            break;
      case ID_TDDD :
            IFF_TDDD(picfile,sizem4);
            break;
      case ID_SC3D :
            IFF_SC3D(picfile,sizem4);
            break;
      case ID_TEXT :
            IFF_TEXT(picfile,sizem4);
            break;
      case ID_FNTR :
            IFF_FNTR(picfile,sizem4);
            break;
      case ID_FNTV :
            IFF_FNTV(picfile,sizem4);
            break;
      case ID_GSCR :
            IFF_GSCR(picfile,sizem4);
            break;
      case ID_PLBM :
            IFF_PLBM(picfile,sizem4);
            break;
      case ID_USCR :
            IFF_USCR(picfile,sizem4);
            break;
      case ID_UVOX :
            IFF_UVOX(picfile,sizem4);
            break;
      case ID_ARC :
            IFF_ARC(picfile,sizem4);
            break;
      case ID_FORM :
            IFF_FORM(picfile,sizem4);
            break;
      case ID_LIST :
            IFF_LIST(picfile,sizem4);
            break;
      case ID_CAT :
            IFF_CAT(picfile,sizem4);
            break;
      case ID_PROP :
            IFF_PROP(picfile,sizem4);
            break;

      default:
            if(VERBOSE) printf("  Type: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,sizem4);

      } /* end of switch */
      
   if(VERBOSE) printf("  End of PROP\n");
}

void IFF_LIST(picfile,size)
FILE *picfile;
LONG size;
{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;

   LONG sizem4;
      
   if(VERBOSE) printf("  Group LIST (group of related data objects)\n");

   sizem4 = size - 4;
   
   IFF_ID(picfile,chunk.text_ID);

   switch (chunk.long_ID){
      case ID_ILBM :
            IFF_ILBM(picfile,sizem4);
            break;
      case ID_ANIM :
            IFF_ANIM(picfile,sizem4);
            break;
      case ID_SMUS :
            IFF_SMUS(picfile,sizem4);
            break;
      case ID_8SVX :
            IFF_8SVX(picfile,sizem4);
            break;
      case ID_ANBM :
            IFF_ANBM(picfile,sizem4);
            break;
      case ID_ACBM :
            IFF_ACBM(picfile,sizem4);
            break;
      case ID_FTXT :
            IFF_FTXT(picfile,sizem4);
            break;
      case ID_AIFF :
            IFF_AIFF(picfile,sizem4);
            break;
      case ID_BANK :
            IFF_BANK(picfile,sizem4);
            break;
      case ID_HEAD :
            IFF_HEAD(picfile,sizem4);
            break;
      case ID_MIDI :
            IFF_MIDI(picfile,sizem4);
            break;
      case ID_PGTB : 
            IFF_PGTB(picfile,sizem4);
            break;
      case ID_SYTH :
            IFF_SYTH(picfile,sizem4);
            break;
      case ID_WORD :
            IFF_WORD(picfile,sizem4);
            break;
      case ID_C100 :
            IFF_C100(picfile,sizem4);
            break;
      case ID_PDEF :
            IFF_PDEF(picfile,sizem4);
            break;
/*
      case ID_RGB4 :
            IFF_RGB4(picfile,sizem4);
            break;
*/
      case ID_SHAK :
            IFF_SHAK(picfile,sizem4);
            break;
      case ID_VDEO :
            IFF_VDEO(picfile,sizem4);
            break;
      case ID_SAMP :
            IFF_SAMP(picfile,sizem4);
            break;
      case ID_TDDD :
            IFF_TDDD(picfile,sizem4);
            break;
      case ID_SC3D :
            IFF_SC3D(picfile,sizem4);
            break;
      case ID_TEXT :
            IFF_TEXT(picfile,sizem4);
            break;
      case ID_FNTR :
            IFF_FNTR(picfile,sizem4);
            break;
      case ID_FNTV :
            IFF_FNTV(picfile,sizem4);
            break;
      case ID_GSCR :
            IFF_GSCR(picfile,sizem4);
            break;
      case ID_PLBM :
            IFF_PLBM(picfile,sizem4);
            break;
      case ID_USCR :
            IFF_USCR(picfile,sizem4);
            break;
      case ID_UVOX :
            IFF_UVOX(picfile,sizem4);
            break;
      case ID_ARC :
            IFF_ARC(picfile,sizem4);
            break;
      case ID_FORM :
            IFF_FORM(picfile,sizem4);
            break;
      case ID_LIST :
            IFF_LIST(picfile,sizem4);
            break;
      case ID_CAT :
            IFF_CAT(picfile,sizem4);
            break;
      case ID_PROP :
            IFF_PROP(picfile,sizem4);
            break;
      default:
            if(VERBOSE) printf("  Type: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,sizem4);

      } /* end of switch */
 
   if(VERBOSE) printf("  End of LIST\n");
   
}

void IFF_CAT(picfile,size)
FILE *picfile;
LONG size;
{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;

   LONG sizem4;
      
   if(VERBOSE) printf("  Group CAT (untyped group of data objects)\n");

   sizem4 = size - 4;
   
   IFF_ID(picfile,chunk.text_ID);

   switch (chunk.long_ID){
      case ID_ILBM :
            IFF_ILBM(picfile,sizem4);
            break;
      case ID_ANIM :
            IFF_ANIM(picfile,sizem4);
            break;
      case ID_SMUS :
            IFF_SMUS(picfile,sizem4);
            break;
      case ID_8SVX :
            IFF_8SVX(picfile,sizem4);
            break;
      case ID_ANBM :
            IFF_ANBM(picfile,sizem4);
            break;
      case ID_ACBM :
            IFF_ACBM(picfile,sizem4);
            break;
      case ID_FTXT :
            IFF_FTXT(picfile,sizem4);
            break;
      case ID_AIFF :
            IFF_AIFF(picfile,sizem4);
            break;
      case ID_BANK :
            IFF_BANK(picfile,sizem4);
            break;
      case ID_HEAD :
            IFF_HEAD(picfile,sizem4);
            break;
      case ID_MIDI :
            IFF_MIDI(picfile,sizem4);
            break;
      case ID_PGTB : 
            IFF_PGTB(picfile,sizem4);
            break;
      case ID_SYTH :
            IFF_SYTH(picfile,sizem4);
            break;
      case ID_WORD :
            IFF_WORD(picfile,sizem4);
            break;
      case ID_C100 :
            IFF_C100(picfile,sizem4);
            break;
      case ID_PDEF :
            IFF_PDEF(picfile,sizem4);
            break;
/*
      case ID_RGB4 :
            IFF_RGB4(picfile,sizem4);
            break;
*/
      case ID_SHAK :
            IFF_SHAK(picfile,sizem4);
            break;
      case ID_VDEO :
            IFF_VDEO(picfile,sizem4);
            break;
      case ID_SAMP :
            IFF_SAMP(picfile,sizem4);
            break;
      case ID_TDDD :
            IFF_TDDD(picfile,sizem4);
            break;
      case ID_SC3D :
            IFF_SC3D(picfile,sizem4);
            break;
      case ID_TEXT :
            IFF_TEXT(picfile,sizem4);
            break;
      case ID_FNTR :
            IFF_FNTR(picfile,sizem4);
            break;
      case ID_FNTV :
            IFF_FNTV(picfile,sizem4);
            break;
      case ID_GSCR :
            IFF_GSCR(picfile,sizem4);
            break;
      case ID_PLBM :
            IFF_PLBM(picfile,sizem4);
            break;
      case ID_USCR :
            IFF_USCR(picfile,sizem4);
            break;
      case ID_UVOX :
            IFF_UVOX(picfile,sizem4);
            break;
      case ID_ARC :
            IFF_ARC(picfile,sizem4);
            break;
      case ID_FORM :
            IFF_FORM(picfile,sizem4);
            break;
      case ID_LIST :
            IFF_LIST(picfile,sizem4);
            break;
      case ID_CAT :
            IFF_CAT(picfile,sizem4);
            break;
      case ID_PROP :
            IFF_PROP(picfile,sizem4);
            break;
      default:
            if(VERBOSE) printf("  Type: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,sizem4);

      } /* end of switch */
   
   if(VERBOSE)printf("  End of CAT.\n");
}

/***************************************************************/ 
/* FORM type handling   (see ILBM.c, SMUS.c, etc for others    */
/***************************************************************/
 
void IFF_ANIM(picfile,size)
FILE *picfile;
LONG size;

{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;
   LONG ch_size,offset;
        
	if(!TERSE)printf("    ANIM (Cel Animation)\n");
   if(TERSE)printf("ANIM");
   offset=0;
   ANIM_FLAG = TRUE;
   
   while(offset <= size-8){
      IFF_ID(picfile,chunk.text_ID);
      ch_size = IFF_size(picfile);
      offset += (8+ch_size+is_odd(ch_size));
            
      switch(chunk.long_ID){
         case ID_ANHD :
            IFF_ANHD(picfile,ch_size);
            break;
         case ID_DLTA :
            IFF_DLTA(picfile,ch_size);
            break;
         case ID_FORM :
            IFF_FORM(picfile,ch_size);
            break;
         case ID_ILBM :
            IFF_ILBM(picfile,ch_size);
            break;
         default:
            if(VERBOSE) printf(
               "   Inappropriate sub chunk for ANIM: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,ch_size);
      } /* end of switch */
      
   } /* end of while */

   IFF_GotoEnd(picfile,size-offset);
         
   if(VERBOSE) printf("    End of ANIM.\n");
   
} /* End of IFF_Anim */

void IFF_ANBM(picfile,size)
FILE *picfile;
LONG size;

{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;
   LONG ch_size,offset;
        
   printf("    ANBM (Animated bitmap -- Deluxe Video)\n");
   offset=0;
   
   while(offset <= size-8){
      IFF_ID(picfile,chunk.text_ID);
      ch_size = IFF_size(picfile);
      offset += (8+ch_size+is_odd(ch_size));
            
      switch(chunk.long_ID){
         case ID_FSQN :
            IFF_FSQN(picfile,ch_size);
            break;
         case ID_LIST :
            IFF_LIST(picfile,ch_size);
            break;
         case ID_PROP :
            IFF_PROP(picfile,ch_size);
            break;
         case ID_FORM :
            IFF_FORM(picfile,ch_size);
            break;
         case ID_BODY :
            IFF_BODY(picfile,ch_size);
            break;
         default:
            if(VERBOSE) printf(
               "   Inappropriate sub chunk for ANBM: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,ch_size);
      } /* end of switch */
      
   } /* end of while */
   IFF_GotoEnd(picfile,size-offset);
   
   if(VERBOSE) printf("    End of ANBM.\n");
   
} /* end of IFF_ANBM */

void IFF_ACBM(picfile,size)
FILE *picfile;
LONG size;

{
   union chunk_ID{
       char text_ID[4];
       LONG long_ID;} chunk;

   LONG ch_size,offset,vpmodes;
   BitMapHeader *BMHD;
        
   printf("    ACBM (Amiga Continuous Bit Map)\n");
   
   offset=0;
   
   while(offset <= (size-8)){
      IFF_ID(picfile,chunk.text_ID);
      ch_size = IFF_size(picfile);
      offset += (8+ch_size+is_odd(ch_size));
                    
      switch(chunk.long_ID){
         case ID_BMHD :
            BMHD = malloc(sizeof(BitMapHeader));
            if(BMHD == NULL){
               printf(" Can't allocate memory for BMHD structure.\n");
               fi_exit();
            }
            IFF_BMHD(picfile,ch_size,BMHD);
            if(VERBOSE) 
               printf("      BMHD (Bit Map HeaDer chunk)\n");
               printf("        Width        : %d\n"
                       "        Height       : %d\n"
                       "        # bit planes : %d\n",
                       BMHD->w,BMHD->h,BMHD->nPlanes);
            free(BMHD);
            break;
            
         case ID_CMAP :
            IFF_CMAP(picfile,ch_size);
            break;
         case ID_ABIT :
            IFF_ABIT(picfile,ch_size);
            break;
         case ID_ANHD :
            IFF_ANHD(picfile,ch_size);
            break;
         case ID_GRAB :
            IFF_GRAB(picfile,ch_size);
            break;
         case ID_DEST :
            IFF_DEST(picfile,ch_size);
            break;
         case ID_SPRT :
            IFF_SPRT(picfile,ch_size);
            break;
         case ID_CAMG :
            vpmodes=IFF_CAMG(picfile,ch_size);
            if(VERBOSE) printf("      CAMG (Amiga Display Mode) chunk.\n");
            break;
         case ID_CRNG :
            IFF_CRNG(picfile,ch_size);
            break;
         case ID_CCRT :
            IFF_CCRT(picfile,ch_size);
            break;
         case ID_NAME :
            IFF_NAME(picfile,ch_size);
            break;
         case ID_copyright :
            IFF_copyright(picfile,ch_size);
            break;
         case ID_AUTH :  
            IFF_AUTH(picfile,ch_size);
            break;
         case ID_ANNO :
            IFF_ANNO(picfile,ch_size);
            break;
         case ID_CHRS :
            IFF_CHRS(picfile,ch_size);
            break;
         case ID_TEXT :
            IFF_TEXT(picfile,ch_size);
            break;
         case ID_DPPV :
            IFF_DPPV(picfile,ch_size);
            break;
         case ID_DGVW :
            IFF_DGVW(picfile,ch_size);
            break;
         case ID_BHSM :
            IFF_BHSM(picfile,ch_size);
            break;
         case ID_BHCP :
            IFF_BHCP(picfile,ch_size);
            break;
         case ID_BHBA :
            IFF_BHBA(picfile,ch_size);
            break;
         default:
            if(VERBOSE) printf(
               "     Inappropriate sub chunk for ACBM: %4s\n",chunk.text_ID);
            IFF_GotoEnd(picfile,ch_size);
      } /* end of switch */
      
   } /* end of while */

   IFF_GotoEnd(picfile,size-offset);
   if(VERBOSE) printf("    End of ACBM chunk\n");
      
}/* end of IFF_ACBM */

/*************************************************************/ 
/* Chunks that can appear anywhere                           */
/*************************************************************/

void IFF_NAME(picfile,size)
FILE *picfile;
LONG size;

{
   char c;
   int i;
   
   if(VERBOSE || COMMENT) printf("      NAME chunk. (text follows)\n\n");
   
   for(i=0;i<size;i++){
      fi_getc(picfile,&c);
      if(VERBOSE || COMMENT) printf("%c",c);
   }
   if(VERBOSE || COMMENT) printf("\n\n");
   
   if(is_odd(size)) fi_getc(picfile,&c);
   
} /* end of IFF_NAME */

void IFF_copyright(picfile,size)
FILE *picfile;
LONG size;

{
   char c;
   int i;
   
   if(VERBOSE || COMMENT) printf(
   "      Copyright chunk. (text follows)\n\n(c)");
   
   for(i=0;i<size;i++){
      fi_getc(picfile,&c);
      if(VERBOSE || COMMENT) printf("%c",c);
   }
   if(VERBOSE || COMMENT) printf("\n\n");
   
   if(is_odd(size)) fi_getc(picfile,&c);
  
} /* end of IFF_copyright */

void IFF_AUTH(picfile,size)
FILE *picfile;
LONG size;

{
   char c;
   int i;
   
   if(VERBOSE || COMMENT) printf
      ("      AUTH (Author) chunk. (text follows)\n\n");
   
   for(i=0;i<size;i++){
      fi_getc(picfile,&c);
      if(VERBOSE || COMMENT)printf("%c",c);
   }
   if(VERBOSE || COMMENT ) printf("\n\n");
   
   if(is_odd(size)) fi_getc(picfile,&c);
   
} /* end of IFF_AUTH */

void IFF_ANNO(picfile,size)
FILE *picfile;
LONG size;
{
   char c;
   int i;
   
   if(VERBOSE || COMMENT) 
      printf("      ANNO (Annotation) chunk.(text follows)\n\n");
   
   for(i=0;i<size;i++){
      fi_getc(picfile,&c);
      if(VERBOSE || COMMENT)printf("%c",c);
   }
   if(VERBOSE || COMMENT) printf("\n\n");
   
   if(is_odd(size)) fi_getc(picfile,&c);
   
} /* end of IFF_ANNO */

/************************************************************/
/* Useful chunks for non-picture files (headers in general) */
/************************************************************/

void IFF_ANHD(picfile,size)  /* deal with ANimation HeaDer chunk */
FILE *picfile;
LONG size;

{
   char c1,c2,c3,c4;
   ULONG abstime,reltime,bits;
   UBYTE operation,interleave;
   UWORD w,h;
   WORD x,y;
   int XORprint;   /* logical: true if XOR mode and VERBOSE are true */
   int BITprint;   /* logical:         mode 4 or 5 and VERBOSE */
     
	fi_getc(picfile,&c1);   /* UBYTE operation */
   operation = c1;
   
   if(VERBOSE) printf("      ANHD (Animation Header) chunk.\n");
   if(VERBOSE){
			printf("       Compression Mode      :");
			if(operation == 0) printf(" None\n");
			if(operation == 1) printf(" XOR ILBM mode\n");
			if(operation == 2) printf(" Long Delta mode\n");
			if(operation == 3) printf(" Short Delta mode\n");
			if(operation == 4) printf(
				" Gen. short/long Delta mode\n");
			if(operation == 5) printf(
				" Byte Vertical Delta mode\n");
			if(operation == 'J') printf(
				" Eric Graham's technique\n");
            }
   
   XORprint = VERBOSE && (operation == 1);
   BITprint = VERBOSE && (operation == 4 || operation == 5);
   
   fi_getc(picfile,&c2);   /* UBYTE mask */
   
   if(XORprint)
         printf("       Plane mask: %d",c2);
         
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   
   w = c1 * 256 + c2;
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   
   h = c1 * 256 + c2;
   
   if(XORprint)
      printf("       BODY part to be changed has: width %d and height %d.\n",
               w,h);             
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   
   x = c1 * 256 + c2;
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   
   y = c1 * 256 + c2;
   
   if(XORprint)
      printf("       BODY part to be changed has position:"
             " x = %d and y = %d.\n",x,y);
                
	fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   fi_getc(picfile,&c3);
   fi_getc(picfile,&c4);
   
   abstime = (unsigned long)makelong(c1,c2,c3,c4);
	
   if(VERBOSE && abstime)
      printf("       Absolute Frame timing (jiffies): %d"
					,abstime);
     
	fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   fi_getc(picfile,&c3);
   fi_getc(picfile,&c4);
   
   reltime = (unsigned long)makelong(c1,c2,c3,c4);
	
   if(VERBOSE && reltime)
      printf("       Relative Frame timing (jiffies): %d"
					,reltime);
	
   if(VERBOSE && (reltime || abstime)) 
      printf("          (1 jiffy=1/60 sec)\n");
   
   fi_getc(picfile,&c1);
   
   interleave = c1;
   
   if(VERBOSE && interleave)
      printf("       Interleave code : %d.\n",interleave);
      
   fi_getc(picfile,&c1);   /* pad0 byte */
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   fi_getc(picfile,&c3);
   fi_getc(picfile,&c4);
   
   if(BITprint){
      bits = (ULONG)makelong(c1,c2,c3,c4);
      printf("       Bit flag options:\n");
      
      printf("         Bit 0 :");
      if(bits & 0x1)
         printf(" one , long data\n");
      else
         printf(" zero, short data\n");
         
      printf("         Bit 1 :");
      if(bits & 0x2)
         printf(" one , XOR\n");
      else
         printf(" zero, set\n");
      
      printf("         Bit 2 :");
      if(bits & 0x4)
         printf(" one , one info list for all planes.\n");
      else
         printf(" zero, separate info for each plane.\n");

      printf("         Bit 3 :");
      if(bits & 0x8)
         printf(" one , Run length coded\n");
      else
         printf(" zero, not run length coded\n");
         
      printf("         Bit 4 :");
      if(bits & 0x10)
         printf(" one , vertical\n");
      else
         printf(" zero, horizontal\n");

      printf("         Bit 5 :");
      if(bits & 0x20)
         printf(" one , long info offsets\n");
      else
         printf(" zero, short info offsets\n");
    
      } /* end of if(BITprint) */
      
/* 
 * This chunk is currently defined to have a 16 byte padding on it for
 * future expansion. Skip it, and anything else left over from "size"
 */
 
      IFF_GotoEnd(picfile,size-24);
      
} /* End of IFF_ANHD */

void IFF_DLTA(picfile,size)
FILE *picfile;
LONG size;

{
   
   if(VERBOSE) printf("      DLTA (Delta Compression Data) chunk.\n");
   
   IFF_GotoEnd(picfile,size);
      
} /* end of IFF_DLTA */

void IFF_FSQN(picfile,size)
FILE *picfile;
LONG size;

{
   char c1,c2,c3,c4;
   WORD numframes;
   LONG dt;
   WORD flags;
   int i;
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
			
   numframes = (WORD)c2 + (WORD)(c1<<8);
			
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   fi_getc(picfile,&c3);
   fi_getc(picfile,&c4);
			
	dt = makelong(c1,c2,c3,c4);
   
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
			
   flags = (WORD)c2 + (WORD)(c1<<8);
	
   		
   if(VERBOSE){
      printf("      FSQN (Frame sequence) chunk\n");
      printf("        Number of Frames              : %d\n",
				numframes);
		printf("        Time between frames (jiffies) : %d",
				dt);
		printf("           (1 jiffy=1/60 sec)\n");
      if(flags && 0x1)
         printf("       Cycle flag set: ignore sequence, cycle a..z,a..z\n");
      else if(flags && 0x2)
         printf("       To-fro flag set: ignore sequence, cycle a..z,y..a\n");
      else
         printf("       Sequence:");
   }

   for(i=0;i<80;i++){
      fi_getc(picfile,&c1);
      if(VERBOSE && !(flags && 0x3))
         printf("%c,",c1);
      }
      
   
   IFF_GotoEnd(picfile,size-86);
   
} /* End of IFF_FSQN */

/*************************************************************/
/*    Miscellaneous IFF utility functions                    */
/*************************************************************/

void IFF_ID(picfile,chunk_ID) /* read chunk ID (4 bytes) */
FILE *picfile;
char *chunk_ID;
{
   if(fread(chunk_ID,4,1,picfile) != 1)
      {
         printf("Unexpected end of file (I-ID)\n");
         close(picfile);
         fi_exit();
      }
   
} /* end of IFF_ID */

LONG IFF_size(picfile) /* return size of chunk */
FILE *picfile;
{
   LONG size;
   unsigned char c1,c2,c3,c4;
      
   fi_getc(picfile,&c1);
   fi_getc(picfile,&c2);
   fi_getc(picfile,&c3);
   fi_getc(picfile,&c4);
   
   size = (ULONG)(c1<<24) + (ULONG)(c2<<16) + (ULONG)(c3<<8) + (ULONG)c4;
          
   return(size);
   
} /* end of IFF_size */

void IFF_GotoEnd(picfile,offset) /* Goto end of chunk of size "offset" */
FILE *picfile;
LONG offset;
{
   char c;
   
   if (fseek(picfile,offset,1) == -1){
         printf(" Unexpected end of file. (I-GotoEnd)\n");  
         fclose(picfile);
         fi_exit();
      }
   
   if(is_odd(offset)) fi_getc(picfile,&c); /* read to even boundary */
}
