home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / Linux / Apps / xanim.tgz / xanim / xanim27064 / xa_iff.c < prev    next >
C/C++ Source or Header  |  1997-01-26  |  87KB  |  2,845 lines

  1.  
  2. /*
  3.  * xa_iff.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994,1995,1996,1997 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim.h"
  19. #include "xa_iff.h"
  20.  
  21. xaULONG IFF_Read_File();
  22. void IFF_Adjust_For_EHB();
  23. void IFF_Read_BODY();
  24. void IFF_Print_ID();
  25. xaULONG IFF_Delta_Body();
  26. xaULONG IFF_Delta_l();
  27. xaULONG IFF_Delta_3();
  28. xaULONG IFF_Delta_5();
  29. xaULONG IFF_Delta_7();
  30. xaULONG IFF_Delta_8();
  31. xaULONG IFF_Delta_J();
  32. void IFF_Long_Mod();
  33. void IFF_Buffer_Action();
  34. void IFF_Buffer_HAM6();
  35. void IFF_Buffer_HAM8();
  36. void IFF_Setup_HMAP();
  37. void IFF_Setup_CMAP();
  38. IFF_ACT_LST *IFF_Add_Frame();
  39. void IFF_Image_To_Bufferable();
  40. void IFF_Read_BMHD();
  41. void IFF_Read_ANHD();
  42. void IFF_Read_ANSQ();
  43. void IFF_Register_CRNGs();
  44. void IFF_Read_CRNG();
  45. void IFF_Read_CMAP_0();
  46. void IFF_Read_CMAP_1();
  47. void IFF_Init_DLTA_HDR();
  48. void IFF_Update_DLTA_HDR();
  49. void IFF_Free_Stuff();
  50. void IFF_Shift_CMAP();
  51. void IFF_HAM6_As_True();
  52. void IFF_HAM8_As_True();
  53. void IFF_Hash_CleanUp();
  54. void IFF_Hash_Init();
  55. void IFF_Hash_Add();
  56. XA_ACTION *IFF_Hash_Get();
  57. xaULONG IFF_Check_Same();
  58.  
  59.  
  60. xaULONG CMAP_Get_Or_Mask();
  61. XA_CHDR *CMAP_Create_332();
  62. XA_CHDR *CMAP_Create_Gray();
  63. XA_CHDR *CMAP_Create_CHDR_From_True();
  64. void ACT_Add_CHDR_To_Action();
  65. void ACT_Del_CHDR_From_Action();
  66. void UTIL_Mapped_To_Bitmap();
  67. void UTIL_Mapped_To_Mapped();
  68. xaUBYTE *UTIL_RGB_To_Map();
  69. xaUBYTE *UTIL_RGB_To_FS_Map();
  70. void ACT_Free_Act();
  71. xaULONG UTIL_Get_Buffer_Scale();
  72. void UTIL_Scale_Pos_Size();
  73.  
  74. extern xaLONG xa_anim_cycling;
  75.  
  76. XA_ACTION *ACT_Get_Action();
  77. void ACT_Setup_Mapped();
  78. void UTIL_Sub_Image();
  79. XA_CHDR *ACT_Get_CMAP();
  80.  
  81. #define IFF_SPEED_DEFAULT 3
  82. #define IFF_MS_PER_60HZ  17
  83. #define ACT_IFF_HMAP6 0x2000
  84. #define ACT_IFF_HMAP8 0x2001
  85.  
  86. typedef struct
  87. {
  88.   xaULONG flag;
  89.   XA_ACTION *dlta;
  90.   XA_ACTION *src;
  91.   XA_ACTION *dst;
  92.   XA_ACTION *nxtdlta;
  93. } IFF_HASH;
  94.  
  95. IFF_HASH *iff_hash_tbl;
  96. xaULONG iff_hash_cur = 0;
  97.  
  98.  
  99. static IFF_ANSQ *iff_ansq;
  100. static xaULONG iff_ansq_cnt;
  101. static IFF_DLTA_TABLE *iff_dlta_acts;
  102.  
  103. static xaLONG  iff_allow_cycling;
  104. static xaULONG iff_time;
  105. static xaULONG iff_anim_flags;
  106. static xaULONG iff_cmap_bits;
  107. static ColorReg iff_hmap[XA_HMAP_SIZE];
  108. static ColorReg *iff_cur_hmap;
  109. static ColorReg iff_cmap[256];
  110. static XA_CHDR *iff_chdr;
  111.  
  112. static xaLONG mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  113.  
  114. static IFF_ACT_LST *iff_act_start,*iff_act_cur;
  115. static xaULONG iff_act_cnt;
  116. static xaULONG iff_dlta_cnt;
  117. static xaULONG iff_dlta_compression,iff_dlta_bits;
  118.  
  119. static xaULONG iff_imagex,iff_imagey,iff_imagec,iff_imaged;
  120. static xaULONG iff_max_imagex,iff_max_imagey,iff_max_imagec,iff_max_imaged;
  121. static xaULONG iff_or_mask;
  122. static xaULONG iff_max_fvid_size;
  123.  
  124. extern xaULONG xa_ham_map_size;
  125. extern xaULONG *xa_ham_map;
  126. extern XA_CHDR *xa_ham_chdr;
  127. extern xaULONG xa_ham_init;
  128.  
  129. /*
  130.  * NOTES: the iff_cmap is read in as 8 bits. It's shifted down to 4 bits
  131.  * before ACT_GET_CMAP is called(unless there are 8 bit planes)
  132.  * How does one know whether is 4 bits or 8 bits per color component?
  133.  */
  134.  
  135. void
  136. IFF_TheEnd()
  137. {
  138.   IFF_Free_Stuff();
  139.   TheEnd();
  140. }
  141.  
  142. void
  143. IFF_TheEnd1(p)
  144. char *p;
  145. {
  146.   IFF_Free_Stuff();
  147.   TheEnd1(p);
  148. }
  149.  
  150. IFF_ACT_LST *IFF_Add_Frame(type,act)
  151. xaULONG type;
  152. XA_ACTION *act;
  153. {
  154.   IFF_ACT_LST *iframe;
  155.  
  156.   iframe = (IFF_ACT_LST *) malloc(sizeof(IFF_ACT_LST));
  157.   if (iframe == 0) IFF_TheEnd1("IFF_Add_Frame: malloc err");
  158.  
  159.   if (type == 1) iff_dlta_cnt++;
  160.   iframe->type = type;
  161.   iframe->act = act;
  162.   iframe->next = 0;
  163.  
  164.   if (iff_act_start == 0) iff_act_start = iframe;
  165.   else iff_act_cur->next = iframe;
  166.  
  167.   iff_act_cur = iframe;
  168.   iff_act_cnt++;
  169.   return(iframe);
  170. }
  171.  
  172. void
  173. IFF_Free_Stuff()
  174. {
  175.   IFF_ACT_LST *itmp;
  176.  
  177.   if (iff_ansq) FREE(iff_ansq,0x1000);
  178.   if (iff_dlta_acts) FREE(iff_dlta_acts,0x1001); 
  179.   iff_ansq = 0; iff_dlta_acts = 0;
  180.   while(iff_act_start != 0)
  181.   {
  182.     itmp = iff_act_start;
  183.     iff_act_start = iff_act_start->next;
  184.     FREE(itmp,0x1003);
  185.   }
  186.   iff_ansq = 0;
  187.   iff_dlta_acts = 0;
  188.   iff_act_start = 0;
  189. }
  190.  
  191.  
  192. /*
  193.  *
  194.  */
  195. xaULONG IFF_Read_File(fname,anim_hdr)
  196. xaBYTE *fname;
  197. XA_ANIM_HDR *anim_hdr;
  198. { XA_INPUT *xin = anim_hdr->xin;
  199.   xaLONG camg_flag,cmap_flag,chdr_flag,ret;
  200.   xaLONG crng_flag,formtype;
  201.   xaLONG ansq_flag;
  202.   xaLONG face_flag,bmhd_flag,file_size,file_read;
  203.   Bit_Map_Header bmhd;
  204.   Chunk_Header  chunk;
  205.   xaLONG prop_flag;
  206.   xaLONG exit_flag;
  207.  
  208.  
  209.   iff_allow_cycling = (anim_hdr->anim_flags & ANIM_CYCLE)?(xaTRUE):(xaFALSE);
  210.   iff_act_start    = 0;
  211.   iff_act_cur    = 0;
  212.   iff_act_cnt    = 0;
  213.   iff_dlta_compression = 0xffff;
  214.   iff_dlta_bits = 0;
  215.   iff_anim_flags = anim_hdr->anim_flags & ~(ANIM_LACE | ANIM_HAM | ANIM_CYCLE);
  216.   file_size    = 0;
  217.   file_read    = 0;
  218.   iff_imagex = iff_max_imagex = 0;
  219.   iff_imagey = iff_max_imagey = 0;
  220.   iff_imagec = iff_max_imagec = 0;
  221.   iff_imaged = iff_max_imaged = 0;
  222.   iff_or_mask = 0;
  223.   iff_max_fvid_size = 0;
  224.   prop_flag    = 0;
  225.   bmhd_flag    = 0;
  226.   face_flag    = 0;
  227.   crng_flag    = 0;
  228.   camg_flag    = 0;
  229.   cmap_flag    = xaFALSE;
  230.   chdr_flag    = xaFALSE;
  231.   ansq_flag    = 0;
  232.   iff_ansq    = 0;
  233.   iff_ansq_cnt    = 0;
  234.   iff_dlta_acts    = 0;
  235.   iff_dlta_cnt    = 0;
  236.   iff_chdr    = 0;
  237.   iff_cmap_bits = 4;
  238.   iff_cur_hmap  = 0;
  239.  
  240.   exit_flag = 0; 
  241.   while( !xin->At_EOF(xin,-1) && !exit_flag)
  242.   {
  243.     /* read Chunk_Header 
  244.     */
  245.     chunk.id   = xin->Read_MSB_U32(xin);
  246.     chunk.size = xin->Read_MSB_U32(xin);
  247.  
  248.     if ( xin->At_EOF(xin,-1) ) break;    
  249.     if (chunk.size == -1) ret = -1;
  250.     else ret = 0;
  251.  
  252.     DEBUG_LEVEL1
  253.     {
  254.       fprintf(stderr,"Chunk.ID = ");
  255.       IFF_Print_ID(stderr,chunk.id);
  256.       fprintf(stderr,"  chunksize=%x\n",chunk.size);
  257.     }
  258.     if (chunk.size & 1) chunk.size += 1; /* halfword pad it */
  259.     if (ret==0)
  260.     {
  261.       switch(chunk.id)
  262.       {
  263.         case PROP: 
  264.                 prop_flag=1;
  265.         case LIST: 
  266.         case FORM: 
  267.                 formtype = xin->Read_MSB_U32(xin);
  268.         file_size = chunk.size;
  269.         if (file_size & 0x01) file_size++;
  270.  
  271.         if (   (formtype != 0x494C424D)   /* ILBM 0x494C424D */
  272.             && (formtype != 0x414E494D) ) /* ANIM 0x414E494D */
  273.         {
  274.           fprintf(stderr,"IFF: unsupported FORM Type: ");
  275.           IFF_Print_ID(stderr,formtype);
  276.                   fprintf(stderr,"\n");
  277.           xin->Seek_FPos(xin,file_size,1);
  278.           file_read = 0;
  279.         }
  280.         else    file_read = -1;
  281.  
  282.                 DEBUG_LEVEL2
  283.                 {
  284.                   fprintf(stderr,"  IFF ");
  285.                   IFF_Print_ID(stderr,chunk.id);
  286.                   fprintf(stderr," = ");
  287.                   IFF_Print_ID(stderr,formtype);
  288.                   fprintf(stderr,"\n");
  289.                 }
  290.                 break;
  291.         case BMHD:
  292.         IFF_Read_BMHD(xin,&bmhd);
  293.                 if (xa_verbose)
  294.                 { fprintf(stderr,"     Size %dx%dx%d comp=%d masking=%d\n",
  295.                                 bmhd.width,bmhd.height,bmhd.depth,
  296.                                 bmhd.compression,bmhd.masking);
  297.                 }
  298.                 iff_imagex = bmhd.width;
  299.                 iff_imagey = bmhd.height;
  300.                 iff_imaged = bmhd.depth;
  301.         if (iff_imaged == 8) iff_cmap_bits = 8;
  302.         else iff_cmap_bits = 4;
  303.                 if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex;
  304.                 if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey;
  305.                 if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged;
  306.         /* or_mask is used to move pixels to upper reaches of cmap
  307.          */
  308.         iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged);
  309.                 bmhd_flag = 1;
  310.                 break;
  311.  
  312.     case FACE: /* used in MovieSetter anims */
  313.           {
  314.         xaULONG garb;
  315.         bmhd.pageWidth  = bmhd.width  = xin->Read_MSB_U16(xin);
  316.         bmhd.pageHeight = bmhd.height = xin->Read_MSB_U16(xin);
  317.         garb = xin->Read_MSB_U32(xin); /* read x, y */
  318.         garb = xin->Read_MSB_U32(xin); /* read xoff, yoff */
  319.         bmhd.depth = 5;
  320.         bmhd.compression = BMHD_COMP_BYTERUN;
  321.         bmhd.x = bmhd.y = bmhd.masking = 0;
  322.         bmhd.transparentColor = 0;
  323.         bmhd.xAspect = bmhd.yAspect = 0;
  324.                 face_flag = bmhd_flag = 1;
  325.                 iff_imagex = bmhd.width;
  326.                 iff_imagey = bmhd.height;
  327.                 iff_imaged = bmhd.depth;
  328.                 if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex;
  329.                 if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey;
  330.                 if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged;
  331.         iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged);
  332.                 if (xa_verbose)
  333.                 {
  334.                  fprintf(stderr,"     Size %dx%dx%d comp=%d masking=%d\n",
  335.                                 bmhd.width,bmhd.height,bmhd.depth,
  336.                                 bmhd.compression,bmhd.masking);
  337.                 }
  338.           }
  339.               break;
  340.  
  341.         case CAMG:
  342.                 {
  343.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CAMG\n");
  344.                   if (chunk.size != 4) 
  345.                   { 
  346.             xin->Seek_FPos(xin,chunk.size,1);
  347.                     break;
  348.                   }
  349.  
  350.                   camg_flag = xin->Read_MSB_U32(xin) | IFF_CAMG_NOP;
  351.  
  352.                   if ((camg_flag & IFF_CAMG_EHB) && (cmap_flag == xaTRUE))  
  353.                   {
  354.                     IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits);
  355.             iff_chdr = 
  356.             ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  357.                 iff_imagec,iff_or_mask,
  358.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  359.             chdr_flag = xaTRUE;
  360.                     break;
  361.                   }
  362.                   if (camg_flag & IFF_CAMG_LACE) iff_anim_flags |= ANIM_LACE;
  363.  
  364.                   if ((camg_flag & IFF_CAMG_HAM) && (cmap_flag == xaTRUE)) 
  365.                   {
  366.                     XA_ACTION *act;
  367.  
  368.                         /* CREATE ACT_IFF_HMAP chunk */
  369.                     if (iff_cmap_bits == 8)
  370.                     {
  371.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8);
  372.                       iff_anim_flags |= ANIM_HAM8;
  373.                     }
  374.                     else
  375.                     {
  376.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6);
  377.                       iff_anim_flags |= ANIM_HAM6;
  378.                     }
  379.                     IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits);
  380.                     iff_cur_hmap = (ColorReg *)act->data;
  381.  
  382.                     if (cmap_true_to_332 == xaTRUE)
  383.                     {
  384.                       iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  385.               iff_or_mask = 0;
  386.                     }
  387.                     else /* if (cmap_true_to_gray == xaTRUE) */
  388.                     {
  389.                       iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  390.               iff_or_mask = 0;
  391.                     }
  392.                     chdr_flag = xaTRUE;
  393.                   }
  394.                 }
  395.                 break;
  396.  
  397.         case CMAP:
  398.                 {
  399.           xaULONG tmp;
  400.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CMAP\n");
  401.  
  402.                   if (chunk.size == 0x40) 
  403.           {
  404.             iff_imagec = chunk.size / 2; /* xR+GB */
  405.             IFF_Read_CMAP_1(iff_cmap,iff_imagec,xin);
  406.           }
  407.                   else
  408.           {
  409.             iff_imagec = chunk.size / 3;  /* Rx+Gx+Bx 1 byte each */
  410.             IFF_Read_CMAP_0(iff_cmap,iff_imagec,xin);
  411.           }
  412.  
  413.                   /* Typically iff_imaged matches iff_imagec but not always 
  414.                    * HAM and EHB are frequent examples
  415.            */
  416.                   if (bmhd_flag)
  417.           {
  418.             tmp = 0x01 << iff_imaged;
  419.             if (tmp < iff_imagec) iff_imagec = tmp;
  420.           }
  421.  
  422.                   if (camg_flag & IFF_CAMG_HAM) 
  423.                   {
  424.                     XA_ACTION *act;
  425.                     if (iff_cmap_bits == 8)
  426.             {
  427.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8);
  428.               iff_anim_flags |= ANIM_HAM8;
  429.             }
  430.                     else
  431.             {
  432.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6);
  433.                       iff_anim_flags |= ANIM_HAM6;
  434.             }
  435.                     IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits);
  436.                     iff_cur_hmap = (ColorReg *)act->data;
  437.  
  438.                     if (cmap_true_to_332 == xaTRUE)
  439.                     {
  440.                       iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  441.                       iff_or_mask = 0;
  442.                     }
  443.                     else /* if (cmap_true_to_gray == xaTRUE) */
  444.                     {
  445.                       iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  446.                       iff_or_mask = 0;
  447.                     }
  448.             chdr_flag = xaTRUE;
  449.                   }
  450.           else if (camg_flag & IFF_CAMG_EHB)
  451.           {
  452.                     IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits);
  453.                     iff_chdr =
  454.                       ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  455.                 iff_imagec,iff_or_mask,
  456.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  457.             chdr_flag = xaTRUE;
  458.           }
  459.           else if (camg_flag) /* NOT HAM6,HAM8 or EHB */
  460.           {
  461.             if (iff_cmap_bits == 4) 
  462.             IFF_Shift_CMAP(iff_cmap,iff_imagec);
  463.                     iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  464.                 iff_imagec,iff_or_mask,
  465.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  466.             chdr_flag = xaTRUE;
  467.           }
  468.                   cmap_flag = xaTRUE;
  469.                 }
  470.                 break;
  471.  
  472.     case BODY:
  473.       {
  474.         XA_ACTION *act;
  475.         ACT_DLTA_HDR *dlta_hdr;
  476.  
  477.         DEBUG_LEVEL2 fprintf(stderr,"IFF BODY\n");
  478.         if (chdr_flag == xaFALSE)
  479.         {
  480.           if (cmap_flag==xaTRUE)
  481.           {   
  482.             if (iff_cmap_bits == 4) IFF_Shift_CMAP(iff_cmap,iff_imagec);
  483.             iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  484.                     iff_imagec,iff_or_mask,iff_cmap_bits,
  485.                     iff_cmap_bits,iff_cmap_bits);
  486.             chdr_flag = xaTRUE;
  487.             IFF_Register_CRNGs(anim_hdr,iff_chdr);
  488.             camg_flag = IFF_CAMG_NOP; /* so future CMAPs okay */
  489.           }   
  490.           else IFF_TheEnd1("IFF_Read_BODY: no cmap\n");
  491.         }
  492.  
  493.         act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  494.         ACT_Add_CHDR_To_Action(act,iff_chdr);
  495.         act->h_cmap = iff_cur_hmap;
  496.         IFF_Add_Frame(1,act);
  497.  
  498. /* POD TEMP FINISH THIS eventually. For now body's are read in
  499.         if (xin->load_flag & XA_IN_LOAD_FILE)
  500.         {
  501.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR));
  502.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err");
  503.           act->data = (xaUBYTE *)dlta_hdr;
  504.           dlta_hdr->flags = ACT_DBL_BUF;
  505.           dlta_hdr->fpos  = xin->Seek_FPos(xin);
  506.           dlta_hdr->fsize = chunk.size;
  507.           xin->Seek_FPos(xin,chunk.size,1);
  508.           if (chunk.size > iff_max_fvid_size) iff_max_fvid_size =chunk.size;
  509.         }
  510.         else
  511. */
  512.         {
  513.           dlta_hdr = (ACT_DLTA_HDR *) malloc( sizeof(ACT_DLTA_HDR)
  514.                         + (iff_imagex * iff_imagey) );
  515.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err");
  516.           act->data = (xaUBYTE *)dlta_hdr;
  517.           dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA;
  518.           dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size;
  519.           IFF_Read_BODY(xin,dlta_hdr->data,chunk.size,
  520.                 iff_imagex, iff_imagey, iff_imaged,
  521.                 (int)(bmhd.compression),(int)(bmhd.masking),
  522.                 iff_or_mask);
  523.         }
  524.         dlta_hdr->xapi_rev = 0x0001;
  525.         dlta_hdr->delta = IFF_Delta_Body;
  526.         dlta_hdr->xsize = iff_imagex;    dlta_hdr->ysize = iff_imagey;
  527.         dlta_hdr->xpos = dlta_hdr->ypos = 0;
  528.         dlta_hdr->special = 0;
  529.         dlta_hdr->extra = (void *)(0);
  530.       }
  531.       break;
  532.  
  533.         case ANHD:
  534.         {
  535.           Anim_Header   anhd;
  536.           DEBUG_LEVEL2 fprintf(stderr,"IFF ANHD\n");
  537.           if (chunk.size >= Anim_Header_SIZE)
  538.           {
  539.             IFF_Read_ANHD(xin,&anhd,chunk.size);
  540.             iff_dlta_compression = anhd.op;
  541.             iff_dlta_bits = anhd.bits;
  542. /*
  543.             if (xa_verbose) 
  544.             fprintf(stderr,"ANHD time = %d\n",anhd.reltime); 
  545. */
  546.           }
  547.           else 
  548.           {
  549.             xin->Seek_FPos(xin,chunk.size,1);
  550.             iff_dlta_compression = 0xffffffff;
  551.             iff_dlta_bits = 0x0;
  552.             fprintf(stderr,"ANHD chunksize mismatch %d\n",chunk.size);
  553.           }
  554.         }
  555.         break;
  556.  
  557.         case DLTA:
  558.       {
  559.         ACT_DLTA_HDR *dlta_hdr;
  560.         XA_ACTION *act;
  561.         DEBUG_LEVEL2 fprintf(stderr,"IFF DLTA: ");
  562.         act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  563.         ACT_Add_CHDR_To_Action(act,iff_chdr);
  564.         act->h_cmap = iff_cur_hmap;
  565.           IFF_Add_Frame(1,act);
  566.  
  567.         if (xin->load_flag & XA_IN_LOAD_FILE)
  568.         {
  569.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR));
  570.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err");
  571.           act->data = (xaUBYTE *)dlta_hdr;
  572.           dlta_hdr->flags = ACT_DBL_BUF;
  573.           dlta_hdr->fpos  = xin->Seek_FPos(xin);
  574.           dlta_hdr->fsize = chunk.size;
  575.           xin->Seek_FPos(xin,chunk.size,1);
  576.           if (chunk.size > iff_max_fvid_size) iff_max_fvid_size =chunk.size;
  577.         }
  578.         else
  579.         {
  580.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR)+chunk.size);
  581.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err");
  582.           act->data = (xaUBYTE *)dlta_hdr;
  583.           dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA;
  584.           dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size;
  585.           ret=xin->Read_Block(xin,dlta_hdr->data,chunk.size);
  586.         }
  587.  
  588.         dlta_hdr->xsize = iff_imagex;
  589.         dlta_hdr->ysize = iff_imagey;
  590.         dlta_hdr->xpos = dlta_hdr->ypos = 0;
  591.         dlta_hdr->special = 0;
  592.         dlta_hdr->extra = (void *)(0);
  593.         dlta_hdr->xapi_rev = 0x0001;
  594.         switch(iff_dlta_compression)
  595.         {
  596.           case  3:
  597.         DEBUG_LEVEL2 fprintf(stderr,"type 3\n");
  598.         dlta_hdr->delta = IFF_Delta_3;
  599.         break;
  600.           case 5:
  601.         DEBUG_LEVEL2 fprintf(stderr,"type 5\n");
  602.         dlta_hdr->delta = IFF_Delta_5;
  603.         break;
  604.           case 7:
  605.         dlta_hdr->delta = IFF_Delta_7;
  606.         if (iff_dlta_bits & IFF_ANHD_LDATA)
  607.         { 
  608.           DEBUG_LEVEL2 fprintf(stderr,"type 7L\n");
  609.           dlta_hdr->extra =  (void *)(0);
  610.         } 
  611.         else 
  612.         { 
  613.           DEBUG_LEVEL2 fprintf(stderr,"type 7S\n");
  614.           dlta_hdr->extra =  (void *)(1);
  615.         } 
  616.         break;
  617.           case 8:
  618.         dlta_hdr->delta = IFF_Delta_8;
  619.         if (iff_dlta_bits & IFF_ANHD_LDATA)
  620.         {
  621.           DEBUG_LEVEL2 fprintf(stderr,"type 8L\n");
  622.           dlta_hdr->extra =  (void *)(0);
  623.         }
  624.         else
  625.         {
  626.           DEBUG_LEVEL2 fprintf(stderr,"type 8S\n");
  627.           dlta_hdr->extra =  (void *)(1);
  628.         }
  629.         break;
  630.           case 74:
  631.         DEBUG_LEVEL2 fprintf(stderr,"type J\n");
  632.         dlta_hdr->delta = IFF_Delta_J;
  633.         break;
  634.           case  108:
  635.         dlta_hdr->delta = IFF_Delta_l;
  636.         dlta_hdr->extra =  (void *)(1);
  637.         DEBUG_LEVEL2 fprintf(stderr,"type l\n");
  638.         break;
  639.           default:  
  640.         act->type = ACT_NOP;
  641.         fprintf(stderr,"Unsupported Delta %d\n",iff_dlta_compression);
  642.         break;
  643.         }
  644.       }
  645.     break;
  646.  
  647.     case ANSQ:
  648.       {
  649.         DEBUG_LEVEL2 fprintf(stderr,"IFF ANSQ\n");
  650.         ansq_flag = 1;  /* we found an ansq chunk */
  651.         IFF_Read_ANSQ(xin,chunk.size);
  652.       }
  653.       break;
  654.  
  655.         case CRNG: 
  656.       DEBUG_LEVEL2 fprintf(stderr,"IFF CRNG\n");
  657.       IFF_Read_CRNG(anim_hdr,xin,chunk.size,&crng_flag);
  658.       break;
  659.  
  660.     case TINY : /* ignore */
  661.     case DPI : /* ignore */
  662.     case IMRT: /* ignore */
  663.     case GRAB: /* ignore */
  664.     case DPPS: /* ignore */
  665.     case DPPV: /* ignore */
  666.     case DPAN: /* ignore */
  667.     case DRNG: /* ignore */
  668.     case VHDR: /* sound ignore should kill next body until bmhd*/
  669.     case ANNO: /* sound ignore */
  670.     case CHAN: /* sound ignore */
  671.     case ANFI: /* sound ignore */
  672.         xin->Seek_FPos(xin,chunk.size,1);
  673.                 break;
  674.     default:
  675.     if ( xin->At_EOF(xin,-1) ) exit_flag = 1;   /* end of file */
  676.     else
  677.     {
  678.       fprintf(stderr,"Unknown IFF type="); IFF_Print_ID(stderr,chunk.id);
  679.       if (   (file_read < file_size)    /* there should be more  */
  680.           && (chunk.size < (file_size - file_read) ) /*  size n 2 big */
  681.          )
  682.       {
  683.         fprintf(stderr,"  Will Continue Reading File.\n");
  684.         xin->Seek_FPos(xin,chunk.size,1);
  685.       }
  686.       else
  687.       {
  688.         fprintf(stderr,"  Will Stop Reading File.\n");
  689.         exit_flag = 1;
  690.       }
  691.     }
  692.     break;
  693.    } /* end chunk switch */
  694.    /*
  695.     * keep track of number of bytes read. This allows us to distinguish
  696.     * valid unknown chunks from garbage tacked to the end of a file.
  697.     */
  698.    if (!exit_flag)
  699.    {
  700.      if (file_read == -1) file_read = 4; /* assuming FORM chunk or similar */
  701.      else file_read += chunk.size + 8; /* add ID and SIZE of other chunks */
  702.    }
  703.  
  704.   } /* end if ret==0 */
  705.  } /* end of while not eof or exit_flag */
  706.  DEBUG_LEVEL2 fprintf(stderr,"Bytes Read = %x\n",file_read);
  707.  xin->Close_File(xin);
  708.  
  709.  /* 
  710.   * Set up a map of delta's to their action numbers.
  711.   */
  712.  {
  713.    xaULONG i;
  714.    xaULONG inter_dlta_i,dlta_i,act_i;
  715.  
  716.    iff_dlta_acts = 
  717.     (IFF_DLTA_TABLE *)malloc( (iff_dlta_cnt + 1) * sizeof(IFF_DLTA_TABLE));
  718.    if (iff_dlta_acts == 0) IFF_TheEnd1("IFF_Read_File: dlta_cnts malloc err");
  719.    for(i=0; i < iff_dlta_cnt; i++) 
  720.    {
  721.      iff_dlta_acts[i].cnt   = 0;
  722.      iff_dlta_acts[i].frame = 0;
  723.      iff_dlta_acts[i].start = 0;
  724.      iff_dlta_acts[i].end   = 0;
  725.    }
  726.    dlta_i = 0;
  727.    act_i = 0;
  728.    inter_dlta_i = 0;
  729.  
  730.    iff_act_cur = iff_act_start;
  731.    iff_dlta_acts[dlta_i].start = iff_act_cur;
  732.    iff_dlta_acts[dlta_i].frame = act_i;
  733.    while(iff_act_cur != 0)
  734.    {
  735.      inter_dlta_i++;
  736.      act_i++;
  737.      switch(iff_act_cur->act->type)
  738.      {
  739.        case ACT_DELTA:
  740.         iff_dlta_acts[dlta_i].cnt = inter_dlta_i;
  741.         iff_dlta_acts[dlta_i].end = iff_act_cur;
  742.         inter_dlta_i = 0;
  743.         iff_act_cur = iff_act_cur->next;
  744.         dlta_i++; 
  745.         if (dlta_i > iff_dlta_cnt)
  746.         {
  747.             fprintf(stderr,"IFF_Read: dlta setup err  <%d > %d> \n",
  748.                         dlta_i,iff_dlta_cnt);
  749.             IFF_TheEnd();
  750.         }
  751.         if (dlta_i < iff_dlta_cnt)
  752.         {
  753.           iff_dlta_acts[dlta_i].start = iff_act_cur;
  754.           iff_dlta_acts[dlta_i].frame = act_i;
  755.         }
  756.         break;
  757.        default:
  758.         iff_act_cur = iff_act_cur->next;
  759.         break;
  760.      }
  761.    } /* end of while */
  762.    DEBUG_LEVEL1 fprintf(stderr,"%d dltas found\n",dlta_i);
  763.  
  764.    iff_time = XA_GET_TIME(IFF_SPEED_DEFAULT * IFF_MS_PER_60HZ);
  765.  
  766.    if (ansq_flag)
  767.    {
  768.      xaLONG i,t_time;
  769.      xaULONG iff_frame_cnt,frame_i;
  770.  
  771.      t_time = 0;
  772.      iff_frame_cnt = iff_dlta_acts[0].cnt;  /* start with body cnt */
  773.      for(i=0; i < iff_ansq_cnt; i++) /* count frames */
  774.      {
  775.        if (iff_ansq[i].time != 0xffff) /* if not loop frame */
  776.       iff_frame_cnt += iff_dlta_acts[ iff_ansq[i].dnum + 1 ].cnt;
  777.      }
  778.      anim_hdr->frame_lst = 
  779.     (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_frame_cnt + 1));
  780.      if (anim_hdr->frame_lst == NULL) 
  781.     IFF_TheEnd1("IFF ANSQ: frame_lst malloc err");
  782.   
  783.        /* For movies default loop frame is 0 */
  784.      anim_hdr->loop_frame = 0;
  785.  
  786.      /* take care of frame up to BODY */
  787.      frame_i = 0;
  788.      iff_act_cur = iff_dlta_acts[0].start;
  789.      while(iff_act_cur != 0)
  790.      {
  791.        anim_hdr->frame_lst[frame_i].act = iff_act_cur->act;
  792.        if (iff_act_cur == iff_dlta_acts[0].end)
  793.        {
  794.      anim_hdr->frame_lst[frame_i].time_dur = iff_time;
  795.      anim_hdr->frame_lst[frame_i].zztime = t_time;
  796.      t_time += iff_time;
  797.      frame_i++;
  798.      break;
  799.        }
  800.        else 
  801.        {
  802.      anim_hdr->frame_lst[frame_i].time_dur = 0;
  803.      anim_hdr->frame_lst[frame_i].zztime = t_time;
  804.        }
  805.        frame_i++;  
  806.        iff_act_cur = iff_act_cur->next;
  807.        if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) )
  808.        {
  809.          fprintf(stderr,"IFF_ansq: frame err %d %d\n",frame_i,iff_frame_cnt);
  810.          IFF_TheEnd();
  811.        }
  812.      }
  813.      for(i=0; i < iff_ansq_cnt; i++)
  814.      {
  815.         if (iff_ansq[i].time == 0xffff) /* loop frame */
  816.         {
  817.           anim_hdr->loop_frame = iff_ansq[ iff_ansq[i].dnum ].frame;
  818.         }
  819.         else
  820.         {
  821.       xaULONG dlta_j;
  822.       iff_ansq[i].frame = frame_i; /* for looping info */
  823.           dlta_j = iff_ansq[i].dnum + 1;
  824.           iff_time = XA_GET_TIME(iff_ansq[i].time * IFF_MS_PER_60HZ);
  825.       iff_act_cur = iff_dlta_acts[dlta_j].start;
  826.       while(iff_act_cur != 0)
  827.       {
  828.         anim_hdr->frame_lst[frame_i].act = iff_act_cur->act;
  829.             if (iff_act_cur == iff_dlta_acts[dlta_j].end) 
  830.         {
  831.           anim_hdr->frame_lst[frame_i].time_dur = iff_time;
  832.           anim_hdr->frame_lst[frame_i].zztime = t_time;
  833.           t_time += iff_time;
  834.           frame_i++;  
  835.           break;
  836.         }
  837.         else 
  838.         {
  839.           anim_hdr->frame_lst[frame_i].time_dur = 0;
  840.           anim_hdr->frame_lst[frame_i].zztime = t_time;
  841.         }
  842.         frame_i++;  
  843.             iff_act_cur = iff_act_cur->next;
  844.         if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) )
  845.         {
  846.           fprintf(stderr,"IFF_ansq: frame err %d %d\n",
  847.                         frame_i,iff_frame_cnt);
  848.           IFF_TheEnd();
  849.         }
  850.       }
  851.         }
  852.       } /* end of for */
  853.       anim_hdr->frame_lst[frame_i].time_dur = 0;
  854.       anim_hdr->frame_lst[frame_i].zztime = -1;
  855.       anim_hdr->frame_lst[frame_i].act  = 0;
  856.       anim_hdr->last_frame = frame_i - 1;
  857.       anim_hdr->total_time = anim_hdr->frame_lst[frame_i-1].zztime 
  858.                                 + anim_hdr->frame_lst[frame_i-1].time_dur;
  859.     }
  860.     else   /* no ansq chunk */
  861.     {
  862.       xaLONG frame_i,t_time;
  863.  
  864.       t_time = 0;
  865.       /* extra for end and JMP2END */
  866.       anim_hdr->frame_lst = 
  867.       (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_act_cnt + 2));
  868.       if (anim_hdr->frame_lst == NULL)
  869.         IFF_TheEnd1("IFF_Read: frame malloc err");
  870.       iff_act_cur = iff_act_start;
  871.       frame_i = 0;
  872.       while(iff_act_cur != 0)
  873.       {
  874.         anim_hdr->frame_lst[frame_i].act  = iff_act_cur->act;
  875.     if (iff_act_cur->type == 1)
  876.     {
  877.       if ( (iff_dlta_cnt == 1) && (crng_flag) && (xa_jiffy_flag == 0) )
  878. /* && (iff_act_cur->act->type == ACT_IFF_BODY) ) */
  879.       {
  880.             anim_hdr->frame_lst[frame_i].time_dur = DEFAULT_CYCLING_TIME;
  881.             anim_hdr->frame_lst[frame_i].zztime = t_time;
  882.         t_time += DEFAULT_CYCLING_TIME;
  883.       }
  884.           else
  885.       {
  886.         anim_hdr->frame_lst[frame_i].time_dur = iff_time;
  887.         anim_hdr->frame_lst[frame_i].zztime   = t_time;
  888.         t_time += iff_time;
  889.       }
  890.     }
  891.     else
  892.     {
  893.       anim_hdr->frame_lst[frame_i].time_dur = 0;
  894.       anim_hdr->frame_lst[frame_i].zztime = t_time;
  895.     }
  896.         iff_act_cur = iff_act_cur->next;
  897.         frame_i++;
  898.         if (frame_i > iff_act_cnt)
  899.         {
  900.           fprintf(stderr,"IFF_Read: frame inconsistency %d %d\n",
  901.                 frame_i,iff_act_cnt);
  902.           IFF_TheEnd();
  903.         }
  904.       }
  905.       /* Add JMP2END so deltas to beginning aren't displayed unless looping */
  906.       if ( !(iff_anim_flags & ANIM_NOLOOP) && (iff_dlta_cnt > 3) && !face_flag)
  907.       { xaULONG kk = frame_i;
  908.     anim_hdr->frame_lst[kk].time_dur = 
  909.             anim_hdr->frame_lst[iff_dlta_acts[1].frame].time_dur;
  910.     anim_hdr->frame_lst[kk].zztime = 
  911.             anim_hdr->frame_lst[iff_dlta_acts[1].frame].zztime;
  912.     anim_hdr->frame_lst[kk].act  = anim_hdr->frame_lst[kk-1].act;
  913.     anim_hdr->frame_lst[kk-1].time_dur = 
  914.             anim_hdr->frame_lst[iff_dlta_acts[0].frame].time_dur;
  915.     anim_hdr->frame_lst[kk-1].zztime = 
  916.             anim_hdr->frame_lst[iff_dlta_acts[0].frame].zztime;
  917.     anim_hdr->frame_lst[kk-1].act  = anim_hdr->frame_lst[kk-2].act;
  918.         anim_hdr->frame_lst[kk-2].time_dur = 0;
  919.         anim_hdr->frame_lst[kk-2].zztime = -1;
  920.     anim_hdr->frame_lst[kk-2].act = ACT_Get_Action(anim_hdr,ACT_JMP2END);
  921.     /* PODNOTE: IFF last two frames need to have zztime start at 0 again*/
  922.         frame_i++;
  923.         anim_hdr->loop_frame = iff_dlta_acts[2].frame;
  924.         anim_hdr->total_time = anim_hdr->frame_lst[frame_i-4].zztime 
  925.                                 + anim_hdr->frame_lst[frame_i-4].time_dur;
  926.       }
  927.       else
  928.       {
  929.     anim_hdr->loop_frame = 0; 
  930.         anim_hdr->total_time = anim_hdr->frame_lst[frame_i-1].zztime 
  931.                                 + anim_hdr->frame_lst[frame_i-1].time_dur;
  932.       }
  933.       if (frame_i > 0 ) anim_hdr->last_frame = frame_i - 1;
  934.       else anim_hdr->last_frame = 0;
  935.       anim_hdr->frame_lst[frame_i].time_dur = 0;
  936.       anim_hdr->frame_lst[frame_i].zztime = -1;
  937.       anim_hdr->frame_lst[frame_i].act  = 0;
  938.       frame_i++;
  939.       if (xa_verbose) 
  940.       {
  941.     fprintf(stderr,"     dlta_cnt=%d comp=%d ",
  942.                 iff_dlta_cnt,iff_dlta_compression);
  943.     if (camg_flag & IFF_CAMG_EHB) fprintf(stderr," EHB\n");
  944.     else if (iff_anim_flags & ANIM_HAM8) fprintf(stderr," HAM8\n");
  945.     else if (iff_anim_flags & ANIM_HAM6) fprintf(stderr," HAM6\n");
  946.     else fprintf(stderr,"\n");
  947.       }
  948.     }
  949.   }
  950.   anim_hdr->imagex = iff_max_imagex;
  951.   anim_hdr->imagey = iff_max_imagey;
  952.   anim_hdr->imagec = iff_imagec;
  953.   anim_hdr->imaged = iff_max_imaged;
  954.  
  955.   /* Some older IFF files don't include a CAMG chunk to indicate they
  956.    * are interlaced. They just assume the viewer will figure it out.
  957.    * Below is an arbitrary ruleset that'll hopefully work for most cases.
  958.    */
  959.    if ((iff_max_imagex >= 400) && (iff_max_imagey > iff_max_imagex))
  960.     iff_anim_flags |= ANIM_LACE;
  961.  
  962.   /* NOTE: A lot of IFF animations have active color cycle chunks, yet
  963.    *       they were never intended to cycle. AAARRRRGH!!!
  964.    */
  965.   if (iff_dlta_cnt == 1)  /* single image IFF files */
  966.   {
  967.     if ( (crng_flag) && (iff_allow_cycling == xaTRUE) )
  968.                     iff_anim_flags |= ANIM_CYCLE;
  969.     else iff_anim_flags &= ~ANIM_CYCLE;
  970.   }
  971.   else /* animation IFF files */
  972.   {
  973.     if ( (crng_flag) && (iff_allow_cycling == xaTRUE) 
  974.         && (xa_anim_cycling == xaTRUE) )   iff_anim_flags |= ANIM_CYCLE;
  975.     else iff_anim_flags &= ~ANIM_CYCLE;
  976.   }
  977.   anim_hdr->anim_flags = iff_anim_flags;
  978.   IFF_Free_Stuff();
  979.   iff_chdr = 0;
  980.   if (xin->load_flag & XA_IN_LOAD_BUF) IFF_Buffer_Action(anim_hdr);
  981.   else
  982.   {
  983.     anim_hdr->anim_flags |= ANIM_SNG_BUF;
  984.     if (iff_dlta_cnt > 1) anim_hdr->anim_flags |= ANIM_DBL_BUF;
  985.     if (iff_anim_flags | ANIM_HAM) anim_hdr->anim_flags |= ANIM_3RD_BUF;
  986.   }
  987.   if (xin->load_flag & XA_IN_LOAD_FILE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  988.   anim_hdr->fname = anim_hdr->name;
  989.   anim_hdr->max_fvid_size = iff_max_fvid_size;
  990.   return(xaTRUE);
  991. }
  992.  
  993. /*
  994.  *
  995.  */
  996. void IFF_Adjust_For_EHB(colormap,cmap_bits)
  997. ColorReg colormap[];
  998. xaULONG cmap_bits;
  999. {
  1000.   xaLONG i,cmap_num;
  1001.  
  1002.   DEBUG_LEVEL1 
  1003.     fprintf(stderr,"Adjusting CMAP for Amiga Extra Half-Brite Mode\n");
  1004.   if (cmap_bits == 8) cmap_num = 128;
  1005.   else 
  1006.   { /* 4 bits per rgb, shift down from 8 bits to 4 bits */
  1007.     cmap_num = 32;
  1008.     IFF_Shift_CMAP(colormap,cmap_num);
  1009.   }
  1010.  
  1011.    /* make upper half a darkened version of the lower half */
  1012.   for(i=0;i<cmap_num;i++)
  1013.   {
  1014.     colormap[i + cmap_num].red   = colormap[i].red   >> 2;
  1015.     colormap[i + cmap_num].green = colormap[i].green >> 2;
  1016.     colormap[i + cmap_num].blue  = colormap[i].blue  >> 2;
  1017.   }
  1018.   iff_imagec = 2 * cmap_num;
  1019.   iff_or_mask = CMAP_Get_Or_Mask(iff_imagec);
  1020. }
  1021.  
  1022.  
  1023. /*
  1024.  *
  1025.  */
  1026. void IFF_Read_BODY(xin,image_out,bodysize,xsize,ysize,depth,
  1027.             compression,masking,or_mask)
  1028. XA_INPUT *xin;
  1029. xaUBYTE *image_out;
  1030. xaULONG xsize,ysize,depth;
  1031. xaLONG bodysize,compression,masking;
  1032. xaULONG or_mask;
  1033. {
  1034.  xaLONG i,ret,x,y,d,dmask,tmp,rowsize;
  1035.  xaLONG imagex_pad;
  1036.  xaBYTE *inbuff,*rowbuff,*sptr;
  1037.  xaBYTE *sbuff,*dbuff;
  1038.  
  1039.  if (   (compression != BMHD_COMP_NONE) 
  1040.      && (compression != BMHD_COMP_BYTERUN) 
  1041.     ) IFF_TheEnd1("IFF_Read_Body: unsupported compression");
  1042.  
  1043.  if (   (masking != BMHD_MSK_NONE)
  1044.      && (masking != BMHD_MSK_HAS)
  1045.      && (masking != BMHD_MSK_TRANS)
  1046.     ) IFF_TheEnd1("IFF_Read_Body: unsupported masking");
  1047.  
  1048.  inbuff = (xaBYTE *)malloc(bodysize);
  1049.  if (inbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed");
  1050.  ret=xin->Read_Block(xin,inbuff,bodysize);
  1051.  if (ret<bodysize) IFF_TheEnd1("IFF_Read_Body: read of BODY chunk failed");
  1052.  sbuff = inbuff;
  1053.  
  1054.  
  1055.  /* width is rounded to multiples of 16 in the BODY form */
  1056.  /* extra bits are ignored upon reading */
  1057.  imagex_pad = xsize / 16;
  1058.  if (xsize % 16) imagex_pad++;
  1059.  imagex_pad *= 16;
  1060.  
  1061.  rowbuff = (xaBYTE *)malloc( imagex_pad );
  1062.  if (rowbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed");
  1063.  
  1064.  memset(image_out,or_mask,(xsize * ysize) );
  1065.  
  1066.  if (compression==BMHD_COMP_NONE) sptr = inbuff;
  1067.  
  1068.  for(y=0; y<ysize; y++)
  1069.  {
  1070.    tmp = y * xsize;
  1071.    dmask=1;
  1072.    for(d=0; d<depth; d++)
  1073.    {
  1074.  
  1075.      if (compression == BMHD_COMP_BYTERUN)
  1076.      {
  1077.        rowsize = imagex_pad / 8; 
  1078.        dbuff = rowbuff;
  1079.        ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  1080.        if (ret) { fprintf(stderr,"error %d in unpack\n",ret); IFF_TheEnd();}
  1081.        sptr = rowbuff;
  1082.      }
  1083.  
  1084.      i = 0;
  1085.      for(x=0; x<xsize; x++)
  1086.      {
  1087.        if (mask[i] & (*sptr)) image_out[tmp+x] |= dmask;
  1088.        i++;
  1089.        if (i >= 8)
  1090.        {
  1091.      i = 0;
  1092.      sptr++;
  1093.        }
  1094.      }
  1095.      if (imagex_pad >= (xsize+8)) sptr++;
  1096.  
  1097.      dmask <<= 1;
  1098.    } /* end of depth loop */
  1099.  
  1100.    if (masking == BMHD_MSK_HAS)
  1101.    {
  1102.      /* read the mask row and then throw out for now */
  1103.      if (compression == BMHD_COMP_BYTERUN)
  1104.      {
  1105.        rowsize = imagex_pad / 8;
  1106.        dbuff = rowbuff;
  1107.        ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  1108.        if (ret) { fprintf(stderr,"error %d in unpack\n",ret); IFF_TheEnd();}
  1109.      }
  1110.      else sptr += xsize/8;
  1111.    }
  1112.  } /* end of y loop */
  1113.  FREE(inbuff,0x1004);  inbuff=0;
  1114.  FREE(rowbuff,0x1005); rowbuff=0;
  1115. }
  1116.  
  1117.  
  1118.  
  1119. /*
  1120.  *
  1121.  */
  1122. void IFF_Print_ID(fout,id)
  1123. FILE *fout;
  1124. xaLONG id;
  1125. {
  1126.  fprintf(fout,"%c",     (char)((id >> 24) & 0xff)   );
  1127.  fprintf(fout,"%c",     (char)((id >> 16) & 0xff)   );
  1128.  fprintf(fout,"%c",     (char)((id >>  8) & 0xff)   );
  1129.  fprintf(fout,"%c(%x)",(char)(id        & 0xff),id);
  1130. }
  1131.  
  1132.  
  1133. /* 
  1134.  *
  1135.  */
  1136. xaULONG
  1137. IFF_Delta_5(image,delta,dsize,dec_info)
  1138. xaUBYTE *image;         /* Image Buffer. */
  1139. xaUBYTE *delta;         /* delta data. */
  1140. xaULONG dsize;          /* delta size */
  1141. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1142. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1143.   xaULONG imaged = dec_info->imaged;
  1144.   register xaLONG col,depth,dmask;
  1145.   register xaLONG rowsize,width;
  1146.   xaULONG poff;
  1147.   register xaUBYTE *i_ptr;
  1148.   register xaUBYTE *dptr,opcnt,op,cnt;
  1149.   xaLONG miny,minx,maxy,maxx;
  1150.  
  1151.   /* set to opposites for min/max testing */
  1152.   dec_info->xe = dec_info->ye = 0; dec_info->ys = imagey; dec_info->xs = imagex;
  1153.  
  1154.   width = imagex;
  1155.   rowsize = width >> 3;
  1156.   dmask = 1;
  1157.  for(depth=0; depth<imaged; depth++)
  1158.  {
  1159.   minx = -1;
  1160.   maxx = -1;
  1161.   
  1162.   i_ptr = image;
  1163.   /* offset into delt chunk */
  1164.   { register xaUSHORT ddepth = depth << 2;
  1165.     poff  = (xaULONG)(delta[ ddepth++ ]) << 24;
  1166.     poff |= (xaULONG)(delta[ ddepth++ ]) << 16;
  1167.     poff |= (xaULONG)(delta[ ddepth++ ]) <<  8;
  1168.     poff |= (xaULONG)(delta[ ddepth   ]);
  1169.   }
  1170.  
  1171.   if (poff)
  1172.   {
  1173.    dptr = (xaUBYTE *)(delta + poff);
  1174.    for(col=0;col<rowsize;col++)
  1175.    {
  1176.     /* start at top of column */
  1177.     i_ptr = (xaUBYTE *)(image + (col << 3));
  1178.     opcnt = *dptr++;  /* get number of ops for this column */
  1179.     
  1180.     miny = -1;
  1181.     maxy = -1;
  1182.  
  1183.     while(opcnt)    /* execute ops */
  1184.     {
  1185.        /* keep track of min and max columns */
  1186.        if (minx == -1) minx = col << 3;
  1187.        maxx = (col << 3) + 7;  
  1188.  
  1189.        op = *dptr++;   /* get op */
  1190.      
  1191.        if (op & 0x80)    /* if type uniqe */
  1192.        {
  1193.           if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  1194.           cnt = op & 0x7f;         /* get cnt */
  1195.       
  1196.           while(cnt--) /* loop through data */
  1197.           {
  1198.              register xaUBYTE data = *dptr++;
  1199.              IFF_Byte_Mod(i_ptr,data,dmask,0);
  1200.              i_ptr += width;
  1201.           }
  1202.         } /* end unique */
  1203.         else
  1204.         {
  1205.            if (op == 0)   /* type same */
  1206.            {
  1207.               register xaUBYTE data;
  1208.               if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  1209.               cnt = *dptr++;
  1210.               data = *dptr++;
  1211.  
  1212.               while(cnt--) /* loop through data */
  1213.               { 
  1214.                  IFF_Byte_Mod(i_ptr,data,dmask,0);
  1215.                  i_ptr += width;
  1216.               }
  1217.             } /* end same */
  1218.             else
  1219.             {
  1220.                i_ptr += (width * op);  /* type skip */
  1221.             }
  1222.          } /* end of hi bit clear */
  1223.        opcnt--;
  1224.      } /* end of while opcnt */
  1225.      maxy = (xaULONG)( i_ptr - image ) / width;
  1226.      if ( (miny>=0) && (miny < dec_info->ys)) dec_info->ys = miny;
  1227.      if ( (maxy>=0) && (maxy > dec_info->ye)) dec_info->ye = maxy;
  1228.     } /* end of column loop */
  1229.    } /* end of valid pointer for this plane */
  1230.    dmask <<= 1;
  1231.    if ( (minx>=0) && (minx < dec_info->xs)) dec_info->xs = minx;
  1232.    if ( (maxx>=0) && (maxx > dec_info->xe)) dec_info->xe = maxx;
  1233.   } /* end of for depth */
  1234.  
  1235.   if (xa_optimize_flag == xaTRUE)
  1236.   {
  1237.     if (dec_info->xs >= imagex) dec_info->xs = 0;
  1238.     if (dec_info->ys >= imagey) dec_info->ys = 0;
  1239.     if (dec_info->xe <= 0)      dec_info->xe = imagex;
  1240.     if (dec_info->ye <= 0)      dec_info->ye = imagey;
  1241.   }
  1242.   else
  1243.   {
  1244.     dec_info->xs = 0;      dec_info->ys = 0;
  1245.     dec_info->xe = imagex; dec_info->ye = imagey;
  1246.   }
  1247.   return(ACT_DLTA_NORM); 
  1248. } /* end of routine */
  1249.  
  1250. /*
  1251.  * 
  1252.  */
  1253. xaULONG
  1254. IFF_Delta_3(image,delta,dsize,dec_info)
  1255. xaUBYTE *image;         /* Image Buffer. */
  1256. xaUBYTE *delta;         /* delta data. */
  1257. xaULONG dsize;          /* delta size */
  1258. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1259. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1260.   xaULONG imaged = dec_info->imaged;
  1261.  register xaLONG i,depth,dmask;
  1262.  xaULONG poff;
  1263.  register xaSHORT  offset;
  1264.  register xaUSHORT s,data;
  1265.  register xaUBYTE  *i_ptr,*dptr;
  1266.  
  1267.  dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
  1268.  dmask = 1;
  1269.  for(depth=0;depth<imaged;depth++)
  1270.  {
  1271.   i_ptr = image;
  1272.  
  1273.   /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1274.  
  1275.   poff  = (xaULONG)(delta[ 4 * depth    ]) << 24;
  1276.   poff |= (xaULONG)(delta[ 4 * depth + 1]) << 16;
  1277.   poff |= (xaULONG)(delta[ 4 * depth + 2]) <<  8;
  1278.   poff |= (xaULONG)(delta[ 4 * depth + 3]);
  1279.  
  1280.   if (poff)
  1281.   {
  1282.    dptr = (xaUBYTE *)(delta + poff);
  1283.    while( (dptr[0] != 0xff) || (dptr[1] != 0xff) )
  1284.    {
  1285.      offset = (*dptr++)<<8; offset |= (*dptr++);
  1286.      if (offset >= 0)
  1287.      {
  1288.       data = (*dptr++)<<8; data |= (*dptr++);
  1289.       i_ptr += 16 * (xaULONG)(offset);
  1290.       IFF_Short_Mod(i_ptr,data,dmask,0);
  1291.      } /* end of pos */
  1292.      else
  1293.      {
  1294.       i_ptr += 16 * (xaULONG)(-(offset+2));
  1295.       s = (*dptr++)<<8; s |= (*dptr++); /* size of next */
  1296.       for(i=0; i < (xaULONG)s; i++)
  1297.       {
  1298.        data = (*dptr++)<<8; data |= (*dptr++);
  1299.        i_ptr += 16;
  1300.        IFF_Short_Mod(i_ptr,data,dmask,0);
  1301.       }
  1302.     }  /* end of neg */
  1303.    } /* end of delta for this plane */
  1304.   } /* plane has changed data */
  1305.   dmask <<= 1;
  1306.  } /* end of d */
  1307.  return(ACT_DLTA_NORM); 
  1308. }
  1309.  
  1310.  
  1311. void IFF_Hash_Init(num)
  1312. xaULONG num;
  1313. { register xaULONG i;
  1314.   iff_hash_cur=0;
  1315.   iff_hash_tbl = (IFF_HASH *)malloc(num * sizeof(IFF_HASH));
  1316.   if (iff_hash_tbl == 0) TheEnd1("IFF_Hash_Init: malloc err");
  1317.   for(i=0;i<num;i++) iff_hash_tbl[i].flag = ACT_DLTA_BAD;
  1318. }
  1319.  
  1320. void IFF_Hash_CleanUp()
  1321. {
  1322.   if (iff_hash_tbl)
  1323.   { register xaULONG i=0;
  1324.     while(i<iff_hash_cur)
  1325.     {
  1326.       register XA_ACTION *tact = iff_hash_tbl[i].dlta;
  1327.       if (tact)
  1328.       {
  1329.     if (tact->type == ACT_DELTA) ACT_Free_Act(tact);
  1330.       }
  1331.       i++;
  1332.     }
  1333.     FREE(iff_hash_tbl,0x100E); iff_hash_tbl=0;
  1334.   }
  1335. }
  1336.  
  1337. void IFF_Hash_Add(dlta,nxtdlta,src,dst,flag)
  1338. XA_ACTION *dlta,*nxtdlta,*src,**dst;
  1339. xaULONG flag;
  1340.   register IFF_HASH *hptr = &iff_hash_tbl[iff_hash_cur];
  1341.   hptr->flag = flag;    
  1342.   hptr->dlta = dlta;    hptr->nxtdlta = nxtdlta;
  1343.   hptr->src = src;    hptr->dst = *dst;
  1344.   iff_hash_cur++;
  1345. }
  1346.  
  1347. xaULONG pod_temp_i;
  1348. XA_ACTION *IFF_Hash_Get(dlta,src,nxtdlta)
  1349. XA_ACTION *dlta,*src,*nxtdlta;
  1350. { register xaULONG i = 0;
  1351.   while(1)
  1352.   { IFF_HASH *hptr = &iff_hash_tbl[i];
  1353. pod_temp_i = i;
  1354.     if (hptr->flag & ACT_DLTA_BAD) return(0); /* end and nothing found */
  1355.     else if (hptr->dlta == dlta)
  1356.     {
  1357.       if (hptr->flag & ACT_DLTA_NOP)            return(src);
  1358.       else if (    (src == hptr->src)
  1359.         || (hptr->flag & ACT_DLTA_BODY) )    return(hptr->dst);
  1360.       else if (    (src == hptr->dst)
  1361.         && (hptr->flag & ACT_DLTA_XOR) )    return(hptr->src);
  1362.       else if (hptr->nxtdlta == nxtdlta)        return(hptr->dst);
  1363.     }
  1364.     i++;
  1365.   }
  1366. }
  1367.  
  1368.  
  1369. /* 
  1370.  *
  1371.  */
  1372. void IFF_Buffer_Action(anim_hdr)
  1373. XA_ANIM_HDR *anim_hdr;
  1374. {
  1375.   xaLONG image_size;
  1376.   xaUBYTE *buff0,*buff1,*tmp,*dbl_buff;
  1377.   XA_ACTION *act,*old_act0,*old_act1;
  1378.   XA_FRAME *frame_lst;
  1379.   xaULONG frame_i,frame_num;
  1380.   xaULONG scale_x,scale_y,need_to_scale;
  1381.  
  1382.   iff_chdr = 0;
  1383.   image_size = iff_imagex * iff_imagey;
  1384.   dbl_buff = buff1 = buff0 = (xaUBYTE *) malloc( 2 * image_size );
  1385.   if (buff0 == 0) TheEnd1("IFF Buffer Action: malloc failed 0");
  1386.   buff1 += image_size;
  1387.   frame_num = anim_hdr->last_frame + 1;
  1388.  
  1389.   IFF_Hash_Init(frame_num);
  1390.   need_to_scale = 
  1391.     UTIL_Get_Buffer_Scale(iff_imagex,iff_imagey,&scale_x,&scale_y);
  1392.  
  1393.   frame_i = 0;  old_act0 = old_act1 = 0;
  1394.   frame_lst = anim_hdr->frame_lst; 
  1395.   while(frame_lst[frame_i].act != 0)
  1396.   {
  1397.     XA_ACTION *dst_act,*new_act,*nxt_act;
  1398.  
  1399.  
  1400.     act = frame_lst[frame_i].act;
  1401.     nxt_act = frame_lst[frame_i + 1].act;
  1402.  
  1403.       switch(act->type)
  1404.       {
  1405.     case ACT_DELTA:
  1406.         { XA_DEC_INFO dec_info;
  1407.       ACT_DLTA_HDR *dlta_hdr = (ACT_DLTA_HDR *)act->data;
  1408.           xaLONG minx,miny,maxx,maxy; 
  1409.           xaLONG pic_x,pic_y;
  1410.           xaUBYTE *t_pic;
  1411.       xaULONG dlta_flag = 1;
  1412.       dec_info.imagex    = iff_imagex;
  1413.       dec_info.imagey    = iff_imagey;
  1414.       dec_info.imaged    = iff_imaged;
  1415.       dec_info.chdr      = 0;
  1416.       dec_info.map_flag  = xaFALSE;
  1417.       dec_info.map       = 0;
  1418.       dec_info.special   = dlta_hdr->special;
  1419.       dec_info.extra     = dlta_hdr->extra;
  1420.       dec_info.skip_flag = 0;
  1421.  
  1422.       dlta_flag = dlta_hdr->delta(buff0, dlta_hdr->data, 
  1423.                         dlta_hdr->fsize, &dec_info);
  1424.       minx = dec_info.xs;    miny = dec_info.ys;
  1425.       maxx = dec_info.xe;    maxy = dec_info.ye;
  1426.  
  1427.           if (dlta_flag & ACT_DLTA_BODY)
  1428.       {
  1429.         memcpy((char *)buff1, (char *)buff0, image_size);
  1430.         maxx = dlta_hdr->xsize; maxy = dlta_hdr->ysize;
  1431.             IFF_Init_DLTA_HDR(maxx,maxy);
  1432.       }
  1433.  
  1434.  
  1435.           IFF_Update_DLTA_HDR(&minx,&miny,&maxx,&maxy);
  1436.       dst_act = IFF_Hash_Get(act,old_act0,nxt_act); 
  1437.     /* IF unbuffered action has been previously setup and IF it's
  1438.      * smaller than old one, use the old one. IF it's larger than
  1439.      * the old one, then free up the old one and replace with this one.
  1440.      * Same goes for deltas that don't change an images(the NOPs).
  1441.      */
  1442.       if ( (dst_act) || (dlta_flag & ACT_DLTA_NOP) )
  1443.       {
  1444.         XA_ACTION *tst_act;
  1445.         if (!dst_act) /* if here because no change */
  1446.         {
  1447.           if (old_act0 == 0) TheEnd1("IFF Buff: No Body err");
  1448.           IFF_Hash_Add(act,nxt_act,old_act0,&old_act0,dlta_flag);
  1449.           tst_act = old_act0;
  1450.         } else tst_act = dst_act;
  1451.  
  1452.             if ( (tst_act->type==ACT_MAPPED) || (tst_act->type==ACT_DISP) )
  1453.         { 
  1454.           ACT_MAPPED_HDR *maphdr = (ACT_MAPPED_HDR *)tst_act->data;
  1455.           xaULONG px,py,sx,sy;
  1456.           xaULONG opx,opy,osx,osy;
  1457.           px = minx;  sx = maxx - minx; py = miny;  sy = maxy - miny;
  1458.           if (need_to_scale) UTIL_Scale_Pos_Size(&px,&py,&sx,&sy,
  1459.                     iff_imagex,iff_imagey,scale_x,scale_y);
  1460.           sx += px;    opx = maphdr->xpos;    osx = maphdr->xsize + opx;
  1461.           sy += py;    opy = maphdr->ypos;    osy = maphdr->ysize + opy;
  1462.           if (   ((px >= opx) && (px <= osx))  /* new is <= old */
  1463.               && ((sx >= opx) && (sx <= osx))
  1464.               && ((py >= opy) && (py <= osy))
  1465.               && ((sy >= opy) && (sy <= osy)) )
  1466.           {
  1467.         frame_lst[frame_i].act = tst_act;
  1468.         old_act0 = old_act1; old_act1 = tst_act;
  1469.         tmp = buff0; buff0 = buff1; buff1 = tmp;
  1470.         break;
  1471.           }
  1472.         } /* NOTE: this might should be an error */
  1473.         ACT_Free_Act(tst_act);
  1474.         new_act = tst_act;   /* free_act should wipe chdr info */ 
  1475.       }
  1476.       else 
  1477.       {
  1478.           /* get new action for unbuffered frame */
  1479.         new_act = ACT_Get_Action(anim_hdr,0);
  1480.         ACT_Add_CHDR_To_Action(new_act,act->chdr);
  1481.       }
  1482.  
  1483.           pic_x = maxx - minx; pic_y = maxy - miny;
  1484.       /* now get into shape */
  1485.           if (iff_anim_flags & ANIM_HAM)
  1486.       { 
  1487.         xaULONG disp_flag;
  1488.  
  1489.         if (x11_display_type == XA_MONOCHROME)
  1490.         {minx=miny=0; pic_x=iff_imagex; pic_y=iff_imagey; }
  1491.  
  1492.             t_pic = (xaUBYTE *) malloc( XA_PIC_SIZE(pic_x * pic_y) );
  1493.         if (x11_display_type & XA_X11_TRUE) disp_flag = xaTRUE;
  1494.         else disp_flag = xaFALSE;
  1495.         if (iff_anim_flags & ANIM_HAM6)
  1496.         {
  1497.           if (cmap_true_map_flag == xaTRUE)
  1498.           {
  1499.             XA_CHDR *tmp_chdr = 0;
  1500.         ACT_Del_CHDR_From_Action(new_act,new_act->chdr);
  1501.         IFF_HAM6_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap,
  1502.             pic_x,pic_y,minx,miny,iff_imagex);
  1503.         ACT_Add_CHDR_To_Action(new_act,tmp_chdr);
  1504.            }
  1505.           else
  1506.          IFF_Buffer_HAM6(t_pic,buff0,new_act->chdr,act->h_cmap,
  1507.             pic_x,pic_y,minx,miny,iff_imagex,xaFALSE);
  1508.         }
  1509.         else
  1510.         {
  1511.           if (cmap_true_map_flag == xaTRUE)
  1512.           {
  1513.             XA_CHDR *tmp_chdr = 0;
  1514.         ACT_Del_CHDR_From_Action(new_act,new_act->chdr);
  1515.         IFF_HAM8_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap,
  1516.             pic_x,pic_y,minx,miny,iff_imagex);
  1517.         ACT_Add_CHDR_To_Action(new_act,tmp_chdr);
  1518.            }
  1519.           else
  1520.         IFF_Buffer_HAM8(t_pic,buff0,new_act->chdr,act->h_cmap,
  1521.             pic_x,pic_y,minx,miny,iff_imagex,xaFALSE);
  1522.         }
  1523.         ACT_Setup_Mapped(new_act, t_pic, new_act->chdr, 
  1524.         minx, miny, pic_x, pic_y, iff_imagex, iff_imagey,
  1525.         xaFALSE, 0, xaTRUE, xaFALSE, disp_flag);
  1526.       }
  1527.       else ACT_Setup_Mapped(new_act, buff0, new_act->chdr, 
  1528.         minx, miny, pic_x, pic_y, iff_imagex, iff_imagey,
  1529.         xaFALSE,0, xaFALSE, xaTRUE, xaFALSE);
  1530.           if (dlta_flag & ACT_DLTA_BODY) old_act0 = old_act1 = new_act;
  1531.       IFF_Hash_Add(act,nxt_act,old_act0,&new_act,dlta_flag);
  1532.       old_act0 = old_act1; old_act1 = new_act; 
  1533.       frame_lst[frame_i].act = new_act;
  1534.           tmp = buff0; buff0 = buff1; buff1 = tmp;
  1535.         } /* end of delta7,5,j */
  1536.         break;
  1537.       } /* end of switch */
  1538.     frame_i++; /* move to next action in list */
  1539.   } /* end of while */
  1540.   if (dbl_buff) { FREE(dbl_buff,0x100A); dbl_buff = buff0 = buff1 = 0;}
  1541.   IFF_Hash_CleanUp();
  1542.   iff_chdr = 0;
  1543. }
  1544.  
  1545. xaULONG
  1546. IFF_Delta_J(image,delta,dsize,dec_info)
  1547. xaUBYTE *image;         /* Image Buffer. */
  1548. xaUBYTE *delta;         /* delta data. */
  1549. xaULONG dsize;          /* delta size */
  1550. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1551. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1552.   xaULONG imaged = dec_info->imaged;
  1553.   register xaLONG rowsize,width;
  1554.   register xaUBYTE *i_ptr;
  1555.   register xaLONG exitflag;
  1556.   register xaULONG  type,r_flag,b_cnt,g_cnt,r_cnt; 
  1557.   register xaULONG b,g,r;
  1558.   register xaULONG offset,dmask,depth;
  1559.   register xaUBYTE data;
  1560.   xaLONG changed,xor_flag;
  1561.   xaLONG tmp,minx,miny,maxx,maxy;
  1562.   xaLONG kludge_j;
  1563.  /* this kludge is because animations with width less than 320 are considered
  1564.   * centered in the middle of a 320 screen. Does this happen with
  1565.   * animations greater than lores overscan(374) and less than hi-res(640)????
  1566.   */
  1567.  
  1568.  if (imagex >= 320) kludge_j = 0;
  1569.  else kludge_j = (320-imagex)/2;
  1570.  
  1571.  maxx = maxy = 0; minx = imagex; miny = imagey;
  1572.  
  1573.  changed = xor_flag = 0;
  1574.  width = imagex;
  1575.  rowsize = width / 8;
  1576.  exitflag = 0;
  1577.  while(!exitflag)
  1578.  {
  1579.   /* read compression type and reversible_flag(xor data not just set) 
  1580.    */
  1581.   type   = (*delta++) << 8; type   |= (*delta++);
  1582.  
  1583.   if (type != 0 )
  1584.   {
  1585.     r_flag = (*delta++) << 8; r_flag |= (*delta++);
  1586.   }
  1587.   else r_flag = 0; /* Might possibly have to read it anyways */
  1588.   /* switch on compression type */
  1589.   switch(type)
  1590.   {
  1591.    case 0: exitflag = 1; break; /* end of list */
  1592.    case 1:
  1593.       /* Get byte count and group count 
  1594.        */
  1595.       xor_flag |= r_flag;
  1596.       b_cnt = (*delta++) << 8; b_cnt |= (*delta++);
  1597.       g_cnt = (*delta++) << 8; g_cnt |= (*delta++);
  1598.       
  1599.       /* Loop thru groups
  1600.        */
  1601.       for(g=0; g<g_cnt; g++)
  1602.       {
  1603.     xaULONG odd_flag;
  1604.         offset = (*delta++) << 8; offset |= (*delta++);
  1605.  
  1606.         offset <<= 3; /* counts bytes */
  1607.         if (kludge_j) 
  1608.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1609.  
  1610.         i_ptr = (xaUBYTE *)(image + offset);
  1611.  
  1612.         tmp = offset%imagex; if (tmp<minx) minx=tmp;
  1613.         tmp += 8;            if (tmp>maxx) maxx=tmp;
  1614.         tmp = offset/imagex; if (tmp<miny) miny=tmp;
  1615.         tmp += b_cnt;        if (tmp>maxy) maxy=tmp;
  1616.        
  1617.         odd_flag = (b_cnt * imaged) & 0x01;
  1618.         /* Loop thru byte count 
  1619.          */
  1620.         for(b=0; b < b_cnt; b++)
  1621.         {
  1622.           dmask = 1;
  1623.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1624.           {
  1625.             data = *delta++;
  1626.             changed |= data;          /* CHECKFORZERO change */
  1627.             IFF_Byte_Mod(i_ptr,data,dmask,r_flag);
  1628.             dmask <<= 1;
  1629.           } /* end of depth loop */
  1630.           i_ptr += width; /* direction is vertical */
  1631.         } /* end of byte loop */
  1632.         if (odd_flag) delta++; /* pad to short */
  1633.       } /* end of group loop */
  1634.       break;
  1635.    case 2:
  1636.       /* Read row count, byte count and group count 
  1637.        */
  1638.       xor_flag |= r_flag;
  1639.       r_cnt = (*delta++) << 8; r_cnt |= (*delta++);
  1640.       b_cnt = (*delta++) << 8; b_cnt |= (*delta++);
  1641.       g_cnt = (*delta++) << 8; g_cnt |= (*delta++);
  1642.       
  1643.       /* Loop thru groups
  1644.        */
  1645.       for(g=0; g < g_cnt; g++)
  1646.       { xaULONG odd_flag;
  1647.         offset = (*delta++) << 8; offset |= (*delta++);
  1648.         offset <<= 3; /* counts bytes */
  1649.         if (kludge_j) 
  1650.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1651.  
  1652.         tmp = offset%imagex;     if (tmp<minx) minx=tmp;
  1653.         tmp += b_cnt * 8;        if (tmp>maxx) maxx=tmp;
  1654.         tmp = offset/imagex;     if (tmp<miny) miny=tmp;
  1655.         tmp += r_cnt;            if (tmp>maxy) maxy=tmp;
  1656.        
  1657.         odd_flag = (r_cnt * b_cnt * imaged) & 0x01;
  1658.         /* Loop thru rows of group
  1659.          */
  1660.         for(r=0; r < r_cnt; r++)
  1661.         {
  1662.           dmask = 1;
  1663.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1664.           {
  1665.             i_ptr = (xaUBYTE *)(image + offset + (r * width));
  1666.             for(b=0; b < b_cnt; b++) /* loop thru byte count */
  1667.             {
  1668.               data = *delta++;
  1669.               changed |= data;        /* CHECKFORZERO */
  1670.            
  1671.               IFF_Byte_Mod(i_ptr,data,dmask,r_flag);
  1672.               i_ptr += 8;        /* data is horizontal */
  1673.             } /* end of byte loop */
  1674.             dmask <<= 1;
  1675.           } /* end of depth loop */
  1676.         } /* end of row loop */
  1677.         if (odd_flag) delta++; /* pad to short */
  1678.       } /* end of group loop */
  1679.       break;
  1680.    default: /* don't know this one yet */
  1681.             fprintf(stderr,"Unknown J-type %x\n",type);
  1682.             type = 0;      /* force an exit */
  1683.             exitflag = 1;
  1684.             break;
  1685.   } /* end of type switch */
  1686.  } /* end of while loop */
  1687.  
  1688.  /* if changed is zero then this Delta didn't change the image at all */ 
  1689.  /* BUT we can't return a NOP because we still need the double buffers to
  1690.   * be swapped
  1691.   */
  1692.  if (changed==0)
  1693.  {
  1694.    dec_info->xs = dec_info->ys = 0;
  1695.    dec_info->xe = 8; dec_info->ye = 1;
  1696.    DEBUG_LEVEL2 fprintf(stderr,"DELTA J nothing changed\n");
  1697.    if (xor_flag) return(ACT_DLTA_XOR);
  1698.    return(ACT_DLTA_NORM);
  1699.  }
  1700.  if (xa_optimize_flag == xaTRUE)
  1701.  {
  1702.    dec_info->xs = minx; dec_info->ys = miny;
  1703.    dec_info->xe = maxx; dec_info->ye = maxy;
  1704.  
  1705.    if (dec_info->xs >= imagex) dec_info->xs = 0;
  1706.    if (dec_info->ys >= imagey) dec_info->ys = 0;
  1707.    if (dec_info->xe <= 0)      dec_info->xe = imagex;
  1708.    if (dec_info->ye <= 0)      dec_info->ye = imagey;
  1709.    DEBUG_LEVEL2 fprintf(stderr,"xypos=<%d,%d> xysize=<%d %d>\n",
  1710.         dec_info->xs,dec_info->ys,dec_info->xe,dec_info->ye );
  1711.  }
  1712.  else
  1713.  {
  1714.    dec_info->xs = 0; dec_info->ys = 0;
  1715.    dec_info->xe = imagex; dec_info->ye = imagey;
  1716.  }
  1717.  if (xor_flag) return(ACT_DLTA_XOR);
  1718.  return(ACT_DLTA_NORM);
  1719. } /* end of IFF_DeltaJ routine */
  1720.  
  1721. /* 
  1722.  *  Decode IFF type l anims
  1723.  */
  1724. xaULONG
  1725. IFF_Delta_l(image,delta,dsize,dec_info)
  1726. xaUBYTE *image;         /* Image Buffer. */
  1727. xaUBYTE *delta;         /* delta data. */
  1728. xaULONG dsize;          /* delta size */
  1729. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1730. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1731.   xaULONG imaged = dec_info->imaged;
  1732.   xaULONG vertflag = (xaULONG)(dec_info->extra);
  1733.  register xaLONG i,depth,dmask,width;
  1734.  xaULONG poff0,poff1;
  1735.  register xaUBYTE *i_ptr;
  1736.  register xaUBYTE *optr,*dptr;
  1737.  register xaSHORT cnt;
  1738.  register xaUSHORT offset,data;
  1739.  
  1740.  dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
  1741.  i_ptr = image;
  1742.  if (vertflag) width = imagex;
  1743.  else width = 16;
  1744.  dmask = 1;
  1745.  for(depth = 0; depth<imaged; depth++)
  1746.  {
  1747.    i_ptr = image;
  1748.    /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1749.    poff0  = (xaULONG)(delta[ 4 * depth    ]) << 24;
  1750.    poff0 |= (xaULONG)(delta[ 4 * depth + 1]) << 16;
  1751.    poff0 |= (xaULONG)(delta[ 4 * depth + 2]) <<  8;
  1752.    poff0 |= (xaULONG)(delta[ 4 * depth + 3]);
  1753.  
  1754.    if (poff0)
  1755.    {
  1756.      poff1  = (xaULONG)(delta[ 4 * (depth+8)    ]) << 24;
  1757.      poff1 |= (xaULONG)(delta[ 4 * (depth+8) + 1]) << 16;
  1758.      poff1 |= (xaULONG)(delta[ 4 * (depth+8) + 2]) <<  8;
  1759.      poff1 |= (xaULONG)(delta[ 4 * (depth+8) + 3]);
  1760.  
  1761.      dptr = (xaUBYTE *)(delta + 2 * poff0); 
  1762.      optr = (xaUBYTE *)(delta + 2 * poff1); 
  1763.  
  1764.      /* while short *optr != -1 */
  1765.      while( (optr[0] != 0xff) || (optr[1] != 0xff) )
  1766.      {
  1767.        offset = (*optr++) << 8; offset |= (*optr++);
  1768.        cnt    = (*optr++) << 8; cnt    |= (*optr++);
  1769.  
  1770.        if (cnt < 0)  /* cnt negative */
  1771.        {
  1772.          i_ptr = image + 16 * (xaULONG)(offset);
  1773.          cnt = -cnt;
  1774.          data = (*dptr++) << 8; data |= (*dptr++);
  1775.          for(i=0; i < (xaULONG)cnt; i++)
  1776.          {
  1777.            IFF_Short_Mod(i_ptr,data,dmask,0);
  1778.            i_ptr += width;
  1779.          }
  1780.        }  /* end of neg */
  1781.        else/* cnt pos then */
  1782.        {
  1783.          i_ptr = image + 16 * (xaULONG)(offset);
  1784.          for(i=0; i < (xaULONG)cnt; i++)
  1785.          {
  1786.            data = (*dptr++) << 8; data |= (*dptr++);
  1787.            IFF_Short_Mod(i_ptr,data,dmask,0);
  1788.            i_ptr += width;
  1789.          }
  1790.        } /* end of pos */
  1791.      } /* end of delta for this plane */
  1792.    } /* plane has changed data */
  1793.    dmask <<= 1;
  1794.  } /* end of d */
  1795.  return(ACT_DLTA_NORM);
  1796. }
  1797.  
  1798. void
  1799. IFF_Setup_HMAP(act,hmap,cmap,bits)
  1800. XA_ACTION *act;
  1801. ColorReg *hmap,*cmap;
  1802. xaULONG bits;
  1803. {
  1804.   ColorReg *hptr;
  1805.   xaULONG i,size,shift;
  1806.  
  1807.   if (bits == 8) {size = XA_HMAP8_SIZE; shift = 2;}
  1808.   else {size = XA_HMAP6_SIZE; shift = 4;}
  1809.   
  1810.   act->data = (xaUBYTE *) malloc(size * sizeof(ColorReg) );
  1811.   if (act->data == 0) IFF_TheEnd1("IFF_Setup_HMAP: malloc failed\n");
  1812.   hptr = (ColorReg *) act->data;
  1813.   for(i=0; i < size; i++) 
  1814.   {
  1815.     hptr[i].red   = hmap[i].red   = cmap[i].red   >> shift;
  1816.     hptr[i].green = hmap[i].green = cmap[i].green >> shift;
  1817.     hptr[i].blue  = hmap[i].blue  = cmap[i].blue  >> shift;
  1818.   }
  1819. }
  1820.  
  1821.  
  1822. IFF_DLTA_HDR iff_dlta[2];
  1823.  
  1824. void
  1825. IFF_Init_DLTA_HDR(max_x,max_y)
  1826. xaULONG max_x,max_y;
  1827. {
  1828.   iff_dlta[0].minx = iff_dlta[1].minx = 0;
  1829.   iff_dlta[0].miny = iff_dlta[1].miny = 0;
  1830.   iff_dlta[0].maxx = iff_dlta[1].maxx = max_x;
  1831.   iff_dlta[0].maxy = iff_dlta[1].maxy = max_y;
  1832. }
  1833.  
  1834. void
  1835. IFF_Update_DLTA_HDR(min_x,min_y,max_x,max_y)
  1836. xaLONG *min_x,*min_y,*max_x,*max_y;
  1837. {
  1838.   register xaLONG tmin_x,tmin_y,tmax_x,tmax_y;
  1839.  
  1840.  /* This mess keeps track of the largest rectangle needed to
  1841.   * display all changes. Since things are double buffered, the
  1842.   * min/maxes of the corners of the current and previous two
  1843.   * images are taken. If the animation is in single step mode
  1844.   * it's best to display the entire image.
  1845.   */
  1846.   /* Special condition if max_x is 0, then return previous largest values*/
  1847.  
  1848.   if (max_x)
  1849.   {
  1850.     tmin_x = *min_x;
  1851.     tmin_y = *min_y;
  1852.     tmax_x = *max_x;
  1853.     tmax_y = *max_y;
  1854.     iff_dlta[0].minx = xaMIN(iff_dlta[0].minx, tmin_x);
  1855.     iff_dlta[0].miny = xaMIN(iff_dlta[0].miny, tmin_y);
  1856.     iff_dlta[0].maxx = xaMAX(iff_dlta[0].maxx, tmax_x);
  1857.     iff_dlta[0].maxy = xaMAX(iff_dlta[0].maxy, tmax_y);
  1858.     *min_x = xaMIN(iff_dlta[1].minx, iff_dlta[0].minx);
  1859.     *min_y = xaMIN(iff_dlta[1].miny, iff_dlta[0].miny);
  1860.     *max_x = xaMAX(iff_dlta[1].maxx, iff_dlta[0].maxx);
  1861.     *max_y = xaMAX(iff_dlta[1].maxy, iff_dlta[0].maxy);
  1862.     /* Throw out oldest rectangle and store current.  */
  1863.     iff_dlta[1].minx = iff_dlta[0].minx;
  1864.     iff_dlta[1].miny = iff_dlta[0].miny;
  1865.     iff_dlta[1].maxx = iff_dlta[0].maxx;
  1866.     iff_dlta[1].maxy = iff_dlta[0].maxy;
  1867.     iff_dlta[0].minx = tmin_x;
  1868.     iff_dlta[0].miny = tmin_y;
  1869.     iff_dlta[0].maxx = tmax_x;
  1870.     iff_dlta[0].maxy = tmax_y;
  1871.   }
  1872.   else
  1873.   {
  1874.     *min_x = xaMIN(iff_dlta[1].minx, iff_dlta[0].minx);
  1875.     *min_y = xaMIN(iff_dlta[1].miny, iff_dlta[0].miny);
  1876.     *max_x = xaMAX(iff_dlta[1].maxx, iff_dlta[0].maxx);
  1877.     *max_y = xaMAX(iff_dlta[1].maxy, iff_dlta[0].maxy);
  1878.   }
  1879. }
  1880.  
  1881. void
  1882. IFF_Read_BMHD(xin,bmhd)
  1883. XA_INPUT *xin;
  1884. Bit_Map_Header *bmhd;
  1885. {
  1886.   /* read Bit_Map_Header into bmhd */
  1887.   /* read so as to avoid endian problems */
  1888.   bmhd->width              = xin->Read_MSB_U16(xin);
  1889.   bmhd->height             = xin->Read_MSB_U16(xin);
  1890.   bmhd->x                  = xin->Read_MSB_U16(xin);
  1891.   bmhd->y                  = xin->Read_MSB_U16(xin);
  1892.   bmhd->depth              = xin->Read_U8(xin);
  1893.   bmhd->masking            = xin->Read_U8(xin);
  1894.   bmhd->compression        = xin->Read_U8(xin);
  1895.   bmhd->pad1               = xin->Read_U8(xin);
  1896.   bmhd->transparentColor   = xin->Read_MSB_U16(xin);
  1897.   bmhd->xAspect            = xin->Read_U8(xin);
  1898.   bmhd->yAspect            = xin->Read_U8(xin);
  1899.   bmhd->pageWidth          = xin->Read_MSB_U16(xin);
  1900.   bmhd->pageHeight         = xin->Read_MSB_U16(xin);
  1901.  
  1902. void
  1903. IFF_Read_ANHD(xin,anhd,chunk_size)
  1904. XA_INPUT *xin;
  1905. Anim_Header *anhd;
  1906. xaULONG chunk_size;
  1907. {
  1908.   xaULONG i;
  1909.   anhd->op        = xin->Read_U8(xin);
  1910.   anhd->mask        = xin->Read_U8(xin);
  1911.   anhd->w        = xin->Read_MSB_U16(xin);
  1912.   anhd->h        = xin->Read_MSB_U16(xin);
  1913.   anhd->x        = xin->Read_MSB_U16(xin);
  1914.   anhd->y        = xin->Read_MSB_U16(xin);
  1915.   anhd->abstime        = xin->Read_MSB_U32(xin);
  1916.   anhd->reltime        = xin->Read_MSB_U32(xin);
  1917.   anhd->interleave    = xin->Read_U8(xin);
  1918.   anhd->pad0        = xin->Read_U8(xin);
  1919.   anhd->bits        = xin->Read_MSB_U32(xin);
  1920.   xin->Read_Block(xin,(xaBYTE *)(anhd->pad),16); /* read pad */
  1921.   i = Anim_Header_SIZE;
  1922.   while(i < chunk_size) {xin->Read_U8(xin); i++;}
  1923. }
  1924.  
  1925. void
  1926. IFF_Read_ANSQ(xin,chunk_size)
  1927. XA_INPUT *xin;
  1928. xaULONG chunk_size;
  1929. { xaULONG i;
  1930.   xaUBYTE *p;  /* data is actually big endian xaUSHORT */
  1931.   xaBYTE *garb;
  1932.  
  1933.   iff_ansq_cnt = chunk_size / 4;
  1934.   iff_ansq_cnt++; /* adding dlta 0 up front */
  1935.   DEBUG_LEVEL2 fprintf(stderr,"    ansq_cnt=%d dlta_cnt=%d\n",
  1936.                         iff_ansq_cnt,iff_dlta_cnt);
  1937.   /* allocate space for ansq variables
  1938.   */
  1939.   iff_ansq = (IFF_ANSQ *)malloc( iff_ansq_cnt * sizeof(IFF_ANSQ));
  1940.   if (iff_ansq == NULL) IFF_TheEnd1("IFF_Read_ANSQ: malloc err");
  1941.   if (xa_verbose) fprintf(stderr,"     frames=%d dlts=%d comp=%d\n",
  1942.             iff_ansq_cnt,iff_dlta_cnt,iff_dlta_compression);
  1943.   garb = (xaBYTE *)malloc(chunk_size);
  1944.   if (garb==0)
  1945.   {
  1946.     fprintf(stderr,"ansq malloc not enough\n");
  1947.     IFF_TheEnd();
  1948.   }
  1949.   xin->Read_Block(xin,garb,chunk_size);
  1950.   p = (xaUBYTE *)(garb);
  1951.   /* first delta is only used once and doesn't appear in
  1952.   * the ANSQ
  1953.   */
  1954.   iff_ansq[0].dnum  = 0;
  1955.   iff_ansq[0].time  = 1;
  1956.   for(i=1; i<iff_ansq_cnt; i++)
  1957.   {
  1958.     /* this is delta to apply */
  1959.     iff_ansq[i].dnum  = (xaULONG)(*p++)<<8;
  1960.     iff_ansq[i].dnum |= (xaULONG)(*p++);
  1961.     /* this is jiffy count or if 0xffff then a goto */
  1962.     iff_ansq[i].time  = (xaULONG)(*p++)<<8;
  1963.     iff_ansq[i].time |= (xaULONG)(*p++);
  1964.     iff_ansq[i].frame = 0;
  1965.     DEBUG_LEVEL2
  1966.     fprintf(stderr,"<%d %d> ",iff_ansq[i].dnum, iff_ansq[i].time);
  1967.   }
  1968.   FREE(garb,0x100C); garb=0;
  1969. }
  1970.  
  1971. /*
  1972.  * Function to register any CRNGs that occur before CMAP in IFF file
  1973.  */
  1974. void
  1975. IFF_Register_CRNGs(anim_hdr,chdr)
  1976. XA_ANIM_HDR *anim_hdr;
  1977. XA_CHDR *chdr;
  1978. {
  1979.   XA_ACTION *act;
  1980.  
  1981.   act = (XA_ACTION *)anim_hdr->acts;
  1982.  
  1983.   while(act)
  1984.   {
  1985.     if ( (act->type == ACT_CYCLE) && (act->chdr == 0) )
  1986.              ACT_Add_CHDR_To_Action(act,chdr);
  1987.     act = act->next;
  1988.   }
  1989. }
  1990.  
  1991.  
  1992. void
  1993. IFF_Read_CRNG(anim_hdr,xin,chunk_size,crng_flag)
  1994. XA_ANIM_HDR *anim_hdr;
  1995. XA_INPUT *xin;
  1996. xaULONG chunk_size;
  1997. xaULONG *crng_flag;
  1998. {
  1999. /* CRNG_HDR
  2000.  * word pad1,rate,active;
  2001.  * byte low,high;
  2002.  */
  2003.  
  2004.   /* is the chunk the correct size ?
  2005.   */
  2006.   if (chunk_size == IFF_CRNG_HDR_SIZE)
  2007.   {
  2008.     XA_ACTION *act;
  2009.     xaULONG rate,active,low,high,csize;
  2010.     ACT_CYCLE_HDR *act_cycle;
  2011.  
  2012.     /* read CRNG chunk */
  2013.     rate   = xin->Read_MSB_U16(xin);  /* throw away pad1 */
  2014.     rate   = xin->Read_MSB_U16(xin);
  2015.     active = xin->Read_MSB_U16(xin);
  2016.     low    = xin->Read_U8(xin);
  2017.     high   = xin->Read_U8(xin);
  2018.     /* make it an action only if its valid
  2019.     */
  2020.     if (   (active & IFF_CRNG_ACTIVE) && (low < high) 
  2021.     && (rate > IFF_CRNG_DPII_KLUDGE) && (iff_allow_cycling == xaTRUE) )
  2022.     {
  2023.       xaULONG i,*i_ptr;
  2024.  
  2025.       csize = high - low + 1;
  2026.       act_cycle = (ACT_CYCLE_HDR *)
  2027.     malloc( sizeof(ACT_CYCLE_HDR) + (csize * sizeof(xaULONG)) );
  2028.       if (act_cycle == 0) IFF_TheEnd1("IFF_Read_CRNG: malloc failed");
  2029.  
  2030.       act_cycle->size = csize;
  2031.       act_cycle->curpos = 0;
  2032.       act_cycle->rate  = (xaULONG)(IFF_CRNG_INTERVAL/rate);
  2033.       act_cycle->flags = ACT_CYCLE_ACTIVE;
  2034.       if (active & IFF_CRNG_REVERSE) act_cycle->flags |= ACT_CYCLE_REVERSE;
  2035.  
  2036.       i_ptr = (xaULONG *)act_cycle->data;
  2037.       for(i=0; i<csize; i++) 
  2038.       {
  2039.         i_ptr[i] = low + i + iff_or_mask;
  2040.       }
  2041.  
  2042.       *crng_flag = *crng_flag + 1;
  2043.       act = ACT_Get_Action(anim_hdr,ACT_CYCLE);
  2044.       IFF_Add_Frame(0,act);
  2045.       act->data = (xaUBYTE *) act_cycle;
  2046.     /* register it now if iff_chdr valid, else wait to later */
  2047.       if (iff_chdr) ACT_Add_CHDR_To_Action(act,iff_chdr);
  2048.     }
  2049.     else DEBUG_LEVEL2 fprintf(stderr,"IFF_CRNG not used\n");
  2050.   }
  2051.   else
  2052.   { xin->Seek_FPos(xin,chunk_size,1);
  2053.     fprintf(stderr,"IFF_CRNG chunksize mismatch %d\n",chunk_size);
  2054.   }
  2055. }
  2056.  
  2057.  
  2058. void
  2059. IFF_Read_CMAP_0(cmap,size,xin)
  2060. ColorReg *cmap;
  2061. xaULONG size;
  2062. XA_INPUT *xin;
  2063. {
  2064.   xaULONG i;
  2065.   for(i=0; i < size; i++)
  2066.   {
  2067.     cmap[i].red   = xin->Read_U8(xin);
  2068.     cmap[i].green = xin->Read_U8(xin);
  2069.     cmap[i].blue  = xin->Read_U8(xin);
  2070.   }
  2071. }
  2072.  
  2073. void
  2074. IFF_Read_CMAP_1(cmap,size,xin)
  2075. ColorReg *cmap;
  2076. xaULONG size;
  2077. XA_INPUT *xin;
  2078. {
  2079.   xaULONG i;
  2080.   for(i=0; i < size; i++)
  2081.   {
  2082.     xaULONG d;
  2083.     d = xin->Read_U8(xin);
  2084.     cmap[i].red   = (d & 0x0f) << 4;
  2085.     d = xin->Read_U8(xin);
  2086.     cmap[i].green = (d & 0xf0);
  2087.     cmap[i].blue  = (d & 0x0f) << 4;
  2088.   }
  2089. }
  2090.  
  2091.  
  2092. void IFF_Buffer_HAM6(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag)
  2093. xaUBYTE *out;        /* output image (size of section) */
  2094. xaUBYTE *in;        /* input image */
  2095. XA_CHDR *chdr;        /* color header to map to */
  2096. ColorReg *h_cmap;    /* ham color map */
  2097. xaULONG xosize,yosize;    /* size of section in input buffer */
  2098. xaULONG xip,yip;        /* pos of section in input buffer */
  2099. xaULONG xisize;        /* x size of input buffer */
  2100. xaULONG d_flag;        /* map_flag */
  2101. {
  2102.   XA_CHDR *the_chdr;
  2103.   xaULONG new_cmap_flag,*the_map,psize;
  2104.   register xaULONG y,xend,the_moff,coff;
  2105.   xaUSHORT g_adj[16];
  2106.  
  2107.   if (x11_display_type & XA_X11_TRUE) 
  2108.     for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ];
  2109.  
  2110.   the_map = chdr->map;
  2111.   coff = chdr->coff;
  2112.   if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; }
  2113.   else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; }
  2114.   the_moff = the_chdr->moff;
  2115.   if (x11_display_type & XA_X11_TRUE) d_flag = xaTRUE;
  2116.   if (d_flag==xaTRUE) psize = x11_bytes_pixel;
  2117.   else psize = 1;
  2118.  
  2119.   DEBUG_LEVEL1 fprintf(stderr,"ham_cmap: = %x\n",(xaULONG)h_cmap);
  2120.  
  2121.   if (xa_ham_map == 0)
  2122.   {
  2123.      xa_ham_map_size = XA_HAM6_CACHE_SIZE;
  2124.      xa_ham_map = (xaULONG *)malloc( xa_ham_map_size * sizeof(xaULONG) );
  2125.      if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM6: h_map malloc err");
  2126.   }
  2127.   if ((the_chdr != xa_ham_chdr) || (xa_ham_init != 6))
  2128.   {
  2129.     register xaULONG i;
  2130.     DEBUG_LEVEL1 fprintf(stderr,"xa_ham_map: old = %x new = %x\n",
  2131.                     (xaULONG)xa_ham_chdr,(xaULONG)the_chdr);
  2132.     for(i=0; i<XA_HAM6_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID;
  2133.     xa_ham_chdr = the_chdr; xa_ham_init = 6;
  2134.   }
  2135.  
  2136.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2137.   for (y=yip; y < (yip + yosize); y++)
  2138.   {
  2139.     register xaULONG x;
  2140.     register xaUBYTE *i_ptr = (xaUBYTE *)( in + y * xisize );
  2141.     register xaUBYTE *o_ptr = (xaUBYTE *)( out + (y-yip)*xosize * psize );
  2142.     register xaULONG pred,pgrn,pblu,data;
  2143.     pred = pgrn = pblu = 0;
  2144.     for (x=0; x<xend; x++)
  2145.     {
  2146.       data = (xaUSHORT )(*i_ptr++);
  2147.       switch(data & 0x30)
  2148.       {
  2149.         case 0x00: /* use color register given by low */
  2150.           { register xaUSHORT low = data & 0x0f;
  2151.             pred = h_cmap[low].red;
  2152.             pgrn = h_cmap[low].green;
  2153.             pblu = h_cmap[low].blue;
  2154.           } break;
  2155.         case 0x10: pblu = data & 0x0f; break; /* change blue */
  2156.         case 0x20: pred = data & 0x0f; break; /* change red */
  2157.         case 0x30: pgrn = data & 0x0f; break; /* change green */
  2158.       }
  2159.       if ( (x >= xip) && (x < xend) )
  2160.       {
  2161.         register xaULONG t_color;
  2162.         register xaUSHORT indx = (pred << 8) | (pgrn << 4) | pblu;
  2163.  
  2164.         if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) 
  2165.         {
  2166.           if (x11_display_type & XA_X11_TRUE) t_color = 
  2167.         X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16);
  2168.       else /* don't gamma because chdr already adjusted */
  2169.       {
  2170.             if (cmap_true_to_332 == xaTRUE)
  2171.          t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE4);
  2172.         else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE9);
  2173.             if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff;
  2174.       }
  2175.           xa_ham_map[indx] = t_color;
  2176.     }
  2177.  
  2178.     if (d_flag)
  2179.     {
  2180.           if (x11_bytes_pixel == 4)
  2181.              { xaULONG *ulp = (xaULONG *)o_ptr; *ulp = t_color; o_ptr += 4; }
  2182.           else if (x11_bytes_pixel == 2) { xaUSHORT *usp = (xaUSHORT *)o_ptr;
  2183.              *usp = (xaUSHORT)(t_color); o_ptr += 2; }
  2184.           else *o_ptr++ = (xaUBYTE)t_color;
  2185.     } else *o_ptr++ = (xaUBYTE)t_color;
  2186.       } /* end of output */
  2187.     } /* end of x */
  2188.   } /* end of y */
  2189. }
  2190.  
  2191.  
  2192. void IFF_Buffer_HAM8(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag)
  2193. xaUBYTE *out;        /* output image (size of section) */
  2194. xaUBYTE *in;        /* input image */
  2195. XA_CHDR *chdr;        /* color header to map to */
  2196. ColorReg *h_cmap;    /* ham color map */
  2197. xaULONG xosize,yosize;    /* size of section in input buffer */
  2198. xaULONG xip,yip;        /* pos of section in input buffer */
  2199. xaULONG xisize;        /* x size of input buffer */
  2200. xaULONG d_flag;        /* map_flag */
  2201. {
  2202.   XA_CHDR *the_chdr;
  2203.   xaULONG new_cmap_flag,*the_map,psize;
  2204.   register xaULONG y,xend,the_moff,coff;
  2205.   xaUSHORT g_adj[64];
  2206.  
  2207.   if (x11_display_type & XA_X11_TRUE) 
  2208.     for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ];
  2209.   the_map = chdr->map;
  2210.   coff = chdr->coff;
  2211.   if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; }
  2212.   else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; }
  2213.   the_moff = chdr->moff;
  2214.   if (x11_display_type & XA_X11_TRUE) d_flag = xaTRUE;
  2215.   if (d_flag==xaTRUE) psize = x11_bytes_pixel;
  2216.   else psize = 1;
  2217.  
  2218.   if (xa_ham_map_size != XA_HAM8_CACHE_SIZE)
  2219.   {
  2220.     if (xa_ham_map == 0)
  2221.     {
  2222.          xa_ham_map_size = XA_HAM8_CACHE_SIZE;
  2223.          xa_ham_map = (xaULONG *)malloc( xa_ham_map_size * sizeof(xaULONG) );
  2224.          if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err");
  2225.     }
  2226.     else
  2227.     {
  2228.       xaULONG *tmp;
  2229.       xa_ham_map_size = XA_HAM8_CACHE_SIZE;
  2230.       tmp = (xaULONG *) realloc(xa_ham_map,xa_ham_map_size * sizeof(xaULONG));
  2231.       if (tmp == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err");
  2232.       xa_ham_map = tmp;
  2233.     }
  2234.     xa_ham_chdr = 0;
  2235.   }
  2236.   if ( (the_chdr != xa_ham_chdr) || (xa_ham_init != 8))
  2237.   {
  2238.     register xaULONG i;
  2239.     DEBUG_LEVEL1 fprintf(stderr,"xa_ham8_map: old = %x new = %x\n",
  2240.                     (xaULONG)xa_ham_chdr,(xaULONG)the_chdr);
  2241.     for(i=0; i<XA_HAM8_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID;
  2242.     xa_ham_chdr = the_chdr; xa_ham_init = 8;
  2243.   }
  2244.  
  2245.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2246.   for (y=yip; y < (yip + yosize); y++)
  2247.   {
  2248.     register xaULONG x;
  2249.     register xaUBYTE *i_ptr = (xaUBYTE *)( in + y * xisize );
  2250.     register xaUBYTE *o_ptr = (xaUBYTE *)( out + (y-yip) *xosize * psize);
  2251.     register xaULONG pred,pgrn,pblu,data;
  2252.  
  2253.     pred = pgrn = pblu = 0;
  2254.     for (x=0; x<xend; x++)
  2255.     {
  2256.       data = (xaULONG )(*i_ptr++);
  2257.       switch(data & 0xc0)
  2258.       {
  2259.         case 0x00: /* use color register given by low */
  2260.           { register xaULONG low = data & 0x3f;
  2261.             pred  = h_cmap[low].red;
  2262.             pgrn  = h_cmap[low].green;
  2263.             pblu  = h_cmap[low].blue;
  2264.           } break;
  2265.         case 0x40: pblu = data & 0x3f; break; /* change blue */
  2266.         case 0x80: pred = data & 0x3f; break; /* change red */
  2267.         case 0xc0: pgrn = data & 0x3f; break; /* change green */
  2268.       }
  2269.       if ( (x >= xip) && (x < xend) )
  2270.       {
  2271.         register xaULONG t_color;
  2272.         register xaULONG indx = (pred << 12) | (pgrn << 6) | pblu;
  2273.  
  2274.         if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) 
  2275.         {
  2276.           if (x11_display_type & XA_X11_TRUE) t_color = 
  2277.         X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16);
  2278.       else /* no gamma here because it's already in cmap */
  2279.       {
  2280.             if (cmap_true_to_332 == xaTRUE)
  2281.          t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE6);
  2282.         else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE11);
  2283.             if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff;
  2284.       }
  2285.           xa_ham_map[indx] = t_color;
  2286.     }
  2287.     if (d_flag)
  2288.     {
  2289.           if (x11_bytes_pixel == 4)
  2290.              { xaULONG *ulp = (xaULONG *)o_ptr; *ulp = t_color; o_ptr += 4; }
  2291.           else if (x11_bytes_pixel == 2) { xaUSHORT *usp = (xaUSHORT *)o_ptr;
  2292.                          *usp = (xaUSHORT)(t_color); o_ptr += 2; }
  2293.           else *o_ptr++ = (xaUBYTE)t_color;
  2294.     } else *o_ptr++ = (xaUBYTE)t_color;
  2295.       } /* end of output */
  2296.     } /* end of x */
  2297.   } /* end of y */
  2298. }
  2299.  
  2300. void
  2301. IFF_Shift_CMAP(cmap,csize)
  2302. ColorReg *cmap;
  2303. xaULONG csize;
  2304. { xaULONG i;
  2305.   for(i=0;i<csize;i++)
  2306.   { cmap[i].red   >>= 4;
  2307.     cmap[i].green >>= 4;
  2308.     cmap[i].blue  >>= 4;
  2309.   }
  2310. }
  2311.  
  2312.  /* Extra Info. 0 = short encoding, 1 = long encoding*/
  2313. xaULONG
  2314. IFF_Delta_7(image,delta,dsize,dec_info)
  2315. xaUBYTE *image;         /* Image Buffer. */
  2316. xaUBYTE *delta;         /* delta data. */
  2317. xaULONG dsize;          /* delta size */
  2318. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  2319. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  2320.   xaULONG imaged = dec_info->imaged;
  2321.   void *extra = dec_info->extra;
  2322.  register xaLONG col,depth,dmask;
  2323.  register xaLONG rowsize,width;
  2324.  xaULONG poff,doff,col_shift;
  2325.  register xaUBYTE *i_ptr;
  2326.  register xaUBYTE *optr,opcnt,op,cnt;
  2327.  xaUBYTE *d_ptr;
  2328.  xaLONG miny,minx,maxy,maxx;
  2329.  xaULONG iextra = (xaULONG)(extra);
  2330.  
  2331.  /* set to opposites for min/max testing */
  2332.  dec_info->xs = imagex;
  2333.  dec_info->ys = imagey;
  2334.  dec_info->xe = 0;
  2335.  dec_info->ye = 0;
  2336.  
  2337.  i_ptr = image;
  2338.  width = imagex;
  2339.  col_shift = (iextra)?4:5;
  2340.  rowsize = width >> col_shift;
  2341.  dmask = 1;
  2342.  for(depth=0; depth<imaged; depth++)
  2343.  {
  2344.   minx = -1;
  2345.   maxx = -1;
  2346.   
  2347.   i_ptr = image;
  2348.   /* offset into delt chunk */
  2349.   { register xaULONG ddepth = depth << 2;
  2350.     poff  = (xaULONG)(delta[ ddepth++ ]) << 24;
  2351.     poff |= (xaULONG)(delta[ ddepth++ ]) << 16;
  2352.     poff |= (xaULONG)(delta[ ddepth++ ]) <<  8;
  2353.     poff |= (xaULONG)(delta[ ddepth   ]);
  2354.     ddepth +=29; /* move to data */
  2355.     doff  = (xaULONG)(delta[ ddepth++ ]) << 24;
  2356.     doff |= (xaULONG)(delta[ ddepth++ ]) << 16;
  2357.     doff |= (xaULONG)(delta[ ddepth++ ]) <<  8;
  2358.     doff |= (xaULONG)(delta[ ddepth   ]);
  2359.   }
  2360.   if (poff)
  2361.   {
  2362.    optr   = (xaUBYTE  *)(delta + poff);
  2363.    d_ptr =  (xaUBYTE *)(delta + doff);
  2364.    
  2365.    for(col=0;col<rowsize;col++)
  2366.    {
  2367.     /* start at top of column */
  2368.     i_ptr = (xaUBYTE *)(image + (col << col_shift));
  2369.     opcnt = *optr++;  /* get number of ops for this column */
  2370.     
  2371.     miny = -1;
  2372.     maxy = -1;
  2373.  
  2374.     while(opcnt)    /* execute ops */
  2375.     {
  2376.       /* keep track of min and max columns */
  2377.       if (minx == -1) minx = col;
  2378.       maxx = col;
  2379.  
  2380.       op = *optr++;   /* get op */
  2381.      
  2382.       if (iextra) /* xaSHORT Data */
  2383.       {
  2384.         if (op & 0x80)    /* if type uniqe */
  2385.         {
  2386.           if (miny == -1) miny = (xaULONG)(i_ptr - image ) / width;
  2387.           cnt = op & 0x7f;         /* get cnt */
  2388.       
  2389.           while(cnt--) /* loop through data */
  2390.           {
  2391.              register xaULONG data;
  2392.          data = (*d_ptr++) << 8; data |= *d_ptr++;
  2393.              IFF_Short_Mod(i_ptr,data,dmask,0);
  2394.              i_ptr += width;
  2395.           }
  2396.         } /* end unique */
  2397.         else
  2398.         {
  2399.           if (op == 0)   /* type same */
  2400.           {
  2401.              register xaUSHORT data;
  2402.              if (miny == -1) miny=(xaULONG)(i_ptr - image) / width;
  2403.              cnt = *optr++;
  2404.          data = (*d_ptr++) << 8; data |= *d_ptr++;
  2405.  
  2406.              while(cnt--) /* loop through data */
  2407.              { 
  2408.                 IFF_Short_Mod(i_ptr,data,dmask,0);
  2409.                 i_ptr += width;
  2410.              }
  2411.            } /* end same */
  2412.            else
  2413.            {
  2414.               i_ptr += (width * op);  /* type skip */
  2415.            }
  2416.          } /* end of hi bit clear */
  2417.       } /* end of short data */
  2418.       else /* xaLONG Data */
  2419.       {
  2420.         if (op & 0x80)    /* if type uniqe */
  2421.         {
  2422.           if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  2423.           cnt = op & 0x7f;         /* get cnt */
  2424.       
  2425.           while(cnt--) /* loop through data */
  2426.           { register xaULONG data;
  2427.         data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16;
  2428.         data |= (*d_ptr++)<<8; data |= *d_ptr++;
  2429.             IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;
  2430.           }
  2431.         } /* end unique */
  2432.         else
  2433.         {
  2434.            if (op == 0) /* type same */
  2435.            { register xaULONG data;
  2436.              if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  2437.              cnt = *optr++;
  2438.          data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16;
  2439.          data |= (*d_ptr++)<<8; data |= *d_ptr++;
  2440.  
  2441.              while(cnt--) {IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;}
  2442.            } /* end same */
  2443.            else { i_ptr += (width * op);  /* type skip */ }
  2444.          } /* end of hi bit clear */
  2445.        } /* end of long data */
  2446.        opcnt--;
  2447.      } /* end of while opcnt */
  2448.      maxy = (xaULONG)( i_ptr - image ) / width;
  2449.      if ( (miny>=0) && (miny < dec_info->ys)) dec_info->ys = miny;
  2450.      if ( (maxy>=0) && (maxy > dec_info->ye)) dec_info->ye = maxy;
  2451.     } /* end of column loop */
  2452.    } /* end of valid pointer for this plane */
  2453.    dmask <<= 1;
  2454.    minx <<= col_shift; maxx <<= col_shift;
  2455.    maxx = (iextra)?(maxx+15):(maxx+31);
  2456.    if ( (minx>=0) && (minx < dec_info->xs)) dec_info->xs = minx;
  2457.    if ( (maxx>=0) && (maxx > dec_info->xe)) dec_info->xe = maxx;
  2458.   } /* end of for depth */
  2459.  
  2460.   if (xa_optimize_flag == xaTRUE)
  2461.   {
  2462.     if (dec_info->xs >= imagex) dec_info->xs = 0;
  2463.     if (dec_info->ys >= imagey) dec_info->ys = 0;
  2464.     if (dec_info->xe <= 0)      dec_info->xe = imagex;
  2465.     if (dec_info->ye <= 0)      dec_info->ye = imagey;
  2466.   }
  2467.   else
  2468.   {
  2469.     dec_info->xs = 0;      dec_info->ys = 0;
  2470.     dec_info->xe = imagex; dec_info->ye = imagey;
  2471.   }
  2472.   return(ACT_DLTA_NORM);
  2473. } /* end of routine */
  2474.  
  2475.  
  2476.  
  2477. /* Extra Info. 0 = short encoding, 1 = long encoding*/
  2478. xaULONG
  2479. IFF_Delta_8(image,delta,dsize,dec_info)
  2480. xaUBYTE *image;         /* Image Buffer. */
  2481. xaUBYTE *delta;         /* delta data. */
  2482. xaULONG dsize;          /* delta size */
  2483. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  2484. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  2485.   xaULONG imaged = dec_info->imaged;
  2486.   void *extra = dec_info->extra;
  2487.   register xaLONG col,depth,dmask;
  2488.   register xaLONG rowsize,width;
  2489.   xaULONG poff,col_shift;
  2490.   register xaUBYTE *i_ptr;
  2491.   register xaUBYTE *optr;
  2492.   register xaULONG opcnt,op,cnt;
  2493.   xaLONG miny,minx,maxy,maxx;
  2494.   xaULONG iextra = (xaULONG)(extra);
  2495.  
  2496.  /* set to opposites for min/max testing */
  2497.   dec_info->xs = imagex;
  2498.   dec_info->ys = imagey;
  2499.   dec_info->xe = 0;
  2500.   dec_info->ye = 0;
  2501.  
  2502.  i_ptr = image;
  2503.  width = imagex;
  2504.  col_shift = (iextra)?4:5;
  2505.  rowsize = width >> col_shift;
  2506.  dmask = 1;
  2507.  for(depth=0; depth<imaged; depth++)
  2508.  {
  2509.   minx = -1;
  2510.   maxx = -1;
  2511.   
  2512.   i_ptr = image;
  2513.   /* offset into delt chunk */
  2514.   { register xaULONG ddepth = depth << 2;
  2515.     poff  = (xaULONG)(delta[ ddepth++ ]) << 24;
  2516.     poff |= (xaULONG)(delta[ ddepth++ ]) << 16;
  2517.     poff |= (xaULONG)(delta[ ddepth++ ]) <<  8;
  2518.     poff |= (xaULONG)(delta[ ddepth   ]);
  2519.   }
  2520.   if (poff)
  2521.   {
  2522.    optr   = (xaUBYTE  *)(delta + poff);
  2523.    
  2524.    for(col=0;col<rowsize;col++)
  2525.    {
  2526.      /* start at top of column */
  2527.      i_ptr = (xaUBYTE *)(image + (col << col_shift));
  2528.      if (iextra) /* xaSHORT Data */
  2529.      {
  2530.        opcnt  = (xaULONG)(*optr++) << 8;  /* get number of ops for this column */
  2531.        opcnt |= (xaULONG)(*optr++);
  2532.     
  2533.        miny = -1;
  2534.        maxy = -1;
  2535.  
  2536.        while(opcnt)    /* execute ops */
  2537.        {
  2538.      /* keep track of min and max columns */
  2539.      if (minx == -1) minx = col;
  2540.      maxx = col;
  2541.  
  2542.      op  = (xaULONG)(*optr++) << 8;   /* get op */
  2543.      op |= (xaULONG)(*optr++);
  2544.      
  2545.      if (op & 0x8000)    /* if type uniqe */
  2546.      {
  2547.        if (miny == -1) miny = (xaULONG)(i_ptr - image ) / width;
  2548.        cnt = op & 0x7fff;         /* get cnt */
  2549.       
  2550.        while(cnt--) /* loop through data */
  2551.        {
  2552.              register xaULONG data;
  2553.          data = (*optr++) << 8; data |= *optr++;
  2554.              IFF_Short_Mod(i_ptr,data,dmask,0);
  2555.              i_ptr += width;
  2556.        }
  2557.      } /* end unique */
  2558.      else
  2559.      {
  2560.        if (op == 0)   /* type same */
  2561.        {
  2562.              register xaUSHORT data;
  2563.              if (miny == -1) miny=(xaULONG)(i_ptr - image) / width;
  2564.          cnt  = (xaULONG)(*optr++) << 8;
  2565.          cnt |= (xaULONG)(*optr++);
  2566.          data = (*optr++) << 8; data |= *optr++;
  2567.  
  2568.              while(cnt--) /* loop through data */
  2569.          { 
  2570.            IFF_Short_Mod(i_ptr,data,dmask,0);
  2571.            i_ptr += width;
  2572.              }
  2573.            } /* end same */
  2574.            else
  2575.            {
  2576.          i_ptr += (width * op);  /* type skip */
  2577.            }
  2578.          } /* end of hi bit clear */
  2579.      opcnt--;
  2580.        } /* end of while opcnt */
  2581.      } /* end of short data */
  2582.      else /* xaLONG Data */
  2583.      {
  2584.        opcnt  = (xaULONG)(*optr++) << 24; /* get number of ops for this column */
  2585.        opcnt |= (xaULONG)(*optr++) << 16;
  2586.        opcnt |= (xaULONG)(*optr++) <<  8;
  2587.        opcnt |= (xaULONG)(*optr++);
  2588.     
  2589.        miny = -1;
  2590.        maxy = -1;
  2591.  
  2592.        while(opcnt)    /* execute ops */
  2593.        {
  2594.      /* keep track of min and max columns */
  2595.      if (minx == -1) minx = col;
  2596.      maxx = col;
  2597.  
  2598.      op  = (xaULONG)(*optr++) << 24;   /* get op */
  2599.      op |= (xaULONG)(*optr++) << 16;
  2600.      op |= (xaULONG)(*optr++) <<  8;
  2601.      op |= (xaULONG)(*optr++);
  2602.  
  2603.      if (op & 0x80000000)    /* if type uniqe */
  2604.      {
  2605.        if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  2606.        cnt = op & 0x7fffffff;         /* get cnt */
  2607.       
  2608.        while(cnt--) /* loop through data */
  2609.        { register xaULONG data;
  2610.          data = (*optr++)<<24; data |= (*optr++)<<16;
  2611.          data |= (*optr++)<<8; data |= *optr++;
  2612.          IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;
  2613.        }
  2614.      } /* end unique */
  2615.      else
  2616.      {
  2617.            if (op == 0) /* type same */
  2618.        { register xaULONG data;
  2619.              if (miny == -1) miny=(xaULONG)( i_ptr - image ) / width;
  2620.          cnt  = (xaULONG)(*optr++) << 24;
  2621.          cnt |= (xaULONG)(*optr++) << 16;
  2622.          cnt |= (xaULONG)(*optr++) <<  8;
  2623.          cnt |= (xaULONG)(*optr++);
  2624.          data = (*optr++)<<24; data |= (*optr++)<<16;
  2625.          data |= (*optr++)<<8; data |= *optr++;
  2626.  
  2627.              while(cnt--) {IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;}
  2628.            } /* end same */
  2629.            else { i_ptr += (width * op);  /* type skip */ }
  2630.          } /* end of hi bit clear */
  2631.      opcnt--;
  2632.        } /* end of while opcnt */
  2633.      } /* end of long data */
  2634.      maxy = (xaULONG)( i_ptr - image ) / width;
  2635.      if ( (miny>=0) && (miny < dec_info->ys)) dec_info->ys = miny;
  2636.      if ( (maxy>=0) && (maxy > dec_info->ye)) dec_info->ye = maxy;
  2637.     } /* end of column loop */
  2638.    } /* end of valid pointer for this plane */
  2639.    dmask <<= 1;
  2640.    minx <<= col_shift; maxx <<= col_shift;
  2641.    maxx = (iextra)?(maxx+15):(maxx+31);
  2642.    if ( (minx>=0) && (minx < dec_info->xs)) dec_info->xs = minx;
  2643.    if ( (maxx>=0) && (maxx > dec_info->xe)) dec_info->xe = maxx;
  2644.   } /* end of for depth */
  2645.  
  2646.   if (xa_optimize_flag == xaTRUE)
  2647.   {
  2648.     if (dec_info->xs >= imagex) dec_info->xs = 0;
  2649.     if (dec_info->ys >= imagey) dec_info->ys = 0;
  2650.     if (dec_info->xe <= 0)      dec_info->xe = imagex;
  2651.     if (dec_info->ye <= 0)      dec_info->ye = imagey;
  2652.   }
  2653.   else
  2654.   {
  2655.     dec_info->xs = 0;      dec_info->ys = 0;
  2656.     dec_info->xe = imagex; dec_info->ye = imagey;
  2657.   }
  2658.   return(ACT_DLTA_NORM);
  2659. } /* end of routine */
  2660.  
  2661.  
  2662. /* POD NOTE: no need to support xorflag yet */
  2663. void IFF_Long_Mod(ptr,data,dmask,xorflag) 
  2664. xaUBYTE *ptr;
  2665. xaULONG data,dmask,xorflag;
  2666. { register xaUBYTE *_iptr = ptr; 
  2667.   register xaUBYTE dmaskoff = ~dmask;
  2668.   if (xorflag) TheEnd1("IFF comp7: xorflag not supported yet. Contact Author");
  2669.   if (0x80000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2670.   if (0x40000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2671.   if (0x20000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2672.   if (0x10000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2673.   if (0x08000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2674.   if (0x04000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2675.   if (0x02000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2676.   if (0x01000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2677.   if (0x00800000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2678.   if (0x00400000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2679.   if (0x00200000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2680.   if (0x00100000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2681.   if (0x00080000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2682.   if (0x00040000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2683.   if (0x00020000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2684.   if (0x00010000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2685.   if (0x00008000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2686.   if (0x00004000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2687.   if (0x00002000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2688.   if (0x00001000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2689.   if (0x00000800 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2690.   if (0x00000400 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2691.   if (0x00000200 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2692.   if (0x00000100 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2693.   if (0x00000080 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2694.   if (0x00000040 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2695.   if (0x00000020 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2696.   if (0x00000010 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2697.   if (0x00000008 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2698.   if (0x00000004 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2699.   if (0x00000002 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2700.   if (0x00000001 & data) *_iptr     |= dmask; else *_iptr     &= dmaskoff;
  2701. }
  2702.  
  2703.  
  2704.  
  2705.  
  2706. void IFF_HAM6_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize)
  2707. xaUBYTE *out,*in;
  2708. XA_CHDR **chdr;
  2709. ColorReg *h_cmap;
  2710. xaULONG xosize,yosize,xip,yip,xisize;
  2711. {
  2712.   xaULONG xend,y;
  2713.   xaUBYTE *tpic,*optr;
  2714.   xaUSHORT g_adj[16];
  2715.  
  2716.   for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ] >> 8;
  2717.   tpic = (xaUBYTE *)malloc( 3 * xosize * yosize);
  2718.   if (tpic == 0) TheEnd1("IFF_HAM6_As_True: malloc err\n");
  2719.   optr = tpic;
  2720.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2721.   for (y=yip; y < (yip + yosize); y++)
  2722.   {
  2723.     register xaULONG x;
  2724.     register xaUBYTE *i_ptr = (xaUBYTE *)( in + y * xisize );
  2725.     register xaULONG pred,pgrn,pblu,data;
  2726.  
  2727.     pred = pgrn = pblu = 0;
  2728.     for (x=0; x<xend; x++)
  2729.     {
  2730.       data = (xaULONG )(*i_ptr++);
  2731.       switch( (data & 0x30) )
  2732.       {
  2733.         case 0x00: /* use color register given by low */
  2734.           { register xaULONG low;
  2735.             low = data & 0x0f;
  2736.             pred  = g_adj[ h_cmap[low].red   ];
  2737.             pgrn  = g_adj[ h_cmap[low].green ];
  2738.             pblu  = g_adj[ h_cmap[low].blue  ];
  2739.           } break;
  2740.         case 0x10: pblu = g_adj[ (data & 0x0f) ]; break;
  2741.         case 0x20: pred = g_adj[ (data & 0x0f) ]; break;
  2742.         case 0x30: pgrn = g_adj[ (data & 0x0f) ]; break;
  2743.       } 
  2744.       if ( (x >= xip) && (x < xend) )
  2745.       {
  2746.     *optr++ = pred;
  2747.     *optr++ = pgrn;
  2748.     *optr++ = pblu;
  2749.       }
  2750.     } /* end of x */
  2751.   } /* end of y */
  2752.   if (    (cmap_true_to_all == xaTRUE) 
  2753.       || ((cmap_true_to_1st == xaTRUE) && (iff_chdr == 0)) )    
  2754.     iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize,
  2755.                     iff_cmap,&iff_imagec);
  2756.   else if ( (cmap_true_to_332 == xaTRUE) && (iff_chdr == 0) )
  2757.     iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  2758.   else if ( (cmap_true_to_gray == xaTRUE) && (iff_chdr == 0) )
  2759.     iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  2760.  
  2761.   if (cmap_dither_type == CMAP_DITHER_FLOYD)
  2762.         out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,xaTRUE);
  2763.   else
  2764.         out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,xaTRUE);
  2765.   *chdr = iff_chdr; 
  2766. }
  2767.  
  2768. void IFF_HAM8_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize)
  2769. xaUBYTE *out,*in;
  2770. XA_CHDR **chdr;
  2771. ColorReg *h_cmap;
  2772. xaULONG xosize,yosize,xip,yip,xisize;
  2773. {
  2774.   xaULONG xend,y;
  2775.   xaUBYTE *tpic,*optr;
  2776.   xaUSHORT g_adj[64];
  2777.  
  2778.   for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ] >> 8;
  2779.   tpic = (xaUBYTE *)malloc( 3 * xosize * yosize);
  2780.   if (tpic == 0) TheEnd1("IFF_HAM8_As_True: malloc err\n");
  2781.   optr = tpic;
  2782.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2783.   for (y=yip; y < (yip + yosize); y++)
  2784.   {
  2785.     register xaULONG x;
  2786.     register xaUBYTE *i_ptr = (xaUBYTE *)( in + y * xisize );
  2787.     register xaULONG pred,pgrn,pblu,data;
  2788.  
  2789.     pred = pgrn = pblu = 0;
  2790.     for (x=0; x<xend; x++)
  2791.     {
  2792.       data = (xaULONG )(*i_ptr++);
  2793.       switch( (data & 0xc0) )
  2794.       {
  2795.         case 0x00: /* use color register given by low */
  2796.           { register xaULONG low = data & 0x3f;
  2797.             pred  = g_adj[ h_cmap[low].red   ];
  2798.             pgrn  = g_adj[ h_cmap[low].green ];
  2799.             pblu  = g_adj[ h_cmap[low].blue  ];
  2800.           } break;
  2801.         case 0x40: pblu = g_adj[ (data & 0x3f) ]; break;
  2802.         case 0x80: pred = g_adj[ (data & 0x3f) ]; break;
  2803.         case 0xc0: pgrn = g_adj[ (data & 0x3f) ]; break;
  2804.       } 
  2805.       if ( (x >= xip) && (x < xend) )
  2806.       {
  2807.     *optr++ = pred;
  2808.     *optr++ = pgrn;
  2809.     *optr++ = pblu;
  2810.       }
  2811.     } /* end of x */
  2812.   } /* end of y */
  2813.   if (    (cmap_true_to_all == xaTRUE) 
  2814.       || ((cmap_true_to_1st == xaTRUE) && (iff_chdr == 0)) )    
  2815.     iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize,
  2816.                     iff_cmap,&iff_imagec);
  2817.   else if ( (cmap_true_to_332 == xaTRUE) && (iff_chdr == 0) )
  2818.     iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  2819.   else if ( (cmap_true_to_gray == xaTRUE) && (iff_chdr == 0) )
  2820.     iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  2821.  
  2822.   if (cmap_dither_type == CMAP_DITHER_FLOYD)
  2823.         out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,xaTRUE);
  2824.   else
  2825.         out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,xaTRUE);
  2826.   *chdr = iff_chdr; 
  2827. }
  2828.  
  2829.  
  2830. xaULONG
  2831. IFF_Delta_Body(image,delta,dsize,dec_info)
  2832. xaUBYTE *image;         /* Image Buffer. */
  2833. xaUBYTE *delta;         /* delta data. */
  2834. xaULONG dsize;          /* delta size */
  2835. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  2836. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  2837.   xaULONG image_size = imagex * imagey;
  2838.   memcpy( (char *)image, (char *)delta, image_size);
  2839.   dec_info->xs = dec_info->ys = 0;  dec_info->xe = imagex; dec_info->ye = imagey; 
  2840.   return(ACT_DLTA_BODY);
  2841. }
  2842.  
  2843.