home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / space / software / unix / xanim / xanim_ff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-04  |  51.0 KB  |  1,790 lines

  1.  
  2. /*
  3.  * xanim_iff.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * 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 "xanim_iff.h"
  20.  
  21. void IFF_Read_File();
  22. void IFF_Adjust_For_EHB();
  23. void IFF_Adjust_For_HAM();
  24. void IFF_Read_BODY();
  25. LONG IFF_Read_Garb();
  26. void IFF_Print_ID();
  27. void IFF_Deltal();
  28. void IFF_Delta3();
  29. void IFF_Delta5();
  30. LONG IFF_DeltaJ();
  31. void IFF_Byte_Mod();
  32. void IFF_Short_Mod();
  33. void IFF_HAM_To_Bufferable();
  34. LONG Is_IFF_File();
  35. void IFF_Buffer_Action();
  36. ULONG UTIL_Get_MSB_Long();
  37. ULONG UTIL_Get_MSB_Short();
  38. void IFF_Setup_HMAP();
  39. void IFF_Setup_CMAP();
  40.  
  41. void ACT_Get_Next_Action();
  42. void ACT_Setup_MAPPED();
  43. void UTIL_Sub_Image();
  44.  
  45.  
  46. #define HMAP_SIZE 16
  47. #define IFF_SPEED_DEFAULT 3
  48.  
  49. ColorReg iff_cmap[256];
  50.  
  51. static LONG mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  52.  
  53. /*
  54.  *
  55.  */
  56. void IFF_Read_File(fname,anim_hdr)
  57. BYTE *fname;
  58. ANIM_HDR *anim_hdr;
  59. {
  60.   FILE *fin;
  61.   LONG j;
  62.   LONG camg_flag,cmap_flag,ret,compression;
  63.   LONG crng_flag,cmap_action,formtype;
  64.   LONG ansq_flag,ansq_cnt,dlta_cnt;
  65.   LONG body_1,dlta_2;
  66.   LONG bmhd_flag,file_size,file_read;
  67.   Bit_Map_Header bmhd;
  68.   Chunk_Header  chunk;
  69.   Anim_Header   anhd;
  70.   LONG *ansq_dnum,*ansq_tim,*dlta_act;
  71.   LONG prop_flag;
  72.   LONG exit_flag;
  73.   LONG iff_imagex,iff_imagey;
  74.   ACTION *cmap_act;
  75.   Face_Header face;
  76.  
  77.  
  78.   dlta_2 = -2;
  79.   body_1 = -1;
  80.   compression=0;
  81.   anim_flags &= (~ANIM_HAM);
  82.   file_size  = 0;
  83.   file_read  = 0;
  84.   iff_imagex = 0;
  85.   iff_imagey = 0;
  86.   prop_flag  = 0;
  87.   bmhd_flag  = 0;
  88.   crng_flag  = 0;
  89.   camg_flag  = 0;
  90.   cmap_flag  = 0;
  91.   ansq_flag  = 0;
  92.   ansq_cnt   = 0;
  93.   ansq_dnum  = 0;
  94.   ansq_tim   = 0;
  95.   dlta_act   = 0;
  96.   dlta_cnt   = 0;
  97.  
  98.   cmap_action = action_cnt;
  99.   ACT_Get_Next_Action(&cmap_act);
  100.  
  101.   if ( (fin=fopen(fname,"r")) == 0)
  102.   { 
  103.     fprintf(stderr,"can't open %s\n",fname); 
  104.     TheEnd();
  105.   }
  106.  
  107.   exit_flag = 0; 
  108.   while( !feof(fin) && !exit_flag)
  109.   {
  110.     /* read Chunk_Header 
  111.     */
  112.     chunk.id   = UTIL_Get_MSB_Long(fin);
  113.     chunk.size = UTIL_Get_MSB_Long(fin);
  114.  
  115.     if ( feof(fin) ) break;    
  116.     if (chunk.size == -1) ret = -1;
  117.     else ret = 0;
  118.  
  119.     if (debug >= 1) 
  120.     {
  121.       fprintf(stderr,"Chunk.ID = ");
  122.       IFF_Print_ID(stderr,chunk.id);
  123.       fprintf(stderr,"  chunksize=%lx\n",chunk.size);
  124.     }
  125.     if (chunk.size & 1) chunk.size+=1; /* halfword pad it */
  126.     if (ret==0)
  127.     {
  128.       switch(chunk.id)
  129.       {
  130.         case PROP: 
  131.                 prop_flag=1;
  132.         case LIST: 
  133.         case FORM: 
  134.                 formtype = UTIL_Get_MSB_Long(fin);
  135.         file_size = chunk.size;
  136.         file_read = -1;
  137.                 if (debug >= 2) 
  138.                 {
  139.                   fprintf(stderr,"  IFF ",formtype);
  140.                   IFF_Print_ID(stderr,chunk.id);
  141.                   fprintf(stderr," = ");
  142.                   IFF_Print_ID(stderr,formtype);
  143.                   fprintf(stderr,"\n");
  144.                 }
  145.                 break;
  146.         case BMHD:
  147.                 /* read Bit_Map_Header into bmhd */
  148.                 /* read so as to avoid endian problems */
  149.                 bmhd.width              = UTIL_Get_MSB_Short(fin);
  150.                 bmhd.height             = UTIL_Get_MSB_Short(fin);
  151.                 bmhd.x                  = UTIL_Get_MSB_Short(fin);
  152.                 bmhd.y                  = UTIL_Get_MSB_Short(fin);
  153.                 bmhd.depth              = fgetc(fin);
  154.                 bmhd.masking            = fgetc(fin);
  155.                 bmhd.compression        = fgetc(fin);
  156.                 bmhd.pad1               = fgetc(fin);
  157.                 bmhd.transparentColor   = UTIL_Get_MSB_Short(fin);
  158.                 bmhd.xAspect            = fgetc(fin);
  159.                 bmhd.yAspect            = fgetc(fin);
  160.                 bmhd.pageWidth          = UTIL_Get_MSB_Short(fin);
  161.                 bmhd.pageHeight         = UTIL_Get_MSB_Short(fin);
  162.                 if (verbose)
  163.                 {
  164.                  fprintf(stderr,"     Size %ldx%ldx%ld comp=%ld masking=%ld\n",
  165.                                 bmhd.width,bmhd.height,bmhd.depth,
  166.                                 bmhd.compression,bmhd.masking);
  167.                 }
  168.                 imagex = bmhd.width;
  169.                 imagey = bmhd.height;
  170.                 imaged = bmhd.depth;
  171.                 if (imagex > iff_imagex) iff_imagex = imagex;
  172.                 if (imagey > iff_imagey) iff_imagey = imagey;
  173.                 bmhd_flag=1;
  174.                 break;
  175.         case FACE:
  176.                 /* read Face_Header into face */
  177.                 /* read so as to avoid endian problems */
  178.                 face.width              = UTIL_Get_MSB_Short(fin);
  179.                 face.height             = UTIL_Get_MSB_Short(fin);
  180.                 face.x                  = UTIL_Get_MSB_Short(fin);
  181.                 face.y                  = UTIL_Get_MSB_Short(fin);
  182.                 face.xoff               = UTIL_Get_MSB_Short(fin);
  183.                 face.yoff               = UTIL_Get_MSB_Short(fin);
  184.                 if (verbose)
  185.                 {
  186.                   fprintf(stderr,"     Size %ldx%ld %ldx%ld %ldx%ld\n",
  187.                         face.width,face.height,
  188.                         face.x,face.y,face.xoff,face.yoff );
  189.                 }
  190.                 imagex = face.width;
  191.                 imagey = face.height;
  192.                 if (imagex > iff_imagex) iff_imagex = imagex;
  193.                 if (imagey > iff_imagey) iff_imagey = imagey;
  194.                 switch(imagec)
  195.                 {
  196.                   case  2: imaged = 1; break;
  197.                   case  4: imaged = 2; break;
  198.                   case  8: imaged = 3; break;
  199.                   case 16: imaged = 4; break;
  200.                   case 32: imaged = 5; break;
  201.                   case 64: imaged = 6; break;
  202.                   default: 
  203.                         fprintf(stderr,"IFF Face error imagec=%ld \n",imagec);
  204.                         fprintf(stderr,"         camg_flag=%ld \n",camg_flag);
  205.                         fprintf(stderr,"         cmap_flag=%ld \n",cmap_flag);
  206.                         TheEnd();
  207.                 }
  208.                 bmhd.width       = imagex;
  209.                 bmhd.height      = imagey;
  210.                 bmhd.depth       = imaged;
  211.                 bmhd.compression = BMHD_COMP_BYTERUN;
  212.                 bmhd.masking     = BMHD_MSK_NONE;
  213.  
  214.                 action[action_cnt].data =
  215.                                 (UBYTE *) malloc( sizeof(SIZE_HDR) );
  216.                 if (action[action_cnt].data == 0)
  217.                                 TheEnd1("IFF_Read_FACE: malloc failed\n");
  218.                 action[action_cnt].type = ACT_SIZE;
  219.                 action[action_cnt].time = 0;
  220.                 { 
  221.                   SIZE_HDR *size_hdr;
  222.                   size_hdr = (SIZE_HDR *)action[action_cnt].data;
  223.                   size_hdr->imagex = imagex;
  224.                   size_hdr->imagey = imagey;
  225.                   size_hdr->xoff = face.x + face.xoff;
  226.                   size_hdr->yoff = face.y + face.yoff;
  227.                 } 
  228.                 action_cnt++;
  229.                 break;
  230.  
  231.         case CAMG:
  232.                 {
  233.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CAMG\n");
  234.                   if (chunk.size != 4) 
  235.                   {
  236.                     ret = IFF_Read_Garb(fin,chunk.size);
  237.                     break;
  238.                   }
  239.  
  240.                   camg_flag = UTIL_Get_MSB_Long(fin);
  241.  
  242.                   if ((camg_flag & 0x80) && (cmap_flag))  
  243.                   {
  244.                     IFF_Adjust_For_EHB( iff_cmap );
  245.                     IFF_Setup_CMAP(cmap_act,iff_cmap,imagec);
  246.                     break;
  247.                   }
  248.  
  249.                   if ((camg_flag & 0x800) && (cmap_flag)) 
  250.                   {
  251.                     ACTION *act;
  252.  
  253.                     IFF_Adjust_For_HAM( iff_cmap );
  254.                     IFF_Setup_CMAP(cmap_act,iff_cmap,imagec);
  255.                     anim_flags |= ANIM_HAM;
  256.  
  257.                         /* CREATE ACT_IFF_HMAP chunk */
  258.                     ACT_Get_Next_Action(&act);
  259.                     IFF_Setup_HMAP(act,ham_map);
  260.                     break;
  261.                   }
  262.                 }
  263.                 break;
  264.  
  265.         case CMAP:
  266.                 {
  267.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CMAP\n");
  268.  
  269.                   if (chunk.size == 0x40) imagec = chunk.size/2; /* R+GB */
  270.                   else imagec = chunk.size / 3;  /* R+G+B 1 byte each */
  271.  
  272.                   if (chunk.size == 0x40)
  273.                   {
  274.                     LONG i,d;
  275.                     for(i=0; i<imagec; i++)
  276.                     {
  277.                       d = fgetc(fin);
  278.                       iff_cmap[i].red   = ((d<<4) | 0x0f) & 0xff;
  279.                       d = fgetc(fin);
  280.                       iff_cmap[i].green = ( d     | 0x0f) & 0xff;
  281.                       iff_cmap[i].blue  = ((d<<4) | 0x0f) & 0xff;
  282.                     }
  283.                   }
  284.                   else 
  285.                   {
  286.                     LONG i;
  287.                     for(i=0;i<imagec;i++)
  288.                     {
  289.                       iff_cmap[i].red   = (fgetc(fin) | 0x0f) & 0xff;
  290.                       iff_cmap[i].green = (fgetc(fin) | 0x0f) & 0xff;
  291.                       iff_cmap[i].blue  = (fgetc(fin) | 0x0f) & 0xff;
  292.                     }
  293.                   }
  294.  
  295.                   /* Typically imaged matches imagec but not always 
  296.                    */
  297.                   if (bmhd_flag)
  298.                   {
  299.                     switch(imaged)
  300.                     {
  301.                       case  1: imagec =   2; break;
  302.                       case  2: imagec =   4; break;
  303.                       case  3: imagec =   8; break;
  304.                       case  4: imagec =  16; break;
  305.                       case  5: imagec =  32; break;
  306.                       case  6: imagec =  64; break;
  307.                       case  7: imagec = 128; break;
  308.                       case  8: imagec = 256; break;
  309.                     }
  310.                   }
  311.  
  312.                   if (camg_flag & 0x80)  IFF_Adjust_For_EHB(iff_cmap);
  313.                   else if (camg_flag & 0x800) 
  314.                   {
  315.                     ACTION *act;
  316.                     IFF_Adjust_For_HAM( iff_cmap );
  317.                     anim_flags |= ANIM_HAM;
  318.                     ACT_Get_Next_Action(&act);
  319.                     IFF_Setup_HMAP(act,ham_map);
  320.                   }
  321.  
  322.                   if (cmap_flag)
  323.                   {
  324.                     ACTION *act;
  325.                     ACT_Get_Next_Action(&act);
  326.                     IFF_Setup_CMAP(act,iff_cmap,imagec);
  327.                   }
  328.                   else 
  329.                     IFF_Setup_CMAP(cmap_act,iff_cmap,imagec);
  330.                   cmap_flag = 1;
  331.                 }
  332.                 break;
  333.  
  334.         case BODY:
  335.                 DEBUG_LEVEL2 fprintf(stderr,"IFF BODY\n");
  336.                 dlta_cnt++;
  337.                 if (body_1 == -1) body_1 = action_cnt;
  338.                 action[action_cnt].data = 
  339.                                 (UBYTE *) malloc( imagex * imagey );
  340.                 if (action[action_cnt].data == 0) 
  341.                                 TheEnd1("IFF_Read_BODY: malloc failed\n");
  342.                 action[action_cnt].type = ACT_IFF_BODY;
  343.                 if (jiffy_flag) action[action_cnt].time = jiffy_flag;
  344.                 else action[action_cnt].time = 
  345.                         IFF_SPEED_DEFAULT * MS_PER_60HZ;
  346.  
  347.                 IFF_Read_BODY(fin,action[action_cnt].data,chunk.size,
  348.                                 (int)(bmhd.compression),(int)(bmhd.masking));
  349.                 action_cnt++;
  350.                 break;
  351.  
  352.         case ANHD:
  353.                 {
  354.                  int i;
  355.                  DEBUG_LEVEL2 fprintf(stderr,"IFF ANHD\n");
  356.  
  357.                  if (chunk.size >= Anim_Header_SIZE)
  358.                  {
  359.                   anhd.op               = fgetc(fin);
  360.                   anhd.mask             = fgetc(fin);
  361.                   anhd.w                = UTIL_Get_MSB_Short(fin);
  362.                   anhd.h                = UTIL_Get_MSB_Short(fin);
  363.                   anhd.x                = UTIL_Get_MSB_Short(fin);
  364.                   anhd.y                = UTIL_Get_MSB_Short(fin);
  365.                   anhd.abstime          = UTIL_Get_MSB_Long(fin);
  366.                   anhd.reltime          = UTIL_Get_MSB_Long(fin);
  367.                   anhd.interleave       = fgetc(fin);
  368.                   anhd.pad0             = fgetc(fin);
  369.                   anhd.bits             = UTIL_Get_MSB_Long(fin);
  370.                   fread((BYTE *)(anhd.pad),1,16,fin); /* read pad */
  371.                   i = Anim_Header_SIZE;
  372.                   while(i < chunk.size) {fgetc(fin); i++;}
  373.  
  374.                   compression = anhd.op;
  375.                  }
  376.                  else 
  377.                  {
  378.                   IFF_Read_Garb(fin,chunk.size); 
  379.                   compression = 0xffffffff;
  380.                   fprintf(stderr,"ANHD chunksize mismatch %ld\n",chunk.size);
  381.                  }
  382.                 }
  383.                 break;
  384.  
  385.         case DLTA:
  386.                 {
  387.                  DEBUG_LEVEL2 fprintf(stderr,"IFF DLTA: ");
  388.                  dlta_cnt++;
  389.                  if (dlta_2 == -1) dlta_2 = action_cnt; /* 2nd DLTA */
  390.                  if (dlta_2 == -2) dlta_2 = -1;  /* 1st DLTA */
  391.                  action[action_cnt].data = (UBYTE *) malloc(chunk.size);
  392.                  if (action[action_cnt].data == 0) 
  393.                         TheEnd1("IFF_Read_DLTA: malloc failed");
  394.                  ret=fread(action[action_cnt].data,chunk.size,1,fin);
  395.  
  396.                  switch(compression)
  397.                  {
  398.                   case 5:
  399.                         DEBUG_LEVEL2 fprintf(stderr,"type 5\n");
  400.                         action[action_cnt].type = ACT_IFF_DLTA5;
  401.                         break;
  402.                   case   3:
  403.                         DEBUG_LEVEL2 fprintf(stderr,"type 3\n");
  404.                         action[action_cnt].type = ACT_IFF_DLTA3;
  405.                         break;
  406.                   case 'J':
  407.                         DEBUG_LEVEL2 fprintf(stderr,"type J\n");
  408.                         action[action_cnt].type = ACT_IFF_DLTAJ;
  409.                         break;
  410.                   case  108:
  411.                         DEBUG_LEVEL2 fprintf(stderr,"type l\n");
  412.                         action[action_cnt].type = ACT_IFF_DLTAl;
  413.                         break;
  414.                   case   0:
  415.                   case   1:
  416.                   case   2:
  417.                   case   4:
  418.                   default:  
  419.                         action[action_cnt].type = ACT_NOP;
  420.                         fprintf(stderr,"Unimplemented Delta %ld\n",compression);
  421.                         break;
  422.                  }
  423.                  if (jiffy_flag) action[action_cnt].time = jiffy_flag;
  424.                  else action[action_cnt].time = 
  425.                         IFF_SPEED_DEFAULT * MS_PER_60HZ;
  426.                  action_cnt++;
  427.                 }
  428.                 break;
  429.  
  430.         case ANSQ:
  431.                {
  432.                 ULONG i;
  433.                 UBYTE *p;  /* data is actually big endian USHORT */
  434.                 BYTE *garb;
  435.  
  436.                 DEBUG_LEVEL2 fprintf(stderr,"IFF ANSQ\n");
  437.                 ansq_flag = 1;  /* we found an ansq chunk */
  438.                 ansq_cnt = chunk.size / 4;
  439.                 ansq_cnt = ansq_cnt + 1; /* adding dlta 0 up front */
  440.  
  441.                 DEBUG_LEVEL2 fprintf(stderr,
  442.             "    ansq_cnt=%ld dlta_cnt=%ld\n",ansq_cnt,dlta_cnt);
  443.  
  444.                 /* allocate space for ansq variables 
  445.                  */
  446.                 ansq_dnum = (LONG *)malloc( ansq_cnt * sizeof(LONG));
  447.                 ansq_tim  = (LONG *)malloc( ansq_cnt * sizeof(LONG));
  448.                 if ( (ansq_dnum==NULL) || (ansq_tim==NULL)) 
  449.                     TheEnd1("ansq can't malloc dnum and tim arrays\0");
  450.                 if (verbose) fprintf(stderr,
  451.                         "     frames=%ld dlts=%d comp=%ld\n",
  452.                                 ansq_cnt,dlta_cnt,compression);
  453.  
  454.                 garb = (BYTE *)malloc(chunk.size);
  455.                 if (garb==0)
  456.                       {fprintf(stderr,"ansq malloc not enough\n"); TheEnd();}
  457.                 fread(garb,chunk.size,1,fin);
  458.                 p = (UBYTE *)(garb);
  459.  
  460.                 /* first delta is only used once and doesn't appear in 
  461.                  * the ANSQ 
  462.                  */
  463.                 ansq_dnum[0] = 0; 
  464.                 ansq_tim[0]  = 1;
  465.                 for(i=1;i<ansq_cnt;i++)
  466.                 {
  467.                   /* this is delta to apply */
  468.                   ansq_dnum[i] = (*p++)<<8; ansq_dnum[i] |= (*p++);
  469.  
  470.                   /* this is jiffy count or if 0xffff then a goto */
  471.                   ansq_tim[i] = (*p++)<<8;  ansq_tim[i] |= (*p++);
  472.  
  473.                   DEBUG_LEVEL2 
  474.                        fprintf(stderr,"<%ld %ld> ",ansq_dnum[i], ansq_tim[i]);
  475.                 }
  476.                 free(garb);
  477.                }
  478.                break;
  479.  
  480.         case CRNG: 
  481.                 DEBUG_LEVEL2 fprintf(stderr,"IFF CRNG\n");
  482.                 {
  483.                  CRNG_HDR *crng_ptr;
  484.  
  485.                  /* is the chunk the correct size ?
  486.                   */
  487.                  if (chunk.size == CRNG_HDR_SIZE)
  488.                  {
  489.                    /* allocate space and read CRNG chunk 
  490.                     */
  491.                    crng_ptr = (CRNG_HDR *)malloc( sizeof(CRNG_HDR) );
  492.                    if (crng_ptr == 0) 
  493.                                 TheEnd1("IFF_Read_CRNG: malloc failed");
  494.                    action[action_cnt].data = (UBYTE *) crng_ptr;
  495.                    crng_ptr->pad1   = UTIL_Get_MSB_Short(fin);
  496.                    crng_ptr->rate   = UTIL_Get_MSB_Short(fin);
  497.                    crng_ptr->active = UTIL_Get_MSB_Short(fin);
  498.                    crng_ptr->low    = fgetc(fin);
  499.                    crng_ptr->high   = fgetc(fin);
  500.  
  501.                    /* make it an action only if its valid 
  502.                     */
  503.                    if (   (crng_ptr->active & CRNG_ACTIVE)
  504.                        && (crng_ptr->low < crng_ptr->high)
  505.                        && (crng_ptr->rate != 0)
  506.                       )
  507.                    {
  508.                      crng_flag++;
  509.                      action[action_cnt].type = ACT_IFF_CRNG;
  510.                      action[action_cnt].time = 0;
  511.                      action_cnt++;
  512.                    }
  513.                    else 
  514.                    {
  515.                      free(crng_ptr);
  516.                      DEBUG_LEVEL2 fprintf(stderr,"CRNG not used\n");
  517.                    }
  518.                  }
  519.                  else
  520.                  {
  521.                     IFF_Read_Garb(fin,chunk.size); 
  522.                     fprintf(stderr,"CRNG chunksize mismatch %ld\n",chunk.size);
  523.                  }
  524.                 }
  525.                 break;
  526.  
  527.         case DPI : /* ignore */
  528.         case IMRT: /* ignore */
  529.         case GRAB: /* ignore */
  530.         case DPPS: /* ignore */
  531.         case DPPV: /* ignore */
  532.         case DPAN: /* ignore */
  533.         case DRNG: /* ignore */
  534.         case VHDR: /* sound ignore should kill next body until bmhd*/
  535.         case ANNO: /* sound ignore */
  536.         case CHAN: /* sound ignore */
  537.                 ret = IFF_Read_Garb(fin,chunk.size);
  538.                 break;
  539.     default:
  540.     if ( feof(fin) ) exit_flag = 1;   /* end of file */
  541.     else
  542.     {
  543.       fprintf(stderr,"unknown IFF type="); IFF_Print_ID(stderr,chunk.id);
  544.       if (   (file_read < file_size)    /* there should be more  */
  545.           && (chunk.size < (file_size - file_read) ) /*  size n 2 big */
  546.          )
  547.       {
  548.         fprintf(stderr,"  Will Continue.\n");
  549.         ret = IFF_Read_Garb(fin,chunk.size);
  550.       }
  551.       else
  552.       {
  553.         fprintf(stderr,"  Will Abort.\n");
  554.         exit_flag = 1;
  555.       }
  556.     }
  557.     break;
  558.    } /* end chunk switch */
  559.    /*
  560.     * keep track of number of bytes read. This allows us to distinguish
  561.     * valid unknown chunks from garbage tacked to the end of a file.
  562.     */
  563.    if (!exit_flag)
  564.    {
  565.      if (file_read == -1) file_read = 4; /* assuming FORM chunk or similar */
  566.      else file_read += chunk.size + 8; /* add ID and SIZE of other chunks */
  567.    }
  568.  
  569.   } /* end if ret==0 */
  570.  } /* end of while not eof or exit_flag */
  571.  DEBUG_LEVEL2 fprintf(stderr,"Bytes Read = %lx\n",file_read);
  572.  fclose(fin);
  573.  
  574.  if (ansq_flag)
  575.  {
  576.    LONG i;
  577.  
  578.    /* 
  579.     * Set up a map of delta's to their action numbers.
  580.     */
  581.    dlta_act = (LONG *)malloc( sizeof(int) * dlta_cnt );
  582.    j=0;
  583.    for(i=action_start; i < action_cnt; i++)
  584.    {
  585.     switch(action[i].type)
  586.     {
  587.      case ACT_IFF_BODY:
  588.      case ACT_IFF_DLTA1:
  589.      case ACT_IFF_DLTA2:
  590.      case ACT_IFF_DLTA3:
  591.      case ACT_IFF_DLTA4:
  592.      case ACT_IFF_DLTA5:
  593.      case ACT_IFF_DLTAJ:
  594.                            dlta_act[j] = i; j++;
  595.                            break;
  596.     }
  597.    }
  598.    DEBUG_LEVEL1 fprintf(stderr,"%ld dltas found\n",j);
  599.    /* NOTE: since we're treating the BODY as a delta, the ansq's will be
  600.     *   one off 
  601.     */
  602.  
  603.    /* +2 is for cmap up front and frame termination at end */
  604.    anim_hdr->frame_lst = (LONG *)malloc(sizeof(int) * (ansq_cnt+2));
  605.    if (anim_hdr->frame_lst == NULL) 
  606.              TheEnd1("IFF ANSQ: couldn't malloc for frame_lst\0");
  607.  
  608.        /* loop frame is the 2nd delta */
  609.                 anim_hdr->loop_frame = body_1 - action_start;
  610.    anim_hdr->loop_frame = dlta_2 - action_start;  
  611.    anim_hdr->frame_lst[0] = cmap_action;  /* cmap action */
  612.    j=1;
  613.    for(i=action_start; i<= body_1; i++)
  614.    {
  615.     anim_hdr->frame_lst[j] = i;  /* take care of frame up to body_1 */
  616.     j++;
  617.    }
  618.     
  619.    for(i=0;i<ansq_cnt;i++)
  620.    {
  621.      /* Goto */
  622.      if (ansq_tim[i] == 0xffff)
  623.      {
  624.       anim_hdr->loop_frame = j + ansq_dnum[i]; /* cmap, body */
  625. /* NOTE:
  626.       anim_hdr->frame_lst[i+j] = -1;
  627. */
  628.      }
  629.      else /* delta to use */
  630.      {
  631.       anim_hdr->frame_lst[i+j] = dlta_act[ ansq_dnum[i]+1 ];
  632.       /* the +1 below is because the ansq chunk ignores the body */
  633.       if (jiffy_flag) action[ dlta_act[ ansq_dnum[i]+1 ] ].time = jiffy_flag;
  634.       else action[ dlta_act[ ansq_dnum[i]+1 ] ].time = 
  635.                         ansq_tim[i] * MS_PER_60HZ;
  636.      } 
  637.    } /* end of for ansq_cnt */
  638.    anim_hdr->frame_lst[ansq_cnt+j] = -1;
  639.    anim_hdr->last_frame = ansq_cnt + j - 1;
  640.   }
  641.    /* no ansq chunk */
  642.   else
  643.   {
  644.     LONG frame_num,ii;
  645.  
  646.     frame_num = action_cnt - action_start;
  647.     anim_hdr->frame_lst = (LONG *)malloc(sizeof(int) * (frame_num+1));
  648.     if (anim_hdr->frame_lst == NULL)
  649.              TheEnd1("IFF: couldn't malloc for frame_lst\0");
  650.     for(ii=0; ii < frame_num; ii++)
  651.            anim_hdr->frame_lst[ii]=action_start+ii;
  652.  
  653.     /* loop frame is the 2nd delta or 1st body if not two deltas 
  654.      * or if ANIM_NOLOP set
  655.      */
  656.     if ( (dlta_2 < 0) || (anim_flags & ANIM_NOLOP) )
  657.                 anim_hdr->loop_frame = body_1 - action_start;
  658.     else 
  659.                 anim_hdr->loop_frame = dlta_2 - action_start;
  660.  
  661.     anim_hdr->frame_lst[frame_num] = -1;
  662.     anim_hdr->last_frame = frame_num - 1;
  663.     if (verbose) fprintf(stderr,"     dlta_cnt=%ld comp=%ld\n",
  664.                                                 dlta_cnt,compression);
  665.   }
  666.  
  667.   if (ansq_dnum) free(ansq_dnum); 
  668.   if (ansq_tim ) free(ansq_tim ); 
  669.   if (dlta_act ) free(dlta_act ); 
  670.   imagex = iff_imagex;
  671.   imagey = iff_imagey;
  672.  
  673.   if ( (dlta_cnt == 1) && (crng_flag) ) anim_flags |= ANIM_CYCLE;
  674.   else anim_flags &= (~ANIM_CYCLE);
  675. }
  676.  
  677.  
  678. /*
  679.  *
  680.  */
  681. void IFF_Adjust_For_EHB(colormap)
  682. ColorReg colormap[];
  683. {
  684.   LONG i;
  685.  
  686.   DEBUG_LEVEL1 
  687.     fprintf(stderr,"Adjusting CMAP for Amiga Extra Half-Brite Mode\n");
  688.   for(i=0;i<32;i++)
  689.   {
  690.     colormap[i+32].red   = colormap[i].red   >> 2;
  691.     colormap[i+32].green = colormap[i].green >> 2;
  692.     colormap[i+32].blue  = colormap[i].blue  >> 2;
  693.   }
  694.   imagec = 64;
  695. }
  696.  
  697.  
  698. /*
  699.  *
  700.  */
  701. void IFF_Adjust_For_HAM(colormap)
  702. ColorReg colormap[];
  703. {
  704.   LONG i;
  705.   DEBUG_LEVEL1 
  706.     fprintf(stderr,"Adjusting CMAP for Amiga Hold And Modify Mode\n");
  707.  
  708.   /* save original color registers - will be need later */
  709.   for(i=0;i<HMAP_SIZE;i++)
  710.   {
  711.     ham_map[i].red   = colormap[i].red;
  712.     ham_map[i].green = colormap[i].green;
  713.     ham_map[i].blue  = colormap[i].blue;
  714.   }
  715.  
  716.   /* generate kludged color map */
  717.   /* basically 3 bits red, 3 bits green and 2 bits blue */
  718.   for(i=0;i<256;i++)
  719.   {
  720.     colormap[i].red   = ( ((i>>5) & 0x07) << 5 ) | 0x1f;
  721.     colormap[i].green = ( ((i>>2) & 0x07) << 5 ) | 0x1f;
  722.     colormap[i].blue  = ( (i & 0x03)      << 6 ) | 0x3f;
  723.   }
  724.   imagec = 256;
  725. }
  726.  
  727.  
  728. /*
  729.  *
  730.  */
  731. void IFF_Read_BODY(fin,image_out,bodysize,compression,masking)
  732. FILE *fin;
  733. UBYTE *image_out;
  734. LONG bodysize,compression,masking;
  735. {
  736.  LONG i,ret,x,y,d,dmask,tmp,rowsize;
  737.  LONG imagex_pad;
  738.  BYTE *inbuff,*rowbuff,*sptr;
  739.  BYTE *sbuff,*dbuff;
  740.  
  741.  if (   (compression != BMHD_COMP_NONE) 
  742.      && (compression != BMHD_COMP_BYTERUN) 
  743.     ) TheEnd1("IFF_Read_Body: unsupported compression");
  744.  
  745.  if (   (masking != BMHD_MSK_NONE)
  746.      && (masking != BMHD_MSK_HAS)
  747.      && (masking != BMHD_MSK_TRANS)
  748.     ) TheEnd1("IFF_Read_Body: unsupported masking");
  749.  
  750.  inbuff = (BYTE *)malloc(bodysize);
  751.  if (inbuff == 0) TheEnd1("IFF_Read_Body: malloc failed");
  752.  ret=fread(inbuff,bodysize,1,fin);
  753.  if (ret!=1) TheEnd1("IFF_Read_Body: read of BODY chunk failed");
  754.  sbuff = inbuff;
  755.  
  756.  rowbuff = (BYTE *)malloc( imagex );
  757.  if (rowbuff == 0) TheEnd1("IFF_Read_Body: malloc failed");
  758.  
  759.  if (x11_display_type == PSEUDO_COLOR)
  760.  {
  761.    i =  (1 << imaged) - 1;
  762.    dmask = ~i;
  763.    memset(image_out,dmask & 0xff,(imagex * imagey));
  764.    dmask = 1;
  765.  }
  766.  else memset(image_out,0x00,(imagex * imagey));
  767.  
  768.  if (compression==BMHD_COMP_NONE) sptr = inbuff;
  769.  
  770.  /* width is rounded to multiples of 16 in the BODY form */
  771.  /* extra bits are ignored upon reading */
  772.  imagex_pad = imagex % 16;
  773.  if (imagex_pad) imagex_pad = imagex + 16 - imagex_pad;
  774.  else imagex_pad = imagex;
  775.  
  776.  for(y=0; y<imagey; y++)
  777.  {
  778.   tmp = y * imagex;
  779.   dmask=1;
  780.   for(d=0; d<imaged; d++)
  781.   {
  782.  
  783.    if (compression == BMHD_COMP_BYTERUN)
  784.    {
  785. /* Question */
  786. /* imagex_pad OR imagex. Need compressed file the is not a multipleof 16 */
  787.     rowsize = imagex_pad / 8; 
  788.  
  789.     dbuff = rowbuff;
  790.     ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  791.     if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); TheEnd();}
  792.     sptr = rowbuff;
  793.    }
  794.  
  795.    for(x=0; x<imagex; x+=8)
  796.    {
  797.     for(i=0; i<8; i++) if (mask[i] & (*sptr)) image_out[tmp+x+i] |= dmask;
  798.     sptr++;
  799.    }
  800.    if (imagex_pad >= (imagex+8)) sptr++;
  801.  
  802.    dmask <<= 1;
  803.   } /* end of depth loop */
  804.  
  805.   if (masking == BMHD_MSK_HAS)
  806.   {
  807.    /* read the mask row and then throw out for now */
  808.    if (compression == BMHD_COMP_BYTERUN)
  809.    {
  810.     rowsize = imagex_pad / 8;
  811.     dbuff = rowbuff;
  812.     ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  813.     if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); TheEnd();}
  814.    }
  815.    else sptr += imagex/8;
  816.   }
  817.  } /* end of y loop */
  818.  free(inbuff);
  819.  free(rowbuff);
  820. }
  821.  
  822.  
  823. /*
  824.  *
  825.  */
  826. LONG IFF_Read_Garb(fp,size)
  827. FILE *fp;
  828. LONG size;
  829. {
  830.  BYTE *garb;
  831.  
  832.  garb = (BYTE *)malloc(size);
  833.  if (garb==0)
  834.  { fprintf(stderr,"readgarb malloc err size=%ld",size); return(-1);}
  835.  fread(garb,size,1,fp);
  836.  free(garb);
  837.  return(0);
  838. }
  839.  
  840. void IFF_Print_ID(fout,id)
  841. FILE *fout;
  842. LONG id;
  843. {
  844.  fprintf(fout,"%c",     ((id >> 24) & 0xff)   );
  845.  fprintf(fout,"%c",     ((id >> 16) & 0xff)   );
  846.  fprintf(fout,"%c",     ((id >>  8) & 0xff)   );
  847.  fprintf(fout,"%c(%lx)", (id        & 0xff),id);
  848. }
  849.  
  850.  
  851. /* 
  852.  *
  853.  */
  854. void IFF_Delta5(fptr,deltaptr,xs,ys,xe,ye)
  855. UBYTE *fptr;
  856. UBYTE *deltaptr;
  857. ULONG *xs,*ys,*xe,*ye;
  858. {
  859.  register LONG i,col,depth,dmask;
  860.  register LONG rowsize,width;
  861.  ULONG poff;
  862.  register UBYTE *imageptr;
  863.  register UBYTE *dptr,opcnt,op,cnt,data;
  864.  LONG miny,minx,maxy,maxx;
  865.  
  866.  /* set to opposites for min/max testing */
  867.  *xs = imagex;
  868.  *ys = imagey;
  869.  *xe = 0;
  870.  *ye = 0;
  871.  
  872.  imageptr = fptr;
  873.  width = imagex;
  874.  rowsize = width / 8;
  875.  dmask = 1;
  876.  for(depth=0; depth<imaged; depth++)
  877.  {
  878.   minx = -1;
  879.   maxx = -1;
  880.   
  881.   imageptr = fptr;
  882.   /* offset into delt chunk */
  883.   poff  = (deltaptr[ 4 * depth    ]) << 24;
  884.   poff |= (deltaptr[ 4 * depth + 1]) << 16;
  885.   poff |= (deltaptr[ 4 * depth + 2]) <<  8;
  886.   poff |= (deltaptr[ 4 * depth + 3]);
  887.  
  888.   if (poff)
  889.   {
  890.    dptr = (UBYTE *)((ULONG)(deltaptr) + poff);
  891.    for(col=0;col<rowsize;col++)
  892.    {
  893.     imageptr = (UBYTE *)((ULONG)(fptr) + col * 8); /* start at top of column */
  894.     opcnt = *dptr++;  /* get number of ops for this column */
  895.     
  896.     miny = -1;
  897.     maxy = -1;
  898.  
  899.     while(opcnt)    /* execute ops */
  900.     {
  901.        /* keep track of min and max columns */
  902.        if (minx == -1) minx = col * 8;
  903.        maxx = (col * 8) + 7;  
  904.  
  905.        op = *dptr++;   /* get op */
  906.      
  907.        if (op & 0x80)    /* if type uniqe */
  908.        {
  909.           if (miny == -1) miny=( (ULONG)imageptr - (ULONG)fptr ) / width;
  910.           cnt = op & 0x7f;         /* get cnt */
  911.       
  912.           for(i=0;i<cnt;i++)       /* loop through data */
  913.           {
  914.              data = *dptr++;
  915.              IFF_Byte_Mod(imageptr,data,dmask,0);
  916.              imageptr += width;
  917.           }
  918.         } /* end unique */
  919.         else
  920.         {
  921.            if (op == 0)   /* type same */
  922.            {
  923.               if (miny == -1) miny=( (ULONG)imageptr - (ULONG)fptr ) / width;
  924.               cnt = *dptr++;
  925.               data = *dptr++;
  926.  
  927.               for(i=0;i<cnt;i++)       /* loop through data */
  928.               { 
  929.                  IFF_Byte_Mod(imageptr,data,dmask,0);
  930.                  imageptr += width;
  931.               }
  932.             } /* end same */
  933.             else
  934.             {
  935.                imageptr += (width * op);  /* type skip */
  936.             }
  937.          } /* end of hi bit clear */
  938.        opcnt--;
  939.      } /* end of while opcnt */
  940.      maxy = ( (ULONG)imageptr -(ULONG)fptr ) / width;
  941.      if ( (miny>=0) && (miny < *ys)) *ys = miny;
  942.      if ( (maxy>=0) && (maxy > *ye)) *ye = maxy;
  943.     } /* end of column loop */
  944.    } /* end of valid pointer for this plane */
  945.    dmask <<= 1;
  946.    if ( (minx>=0) && (minx < *xs)) *xs = minx;
  947.    if ( (maxx>=0) && (maxx > *xe)) *xe = maxx;
  948.   } /* end of for depth */
  949.  
  950.   if (optimize_flag == TRUE)
  951.   {
  952.     if (*xs >= imagex) *xs = 0;
  953.     if (*ys >= imagey) *ys = 0;
  954.     if (*xe <= 0)      *xe = imagex;
  955.     if (*ye <= 0)      *ye = imagey;
  956.   }
  957.   else
  958.   {
  959.     *xs = 0;      *ys = 0;
  960.     *xe = imagex; *ye = imagey;
  961.   }
  962.  
  963. } /* end of routine */
  964.  
  965. /*
  966.  * 
  967.  */
  968. void IFF_Delta3(fptr,deltaptr)
  969. UBYTE *fptr;
  970. UBYTE *deltaptr;
  971. {
  972.  register LONG i,depth,dmask;
  973.  ULONG poff;
  974.  register SHORT  offset;
  975.  register USHORT s,data;
  976.  register UBYTE  *imageptr,*dptr;
  977.  
  978.  imageptr = fptr;
  979.  dmask = 1;
  980.  for(depth=0;depth<imaged;depth++)
  981.  {
  982.   imageptr = fptr;
  983.  
  984.   /*poff = planeoff[depth];*/ /* offset into delt chunk */
  985.  
  986.   poff  = (deltaptr[ 4 * depth    ]) << 24;
  987.   poff |= (deltaptr[ 4 * depth + 1]) << 16;
  988.   poff |= (deltaptr[ 4 * depth + 2]) <<  8;
  989.   poff |= (deltaptr[ 4 * depth + 3]);
  990.  
  991.   if (poff)
  992.   {
  993.    dptr = (UBYTE *)( (ULONG)(deltaptr) + poff);
  994.    while( (dptr[0] != 0xff) || (dptr[1] != 0xff) )
  995.    {
  996.      offset = (*dptr++)<<8; offset |= (*dptr++);
  997.      if (offset >= 0)
  998.      {
  999.       data = (*dptr++)<<8; data |= (*dptr++);
  1000.       imageptr += 16 * (ULONG)(offset);
  1001.       IFF_Short_Mod(imageptr,data,dmask,0);
  1002.      } /* end of pos */
  1003.      else
  1004.      {
  1005.       imageptr += 16 * (ULONG)(-(offset+2));
  1006.       s = (*dptr++)<<8; s |= (*dptr++); /* size of next */
  1007.       for(i=0; i < (ULONG)s; i++)
  1008.       {
  1009.        data = (*dptr++)<<8; data |= (*dptr++);
  1010.        imageptr += 16;
  1011.        IFF_Short_Mod(imageptr,data,dmask,0);
  1012.       }
  1013.     }  /* end of neg */
  1014.    } /* end of delta for this plane */
  1015.   } /* plane has changed data */
  1016.   dmask <<= 1;
  1017.  } /* end of d */
  1018. }
  1019.  
  1020. /* 
  1021.  *  NOTE: optimize
  1022.  */
  1023. void IFF_Byte_Mod(iptr,data,dmask,xorflag)
  1024. register BYTE *iptr;
  1025. register UBYTE data;
  1026. ULONG dmask;
  1027. register ULONG xorflag;
  1028. {
  1029.  register LONG i,rmask;
  1030.  register UBYTE dmskoff,dmskon;
  1031.  
  1032.  dmskon = dmask;
  1033.  dmskoff = ~dmask;
  1034.  rmask = 0x80;
  1035.  if (xorflag)
  1036.  {
  1037.     /* if set then invert bit */
  1038.  
  1039.   for(i=0;i<8;i++)
  1040.   {
  1041.    if (rmask & data) *iptr++ ^= dmskon; /* invert bit */
  1042.    else iptr++;   /* do nothing but still have to inc ptr */
  1043.    rmask >>= 1;
  1044.   }
  1045.  }
  1046.  else
  1047.  {
  1048.     /* if set then set bit otherwise clear */
  1049.   for(i=0;i<8;i++)
  1050.   {
  1051.    if (rmask & data) *iptr++ |= dmskon;
  1052.    else *iptr++ &= dmskoff;
  1053.    rmask >>= 1;
  1054.   }
  1055.  }
  1056. }
  1057.  
  1058.  
  1059. /*  NOTE: optimize
  1060.  *
  1061.  */
  1062. void IFF_Short_Mod(iptr,data,dmask,xorflag)
  1063. UBYTE *iptr;
  1064. USHORT data;
  1065. ULONG dmask;
  1066. LONG xorflag;
  1067. {
  1068.  register LONG i;
  1069.  register UBYTE bdata,dmskoff,dmskon;
  1070.  
  1071.  dmskon = dmask;
  1072.  dmskoff = ~dmask;
  1073.  if (xorflag)
  1074.  {
  1075.   bdata = (UBYTE)(data >> 8);
  1076.   for(i=0;i<8;i++)
  1077.   {
  1078.    if (mask[i] & bdata) *iptr++ ^= dmskon;
  1079.    else iptr++;
  1080.   }
  1081.   bdata = (UBYTE)(data & 0xff);
  1082.   for(i=0;i<8;i++)
  1083.   {
  1084.    if (mask[i] & bdata) *iptr++ ^= dmskon;
  1085.    else iptr++;
  1086.   }
  1087.  }
  1088.  else
  1089.  {
  1090.   bdata = (UBYTE)(data >> 8);
  1091.   for(i=0;i<8;i++)
  1092.   {
  1093.    if (mask[i] & bdata) *iptr++ |= dmskon;
  1094.    else *iptr++ &= dmskoff;
  1095.   }
  1096.   bdata = (UBYTE)(data & 0xff);
  1097.   for(i=0;i<8;i++)
  1098.   {
  1099.    if (mask[i] & bdata) *iptr++ |= dmskon;
  1100.    else *iptr++ &= dmskoff;
  1101.   }
  1102.  }
  1103. }
  1104.  
  1105.  
  1106. /* 
  1107.  *
  1108.  */
  1109. void IFF_HAM_To_Bufferable(out,in,h_cmap,xosize,yosize,xip,yip,xisize)
  1110. UBYTE *out,*in;
  1111. ColorReg *h_cmap;
  1112. ULONG xosize,yosize,xip,yip,xisize;
  1113. {
  1114.   register ULONG x,y;
  1115.   register ULONG pred,pgreen,pblue,data,xend;
  1116.  
  1117.   xend = xip + xosize;
  1118.   for (y=0; y < (yip + yosize); y++)
  1119.   {
  1120.    /* NOTE: this might should be moved before y loop */
  1121.     pred=pgreen=pblue=0;
  1122.     for (x=0; x<xisize; x++)
  1123.     {
  1124.       data = (ULONG )(*in++);
  1125.       switch( (data & 0x30) )
  1126.       {
  1127.         case 0x00: /* use color register given by low */
  1128.           {
  1129.             register ULONG low;
  1130.             low = data & 0x0f;
  1131.             pred   = h_cmap[low].red;
  1132.             pgreen = h_cmap[low].green;
  1133.             pblue  = h_cmap[low].blue;
  1134.           }
  1135.           break;
  1136.         case 0x10: /* hold red and green   but change blue to low*/
  1137.           pblue = ((data << 4) | 0x0f) & 0xff;
  1138.           break;
  1139.         case 0x20: /* hold green and blue  but change red to low */
  1140.           pred = ((data << 4) | 0x0f) & 0xff;
  1141.           break;
  1142.         case 0x30: /* hold red and blue    but change green to low */
  1143.           pgreen = ((data << 4) | 0x0f) & 0xff;
  1144.           break;
  1145.       } /* end of switch */
  1146.       if ( (y >= yip) && (x >= xip) && (x < xend) )
  1147.       {
  1148.         register ULONG t_color;
  1149.         if (x11_display_type == TRUE_COLOR)
  1150.         {
  1151.            t_color = X11_Get_True_Color(pred,pgreen,pblue,8);
  1152.            if (x11_bytes_pixel == 4)
  1153.         { ULONG *ulp = (ULONG *)out;  *ulp = (ULONG)(t_color); }
  1154.            else if (x11_bytes_pixel == 2)
  1155.         { USHORT *usp = (USHORT *)out;  *usp = (USHORT)(t_color); }
  1156.            else *out = (UBYTE)(t_color);
  1157.        out += x11_bytes_pixel;
  1158.         }
  1159.         else *out++ =     (pred   & 0xe0) | ((pgreen & 0xe0) >> 3)
  1160.                        | ((pblue  & 0xc0) >> 6);
  1161.       } /* end of output */
  1162.     } /* end of x */
  1163.   } /* end of y */
  1164. }
  1165.  
  1166.  
  1167. /* 
  1168.  *
  1169.  */
  1170. LONG Is_IFF_File(filename)
  1171. BYTE *filename;
  1172. {
  1173.  FILE *fp;
  1174.  ULONG firstword;
  1175.  
  1176.  if ( (fp=fopen(filename,"r")) == 0)
  1177.  { 
  1178.   fprintf(stderr,"can't open %s\n",filename); 
  1179.   TheEnd();
  1180.  }
  1181.   /* by reading bytes we can ignore big/little endian problems */
  1182.  firstword  = (fgetc(fp) & 0xff) << 24;
  1183.  firstword |= (fgetc(fp) & 0xff) << 16;
  1184.  firstword |= (fgetc(fp) & 0xff) <<  8;
  1185.  firstword |= (fgetc(fp) & 0xff);
  1186.  
  1187.  fclose(fp);
  1188.  
  1189.  if (firstword == FORM) return(TRUE);
  1190.  if (firstword == LIST) return(TRUE);
  1191.  if (firstword == PROP) return(TRUE);
  1192.  return(FALSE);
  1193. }
  1194.  
  1195.  
  1196. /* 
  1197.  *
  1198.  */
  1199. void IFF_Buffer_Action(action_start)
  1200. LONG action_start;
  1201. {
  1202.  LONG i,image_size;
  1203.  UBYTE *buff0,*buff1,*tmp;
  1204.  ACTION *act;
  1205.  ULONG buff_csize;
  1206.  ColorReg *image_map;
  1207.  
  1208.  image_size = imagex * imagey;
  1209.  buff0 = (UBYTE *) malloc( image_size );
  1210.  if (buff0 == 0) TheEnd1("IFF Buffer Action: malloc failed 0");
  1211.  
  1212.  buff1 = (UBYTE *) malloc( image_size );
  1213.  if (buff1 == 0) 
  1214.  {
  1215.   free(buff0);
  1216.   TheEnd1("IFF Buffer Action: malloc failed 1");
  1217.  }
  1218.  
  1219.  buff_csize = imagec;  /* for IFF files with different image types */
  1220.  i=action_start;
  1221.  while(i<action_cnt)
  1222.  {
  1223.   act = &action[i];
  1224.   switch(act->type)
  1225.   {
  1226.    case ACT_CMAP:
  1227.         {
  1228.           CMAP_HDR *cmap_hdr;
  1229.  
  1230.           cmap_hdr = (CMAP_HDR *)act->data;
  1231.           image_map = (ColorReg *)cmap_hdr->data;
  1232.       buff_csize = cmap_hdr->cmap_size;
  1233.         }
  1234.         break;
  1235.  
  1236.    case ACT_SIZE:       
  1237.         { 
  1238.           SIZE_HDR *size_hdr;
  1239.           size_hdr = (SIZE_HDR *)act->data;
  1240.           imagex = size_hdr->imagex;
  1241.           imagey = size_hdr->imagey;
  1242.         } 
  1243.         break;
  1244.  
  1245.    case ACT_IFF_DLTA5:
  1246.    case ACT_IFF_DLTAJ:
  1247.         {
  1248.           int minx,miny,maxx,maxy; 
  1249.           int pic_size,pic_x,pic_y;
  1250.           UBYTE *t_pic,*w_pic;
  1251.  
  1252.           switch(act->type)
  1253.           {
  1254.             case ACT_IFF_DLTA5:
  1255.                 IFF_Delta5(buff0, act->data, &minx, &miny, &maxx, &maxy);
  1256.                 break;
  1257.             case ACT_IFF_DLTAJ:
  1258.                 IFF_DeltaJ(buff0, act->data, &minx, &miny, &maxx, &maxy);
  1259.                 break;
  1260.           }
  1261.           free(act->data);      /* free delta chunk */
  1262.           IFF_Update_DLTA_HDR(&minx,&miny,&maxx,&maxy);
  1263.  
  1264.           pic_x = maxx - minx; pic_y = maxy - miny;
  1265.           pic_size = pic_x * pic_y;
  1266.           t_pic = (UBYTE *) malloc( pic_size * x11_bytes_pixel);
  1267.           if (t_pic == 0) TheEnd1("Buff IFF DLTA5: malloc failed");
  1268.  
  1269.           IFF_Image_To_Bufferable(&w_pic, t_pic, buff0,
  1270.                 image_map, ham_map, buff_csize, pic_x, pic_y,
  1271.                 minx, miny, imagex, imagey, anim_flags);
  1272.           if (w_pic == buff0) memcpy((char *)t_pic,(char *)buff0,pic_size);
  1273.  
  1274.       ACT_Setup_Mapped(act, act->time, t_pic, image_map, buff_csize,
  1275.         minx, miny, pic_x, pic_y, TRUE, 0);
  1276.  
  1277.  
  1278.           tmp = buff0; buff0 = buff1; buff1 = tmp;
  1279.         }
  1280.         break;
  1281.  
  1282.    case ACT_IFF_BODY:
  1283.    case ACT_IFF_DLTA3:
  1284.    case ACT_IFF_DLTAl:
  1285.         {
  1286.           UBYTE *t_pic,*w_pic;
  1287.           switch(act->type)
  1288.           {
  1289.             case ACT_IFF_BODY:
  1290.                 memcpy((char *)buff0, (char *)act->data, image_size);
  1291.                 memcpy((char *)buff1, (char *)act->data, image_size);
  1292.                 IFF_Init_DLTA_HDR(imagex,imagey);
  1293.                 break;
  1294.  
  1295.             case ACT_IFF_DLTA3:
  1296.                 IFF_Delta3(buff0, act->data);
  1297.                 break;
  1298.             case ACT_IFF_DLTAl:
  1299.                 IFF_Deltal(buff0, act->data, 1);
  1300.                 break;
  1301.           }
  1302.  
  1303.           free(act->data);         /* free delta chunk */
  1304.           t_pic = (UBYTE *) malloc( image_size * x11_bytes_pixel);
  1305.  
  1306.           IFF_Image_To_Bufferable(&w_pic, t_pic, buff0,
  1307.                 image_map, ham_map, buff_csize, imagex, imagey, 0, 0,
  1308.         imagex, imagey, anim_flags);
  1309.           if (w_pic == buff0) memcpy((char *)t_pic,(char *)buff0,image_size);
  1310.  
  1311.       ACT_Setup_Mapped(act, act->time, t_pic, image_map, buff_csize,
  1312.         0, 0, imagex, imagey, TRUE, 0);
  1313.  
  1314.           tmp = buff0; buff0 = buff1; buff1 = tmp;
  1315.         }
  1316.         break;
  1317.  
  1318.    case ACT_IFF_HMAP:   
  1319.         {
  1320.           ColorReg *hptr;
  1321.           LONG i;
  1322.  
  1323.           hptr = (ColorReg *)act->data;
  1324.           for(i=0;i<HMAP_SIZE;i++)
  1325.           {
  1326.             ham_map[i].red   = hptr[i].red;
  1327.             ham_map[i].green = hptr[i].green;
  1328.             ham_map[i].blue  = hptr[i].blue;
  1329.           }
  1330.           act->type = ACT_NOP;
  1331.           free(act->data);
  1332.           act->data = 0;
  1333.         }
  1334.         break;
  1335.   }
  1336.   i++;
  1337.  }
  1338.  if (buff0) free(buff0);
  1339.  if (buff1) free(buff1);
  1340. }
  1341.  
  1342. LONG IFF_DeltaJ(fptr,deltaptr,tminx,tminy,tmaxx,tmaxy)
  1343. UBYTE *fptr;
  1344. register UBYTE *deltaptr;
  1345. LONG *tminx,*tminy,*tmaxx,*tmaxy;
  1346. {
  1347.  register LONG rowsize,width;
  1348.  register UBYTE *imageptr;
  1349.  register LONG exitflag;
  1350.  register ULONG  type,r_flag,b_cnt,g_cnt,r_cnt; 
  1351.  register ULONG b,g,r;
  1352.  register ULONG offset,dmask,depth;
  1353.  register UBYTE data;
  1354.  LONG changed;
  1355.  LONG tmp,minx,miny,maxx,maxy;
  1356.  LONG kludge_j;
  1357.  /* this kludge is because xanimations with width less than 320 get
  1358.   * centered in the middle of a 320 screen. Does this happen with
  1359.   * animations greater than lores overscan(374) and less than hi-res(640)????
  1360.   */
  1361.  
  1362.  if (imagex >= 320) kludge_j = 0;
  1363.  else kludge_j = (320-imagex)/2;
  1364.  
  1365.  maxx=0;
  1366.  maxy=0;
  1367.  minx=imagex;
  1368.  miny=imagey;
  1369.  
  1370.  changed=0;
  1371.  width = imagex;
  1372.  rowsize = width / 8;
  1373.  exitflag=0;
  1374.  while(!exitflag)
  1375.  {
  1376.   /* read compression type and reversible_flag(xor data not just set) 
  1377.    */
  1378.   type   = (*deltaptr++) << 8; type   |= (*deltaptr++);
  1379.   r_flag = (*deltaptr++) << 8; r_flag |= (*deltaptr++);
  1380.   DEBUG_LEVEL2 
  1381.         fprintf(stderr,"J type=%lx rev_flag=%lx imaged=%lx\n",
  1382.                                                 type,r_flag,imaged);
  1383.  
  1384.   /* switch on compression type */
  1385.   switch(type)
  1386.   {
  1387.    case 0: exitflag = 1; break; /* end of list */
  1388.    case 1:
  1389.       /* Get byte count and group count 
  1390.        */
  1391.       b_cnt = (*deltaptr++) << 8; b_cnt |= (*deltaptr++);
  1392.       g_cnt = (*deltaptr++) << 8; g_cnt |= (*deltaptr++);
  1393.       DEBUG_LEVEL2 
  1394.                 fprintf(stderr,"byte group cnts %lx %lx\n",b_cnt,g_cnt);
  1395.       
  1396.       /* Loop thru groups
  1397.        */
  1398.       for(g=0; g<g_cnt; g++)
  1399.       {
  1400.         offset = (*deltaptr++) << 8; offset |= (*deltaptr++);
  1401.         DEBUG_LEVEL2 
  1402.                 fprintf(stderr,"  g%ld) offset=%lx\n",g,offset);
  1403.  
  1404.         offset <<= 3; /* counts bytes */
  1405.         if (kludge_j) 
  1406.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1407.  
  1408.         imageptr = (UBYTE *)((ULONG)fptr + offset);
  1409.  
  1410.         tmp = offset%imagex; if (tmp<minx) minx=tmp;
  1411.         tmp += 8;            if (tmp>maxx) maxx=tmp;
  1412.         tmp = offset/imagex; if (tmp<miny) miny=tmp;
  1413.         tmp += b_cnt;        if (tmp>maxy) maxy=tmp;
  1414.        
  1415.         /* Loop thru byte count 
  1416.          */
  1417.         for(b=0; b < b_cnt; b++)
  1418.         {
  1419.           dmask = 1;
  1420.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1421.           {
  1422.             data = *deltaptr++;
  1423.             DEBUG_LEVEL3 fprintf(stderr,"<%lx>",data);
  1424.             changed |= data;          /* CHECKFORZERO change */
  1425.             IFF_Byte_Mod(imageptr,data,dmask,r_flag);
  1426.             dmask <<= 1;
  1427.           } /* end of depth loop */
  1428.           DEBUG_LEVEL3 fprintf(stderr,"\n");
  1429.           imageptr += width; /* direction is vertical */
  1430.         } /* end of byte loop */
  1431.       } /* end of group loop */
  1432.       break;
  1433.    case 2:
  1434.       /* Read row count, byte count and group count 
  1435.        */
  1436.       r_cnt = (*deltaptr++) << 8; r_cnt |= (*deltaptr++);
  1437.       b_cnt = (*deltaptr++) << 8; b_cnt |= (*deltaptr++);
  1438.       g_cnt = (*deltaptr++) << 8; g_cnt |= (*deltaptr++);
  1439.       DEBUG_LEVEL2 fprintf(stderr,"row byte group cnts %lx %lx %lx\n",
  1440.                            r_cnt,b_cnt,g_cnt);
  1441.       
  1442.       /* Loop thru groups
  1443.        */
  1444.       for(g=0; g < g_cnt; g++)
  1445.       {
  1446.         offset = (*deltaptr++) << 8; offset |= (*deltaptr++);
  1447.         DEBUG_LEVEL2 fprintf(stderr,"  g%ld) offset=%lx\n",g,offset);
  1448.         offset <<= 3; /* counts bytes */
  1449.         if (kludge_j) 
  1450.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1451.  
  1452.         tmp = offset%imagex;     if (tmp<minx) minx=tmp;
  1453.         tmp += b_cnt * 8;        if (tmp>maxx) maxx=tmp;
  1454.         tmp = offset/imagex;     if (tmp<miny) miny=tmp;
  1455.         tmp += r_cnt;            if (tmp>maxy) maxy=tmp;
  1456.        
  1457.         /* Loop thru rows of group
  1458.          */
  1459.         for(r=0; r < r_cnt; r++)
  1460.         {
  1461.           DEBUG_LEVEL2 fprintf(stderr,"     ROW%lx ++%ld,%ld++",r,
  1462.               (offset%width),(offset/width + r));
  1463.           dmask = 1;
  1464.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1465.           {
  1466.             imageptr = (UBYTE *)(fptr + offset + (r * width));
  1467.             for(b=0; b < b_cnt; b++) /* loop thru byte count */
  1468.             {
  1469.               data = *deltaptr++;
  1470.               DEBUG_LEVEL3 fprintf(stderr,"<%lx>",data);
  1471.               changed |= data;        /* CHECKFORZERO */
  1472.            
  1473.               IFF_Byte_Mod(imageptr,data,dmask,r_flag);
  1474.               imageptr += 8;        /* data is horizontal */
  1475.             } /* end of byte loop */
  1476.             dmask <<= 1;
  1477.             DEBUG_LEVEL3 fprintf(stderr,"((%lx))\n",depth);
  1478.           } /* end of depth loop */
  1479.         } /* end of row loop */
  1480.       } /* end of group loop */
  1481.       break;
  1482.    default: /* don't know this one yet */
  1483.             fprintf(stderr,"Unknown J-type %x\n",type);
  1484.             type = 0;      /* force an exit */
  1485.             exitflag = 1;
  1486.             break;
  1487.   } /* end of type switch */
  1488.  } /* end of while loop */
  1489.  
  1490.  if (optimize_flag == TRUE)
  1491.  {
  1492.    *tminx = minx; *tminy = miny;
  1493.    *tmaxx = maxx; *tmaxy = maxy;
  1494.  
  1495.    if (*tminx >= imagex) *tminx = 0;
  1496.    if (*tminy >= imagey) *tminy = 0;
  1497.    if (*tmaxx <= 0)      *tmaxx = imagex;
  1498.    if (*tmaxy <= 0)      *tmaxy = imagey;
  1499.    DEBUG_LEVEL2 fprintf(stderr,"xypos=<%ld,%ld> xysize=<%ld %ld>\n",
  1500.         *tminx,*tminy,*tmaxx,*tmaxy );
  1501.  }
  1502.  else
  1503.  {
  1504.    *tminx = 0; *tminy = 0;
  1505.    *tmaxx = imagex; *tmaxy = imagey;
  1506.  }
  1507.  
  1508.  /* if changed is zero then this Delta didn't change the image at all */ 
  1509.  return(changed);
  1510. } /* end of routine */
  1511.  
  1512. /* 
  1513.  *  Decode IFF type l anims
  1514.  */
  1515. void IFF_Deltal(fptr,deltaptr,vertflag)
  1516. UBYTE *fptr;
  1517. UBYTE *deltaptr;
  1518. LONG vertflag;
  1519. {
  1520.  register LONG i,depth,dmask,width;
  1521.  ULONG poff0,poff1;
  1522.  register UBYTE *imageptr;
  1523.  register UBYTE *optr,*dptr;
  1524.  register SHORT cnt;
  1525.  register USHORT offset,data;
  1526.  
  1527.  imageptr = fptr;
  1528.  if (vertflag) width = imagex;
  1529.  else width = 16;
  1530.  dmask = 1;
  1531.  for(depth = 0; depth<imaged; depth++)
  1532.  {
  1533.    imageptr = fptr;
  1534.    /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1535.    poff0  = (deltaptr[ 4 * depth    ]) << 24;
  1536.    poff0 |= (deltaptr[ 4 * depth + 1]) << 16;
  1537.    poff0 |= (deltaptr[ 4 * depth + 2]) <<  8;
  1538.    poff0 |= (deltaptr[ 4 * depth + 3]);
  1539.  
  1540.    if (poff0)
  1541.    {
  1542.      poff1  = (deltaptr[ 4 * (depth+8)    ]) << 24;
  1543.      poff1 |= (deltaptr[ 4 * (depth+8) + 1]) << 16;
  1544.      poff1 |= (deltaptr[ 4 * (depth+8) + 2]) <<  8;
  1545.      poff1 |= (deltaptr[ 4 * (depth+8) + 3]);
  1546.  
  1547.      dptr = (UBYTE *)( (ULONG)(deltaptr) + 2 * poff0); 
  1548.      optr = (UBYTE *)( (ULONG)(deltaptr) + 2 * poff1); 
  1549.  
  1550.      /* while short *optr != -1 */
  1551.      while( (optr[0] != 0xff) || (optr[1] != 0xff) )
  1552.      {
  1553.        offset = (*optr++) << 8; offset |= (*optr++);
  1554.        cnt    = (*optr++) << 8; cnt    |= (*optr++);
  1555.  
  1556.        if (cnt < 0)  /* cnt negative */
  1557.        {
  1558.          imageptr = fptr + 16 * (ULONG)(offset);
  1559.          cnt = -cnt;
  1560.          data = (*dptr++) << 8; data |= (*dptr++);
  1561.          for(i=0; i < (ULONG)cnt; i++)
  1562.          {
  1563.            IFF_Short_Mod(imageptr,data,dmask,0);
  1564.            imageptr += width;
  1565.          }
  1566.        }  /* end of neg */
  1567.        else/* cnt pos then */
  1568.        {
  1569.          imageptr = fptr + 16 * (ULONG)(offset);
  1570.          for(i=0; i < (ULONG)cnt; i++)
  1571.          {
  1572.            data = (*dptr++) << 8; data |= (*dptr++);
  1573.            IFF_Short_Mod(imageptr,data,dmask,0);
  1574.            imageptr += width;
  1575.          }
  1576.        } /* end of pos */
  1577.      } /* end of delta for this plane */
  1578.    } /* plane has changed data */
  1579.    dmask <<= 1;
  1580.  } /* end of d */
  1581. }
  1582.  
  1583. void
  1584. IFF_Setup_HMAP(act,hmap)
  1585. ACTION *act;
  1586. ColorReg *hmap;
  1587. {
  1588.   ColorReg *hptr;
  1589.   ULONG i;
  1590.  
  1591.   act->data = (UBYTE *) malloc(HMAP_SIZE * sizeof(ColorReg) );
  1592.   if (act->data == 0) TheEnd1("IFF_Setup_HMAP: malloc failed\n");
  1593.   act->type = ACT_IFF_HMAP;
  1594.   act->time = 0;
  1595.   hptr = (ColorReg *) act->data;
  1596.   for(i=0; i < HMAP_SIZE; i++) 
  1597.   {
  1598.     hptr[i].red   = hmap[i].red;
  1599.     hptr[i].green = hmap[i].green;
  1600.     hptr[i].blue  = hmap[i].blue;
  1601.   }
  1602. }
  1603.  
  1604. void
  1605. IFF_Setup_CMAP(act,cmap_ptr,sizec)
  1606. ACTION *act;
  1607. ColorReg *cmap_ptr;
  1608. ULONG sizec;
  1609. {
  1610.   ColorReg *act_cmap;
  1611.   CMAP_HDR *cmap_hdr; 
  1612.   ULONG i;
  1613.   LONG tmp;
  1614.  
  1615.   cmap_hdr = (CMAP_HDR *)
  1616.         malloc( sizec * sizeof(ColorReg) + sizeof(CMAP_HDR));
  1617.   if (cmap_hdr == 0) TheEnd1("IFF_Setup_CMAP: malloc failed\n");
  1618.  
  1619.   act->type = ACT_CMAP;
  1620.   act->time = 0;
  1621.   act->data = (UBYTE *)cmap_hdr;
  1622.  
  1623.   cmap_hdr->cmap_size = sizec;
  1624.  
  1625.   act_cmap = (ColorReg *)cmap_hdr->data;
  1626.   
  1627.   tmp = x11_cmap_size - sizec;
  1628.   if ( (tmp < 0) && (x11_cmap_flag == TRUE) )
  1629.   {
  1630.     fprintf(stderr,"IFF image has larger colormap than display.\n");
  1631.     fprintf(stderr,"This is not yet supported.\n");
  1632.     TheEnd();
  1633.   }
  1634.   else
  1635.   for(i = 0; i < sizec; i++)
  1636.   {
  1637.     act_cmap[i].red   = cmap_ptr[i].red;
  1638.     act_cmap[i].green = cmap_ptr[i].green;
  1639.     act_cmap[i].blue  = cmap_ptr[i].blue;
  1640.     if (x11_display_type == TRUE_COLOR)
  1641.       act_cmap[i].map = X11_Get_True_Color(
  1642.           cmap_ptr[i].red, cmap_ptr[i].green, cmap_ptr[i].blue, 8);
  1643.     else if (x11_display_type == MONOCHROME) act_cmap[i].map = i;
  1644.     else act_cmap[i].map = i + tmp;
  1645.   }
  1646. }
  1647.  
  1648. IFF_DLTA_HDR iff_dlta[2];
  1649.  
  1650. IFF_Init_DLTA_HDR(max_x,max_y)
  1651. ULONG max_x,max_y;
  1652. {
  1653.   iff_dlta[0].minx = iff_dlta[1].minx = 0;
  1654.   iff_dlta[0].miny = iff_dlta[1].miny = 0;
  1655.   iff_dlta[0].maxx = iff_dlta[1].maxx = imagex;
  1656.   iff_dlta[0].maxy = iff_dlta[1].maxy = imagey;
  1657. }
  1658.  
  1659. IFF_Update_DLTA_HDR(min_x,min_y,max_x,max_y)
  1660. LONG *min_x,*min_y,*max_x,*max_y;
  1661. {
  1662.   LONG tmin_x,tmin_y,tmax_x,tmax_y;
  1663.  
  1664.  /* This mess keeps track of the largest rectangle needed to
  1665.   * display all changes. Since things are double buffered, the
  1666.   * min/maxes of the corners of the current and previous two
  1667.   * images are taken. If the animation is in single step mode
  1668.   * it's best to display the entire image.
  1669.   */
  1670.  
  1671.   tmin_x = *min_x;
  1672.   tmin_y = *min_y;
  1673.   tmax_x = *max_x;
  1674.   tmax_y = *max_y;
  1675.   iff_dlta[0].minx = MIN(iff_dlta[0].minx, tmin_x);
  1676.   iff_dlta[0].miny = MIN(iff_dlta[0].miny, tmin_y);
  1677.   iff_dlta[0].maxx = MAX(iff_dlta[0].maxx, tmax_x);
  1678.   iff_dlta[0].maxy = MAX(iff_dlta[0].maxy, tmax_y);
  1679.   *min_x = iff_dlta[1].minx = MIN(iff_dlta[1].minx, iff_dlta[0].minx);
  1680.   *min_y = iff_dlta[1].miny = MIN(iff_dlta[1].miny, iff_dlta[0].miny);
  1681.   *max_x = iff_dlta[1].maxx = MAX(iff_dlta[1].maxx, iff_dlta[0].maxx);
  1682.   *max_y = iff_dlta[1].maxy = MAX(iff_dlta[1].maxy, iff_dlta[0].maxy);
  1683.  
  1684. /* Throw out oldest rectangle and store current.
  1685.  */
  1686.   iff_dlta[1].minx = iff_dlta[0].minx;
  1687.   iff_dlta[1].miny = iff_dlta[0].miny;
  1688.   iff_dlta[1].maxx = iff_dlta[0].maxx;
  1689.   iff_dlta[1].maxy = iff_dlta[0].maxy;
  1690.   iff_dlta[0].minx = tmin_x;
  1691.   iff_dlta[0].miny = tmin_y;
  1692.   iff_dlta[0].maxx = tmax_x;
  1693.   iff_dlta[0].maxy = tmax_y;
  1694. }
  1695.  
  1696.   
  1697. IFF_Image_To_Bufferable(i_ptr,out,in,map,h_cmap, map_size,
  1698.                         xosize,yosize,xip,yip,xisize,yisize,flags)
  1699. UBYTE **i_ptr,*out,*in;
  1700. ColorReg *map,*h_cmap;
  1701. ULONG map_size;
  1702. ULONG xosize,yosize,xip,yip,xisize,yisize,flags;
  1703. {
  1704.  
  1705.   if (x11_display_type == MONOCHROME)
  1706.   {
  1707.     register ULONG line_size;
  1708.  
  1709.     *i_ptr = out;
  1710.     line_size = X11_Get_Line_Size(xisize);
  1711.  
  1712.     /* NOTE: this code currently assumes no optimization under MONOCHROME */
  1713.     if (flags & ANIM_HAM)
  1714.     {
  1715.       IFF_HAM_To_Bufferable(out,in,h_cmap,xisize,yisize,0,0,xisize);
  1716.       UTIL_Mapped_To_Bitmap(out,out,map,map_size,xisize,yisize,line_size);
  1717.     }
  1718.     else UTIL_Mapped_To_Bitmap(out,in,map,map_size,xisize,yisize,line_size);
  1719.     return;
  1720.   }
  1721.  
  1722.   if (flags & ANIM_HAM)
  1723.   {
  1724.     *i_ptr = out;
  1725.     IFF_HAM_To_Bufferable(out,in,h_cmap,xosize,yosize,xip,yip,xisize);
  1726.     return;
  1727.   }
  1728.  
  1729.   if (x11_display_type == TRUE_COLOR)
  1730.   {
  1731.     *i_ptr = out;
  1732.     UTIL_Sub_Mapped_To_True(out, in, map, xosize, yosize,
  1733.                                 xip, yip, xisize);
  1734.   }
  1735.   else
  1736.   {
  1737.     /* Optimize if xip==yip==0 and xosize==imagex and yosize==imagey */
  1738.     *i_ptr = out;
  1739.     UTIL_Sub_Image(out, in, xosize, yosize, xip, yip, xisize, 1);
  1740.   }
  1741. }
  1742.  
  1743. IFF_Image_To_Displayable(i_ptr,out,in,map,h_cmap,map_size,xop,yop,x_im,y_im,
  1744.                          xosize,yosize,xip,yip,xisize,yisize,flags)
  1745. UBYTE **i_ptr,*out,*in;
  1746. ColorReg *map,*h_cmap;
  1747. ULONG map_size;
  1748. ULONG *xop,*yop,*x_im,*y_im;
  1749. ULONG xosize,yosize,xip,yip,xisize,yisize,flags;
  1750. {
  1751.  
  1752.   *xop = 0; *yop = 0; *x_im = xosize; *y_im = yosize;
  1753.  
  1754.   if (x11_display_type == MONOCHROME)
  1755.   {
  1756.     register ULONG line_size;
  1757.  
  1758.     *i_ptr = out;
  1759.     line_size = X11_Get_Line_Size(xisize);
  1760.  
  1761.     if (flags & ANIM_HAM)
  1762.     {
  1763.       IFF_HAM_To_Bufferable(out,in,h_cmap,xisize,yisize,0,0,xisize);
  1764.       UTIL_Mapped_To_Bitmap(out,out,map,map_size,xisize,yisize,line_size);
  1765.     }
  1766.     else UTIL_Mapped_To_Bitmap(out,in,map,map_size,xisize,yisize,line_size);
  1767.     *x_im = xisize; *y_im = yisize;
  1768.     return;
  1769.   }
  1770.  
  1771.   if (flags & ANIM_HAM)
  1772.   {
  1773.     *i_ptr = out;
  1774.     IFF_HAM_To_Bufferable(out,in,h_cmap,xosize,yosize,xip,yip,xisize);
  1775.     return;
  1776.   }
  1777.  
  1778.   if (x11_display_type == TRUE_COLOR)
  1779.   {
  1780.     *i_ptr = out;
  1781.     UTIL_Sub_Mapped_To_True(out, in, map, xosize, yosize, xip, yip, xisize);
  1782.     return;
  1783.   }
  1784.   else /* PSEUDO COLOR display */
  1785.   {
  1786.     *i_ptr = in;
  1787.     *xop = xip; *yop = yip; *x_im = xisize; *y_im = yisize;
  1788.   }
  1789. }
  1790.