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

  1.  
  2. /*
  3.  * xa_avi.c
  4.  *
  5.  * Copyright (C) 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. /* The following copyright applies to all Ultimotion Segments of the Code:
  19.  *
  20.  * "Copyright International Business Machines Corporation 1994, All rights
  21.  *  reserved. This product uses Ultimotion(tm) IBM video technology."
  22.  *
  23.  */
  24.  
  25. /*******************************
  26.  * Revision History
  27.  *
  28.  * 16Aug94  video chunks of 0 size now properly used as NOP's with timing info.
  29.  * 12Apr95  added RGB depth 24 support
  30.  * 15Apr95  added XMPG support - what a KLUDGE format.
  31.  * 16Jun95  Removed Cinepak Codec per Radius request.
  32.  * 19Mar96  Modified for support of audio only files.
  33.  * 28Mar96  Added RGB depth  4 support
  34.  * 28Mar96  Added RGB depth 16 support
  35.  * 31Mar96  ULTI: fixed problem with 16/24 bit displays(wrong colors)
  36.  * 11Apr96  CRAM16: added some dithering support.
  37.  *
  38.  ********************************/
  39.  
  40.  
  41. #include "xa_avi.h" 
  42. #include "xa_xmpg.h" 
  43. #include "xa_codecs.h"
  44.  
  45.  
  46. #ifdef XA_CINEPAK
  47. extern xaULONG    Cinepak_What_Rev_API();
  48. extern xaLONG   Cinepak_Codec_Query();
  49. #define XA_CINEPAK_QUERY_CNT 1
  50. #else
  51. #define XA_CINEPAK_QUERY_CNT 0
  52. #endif
  53.  
  54. #ifdef XA_INDEO
  55. extern xaULONG    Indeo_What_Rev_API();
  56. extern xaLONG    Indeo_Codec_Query();
  57. #define XA_INDEO_QUERY_CNT 1
  58. #else
  59. #define XA_INDEO_QUERY_CNT 0
  60. #endif
  61.  
  62. #ifdef XA_CYUV
  63. extern xaULONG    CYUV_What_Rev_API();
  64. extern xaLONG    CYUV_Codec_Query();
  65. #define XA_CYUV_QUERY_CNT 1
  66. #else
  67. #define XA_CYUV_QUERY_CNT 0
  68. #endif
  69.  
  70. static xaLONG  AVI_Codec_Query();
  71. static xaLONG  AVI_UNK_Codec_Query();
  72.  
  73. #define AVI_QUERY_CNT 2 + XA_INDEO_QUERY_CNT + XA_CINEPAK_QUERY_CNT + XA_CYUV_QUERY_CNT
  74.  
  75. xaLONG (*avi_query_func[])() = {
  76. #ifdef XA_CYUV
  77.         CYUV_Codec_Query,
  78. #endif
  79. #ifdef XA_INDEO
  80.         Indeo_Codec_Query,
  81. #endif
  82. #ifdef XA_CINEPAK
  83.         Cinepak_Codec_Query,
  84. #endif
  85.         AVI_Codec_Query,
  86.         AVI_UNK_Codec_Query};
  87.  
  88.  
  89.  
  90. static xaULONG AVI_IJPG_Read_Ext();
  91. static xaULONG AVI_JPEG_Read_Ext();
  92. xaULONG AVI_Read_File();
  93. void AVI_Print_ID();
  94. AVI_FRAME *AVI_Add_Frame();
  95. void AVI_Free_Frame_List();
  96. xaULONG RIFF_Read_AVIH();
  97. xaULONG RIFF_Read_STRD();
  98. xaULONG RIFF_Read_STRH();
  99. xaULONG RIFF_Read_VIDS();
  100. xaULONG RIFF_Read_AUDS();
  101. void AVI_Print_Audio_Type();
  102. xaULONG AVI_Get_Color();
  103. void AVI_Get_RGBColor();
  104. ACT_DLTA_HDR *AVI_Read_00DC();
  105. void ACT_Setup_Delta();
  106. xaULONG AVI_XMPG_00XM();
  107. xaULONG AVI_Stream_Chunk();
  108. xaULONG AVI_Read_IDX1();
  109.  
  110. /* CODEC ROUTINES */
  111. xaULONG JFIF_Decode_JPEG();
  112. void JFIF_Read_IJPG_Tables();
  113. xaULONG AVI_Decode_RLE8();
  114. xaULONG AVI_Decode_CRAM();
  115. xaULONG AVI_Decode_CRAM16();
  116. xaULONG AVI_Decode_RGB4();
  117. xaULONG AVI_Decode_RGB8();
  118. xaULONG AVI_Decode_RGB16();
  119. xaULONG AVI_Decode_RGB24();
  120. extern xaULONG QT_Decode_RPZA();
  121. extern xaULONG XA_RGB24_To_CLR32();
  122. extern xaULONG XA_RGB16_To_CLR32();
  123. xaULONG AVI_Decode_ULTI();
  124. extern xaULONG MPG_Decode_I();
  125. extern void MPG_Init_Stuff();
  126. extern xaULONG MPG_Setup_Delta();
  127. extern void XA_Gen_YUV_Tabs();
  128. extern void JPG_Alloc_MCU_Bufs();
  129. extern void JPG_Setup_Samp_Limit_Table();
  130. extern jpg_search_marker();
  131. xaULONG AVI_Get_Ulti_Color();
  132. void AVI_Get_Ulti_rgbColor();
  133. void AVI_ULTI_Gen_YUV();
  134. void AVI_ULTI_LTC();
  135. void AVI_Ulti_Gen_LTC();
  136. xaULONG AVI_Ulti_Check();
  137.  
  138. void CMAP_Cache_Clear();
  139. void CMAP_Cache_Init();
  140.  
  141. XA_ACTION *ACT_Get_Action();
  142. XA_CHDR *ACT_Get_CMAP();
  143. XA_CHDR *CMAP_Create_332();
  144. XA_CHDR *CMAP_Create_422();
  145. XA_CHDR *CMAP_Create_Gray();
  146. void ACT_Add_CHDR_To_Action();
  147. void ACT_Setup_Mapped();
  148. void ACT_Get_CCMAP();
  149. XA_CHDR *CMAP_Create_CHDR_From_True();
  150. xaULONG CMAP_Find_Closest();
  151. xaUBYTE *UTIL_RGB_To_FS_Map();
  152. xaUBYTE *UTIL_RGB_To_Map();
  153.  
  154. extern XA_ANIM_SETUP *XA_Get_Anim_Setup();
  155. void XA_Free_Anim_Setup();
  156.  
  157.  
  158. static xaULONG avi_video_attempt;
  159. /** AVI SOUND STUFF ****/
  160. static xaULONG avi_audio_attempt;
  161. static xaULONG avi_has_audio;
  162. static xaULONG avi_has_video;
  163. static xaULONG avi_audio_type;
  164. static xaULONG avi_audio_freq;
  165. static xaULONG avi_audio_chans;
  166. static xaULONG avi_audio_bps;
  167. static xaULONG avi_audio_end;
  168. static AUDS_HDR auds_hdr;
  169. xaULONG XA_Add_Sound();
  170.  
  171.  
  172. extern xaLONG xa_dither_flag;
  173. extern xaUBYTE  *xa_byte_limit;
  174.  
  175. /* Currently used to check 1st frame for Microsoft MJPG screwup */
  176. static xaULONG avi_first_delta;
  177.  
  178. static xaLONG ulti_Cr[16],ulti_Cb[16],ulti_CrCb[256];
  179. xaUBYTE *avi_ulti_tab = 0;
  180.  
  181.  
  182. static AVI_HDR avi_hdr;
  183. static AVI_STREAM_HDR strh_hdr;
  184. static VIDS_HDR vids_hdr;
  185. static xaULONG avi_use_index_flag;
  186. static xaLONG avi_movi_offset;
  187. static xaUBYTE *avi_strd;
  188. static xaULONG avi_strd_size,avi_strd_cursz;
  189.  
  190. #define AVI_MAX_STREAMS 8
  191. XA_CODEC_HDR avi_codec_hdr[AVI_MAX_STREAMS];
  192. static xaULONG avi_stream_type[AVI_MAX_STREAMS];
  193. static xaULONG avi_stream_ok[AVI_MAX_STREAMS];
  194. static xaULONG avi_stream_cnt;
  195.  
  196. static xaULONG avi_frame_cnt;
  197. static AVI_FRAME *avi_frame_start,*avi_frame_cur;
  198.  
  199. AVI_FRAME *AVI_Add_Frame(time,timelo,act)
  200. xaULONG time,timelo;
  201. XA_ACTION *act;
  202. {
  203.   AVI_FRAME *fframe;
  204.  
  205.   fframe = (AVI_FRAME *) malloc(sizeof(AVI_FRAME));
  206.   if (fframe == 0) TheEnd1("AVI_Add_Frame: malloc err");
  207.  
  208.   fframe->time   = time;
  209.   fframe->timelo = timelo;
  210.   fframe->act = act;
  211.   fframe->next = 0;
  212.  
  213.   if (avi_frame_start == 0) avi_frame_start = fframe;
  214.   else avi_frame_cur->next = fframe;
  215.  
  216.   avi_frame_cur = fframe;
  217.   avi_frame_cnt++;
  218.   return(fframe);
  219. }
  220.  
  221. void AVI_Free_Frame_List(fframes)
  222. AVI_FRAME *fframes;
  223. {
  224.   AVI_FRAME *ftmp;
  225.   while(fframes != 0)
  226.   {
  227.     ftmp = fframes;
  228.     fframes = fframes->next;
  229.     FREE(ftmp,0xA000);
  230.   }
  231. }
  232.  
  233. xaULONG AVI_Read_File(fname,anim_hdr,audio_attempt)
  234. char *fname;
  235. XA_ANIM_HDR *anim_hdr;
  236. xaULONG audio_attempt;    /* xaTRUE if audio is to be attempted */
  237. { XA_INPUT *xin;
  238.   xaLONG i,t_time;
  239.   xaULONG t_timelo;
  240.   XA_ACTION *act;
  241.   xaLONG avi_riff_size;
  242.   XA_ANIM_SETUP *avi;
  243.  
  244.   xin = anim_hdr->xin;
  245.   avi = XA_Get_Anim_Setup();
  246.   avi->vid_time = XA_GET_TIME( 100 ); /* default */
  247.  
  248.   avi_strd        = 0;
  249.   avi_strd_size        = avi_strd_cursz = 0;
  250.   avi_frame_cnt        = 0;
  251.   avi_frame_start    = 0;
  252.   avi_frame_cur        = 0;
  253.   avi_use_index_flag    = 0;
  254.   avi_movi_offset    = 0;
  255.   avi_audio_attempt    = audio_attempt;
  256.   avi_video_attempt    = xaTRUE;
  257.   avi_has_audio        = xaFALSE;
  258.   avi_has_video        = xaFALSE;
  259.   avi_riff_size        = 1;
  260.   avi_first_delta    = 0;
  261.   avi_stream_cnt    = 0;
  262.   for(i=0; i < AVI_MAX_STREAMS; i++)
  263.     { avi_stream_type[i] = 0; avi_stream_ok[i] = xaFALSE; }
  264.  
  265.   xin->Set_EOF(xin,9);
  266.   while( !xin->At_EOF(xin,8) && (avi_riff_size > 0) )
  267.   {
  268.     xaULONG d,ck_id,ck_size;
  269.  
  270.     ck_id = xin->Read_MSB_U32(xin);
  271.     ck_size = xin->Read_LSB_U32(xin);
  272.     avi_riff_size -= 8;
  273. DEBUG_LEVEL2 
  274. {
  275.   fprintf(stdout,"AVI cid ");
  276.   AVI_Print_ID(stdout,ck_id);
  277.   fprintf(stdout,"  cksize %08x\n",ck_size);
  278. }
  279.     switch(ck_id)
  280.     {
  281.     case RIFF_RIFF:
  282.         xin->Set_EOF(xin, (ck_size + 8));
  283.         d = xin->Read_MSB_U32(xin);
  284.         avi_riff_size = (2*ck_size) - 4;
  285.         DEBUG_LEVEL2 
  286.         {
  287.             fprintf(stdout,"  RIFF form type ");
  288.             AVI_Print_ID(stdout,d);
  289.             fprintf(stdout,"\n");
  290.         }
  291.                 break;
  292.     case RIFF_LIST:
  293.         d = xin->Read_MSB_U32(xin);
  294.             /* Skip over movie list if using Index chunk */
  295.         if ((d == RIFF_movi) && (avi_use_index_flag))
  296.             { xaLONG eof_pos;
  297.           avi_movi_offset = xin->Get_FPos(xin);
  298.           avi_movi_offset -= 4;  /* back over type */
  299.             /* use to test for truncation */
  300.           xin->Seek_FPos(xin,0,2);
  301.           eof_pos = xin->Get_FPos(xin);
  302.  
  303. DEBUG_LEVEL2 fprintf(stdout,
  304.         "movi LIST: eof %d movi_offset %d ck_size %d\n",
  305.             eof_pos, avi_movi_offset, ck_size);
  306.  
  307.           if (eof_pos < (avi_movi_offset + ck_size)) /* truncated */
  308.           { avi_use_index_flag = 0;
  309.             xin->Seek_FPos(xin,(avi_movi_offset + 4),0);
  310.             avi_riff_size += (ck_size - 4);
  311. DEBUG_LEVEL2 fprintf(stdout,"TRUNCATED\n");
  312.           }
  313.           else
  314.           { if (ck_size & 1) ck_size++;
  315.             /* skip over movi List */
  316.             xin->Seek_FPos(xin,(avi_movi_offset + ck_size),0);
  317.           }
  318.         }
  319.         else
  320.         { /* re-add list size minus size of type */
  321.           avi_riff_size += (ck_size - 4); /* don't count LISTs */ 
  322.         }
  323.  
  324.         DEBUG_LEVEL2 
  325.         {
  326.             fprintf(stdout,"  List type ");
  327.             AVI_Print_ID(stdout,d);
  328.             fprintf(stdout,"\n");
  329.         }
  330.         break;
  331.  
  332.     case RIFF_avih:
  333.         DEBUG_LEVEL2 fprintf(stdout,"  AVI_HDR:\n");
  334.                 if (RIFF_Read_AVIH(xin,avi,ck_size,&avi_hdr)==xaFALSE) return(xaFALSE);
  335.                 break;
  336.  
  337.     case RIFF_strh:
  338.         DEBUG_LEVEL2 fprintf(stdout,"  STRH HDR:\n");
  339.                 if (RIFF_Read_STRH(xin,ck_size,&strh_hdr)==xaFALSE) return(xaFALSE);
  340.                 break;
  341.  
  342.     case RIFF_strd:
  343.         DEBUG_LEVEL2 fprintf(stdout,"  STRD HDR:\n");
  344.         avi_strd_cursz = ck_size;
  345.         if (ck_size & 1) ck_size++;
  346.         if (avi_strd_size==0)
  347.         { avi_strd_size = ck_size;
  348.           avi_strd = (xaUBYTE *)malloc(ck_size);
  349.           if (avi_strd==0) TheEnd1("AVI: strd malloc err");
  350.         }
  351.           else if (ck_size > avi_strd_size)
  352.         { xaUBYTE *tmp;
  353.           avi_strd_size = ck_size;
  354.           tmp = (xaUBYTE *)realloc(avi_strd,ck_size);
  355.           if (tmp==0) TheEnd1("AVI: strd malloc err");
  356.           else avi_strd = tmp;
  357.         }
  358.         xin->Read_Block(xin,avi_strd,ck_size);
  359.         break;
  360.  
  361.     case RIFF_strf:
  362.       DEBUG_LEVEL2 fprintf(stdout,"  STRF HDR:\n");
  363.       if  (    (avi_stream_cnt < AVI_MAX_STREAMS)
  364.         && (avi_stream_cnt < avi_hdr.streams) )
  365.       { xaULONG str_type,break_flag = xaFALSE;
  366.         str_type = avi_stream_type[avi_stream_cnt] = strh_hdr.fcc_type;
  367.         switch(str_type)
  368.         {
  369.           case RIFF_vids:
  370.         avi_stream_ok[avi_stream_cnt] = 
  371.             RIFF_Read_VIDS(xin,anim_hdr,avi,ck_size,&vids_hdr,
  372.                     avi_stream_cnt);
  373.         break_flag = xaTRUE;
  374.         break;
  375.           case RIFF_auds:
  376.         { xaULONG ret = RIFF_Read_AUDS(xin,ck_size,&auds_hdr);
  377.           if ( (avi_audio_attempt==xaTRUE) && (ret==xaFALSE))
  378.           {
  379.             fprintf(stdout,"  AVI Audio Type Unsupported\n");
  380.             avi_audio_attempt = xaFALSE;
  381.           }
  382.           avi_stream_ok[avi_stream_cnt] = avi_audio_attempt;
  383.         }
  384.         break_flag = xaTRUE;
  385.         break;
  386.           case RIFF_pads:
  387.         DEBUG_LEVEL1 fprintf(stdout,"AVI: STRH(pads) ignored\n");
  388.         avi_stream_ok[avi_stream_cnt] = xaFALSE;
  389.         break;
  390.           case RIFF_txts:
  391.         DEBUG_LEVEL1 fprintf(stdout,"AVI: STRH(txts) ignored\n");
  392.         avi_stream_ok[avi_stream_cnt] = xaFALSE;
  393.         break;
  394.           default:
  395.         fprintf(stdout,"unknown fcc_type at strf %08x ",str_type);
  396.         fprintf(stdout,"- ignoring this stream.\n");
  397.         avi_stream_ok[avi_stream_cnt] = xaFALSE;
  398.         }
  399.         avi_stream_cnt++;
  400.         if (break_flag) break;
  401.       }
  402.       /* ignore STRF chunk on higher streams or unsupport fcc_types */
  403.       if (ck_size & 0x01) ck_size++;
  404.       xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  405.       break;
  406.  
  407.  
  408.     case RIFF_01pc:
  409.     case RIFF_00pc:
  410.         { xaULONG pc_firstcol,pc_numcols;
  411.           pc_firstcol = xin->Read_U8(xin);
  412.           pc_numcols  = xin->Read_U8(xin);
  413. DEBUG_LEVEL2 fprintf(stdout,"00PC: 1st %d num %d\n",pc_firstcol,pc_numcols);
  414.           d = xin->Read_U8(xin);
  415.           d = xin->Read_U8(xin);
  416.           for(i = 0; i < pc_numcols; i++) 
  417.           {
  418.             avi->cmap[i + pc_firstcol].red   = xin->Read_U8(xin);
  419.             avi->cmap[i + pc_firstcol].green = xin->Read_U8(xin);
  420.             avi->cmap[i + pc_firstcol].blue  = xin->Read_U8(xin);
  421.             d = xin->Read_U8(xin);
  422.           }
  423.           act = ACT_Get_Action(anim_hdr,0);
  424.           AVI_Add_Frame(avi->vid_time,avi->vid_timelo,act);
  425.           avi->chdr = ACT_Get_CMAP(avi->cmap,avi->imagec,0,
  426.                             avi->imagec,0,8,8,8);
  427.           ACT_Add_CHDR_To_Action(act,avi->chdr);
  428.         }
  429.         break;
  430.  
  431.  
  432.  
  433.         case RIFF_idx1:
  434.         if (avi_use_index_flag)
  435.         { 
  436.                   if (ck_size & 0x01) ck_size++;
  437.           AVI_Read_IDX1(xin,anim_hdr,avi,ck_size,fname);
  438.         }
  439.         else
  440.         {
  441.                   if (ck_size & 0x01) ck_size++;
  442.           xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  443.         }
  444.         break;
  445.  
  446.         case RIFF_vedt:
  447.         case RIFF_strl:
  448.         case RIFF_hdrl:
  449.         case RIFF_vids:
  450.         case RIFF_JUNK:
  451.     case RIFF_DISP:
  452.     case RIFF_ISBJ:
  453. /*
  454.     case RIFF_ISFT:
  455.     case RIFF_IDIT:
  456. */
  457.     case RIFF_00AM:
  458.                 if (ck_size & 0x01) ck_size++;
  459.         xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  460.                 break;
  461.  
  462.         default:
  463.       /* Check for EOF */
  464.       if (xin->At_EOF(xin,0))  break;    /* End of File */
  465.     
  466.       /* Check if past end of RIFF Chunk */
  467.       if (avi_riff_size <= 0)
  468.       { fprintf(stdout,"  Past End of AVI File\n");
  469.         xin->Seek_FPos(xin,0,2); /* goto end of file */
  470.         break;
  471.       }
  472.  
  473.       /*** Check if Stream chunk or handle other unknown chunks */
  474.           if ( AVI_Stream_Chunk(xin,anim_hdr,avi,
  475.                 ck_id,ck_size,fname) == xaFALSE)
  476.                             return(xaFALSE);
  477.  
  478.       break;
  479.  
  480.       } /* end of ck_id switch */
  481.       /* reduce pessimism */
  482.       avi_riff_size -= ck_size;
  483.       if (ck_size & 0x01) avi_riff_size--; /* odd byte pad */
  484.     } /* while not exitflag */
  485.  
  486.   if (avi->pic != 0) { FREE(avi->pic,0xA003); avi->pic=0; }
  487.   xin->Close_File(xin);
  488.  
  489.   if (xa_verbose) 
  490.   { float fps =  1000000.0 / (float)(avi_hdr.us_frame);
  491.     fprintf(stdout, "  Frame Stats: Size=%dx%d  Frames=%d  fps=%2.1f\n",
  492.         avi->imagex,avi->imagey,avi_frame_cnt,fps);
  493.   }
  494.  
  495.   if (avi_frame_cnt == 0)
  496.   {
  497.     if (avi_has_video == xaTRUE)
  498.     { if (avi_has_audio == xaFALSE)
  499.       { fprintf(stdout,"  AVI Notice: No supported Video frames found.\n");
  500.     return(xaFALSE); }
  501.       else fprintf(stdout,"  AVI Notice: No supported Video frames - treating as audio only file\n");          
  502.     }
  503.  
  504.  
  505.     if (auds_hdr.blockalign == 0) auds_hdr.blockalign = 1;
  506.     /* can easily blow out of 32 bits - hence the float */
  507.     if (auds_hdr.rate)
  508.         anim_hdr->total_time = (xaULONG)
  509.             ((((float)auds_hdr.byte_cnt * (float)auds_hdr.samps_block * 1000.0)
  510.                                         / (float)auds_hdr.blockalign)
  511.                                         / (float)auds_hdr.rate);
  512.     else  anim_hdr->total_time = 0;
  513. /*
  514. fprintf(stderr,"byte_cnt %d  sampblk %d  blkalign %d rate %d\n",
  515.     auds_hdr.byte_cnt,auds_hdr.samps_block,
  516.     auds_hdr.blockalign,auds_hdr.rate);
  517. fprintf(stderr,"total time %d\n", anim_hdr->total_time);
  518. */
  519.   }
  520.   else
  521.   {
  522.     anim_hdr->frame_lst = (XA_FRAME *)
  523.                 malloc( sizeof(XA_FRAME) * (avi_frame_cnt+1));
  524.     if (anim_hdr->frame_lst == NULL) TheEnd1("AVI_Read_File: frame malloc err");
  525.  
  526.     avi_frame_cur = avi_frame_start;
  527.     i = 0;
  528.     t_time = 0;
  529.     t_timelo = 0;
  530.     while(avi_frame_cur != 0)
  531.     { if (i > avi_frame_cnt)
  532.       { fprintf(stdout,"AVI_Read_Anim: frame inconsistency %d %d\n",
  533.                         i,avi_frame_cnt); break; }
  534.       anim_hdr->frame_lst[i].time_dur = avi_frame_cur->time;
  535.       anim_hdr->frame_lst[i].zztime = t_time;
  536.       t_time += avi_frame_cur->time;
  537.       t_timelo += avi_frame_cur->timelo;
  538.       while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
  539.       anim_hdr->frame_lst[i].act = avi_frame_cur->act;
  540.       avi_frame_cur = avi_frame_cur->next;
  541.       i++;
  542.     }
  543.     if (i > 0) 
  544.     { anim_hdr->last_frame = i - 1;
  545.       anim_hdr->total_time = anim_hdr->frame_lst[i-1].zztime
  546.                 + anim_hdr->frame_lst[i-1].time_dur;
  547.     }
  548.     else
  549.     { anim_hdr->last_frame = 0;
  550.       anim_hdr->total_time = 0;
  551.     }
  552.     AVI_Free_Frame_List(avi_frame_start);
  553.     anim_hdr->imagex = avi->imagex;
  554.     anim_hdr->imagey = avi->imagey;
  555.     anim_hdr->imagec = avi->imagec;
  556.     anim_hdr->imaged = 8; /* nop */
  557.     anim_hdr->frame_lst[i].time_dur = 0;
  558.     anim_hdr->frame_lst[i].zztime = -1;
  559.     anim_hdr->frame_lst[i].act  = 0;
  560.     anim_hdr->loop_frame = 0;
  561.   } /* end of video present */
  562.  
  563.   if (xa_buffer_flag == xaFALSE) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  564.   if (xa_file_flag == xaTRUE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  565.   anim_hdr->max_fvid_size = avi->max_fvid_size;
  566.   anim_hdr->max_faud_size = avi->max_faud_size;
  567.   anim_hdr->fname = anim_hdr->name;
  568.   XA_Free_Anim_Setup(avi);
  569.   return(xaTRUE);
  570. } /* end of read file */
  571.  
  572. xaULONG RIFF_Read_AVIH(xin,avi,size,avi_hdr)
  573. XA_INPUT *xin;
  574. XA_ANIM_SETUP *avi;
  575. xaULONG size;
  576. AVI_HDR *avi_hdr;
  577. {
  578.   if (size != 0x38)
  579.   {
  580.     fprintf(stdout,"avih: size not 56 size=%d\n",size);
  581.     return(xaFALSE);
  582.   }
  583.  
  584.   avi_hdr->us_frame     = xin->Read_LSB_U32(xin);
  585.   avi_hdr->max_bps      = xin->Read_LSB_U32(xin);
  586.   avi_hdr->pad_gran     = xin->Read_LSB_U32(xin);
  587.   avi_hdr->flags        = xin->Read_LSB_U32(xin);
  588.   avi_hdr->tot_frames   = xin->Read_LSB_U32(xin);
  589.   avi_hdr->init_frames  = xin->Read_LSB_U32(xin);
  590.   avi_hdr->streams      = xin->Read_LSB_U32(xin);
  591.   avi_hdr->sug_bsize    = xin->Read_LSB_U32(xin);
  592.   avi_hdr->width        = xin->Read_LSB_U32(xin);
  593.   avi_hdr->height       = xin->Read_LSB_U32(xin);
  594.   avi_hdr->scale        = xin->Read_LSB_U32(xin);
  595.   avi_hdr->rate         = xin->Read_LSB_U32(xin);
  596.   avi_hdr->start        = xin->Read_LSB_U32(xin);
  597.   avi_hdr->length       = xin->Read_LSB_U32(xin);
  598.  
  599.   avi->cmap_frame_num = avi_hdr->tot_frames / cmap_sample_cnt;
  600.   if (xa_jiffy_flag) { avi->vid_time = xa_jiffy_flag; avi->vid_timelo = 0; }
  601.   else
  602.   { double ftime = (double)((avi_hdr->us_frame)/1000.0); /* convert to ms */
  603.     avi->vid_time =  (xaULONG)(ftime);
  604.     ftime -= (double)(avi->vid_time);
  605.     avi->vid_timelo = (ftime * (double)(1<<24));
  606.   }
  607.  
  608.   if (!(xin->type_flag & XA_IN_TYPE_RANDOM)) /* sequential */
  609.   {
  610.     if (avi_hdr->flags & AVIF_MUSTUSEINDEX)
  611.     {
  612.     fprintf(stdout,"AVI file must use index, but not possible with this input stream.\n");
  613.     fprintf(stdout,"   Will do the best it can, but expect strange results.\n");
  614.     }
  615.     avi_use_index_flag = 0;
  616.   }
  617.   else if (   (avi_hdr->flags & AVIF_MUSTUSEINDEX) 
  618.        || (avi_hdr->flags & AVIF_HASINDEX) )    avi_use_index_flag = 1;
  619.   else avi_use_index_flag = 0;
  620.  
  621. #ifdef POD_USE
  622.   if (xa_verbose)
  623. #else
  624.   DEBUG_LEVEL1
  625. #endif
  626.   {
  627.     fprintf(stdout,"  AVI flags: ");
  628.     if (avi_hdr->flags & AVIF_HASINDEX) fprintf(stdout,"Has_Index ");
  629.     if (avi_hdr->flags & AVIF_MUSTUSEINDEX) fprintf(stdout,"Use_Index ");
  630.     if (avi_hdr->flags & AVIF_ISINTERLEAVED) fprintf(stdout,"Interleaved ");
  631.     if (avi_hdr->flags & AVIF_WASCAPTUREFILE) fprintf(stdout,"Captured ");
  632.     if (avi_hdr->flags & AVIF_COPYRIGHTED) fprintf(stdout,"Copyrighted ");
  633.     fprintf(stdout,"\n");
  634.   }
  635.   return(xaTRUE);
  636. }
  637.  
  638. xaULONG RIFF_Read_STRH(xin,size,strh_hdr)
  639. XA_INPUT *xin;
  640. xaULONG size;
  641. AVI_STREAM_HDR *strh_hdr;
  642. {
  643.   xaULONG d,tsize;
  644.  
  645.   if (size < 0x24) 
  646.     {fprintf(stdout,"strh: size < 36 size = %d\n",size); return(xaFALSE);}
  647.  
  648.   strh_hdr->fcc_type    = xin->Read_MSB_U32(xin);
  649.   strh_hdr->fcc_handler = xin->Read_MSB_U32(xin);
  650.   strh_hdr->flags       = xin->Read_LSB_U32(xin);
  651.   strh_hdr->priority    = xin->Read_LSB_U32(xin);
  652.   strh_hdr->init_frames = xin->Read_LSB_U32(xin);
  653.   strh_hdr->scale       = xin->Read_LSB_U32(xin);
  654.   strh_hdr->rate        = xin->Read_LSB_U32(xin);
  655.   strh_hdr->start       = xin->Read_LSB_U32(xin);
  656.   strh_hdr->length      = xin->Read_LSB_U32(xin);
  657.   strh_hdr->sug_bsize   = xin->Read_LSB_U32(xin);
  658.   strh_hdr->quality     = xin->Read_LSB_U32(xin);
  659.   strh_hdr->samp_size   = xin->Read_LSB_U32(xin);
  660.  
  661.   tsize = 48; if (size & 0x01) size++;
  662.   while(tsize < size) { d = xin->Read_U8(xin); tsize++; }
  663.  
  664.   DEBUG_LEVEL2 fprintf(stdout,"AVI TEST handler = 0x%08x\n",
  665.                         strh_hdr->fcc_handler);
  666.   return(xaTRUE);
  667. }
  668.  
  669. /***********************************************
  670.  *
  671.  * Return:   xaFALSE on error.  xaTRUE on ok(supported or not)
  672.  **************/
  673. xaULONG RIFF_Read_VIDS(xin,anim_hdr,avi,size,vids_hdr,stream_cnt)
  674. XA_INPUT *xin;
  675. XA_ANIM_HDR *anim_hdr;
  676. XA_ANIM_SETUP *avi;
  677. xaLONG size;
  678. VIDS_HDR *vids_hdr;
  679. xaULONG stream_cnt;
  680. { xaULONG d,i,ctable_flag;
  681.   xaLONG  codec_ret;
  682.  
  683.   avi_has_video = xaTRUE;
  684.  
  685.   if (size & 0x01) size++;
  686.   ctable_flag        = xaTRUE;
  687.   vids_hdr->size        = xin->Read_LSB_U32(xin);
  688.   vids_hdr->width       = xin->Read_LSB_U32(xin);
  689.   vids_hdr->height      = xin->Read_LSB_U32(xin);
  690.   vids_hdr->planes      = xin->Read_LSB_U16(xin);
  691.   vids_hdr->bit_cnt     = xin->Read_LSB_U16(xin);
  692.   vids_hdr->compression = xin->Read_MSB_U32(xin);
  693.   vids_hdr->image_size  = xin->Read_LSB_U32(xin);
  694.   vids_hdr->xpels_meter = xin->Read_LSB_U32(xin);
  695.   vids_hdr->ypels_meter = xin->Read_LSB_U32(xin);
  696.   vids_hdr->num_colors  = xin->Read_LSB_U32(xin);
  697.   vids_hdr->imp_colors  = xin->Read_LSB_U32(xin);
  698.   size -= 40;
  699.  
  700.   avi->compression = vids_hdr->compression;
  701. DEBUG_LEVEL2 fprintf(stdout,"VIDS compression = %08x\n",avi->compression);
  702.   avi->depth = vids_hdr->bit_cnt;
  703.   avi->imagex = vids_hdr->width;
  704.   avi->imagey = vids_hdr->height;
  705.   avi->imagec = vids_hdr->num_colors;
  706.   if ( (avi->imagec==0) && (avi->depth <= 8) ) avi->imagec = (1 << avi->depth);
  707.   vids_hdr->num_colors = avi->imagec; /* re-update struct */
  708.  
  709.   avi_codec_hdr[stream_cnt].compression = avi->compression;
  710.   avi_codec_hdr[stream_cnt].x = avi->imagex;
  711.   avi_codec_hdr[stream_cnt].y = avi->imagey;
  712.   avi_codec_hdr[stream_cnt].depth = avi->depth;
  713.   avi_codec_hdr[stream_cnt].anim_hdr = (void *)anim_hdr;
  714.   avi_codec_hdr[stream_cnt].avi_ctab_flag = ctable_flag;
  715.  
  716.   /* Query to see if Video Compression is supported or not */
  717.   codec_ret = CODEC_UNKNOWN;
  718.   { xaULONG q = 0;
  719.     while(q < (AVI_QUERY_CNT) )
  720.     {
  721.       codec_ret = avi_query_func[q](&avi_codec_hdr[stream_cnt]);
  722.       if (codec_ret == CODEC_SUPPORTED)
  723.       { avi->imagex = avi_codec_hdr[stream_cnt].x;
  724.     avi->imagey = avi_codec_hdr[stream_cnt].y;
  725.     avi->compression = avi_codec_hdr[stream_cnt].compression;
  726.     ctable_flag = avi_codec_hdr[stream_cnt].avi_ctab_flag;
  727.         break;
  728.       }
  729.       else if (codec_ret == CODEC_UNSUPPORTED) break;
  730.       q++;
  731.     }
  732.   }
  733.  
  734.   /*** Return False if Codec is Unknown or Not Supported */
  735.   if (codec_ret != CODEC_SUPPORTED)
  736.   { char tmpbuf[256];
  737.     if (codec_ret == CODEC_UNKNOWN)
  738.     { xaULONG ii,a[4],dd = avi->compression;
  739.  
  740. fprintf(stderr,"comp %08x %08x %08x\n",
  741.         avi->compression,
  742.         avi_codec_hdr[stream_cnt].compression,
  743.         dd );
  744.  
  745.       for(ii=0; ii<4; ii++)
  746.       { a[ii] = dd & 0xff;  dd >>= 8;
  747.     if ((a[ii] < ' ') || (a[ii] > 'z')) a[ii] = '.';
  748.       }
  749.       sprintf(tmpbuf,"Unknown %c%c%c%c(%08x)",
  750.            (char)a[3],(char)a[2],(char)a[1],(char)a[0],avi->compression);
  751.       avi_codec_hdr[stream_cnt].description = tmpbuf;
  752.     }
  753.     if (xa_verbose)
  754.                 fprintf(stdout,"  Video Codec: %s",
  755.             avi_codec_hdr[stream_cnt].description);
  756.     else        fprintf(stdout,"AVI Video Codec: %s",
  757.             avi_codec_hdr[stream_cnt].description);
  758.     fprintf(stdout," is unsupported by this executable.(E%x)\n",
  759.                                 avi->depth);
  760.  
  761. /* point 'em to the readme's */
  762.     switch(avi->compression)
  763.     { 
  764.       case RIFF_iv31: 
  765.       case RIFF_IV31: 
  766.       case RIFF_iv32: 
  767.       case RIFF_IV32: 
  768.       case RIFF_YVU9: 
  769.       case RIFF_YUV9: 
  770.     fprintf(stdout,"      Please see the file \"indeo.readme\".\n");
  771.     break;
  772.       case RIFF_cvid: 
  773.       case RIFF_CVID: 
  774.     fprintf(stdout,"      Please see the file \"cinepak.readme\".\n");
  775.     break;
  776.       case RIFF_cyuv: 
  777.     fprintf(stdout,"      Please see the file \"creative.readme\".\n");
  778.     break;
  779.     }
  780.     while(size > 0) { d = xin->Read_U8(xin); size--; }
  781.     return(xaFALSE);
  782.   }
  783.  
  784.   
  785.   if (xa_verbose) fprintf(stdout,"  Video Codec: %s depth=%d\n",
  786.             avi_codec_hdr[stream_cnt].description,avi->depth);
  787.  
  788.   /*** Read AVI Color Table if it's present */
  789.   if ( (avi->depth <= 8) && (ctable_flag==xaTRUE) )
  790.   {
  791.     DEBUG_LEVEL1 fprintf(stdout,"AVI reading cmap %d\n",avi->imagec);
  792.     for(i=0; i < avi->imagec; i++)
  793.     {
  794.       avi->cmap[i].blue  =  xin->Read_U8(xin);
  795.       avi->cmap[i].green =  xin->Read_U8(xin);
  796.       avi->cmap[i].red   =  xin->Read_U8(xin);
  797.       d = xin->Read_U8(xin); /* pad */
  798.       size -= 4; if (size <= 0) break;
  799.     }
  800.     avi->chdr = ACT_Get_CMAP(avi->cmap,avi->imagec,0,avi->imagec,0,8,8,8);
  801.   }
  802.   else if (   (cmap_true_map_flag == xaFALSE) /* depth 16 and not true_map */
  803.            || (xa_buffer_flag == xaFALSE) )
  804.   {
  805.      if (cmap_true_to_332 == xaTRUE)
  806.              avi->chdr = CMAP_Create_332(avi->cmap,&avi->imagec);
  807.      else    avi->chdr = CMAP_Create_Gray(avi->cmap,&avi->imagec);
  808.   }
  809.   if ( (avi->pic==0) && (xa_buffer_flag == xaTRUE))
  810.   {
  811.     avi->pic_size = avi->imagex * avi->imagey;
  812.     if ( (cmap_true_map_flag == xaTRUE) && (avi->depth > 8) )
  813.         avi->pic = (xaUBYTE *) malloc( 3 * avi->pic_size );
  814.     else avi->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(avi->pic_size) );
  815.     if (avi->pic == 0) TheEnd1("AVI_Buffer_Action: malloc failed");
  816.   }
  817.  
  818.   /************* Some Video Codecs have Header Extensions ***************/
  819.   if ( (size > 0) && (avi_codec_hdr[stream_cnt].avi_read_ext))
  820.   { xaULONG ret = avi_codec_hdr[stream_cnt].avi_read_ext(xin,anim_hdr);
  821.     size -= ret;
  822.   }
  823.  
  824.   while(size > 0) { d = xin->Read_U8(xin); size--; }
  825.   return(xaTRUE);
  826. }
  827.  
  828.     /* by not setting act->type to NOP, yet returning 0, indicates
  829.          * that compression is not supported and that this AVI
  830.      * file should be no read in. Currently this is fine since
  831.      * only one compression is supported per file.
  832.      */
  833.  
  834. /****************************
  835.  * This function return in three ways.
  836.  *
  837.  *  act->type = NOP        : NOP frame.
  838.  *  dlta_hdr = 0           : comprssion not supported.
  839.  *  dlta_hdr != 0       : valid frame
  840.  *
  841.  *  NOTE: act->type comes in as ACT_DELTA
  842.  *
  843.  */
  844. ACT_DLTA_HDR *AVI_Read_00DC(xin,avi,ck_size,act,ck_offset,stream_num)
  845. XA_INPUT *xin;
  846. XA_ANIM_SETUP *avi;
  847. xaLONG ck_size;
  848. XA_ACTION *act;
  849. xaLONG ck_offset;
  850. xaLONG stream_num;
  851. {
  852.   ACT_DLTA_HDR *dlta_hdr = 0;
  853.   xaULONG d;
  854.  
  855.   if (ck_size & 0x01) ck_size++;
  856.   if (ck_size == 0)  /* NOP wait frame */
  857.   {
  858.     act->type = ACT_NOP;
  859.     act->data = 0;
  860.     act->chdr = 0;
  861.     AVI_Add_Frame( avi->vid_time, avi->vid_timelo, act);
  862.     return(0);
  863.   }
  864.  
  865.   if (xa_file_flag==xaTRUE)
  866.   {
  867.     dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  868.     if (dlta_hdr == 0) TheEnd1("AVI vid dlta0: malloc failed");
  869.     act->data = (xaUBYTE *)dlta_hdr;
  870.     dlta_hdr->flags = ACT_SNGL_BUF;
  871.     dlta_hdr->fsize = ck_size;
  872.     if (ck_offset >= 0)        dlta_hdr->fpos  = ck_offset;
  873.     else   /* fin marks chunk offset and need to seek past */
  874.     { dlta_hdr->fpos  = xin->Get_FPos(xin);
  875.       xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  876.     }
  877.     if (ck_size > avi->max_fvid_size) avi->max_fvid_size = ck_size;
  878.   }
  879.   else
  880.   { xaLONG ret;
  881.     d = ck_size + (sizeof(ACT_DLTA_HDR));
  882.     dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
  883.     if (dlta_hdr == 0) TheEnd1("AVI vid dlta1: malloc failed");
  884.     act->data = (xaUBYTE *)dlta_hdr;
  885.     dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  886.     dlta_hdr->fpos = 0; dlta_hdr->fsize = ck_size;
  887.     if (ck_offset >= 0)        xin->Seek_FPos( xin, ck_offset, 0);
  888.     ret = xin->Read_Block(xin,dlta_hdr->data,ck_size);
  889.     if (ret != ck_size) 
  890.     {  fprintf(stdout,"AVI vid dlta: read failed\n"); 
  891.        act->type = ACT_NOP;    act->data = 0;    act->chdr = 0;
  892.        free(dlta_hdr);
  893.        return(0);
  894.     }
  895.   }
  896.  
  897.   AVI_Add_Frame( avi->vid_time, avi->vid_timelo, act);
  898.   dlta_hdr->xpos = dlta_hdr->ypos = 0;
  899.   dlta_hdr->xsize = avi->imagex;
  900.   dlta_hdr->ysize = avi->imagey;
  901.   dlta_hdr->special = 0;
  902.   dlta_hdr->xapi_rev = avi_codec_hdr[stream_num].xapi_rev;
  903.   dlta_hdr->delta = avi_codec_hdr[stream_num].decoder;
  904.   dlta_hdr->extra = avi_codec_hdr[stream_num].extra;
  905.  
  906.   if (avi->compression == RIFF_MJPG)  /* Special Case */
  907.   { if (avi_first_delta==0)
  908.     { xaUBYTE *mjpg_tmp,*mjpg_buff = dlta_hdr->data;
  909.       xaLONG  mjpg_size  = ck_size;
  910.       avi_first_delta = 1;
  911.       if (xa_file_flag==xaTRUE) /* read from file if necessary */
  912.       { xaULONG ret;
  913.     mjpg_tmp = mjpg_buff = (xaUBYTE *)malloc(ck_size);
  914.     xin->Seek_FPos(xin,dlta_hdr->fpos,0);
  915.     ret = xin->Read_Block(xin, mjpg_tmp, mjpg_size);
  916.       }
  917.       while(jpg_search_marker(0xdb,&mjpg_buff,&mjpg_size) == xaTRUE)
  918.       { xaULONG len = (*mjpg_buff++) << 8;  len |= (*mjpg_buff++);
  919.     if ((len == 0x41) || (len == 0x82)) /* Microsoft MJPG screw up */
  920.     { 
  921.     dlta_hdr->extra = (void *)(0x40); break;
  922.     }
  923.     else if ((len == 0x43) || (len == 0x84)) /* valid lengths */
  924.     { 
  925.     dlta_hdr->extra = (void *)(0x00); break;
  926.     }
  927.     else mjpg_buff -= 2;  /* else back up */
  928.       }
  929.     } /* end of 1st delta */
  930.   }
  931.   return(dlta_hdr);
  932. }
  933.  
  934.  
  935. /*
  936.  * Routine to Decode an AVI CRAM chunk
  937.  */
  938.  
  939. #define CRAM_DITH_COL2RGB(_r,_g,_b,_col) { \
  940. _r = (_col & 0x7c00); _g = (_col & 0x03e0); _b = (_col & 0x001f);       \
  941. _r = _r | (_r >> 5);  _g = (_g << 5) | _g; _b = (_b << 10) | (_b << 5); }
  942.  
  943. #define CRAM_DITH_GET_RGB(_r,_g,_b,_re,_ge,_be,_col) { xaLONG r1,g1,b1; \
  944.   r1 = (xaLONG)rnglimit[(_r + _re) >> 7]; \
  945.   g1 = (xaLONG)rnglimit[(_g + _ge) >> 7]; \
  946.   b1 = (xaLONG)rnglimit[(_b + _be) >> 7]; \
  947.   _col = (r1 & 0xe0) | ((g1 & 0xe0) >> 3) | ((b1 & 0xc0) >> 6); }
  948.  
  949. #define CRAM_DITH_GET_ERR(_r,_g,_b,_re,_ge,_be,_col,cmap) { \
  950.   _re =  ((xaLONG)(_r) - (xaLONG)(cmap[_col].red   >> 1)) >> 1; \
  951.   _ge =  ((xaLONG)(_g) - (xaLONG)(cmap[_col].green >> 1)) >> 1; \
  952.   _be =  ((xaLONG)(_b) - (xaLONG)(cmap[_col].blue  >> 1)) >> 1; }
  953.  
  954.  
  955. #define AVI_CRAM_C1(ip,clr,rdec) { \
  956.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  957.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  958.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  959.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; }
  960.  
  961. #define AVI_CRAM_C2(ip,flag,cA,cB,rdec) { \
  962.   *ip++ =(flag&0x01)?(cB):(cA); *ip++ =(flag&0x02)?(cB):(cA); \
  963.   *ip++ =(flag&0x04)?(cB):(cA); *ip   =(flag&0x08)?(cB):(cA); ip-=rdec; \
  964.   *ip++ =(flag&0x10)?(cB):(cA); *ip++ =(flag&0x20)?(cB):(cA); \
  965.   *ip++ =(flag&0x40)?(cB):(cA); *ip   =(flag&0x80)?(cB):(cA); }
  966.  
  967. #define AVI_CRAM_C4(ip,flag,cA0,cA1,cB0,cB1,rdec) { \
  968.   *ip++ =(flag&0x01)?(cB0):(cA0); *ip++ =(flag&0x02)?(cB0):(cA0); \
  969.   *ip++ =(flag&0x04)?(cB1):(cA1); *ip   =(flag&0x08)?(cB1):(cA1); ip-=rdec; \
  970.   *ip++ =(flag&0x10)?(cB0):(cA0); *ip++ =(flag&0x20)?(cB0):(cA0); \
  971.   *ip++ =(flag&0x40)?(cB1):(cA1); *ip   =(flag&0x80)?(cB1):(cA1); }
  972.  
  973. #define AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y) { \
  974.     if (x < min_x) min_x = x; if (y > max_y) max_y = y; \
  975.     if (x > max_x) max_x = x; if (y < min_y) min_y = y; } 
  976.  
  977. #define AVI_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y -= 4; } }
  978.  
  979. #define AVI_GET_16(data,dptr) { data = *dptr++; data |= (*dptr++) << 8; }
  980.  
  981. #define AVI_CRAM_rgbC1(ip,r,g,b) { \
  982.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip++=b; \
  983.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip  =b; }
  984.  
  985. #define AVI_CRAM_rgbC2(ip,flag,rA,gA,bA,rB,gB,bB) { \
  986.   if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  987.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  988.   if (flag&0x02) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  989.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  990.   if (flag&0x04) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  991.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  992.   if (flag&0x08) {*ip++=rB; *ip++=gB; *ip  =bB;} \
  993.   else         {*ip++=rA; *ip++=gA; *ip  =bA;}  }
  994.  
  995. #define AVI_CRAM_rgbC4(ip,flag,rA,gA,bA,rB,gB,bB) { \
  996.   if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  997.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  998.   if (flag&0x02) {*ip++=rB; *ip++=gB; *ip  =bB;} \
  999.   else         {*ip++=rA; *ip++=gA; *ip  =bA;} }
  1000.  
  1001. #define AVI_Get_RGBColor(r,g,b,color) \
  1002. { register xaULONG _r,_g,_b; \
  1003.   _r = (color >> 10) & 0x1f; r = (_r << 3) | (_r >> 2); \
  1004.   _g = (color >>  5) & 0x1f; g = (_g << 3) | (_g >> 2); \
  1005.   _b =  color & 0x1f;        b = (_b << 3) | (_b >> 2); \
  1006.   if (xa_gamma_flag==xaTRUE) { r = xa_gamma_adj[r]>>8;    \
  1007.      g = xa_gamma_adj[g]>>8; b = xa_gamma_adj[b]>>8; } }
  1008.  
  1009.  
  1010. xaULONG
  1011. AVI_Decode_CRAM(image,delta,dsize,dec_info)
  1012. xaUBYTE *image;         /* Image Buffer. */
  1013. xaUBYTE *delta;         /* delta data. */
  1014. xaULONG dsize;          /* delta size */
  1015. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1016. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1017.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1018.   xaULONG row_dec,exitflag,changed,block_cnt;
  1019.   xaULONG code0,code1;
  1020.   xaLONG x,y,min_x,max_x,min_y,max_y;
  1021.   xaUBYTE *dptr;
  1022.  
  1023.   changed = 0;
  1024.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  1025.   dptr = delta;
  1026.   row_dec = imagex + 3;
  1027.   x = 0;
  1028.   y = imagey - 1;
  1029.   exitflag = 0;
  1030.   block_cnt = ((imagex * imagey) >> 4) + 1;
  1031.  
  1032.   if (map_flag == xaTRUE)
  1033.   {
  1034.     if (x11_bytes_pixel == 4)
  1035.     {
  1036.       while(!exitflag)
  1037.       {
  1038.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1039.     if ( ((code1==0) && (code0==0) && !block_cnt) || (y<0)) exitflag = 1;
  1040.     else
  1041.     {
  1042.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1043.       { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1044.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1045.       }
  1046.       else /* single block encoded */
  1047.       {
  1048.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  1049.         { xaULONG cA0,cA1,cB0,cB1;
  1050.           xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex + x) << 2) );
  1051.           cB0 = (xaULONG)map[*dptr++];  cA0 = (xaULONG)map[*dptr++];
  1052.           cB1 = (xaULONG)map[*dptr++];  cA1 = (xaULONG)map[*dptr++];
  1053.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1054.           cB0 = (xaULONG)map[*dptr++];  cA0 = (xaULONG)map[*dptr++];
  1055.           cB1 = (xaULONG)map[*dptr++];  cA1 = (xaULONG)map[*dptr++];
  1056.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1057.         } else if (code1 < 0x80) /* 2 color encoding */
  1058.         { register xaULONG clr_A,clr_B;
  1059.           xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex + x) << 2) );
  1060.           clr_B = (xaULONG)map[*dptr++];   clr_A = (xaULONG)map[*dptr++];
  1061.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  1062.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  1063.         }
  1064.         else /* 1 color encoding */
  1065.         { xaULONG clr = (xaULONG)map[code0]; 
  1066.           xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex + x) << 2) );
  1067.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  1068.         }
  1069.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1070.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  1071.       } /* end of single block */
  1072.     } /* end of not term code */
  1073.       } /* end of not while exit */
  1074.     } /* end of 4 bytes pixel */
  1075.     else if (x11_bytes_pixel == 2)
  1076.     {
  1077.       while(!exitflag)
  1078.       {
  1079.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1080.     if ( ((code1==0) && (code0==0) && !block_cnt) || (y<0)) exitflag = 1;
  1081.     else
  1082.     {
  1083.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1084.       { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1085.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1086.       } else /* single block encoded */
  1087.       {
  1088.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  1089.         {
  1090.           xaUSHORT cA0,cA1,cB0,cB1;
  1091.           xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex + x) << 1) );
  1092.           cB0 = map[*dptr++];  cA0 = map[*dptr++];
  1093.           cB1 = map[*dptr++];  cA1 = map[*dptr++];
  1094.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1095.           cB0 = map[*dptr++];  cA0 = map[*dptr++];
  1096.           cB1 = map[*dptr++];  cA1 = map[*dptr++];
  1097.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1098.         } /* end of 8 color quadrant encoding */
  1099.         else if (code1 < 0x80) /* 2 color encoding */
  1100.         { xaUSHORT clr_A,clr_B;
  1101.           xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex + x) << 1) );
  1102.           clr_B = (xaUSHORT)map[*dptr++];   clr_A = (xaUSHORT)map[*dptr++];
  1103.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  1104.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  1105.         } /* end of 2 color */
  1106.         else /* 1 color encoding */
  1107.         { xaUSHORT clr = (xaUSHORT)map[code0];
  1108.           xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex + x) << 1) );
  1109.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  1110.         }
  1111.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1112.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  1113.       } /* end of single block */
  1114.     } /* end of not term code */
  1115.       } /* end of not while exit */
  1116.     } /* end of 2 bytes pixel */
  1117.     else /* (x11_bytes_pixel == 1) */
  1118.     {
  1119.       while(!exitflag)
  1120.       {
  1121.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1122.     if ( ((code1==0) && (code0==0) && !block_cnt) || (y<0)) exitflag = 1;
  1123.     else
  1124.     {
  1125.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1126.       { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1127.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1128.       } else /* single block encoded */
  1129.       { 
  1130.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  1131.         { xaUBYTE cA0,cA1,cB0,cB1;
  1132.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1133.           cB0 = (xaUBYTE)map[*dptr++];  cA0 = (xaUBYTE)map[*dptr++];
  1134.           cB1 = (xaUBYTE)map[*dptr++];  cA1 = (xaUBYTE)map[*dptr++];
  1135.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1136.           cB0 = (xaUBYTE)map[*dptr++];  cA0 = (xaUBYTE)map[*dptr++];
  1137.           cB1 = (xaUBYTE)map[*dptr++];  cA1 = (xaUBYTE)map[*dptr++];
  1138.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1139.         } 
  1140.         else if (code1 < 0x80) /* 2 color encoding */
  1141.         { xaUBYTE clr_A,clr_B;
  1142.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1143.           clr_B = (xaUBYTE)map[*dptr++];   clr_A = (xaUBYTE)map[*dptr++];
  1144.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  1145.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  1146.         }
  1147.         else /* 1 color encoding */
  1148.         { xaUBYTE clr = (xaUBYTE)map[code0];
  1149.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1150.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  1151.         }
  1152.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1153.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  1154.       } /* end of single block */
  1155.     } /* end of not term code */
  1156.       } /* end of not while exit */
  1157.     } /* end of 1 bytes pixel */
  1158.   } /* end of map is xaTRUE */
  1159.   else
  1160.   {
  1161.       while(!exitflag)
  1162.       {
  1163.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1164.     if ( ((code1==0) && (code0==0) && !block_cnt) || (y<0)) exitflag = 1;
  1165.     else
  1166.     {
  1167.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1168.       { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1169.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1170.       } else /* single block encoded */
  1171.       {
  1172.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  1173.         {
  1174.           xaUBYTE cA0,cA1,cB0,cB1;
  1175.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1176.           cB0 = (xaUBYTE)*dptr++;  cA0 = (xaUBYTE)*dptr++;
  1177.           cB1 = (xaUBYTE)*dptr++;  cA1 = (xaUBYTE)*dptr++;
  1178.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1179.           cB0 = (xaUBYTE)*dptr++;  cA0 = (xaUBYTE)*dptr++;
  1180.           cB1 = (xaUBYTE)*dptr++;  cA1 = (xaUBYTE)*dptr++;
  1181.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1182.         } 
  1183.         else if (code1 < 0x80) /* 2 color encoding */
  1184.         { xaUBYTE clr_A,clr_B;
  1185.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1186.           clr_B = (xaUBYTE)*dptr++;   clr_A = (xaUBYTE)*dptr++;
  1187.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  1188.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  1189.         } /* end of 2 color */
  1190.         else /* 1 color encoding */
  1191.         {
  1192.           xaUBYTE clr = (xaUBYTE)code0;
  1193.           xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex + x);
  1194.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  1195.         }
  1196.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1197.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  1198.       } /* end of single block */
  1199.     } /* end of not term code */
  1200.       } /* end of not while exit */
  1201.   }
  1202.   if (xa_optimize_flag == xaTRUE)
  1203.   {
  1204.     if (changed) { dec_info->xs=min_x; dec_info->ys=min_y - 3;
  1205.             dec_info->xe=max_x + 4; dec_info->ye=max_y + 1; }
  1206.     else  { dec_info->xs = dec_info->ys = dec_info->xe = dec_info->ye = 0;
  1207.             return(ACT_DLTA_NOP); }
  1208.   }
  1209.   else { dec_info->xs = dec_info->ys = 0;
  1210.      dec_info->xe = imagex; dec_info->ye = imagey; }
  1211.   if (map_flag) return(ACT_DLTA_MAPD);
  1212.   else return(ACT_DLTA_NORM);
  1213. }
  1214.  
  1215.  
  1216. /*
  1217.  * Routine to Decode an AVI RGB chunk
  1218.  * (i.e. just copy it into the image buffer)
  1219.  * courtesy of Julian Bradfield.
  1220.  */
  1221.  
  1222. xaULONG
  1223. AVI_Decode_RGB4(image,delta,dsize,dec_info)
  1224. xaUBYTE *image;         /* Image Buffer. */
  1225. xaUBYTE *delta;         /* delta data. */
  1226. xaULONG dsize;          /* delta size */
  1227. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1228. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1229.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1230.   xaULONG oddcnt;
  1231.   xaUBYTE *dptr = delta;
  1232.   
  1233.   dec_info->xs = dec_info->ys = 0;
  1234.   dec_info->xe = imagex; dec_info->ye = imagey;
  1235.     /* Indicate we can drop these frames */
  1236.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1237.  
  1238.   oddcnt = ((imagex & 0x03)==1)?(1):(0);
  1239.   if (map_flag == xaTRUE)
  1240.   { if (x11_bytes_pixel == 4)
  1241.     { xaLONG x,y = imagey - 1;
  1242.       while ( y >= 0 )
  1243.       { xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex)<<2) ); y--; 
  1244.         x = imagex; while(x) { xaUBYTE d = *dptr++; x -= 2;
  1245.        *i_ptr++ = (xaULONG)map[d >> 4]; *i_ptr++ = (xaULONG)map[d & 0xf]; }
  1246.         x = oddcnt; while(x--) dptr++; 
  1247.       }
  1248.     }
  1249.     else if (x11_bytes_pixel == 2)
  1250.     { xaLONG x,y = imagey - 1;
  1251.       while ( y >= 0 )
  1252.       { xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex)<<1) ); y--; 
  1253.         x = imagex; while(x) { xaUBYTE d = *dptr++; x -= 2;
  1254.       *i_ptr++ = (xaUSHORT)map[d >> 4]; *i_ptr++ = (xaUSHORT)map[d & 0xf]; }
  1255.         x = oddcnt; while(x--) dptr++; 
  1256.       }
  1257.     }
  1258.     else /* (x11_bytes_pixel == 1) */
  1259.     { xaLONG x,y = imagey - 1;
  1260.       while ( y >= 0 )
  1261.       { xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex); y--; 
  1262.         x = imagex; while(x) { xaUBYTE d = *dptr++; x -= 2;
  1263.        *i_ptr++ = (xaUBYTE)map[d >> 4]; *i_ptr++ = (xaUBYTE)map[d & 0xf]; }
  1264.         x = oddcnt; while(x--) dptr++; 
  1265.       }
  1266.     }
  1267.   } /* end of map is xaTRUE */
  1268.   else
  1269.   { xaLONG x,y = imagey - 1;
  1270.     while ( y >= 0 )
  1271.     { xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex); y--; 
  1272.         x = imagex; while(x) { xaUBYTE d = *dptr++; x -= 2;
  1273.        *i_ptr++ = (xaUBYTE)(d >> 4); *i_ptr++ = (xaUBYTE)(d & 0xf); }
  1274.       x = oddcnt; while(x--) dptr++; 
  1275.     }
  1276.   }
  1277.   if (map_flag) return(ACT_DLTA_MAPD);
  1278.   else return(ACT_DLTA_NORM);
  1279. }
  1280.  
  1281.  
  1282. xaULONG
  1283. AVI_Decode_RGB8(image,delta,dsize,dec_info)
  1284. xaUBYTE *image;         /* Image Buffer. */
  1285. xaUBYTE *delta;         /* delta data. */
  1286. xaULONG dsize;          /* delta size */
  1287. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1288. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1289.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1290.   xaULONG oddcnt;
  1291.   xaUBYTE *dptr = delta;
  1292.   
  1293.   dec_info->xs = dec_info->ys = 0;
  1294.   dec_info->xe = imagex; dec_info->ye = imagey;
  1295.     /* Indicate we can drop these frames */
  1296.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1297.  
  1298.   oddcnt = 4 - (imagex & 0x03);  if (oddcnt == 4) oddcnt = 0;
  1299.   if (map_flag == xaTRUE)
  1300.   {
  1301.     if (x11_bytes_pixel == 4)
  1302.     { xaLONG x,y = imagey - 1;
  1303.       while ( y >= 0 )
  1304.       { xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex)<<2) ); y--; 
  1305.         x = imagex; while(x--) *i_ptr++ = (xaULONG)map[*dptr++];
  1306.         x = oddcnt; while(x--) dptr++; 
  1307.       }
  1308.     }
  1309.     else if (x11_bytes_pixel == 2)
  1310.     { xaLONG x,y = imagey - 1;
  1311.       while ( y >= 0 )
  1312.       { xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex)<<1) ); y--; 
  1313.         x = imagex; while(x--) *i_ptr++ = (xaUSHORT)map[*dptr++];
  1314.         x = oddcnt; while(x--) dptr++; 
  1315.       }
  1316.     }
  1317.     else /* (x11_bytes_pixel == 1) */
  1318.     { xaLONG x,y = imagey - 1;
  1319.       while ( y >= 0 )
  1320.       { xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex); y--; 
  1321.         x = imagex; while(x--) *i_ptr++ = (xaUBYTE)map[*dptr++];
  1322.         x = oddcnt; while(x--) dptr++; 
  1323.       }
  1324.     }
  1325.   } /* end of map is xaTRUE */
  1326.   else
  1327.   { xaLONG x,y = imagey - 1;
  1328.     while ( y >= 0 )
  1329.     { xaUBYTE *i_ptr = (xaUBYTE *)(image + y * imagex); y--; 
  1330.       x = imagex; while(x--) *i_ptr++ = (xaUBYTE)*dptr++;
  1331.       x = oddcnt; while(x--) dptr++; 
  1332.     }
  1333.   }
  1334.   if (map_flag) return(ACT_DLTA_MAPD);
  1335.   else return(ACT_DLTA_NORM);
  1336. }
  1337.  
  1338. /*******************
  1339.  *  RGB Decode Depth 16
  1340.  ******/
  1341. xaULONG
  1342. AVI_Decode_RGB16(image,delta,dsize,dec_info)
  1343. xaUBYTE *image;         /* Image Buffer. */
  1344. xaUBYTE *delta;         /* delta data. */
  1345. xaULONG dsize;          /* delta size */
  1346. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1347. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1348.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1349.   xaULONG special = dec_info->special;
  1350.   XA_CHDR *chdr = dec_info->chdr;
  1351.   xaUBYTE *dp = delta;
  1352.   xaULONG special_flag = special & 0x0001;
  1353.  
  1354.   dec_info->xs = dec_info->ys = 0;
  1355.   dec_info->xe = imagex; dec_info->ye = imagey;
  1356.     /* Indicate we can drop these frames */
  1357.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1358.  
  1359.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  1360.   if (special_flag)
  1361.   { xaLONG x,y = imagey - 1;
  1362.     while ( y >= 0 )
  1363.     { xaUBYTE *iptr = (xaUBYTE *)(image + (y * imagex * 3)); y--; 
  1364.       x = imagex;
  1365.       while(x--) { xaULONG r,g,b, d = *dp++; d |= (*dp++)<<8;
  1366.             r = (d >> 10) & 0x1f; r = (r << 3) | (r >> 2);
  1367.             g = (d >>  5) & 0x1f; g = (g << 3) | (g >> 2);
  1368.             b =  d & 0x1f;        b = (b << 3) | (b >> 2);
  1369.     *iptr++ = (xaUBYTE)r; *iptr++ = (xaUBYTE)g; *iptr++ = (xaUBYTE)b; }
  1370.     }
  1371.   }
  1372.   else if ( (map_flag==xaFALSE) || (x11_bytes_pixel==1) )
  1373.   { xaLONG x,y = imagey - 1;
  1374.     while ( y >= 0 )
  1375.     { xaUBYTE *iptr = (xaUBYTE *)(image + y * imagex); y--; 
  1376.       x = imagex; 
  1377.       while(x--) 
  1378.       { xaULONG d = *dp++; d |= (*dp++)<<8;
  1379.         *iptr++ = (xaUBYTE)XA_RGB16_To_CLR32(d,map_flag,map,chdr);
  1380.       }
  1381.     }
  1382.   }
  1383.   else if (x11_bytes_pixel==4)
  1384.   { xaLONG x,y = imagey - 1;
  1385.     while ( y >= 0 )
  1386.     { xaULONG *iptr = (xaULONG *)(image + ((y * imagex)<<2) ); y--; 
  1387.       x = imagex; 
  1388.       while(x--) 
  1389.       { xaULONG d = *dp++; d |= (*dp++)<<8;
  1390.         *iptr++ = (xaULONG)XA_RGB16_To_CLR32(d,map_flag,map,chdr);
  1391.       }
  1392.     }
  1393.   }
  1394.   else if (x11_bytes_pixel==2)
  1395.   { xaLONG x,y = imagey - 1;
  1396.     while ( y >= 0 )
  1397.     { xaUSHORT *iptr = (xaUSHORT *)(image + ((y * imagex)<<1) ); y--; 
  1398.       x = imagex; 
  1399.       while(x--) 
  1400.       { xaULONG d = *dp++; d |= (*dp++)<<8;
  1401.         *iptr++ = (xaUSHORT)XA_RGB16_To_CLR32(d,map_flag,map,chdr);
  1402.       }
  1403.     }
  1404.   }
  1405.   if (map_flag) return(ACT_DLTA_MAPD);
  1406.   else return(ACT_DLTA_NORM);
  1407. }
  1408.  
  1409.  
  1410. /*******************
  1411.  *  RGB Decode Depth 24
  1412.  *  Actually BGR
  1413.  ******/
  1414. xaULONG
  1415. AVI_Decode_RGB24(image,delta,dsize,dec_info)
  1416. xaUBYTE *image;         /* Image Buffer. */
  1417. xaUBYTE *delta;         /* delta data. */
  1418. xaULONG dsize;          /* delta size */
  1419. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1420. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1421.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1422.   xaULONG special = dec_info->special;
  1423.   XA_CHDR *chdr = dec_info->chdr;
  1424.   xaUBYTE *dp = delta;
  1425.   xaULONG oddflag;
  1426.   xaULONG special_flag = special & 0x0001;
  1427.  
  1428.   dec_info->xs = dec_info->ys = 0;
  1429.   dec_info->xe = imagex; dec_info->ye = imagey;
  1430.     /* Indicate we can drop these frames */
  1431.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1432.  
  1433.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  1434.   oddflag = imagex & 0x01;
  1435.   if (special_flag)
  1436.   { xaLONG x,y = imagey - 1;
  1437.     while ( y >= 0 )
  1438.     { xaUBYTE *iptr = (xaUBYTE *)(image + (y * imagex * 3)); y--; 
  1439.       x = imagex;
  1440.       while(x--) { xaUBYTE r,g,b; b = *dp++; g = *dp++; r = *dp++;
  1441.        *iptr++ = r; *iptr++ = g; *iptr++ = b; }
  1442.       if (oddflag) dp++; /* pad to short words ness in RGB 8 but here? */
  1443.     }
  1444.   }
  1445.   else if ( (map_flag==xaFALSE) || (x11_bytes_pixel==1) )
  1446.   { xaLONG x,y = imagey - 1;
  1447.     while ( y >= 0 )
  1448.     { xaUBYTE *iptr = (xaUBYTE *)(image + y * imagex); y--; 
  1449.       x = imagex; 
  1450.       while(x--) 
  1451.       { xaULONG r,g,b; b = (xaULONG)*dp++; g = (xaULONG)*dp++; r = (xaULONG)*dp++;
  1452.         *iptr++ = (xaUBYTE)XA_RGB24_To_CLR32(r,g,b,map_flag,map,chdr);
  1453.       }
  1454.       if (oddflag) dp++;
  1455.     }
  1456.   }
  1457.   else if (x11_bytes_pixel==4)
  1458.   { xaLONG x,y = imagey - 1;
  1459.     while ( y >= 0 )
  1460.     { xaULONG *iptr = (xaULONG *)(image + ((y * imagex)<<2) ); y--; 
  1461.       x = imagex; 
  1462.       while(x--) 
  1463.       { xaULONG r,g,b; b = (xaULONG)*dp++; g = (xaULONG)*dp++; r = (xaULONG)*dp++;
  1464.         *iptr++ = (xaULONG)XA_RGB24_To_CLR32(r,g,b,map_flag,map,chdr);
  1465.       }
  1466.       if (oddflag) dp++;
  1467.     }
  1468.   }
  1469.   else if (x11_bytes_pixel==2)
  1470.   { xaLONG x,y = imagey - 1;
  1471.     while ( y >= 0 )
  1472.     { xaUSHORT *iptr = (xaUSHORT *)(image + ((y * imagex)<<1) ); y--; 
  1473.       x = imagex; 
  1474.       while(x--) 
  1475.       { xaULONG r,g,b; b = (xaULONG)*dp++; g = (xaULONG)*dp++; r = (xaULONG)*dp++;
  1476.         *iptr++ = (xaUSHORT)XA_RGB24_To_CLR32(r,g,b,map_flag,map,chdr);
  1477.       }
  1478.       if (oddflag) dp++;
  1479.     }
  1480.   }
  1481.   if (map_flag) return(ACT_DLTA_MAPD);
  1482.   else return(ACT_DLTA_NORM);
  1483. }
  1484.  
  1485.  
  1486. void AVI_Print_ID(fout,id)
  1487. FILE *fout;
  1488. xaLONG id;
  1489. { fprintf(fout,"%c",     (char)((id >> 24) & 0xff)   );
  1490.   fprintf(fout,"%c",     (char)((id >> 16) & 0xff)   );
  1491.   fprintf(fout,"%c",     (char)((id >>  8) & 0xff)   );
  1492.   fprintf(fout,"%c(%x)",(char) (id        & 0xff),id);
  1493. }
  1494.  
  1495.  
  1496. xaULONG AVI_Get_Color(color,map_flag,map,chdr)
  1497. xaULONG color,map_flag,*map;
  1498. XA_CHDR *chdr;
  1499. { register xaULONG clr,ra,ga,ba,tr,tg,tb;
  1500.  
  1501.   ra = (color >> 10) & 0x1f;
  1502.   ga = (color >>  5) & 0x1f;
  1503.   ba =  color & 0x1f;
  1504.   tr = (ra << 3) | (ra >> 2);
  1505.   tg = (ga << 3) | (ga >> 2);
  1506.   tb = (ba << 3) | (ba >> 2);
  1507.   if (xa_gamma_flag==xaTRUE) { tr = xa_gamma_adj[tr]>>8;  
  1508.      tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; }
  1509.  
  1510.  
  1511.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,5);
  1512.   else
  1513.   { 
  1514.     if ((cmap_color_func == 4) && (chdr))
  1515.     { register xaULONG cache_i = color & 0x7fff;
  1516.       if (cmap_cache == 0) CMAP_Cache_Init(0);
  1517.       if (chdr != cmap_cache_chdr)
  1518.       {
  1519.     CMAP_Cache_Clear();
  1520.     cmap_cache_chdr = chdr;
  1521.       }
  1522.       if (cmap_cache[cache_i] == 0xffff)
  1523.       {
  1524.         clr = chdr->coff + 
  1525.        CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,5,5,5,xaTRUE);
  1526.         cmap_cache[cache_i] = (xaUSHORT)clr;
  1527.       }
  1528.       else clr = (xaULONG)cmap_cache[cache_i];
  1529.     }
  1530.     else
  1531.     {
  1532.       if (cmap_true_to_332 == xaTRUE) 
  1533.       clr=CMAP_GET_332(ra,ga,ba,CMAP_SCALE5);
  1534.       else   clr = CMAP_GET_GRAY(ra,ga,ba,CMAP_SCALE10);
  1535.       if (map_flag) clr = map[clr];
  1536.     }
  1537.   }
  1538.   return(clr);
  1539. }
  1540.  
  1541.  
  1542. xaULONG
  1543. AVI_Decode_RLE8(image,delta,dsize,dec_info)
  1544. xaUBYTE *image;         /* Image Buffer. */
  1545. xaUBYTE *delta;         /* delta data. */
  1546. xaULONG dsize;          /* delta size */
  1547. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1548. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1549.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1550.   xaULONG opcode,mod;
  1551.   xaLONG x,y,min_x,max_x,min_y,max_y;
  1552.   xaUBYTE *dptr;
  1553.  
  1554.   max_x = max_y = 0; min_x = imagex; min_y = imagey;
  1555.   x = 0;  y = imagey - 1;
  1556.   dptr = delta;
  1557.  
  1558.   while( (y >= 0) && (dsize > 0) )
  1559.   {
  1560.     mod = *dptr++;
  1561.     opcode = *dptr++;  dsize-=2;
  1562.  
  1563. DEBUG_LEVEL2 fprintf(stdout,"MOD %x OPCODE %x <%d,%d>\n",mod,opcode,x,y);
  1564.     if (mod == 0x00)                /* END-OF-LINE */
  1565.     {
  1566.       if (opcode==0x00)
  1567.       {
  1568.         while(x > imagex) { x -=imagex; y--; }
  1569.         x = 0; y--;
  1570. DEBUG_LEVEL2 fprintf(stdout,"EOL <%d,%d>\n",x,y);
  1571.       }
  1572.       else if (opcode==0x01)            /* END Of Image */
  1573.       {
  1574.         y = -1;
  1575. DEBUG_LEVEL2 fprintf(stdout,"EOI <%d,%d>\n",x,y);
  1576.       }
  1577.       else if (opcode==0x02)            /* SKIP */
  1578.       {
  1579.         xaULONG yskip,xskip;
  1580.         xskip = *dptr++; 
  1581.         yskip = *dptr++;  dsize-=2;
  1582.         x += xskip;
  1583.         y -= yskip;
  1584. DEBUG_LEVEL2 fprintf(stdout,"SKIP <%d,%d>\n",x,y);
  1585.       }
  1586.       else                    /* ABSOLUTE MODE */
  1587.       {
  1588.         int cnt = opcode;
  1589.         
  1590.     dsize-=cnt;
  1591.         while(x >= imagex) { x -= imagex; y--; }
  1592.     if (y > max_y) max_y = y; if (x < min_x) min_x = x;
  1593.         if (map_flag==xaTRUE)
  1594.     {
  1595.       if (x11_bytes_pixel==1)
  1596.           { xaUBYTE *iptr = (xaUBYTE *)(image + (y * imagex + x) );
  1597.             while(cnt--) 
  1598.         { if (x >= imagex) { max_x = imagex; min_x = 0;
  1599.          x -= imagex; y--; iptr = (xaUBYTE *)(image+y*imagex+x); }
  1600.               *iptr++ = (xaUBYTE)map[*dptr++];  x++;
  1601.         }
  1602.       }
  1603.       else if (x11_bytes_pixel==2)
  1604.           { xaUSHORT *iptr = (xaUSHORT *)(image + ((y * imagex + x)<<1) );
  1605.             while(cnt--) 
  1606.         { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1607.         x -= imagex; y--; iptr = (xaUSHORT *)(image+y*imagex+x); }
  1608.               *iptr++ = (xaUSHORT)map[*dptr++];  x++;
  1609.         }
  1610.       }
  1611.       else /* if (x11_bytes_pixel==4) */
  1612.           { xaULONG *iptr = (xaULONG *)(image + ((y * imagex + x)<<2) );
  1613.             while(cnt--) 
  1614.         { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1615.         x -= imagex; y--; iptr = (xaULONG *)(image+y*imagex+x); }
  1616.               *iptr++ = (xaULONG)map[*dptr++];  x++;
  1617.         }
  1618.       }
  1619.         }
  1620.         else
  1621.         { xaUBYTE *iptr = (xaUBYTE *)(image + (y * imagex + x) );
  1622.           while(cnt--) 
  1623.       { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1624.         x -=imagex; y--; iptr = (xaUBYTE *)(image+y*imagex+x); }
  1625.         *iptr++ = (xaUBYTE)(*dptr++); x++;
  1626.       }
  1627.         }
  1628. DEBUG_LEVEL2 fprintf(stdout,"ABSOLUTE <%d,%d>\n",x,y);
  1629.         /* PAD to Short */
  1630.         if (opcode & 0x01) { dptr++; dsize--; }
  1631.         if (y < min_y) min_y = y; if (x > max_x) max_x = x;
  1632.       }
  1633.     }
  1634.     else                    /* ENCODED MODE */
  1635.     {
  1636.       int color,cnt;
  1637.       while(x >= imagex) { x -=imagex; y--; }
  1638.       if (y > max_y) max_y = y; if (x < min_x) min_x = x;
  1639.       cnt = mod;
  1640.       color = (map_flag==xaTRUE)?(map[opcode]):(opcode);
  1641.       if ( (map_flag==xaFALSE) || (x11_bytes_pixel==1) )
  1642.       { xaUBYTE *iptr = (xaUBYTE *)(image + (y * imagex + x) );
  1643.     xaUBYTE clr = (xaUBYTE)color;
  1644.     while(cnt--) 
  1645.     { if (x >= imagex) { max_x = imagex; min_x = 0;
  1646.         x -=imagex; y--; iptr = (xaUBYTE *)(image+y*imagex+x); }
  1647.       *iptr++ = clr; x++;
  1648.     }
  1649.       }
  1650.       else if (x11_bytes_pixel==2)
  1651.       { xaUSHORT *iptr = (xaUSHORT *)(image + ((y * imagex + x)<<1) );
  1652.     xaUSHORT clr = (xaUSHORT)color;
  1653.     while(cnt--) 
  1654.     { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1655.         x -=imagex; y--; iptr = (xaUSHORT *)(image+y*imagex+x); }
  1656.       *iptr++ = clr; x++;
  1657.     }
  1658.       }
  1659.       else /* if (x11_bytes_pixel==4) */
  1660.       { xaULONG *iptr = (xaULONG *)(image + ((y * imagex + x)<<2) );
  1661.     xaULONG clr = (xaULONG)color;
  1662.     while(cnt--) 
  1663.     { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1664.         x -=imagex; y--; iptr = (xaULONG *)(image+y*imagex+x); }
  1665.       *iptr++ = clr; x++;
  1666.     }
  1667.       }
  1668.       if (y < min_y) min_y = y; if (x > max_x) max_x = x;
  1669. DEBUG_LEVEL2 fprintf(stdout,"ABSOLUTE <%d,%d>\n",x,y);
  1670.     }
  1671.   } /* end of while */
  1672.  
  1673.   if (xa_optimize_flag == xaTRUE)
  1674.   {
  1675.     max_x++; if (max_x>imagex) max_x=imagex;
  1676.     max_y++; if (max_y>imagey) max_y=imagey;
  1677.     if ((min_x >= max_x) || (min_y >= max_y)) /* no change */
  1678.     { dec_info->xs = dec_info->ys = dec_info->xe = dec_info->ye = 0; 
  1679.             return(ACT_DLTA_NOP); }
  1680.     else { dec_info->xs=min_x; dec_info->ys=min_y; 
  1681.             dec_info->xe=max_x; dec_info->ye=max_y; }
  1682.   }
  1683.   else { dec_info->xs = dec_info->ys = 0;
  1684.      dec_info->xe = imagex; dec_info->ye = imagey; }
  1685.  
  1686.   if (map_flag) return(ACT_DLTA_MAPD);
  1687.   else return(ACT_DLTA_NORM);
  1688. }
  1689.  
  1690. /**************************************************
  1691.  * Decode Microsoft Video 1 Depth 16 Video Codec
  1692.  * XAPI Rev 0x0001
  1693.  *
  1694.  *************/
  1695. xaULONG AVI_Decode_CRAM16(image,delta,dsize,dec_info)
  1696. xaUBYTE *image;        /* Image Buffer. */
  1697. xaUBYTE *delta;        /* delta data. */
  1698. xaULONG dsize;        /* delta size */
  1699. XA_DEC_INFO *dec_info;    /* Decoder Info Header */
  1700. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1701.   xaULONG map_flag = dec_info->map_flag;    xaULONG *map = dec_info->map;
  1702.   xaULONG special = dec_info->special;
  1703.   XA_CHDR *chdr = dec_info->chdr;
  1704.   xaULONG row_dec,exitflag,changed,block_cnt;
  1705.   xaULONG code0,code1,dither = 0;
  1706.   xaLONG x,y,min_x,max_x,min_y,max_y;
  1707.   xaUBYTE *dptr;
  1708.  
  1709.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  1710.  
  1711.    /* special case dither routine - fill out a bit */
  1712.   if (   (!special) && (x11_bytes_pixel==1)
  1713.       && (chdr) && (x11_display_type == XA_PSEUDOCOLOR)
  1714.       && (cmap_color_func != 4)
  1715.       && (cmap_true_to_332 == xaTRUE) && (x11_cmap_size == 256)
  1716.       && (xa_dither_flag==xaTRUE)
  1717.      )
  1718.      dither = 1;
  1719.  
  1720.  
  1721.   changed = 0;
  1722.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  1723.   dptr = delta;
  1724.   if (special) row_dec = (3*(imagex+4))-1; else row_dec = imagex + 3; 
  1725.   x = 0;
  1726.   y = imagey - 1;
  1727.   exitflag = 0;
  1728.   block_cnt = ((imagex * imagey) >> 4) + 1;
  1729.  
  1730.   if (special == 1)
  1731.   {
  1732.     while(!exitflag)
  1733.     {
  1734.       code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1735.       if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1736.       if (y < 0) {exitflag = 1; continue; }
  1737.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1738.       { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1739.     block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1740.       }
  1741.       else /* not skip */
  1742.       { xaUBYTE *i_ptr = (xaUBYTE *)(image + 3 * (y * imagex + x) );
  1743.     if (code1 < 0x80) /* 2 or 8 color encoding */
  1744.     { xaULONG cA,cB; xaUBYTE rA0,gA0,bA0,rB0,gB0,bB0;
  1745.       AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB);
  1746.       AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); 
  1747.       if (cB & 0x8000)   /* Eight Color Encoding */
  1748.       { xaUBYTE rA1,gA1,bA1,rB1,gB1,bB1;
  1749.         register xaULONG flag = code0;
  1750.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB);
  1751.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); 
  1752.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1753.         i_ptr++; flag >>= 2;
  1754.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1755.         i_ptr -= row_dec; flag >>= 2;
  1756.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1757.         i_ptr++; flag >>= 2;
  1758.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1759.         i_ptr -= row_dec; flag = code1;
  1760.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB);
  1761.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); 
  1762.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB);
  1763.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); 
  1764.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1765.         i_ptr++; flag >>= 2;
  1766.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1767.         i_ptr -= row_dec; flag >>= 2;
  1768.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1769.         i_ptr++; flag >>= 2;
  1770.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1771.       } else /* Two Color Encoding */
  1772.       { register xaULONG flag = code0;
  1773.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1774.         i_ptr -= row_dec; flag >>= 4;
  1775.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1776.         i_ptr -= row_dec; flag = code1;
  1777.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1778.         i_ptr -= row_dec; flag >>= 4;
  1779.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1780.       }
  1781.     } /* end of 2 or 8 */
  1782.     else /* 1 color encoding (80-83) && (>=88)*/
  1783.     { xaULONG cA = (code1<<8) | code0;
  1784.       xaUBYTE r,g,b;
  1785.       AVI_Get_RGBColor(r,g,b,cA);
  1786.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1787.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1788.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1789.       AVI_CRAM_rgbC1(i_ptr,r,g,b);
  1790.     }
  1791.     changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1792.     AVI_BLOCK_INC(x,y,imagex);
  1793.       } /* end of not skip */
  1794.     } /* end of not while exit */
  1795.   } /* end of special */
  1796.   else
  1797.   {
  1798.     if (dither)
  1799.     { ColorReg *cmap = chdr->cmap;
  1800.       xaUBYTE *rnglimit = xa_byte_limit;
  1801.  
  1802.       while(!exitflag)
  1803.       { code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1804.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1805.     if (y < 0) {exitflag = 1; continue; }
  1806.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1807.     { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1808.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1809.     }
  1810.     else /* not skip */
  1811.     { xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
  1812.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1813.       { xaULONG cA,cB;
  1814.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1815.         if (cB & 0x8000)   /* Eight Color Encoding */
  1816.         { xaUBYTE cA0,cB0, cA1,cB1;
  1817.           cB0 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1818.           cA0 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1819.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1820.           cB1 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1821.           cA1 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1822.           AVI_CRAM_C4(ip,code0,cA0,cA1,cB0,cB1,row_dec);
  1823.           ip -=row_dec;
  1824.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1825.           cB0 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1826.           cA0 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1827.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1828.           cB1 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1829.           cA1 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1830.           AVI_CRAM_C4(ip,code1,cA0,cA1,cB0,cB1,row_dec);
  1831.         } else /* Two Color Encoding */
  1832.         { xaUBYTE clr0a,clr0b,clr1a,clr1b;
  1833.           xaLONG re,ge,be,r,g,b;
  1834.  
  1835.           CRAM_DITH_COL2RGB(r,g,b,cA);
  1836.           CRAM_DITH_GET_RGB(r,g,b, 0, 0, 0,clr0a);
  1837.           if (map_flag) clr0a = map[clr0a];
  1838.           CRAM_DITH_GET_ERR(r,g,b,re,ge,be,clr0a,cmap);
  1839.           CRAM_DITH_GET_RGB(r,g,b,re,ge,be,clr1a);
  1840.           if (map_flag) clr1a = map[clr1a];
  1841.  
  1842.           CRAM_DITH_COL2RGB(r,g,b,cB);
  1843.           CRAM_DITH_GET_RGB(r,g,b, 0, 0, 0,clr0b);
  1844.           if (map_flag) clr0b = map[clr0b];
  1845.           CRAM_DITH_GET_ERR(r,g,b,re,ge,be,clr0b,cmap);
  1846.           CRAM_DITH_GET_RGB(r,g,b,re,ge,be,clr1b);
  1847.           if (map_flag) clr1b = map[clr1b];
  1848.  
  1849.   *ip++ =(code0 & 0x01)?(clr0b):(clr0a); *ip++ =(code0 & 0x02)?(clr1b):(clr1a); 
  1850.   *ip++ =(code0 & 0x04)?(clr0b):(clr0a); *ip   =(code0 & 0x08)?(clr1b):(clr1a);
  1851.   ip -= row_dec; 
  1852.   *ip++ =(code0 & 0x10)?(clr1b):(clr1a); *ip++ =(code0 & 0x20)?(clr0b):(clr0a); 
  1853.   *ip++ =(code0 & 0x40)?(clr1b):(clr1a); *ip   =(code0 & 0x80)?(clr0b):(clr0a);
  1854.   ip -= row_dec;
  1855.   *ip++ =(code1 & 0x01)?(clr0b):(clr0a); *ip++ =(code1 & 0x02)?(clr1b):(clr1a); 
  1856.   *ip++ =(code1 & 0x04)?(clr0b):(clr0a); *ip   =(code1 & 0x08)?(clr1b):(clr1a);
  1857.   ip -= row_dec; 
  1858.   *ip++ =(code1 & 0x10)?(clr1b):(clr1a); *ip++ =(code1 & 0x20)?(clr0b):(clr0a); 
  1859.   *ip++ =(code1 & 0x40)?(clr1b):(clr1a); *ip   =(code1 & 0x80)?(clr0b):(clr0a);
  1860.  
  1861.         }
  1862.       } /* end of 2 or 8 */
  1863.       else /* 1 color encoding (80-83) && (>=88)*/
  1864.       { xaULONG cA = (code1<<8) | code0;
  1865.         xaUBYTE clr0,clr1;
  1866.         xaLONG re,ge,be,r,g,b;
  1867.  
  1868.         CRAM_DITH_COL2RGB(r,g,b,cA);
  1869.         CRAM_DITH_GET_RGB(r,g,b, 0, 0, 0,clr0);
  1870.         if (map_flag) clr0 = map[clr0];
  1871.         CRAM_DITH_GET_ERR(r,g,b,re,ge,be,clr0,cmap);
  1872.         CRAM_DITH_GET_RGB(r,g,b,re,ge,be,clr1);
  1873.         if (map_flag) clr1 = map[clr1];
  1874.  
  1875.  *ip++ = clr0; *ip++ = clr1; *ip++ = clr0; *ip = clr1; ip -= row_dec; 
  1876.  *ip++ = clr1; *ip++ = clr0; *ip++ = clr1; *ip = clr0; ip -= row_dec; 
  1877.  *ip++ = clr0; *ip++ = clr1; *ip++ = clr0; *ip = clr1; ip -= row_dec; 
  1878.  *ip++ = clr1; *ip++ = clr0; *ip++ = clr1; *ip = clr0; 
  1879.  
  1880.  
  1881.       }
  1882.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1883.       AVI_BLOCK_INC(x,y,imagex);
  1884.     } /* end of not skip */
  1885.       } /* end of not while exit */
  1886.     } /* end of dither */
  1887.     else if ( (x11_bytes_pixel == 1) || (map_flag == xaFALSE) )
  1888.     {
  1889.       while(!exitflag)
  1890.       { code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1891.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1892.     if (y < 0) {exitflag = 1; continue; }
  1893.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1894.     { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1895.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1896.     }
  1897.     else /* not skip */
  1898.     { xaUBYTE *i_ptr = (xaUBYTE *)(image + (y * imagex + x) );
  1899.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1900.       { xaULONG cA,cB; xaUBYTE cA0,cB0;
  1901.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1902.         cB0 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1903.         cA0 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1904.         if (cB & 0x8000)   /* Eight Color Encoding */
  1905.         { xaUBYTE cA1,cB1;
  1906.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1907.           cB1 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1908.           cA1 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1909.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1910.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1911.           cB0 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1912.           cA0 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1913.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1914.           cB1 = (xaUBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1915.           cA1 = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1916.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1917.         } else /* Two Color Encoding */
  1918.         { 
  1919.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  1920.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  1921.         }
  1922.       } /* end of 2 or 8 */
  1923.       else /* 1 color encoding (80-83) && (>=88)*/
  1924.       { xaULONG cA = (code1<<8) | code0;
  1925.         xaUBYTE clr = (xaUBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1926.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  1927.       }
  1928.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1929.       AVI_BLOCK_INC(x,y,imagex);
  1930.     } /* end of not skip */
  1931.       } /* end of not while exit */
  1932.     } /* end of 1 bytes pixel */
  1933.     else if (x11_bytes_pixel == 2)
  1934.     {
  1935.       while(!exitflag)
  1936.       {
  1937.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1938.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1939.     if (y < 0) {exitflag = 1; continue; }
  1940.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1941.     { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1942.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1943.     }
  1944.     else /* not skip */
  1945.     { xaUSHORT *i_ptr = (xaUSHORT *)(image + ((y * imagex + x) << 1) );
  1946.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1947.       { xaULONG cA,cB; xaUSHORT cA0,cB0;
  1948.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1949.         cB0 = (xaUSHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1950.         cA0 = (xaUSHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1951.         if (cB & 0x8000)   /* Eight Color Encoding */
  1952.         { xaUSHORT cA1,cB1;
  1953.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1954.           cB1 = (xaUSHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1955.           cA1 = (xaUSHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1956.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1957.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1958.           cB0 = (xaUSHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1959.           cA0 = (xaUSHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1960.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1961.           cB1 = (xaUSHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1962.           cA1 = (xaUSHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1963.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1964.         } else /* Two Color Encoding */
  1965.         { 
  1966.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  1967.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  1968.         }
  1969.       } /* end of 2 or 8 */
  1970.       else /* 1 color encoding (80-83) && (>=88)*/
  1971.       { xaULONG cA = (code1<<8) | code0;
  1972.         xaUSHORT clr = (xaUSHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1973.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  1974.       }
  1975.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1976.       AVI_BLOCK_INC(x,y,imagex);
  1977.     } /* end of not skip */
  1978.       } /* end of not while exit */
  1979.     } /* end of 2 bytes pixel */
  1980.     else if (x11_bytes_pixel == 4)
  1981.     {
  1982.       while(!exitflag)
  1983.       {
  1984.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1985.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1986.     if (y < 0) {exitflag = 1; continue; }
  1987.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1988.     { xaULONG skip = ((code1 - 0x84) << 8) + code0;
  1989.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1990.     }
  1991.     else /* not skip */
  1992.     { xaULONG *i_ptr = (xaULONG *)(image + ((y * imagex + x) << 2) );
  1993.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1994.       { xaULONG cA,cB,cA0,cB0;
  1995.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1996.         cB0 = AVI_Get_Color(cB,map_flag,map,chdr);
  1997.         cA0 = AVI_Get_Color(cA,map_flag,map,chdr);
  1998.         if (cB & 0x8000)   /* Eight Color Encoding */
  1999.         { xaULONG cA1,cB1;
  2000.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  2001.           cB1 = AVI_Get_Color(cB,map_flag,map,chdr);
  2002.           cA1 = AVI_Get_Color(cA,map_flag,map,chdr);
  2003.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  2004.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  2005.           cB0 = AVI_Get_Color(cB,map_flag,map,chdr);
  2006.           cA0 = AVI_Get_Color(cA,map_flag,map,chdr);
  2007.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  2008.           cB1 = AVI_Get_Color(cB,map_flag,map,chdr);
  2009.           cA1 = AVI_Get_Color(cA,map_flag,map,chdr);
  2010.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  2011.         } else /* Two Color Encoding */
  2012.         {
  2013.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  2014.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  2015.         }
  2016.       } /* end of 2 or 8 */
  2017.       else /* 1 color encoding (80-83) && (>=88)*/
  2018.       { xaULONG cA = (code1<<8) | code0;
  2019.         xaULONG clr = AVI_Get_Color(cA,map_flag,map,chdr);
  2020.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  2021.       }
  2022.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  2023.       AVI_BLOCK_INC(x,y,imagex);
  2024.     } /* end of not skip */
  2025.       } /* end of not while exit */
  2026.     } /* end of 4 bytes pixel */
  2027.   } /* end of not special */
  2028.   if (xa_optimize_flag == xaTRUE)
  2029.   {
  2030.     if (changed) {     dec_info->xs=min_x;    dec_info->ys=min_y - 3;
  2031.             dec_info->xe=max_x + 4;    dec_info->ye=max_y + 1; }
  2032.     else  { dec_info->xs = dec_info->ys = dec_info->xe = dec_info->ye = 0;
  2033.                         return(ACT_DLTA_NOP); }
  2034.   }
  2035.   else { dec_info->xs = dec_info->ys = 0; 
  2036.      dec_info->xe = imagex; dec_info->ye = imagey; }
  2037.   if (map_flag) return(ACT_DLTA_MAPD);
  2038.   else return(ACT_DLTA_NORM);
  2039. }
  2040.  
  2041. #define ULTI_CHROM_NORM 0
  2042. #define ULTI_CHROM_UNIQ 1
  2043. #define ULTI_STREAM0 0x0
  2044. #define ULTI_STREAM1 0x4
  2045.  
  2046. #define AVI_ULTI_C2(ip,flag,CST,c0,c1,rinc) { \
  2047.   *ip++ =(CST)((flag&0x80)?(c1):(c0)); *ip++ =(CST)(flag&0x40)?(c1):(c0); \
  2048.   *ip++ =(CST)((flag&0x20)?(c1):(c0)); *ip++ =(CST)(flag&0x10)?(c1):(c0);  \
  2049.   ip += rinc; \
  2050.   *ip++ =(CST)((flag&0x08)?(c1):(c0)); *ip++ =(CST)(flag&0x04)?(c1):(c0); \
  2051.   *ip++ =(CST)((flag&0x02)?(c1):(c0)); *ip++ =(CST)(flag&0x01)?(c1):(c0); }
  2052.  
  2053. #define AVI_ULTI_rgbC2(p,msk,r0,r1,g0,g1,b0,b1,rinc) { \
  2054.  if (msk&0x80) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2055.  if (msk&0x40) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2056.  if (msk&0x20) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2057.  if (msk&0x10) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2058.  p += rinc; \
  2059.  if (msk&0x08) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2060.  if (msk&0x04) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2061.  if (msk&0x02) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  2062.  if (msk&0x01) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} }
  2063.  
  2064. xaULONG
  2065. AVI_Decode_ULTI(image,delta,dsize,dec_info)
  2066. xaUBYTE *image;         /* Image Buffer. */
  2067. xaUBYTE *delta;         /* delta data. */
  2068. xaULONG dsize;          /* delta size */
  2069. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  2070. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  2071.   xaULONG map_flag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  2072.   xaULONG special = dec_info->special;
  2073.   XA_CHDR *chdr = dec_info->chdr;
  2074.   xaULONG r_inc,exitflag,changed;
  2075.   xaLONG block_cnt;
  2076.   xaLONG x,y,min_x,max_x,min_y,max_y;
  2077.   xaUBYTE *dptr;
  2078.   xaULONG stream_mode,chrom_mode,chrom_next_uniq;
  2079.   xaULONG bhedr,opcode,chrom;
  2080.  
  2081.   stream_mode = ULTI_STREAM0;
  2082.   chrom_mode = ULTI_CHROM_NORM;
  2083.   chrom_next_uniq = xaFALSE;
  2084.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  2085.   changed = 0;
  2086.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  2087.   dptr = delta;
  2088.   r_inc = imagex - 4; if (special) r_inc *= 3;
  2089.   x = 0;
  2090.   y = 0;
  2091.   exitflag = 0;
  2092.   block_cnt = ((imagex * imagey) >> 6) + 1;
  2093.   while(!exitflag)
  2094.   { 
  2095.     bhedr = *dptr++;
  2096.  
  2097.     if ( (y > imagey) || (block_cnt < 0) )
  2098.     {
  2099.       exitflag = 1;
  2100.       fprintf(stdout,"y = %d block_cnt = %d bhedr = %x\n",y,block_cnt,bhedr);
  2101.       continue;
  2102.     }
  2103.     else if ( (bhedr & 0xf8) == 0x70) /* ESCAPE */
  2104.     {
  2105.       switch(bhedr)
  2106.       {
  2107.     case 0x70: /* stream mode toggle */ 
  2108.       { xaULONG d;
  2109.         d = *dptr++;
  2110.         if (d==0) stream_mode = ULTI_STREAM0;
  2111.         else if (d==1) stream_mode = ULTI_STREAM1;
  2112.         else { fprintf(stdout,"ULTI: stream err %d\n",stream_mode);
  2113.                TheEnd(); }
  2114.       }
  2115.       break;
  2116.     case 0x71: /* next blk has uniq chrom */
  2117.       chrom_next_uniq = xaTRUE;
  2118.       break;
  2119.     case 0x72: /* chrom mode toggle */
  2120.       chrom_mode = (chrom_mode==ULTI_CHROM_NORM)?(ULTI_CHROM_UNIQ)
  2121.                             :(ULTI_CHROM_NORM); 
  2122.       break;
  2123.     case 0x73: /* Frame Guard */
  2124.       exitflag = 1; 
  2125.       break;
  2126.     case 0x74: /* Skip */
  2127.       { xaULONG cnt = (xaULONG)(*dptr++);
  2128.         block_cnt -= cnt;
  2129.         while(cnt--) { x += 8; if (x>=imagex) { x=0; y += 8; } }
  2130.       }
  2131.       break;
  2132.     default: /* reserved escapes */
  2133.       fprintf(stdout,"Reserved Escapes %x\n",bhedr);
  2134.       exitflag = 1;
  2135.       break;
  2136.       }
  2137.     } /* end of escape */
  2138.     else /* not escape */
  2139.     { xaULONG chrom_flag;
  2140.       xaULONG quadrant,msh;
  2141.  
  2142.       block_cnt--;
  2143.       if ( (chrom_mode==ULTI_CHROM_UNIQ) || (chrom_next_uniq == xaTRUE) )
  2144.       { 
  2145.     chrom_next_uniq = xaFALSE;
  2146.     chrom_flag = xaTRUE;
  2147.     chrom = 0; 
  2148.       }
  2149.       else 
  2150.       { 
  2151.     chrom_flag = xaFALSE; 
  2152.     if (bhedr != 0x00) chrom = *dptr++; /* read chrom */
  2153.       }
  2154.       msh = 8;
  2155.       for(quadrant=0;quadrant<4;quadrant++)
  2156.       { xaULONG tx,ty;
  2157.     /* move to quadrant */
  2158.     if (quadrant==0) {tx=x; ty=y;}
  2159.     else if (quadrant==1) ty+=4;
  2160.     else if (quadrant==2) tx+=4;
  2161.     else ty-=4;
  2162.     msh -= 2;
  2163.     opcode = ((bhedr >> msh) & 0x03) | stream_mode;
  2164.  
  2165.         /* POSSIBLY TEST FOR 0x04 or 0x00 1st */
  2166.     switch(opcode)
  2167.     {
  2168.       case 0x04:
  2169.       case 0x00:  /* Unchanged quadrant */
  2170.         /* ??? in unique chrom mode is there a chrom for this quad?? */
  2171.       break;
  2172.  
  2173.       case 0x05:
  2174.       case 0x01:  /* Homogenous/shallow LTC quadrant */
  2175.       {
  2176.         xaULONG angle,y0,y1;
  2177.         if (chrom_flag==xaTRUE) { chrom = *dptr++; }
  2178.         y0 = *dptr++;  angle = (y0 >> 6) & 0x03;  y0 &= 0x3f;
  2179.         if (angle == 0)
  2180.         {
  2181.            AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  2182.                             y0,y0,y0,y0,chrom,angle);
  2183.         }
  2184.         else
  2185.         {  y1 = y0 + 1; if (y1 > 63) y1 = 63;
  2186.            if (angle==3) angle = 12;
  2187.            else if (angle==2) angle = 6;
  2188.            else angle = 2; 
  2189.            AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  2190.                          y0,y0,y1,y1,chrom,angle);
  2191.         }
  2192.       }
  2193.       break;
  2194.  
  2195.       case 0x02:  /* LTC quadrant */
  2196.       { xaULONG angle,ltc_idx,y0,y1,y2,y3;
  2197.         xaUBYTE *tmp;
  2198.         if (chrom_flag==xaTRUE) { chrom = *dptr++; }
  2199.         ltc_idx = (*dptr++) << 8; ltc_idx |= (*dptr++);
  2200.         angle = (ltc_idx >> 12) & 0x0f; /* 4 bits angle */
  2201.         ltc_idx &= 0x0fff; /* index to 4 byte lum table */
  2202.         tmp = &avi_ulti_tab[ ( ltc_idx << 2 ) ];
  2203.         y0 = (xaULONG)(*tmp++); y1 = (xaULONG)(*tmp++); 
  2204.         y2 = (xaULONG)(*tmp++); y3 = (xaULONG)(*tmp++);
  2205.         AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  2206.                     y0,y1,y2,y3,chrom,angle);
  2207.       }
  2208.       break;
  2209.  
  2210.       case 0x03:  /* Statistical/extended LTC */
  2211.       { xaULONG d;
  2212.         if (chrom_flag==xaTRUE) { chrom = *dptr++; }
  2213.         d = *dptr++;
  2214.         if (d & 0x80) /* extend LTC */
  2215.         { xaULONG angle,y0,y1,y2,y3;
  2216.           angle = (d >> 4) & 0x07; /* 3 bits angle */
  2217.           d =  (d << 8) | (*dptr++);
  2218.           y0 = (d >> 6) & 0x3f;    y1 = d & 0x3f;
  2219.           y2 = (*dptr++) & 0x3f;   y3 = (*dptr++) & 0x3f;
  2220.           AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  2221.                          y0,y1,y2,y3,chrom,angle);
  2222.         }
  2223.         else /* Statistical pattern */
  2224.         { xaULONG y0,y1; xaUBYTE flag0,flag1;
  2225.           flag0 = *dptr++;  flag1 = (xaUBYTE)d;
  2226.           y0 = (*dptr++) & 0x3f;   y1 = (*dptr++) & 0x3f;
  2227.           /* bit 0 => y0, bit 1 = > y1. */
  2228.           /* raster scan order MSB = 0 */
  2229.           if (special)
  2230.           { xaUBYTE r0,r1,g0,g1,b0,b1;
  2231.         xaUBYTE *ip = (xaUBYTE *)(image + 3 * (ty * imagex + tx) );
  2232.             AVI_Get_Ulti_rgbColor(y0,chrom,&r0,&g0,&b0);
  2233.             AVI_Get_Ulti_rgbColor(y1,chrom,&r1,&g1,&b1);
  2234.             AVI_ULTI_rgbC2(ip,flag1,r0,r1,g0,g1,b0,b1,r_inc); 
  2235.         ip += r_inc;
  2236.             AVI_ULTI_rgbC2(ip,flag0,r0,r1,g0,g1,b0,b1,r_inc); 
  2237.           }
  2238.           else 
  2239.           { xaULONG c0,c1;
  2240.             c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  2241.             c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  2242.             if ( (x11_bytes_pixel==1) || (map_flag==xaFALSE) )
  2243.             { xaUBYTE *ip = (xaUBYTE *)(image + (ty * imagex + tx) );
  2244.               AVI_ULTI_C2(ip,flag1,xaUBYTE,c0,c1,r_inc); ip += r_inc;
  2245.               AVI_ULTI_C2(ip,flag0,xaUBYTE,c0,c1,r_inc);
  2246.         }
  2247.             else if (x11_bytes_pixel==4)
  2248.             { xaULONG *ip = (xaULONG *)(image + ((ty * imagex + tx)<<2) );
  2249.               AVI_ULTI_C2(ip,flag1,xaULONG,c0,c1,r_inc); ip += r_inc;
  2250.               AVI_ULTI_C2(ip,flag0,xaULONG,c0,c1,r_inc);
  2251.         }
  2252.             else /* (x11_bytes_pixel==2) */
  2253.             { xaUSHORT *ip = (xaUSHORT *)(image + ((ty * imagex + tx)<<1) );
  2254.               AVI_ULTI_C2(ip,flag1,xaUSHORT,c0,c1,r_inc); ip += r_inc;
  2255.               AVI_ULTI_C2(ip,flag0,xaUSHORT,c0,c1,r_inc);
  2256.         }
  2257.           }
  2258.         }
  2259.       }
  2260.       break;
  2261.  
  2262.       case 0x06:  /* Subsampled 4-luminance quadrant */
  2263.       { xaULONG y0,y1,y2,y3;
  2264.         if (chrom_flag==xaTRUE) { chrom = *dptr++; }
  2265.         y3 = (*dptr++) << 16; y3 |= (*dptr++) << 8; y3 |= (*dptr++);
  2266.         y0 = (y3 >> 18) & 0x3f;  /* NW */
  2267.         y1 = (y3 >> 12) & 0x3f;  /* NE */
  2268.         y2 = (y3 >>  6) & 0x3f;  /* SW */
  2269.         y3 &= 0x3f;   /* SE */
  2270.         AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  2271.                     y0,y1,y2,y3,chrom,0x10);
  2272.       }
  2273.       break;
  2274.  
  2275.       case 0x07:  /* 16-luminance quadrant */
  2276.       { xaULONG i,d,y[16];
  2277.         if (chrom_flag==xaTRUE) { chrom = *dptr++; }
  2278.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  2279.         y[0] = (d >> 18) & 0x3f;   y[1] = (d >> 12) & 0x3f;
  2280.         y[2] = (d >>  6) & 0x3f;   y[3] = d & 0x3f;
  2281.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  2282.         y[4] = (d >> 18) & 0x3f;   y[5] = (d >> 12) & 0x3f;
  2283.         y[6] = (d >>  6) & 0x3f;   y[7] = d & 0x3f;
  2284.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  2285.         y[8] = (d >> 18) & 0x3f;   y[9] = (d >> 12) & 0x3f;
  2286.         y[10] = (d >>  6) & 0x3f;  y[11] = d & 0x3f;
  2287.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  2288.         y[12] = (d >> 18) & 0x3f;  y[13] = (d >> 12) & 0x3f;
  2289.         y[14] = (d >>  6) & 0x3f;  y[15] = d & 0x3f;
  2290.  
  2291.         if (special)
  2292.         { xaUBYTE r,g,b,*ip = (xaUBYTE *)(image + 3 * (ty * imagex + tx) );
  2293.           for(i=0;i<16;i++)
  2294.           { AVI_Get_Ulti_rgbColor(y[i],chrom,&r,&g,&b);
  2295.         *ip++ = r; *ip++ = g; *ip++ = b; if ( (i%4)==3) ip += r_inc;
  2296.           }
  2297.         }
  2298.         else if ( (x11_bytes_pixel==1) || (map_flag==xaFALSE) )
  2299.         { xaUBYTE c,*ip = (xaUBYTE *)(image + (ty * imagex + tx) );
  2300.           for(i=0;i<16;i++)
  2301.           { c = (xaUBYTE)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  2302.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  2303.         }
  2304.         else if (x11_bytes_pixel==4)
  2305.         { xaULONG c,*ip = (xaULONG *)(image + ((ty * imagex + tx)<<2) );
  2306.           for(i=0;i<16;i++)
  2307.           { c = (xaULONG)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  2308.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  2309.         }
  2310.         else /* if (x11_bytes_pixel==2) */
  2311.         { xaUSHORT c,*ip = (xaUSHORT *)(image + ((ty * imagex + tx)<<1) );
  2312.           for(i=0;i<16;i++)
  2313.           { c = (xaUSHORT)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  2314.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  2315.         }
  2316.       }
  2317.       break;
  2318.       default:
  2319.         fprintf(stdout,"Error opcode=%x\n",opcode);
  2320.         break;
  2321.     } /* end of switch opcode */
  2322.       } /* end of 4 quadrant */
  2323.       { x += 8; if (x>=imagex) { x=0; y += 8; } }
  2324.     } /* end of not escape */
  2325.   } /* end of while */
  2326. changed = 1;
  2327.   { dec_info->xs = dec_info->ys = 0;
  2328.     dec_info->xe = imagex; dec_info->ye = imagey; }
  2329.   if (map_flag) return(ACT_DLTA_MAPD);
  2330.   else return(ACT_DLTA_NORM);
  2331. }
  2332.  
  2333.  
  2334. void AVI_ULTI_Gen_YUV()
  2335. {
  2336.   float r0,r1,b0,b1;
  2337.   xaLONG i;
  2338.  
  2339.   r0 = 16384.0 *  1.40200;
  2340.   b0 = 16384.0 *  1.77200;
  2341.   r1 = 16384.0 * -0.71414;
  2342.   b1 = 16384.0 * -0.34414;
  2343.  
  2344.   for(i=0;i<16;i++)
  2345.   { xaLONG tmp; float cr,cb;
  2346.     tmp = (i & 0x0f); 
  2347.     cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0);  
  2348.     cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0);
  2349.     ulti_Cr[i] = (xaLONG)(r0 * (float)(cr) );
  2350.     ulti_Cb[i] = (xaLONG)(b0 * (float)(cb) );
  2351.   }
  2352.   for(i=0;i<256;i++)
  2353.   { xaLONG tmp; float cr,cb;
  2354.     tmp = (i & 0x0f); 
  2355.     cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0);  
  2356.     tmp = ( (i>>4) & 0x0f); 
  2357.     cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0);
  2358.     ulti_CrCb[i] = (xaLONG)(b1 * cb + r1 * cr); 
  2359.   }
  2360. }
  2361.  
  2362. /*
  2363. > >     y = y6 / 63
  2364. > >     u = (u4 - 5) / 40
  2365. > >     v = (v4 - 6) / 34
  2366.  
  2367. I should have mentioned that these numbers come from inspecting the
  2368. weird decimals used in the specification:
  2369.  
  2370.     2.037 should be 2.032 = 63/31
  2371.  
  2372.     8.226 = 255/31
  2373.  
  2374.     6.375 = 255/40
  2375.  
  2376.     7.5   = 255/34
  2377. */
  2378.  
  2379. void AVI_Get_Ulti_rgbColor(lum,chrom,r,g,b)
  2380. xaLONG lum;
  2381. xaULONG chrom;
  2382. xaUBYTE *r,*g,*b;
  2383. { xaULONG cr,cb,ra,ga,ba;
  2384.   xaLONG tmp;
  2385.   if (cmap_true_to_gray == xaTRUE) { ra = ba = ga = lum; }
  2386.   else
  2387.   {
  2388.   lum <<= 14; 
  2389.   cb = (chrom >> 4) & 0x0f;   cr = chrom & 0x0f;
  2390.   tmp = (lum + ulti_Cr[cr]) >> 14; 
  2391.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ra = tmp;
  2392.   tmp = (lum + ulti_Cb[cb]) >> 14;
  2393.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ba = tmp;
  2394.   tmp = (lum + ulti_CrCb[chrom]) >> 14;
  2395.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ga = tmp;
  2396.   }
  2397.   *r = (xaUBYTE)( (ra << 2) | (ra >> 4) );
  2398.   *g = (xaUBYTE)( (ga << 2) | (ga >> 4) );
  2399.   *b = (xaUBYTE)( (ba << 2) | (ba >> 4) );
  2400. }
  2401.  
  2402. xaULONG AVI_Get_Ulti_Color(lum,chrom,map_flag,map,chdr)
  2403. xaLONG lum;        /* 6 bits of lum */
  2404. xaULONG chrom;        /* 8 bits of chrom */
  2405. xaULONG map_flag,*map;
  2406. XA_CHDR *chdr;
  2407. {
  2408.   register xaULONG cr,cb,clr,ra,ga,ba,tr,tg,tb;
  2409.   xaLONG tmp;
  2410.  
  2411.   if (cmap_true_to_gray == xaTRUE) { ra = ba = ga = lum; }
  2412.   else
  2413.   { xaLONG lum1 = lum << 14;
  2414.   cb = (chrom >> 4) & 0x0f;   cr = chrom & 0x0f;
  2415.   tmp = (lum1 + ulti_Cr[cr]) >> 14; 
  2416.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ra = tmp;
  2417.   tmp = (lum1 + ulti_Cb[cb]) >> 14;
  2418.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ba = tmp;
  2419.   tmp = (lum1 + ulti_CrCb[chrom]) >> 14;
  2420.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ga = tmp;
  2421.   }
  2422.  
  2423.   tr = (ra << 2) | (ra >> 4);
  2424.   tg = (ga << 2) | (ga >> 4);
  2425.   tb = (ba << 2) | (ba >> 4);
  2426.   if (xa_gamma_flag==xaTRUE) { tr = xa_gamma_adj[tr]>>8;  
  2427.      tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; }
  2428.  
  2429.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(tr,tg,tb,8);
  2430.   else
  2431.   { 
  2432.     if ((cmap_color_func == 4) && (chdr))
  2433.     { register xaULONG cache_i = ((lum << 8) | chrom) & 0x3fff;
  2434.       if (cmap_cache == 0) CMAP_Cache_Init(0);
  2435.       if (chdr != cmap_cache_chdr)
  2436.       {
  2437.     CMAP_Cache_Clear();
  2438.     cmap_cache_chdr = chdr;
  2439.       }
  2440.       if (cmap_cache[cache_i] == 0xffff)
  2441.       {
  2442.         clr = chdr->coff + 
  2443.        CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,6,6,6,xaTRUE);
  2444.         cmap_cache[cache_i] = (xaUSHORT)clr;
  2445.       }
  2446.       else clr = (xaULONG)cmap_cache[cache_i];
  2447.     }
  2448.     else
  2449.     {
  2450.       if (cmap_true_to_332 == xaTRUE) 
  2451.       clr=CMAP_GET_332(tr,tg,tb,CMAP_SCALE8);
  2452.       else   clr = CMAP_GET_GRAY(tr,tg,tb,CMAP_SCALE13);
  2453.       if (map_flag) clr = map[clr];
  2454.     }
  2455.   }
  2456.   return(clr);
  2457. }
  2458.  
  2459. #define AVI_ULTI_0000(ip,CST,c0,c1,c2,c3,r_inc) { \
  2460.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2461.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2462.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2463.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; }
  2464.  
  2465. #define AVI_ULTI_0225(ip,CST,c0,c1,c2,c3,r_inc) { \
  2466.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2467.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2468.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2469.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; }
  2470.  
  2471. #define AVI_ULTI_0450(ip,CST,c0,c1,c2,c3,r_inc) { \
  2472.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2473.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2474.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \
  2475.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; }
  2476.  
  2477. #define AVI_ULTI_0675(ip,CST,c0,c1,c2,c3,r_inc) { \
  2478.   *ip++ =(CST)c2; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2479.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  2480.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \
  2481.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c1; }
  2482.  
  2483. #define AVI_ULTI_0900(ip,CST,c0,c1,c2,c3,r_inc) { \
  2484.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2485.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \
  2486.   *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2487.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; }
  2488.  
  2489. #define AVI_ULTI_1125(ip,CST,c0,c1,c2,c3,r_inc) { \
  2490.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c2; ip += r_inc; \
  2491.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \
  2492.   *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2493.   *ip++ =(CST)c1; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; }
  2494.  
  2495. #define AVI_ULTI_1350(ip,CST,c0,c1,c2,c3,r_inc) { \
  2496.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \
  2497.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2498.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2499.   *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; }
  2500.  
  2501. #define AVI_ULTI_1575(ip,CST,c0,c1,c2,c3,r_inc) { \
  2502.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \
  2503.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2504.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2505.   *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; }
  2506.  
  2507. #define AVI_ULTI_C4(ip,CST,c0,c1,c2,c3,r_inc) { \
  2508.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2509.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2510.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2511.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; }
  2512.  
  2513. void AVI_ULTI_LTC(image,x,y,imagex,special,map_flag,map,chdr,
  2514.                     y0,y1,y2,y3,chrom,angle)
  2515. xaUBYTE *image;
  2516. xaULONG x,y,imagex,special,map_flag,*map;
  2517. XA_CHDR *chdr;
  2518. xaULONG y0,y1,y2,y3,chrom,angle;
  2519. { xaULONG r_inc;
  2520.  
  2521.   if (special)
  2522.   { xaULONG i;
  2523.     xaUBYTE *ip = (xaUBYTE *)(image + 3 * (y * imagex + x) );
  2524.     xaUBYTE r[4],g[4],b[4],*ix,idx[16];
  2525.     r_inc = 3 * (imagex - 4);
  2526.     if (angle & 0x08) /* reverse */
  2527.     { angle &= 0x07;
  2528.       AVI_Get_Ulti_rgbColor(y3,chrom,&r[0],&g[0],&b[0]);
  2529.       AVI_Get_Ulti_rgbColor(y2,chrom,&r[1],&g[1],&b[1]);
  2530.       AVI_Get_Ulti_rgbColor(y1,chrom,&r[2],&g[2],&b[2]);
  2531.       AVI_Get_Ulti_rgbColor(y0,chrom,&r[3],&g[3],&b[3]);
  2532.     }
  2533.     else
  2534.     {
  2535.       AVI_Get_Ulti_rgbColor(y0,chrom,&r[0],&g[0],&b[0]);
  2536.       if (y1==y0) {r[1]=r[0]; g[1]=g[0]; b[1]=b[0]; }
  2537.       else AVI_Get_Ulti_rgbColor(y1,chrom,&r[1],&g[1],&b[1]);
  2538.       if (y2==y1) {r[2]=r[1]; g[2]=g[1]; b[2]=b[1]; }
  2539.       else AVI_Get_Ulti_rgbColor(y2,chrom,&r[2],&g[2],&b[2]);
  2540.       if (y3==y2) {r[3]=r[2]; g[3]=g[2]; b[3]=b[2]; }
  2541.       else AVI_Get_Ulti_rgbColor(y3,chrom,&r[3],&g[3],&b[3]);
  2542.     }
  2543.     ix = idx;
  2544.     switch(angle)
  2545.     {   case 0: AVI_ULTI_0000(ix,xaUBYTE,0,1,2,3,1); break;
  2546.     case 1: AVI_ULTI_0225(ix,xaUBYTE,0,1,2,3,1); break;
  2547.     case 2: AVI_ULTI_0450(ix,xaUBYTE,0,1,2,3,1); break;
  2548.     case 3: AVI_ULTI_0675(ix,xaUBYTE,0,1,2,3,1); break;
  2549.     case 4: AVI_ULTI_0900(ix,xaUBYTE,0,1,2,3,1); break;
  2550.     case 5: AVI_ULTI_1125(ix,xaUBYTE,0,1,2,3,1); break;
  2551.     case 6: AVI_ULTI_1350(ix,xaUBYTE,0,1,2,3,1); break;
  2552.     case 7: AVI_ULTI_1575(ix,xaUBYTE,0,1,2,3,1); break;
  2553.     default: AVI_ULTI_C4(ix,xaUBYTE,0,1,2,3,1); break;
  2554.     } /* end switch */
  2555.     for(i=0;i<16;i++)
  2556.     { register xaULONG j = idx[i];
  2557.       *ip++ = r[j]; *ip++ = g[j]; *ip++ = b[j];
  2558.       if ( (i & 3) == 3 ) ip += r_inc;
  2559.     }
  2560.   }
  2561.   else 
  2562.   { xaULONG c0,c1,c2,c3;
  2563.     r_inc = imagex - 3;
  2564.     if (angle & 0x08) /* reverse */
  2565.     { angle &= 0x07;
  2566.       c0 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr);
  2567.       c1 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr);
  2568.       c2 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  2569.       c3 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  2570.     }
  2571.     else
  2572.     {
  2573.       c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  2574.       if (y1==y0) c1 = c0;
  2575.       else c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  2576.       if (y2==y1) c2 = c1;
  2577.       else c2 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr);
  2578.       if (y3==y2) c3 = c2;
  2579.       else c3 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr);
  2580.     }
  2581.  
  2582.     if ( (x11_bytes_pixel == 1) || (map_flag == xaFALSE) )
  2583.     { xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
  2584.       switch(angle)
  2585.       { case 0: AVI_ULTI_0000(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2586.     case 1: AVI_ULTI_0225(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2587.     case 2: AVI_ULTI_0450(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2588.     case 3: AVI_ULTI_0675(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2589.     case 4: AVI_ULTI_0900(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2590.     case 5: AVI_ULTI_1125(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2591.     case 6: AVI_ULTI_1350(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2592.     case 7: AVI_ULTI_1575(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2593.     default: AVI_ULTI_C4(ip,xaUBYTE,c0,c1,c2,c3,r_inc); break;
  2594.       }
  2595.     }
  2596.     else if (x11_bytes_pixel == 4)
  2597.     { xaULONG *ip = (xaULONG *)(image + ((y * imagex + x) << 2) );
  2598.       switch(angle)
  2599.       { case 0: AVI_ULTI_0000(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2600.     case 1: AVI_ULTI_0225(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2601.     case 2: AVI_ULTI_0450(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2602.     case 3: AVI_ULTI_0675(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2603.     case 4: AVI_ULTI_0900(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2604.     case 5: AVI_ULTI_1125(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2605.     case 6: AVI_ULTI_1350(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2606.     case 7: AVI_ULTI_1575(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2607.     default: AVI_ULTI_C4(ip,xaULONG,c0,c1,c2,c3,r_inc); break;
  2608.       }
  2609.     }
  2610.     else /* if (x11_bytes_pixel == 2) */
  2611.     { xaUSHORT *ip = (xaUSHORT *)(image + ( (y * imagex + x) << 1) );
  2612.       switch(angle)
  2613.       { case 0: AVI_ULTI_0000(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2614.     case 1: AVI_ULTI_0225(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2615.     case 2: AVI_ULTI_0450(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2616.     case 3: AVI_ULTI_0675(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2617.     case 4: AVI_ULTI_0900(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2618.     case 5: AVI_ULTI_1125(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2619.     case 6: AVI_ULTI_1350(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2620.     case 7: AVI_ULTI_1575(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2621.     default: AVI_ULTI_C4(ip,xaUSHORT,c0,c1,c2,c3,r_inc); break;
  2622.       }
  2623.     } /* end of shorts */
  2624.   } /* end of not special */
  2625. } /* end */
  2626.  
  2627. xaULONG RIFF_Read_AUDS(xin,size,auds_hdr)
  2628. XA_INPUT *xin;
  2629. xaLONG size;
  2630. AUDS_HDR *auds_hdr;
  2631. { xaULONG ret = xaTRUE;
  2632.   auds_hdr->format    = xin->Read_LSB_U16(xin);
  2633.   auds_hdr->channels    = xin->Read_LSB_U16(xin);
  2634.   auds_hdr->rate    = xin->Read_LSB_U32(xin);
  2635.   auds_hdr->av_bps    = xin->Read_LSB_U32(xin);
  2636.   auds_hdr->blockalign    = xin->Read_LSB_U16(xin);
  2637.   auds_hdr->samps_block    = 1;
  2638.   auds_hdr->byte_cnt    = 0;
  2639.  
  2640.   if (size & 0x01) size++;
  2641.   if (size >= 0x10) { auds_hdr->size = xin->Read_LSB_U16(xin); size -= 0x10; }
  2642.   else  { auds_hdr->size  = 8; size -= 0x0e; }
  2643.  
  2644.  
  2645.   DEBUG_LEVEL2 fprintf(stdout,"ret = %x\n",ret);
  2646.   if (auds_hdr->format == WAVE_FORMAT_PCM)
  2647.   {
  2648.     if (auds_hdr->size == 8) avi_audio_type = XA_AUDIO_LINEAR;
  2649.     else if (auds_hdr->size == 16) avi_audio_type = XA_AUDIO_SIGNED;
  2650.     else avi_audio_type = XA_AUDIO_INVALID;
  2651.   }
  2652.   else if (auds_hdr->format == WAVE_FORMAT_ADPCM)
  2653.   { int i;
  2654.     if (auds_hdr->size == 4) avi_audio_type = XA_AUDIO_ADPCM;
  2655.     else avi_audio_type = XA_AUDIO_INVALID;
  2656.     auds_hdr->ext_size    = xin->Read_LSB_U16(xin);
  2657.     auds_hdr->samps_block = xin->Read_LSB_U16(xin);
  2658.     auds_hdr->num_coefs   = xin->Read_LSB_U16(xin);    size -= 6;
  2659. #ifdef POD_USE
  2660.     if (xa_verbose) fprintf(stdout," MSADPM_EXT: sampblk %d numcoefs %d\n",
  2661.                 auds_hdr->samps_block, auds_hdr->num_coefs);
  2662. #endif
  2663.     for(i=0; i < auds_hdr->num_coefs; i++)
  2664.     { xaSHORT coef1, coef2;
  2665.       coef1 = xin->Read_LSB_U16(xin);
  2666.       coef2 = xin->Read_LSB_U16(xin);            size -= 4;
  2667. #ifdef POD_USE
  2668.       if (xa_verbose) fprintf(stdout,"%d) coef1 %d coef2 %d\n",
  2669.                             i, coef1, coef2);
  2670. #endif
  2671.     }
  2672.   }
  2673.   else if (auds_hdr->format == WAVE_FORMAT_DVI_ADPCM)
  2674.   {
  2675.     avi_audio_type = XA_AUDIO_DVI;
  2676.     auds_hdr->ext_size    = xin->Read_LSB_U16(xin);
  2677.     auds_hdr->samps_block = xin->Read_LSB_U16(xin);    size -= 4;
  2678.     if (xa_verbose) fprintf(stdout," DVI: samps per block %d\n",
  2679.                         auds_hdr->samps_block);
  2680.   }
  2681.   else if (auds_hdr->format == WAVE_FORMAT_MULAW)
  2682.   {
  2683.     avi_audio_type = XA_AUDIO_ULAW;
  2684.   }
  2685.   else
  2686.   {
  2687.     avi_audio_type = XA_AUDIO_INVALID;
  2688.     ret = xaFALSE;
  2689.   }
  2690.   avi_audio_freq  = auds_hdr->rate;
  2691.   avi_audio_chans = auds_hdr->channels;
  2692.   if (auds_hdr->size == 8) avi_audio_bps = 1;
  2693.   else if (auds_hdr->size == 16) avi_audio_bps = 2;
  2694.   else if (auds_hdr->size == 32) avi_audio_bps = 4;
  2695.   else if (auds_hdr->size == 4) avi_audio_bps = 1;
  2696.   else avi_audio_bps = 1000 + auds_hdr->size;
  2697.   avi_audio_end   = 0;
  2698.   if (avi_audio_chans > 2) ret = xaFALSE;
  2699.   if (avi_audio_bps > 2) ret = xaFALSE;
  2700.  
  2701.   if (xa_verbose)
  2702.   {
  2703.     fprintf(stdout,"  Audio Codec: "); AVI_Print_Audio_Type(auds_hdr->format);
  2704.     fprintf(stdout," Rate=%d Chans=%d bps=%d\n",
  2705.             avi_audio_freq,avi_audio_chans,auds_hdr->size);
  2706. #ifdef POD_USE
  2707.   fprintf(stdout,"        block_align %d\n",auds_hdr->blockalign);
  2708. #endif
  2709.   }
  2710. /* modify type */
  2711.   if (avi_audio_chans==2)    avi_audio_type |= XA_AUDIO_STEREO_MSK;
  2712.   if (avi_audio_bps==2)        avi_audio_type |= XA_AUDIO_BPS_2_MSK;
  2713.   DEBUG_LEVEL2 fprintf(stdout,"size = %d ret = %x\n",size,ret);
  2714.   while(size > 0) { (void)xin->Read_U8(xin); size--; }
  2715.   return(ret);
  2716. }
  2717.  
  2718. void AVI_Print_Audio_Type(type)
  2719. xaULONG type;
  2720. {
  2721.   switch(type)
  2722.   {
  2723.     case WAVE_FORMAT_PCM: fprintf(stdout,"PCM"); break;
  2724.     case WAVE_FORMAT_ADPCM: fprintf(stdout,"MS ADPCM"); break;
  2725.     case WAVE_FORMAT_DVI_ADPCM: fprintf(stdout,"DVI ADPCM"); break;
  2726.     case WAVE_FORMAT_ALAW: fprintf(stdout,"ALAW"); break;
  2727.     case WAVE_FORMAT_MULAW: fprintf(stdout,"ULAW"); break;
  2728.     case WAVE_FORMAT_OKI_ADPCM: fprintf(stdout,"OKI_ADPCM"); break;
  2729.     case IBM_FORMAT_MULAW: fprintf(stdout,"IBM_ULAW"); break;
  2730.     case IBM_FORMAT_ALAW: fprintf(stdout,"IBM_ALAW"); break;
  2731.     case IBM_FORMAT_ADPCM: fprintf(stdout,"IBM_ADPCM"); break;
  2732.     default: fprintf(stdout,"Unknown(%x)",type); break;
  2733.   }
  2734. }
  2735.  
  2736. static xaUBYTE avi_ulti_lin[11] = {2,3,5,6,7,8,11,14,17,20,255};
  2737. static xaUBYTE avi_ulti_lo[15]  = {4,5,6,7,8,11,14,17,20,23,26,29,32,36,255};
  2738. static xaUBYTE avi_ulti_hi[14]  = {6,8,11,14,17,20,23,26,29,32,35,40,46,255};
  2739.  
  2740. xaULONG AVI_Ulti_Check(val,ptr)
  2741. xaULONG val;
  2742. xaUBYTE *ptr;
  2743.   while(*ptr != 255) if ((xaULONG)(*ptr++) == val) return(1);
  2744.   return(0);
  2745. }
  2746.  
  2747. void AVI_Ulti_Gen_LTC()
  2748. { xaLONG ys,ye,ydelta;
  2749.   xaUBYTE *utab;
  2750.   if (avi_ulti_tab==0) avi_ulti_tab = (xaUBYTE *)malloc(16384 * sizeof(xaUBYTE));
  2751.   else return;
  2752.   if (avi_ulti_tab==0) TheEnd1("AVI_Ulti_Gen_LTC: malloc err");
  2753.   utab = avi_ulti_tab;
  2754.   for(ys=0; ys <= 63; ys++)
  2755.   {
  2756.     for(ye=ys; ye <= 63; ye++)
  2757.     {
  2758.       ydelta = ye - ys;
  2759.       if (AVI_Ulti_Check(ydelta,avi_ulti_lin))
  2760.     { xaULONG yinc = (ydelta + 1) / 3;
  2761.       *utab++ = ys; *utab++ = ys + yinc; *utab++ = ye - yinc; *utab++ = ye;
  2762.     }
  2763.       if (AVI_Ulti_Check(ydelta,avi_ulti_lo)==1)
  2764.     { xaLONG y1,y2;
  2765.           float yd = (float)(ydelta);
  2766.       /* 1/4 */
  2767.       y1 = ye - (xaLONG)(  (2 * yd - 5.0) / 10.0 );
  2768.       y2 = ye - (xaLONG)(  (    yd - 5.0) / 10.0 );
  2769.       *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye;
  2770.       /* 1/2 */
  2771.       y2 = ys + (xaLONG)(  (2 * yd + 5.0) / 10.0 );
  2772.       *utab++ = ys; *utab++ = y2; *utab++ = y1; *utab++ = ye;
  2773.       /* 3/4 */
  2774.       y1 = ys + (xaLONG)(  (    yd + 5.0) / 10.0 );
  2775.       *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye;
  2776.     }
  2777.       if (AVI_Ulti_Check(ydelta,avi_ulti_hi)==1)
  2778.     {
  2779.       *utab++ = ys; *utab++ = ye; *utab++ = ye; *utab++ = ye;
  2780.       *utab++ = ys; *utab++ = ys; *utab++ = ye; *utab++ = ye;
  2781.       *utab++ = ys; *utab++ = ys; *utab++ = ys; *utab++ = ye;
  2782.     }
  2783.     }
  2784.   }
  2785. DEBUG_LEVEL2
  2786. { xaULONG i;
  2787.   xaUBYTE *tmp = avi_ulti_tab;
  2788.   for(i=0;i<4096;i++)
  2789.   {
  2790.     fprintf(stdout,"%02x %02x %02x %02x\n",tmp[0],tmp[1],tmp[2],tmp[3]);
  2791.     tmp += 4;
  2792.   }
  2793. }
  2794. }
  2795.  
  2796.  
  2797. /* my shifted version */
  2798. static xaUBYTE xmpg_def_intra_qtab[64] = {
  2799.          8,16,19,22,22,26,26,27,
  2800.         16,16,22,22,26,27,27,29,
  2801.         19,22,26,26,27,29,29,35,
  2802.         22,24,27,27,29,32,34,38,
  2803.         26,27,29,29,32,35,38,46,
  2804.         27,29,34,34,35,40,46,56,
  2805.         29,34,34,37,40,48,56,69,
  2806.         34,37,38,40,48,58,69,83 };
  2807.  
  2808.  
  2809. /************************
  2810.  *  Find next MPEG start code. If buf is non-zero, get data from
  2811.  *  buf. Else use the file pointer, xin.
  2812.  *
  2813.  ****/
  2814. xaLONG xmpg_get_start_code(xin,bufp,buf_size)
  2815. XA_INPUT *xin;
  2816. xaUBYTE **bufp;
  2817. xaLONG *buf_size;
  2818. { xaLONG d,size = *buf_size;
  2819.   xaULONG state = 0;
  2820.   xaULONG flag = 0;
  2821.   xaUBYTE *buf;
  2822.  
  2823.   if (bufp) {buf = *bufp; flag = 1;}
  2824.   while(size > 0)
  2825.   { if (flag) d = (xaLONG)((*buf++) & 0xff);
  2826.     else d = xin->Read_U8(xin);
  2827.     size--;
  2828.     if (state == 3) 
  2829.     { *buf_size = size; 
  2830.       if (flag) *bufp = buf; 
  2831.       return(d); 
  2832.     }
  2833.     else if (state == 2)
  2834.     { if (d==0x01) state = 3;
  2835.       else if (d==0x00) state = 2;
  2836.       else state = 0;
  2837.     }
  2838.     else
  2839.     { if (d==0x00) state++;
  2840.       else state = 0;
  2841.     }
  2842.   }
  2843.   if (flag) *bufp = buf;
  2844.   *buf_size = 0;
  2845.   return((xaLONG)(-1));
  2846. }
  2847.  
  2848.  
  2849. /* FROM xa_mpg.c */
  2850. extern xaUBYTE mpg_dlta_buf;
  2851. extern xaULONG mpg_dlta_size;
  2852.  
  2853. xaULONG xmpg_avi_once = 0;
  2854.  
  2855. xaULONG AVI_XMPG_00XM(xin,avi,ck_size,act,anim_hdr)
  2856. XA_INPUT *xin;
  2857. XA_ANIM_SETUP *avi;
  2858. xaLONG ck_size;
  2859. XA_ACTION *act;
  2860. XA_ANIM_HDR *anim_hdr;
  2861. { MPG_SEQ_HDR *seq_hdr = 0;
  2862.   MPG_PIC_HDR *pic_hdr = 0;
  2863.   MPG_SLICE_HDR *slice = 0;
  2864.   ACT_DLTA_HDR *dlta_hdr = 0;
  2865.   XA_ACTION *tmp_act;
  2866.   xaLONG i,code;
  2867.  
  2868.   act->type = ACT_NOP; /* in case of failure */
  2869.  
  2870.   /* Allocate and fake out SEQ Header */
  2871.   tmp_act = ACT_Get_Action(anim_hdr,ACT_NOP);
  2872.   seq_hdr = (MPG_SEQ_HDR *)malloc(sizeof(MPG_SEQ_HDR));
  2873.   tmp_act->data = (xaUBYTE *)seq_hdr;
  2874.   tmp_act = 0;
  2875.   seq_hdr->width  = avi->imagex;
  2876.   seq_hdr->height = avi->imagey;
  2877.   for(i=0; i < 64;i++)
  2878.   { seq_hdr->intra_qtab[i] = xmpg_def_intra_qtab[i];  /* NO-ZIG */
  2879.   }
  2880.  
  2881.   { xaUBYTE *strd_buf = avi_strd;
  2882.   i = avi_strd_cursz; 
  2883.   if (strd_buf == 0) i = 0; /* redundant checking */
  2884.   while(i > 0) 
  2885.   {
  2886.     code = xmpg_get_start_code(xin,&strd_buf,&i);
  2887.     if (code < 0) break;
  2888.     if (code == MPG_SEQ_START)
  2889.     { /* 12 w, 12 h, 4 aspect, 4 picrate, 18 bitrate etc */
  2890.       xaLONG d;
  2891.       xaULONG width,height,pic_rate,pic_size;
  2892.       width = height = pic_rate = 0;
  2893.       d = *strd_buf++;  i--;
  2894.       if (d >= 0) { width = (d & 0xff) << 4; }
  2895.       else break;
  2896.  
  2897.       d = *strd_buf++;  i--;
  2898.       if (d >= 0) { width |= (d >> 4) & 0x0f; height = (d & 0x0f) << 8; }
  2899.       else { width = 0; break; }
  2900.  
  2901.       d = *strd_buf++;  i--;
  2902.       if (d >= 0) { height |= (d & 0xff); }
  2903.       else break;
  2904.  
  2905.       if ( (width != avi->imagex) || (height != avi->imagey) )
  2906.       {
  2907.     if (xmpg_avi_once==0)  
  2908.     { xmpg_avi_once = 1; 
  2909.       fprintf(stdout,"AVI XMPG: Mismatched image size\n");
  2910.     }
  2911.         seq_hdr->width  = width;
  2912.         seq_hdr->height = height;
  2913.         avi->imagex = width;
  2914.         avi->imagey = height;
  2915.         if (width > avi->max_imagex) avi->max_imagex = width;
  2916.         if (height > avi->max_imagey) avi->max_imagey = height;
  2917.         /* readjust pic_size if necessary(ie it gets larger) */
  2918.         pic_size = width * height;
  2919.         if ( (avi->pic) && (pic_size > avi->pic_size))
  2920.         { xaUBYTE *tmp_pic;
  2921.           if ( (cmap_true_map_flag == xaTRUE) && (avi->depth > 8) )
  2922.                tmp_pic = (xaUBYTE *)realloc( avi->pic, (3 * pic_size));
  2923.           else tmp_pic = (xaUBYTE *)realloc( avi->pic, (XA_PIC_SIZE(pic_size)) );
  2924.           if (tmp_pic == 0) TheEnd1("AVI_XMPG: pic malloc err");
  2925.           avi->pic = tmp_pic;
  2926.       avi->pic_size = pic_size;  /* only size it grew */
  2927.         }
  2928.       }
  2929.       break;
  2930.     }
  2931.   } /* end of while */
  2932.   } /* end of test strd */
  2933.  
  2934.   if (ck_size & 0x01) ck_size++; /* PAD */
  2935.  
  2936.   DEBUG_LEVEL1 fprintf(stdout,"AVI_XMPG_00XM:\n");
  2937.   /* Loop on MPEG start codes */
  2938.   while(ck_size > 0) 
  2939.   {
  2940.     code = xmpg_get_start_code(xin, (xaUBYTE **)(0),&ck_size);
  2941.     if (code < 0) 
  2942.     {fprintf(stdout,"XMPG: start err\n");  return(xaFALSE); }
  2943.  
  2944.     if (code == MPG_USR_START)
  2945.         { DEBUG_LEVEL1 fprintf(stdout,"USR START:\n"); }
  2946.     else if (code == MPG_EXT_START)
  2947.         { DEBUG_LEVEL1 fprintf(stdout,"EXT START:\n"); }
  2948.     else if (code == MPG_SEQ_END)
  2949.         { DEBUG_LEVEL1 fprintf(stdout,"SEQ END:\n"); }
  2950.     else if (code == MPG_PIC_START)
  2951.     { xaLONG d;
  2952.       DEBUG_LEVEL1 fprintf(stdout,"PIC START:\n");
  2953.       /* Allocate and fake out PIC Header */
  2954.       /* 10bits time  3bits type  16bits vbv_delay */
  2955.  
  2956.       /* NOTE: MPG_PIC_HDR includes 1 SLICE_HDR free of charge */
  2957.       dlta_hdr = (ACT_DLTA_HDR *)
  2958.         malloc( sizeof(ACT_DLTA_HDR) + sizeof(MPG_PIC_HDR) );
  2959.       if (dlta_hdr == 0) TheEnd1("AVI XMPG dlta malloc err");
  2960.       act->data = (xaUBYTE *)dlta_hdr;
  2961.       dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  2962.       dlta_hdr->fpos = dlta_hdr->fsize = 0;
  2963.  
  2964.       pic_hdr = (MPG_PIC_HDR *)(dlta_hdr->data);
  2965.  
  2966.       pic_hdr->seq_hdr = seq_hdr;
  2967.       pic_hdr->slice_1st = pic_hdr->slice_last = 0;
  2968.       pic_hdr->slice_cnt = 0;
  2969.       pic_hdr->slices[0].fsize = 0;
  2970.       pic_hdr->slices[0].act   = 0;
  2971.       pic_hdr->full_forw_flag = 0;
  2972.       pic_hdr->forw_r_size = pic_hdr->forw_f = 0;
  2973.       pic_hdr->full_back_flag = 0;
  2974.       pic_hdr->back_r_size = pic_hdr->back_f = 0;
  2975.       /* Assume ONLY I Frames */
  2976.       d = xin->Read_U8(xin); ck_size--;  /* 8 bits time */
  2977.       d = xin->Read_U8(xin); ck_size--;  /* 2b time, 3b type, 3b vbv */
  2978.       d >>= 3;  pic_hdr->type = d & 0x07;
  2979.       if (pic_hdr->type != 0x01) fprintf(stdout,"XMPG: Not I Frame err\n");
  2980.       d = xin->Read_U8(xin); ck_size--;  /* 8b vbv */
  2981.       d = xin->Read_U8(xin); ck_size--;  /* 5b vbv */
  2982.       AVI_Add_Frame( avi->vid_time, avi->vid_timelo, act);
  2983.     }
  2984.     else if ((code >= MPG_MIN_SLICE) && (code <= MPG_MAX_SLICE))
  2985.     { MPG_SLICE_HDR *last_slice;
  2986.       if (pic_hdr == 0) 
  2987.     { fprintf(stdout,"XMPG: no pic hdr\n"); return(xaFALSE); }
  2988.  
  2989.       DEBUG_LEVEL1 fprintf(stdout,"SLICE START:\n");
  2990.       last_slice = slice = pic_hdr->slices;
  2991.       last_slice++;
  2992.       last_slice->fpos = 0;
  2993.       last_slice->fsize = 0;
  2994.       last_slice->act = 0;
  2995.  
  2996.       slice->next = 0;
  2997.       slice->act  = 0;
  2998.       if (pic_hdr->slice_1st) pic_hdr->slice_last->next = slice;
  2999.       else                    pic_hdr->slice_1st = slice;
  3000.       pic_hdr->slice_last = slice;
  3001.       pic_hdr->slice_cnt++;
  3002.       slice->vert_pos = code & 0xff;
  3003.       slice->fpos = xin->Get_FPos(xin);  /* get file position */
  3004.       if (ck_size > avi->max_fvid_size) avi->max_fvid_size = ck_size;
  3005.       slice->fsize = ck_size;
  3006.  
  3007.  
  3008.       if ( (xa_buffer_flag == xaFALSE) && (xa_file_flag == xaFALSE) )
  3009.       { xaUBYTE *tmp;
  3010.         tmp_act = ACT_Get_Action(anim_hdr,ACT_NOP);
  3011.         tmp = (xaUBYTE *)malloc( ck_size );
  3012.     if (tmp==0) TheEnd1("MPG: alloc err 3");
  3013.         xin->Read_Block(xin,(char *)tmp,ck_size);
  3014.         tmp_act->data = tmp;
  3015.         slice->act = tmp_act;
  3016.     tmp_act = 0;
  3017.       }
  3018.       else xin->Seek_FPos(xin,ck_size,1); /* else skip over bytes */
  3019.       AVI_Add_Frame( avi->vid_time, avi->vid_timelo, act);
  3020.       ck_size = 0;
  3021.     } /* end of slice */
  3022.   } /* end of while */
  3023.   if (slice == 0) 
  3024.     {fprintf(stdout,"XMPG: failed before slice\n");  return(xaFALSE); }
  3025.  
  3026.   act->type = ACT_DELTA; /* in case of failure */
  3027.   return(xaTRUE);
  3028. }
  3029.  
  3030. /****************************
  3031.  *
  3032.  *
  3033.  ****************/
  3034. static xaLONG    AVI_Codec_Query(codec)
  3035. XA_CODEC_HDR *codec;
  3036. { xaLONG ret = CODEC_UNKNOWN;    /* default */
  3037.   codec->extra = 0;
  3038.   codec->xapi_rev = 0x0001;
  3039.   codec->decoder = 0;
  3040.   codec->description = 0;
  3041.   codec->avi_read_ext = 0;
  3042.  
  3043.   switch(codec->compression)
  3044.   {
  3045.     case RIFF_RGB:  
  3046.     case RIFF_rgb:  
  3047.     codec->compression    = RIFF_RGB;
  3048.     codec->description    = "Microsoft RGB";
  3049.     ret = CODEC_SUPPORTED;
  3050.     if (codec->depth == 4)        codec->decoder = AVI_Decode_RGB4;
  3051.     else if (codec->depth == 8)    codec->decoder = AVI_Decode_RGB8;
  3052.     else if (codec->depth == 16)    codec->decoder = AVI_Decode_RGB16;
  3053.     else if (codec->depth == 24)    codec->decoder = AVI_Decode_RGB24;
  3054.     else ret = CODEC_UNSUPPORTED;
  3055.     break;
  3056.  
  3057.     case RIFF_RLE8: 
  3058.     case RIFF_rle8: 
  3059.     codec->compression    = RIFF_RLE8;
  3060.     codec->description    = "Microsoft RLE8";
  3061.     ret = CODEC_SUPPORTED;
  3062.     if (codec->depth == 8)        codec->decoder = AVI_Decode_RLE8;
  3063.     else ret = CODEC_UNSUPPORTED;
  3064.     break;
  3065.  
  3066.     case RIFF_wham:
  3067.     case RIFF_WHAM:
  3068.     case RIFF_msvc:
  3069.     case RIFF_MSVC:
  3070.     case RIFF_cram:
  3071.     case RIFF_CRAM:
  3072.     codec->compression    = RIFF_CRAM;
  3073.     codec->description    = "Microsoft Video 1";
  3074.     ret = CODEC_SUPPORTED;
  3075.         if (codec->depth == 8)        codec->decoder = AVI_Decode_CRAM;
  3076.     else if (codec->depth == 16)    codec->decoder = AVI_Decode_CRAM16;
  3077.     else ret = CODEC_UNSUPPORTED;
  3078.     codec->x = 4 * ((codec->x + 3)/4);
  3079.     codec->y = 4 * ((codec->y + 3)/4);
  3080.     JPG_Setup_Samp_Limit_Table(codec->anim_hdr);
  3081.     break;
  3082.  
  3083.     /* POD NOTE: this needs special case later on. Work In?? */
  3084.     case RIFF_xmpg:
  3085.     case RIFF_XMPG:
  3086.     codec->compression    = RIFF_XMPG;
  3087.     codec->description    = "Editable MPEG";
  3088.     ret = CODEC_SUPPORTED;
  3089.     codec->decoder        = MPG_Decode_I;
  3090.     codec->x = 4 * ((codec->x + 3)/4);
  3091.     codec->y = 4 * ((codec->y + 3)/4);
  3092.     XA_Gen_YUV_Tabs(codec->anim_hdr);
  3093.     JPG_Alloc_MCU_Bufs(codec->anim_hdr,codec->x,codec->y,xaTRUE);
  3094.     JPG_Setup_Samp_Limit_Table(codec->anim_hdr);
  3095.     MPG_Init_Stuff(codec->anim_hdr);
  3096.     break;
  3097.  
  3098.     case RIFF_ulti:
  3099.     case RIFF_ULTI: 
  3100.     codec->compression    = RIFF_ULTI;
  3101.     codec->description    = "IBM Ultimotion";
  3102.     ret = CODEC_SUPPORTED;
  3103.     if (codec->depth == 16) 
  3104.     {
  3105.       codec->decoder = AVI_Decode_ULTI;
  3106.       codec->x = 8 * ((codec->x + 7)/8);
  3107.       codec->y = 8 * ((codec->y + 7)/8);
  3108.       AVI_ULTI_Gen_YUV();  /* generate tables POD NOTE: free chain 'em */
  3109.       AVI_Ulti_Gen_LTC();
  3110.     }
  3111.     else ret = CODEC_UNSUPPORTED;
  3112.     break;
  3113.  
  3114.     case RIFF_jpeg: 
  3115.     case RIFF_JPEG:
  3116.     codec->compression    = RIFF_JPEG;
  3117.     codec->description    = "JFIF JPEG";
  3118.     codec->xapi_rev = 0x0002;
  3119.     ret = CODEC_SUPPORTED;
  3120.     if ( (codec->depth == 8) || (codec->depth == 24) )
  3121.     {
  3122.       codec->avi_read_ext = AVI_JPEG_Read_Ext;
  3123.       codec->decoder = JFIF_Decode_JPEG;
  3124.       codec->x = 4 * ((codec->x + 3)/4);
  3125.       codec->y = 2 * ((codec->y + 1)/2);
  3126.       if (codec->depth > 8)    XA_Gen_YUV_Tabs(codec->anim_hdr);
  3127.       else    codec->avi_ctab_flag = xaFALSE;
  3128.       XA_Gen_YUV_Tabs(codec->anim_hdr);
  3129.       JPG_Alloc_MCU_Bufs(codec->anim_hdr,codec->x,0,xaFALSE);
  3130.       JPG_Setup_Samp_Limit_Table(codec->anim_hdr);
  3131.     }
  3132.     else ret = CODEC_UNSUPPORTED;
  3133.     break;
  3134.  
  3135.     case RIFF_IJPG: 
  3136.     codec->compression    = RIFF_IJPG;
  3137.     codec->description    = "Intergraph JPEG";
  3138.     codec->xapi_rev = 0x0002;
  3139.     ret = CODEC_SUPPORTED;
  3140.     if (codec->depth == 24)
  3141.     {
  3142.       codec->avi_read_ext = AVI_IJPG_Read_Ext;
  3143.           codec->extra = (void *)(0x11);
  3144.           codec->decoder = JFIF_Decode_JPEG;
  3145.       codec->x = 4 * ((codec->x + 3)/4);
  3146.       codec->y = 2 * ((codec->y + 1)/2);
  3147.       XA_Gen_YUV_Tabs(codec->anim_hdr);
  3148.       JPG_Alloc_MCU_Bufs(codec->anim_hdr,codec->x,0,xaFALSE);
  3149.     }
  3150.     else ret = CODEC_UNSUPPORTED;
  3151.     break;
  3152.  
  3153.     case RIFF_azpr:
  3154.     case RIFF_rpza:
  3155.     codec->compression    = RIFF_rpza;
  3156.     codec->description    = "Apple Video(RPZA)";
  3157.     ret = CODEC_SUPPORTED;
  3158.     if ( (codec->depth == 16) || (codec->depth == 24))
  3159.     { codec->decoder = QT_Decode_RPZA;
  3160.       codec->x = 4 * ((codec->x + 3)/4);
  3161.       codec->y = 4 * ((codec->y + 3)/4);
  3162.       JPG_Setup_Samp_Limit_Table(codec->anim_hdr);
  3163.     }
  3164.     else ret = CODEC_UNSUPPORTED;
  3165.     break;
  3166.  
  3167.     case RIFF_mJPG:
  3168.     case RIFF_MJPG:
  3169.     codec->compression    = RIFF_MJPG;
  3170.     codec->description    = "Motion JPEG";
  3171.     codec->xapi_rev = 0x0002;
  3172.     ret = CODEC_SUPPORTED;
  3173.     codec->avi_read_ext = AVI_JPEG_Read_Ext;
  3174.     codec->extra    = (void *)(0x00);  /* Changed Later */
  3175.         codec->decoder = JFIF_Decode_JPEG;
  3176.     codec->x = 4 * ((codec->x + 3)/4);
  3177.     codec->y = 2 * ((codec->y + 1)/2);
  3178.     if (codec->depth > 8)    XA_Gen_YUV_Tabs(codec->anim_hdr);
  3179.     else    codec->avi_ctab_flag = xaFALSE;
  3180.     JPG_Alloc_MCU_Bufs(codec->anim_hdr,codec->x,0,xaFALSE);
  3181.     break;
  3182.     default:
  3183.     ret = CODEC_UNKNOWN;
  3184.     break;
  3185.   }
  3186.   return(ret);
  3187. }
  3188.  
  3189. /****************************
  3190.  *
  3191.  ****************/
  3192. static xaLONG AVI_UNK_Codec_Query(codec)
  3193. XA_CODEC_HDR *codec;
  3194. { xaLONG ret = CODEC_UNKNOWN;    /* default */
  3195.   codec->extra = 0;
  3196.   codec->xapi_rev = 0x0001;
  3197.   codec->decoder = 0;
  3198.   codec->description = 0;
  3199.   codec->avi_read_ext = 0;
  3200.  
  3201.   switch(codec->compression)
  3202.   {
  3203.     case RIFF_RLE4: 
  3204.     case RIFF_rle4: 
  3205.     codec->compression    = RIFF_RLE4;
  3206.     codec->description    = "Microsoft RLE4";
  3207.     ret = CODEC_UNSUPPORTED;
  3208.     break;
  3209.     case RIFF_cvid: 
  3210.     case RIFF_CVID: 
  3211.     codec->compression    = RIFF_CVID;
  3212.     codec->description    = "Radius Cinepak";
  3213.     ret = CODEC_UNSUPPORTED;
  3214.     break;
  3215.     case RIFF_rt21: 
  3216.     case RIFF_RT21: 
  3217.     codec->compression    = RIFF_RT21;
  3218.     codec->description    = "Intel Indeo R2.1";
  3219.     ret = CODEC_UNSUPPORTED;
  3220.     break;
  3221.     case RIFF_iv41: 
  3222.     case RIFF_IV41: 
  3223.     codec->compression    = RIFF_IV41;
  3224.     codec->description    = "Intel Indeo R4.1";
  3225.     ret = CODEC_UNSUPPORTED;
  3226.     break;
  3227.     case RIFF_iv31: 
  3228.     case RIFF_IV31: 
  3229.     codec->compression    = RIFF_IV32;
  3230.     codec->description    = "Intel Indeo R3.1";
  3231.     ret = CODEC_UNSUPPORTED;
  3232.     break;
  3233.     case RIFF_iv32: 
  3234.     case RIFF_IV32: 
  3235.     codec->compression    = RIFF_IV32;
  3236.     codec->description    = "Intel Indeo R3.2";
  3237.     ret = CODEC_UNSUPPORTED;
  3238.     break;
  3239.     case RIFF_YVU9: 
  3240.     case RIFF_YUV9: 
  3241.     codec->compression    = RIFF_YUV9;
  3242.     codec->description    = "Intel Raw(YUV9)";
  3243.     ret = CODEC_UNSUPPORTED;
  3244.     break;
  3245.     case RIFF_cyuv: 
  3246.     codec->compression    = RIFF_cyuv;
  3247.     codec->description    = "Creative Video Blaster CYUV";
  3248.     ret = CODEC_UNSUPPORTED;
  3249.     break;
  3250.     case RIFF_VDOW: 
  3251.     codec->compression    = RIFF_VDOW;
  3252.     codec->description    = "VDONet Video";
  3253.     ret = CODEC_UNSUPPORTED;
  3254.     break;
  3255.  
  3256.     case RIFF_MVI1:
  3257.     case RIFF_mvi1:
  3258.     case RIFF_MPIX:
  3259.     codec->compression    = RIFF_MVI1;
  3260.     codec->description    = "Motion Pixels";
  3261.     ret = CODEC_UNSUPPORTED;
  3262.     break;
  3263.  
  3264.     default:
  3265.     break;
  3266.   }
  3267.   return(ret);
  3268. }
  3269.  
  3270. /****************************
  3271.  * Function for reading the JPEG and MJPG AVI header extension.
  3272.  *
  3273.  ****************/
  3274. static xaULONG AVI_JPEG_Read_Ext(xin,anim_hdr)
  3275. XA_INPUT *xin;
  3276. void *anim_hdr;
  3277. { xaULONG offset, jsize, format, cspace, bits, hsubsamp,vsubsamp;
  3278.   offset   = xin->Read_LSB_U32(xin);
  3279.   jsize    = xin->Read_LSB_U32(xin);
  3280.   format   = xin->Read_LSB_U32(xin);
  3281.   cspace   = xin->Read_LSB_U32(xin);
  3282.   bits     = xin->Read_LSB_U32(xin);
  3283.   hsubsamp = xin->Read_LSB_U32(xin);
  3284.   vsubsamp = xin->Read_LSB_U32(xin);
  3285.  
  3286.   DEBUG_LEVEL1 
  3287.   {
  3288.     fprintf(stdout,"M/JPG: offset %x jsize %x format %x ",
  3289.                         offset,jsize,format);
  3290.     fprintf(stdout,"cspace %x bits %x hsub %x vsub %x\n", 
  3291.                     cspace,bits,hsubsamp,vsubsamp);
  3292.   }
  3293.   return(28);  /* return number of bytes read */
  3294. }
  3295.  
  3296. /****************************
  3297.  * Function for reading the JPEG and MJPG AVI header extension.
  3298.  *
  3299.  ****************/
  3300. static xaULONG AVI_IJPG_Read_Ext(xin,anim_hdr)
  3301. XA_INPUT *xin;
  3302. void *anim_hdr;
  3303. { xaULONG offset, jsize, format, cspace, ret_size;
  3304.   offset = xin->Read_LSB_U32(xin);
  3305.   jsize  = xin->Read_LSB_U32(xin);
  3306.   format = xin->Read_LSB_U32(xin);
  3307.   cspace = xin->Read_LSB_U32(xin);
  3308.   DEBUG_LEVEL1
  3309.   {
  3310.     fprintf(stdout,"IJPG: offset %x jsize %x format %x cspace %x\n",
  3311.                         offset,jsize,format,cspace);
  3312.   }
  3313.   ret_size = 16;
  3314.   JFIF_Read_IJPG_Tables(xin);
  3315.   ret_size += 128;
  3316.   return(ret_size);
  3317. }
  3318.  
  3319.       /*** Check if Stream chunk or handle other unknown chunks */
  3320. xaULONG AVI_Stream_Chunk(xin,anim_hdr,avi,ck_id,ck_size,fname)
  3321. XA_INPUT *xin;
  3322. XA_ANIM_HDR *anim_hdr;
  3323. XA_ANIM_SETUP *avi;
  3324. xaLONG ck_id;
  3325. xaLONG ck_size;
  3326. char *fname;
  3327. { xaULONG stream_id = ck_id & RIFF_FF00;
  3328.   xaULONG stream_type,stream_ok;
  3329.   xaLONG  stream_num = -1;
  3330.   XA_ACTION *act;
  3331.  
  3332.   /*** Potentially get stream_type */
  3333.   switch(stream_id)
  3334.   {
  3335.     case RIFF_00:    stream_num = 0; break;
  3336.     case RIFF_01:    stream_num = 1; break;
  3337.     case RIFF_02:    stream_num = 2; break;
  3338.     case RIFF_03:    stream_num = 3; break;
  3339.     case RIFF_04:    stream_num = 4; break;
  3340.     case RIFF_05:    stream_num = 5; break;
  3341.     case RIFF_06:    stream_num = 6; break;
  3342.     case RIFF_07:    stream_num = 7; break;
  3343.     default:         stream_num = -1; break;
  3344.   }
  3345.   if (stream_num >= 0)
  3346.   { stream_type = avi_stream_type[stream_num];
  3347.     stream_ok   = avi_stream_ok[stream_num]; 
  3348.   }
  3349.   else { stream_type = 0; stream_ok   = xaFALSE; }
  3350.  
  3351. /* POD exit early if stream not OK - re do this mess */
  3352.  
  3353.   switch(stream_type)
  3354.   {
  3355.     case RIFF_vids:
  3356.     if (stream_ok == xaFALSE)  /* ignore chunk */
  3357.     { if (ck_size & 0x01) ck_size++;
  3358.       xin->Seek_FPos(xin,ck_size,1);
  3359.     }
  3360.     else
  3361.     { act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  3362.       if (avi->compression == RIFF_XMPG)
  3363.       { xaULONG ret;
  3364.     ret = AVI_XMPG_00XM(xin,avi,ck_size,act,anim_hdr);
  3365.     if (ret==xaFALSE) return(xaFALSE);
  3366.     MPG_Setup_Delta(avi,fname,act);
  3367.       }
  3368.       else
  3369.       { ACT_DLTA_HDR *dlta_hdr = 
  3370.     AVI_Read_00DC(xin,avi,ck_size,act,-1,stream_num);
  3371.     if (act->type == ACT_NOP) break;
  3372.     if (dlta_hdr == 0)        return(xaFALSE);
  3373.     ACT_Setup_Delta(avi,act,dlta_hdr,xin);
  3374.       }
  3375.     }
  3376.     break;
  3377.  
  3378.     case RIFF_auds:
  3379.     { xaULONG snd_size = ck_size;
  3380.       auds_hdr.byte_cnt += ck_size;
  3381.       if (ck_size & 0x01) ck_size++;
  3382.       if (ck_size == 0) break;
  3383.       if ((avi_audio_attempt==xaTRUE) && (stream_ok==xaTRUE))
  3384.       { xaLONG ret;
  3385.     if (xa_file_flag==xaTRUE)
  3386.     { xaLONG rets, cur_fpos = xin->Get_FPos(xin);
  3387.       rets = XA_Add_Sound(anim_hdr,0,avi_audio_type, 
  3388.                 cur_fpos, avi_audio_freq, snd_size, 
  3389.                 &avi->aud_time,&avi->aud_timelo,
  3390.                 auds_hdr.blockalign, auds_hdr.samps_block);
  3391.       if (rets==xaFALSE) avi_audio_attempt = xaFALSE;
  3392.       xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  3393.       if (snd_size > avi->max_faud_size) avi->max_faud_size = snd_size;
  3394.     }
  3395.     else
  3396.     { xaUBYTE *snd = (xaUBYTE *)malloc(ck_size);
  3397.       if (snd==0) TheEnd1("AVI: snd malloc err");
  3398.       ret = xin->Read_Block(xin, snd, ck_size);
  3399.       if (ret != ck_size) fprintf(stdout,"AVI: snd rd err\n");
  3400.       else
  3401.       { int rets; /*NOTE: don't free snd */
  3402.         rets = XA_Add_Sound(anim_hdr,snd,avi_audio_type, -1,
  3403.                 avi_audio_freq, snd_size, 
  3404.                 &avi->aud_time, &avi->aud_timelo,
  3405.                 auds_hdr.blockalign, auds_hdr.samps_block);
  3406.         if (rets==xaFALSE) avi_audio_attempt = xaFALSE;
  3407.       }
  3408.     }
  3409.     if (avi_audio_attempt == xaTRUE) avi_has_audio = xaTRUE;
  3410.       } /* valid audio */
  3411.       else xin->Seek_FPos(xin,ck_size,1);
  3412.     }
  3413.     break;/* break out - spotlights, sirens, rifles - but he...*/
  3414.  
  3415.     case 0x00:   /* NOT A STREAM */
  3416.       DEBUG_LEVEL2 
  3417.       {
  3418.         fprintf(stdout,"AVI: unknown chunk ");
  3419.         AVI_Print_ID(stdout,ck_id);
  3420.         fprintf(stdout,"\n");
  3421.       }
  3422.       if (ck_size & 0x01) ck_size++;
  3423.       xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  3424.       break;
  3425.  
  3426.     /* Unsupported or Unknown stream */
  3427.     case RIFF_pads:
  3428.     case RIFF_txts:
  3429.     default:
  3430.       if (ck_size & 0x01) ck_size++;
  3431.       xin->Seek_FPos(xin,ck_size,1); /* move past this chunk */
  3432.       break;
  3433.   } /* end of switch */
  3434.   return(xaTRUE);
  3435.  
  3436.  
  3437. /* POD todo */
  3438.       /*** Check if Stream chunk or handle other unknown chunks */
  3439.  
  3440. xaULONG AVI_Read_IDX1(xin,anim_hdr,avi,ck_size,fname)
  3441. XA_INPUT *xin;
  3442. XA_ANIM_HDR *anim_hdr;
  3443. XA_ANIM_SETUP *avi;
  3444. xaLONG ck_size;
  3445. char *fname;
  3446. { xaULONG i,cnt, minoff;
  3447.   xaULONG stream_id, stream_type, stream_ok;
  3448.   XA_ACTION *act;
  3449.   AVI_INDEX_ENTRY *idx;
  3450.   xaLONG tmp_fpos;
  3451.   xaLONG stream_num = -1;
  3452.  
  3453.   cnt = ck_size >> 4;
  3454.   idx = (AVI_INDEX_ENTRY *)malloc(cnt * sizeof(AVI_INDEX_ENTRY));
  3455.   if (idx == 0) TheEnd1("AVI: malloc err");
  3456.  
  3457. DEBUG_LEVEL1 fprintf(stdout,"IDX1 cnt = %d\n",cnt);
  3458.  
  3459.   minoff = 0xffffffff;
  3460.   for(i=0; i<cnt; i++)
  3461.   { idx[i].ckid        = xin->Read_MSB_U32(xin);
  3462.     idx[i].flags    = xin->Read_LSB_U32(xin);
  3463.     idx[i].offset    = xin->Read_LSB_U32(xin);
  3464.     idx[i].size        = xin->Read_LSB_U32(xin);
  3465.     if (idx[i].offset < minoff) minoff = idx[i].offset;
  3466.  
  3467.     DEBUG_LEVEL2 fprintf(stdout,"CKID %x off %x size %x\n",
  3468.             idx[i].ckid, idx[i].offset, idx[i].size);
  3469.   }
  3470.  
  3471.   /* The IDX1 chunk either references from the start of the file
  3472.    * OR from the start of the MOVI LIST. How do you tell which 
  3473.    * to do, you ask? You can't. You just have to take an educated
  3474.    * guess.
  3475.    */
  3476.   if (minoff >= avi_movi_offset) avi_movi_offset = 0;
  3477.   avi_movi_offset += 8;  /* skip over chunk's id and size */
  3478.  
  3479.  /* just in case extra bytes */
  3480.   ck_size -= (cnt << 4);
  3481.   while(ck_size--) (void)(xin->Read_U8(xin));
  3482.   tmp_fpos = xin->Get_FPos(xin);  /* save for later */
  3483.  
  3484. DEBUG_LEVEL2 fprintf(stdout,"movi_offset = %x\n",avi_movi_offset);
  3485.  
  3486.   for(i=0; i<cnt; i++)
  3487.   {
  3488.     idx[i].offset += avi_movi_offset;
  3489.     
  3490.     stream_id         = idx[i].ckid & RIFF_FF00;
  3491.     /*** Potentially get stream_type */
  3492.    switch(stream_id)
  3493.    {
  3494.      case RIFF_00:       stream_num = 0; break;
  3495.      case RIFF_01:       stream_num = 1; break;
  3496.      case RIFF_02:       stream_num = 2; break;
  3497.      case RIFF_03:       stream_num = 3; break;
  3498.      case RIFF_04:       stream_num = 4; break;
  3499.      case RIFF_05:       stream_num = 5; break;
  3500.      case RIFF_06:       stream_num = 6; break;
  3501.      case RIFF_07:       stream_num = 7; break;
  3502.      default:            stream_num = -1; break;
  3503.    }
  3504.    if (stream_num >= 0)
  3505.    { stream_type = avi_stream_type[stream_num];
  3506.      stream_ok   = avi_stream_ok[stream_num];
  3507.    }
  3508.    else { stream_type = 0; stream_ok   = xaFALSE; }
  3509.  
  3510.     if (stream_ok == xaFALSE) continue; /* POD NEW: back to for( */
  3511.  
  3512.     switch(stream_type)
  3513.     {
  3514.       case RIFF_vids:
  3515.       { act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  3516.         if (avi->compression == RIFF_XMPG)
  3517.         { xaULONG ret;
  3518.       ret = AVI_XMPG_00XM(xin,avi,idx[i].size,act,anim_hdr); /* POD offset */
  3519.       if (ret==xaFALSE) return(xaFALSE);
  3520.       MPG_Setup_Delta(avi,fname,act);
  3521.         }
  3522.         else
  3523.         { ACT_DLTA_HDR *dlta_hdr = 
  3524.           AVI_Read_00DC(xin,avi, idx[i].size, act, idx[i].offset,
  3525.                 stream_num);
  3526.       if (act->type == ACT_NOP) break;
  3527.       if (dlta_hdr == 0)        return(xaFALSE);
  3528.       ACT_Setup_Delta(avi,act,dlta_hdr,xin);
  3529.         }
  3530.       }
  3531.       break;
  3532.  
  3533.       case RIFF_auds:
  3534.       { xaULONG snd_size = idx[i].size;
  3535.         auds_hdr.byte_cnt += idx[i].size;
  3536.         if (avi_audio_attempt==xaTRUE)
  3537.         { xaLONG ret;
  3538.       if (xa_file_flag==xaTRUE)
  3539.       { xaLONG rets, cur_fpos = idx[i].offset;
  3540.         rets = XA_Add_Sound(anim_hdr,0,avi_audio_type, 
  3541.                 cur_fpos, avi_audio_freq, snd_size, 
  3542.                 &avi->aud_time,&avi->aud_timelo,
  3543.                 auds_hdr.blockalign, auds_hdr.samps_block);
  3544.         if (rets==xaFALSE) avi_audio_attempt = xaFALSE;
  3545.         if (snd_size > avi->max_faud_size) avi->max_faud_size = snd_size;
  3546.       }
  3547.       else
  3548.       { xaUBYTE *snd = (xaUBYTE *)malloc(snd_size);
  3549.         if (snd==0) TheEnd1("AVI: snd malloc err");
  3550.  
  3551.         ret = xin->Seek_FPos(xin, idx[i].offset, 0);
  3552.  
  3553.         DEBUG_LEVEL2 fprintf(stdout,"AUDS offset %x size %x ret %x\n",
  3554.             idx[i].offset,snd_size,ret);
  3555.  
  3556.         ret = xin->Read_Block(xin, snd, snd_size);
  3557.         if (ret != snd_size) fprintf(stdout,"AVI: snd rd err\n");
  3558.         else
  3559.         { int rets; /*NOTE: don't free snd */
  3560.           rets = XA_Add_Sound(anim_hdr,snd,avi_audio_type, -1,
  3561.                 avi_audio_freq, snd_size, 
  3562.                 &avi->aud_time, &avi->aud_timelo,
  3563.                 auds_hdr.blockalign, auds_hdr.samps_block);
  3564.           if (rets==xaFALSE) avi_audio_attempt = xaFALSE;
  3565.         }
  3566.       }
  3567.         } /* valid audio */
  3568.     if (avi_audio_attempt == xaTRUE) avi_has_audio = xaTRUE;
  3569.       }
  3570.       break;/* break out - spotlights, sirens, rifles - but he...*/
  3571.     } /* end of switch */
  3572.   }
  3573.   free(idx);
  3574.   xin->Seek_FPos(xin, tmp_fpos, 0);
  3575.   return(xaTRUE);
  3576. }
  3577.  
  3578.