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

  1.  
  2. /*
  3.  * xa_fli.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 "xa_fli.h" 
  19.  
  20. extern xaULONG xa_kludge1_fli;
  21.  
  22. xaLONG Is_FLI_File();
  23. xaULONG Fli_Read_File();
  24. static void FLI_Read_Header();
  25. xaULONG FLI_Read_Frame_Header();
  26. FLI_FRAME *FLI_Add_Frame();
  27. void FLI_Set_Time();
  28. xaULONG FLI_Decode_BRUN();
  29. xaULONG FLI_Decode_LC();
  30. xaULONG FLI_Decode_COPY();
  31. xaULONG FLI_Decode_BLACK();
  32. xaULONG FLI_Decode_LC7();
  33. static void FLI_Read_COLOR();
  34.  
  35. extern XA_ACTION *ACT_Get_Action();
  36. extern XA_CHDR *ACT_Get_CMAP();
  37. extern void ACT_Add_CHDR_To_Action();
  38. extern void ACT_Get_CCMAP();
  39. extern XA_ANIM_SETUP *XA_Get_Anim_Setup();
  40. extern void XA_Free_Anim_Setup();
  41. extern void ACT_Setup_Delta();
  42.  
  43. extern void UTIL_Sub_Image();
  44.  
  45. static Fli_Header fli_hdr;
  46. static Fli_Frame_Header frame_hdr;
  47.  
  48. static FLI_FRAME *fli_frame_start,*fli_frame_cur;
  49. static xaULONG fli_frame_cnt;
  50.  
  51. FLI_FRAME *FLI_Add_Frame(time,timelo,act)
  52. xaULONG time,timelo;
  53. XA_ACTION *act;
  54. {
  55.   FLI_FRAME *fframe;
  56.  
  57.   fframe = (FLI_FRAME *) malloc(sizeof(FLI_FRAME));
  58.   if (fframe == 0) TheEnd1("FLI_Add_Frame: malloc err");
  59.  
  60.   fframe->time   = time;
  61.   fframe->timelo = timelo;
  62.   fframe->act = act;
  63.   fframe->next = 0;
  64.  
  65.   if (fli_frame_start == 0) fli_frame_start = fframe;
  66.   else fli_frame_cur->next = fframe;
  67.  
  68.   fli_frame_cur = fframe;
  69.   fli_frame_cnt++;
  70.   return(fframe);
  71. }
  72.  
  73. static void FLI_Free_Frame_List(fframes)
  74. FLI_FRAME *fframes;
  75. {
  76.   FLI_FRAME *ftmp;
  77.   while(fframes != 0)
  78.   {
  79.     ftmp = fframes;
  80.     fframes = fframes->next;
  81.     FREE(ftmp,0x2000);
  82.   }
  83. }
  84.  
  85.  
  86. static void FLI_Read_Header(fli,xin,fli_hdr)
  87. XA_ANIM_SETUP *fli;
  88. XA_INPUT *xin;
  89. Fli_Header *fli_hdr;
  90. {
  91.   xaLONG i;
  92.  
  93.   fli_hdr->size   = xin->Read_LSB_U32(xin);
  94.   fli_hdr->magic  = xin->Read_LSB_U16(xin);
  95.   fli_hdr->frames = xin->Read_LSB_U16(xin);
  96.   fli_hdr->width  = xin->Read_LSB_U16(xin);
  97.   fli_hdr->height = xin->Read_LSB_U16(xin);
  98.   fli_hdr->res1   = xin->Read_LSB_U16(xin);
  99.   fli_hdr->flags  = xin->Read_LSB_U16(xin);
  100.   fli_hdr->speed  = xin->Read_LSB_U16(xin);
  101.   if (fli_hdr->speed <= 0) fli_hdr->speed = 1;
  102.   fli_hdr->next   = xin->Read_LSB_U32(xin);
  103.   fli_hdr->frit   = xin->Read_LSB_U32(xin);
  104.   for(i=0;i<102;i++) xin->Read_U8(xin);   /* ignore unused part of Fli_Header */
  105.  
  106.   xin->Set_EOF(xin,fli_hdr->size);
  107.   fli->imagex=fli_hdr->width;
  108.   fli->imagey=fli_hdr->height;
  109.   if ((fli_hdr->magic != 0xaf11) && (fli_hdr->magic != 0xaf12))
  110.   {
  111.    fprintf(stderr,"imagex=%x imagey=%x\n",fli->imagex,fli->imagey);
  112.    fprintf(stderr,"Fli Header Error magic %x not = 0xaf11\n",fli_hdr->magic);
  113.    TheEnd();
  114.   }
  115. }
  116.  
  117. xaULONG FLI_Read_Frame_Header(xin,frame_hdr)
  118. XA_INPUT *xin;
  119. Fli_Frame_Header *frame_hdr;
  120. { xaULONG i;
  121.   xaUBYTE tmp[6];
  122.  
  123.   if (xin->At_EOF(xin,16))    return(0);
  124.   for(i=0;i<6;i++) tmp[i] = (xaUBYTE)xin->Read_U8(xin);
  125.  
  126.   DEBUG_LEVEL1 fprintf(stderr,"  magic = %02x%02x\n",(int)tmp[5],(int)tmp[4]);
  127.   while( !( (tmp[5]==0xf1) && ((tmp[4]==0xfa) || (tmp[4] == 0x00)) ) )
  128.   {
  129.     for(i=0;i<6;i++) tmp[i] = tmp[i+1];
  130.     tmp[5] = (xaUBYTE)xin->Read_U8(xin);
  131.     if (xin->At_EOF(xin,10)) return(0);
  132.   }
  133.  
  134.   frame_hdr->size = (tmp[0])|(tmp[1] << 8)|(tmp[2] << 16)|(tmp[3] << 24);
  135.   frame_hdr->magic = (tmp[4])|(tmp[5] << 8);
  136.   frame_hdr->chunks = xin->Read_LSB_U16(xin);
  137.     /* ignore unused part of Fli_Frame_Header */
  138.   for(i=0;i<8;i++) xin->Read_U8(xin); 
  139.  
  140.   DEBUG_LEVEL1 
  141.     fprintf(stderr,"Frame Header size %x  magic %x  chunks %d\n",
  142.         frame_hdr->size,frame_hdr->magic,frame_hdr->chunks);
  143.  
  144.   return(1);
  145. }
  146.  
  147. xaULONG Fli_Read_File(fname,anim_hdr)
  148. char *fname;
  149. XA_ANIM_HDR *anim_hdr;
  150. {
  151.   XA_INPUT *xin = anim_hdr->xin;
  152.   xaLONG j,ret;
  153.   XA_ACTION *act;
  154.   xaULONG tmp_frame_cnt,file_pos,frame_i;
  155.   xaULONG t_time,t_timelo;
  156.   XA_ANIM_SETUP *fli;
  157.  
  158.   fli = XA_Get_Anim_Setup();
  159.   fli->depth = 8;
  160.  
  161.   fli_frame_start = 0;
  162.   fli_frame_cur = 0;
  163.   fli_frame_cnt = 0;
  164.  
  165.   FLI_Read_Header(fli,xin,&fli_hdr);
  166.  
  167.   if (xa_verbose) fprintf(stderr,"  Size %dx%d Frames= %d Magic= %x\n",
  168.     fli_hdr.width, fli_hdr.height,fli_hdr.frames,fli_hdr.magic);
  169.  
  170.     /* Allocate image buffer so deltas may be applied if buffering */
  171.   fli->pic_size = fli->imagex * fli->imagey;
  172.   if (xa_buffer_flag == xaTRUE)
  173.   {
  174.     fli->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(fli->pic_size) );
  175.     if (fli->pic == 0) TheEnd1("BufferAction: malloc failed");
  176.   }
  177.  
  178.  
  179.   tmp_frame_cnt = 0;
  180.   file_pos= 0x80;  /* need to do this because chunk sizes don't always
  181.             * add up to the frame size. */
  182.   while( FLI_Read_Frame_Header(xin, &frame_hdr) != 0)
  183.   {
  184.     xaULONG frame_read_size;
  185.  
  186.     if (frame_hdr.size == 0) break;
  187.  
  188.     file_pos += frame_hdr.size;
  189.  
  190. DEBUG_LEVEL1 fprintf(stderr,"FLI %d) size %x fpos %x xinpos %x\n",
  191.          tmp_frame_cnt,file_pos, frame_hdr.size, xin->fpos);
  192.  
  193.     tmp_frame_cnt++;
  194.     FLI_Set_Time(fli,fli_hdr.speed);
  195.     
  196.     if (frame_hdr.magic == 0xf100)
  197.     {
  198.       xaLONG i;
  199.       DEBUG_LEVEL1 
  200.      fprintf(stderr,"FLI 0xf100 Frame: size = %x\n",frame_hdr.size);
  201.       for(i=0;i<(frame_hdr.size - 16);i++) xin->Read_U8(xin);
  202.       if (frame_hdr.size & 0x01) xin->Read_U8(xin);
  203.     }
  204.     else if (frame_hdr.chunks==0)  /* this frame is for timing purposes */
  205.     {
  206.       DEBUG_LEVEL1 fprintf(stderr," FLI DELAY %d\n",fli_hdr.speed);
  207.       act = ACT_Get_Action(anim_hdr,ACT_DELAY);
  208.       act->data = 0;
  209.       FLI_Add_Frame(fli->vid_time,fli->vid_timelo,act);
  210.     }
  211.     else /* this frame has real data in it */
  212.     {
  213.       /* Loop through chunks in the frame
  214.        */
  215.       frame_read_size = 10;
  216.       for(j=0;j<frame_hdr.chunks;j++)
  217.       {
  218.         xaLONG chunk_size;
  219.     xaULONG chunk_type;
  220.    
  221.     /* only last chunk in frame should have full time(j must stay signed)*/
  222.         if (j < (frame_hdr.chunks - 1) ) { fli->vid_time = fli->vid_timelo = 0; }
  223.     else FLI_Set_Time(fli,fli_hdr.speed);
  224.         chunk_size = xin->Read_LSB_U32(xin) & 0xffffff;
  225.         chunk_type = xin->Read_LSB_U16(xin);
  226.     frame_read_size += 6 + chunk_size;
  227.     if ( (chunk_size & 0x01)&&(xa_kludge1_fli==xaFALSE)) frame_read_size++;
  228.         DEBUG_LEVEL1 fprintf(stderr,"  chunk %d) size %x  type %x tot %x\n",
  229.         j,chunk_size,chunk_type,frame_read_size);
  230.         switch(chunk_type)
  231.         {
  232.           case CHUNK_4:     /* FLI Color with 8 bits RGB */
  233.         DEBUG_LEVEL1 fprintf(stderr," FLI COLOR(4)\n");
  234.         FLI_Read_COLOR(fli,anim_hdr,xin,8,frame_hdr.chunks);
  235.         break;
  236.           case FLI_COLOR:     /* FLI Color with 6 bits RGB */
  237.         DEBUG_LEVEL1 fprintf(stderr," FLI COLOR(11)\n");
  238.         FLI_Read_COLOR(fli,anim_hdr,xin,6,frame_hdr.chunks);
  239.         break;
  240.           case FLI_LC:
  241.           case FLI_LC7:
  242.           case FLI_BRUN:
  243.           case FLI_COPY:
  244.           case FLI_BLACK:
  245.         {
  246.           ACT_DLTA_HDR *dlta_hdr;
  247.          
  248.           if (chunk_type==FLI_COPY) chunk_size = fli->pic_size;
  249.           else    chunk_size -= 6;
  250.  
  251.           act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  252.           FLI_Add_Frame(fli->vid_time,fli->vid_timelo,act);
  253.  
  254.           if (chunk_type == FLI_BLACK)
  255.           {
  256.             if (chunk_size != 0) TheEnd1("FLI BLACK: size err\n");
  257.             else
  258.             {
  259.                dlta_hdr = (ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR));
  260.                if (dlta_hdr == 0) TheEnd1("FLI BK CHUNK: malloc failed");
  261.               act->data = (xaUBYTE *)dlta_hdr;
  262.               dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  263.               dlta_hdr->fpos = 0; dlta_hdr->fsize = 0;
  264.             }
  265.           }
  266.           else if (chunk_size > 0)
  267.           {
  268.             if (xa_file_flag == xaTRUE)
  269.             {
  270.                dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  271.                if (dlta_hdr == 0) TheEnd1("FLI CHUNK: malloc failed");
  272.               act->data = (xaUBYTE *)dlta_hdr;
  273.               dlta_hdr->flags = ACT_SNGL_BUF;
  274.               dlta_hdr->fpos  = xin->Get_FPos(xin);
  275.               dlta_hdr->fsize = chunk_size;
  276.                xin->Seek_FPos(xin,chunk_size,1); /* move past chunk */
  277.               if (chunk_size > fli->max_fvid_size) 
  278.                     fli->max_fvid_size = chunk_size;
  279.             }
  280.             else
  281.             {
  282.                dlta_hdr = (ACT_DLTA_HDR *)
  283.                 malloc(sizeof(ACT_DLTA_HDR) + chunk_size);
  284.                if (dlta_hdr == 0) TheEnd1("FLI CHUNK: malloc failed");
  285.               act->data = (xaUBYTE *)dlta_hdr;
  286.               dlta_hdr->flags = 
  287.                 ACT_SNGL_BUF | DLTA_DATA;
  288.               dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk_size;
  289.               ret = xin->Read_Block(xin,dlta_hdr->data, chunk_size);
  290.                if (ret < chunk_size) TheEnd1("FLI: read dlta err");
  291.             }
  292.           }
  293.           else TheEnd1("FLI DLTA: invalid size");
  294.  
  295.           dlta_hdr->xpos = dlta_hdr->ypos = 0;
  296.           dlta_hdr->xsize = fli->imagex;
  297.           dlta_hdr->ysize = fli->imagey;
  298.           dlta_hdr->special = 0;
  299.           dlta_hdr->extra = (void *)(0);
  300.           dlta_hdr->xapi_rev = 0x0001;
  301.           switch(chunk_type)
  302.           {
  303.            case FLI_LC7:
  304.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(7)\n");
  305.             dlta_hdr->delta = FLI_Decode_LC7;
  306.             break;
  307.           case FLI_LC:
  308.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(12)\n");
  309.             dlta_hdr->delta = FLI_Decode_LC;
  310.             break;
  311.           case FLI_BLACK:
  312.             DEBUG_LEVEL1 fprintf(stderr," FLI BLACK(13)\n");
  313.             dlta_hdr->delta = FLI_Decode_BLACK;
  314.             break;
  315.           case FLI_BRUN:
  316.             DEBUG_LEVEL1 fprintf(stderr," FLI BRUN(15)\n");
  317.             dlta_hdr->delta = FLI_Decode_BRUN;
  318.             break;
  319.           case FLI_COPY:
  320.             DEBUG_LEVEL1 fprintf(stderr," FLI COPY(16)\n");
  321.             dlta_hdr->delta = FLI_Decode_COPY;
  322.             break;
  323.          }
  324.          ACT_Setup_Delta(fli,act,dlta_hdr,xin);
  325.         }
  326.         break;
  327.  
  328.           case FLI_MINI:
  329.         {
  330.           xaLONG i;
  331.           DEBUG_LEVEL1 fprintf(stderr," FLI MINI(18) ignored.\n");
  332.           for(i=0;i<(chunk_size-6);i++) xin->Read_U8(xin);
  333.           if ((xa_kludge1_fli==xaFALSE)&&(chunk_size & 0x01)) xin->Read_U8(xin);
  334.         }
  335.         break;
  336.  
  337.            default: 
  338.              {
  339.                xaLONG i;
  340.            fprintf(stderr,"FLI Unsupported Chunk: type = %x size=%x\n",
  341.                     chunk_type,chunk_size);
  342.                for(i=0;i<(chunk_size-6);i++) xin->Read_U8(xin);
  343.            if ((xa_kludge1_fli==xaFALSE)&&(chunk_size & 0x01)) xin->Read_U8(xin);
  344.              }
  345.              
  346.          break;
  347.         } /* end of switch */
  348.       } /* end of chunks is frame */
  349.     } /* end of not Timing Frame */
  350.     /* More robust way of reading FLI's. */
  351.     xin->Seek_FPos(xin,file_pos,0);
  352.   } /* end of frames in file */
  353.   if (fli->pic != 0) { FREE(fli->pic,0x2000); fli->pic=0;}
  354.   xin->Close_File(xin);
  355.  
  356.   /* extra for end and JMP2END */
  357.   anim_hdr->frame_lst = (XA_FRAME *)
  358.         malloc(sizeof(XA_FRAME) * (fli_frame_cnt + 2));
  359.   if (anim_hdr->frame_lst == NULL) TheEnd1("FLI_Read_Anim: malloc err");
  360.  
  361.   fli_frame_cur = fli_frame_start;
  362.   frame_i = 0;
  363.   t_time = t_timelo = 0;
  364.   while(fli_frame_cur != 0)
  365.   {
  366.     if (frame_i > fli_frame_cnt)
  367.     {
  368.       fprintf(stderr,"FLI_Read_Anim: frame inconsistency %d %d\n",
  369.                 frame_i,fli_frame_cnt);
  370.       break;
  371.     }
  372.     anim_hdr->frame_lst[frame_i].time_dur = fli_frame_cur->time;
  373.     anim_hdr->frame_lst[frame_i].zztime = t_time;
  374.     anim_hdr->frame_lst[frame_i].act = fli_frame_cur->act;
  375.     t_time += fli_frame_cur->time;
  376.     t_timelo += fli_frame_cur->timelo;
  377.     while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
  378.     fli_frame_cur = fli_frame_cur->next;
  379.     frame_i++;
  380.   }
  381.   /* ADD JMP2END for FLI/FLC animations with a loop frame */
  382.   if ( (tmp_frame_cnt > fli_hdr.frames) && (frame_i > 1)
  383.       && (!(anim_hdr->anim_flags & ANIM_NOLOOP)) )
  384.   { 
  385.     anim_hdr->total_time = anim_hdr->frame_lst[frame_i-2].zztime 
  386.                 + anim_hdr->frame_lst[frame_i-2].time_dur;
  387.  
  388.     /* This last frame takes place of 1st frame and so has time of 0 */
  389.     anim_hdr->frame_lst[frame_i].zztime = 0;
  390.     anim_hdr->frame_lst[frame_i].time_dur 
  391.                 = anim_hdr->frame_lst[frame_i-1].time_dur;
  392.     anim_hdr->frame_lst[frame_i].act  = anim_hdr->frame_lst[frame_i-1].act;
  393.     anim_hdr->frame_lst[frame_i-1].zztime = -1;
  394.     anim_hdr->frame_lst[frame_i-1].time_dur = 0;
  395.     anim_hdr->frame_lst[frame_i-1].act = ACT_Get_Action(anim_hdr,ACT_JMP2END);
  396.     frame_i++;
  397.     anim_hdr->loop_frame = 1;
  398.   }
  399.   else 
  400.   {
  401.     anim_hdr->loop_frame = 0;
  402.     if (frame_i > 0)
  403.       anim_hdr->total_time = anim_hdr->frame_lst[frame_i-1].zztime 
  404.                 + anim_hdr->frame_lst[frame_i-1].time_dur;
  405.     else anim_hdr->total_time = 0;
  406.   }
  407.   anim_hdr->last_frame = (frame_i>0)?(frame_i-1):(0);
  408.   anim_hdr->frame_lst[frame_i].zztime = -1;
  409.   anim_hdr->frame_lst[frame_i].time_dur = 0;
  410.   anim_hdr->frame_lst[frame_i].act  = 0;
  411.   frame_i++;
  412.   anim_hdr->imagex = fli->imagex;
  413.   anim_hdr->imagey = fli->imagey;
  414.   anim_hdr->imagec = fli->imagec;
  415.   anim_hdr->imaged = fli->depth;
  416.   anim_hdr->max_fvid_size = fli->max_fvid_size;
  417.   FLI_Free_Frame_List(fli_frame_start);
  418.   if (!(xin->load_flag & XA_IN_LOAD_BUF)) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  419.   if (xin->load_flag & XA_IN_LOAD_FILE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  420.   anim_hdr->fname = anim_hdr->name; /* data file is same as name */
  421.   XA_Free_Anim_Setup(fli);
  422.   return(xaTRUE);
  423. }
  424.  
  425.  
  426. /*
  427.  * Routine to Decode a Fli BRUN chunk
  428.  */
  429. xaULONG
  430. FLI_Decode_BRUN(image,delta,dsize,dec_info)
  431. xaUBYTE *image;         /* Image Buffer. */
  432. xaUBYTE *delta;         /* delta data. */
  433. xaULONG dsize;          /* delta size */
  434. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  435. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  436.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  437.   xaULONG i,k,packets,size,x,offset,pix_size;
  438.  
  439.   dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
  440.   pix_size = (map_flag==xaTRUE)?x11_bytes_pixel:1;
  441.   for(i=0; i < imagey; i++)
  442.   { offset = i * imagex;
  443.     packets = *delta++;
  444.  
  445.     x=0;
  446. /* Apparently, some flc file don't properly set packets. POD NOTE:
  447.     for(j= 0; j < packets; j++)
  448. */
  449.     while(x < imagex)
  450.     {
  451.       size = *delta++;
  452.       if (size & 0x80)         /* size < 0 so there is -size unique bytes */
  453.       {
  454.         size = 256-size; 
  455.         if (map_flag == xaTRUE)
  456.         {
  457.           if (pix_size == 4)
  458.             for(k=x;k<(x+size);k++)
  459.                 ((xaULONG *)(image))[k+offset] = (xaULONG)(map[*delta++]);
  460.           else if (pix_size == 2)
  461.             for(k=x;k<(x+size);k++)
  462.                 ((xaUSHORT *)(image))[k+offset] = (xaUSHORT)(map[*delta++]);
  463.           else
  464.             for(k=x;k<(x+size);k++)
  465.                 ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(map[*delta++]);
  466.         }
  467.         else
  468.         {
  469.           for(k=x;k<(x+size);k++)
  470.                 ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(*delta++);
  471.         }
  472.  
  473.         x += size;   
  474.       }
  475.       else                     /* size is pos repeat next byte size times */
  476.       {
  477.         xaULONG d;
  478.         d = *delta++;
  479.         if (map_flag == xaTRUE)
  480.         {
  481.           if (pix_size == 4)
  482.             for(k=x;k<(x+size);k++)
  483.                 ((xaULONG *)(image))[k+offset] = (xaULONG)(map[d]);
  484.           else if (pix_size == 2)
  485.              for(k=x;k<(x+size);k++)
  486.                 ((xaUSHORT *)(image))[k+offset] = (xaUSHORT)(map[d]);
  487.           else
  488.              for(k=x;k<(x+size);k++)
  489.                 ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(map[d]);
  490.         }
  491.         else
  492.         {
  493.           for(k=x;k<(x+size);k++)
  494.                 ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(d);
  495.         }
  496.         x+=size;   
  497.       }
  498.     } /* end of packets per line */
  499.   } /* end of line */
  500.   if (map_flag) return(ACT_DLTA_MAPD);
  501.   else return(ACT_DLTA_NORM);
  502. }
  503.  
  504. /*
  505.  * Routine to Decode an Fli LC chunk
  506.  */
  507.  
  508. xaULONG
  509. FLI_Decode_LC(image,delta,dsize,dec_info)
  510. xaUBYTE *image;         /* Image Buffer. */
  511. xaUBYTE *delta;         /* delta data. */
  512. xaULONG dsize;          /* delta size */
  513. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  514. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  515.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  516.   xaULONG i,j,k,packets,size,x,offset;
  517.   xaULONG start,lines,skip,minx,maxx,pix_size;
  518.  
  519.   pix_size = (map_flag==xaTRUE)?x11_bytes_pixel:1;
  520.   start = *delta++; start |= *delta++ << 8;  /* lines to skip */
  521.   lines = *delta++; lines |= *delta++ << 8;  /* number of lines */
  522.  
  523.   minx = imagex; 
  524.   maxx = 0;
  525.  
  526.   for(i=start;i<(start+lines);i++)
  527.   {
  528.     offset = i * imagex;
  529.     packets = *delta++;
  530.  
  531.     x=0;
  532.     for(j=0;j<packets;j++)
  533.     {
  534.       skip = *delta++;   /* this is the skip count */
  535.       size = *delta++;
  536.  
  537.       if (j==0) { if (skip < minx) minx = skip; }
  538.       x+=skip;
  539.       if (size & 0x80) /* next byte repeated -size times */
  540.       {
  541.         xaULONG d;
  542.         size = 256-size; 
  543.         d = *delta++;
  544.     if (map_flag == xaTRUE)
  545.         {
  546.       if (pix_size == 4)
  547.             for(k=x;k<(x+size);k++) 
  548.         ((xaULONG *)(image))[k+offset] = (xaULONG)(map[d]);
  549.       else if (pix_size == 2)
  550.              for(k=x;k<(x+size);k++) 
  551.         ((xaUSHORT *)(image))[k+offset] = (xaUSHORT)(map[d]);
  552.       else
  553.              for(k=x;k<(x+size);k++) 
  554.         ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(map[d]);
  555.         }
  556.         else
  557.         {
  558.           for(k=x;k<(x+size);k++) 
  559.         ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(d);
  560.         }
  561.         x+=size;   
  562.       }
  563.       else if (size) /* size is pos */
  564.       {
  565.         if (map_flag == xaTRUE)
  566.         {
  567.           if (pix_size == 4)
  568.             for(k=x;k<(x+size);k++) 
  569.         ((xaULONG *)(image))[k+offset] = (xaULONG)(map[*delta++]);
  570.           else if (pix_size == 2)
  571.             for(k=x;k<(x+size);k++) 
  572.         ((xaUSHORT *)(image))[k+offset] = (xaUSHORT)(map[*delta++]);
  573.           else
  574.             for(k=x;k<(x+size);k++) 
  575.         ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(map[*delta++]);
  576.         }
  577.         else
  578.         {
  579.           for(k=x;k<(x+size);k++) 
  580.         ((xaUBYTE *)(image))[k+offset] = (xaUBYTE)(*delta++);
  581.         }
  582.  
  583.         x+=size;   
  584.       }
  585.     } /* end of packets per line */
  586.     if (x > maxx) maxx = x;
  587.   } /* end of line */
  588.  
  589.   if ( (lines==0) || (maxx <= minx) )
  590.       { dec_info->ys = dec_info->ye = dec_info->xs = dec_info->xe = 0;
  591.                         return(ACT_DLTA_NOP); }
  592.   if (xa_optimize_flag == xaTRUE)
  593.   {
  594.     dec_info->ys = start;
  595.     dec_info->ye = start + lines;
  596.     dec_info->xs = minx;
  597.     if (maxx > imagex) maxx=imagex;
  598.     if (maxx > minx) dec_info->xe = maxx;
  599.     else dec_info->xe = imagex;
  600.   }
  601.   else { dec_info->ys = 0; dec_info->ye = imagey;
  602.      dec_info->xs = 0; dec_info->xe = imagex; }
  603.  
  604.   if (map_flag) return(ACT_DLTA_MAPD);
  605.   else return(ACT_DLTA_NORM);
  606. }
  607.  
  608. xaULONG
  609. FLI_Decode_COPY(image,delta,dsize,dec_info)
  610. xaUBYTE *image;         /* Image Buffer. */
  611. xaUBYTE *delta;         /* delta data. */
  612. xaULONG dsize;          /* delta size */
  613. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  614. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  615.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  616.   xaULONG image_size = imagex * imagey;
  617.   dec_info->xs = dec_info->ys = 0;
  618.   dec_info->xe = imagex; dec_info->ye = imagey;
  619.   if (map_flag)
  620.   {
  621.     if (x11_bytes_pixel == 4)
  622.     { xaULONG *i_ptr = (xaULONG *)image;
  623.       while(image_size--) *i_ptr++ = (xaULONG)map[ *delta++ ];
  624.     }
  625.     else if (x11_bytes_pixel == 2)
  626.     { xaUSHORT *i_ptr = (xaUSHORT *)image;
  627.       while(image_size--) *i_ptr++ = (xaUSHORT)map[ *delta++ ];
  628.     }
  629.     else
  630.     { xaUBYTE *i_ptr = (xaUBYTE *)image;
  631.       while(image_size--) *i_ptr++ = (xaUBYTE)map[ *delta++ ];
  632.     }
  633.   } 
  634.   else memcpy( (char *)image,(char *)delta,image_size);
  635.   if (map_flag) return(ACT_DLTA_MAPD);
  636.   else return(ACT_DLTA_NORM);
  637. }
  638.  
  639. xaULONG
  640. FLI_Decode_BLACK(image,delta,dsize,dec_info)
  641. xaUBYTE *image;         /* Image Buffer. */
  642. xaUBYTE *delta;         /* delta data. */
  643. xaULONG dsize;          /* delta size */
  644. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  645. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  646.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  647.   xaULONG image_size = imagex * imagey;
  648.   dec_info->xs = dec_info->ys = 0;
  649.   dec_info->xe = imagex; dec_info->ye = imagey;
  650.   if (map_flag)
  651.   {
  652.     xaULONG black = map[0];
  653.     if (x11_bytes_pixel == 4)
  654.     { xaULONG *i_ptr = (xaULONG *)image;
  655.       while(image_size--) *i_ptr++ = (xaULONG)black;
  656.     }
  657.     else if (x11_bytes_pixel == 2)
  658.     { xaUSHORT *i_ptr = (xaUSHORT *)image;
  659.       while(image_size--) *i_ptr++ = (xaUSHORT)black;
  660.     }
  661.     else
  662.     { xaUBYTE *i_ptr = (xaUBYTE *)image;
  663.       while(image_size--) *i_ptr++ = (xaUBYTE)black;
  664.     }
  665.   } 
  666.   else memset( (char *)image,0,image_size);
  667.   if (map_flag) return(ACT_DLTA_MAPD);
  668.   else return(ACT_DLTA_NORM);
  669. }
  670.  
  671.  
  672. /*
  673.  * Routine to read an Fli COLOR chunk
  674.  */
  675. static void FLI_Read_COLOR(fli,anim_hdr,xin,cbits,num_of_chunks)
  676. XA_ANIM_SETUP *fli;
  677. XA_ANIM_HDR *anim_hdr;
  678. XA_INPUT *xin;
  679. xaULONG cbits;
  680. xaULONG num_of_chunks;
  681. {
  682.  XA_ACTION *act;
  683.  xaULONG k,l,c_index,packets,skip,colors,cnt;
  684.  xaULONG mask;
  685.  
  686.  mask = (0x01 << cbits) - 1;
  687.  packets = xin->Read_LSB_U16(xin);
  688.  c_index = 0;
  689.  
  690.  DEBUG_LEVEL1 fprintf(stderr,"   packets = %d\n",packets);
  691.  cnt=2;
  692.  for(k=0;k<packets;k++)
  693.  {
  694.   skip = xin->Read_U8(xin);
  695.   colors=xin->Read_U8(xin);
  696.   DEBUG_LEVEL1 fprintf(stderr,"      skip %d colors %d\n",skip,colors);
  697.   cnt+=2;
  698.   if (colors==0) colors=FLI_MAX_COLORS;
  699.   c_index += skip;
  700.   for(l = 0; l < colors; l++)
  701.   {
  702.    fli->cmap[c_index].red   = xin->Read_U8(xin) & mask;
  703.    fli->cmap[c_index].green = xin->Read_U8(xin) & mask;
  704.    fli->cmap[c_index].blue  = xin->Read_U8(xin) & mask;
  705.    DEBUG_LEVEL5 fprintf(stderr,"         %d)  <%x %x %x>\n", 
  706.           l,fli->cmap[l].red, fli->cmap[l].green,fli->cmap[l].blue);
  707.    c_index++;
  708.   } /* end of colors */
  709.   cnt+= 3 * colors;
  710.  } /* end of packets */
  711.             /* read pad byte if needed */
  712.  if ((xa_kludge1_fli==xaFALSE)&&(cnt&0x01)) xin->Read_U8(xin);
  713.  
  714.  /* if only one chunk in frame this is a cmap change only */
  715.  if ( (num_of_chunks==1) && (fli->chdr != 0) )
  716.  {
  717.    act = ACT_Get_Action(anim_hdr,0);
  718.    ACT_Get_CCMAP(act,fli->cmap,FLI_MAX_COLORS,0,cbits,cbits,cbits);
  719.    FLI_Add_Frame(fli->vid_time,fli->vid_timelo,act);
  720.    ACT_Add_CHDR_To_Action(act,fli->chdr);
  721.  }
  722.  else
  723.    fli->chdr = ACT_Get_CMAP(fli->cmap,FLI_MAX_COLORS,0,FLI_MAX_COLORS,0,
  724.                             cbits,cbits,cbits);
  725. }
  726.  
  727. /*
  728.  * Routine to Decode an Fli LC chunk
  729.  */
  730. xaULONG
  731. FLI_Decode_LC7(image,delta,dsize,dec_info)
  732. xaUBYTE *image;         /* Image Buffer. */
  733. xaUBYTE *delta;         /* delta data. */
  734. xaULONG dsize;          /* delta size */
  735. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  736. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  737.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  738.   xaULONG i,j,x,y;
  739.   xaULONG lines,blocks,xoff,cnt,tmp_data0,tmp_data1;
  740.   xaULONG minx,maxx,miny,pix_size,last_pixel,last_pix_flag;
  741.   xaUBYTE *ptr;
  742.   
  743.   minx = imagex;
  744.   maxx = 0;
  745.   miny = imagey;
  746.  
  747.   pix_size = (map_flag==xaTRUE)?x11_bytes_pixel:1;
  748.   ptr = image;
  749.   y = 0;
  750.   lines = *delta++; lines |= *delta++ << 8;  /* # of lines encoded */
  751.  
  752.   DEBUG_LEVEL5 fprintf(stderr,"lines=%d\n",lines);
  753.  
  754.   last_pix_flag = last_pixel = 0;
  755.   for(i=0; i < lines; i++)
  756.   {
  757.    
  758.     blocks = *delta++; blocks |= *delta++ << 8; 
  759.  
  760.     DEBUG_LEVEL5 fprintf(stderr,"     %d) ",i);
  761.  
  762.     while(blocks & 0x8000)
  763.     {
  764.       /* Upper bits 11 - SKIP lines */
  765.       if (blocks & 0x4000)
  766.       {
  767.         blocks = 0x10000 - blocks;
  768.         y += blocks;
  769.         DEBUG_LEVEL5 fprintf(stderr,"     yskip %d",blocks);
  770.       }
  771.       else /* Upper bits 10 - Last Pixel Encoding */
  772.       {
  773.         DEBUG_LEVEL5 fprintf(stderr,"     lastpixel %d",blocks);
  774.         last_pix_flag = 1;
  775.         last_pixel = blocks & 0xff;
  776.       }
  777.       blocks = *delta++; blocks |= *delta++ << 8;
  778.     }
  779.  
  780.     DEBUG_LEVEL5 fprintf(stderr,"     blocks = %d\n",blocks);
  781.  
  782.     if (xa_optimize_flag == xaTRUE) if (y < miny) miny = y;
  783.  
  784.     ptr = (xaUBYTE *)(image + (y*imagex*pix_size) );
  785.     x = 0;
  786.  
  787.     for(j=0; j < blocks; j++)
  788.     {
  789.       xoff = (xaULONG) *delta++;  /* x offset */
  790.       cnt  = (xaULONG) *delta++;  /* halfword count */
  791.       ptr += (xoff * pix_size);
  792.       x += xoff;
  793.  
  794.       DEBUG_LEVEL5 
  795.         fprintf(stderr,"          %d) xoff %x  cnt = %x",j,xoff,cnt);
  796.  
  797.       if (cnt & 0x80)
  798.       {
  799.         cnt = 256 - cnt;
  800.         DEBUG_LEVEL5 fprintf(stderr,"               NEG %d\n",cnt);
  801.         if (xa_optimize_flag == xaTRUE)
  802.         {  
  803.           if (x < minx) minx = x;
  804.           x += (cnt << 1);
  805.           if (x > maxx) maxx = x;
  806.         }
  807.  
  808.     if (map_flag == xaTRUE)
  809.         {
  810.           tmp_data0 = map[*delta++];
  811.           tmp_data1 = map[*delta++];
  812.           if (pix_size == 4)
  813.       { 
  814.         xaULONG *ulp = (xaULONG *)ptr;
  815.             while(cnt--) { *ulp++ = (xaULONG)tmp_data0;
  816.                *ulp++ = (xaULONG)tmp_data1; }
  817.         ptr = (xaUBYTE *)ulp;
  818.           }
  819.           else if (pix_size == 2)
  820.       { 
  821.         xaUSHORT *usp = (xaUSHORT *)ptr;
  822.         while(cnt--) { *usp++ = (xaUSHORT)tmp_data0;
  823.                *usp++ = (xaUSHORT)tmp_data1; }
  824.         ptr = (xaUBYTE *)usp;
  825.           }
  826.           else
  827.             while(cnt--) { *ptr++ = (xaUBYTE)tmp_data0;
  828.                            *ptr++ = (xaUBYTE)tmp_data1; }
  829.     }
  830.     else
  831.     {
  832.           tmp_data0 = *delta++;
  833.           tmp_data1 = *delta++;
  834.           while(cnt--) { *ptr++ = (xaUBYTE)tmp_data0;
  835.                          *ptr++ = (xaUBYTE)tmp_data1; }
  836.     }
  837.  
  838.       }
  839.       else
  840.       {   /* cnt is number of unique pairs of bytes */
  841.         DEBUG_LEVEL5 fprintf(stderr,"               POS %d\n",cnt);
  842.         if (xa_optimize_flag == xaTRUE)
  843.         {
  844.           if (cnt == 1)  /* potential NOPs just to move x */
  845.           {
  846.             if ( (*ptr != *delta) || (ptr[1] != delta[1]) )  
  847.             {
  848.               if (x < minx) minx = x; 
  849.               x += (cnt << 1);
  850.               if (x > maxx) maxx = x;
  851.             }
  852.           }
  853.       else
  854.           {
  855.             if (x < minx) minx = x; 
  856.             x += (cnt << 1);
  857.             if (x > maxx) maxx = x;
  858.           }
  859.         }
  860.         if (map_flag == xaTRUE)
  861.         {
  862.           if (pix_size == 4)
  863.       { 
  864.         xaULONG *ulp = (xaULONG *)ptr;
  865.         while(cnt--) { *ulp++ = (xaULONG)map[*delta++];
  866.                            *ulp++ = (xaULONG)map[*delta++]; }
  867.         ptr = (xaUBYTE *)ulp;
  868.           }
  869.           else if (pix_size == 2)
  870.       { 
  871.         xaUSHORT *usp = (xaUSHORT *)ptr;
  872.         while(cnt--) { *usp++ = (xaUSHORT)map[*delta++];
  873.                *usp++ = (xaUSHORT)map[*delta++]; }
  874.         ptr = (xaUBYTE *)usp;
  875.           }
  876.           else
  877.              while(cnt--) { *ptr++ = (xaUBYTE)map[*delta++];
  878.                 *ptr++ = (xaUBYTE)map[*delta++]; }
  879.         }
  880.         else
  881.              while(cnt--) { *ptr++ = (xaUBYTE) *delta++;
  882.                 *ptr++ = (xaUBYTE) *delta++; }
  883.  
  884.       } 
  885.     } /* (j) end of blocks */
  886.     if (last_pix_flag) /* last pixel */
  887.     {
  888.         if (map_flag == xaTRUE)
  889.         {
  890.           if (pix_size == 4)
  891.         { xaULONG *ulp = (xaULONG *)ptr; *ulp = (xaULONG)map[last_pixel];}
  892.           else if (pix_size == 2)
  893.         { xaUSHORT *slp = (xaUSHORT *)ptr; *slp = (xaUSHORT)map[last_pixel];}
  894.           else { *ptr = (xaUBYTE)map[last_pixel]; }
  895.         }
  896.         else *ptr = (xaUBYTE)(last_pixel);
  897.         last_pix_flag = 0;
  898.     }
  899.     y++;
  900.   } /* (i) end of lines */
  901.  
  902.   if (xa_optimize_flag == xaTRUE)
  903.   {
  904.     if ( (maxx <= minx) || (y <= miny) )
  905.       { dec_info->ys = dec_info->ye = dec_info->xs = dec_info->xe = 0;
  906.                     return(ACT_DLTA_NOP); }
  907.     if (minx >= imagex) minx = 0;     dec_info->xs = minx;
  908.     if (miny >= imagey) miny = 0;     dec_info->ys = miny;
  909. /* POD NOTE: look into the +2 and +1 stuff */
  910.     maxx += 2;  if (maxx > imagex) maxx = imagex;
  911.     y += 1; if (y > imagey) y = imagey;
  912.     dec_info->xe = maxx;
  913.     dec_info->ye = y;
  914.   }
  915.   else { dec_info->xs = 0; dec_info->ys = 0;
  916.      dec_info->xe = imagex; dec_info->ye = imagey; }
  917.   DEBUG_LEVEL1 fprintf(stderr,"      LC7: xypos=<%d %d> xysize=<%d %d>\n",
  918.          dec_info->xs,dec_info->ys,dec_info->xe,dec_info->ye);
  919.   if (map_flag) return(ACT_DLTA_MAPD);
  920.   else return(ACT_DLTA_NORM);
  921. }
  922.  
  923. /* 
  924.  * FLI has time period of 1/70th sec where  FLC has time period of 1 ms.
  925.  * affects global variables fli->vid_time, fli->vid_timelo.
  926.  * uses global variable fli_hdr.magic.
  927.  */
  928. void FLI_Set_Time(fli,speed)
  929. XA_ANIM_SETUP *fli;
  930. xaULONG speed;
  931. {
  932.   fli->vid_timelo = 0;
  933.   if (xa_jiffy_flag) fli->vid_time = xa_jiffy_flag;
  934.   else if (fli_hdr.magic == 0xaf11)    /* 1/70th sec units */
  935.   { double ftime = (((double)(speed) * 1000.0)/70.0); /* convert to ms */
  936.     fli->vid_time =  (xaULONG)(ftime);
  937.     ftime -= (double)(fli->vid_time);
  938.     fli->vid_timelo = (ftime * (double)(1<<24));
  939.   }
  940.   else fli->vid_time = speed; /* 1 ms units */
  941. }
  942.  
  943.  
  944.