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

  1.  
  2. /*
  3.  * xa_movi.c
  4.  *
  5.  * Copyright (C) 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.  
  19. /*******************************
  20.  * Revision
  21.  *
  22.  *
  23.  ********************************/
  24.  
  25.  
  26. #include "xa_movi.h" 
  27.  
  28. xaULONG MOVI_Read_File();
  29. MOVI_FRAME *MOVI_Add_Frame();
  30. void MOVI_Free_Frame_List();
  31. void ACT_Setup_Delta();
  32.  
  33. float MOVI_Read_Float();
  34. xaULONG MOVI_Read_Int();
  35. xaULONG MOVI_Read_I_Compression();
  36. xaULONG MOVI_Read_A_Compression();
  37. xaULONG MOVI_Read_Header();
  38. xaULONG MOVI_Read_Header2();
  39. xaULONG MOVI_Read_Header3();
  40. xaULONG MOVI_Parse_MOVI_HDR();
  41. xaULONG MOVI_Parse_MOVI_I_HDR();
  42. xaULONG MOVI_Parse_MOVI_A_HDR();
  43. xaULONG MOVI_Read_Index2();
  44. xaULONG MOVI_Read_Index3();
  45. void MOVI_Add_Video_Frames();
  46. void MOVI_Add_Audio_Frames();
  47. xaULONG MOVI_Get_Color();
  48. extern void CMAP_Cache_Init();
  49. extern void CMAP_Cache_Clear();
  50. extern void JPG_Setup_Samp_Limit_Table();
  51.  
  52.  
  53. /* CODEC ROUTINES */
  54. xaULONG MOVI_Decode_MVC1();
  55. extern xaULONG JFIF_Decode_JPEG();
  56. extern xaULONG FLI_Decode_BLACK();
  57. extern void XA_Gen_YUV_Tabs();
  58. extern JPG_Alloc_MCU_Bufs();
  59. extern jpg_search_marker();
  60.  
  61. XA_ACTION *ACT_Get_Action();
  62. XA_CHDR *ACT_Get_CMAP();
  63. XA_CHDR *CMAP_Create_332();
  64. XA_CHDR *CMAP_Create_422();
  65. XA_CHDR *CMAP_Create_Gray();
  66. void ACT_Add_CHDR_To_Action();
  67. void ACT_Setup_Mapped();
  68. void ACT_Get_CCMAP();
  69. XA_CHDR *CMAP_Create_CHDR_From_True();
  70. xaULONG CMAP_Find_Closest();
  71. xaUBYTE *UTIL_RGB_To_FS_Map();
  72. xaUBYTE *UTIL_RGB_To_Map();
  73.  
  74. void  UTIL_FPS_2_Time();
  75. extern XA_ANIM_SETUP *XA_Get_Anim_Setup();
  76. void XA_Free_Anim_Setup();
  77.  
  78. extern xaLONG xa_dither_flag;
  79. extern xaUBYTE  *xa_byte_limit;
  80.  
  81. static xaULONG movi_audio_attempt;
  82. static xaULONG movi_audio_type;
  83. static xaULONG movi_audio_freq;
  84. static xaULONG movi_audio_chans;
  85. static xaULONG movi_audio_bps;
  86. xaULONG XA_Add_Sound();
  87.  
  88. #define MOVI_ICOMP_UNK    0
  89. #define MOVI_ICOMP_MVC1    1
  90. #define MOVI_ICOMP_MVC2    2
  91. #define MOVI_ICOMP_JPEG    10
  92.  
  93. #define MOVI_ACOMP_UNK    0
  94. #define MOVI_ACOMP_100    100
  95. #define MOVI_ACOMP_401     401
  96. #define MOVI_ACOMP_402     402
  97.  
  98. static xaULONG movi_frame_cnt;
  99. static MOVI_FRAME *movi_frame_start,*movi_frame_cur;
  100.  
  101. MOVI_FRAME *MOVI_Add_Frame(time,timelo,act)
  102. xaULONG time,timelo;
  103. XA_ACTION *act;
  104. {
  105.   MOVI_FRAME *fframe;
  106.  
  107.   fframe = (MOVI_FRAME *) malloc(sizeof(MOVI_FRAME));
  108.   if (fframe == 0) TheEnd1("MOVI_Add_Frame: malloc err");
  109.  
  110.   fframe->time   = time;
  111.   fframe->timelo = timelo;
  112.   fframe->act = act;
  113.   fframe->next = 0;
  114.  
  115.   if (movi_frame_start == 0) movi_frame_start = fframe;
  116.   else movi_frame_cur->next = fframe;
  117.  
  118.   movi_frame_cur = fframe;
  119.   movi_frame_cnt++;
  120.   return(fframe);
  121. }
  122.  
  123. void MOVI_Free_Frame_List(fframes)
  124. MOVI_FRAME *fframes;
  125. {
  126.   MOVI_FRAME *ftmp;
  127.   while(fframes != 0)
  128.   {
  129.     ftmp = fframes;
  130.     fframes = fframes->next;
  131.     FREE(ftmp,0xA000);
  132.   }
  133. }
  134.  
  135.  
  136. xaULONG MOVI_Read_File(fname,anim_hdr,audio_attempt)
  137. char *fname;
  138. XA_ANIM_HDR *anim_hdr;
  139. xaULONG audio_attempt;    /* xaTRUE if audio is to be attempted */
  140. { XA_INPUT *xin = anim_hdr->xin;
  141.   xaLONG i,t_time;
  142.   xaULONG t_timelo;
  143.   XA_ANIM_SETUP *movi;
  144.   MOVI_HDR   movi_hdr;
  145.   
  146.   movi = XA_Get_Anim_Setup();
  147.   movi->vid_time = XA_GET_TIME( 100 ); /* default */
  148.   movi->compression    = MOVI_ICOMP_UNK;
  149.  
  150.   movi_frame_cnt    = 0;
  151.   movi_frame_start    = 0;
  152.   movi_frame_cur    = 0;
  153.   movi_audio_attempt    = audio_attempt;
  154.  
  155.   movi_hdr.version    = 0;
  156.   movi_hdr.a_hdr    = 0;
  157.   movi_hdr.i_hdr    = 0;
  158.  
  159.   if (MOVI_Read_Header(xin,anim_hdr,movi,&movi_hdr) == xaFALSE)
  160.   { xin->Close_File(xin);
  161.     return(xaFALSE);
  162.   }
  163.  
  164.   if (movi_hdr.version == 3)
  165.   {  if (MOVI_Read_Index3(xin,anim_hdr,movi,&movi_hdr)==xaFALSE) 
  166.                             return(xaFALSE);
  167.   }
  168.   else if (movi_hdr.version == 2)
  169.   {  if (MOVI_Read_Index2(xin,anim_hdr,movi,&movi_hdr)==xaFALSE) 
  170.                             return(xaFALSE);
  171.   }
  172.   else 
  173.   { xin->Close_File(xin);
  174.     return(xaFALSE);
  175.   }
  176.  
  177.   movi->cmap_frame_num = movi_hdr.i_hdr->frames / cmap_sample_cnt;
  178.  
  179.   MOVI_Add_Video_Frames(xin,anim_hdr,movi,&movi_hdr);
  180.   MOVI_Add_Audio_Frames(xin,anim_hdr,movi,&movi_hdr);
  181.  
  182.   xin->Close_File(xin);
  183.   if (movi_hdr.a_hdr) 
  184.   { if (movi_hdr.a_hdr->off)
  185.     { free(movi_hdr.a_hdr->off);
  186.       free(movi_hdr.a_hdr->size);
  187.     }
  188.     free(movi_hdr.a_hdr); movi_hdr.a_hdr = 0; 
  189.   } 
  190.   if (movi_hdr.i_hdr) 
  191.   { if (movi_hdr.i_hdr->off)
  192.     { free(movi_hdr.i_hdr->off);
  193.       free(movi_hdr.i_hdr->size);
  194.     }
  195.     free(movi_hdr.i_hdr); movi_hdr.i_hdr = 0;
  196.   } 
  197.  
  198.   if (movi_frame_cnt == 0)
  199.   { 
  200.     fprintf(stderr,"MOVI: No supported video frames exist in this file.\n");
  201.     return(xaFALSE);
  202.   }
  203.  
  204.   anim_hdr->frame_lst = (XA_FRAME *)
  205.                 malloc( sizeof(XA_FRAME) * (movi_frame_cnt+1));
  206.   if (anim_hdr->frame_lst == NULL) TheEnd1("MOVI_Read_File: frame malloc err");
  207.  
  208.   movi_frame_cur = movi_frame_start;
  209.   i = 0;
  210.   t_time = 0;
  211.   t_timelo = 0;
  212.   while(movi_frame_cur != 0)
  213.   {
  214.     if (i > movi_frame_cnt)
  215.     {
  216.       fprintf(stderr,"MOVI_Read_Anim: frame inconsistency %d %d\n",
  217.                 i,movi_frame_cnt);
  218.       break;
  219.     }
  220.     anim_hdr->frame_lst[i].time_dur = movi_frame_cur->time;
  221.     anim_hdr->frame_lst[i].zztime = t_time;
  222.     t_time += movi_frame_cur->time;
  223.     t_timelo += movi_frame_cur->timelo;
  224.     while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
  225.     anim_hdr->frame_lst[i].act = movi_frame_cur->act;
  226.     movi_frame_cur = movi_frame_cur->next;
  227.     i++;
  228.   }
  229.   anim_hdr->imagex = movi->imagex;
  230.   anim_hdr->imagey = movi->imagey;
  231.   anim_hdr->imagec = movi->imagec;
  232.   anim_hdr->imaged = 8; /* nop */
  233.   anim_hdr->frame_lst[i].time_dur = 0;
  234.   anim_hdr->frame_lst[i].zztime = -1;
  235.   anim_hdr->frame_lst[i].act  = 0;
  236.   anim_hdr->loop_frame = 0;
  237.   if (!(xin->load_flag & XA_IN_LOAD_BUF)) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  238.   if (xin->load_flag & XA_IN_LOAD_FILE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  239.   anim_hdr->anim_flags |= ANIM_FULL_IM;
  240.   anim_hdr->max_fvid_size = movi->max_fvid_size;
  241.   anim_hdr->max_faud_size = movi->max_faud_size;
  242.   anim_hdr->fname = anim_hdr->name;
  243.   if (i > 0) 
  244.   {
  245.     anim_hdr->last_frame = i - 1;
  246.     anim_hdr->total_time = anim_hdr->frame_lst[i-1].zztime
  247.                 + anim_hdr->frame_lst[i-1].time_dur;
  248.   }
  249.   else
  250.   {
  251.     anim_hdr->last_frame = 0;
  252.     anim_hdr->total_time = 0;
  253.   }
  254.   MOVI_Free_Frame_List(movi_frame_start);
  255.   XA_Free_Anim_Setup(movi);
  256. /* POD TBD  Free movi_hdr */
  257.   return(xaTRUE);
  258. } /* end of read file */
  259.  
  260. /********************
  261.  *
  262.  *********************/
  263. float MOVI_Read_Float(xin,size)
  264. XA_INPUT *xin;
  265. xaULONG size;
  266. { float fret = 0.0;
  267.   float scale = 0.1;
  268.  
  269.  /** integer part */
  270.  while(size--)
  271.  { xaULONG dat = xin->Read_U8(xin);
  272.    DEBUG_LEVEL1 fprintf(stderr,"<%x>",dat);
  273.    if ( (dat >= 0x30) && (dat <= 0x39)) 
  274.             fret = (10.0 * fret) + (float)(dat - 0x30);
  275.    else if (dat <= 0) return(fret);
  276.    else break;
  277.  }
  278.  /** fractional part */
  279.  DEBUG_LEVEL1 fprintf(stderr,"<.>");
  280.  while(size--)
  281.  { xaULONG dat = xin->Read_U8(xin);
  282.    DEBUG_LEVEL1 fprintf(stderr,"<%x>",dat);
  283.    if ( (dat >= 0x30) && (dat <= 0x39)) 
  284.    {
  285.      fret += scale * (float)(dat - 0x30);
  286.      scale /= 10.0;
  287.    }
  288.    else break;
  289.  }
  290.  DEBUG_LEVEL1 fprintf(stderr,"size %x\n",size);
  291.  return(fret);
  292. }
  293.  
  294.  
  295. /********************
  296.  *
  297.  *********************/
  298. xaULONG MOVI_Read_Int(xin,size)
  299. XA_INPUT *xin;
  300. xaULONG size;
  301. { xaULONG ret = 0;
  302.  while(size--)
  303.  { xaULONG dat = xin->Read_U8(xin);
  304.    if ( (dat >= 0x30) && (dat <= 0x39)) ret = (10 * ret) + (dat - 0x30);
  305.    else break;
  306.  }
  307.  return(ret);
  308. }
  309.  
  310. /********************
  311.  *
  312.  *********************/
  313. xaULONG MOVI_Read_I_Compression(xin,size)
  314. XA_INPUT *xin;
  315. xaULONG size;
  316. { xaULONG ret = 0;
  317.   if (size >= 256) 
  318.   { fprintf(stderr,"MOVI: string to long %d\n",size); 
  319.     while(size--) (void)(xin->Read_U8(xin));
  320.   }
  321.   else
  322.   { char tbuf[256]; char *p = tbuf;
  323.     while(size--) *p++ = (char)(xin->Read_U8(xin) & 0xff);
  324.     if (strcmp(tbuf,"1") == 0)        ret = MOVI_ICOMP_MVC1;
  325.     else if (strcmp(tbuf,"10") == 0)    ret = MOVI_ICOMP_JPEG;
  326.     else if (strcmp(tbuf,"MVC2") == 0)    ret = MOVI_ICOMP_MVC2;
  327.     else
  328.     { fprintf(stderr,"  MOVI: unknown video codec (%s)\n",tbuf);
  329.       ret = MOVI_ICOMP_UNK;
  330.     }
  331.   }
  332.   return(ret);
  333. }
  334.  
  335. /********************
  336.  *
  337.  *********************/
  338. xaULONG MOVI_Read_A_Compression(xin,size)
  339. XA_INPUT *xin;
  340. xaULONG size;
  341. { xaULONG ret = 0;
  342.   if (size >= 256) 
  343.   { fprintf(stderr,"MOVI: string to long %d\n",size); 
  344.     while(size--) (void)(xin->Read_U8(xin));
  345.   }
  346.   else
  347.   { char tbuf[256]; char *p = tbuf;
  348.     while(size--) *p++ = (char)(xin->Read_U8(xin) & 0xff);
  349.     if (strcmp(tbuf,"100") == 0)    ret = MOVI_ACOMP_100;
  350.     else if (strcmp(tbuf,"401") == 0)    ret = MOVI_ACOMP_401;
  351.     else if (strcmp(tbuf,"402") == 0)    ret = MOVI_ACOMP_402;
  352.     else
  353.     { fprintf(stderr,"  MOVI: unknown audio codec (%s)\n",tbuf);
  354.       ret = MOVI_ACOMP_UNK;
  355.     }
  356.   }
  357.   return(ret);
  358. }
  359.  
  360. /********************
  361.  *
  362.  *********************/
  363. xaULONG MOVI_Parse_MOVI_HDR(xin,movi_hdr,buf,size)
  364. XA_INPUT *xin;
  365. MOVI_HDR *movi_hdr;
  366. char *buf;
  367. xaULONG size;
  368. {
  369.   if (strcmp(buf,"__NUM_I_TRACKS") == 0)
  370.                 movi_hdr->i_tracks = MOVI_Read_Int(xin,size); 
  371.   else if (strcmp(buf,"__NUM_A_TRACKS") == 0)
  372.                 movi_hdr->a_tracks = MOVI_Read_Int(xin,size); 
  373.   else if (strcmp(buf,"LOOP_MODE") == 0)
  374.                 movi_hdr->loop_mode = MOVI_Read_Int(xin,size); 
  375.   else if (strcmp(buf,"NUM_LOOPS") == 0)
  376.                 movi_hdr->num_loops = MOVI_Read_Int(xin,size); 
  377.   else if (strcmp(buf,"OPTIMIZED") == 0)
  378.                 movi_hdr->optimized = MOVI_Read_Int(xin,size); 
  379.   else /* unknown */
  380.   {
  381.     fprintf(stderr,"MOVI: unknown HDR var %s with size %d\n",buf,size);
  382.     while(size--) (void)xin->Read_U8(xin);
  383.   }
  384.   return(xaTRUE);
  385. }
  386.  
  387. /********************
  388.  *
  389.  *********************/
  390. xaULONG MOVI_Parse_MOVI_A_HDR(xin,a_hdr,buf,size)
  391. XA_INPUT *xin;
  392. MOVI_A_HDR *a_hdr;
  393. char *buf;
  394. xaULONG size;
  395. {
  396.   if (strcmp(buf,"__DIR_COUNT") == 0)
  397.                 a_hdr->frames = MOVI_Read_Int(xin,size); 
  398.   else if (strcmp(buf,"SAMPLE_WIDTH") == 0)
  399.                 a_hdr->width = MOVI_Read_Int(xin,size); 
  400.   else if (strcmp(buf,"NUM_CHANNELS") == 0)
  401.                 a_hdr->chans = MOVI_Read_Int(xin,size); 
  402.   else if (strcmp(buf,"AUDIO_FORMAT") == 0)
  403.             a_hdr->format = MOVI_Read_A_Compression(xin,size); 
  404.   else if (strcmp(buf,"SAMPLE_RATE") == 0)
  405.                 a_hdr->rate = MOVI_Read_Float(xin,size); 
  406.   else if (strcmp(buf,"COMPRESSION") == 0)
  407.             a_hdr->compression = MOVI_Read_A_Compression(xin,size); 
  408.   else /* unknown */
  409.   {
  410.     fprintf(stderr,"MOVI: unknown A_HDR var %s with size %d\n",buf,size);
  411.     while(size--) (void)xin->Read_U8(xin);
  412.   }
  413.   return(xaTRUE);
  414. }
  415.  
  416. /********************
  417.  *
  418.  *********************/
  419. xaULONG MOVI_Parse_MOVI_I_HDR(xin,i_hdr,buf,size)
  420. XA_INPUT *xin;
  421. MOVI_I_HDR *i_hdr;
  422. char *buf;
  423. xaULONG size;
  424. {
  425.   if (strcmp(buf,"__DIR_COUNT") == 0)
  426.             i_hdr->frames = MOVI_Read_Int(xin,size); 
  427.   else if (strcmp(buf,"WIDTH") == 0)
  428.             i_hdr->width = MOVI_Read_Int(xin,size); 
  429.   else if (strcmp(buf,"HEIGHT") == 0)
  430.             i_hdr->height = MOVI_Read_Int(xin,size); 
  431.   else if (strcmp(buf,"COMPRESSION") == 0)
  432.             i_hdr->compression = MOVI_Read_I_Compression(xin,size); 
  433.   else if (strcmp(buf,"INTERLACING") == 0)
  434.             i_hdr->interlacing = MOVI_Read_Int(xin,size); 
  435.   else if (strcmp(buf,"PACKING") == 0)
  436.             i_hdr->packing = MOVI_Read_Int(xin,size); 
  437.   else if (strcmp(buf,"ORIENTATION") == 0)
  438.             i_hdr->orientation = MOVI_Read_Int(xin,size); 
  439.   else if (strcmp(buf,"PIXEL_ASPECT") == 0)
  440.             i_hdr->pixel_aspect = MOVI_Read_Float(xin,size); 
  441.   else if (strcmp(buf,"FPS") == 0)
  442.             i_hdr->fps = MOVI_Read_Float(xin,size); 
  443.   else if (strcmp(buf,"Q_SPATIAL") == 0)
  444.             i_hdr->q_spatial = MOVI_Read_Float(xin,size); 
  445.   else if (strcmp(buf,"Q_TEMPORAL") == 0)
  446.             i_hdr->q_temporal = MOVI_Read_Float(xin,size); 
  447.   else /* unknown */
  448.   {
  449.     fprintf(stderr,"MOVI: unknown I HDR var %s with size %d\n",buf,size);
  450.     while(size--) (void)xin->Read_U8(xin);
  451.   }
  452.   return(xaTRUE);
  453. }
  454.  
  455.  
  456. xaULONG MOVI_Read_Header(xin,anim_hdr,movi,movi_hdr)
  457. XA_INPUT *xin;
  458. XA_ANIM_HDR *anim_hdr;
  459. XA_ANIM_SETUP *movi;
  460. MOVI_HDR *movi_hdr;
  461. { xaULONG t,version;
  462.  
  463.   t             = xin->Read_MSB_U32(xin); /* skip MOVI */
  464.  
  465.   /* Really have no clue about this, BUT some have
  466.    *
  467.    *        MOVI 0000_00003 0000_0000   => MOVI_Read_Header3
  468.    *
  469.    *        MOVI 0002_width hite_0000   => MOVI_Read_Header2
  470.    */
  471.  
  472.   version         = xin->Read_MSB_U16(xin); 
  473.   if (version == 0)
  474.   { version = xin->Read_MSB_U16(xin);
  475.     if (version == 3)
  476.     { movi_hdr->version = 3;
  477.       t = xin->Read_MSB_U32(xin); /* unknown */
  478.       return( MOVI_Read_Header3(xin,anim_hdr,movi,movi_hdr) );
  479.     }
  480.   }
  481.   else if (version == 2)
  482.   {  movi_hdr->version = 2;
  483.      t = xin->Read_MSB_U16(xin); /* width */
  484.      t = xin->Read_MSB_U16(xin); /* height */
  485.      t = xin->Read_MSB_U16(xin); /* unknown */
  486.      return( MOVI_Read_Header2(xin,anim_hdr,movi,movi_hdr) );
  487.   }
  488.   /* fall through cases */
  489.   fprintf(stderr,"MOVI: Unknown format variation\n");
  490.   return(xaFALSE);
  491. }
  492.  
  493. xaULONG MOVI_Read_Header3(xin,anim_hdr,movi,movi_hdr)
  494. XA_INPUT *xin;
  495. XA_ANIM_HDR *anim_hdr;
  496. XA_ANIM_SETUP *movi;
  497. MOVI_HDR *movi_hdr;
  498. { xaULONG t,size;
  499.   xaULONG vars;
  500.   char buf[16];
  501.  
  502.  
  503.   /*** MOVI Header Group ***/
  504.   movi_hdr->i_tracks    = 0;
  505.   movi_hdr->a_tracks    = 0;
  506.   movi_hdr->loop_mode    = 0;
  507.   movi_hdr->num_loops    = 0;
  508.   movi_hdr->optimized    = 0;
  509.   movi_hdr->a_hdr    = 0;
  510.   movi_hdr->i_hdr    = 0;
  511.  
  512.   t             = xin->Read_MSB_U32(xin); /* unk */
  513.   vars             = xin->Read_MSB_U32(xin); /* num of variables */
  514.   t             = xin->Read_MSB_U32(xin); /* unk */
  515.   while(vars--)
  516.   { int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
  517.     size = xin->Read_MSB_U32(xin); /* size */
  518.     DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
  519.     if (MOVI_Parse_MOVI_HDR(xin,movi_hdr,buf,size)==xaFALSE) return(xaFALSE);
  520.   }
  521.  
  522.   /*** MOVI Audio Header Group ***/
  523.  
  524.   if (movi_hdr->a_tracks > 1)
  525.   { fprintf(stderr,"MOVI: multiple audio tracks not yet tolerated\n");
  526.     return(xaFALSE);
  527.   }
  528.   if (movi_hdr->a_tracks == 1)  /* assume audio is optional */
  529.   { MOVI_A_HDR *a_hdr = (MOVI_A_HDR *)malloc(sizeof(MOVI_A_HDR));
  530.     if (a_hdr == 0) TheEnd1("MOVI: a_hdr malloc err");
  531. /* POD TBD - free up MOVI_A_HDR and MOVI_I_HDR at end of read */
  532.     movi_hdr->a_hdr = a_hdr;
  533.     a_hdr->frames    = 0;
  534.     a_hdr->width    = 0;
  535.     a_hdr->chans    = 0;
  536.     a_hdr->format    = 0;
  537.     a_hdr->rate        = 0.0;
  538.     a_hdr->compression    = 0;
  539.  
  540.     t             = xin->Read_MSB_U32(xin); /* unk */
  541.     vars         = xin->Read_MSB_U32(xin); /* num of variables */
  542.     t             = xin->Read_MSB_U32(xin); /* unk */
  543.     while(vars--)
  544.     { int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
  545.       size = xin->Read_MSB_U32(xin); /* size */
  546.       DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
  547.       if (MOVI_Parse_MOVI_A_HDR(xin,a_hdr,buf,size)==xaFALSE) return(xaFALSE);
  548.     }
  549.     if (xa_verbose)
  550.     {
  551.       fprintf(stdout,
  552.         "  Audio: freq %5.1f chans %d  bps %d form %d comp %d\n",
  553.         a_hdr->rate, a_hdr->chans, a_hdr->width, a_hdr->format, 
  554.         a_hdr->compression);
  555.     }
  556. /* POD check for 0 frames?? */
  557.     if (a_hdr->frames == 0) TheEnd1("MOVI: Audio err");
  558.     a_hdr->off = (xaULONG *)malloc( a_hdr->frames * sizeof(xaULONG) );
  559.     a_hdr->size = (xaULONG *)malloc( a_hdr->frames * sizeof(xaULONG) );
  560.  
  561.     movi_audio_freq =  (xaULONG)a_hdr->rate;
  562.     movi_audio_chans = a_hdr->chans;
  563.     movi_audio_bps   = a_hdr->width;
  564.     movi_audio_type = XA_AUDIO_INVALID;
  565.  
  566.     if (   (a_hdr->compression == MOVI_ACOMP_100)
  567.     && (a_hdr->format == MOVI_ACOMP_401))
  568.     {
  569.       movi_audio_type = XA_AUDIO_SIGNED;
  570.     }
  571.     else if (   (a_hdr->compression == MOVI_ACOMP_100)
  572.          && (a_hdr->format == MOVI_ACOMP_402))
  573.     {
  574.       movi_audio_type = XA_AUDIO_LINEAR;
  575.     }
  576.   
  577.     if ( (movi_audio_bps > 2) || (movi_audio_bps == 0) )
  578.                     movi_audio_type = XA_AUDIO_INVALID;
  579.     if (movi_audio_chans == 2) movi_audio_type |= XA_AUDIO_STEREO_MSK;
  580.     if (movi_audio_bps == 2)   
  581.     {
  582.       movi_audio_type |= XA_AUDIO_BPS_2_MSK;
  583.       movi_audio_type |= XA_AUDIO_BIGEND_MSK;
  584.     }
  585.     if (movi_audio_type == XA_AUDIO_INVALID)
  586.     {
  587.       if (movi_audio_attempt == xaTRUE) 
  588.     fprintf(stderr,"MOVI: Audio Type unsupported %d \n",
  589.                         a_hdr->compression);
  590.       movi_audio_attempt = xaFALSE;
  591.     }
  592.   } /* end audio group */
  593.  
  594.   /*** MOVI Video Header Group ***/
  595.   if (movi_hdr->i_tracks > 1)
  596.   { fprintf(stderr,"MOVI: multiple video tracks not yet tolerated\n");
  597.     return(xaFALSE);
  598.   }
  599.   if (movi_hdr->i_tracks == 1)
  600.   { MOVI_I_HDR *i_hdr = (MOVI_I_HDR *)malloc(sizeof(MOVI_I_HDR));
  601.     if (i_hdr == 0) TheEnd1("MOVI: i_hdr malloc err");
  602.     movi_hdr->i_hdr     = i_hdr;
  603.     i_hdr->frames    = 0;
  604.     i_hdr->width    = 0;
  605.     i_hdr->height    = 0;
  606.     i_hdr->compression    = 0;
  607.     i_hdr->interlacing    = 0;
  608.     i_hdr->packing    = 0;
  609.     i_hdr->orientation    = 0;
  610.     i_hdr->pixel_aspect    = 0.0;
  611.     i_hdr->fps        = 0.0;
  612.     i_hdr->q_spatial    = 0.0;
  613.     i_hdr->q_temporal    = 0.0;
  614.  
  615.     t             = xin->Read_MSB_U32(xin); /* unk */
  616.     vars         = xin->Read_MSB_U32(xin); /* num of variables */
  617.     t             = xin->Read_MSB_U32(xin); /* unk */
  618.     while(vars--)
  619.     { int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
  620.       size = xin->Read_MSB_U32(xin); /* size */
  621.       DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
  622.       if (MOVI_Parse_MOVI_I_HDR(xin,i_hdr,buf,size)==xaFALSE) return(xaFALSE);
  623.     }
  624.     if (xa_verbose)
  625.     {
  626.       fprintf(stdout, "  Video: %dx%d  codec ", i_hdr->width, i_hdr->height);
  627.       switch(i_hdr->compression)
  628.       { case MOVI_ICOMP_MVC1: fprintf(stdout,"MVC1"); break;
  629.     case MOVI_ICOMP_MVC2: fprintf(stdout,"MVC2"); break;
  630.     case MOVI_ICOMP_JPEG: fprintf(stdout,"JPEG"); break;
  631.     default: fprintf(stdout,"unk(%d)",i_hdr->compression);
  632.       }
  633.       fprintf(stdout," frames %d fps %3.2f\n",i_hdr->frames,i_hdr->fps);
  634.     }
  635.  
  636. /* POD check for 0 frames?? */
  637.     if (i_hdr->frames == 0) TheEnd1("MOVI: Video err");
  638.     i_hdr->off = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
  639.     i_hdr->size = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
  640.  
  641.     UTIL_FPS_2_Time(movi, ((double)(i_hdr->fps)) );
  642.  
  643.     switch(i_hdr->compression)
  644.     {  
  645.       case MOVI_ICOMP_JPEG:
  646.         movi->compression = MOVI_ICOMP_JPEG;
  647.         movi->depth = 24;
  648.         movi->imagex = i_hdr->width;
  649.         movi->imagey = i_hdr->height;
  650.         movi->imagex = 4 * ((movi->imagex + 3)/4);
  651.         movi->imagey = 4 * ((movi->imagey + 3)/4);
  652.         XA_Gen_YUV_Tabs(anim_hdr);
  653.         JPG_Alloc_MCU_Bufs(anim_hdr,movi->imagex,0,xaFALSE);
  654.     JPG_Setup_Samp_Limit_Table(anim_hdr);
  655.         break;
  656.  
  657.       case MOVI_ICOMP_MVC1:
  658.         movi->compression = MOVI_ICOMP_MVC1;
  659.         movi->depth = 16;
  660.         movi->imagex = i_hdr->width;
  661.         movi->imagey = i_hdr->height;
  662.         movi->imagex = 4 * ((movi->imagex + 3)/4);
  663.         movi->imagey = 4 * ((movi->imagey + 3)/4);
  664.     JPG_Setup_Samp_Limit_Table(anim_hdr);
  665.         break;
  666.  
  667.       case MOVI_ICOMP_MVC2:
  668.         movi->compression = MOVI_ICOMP_UNK;
  669.         movi->depth = 8;
  670.         movi->imagex = i_hdr->width;
  671.         movi->imagey = i_hdr->height;
  672.         fprintf(stderr,"  MOVI: Video Codec MVC2 not supported\n"); 
  673.         return(xaFALSE);
  674.         break;
  675.  
  676.       default:
  677.         movi->compression = MOVI_ICOMP_UNK;
  678.         movi->depth = 8;
  679.         movi->imagex = i_hdr->width;
  680.         movi->imagey = i_hdr->height;
  681.         fprintf(stderr," MOVI: Unknown Video Codec not supported\n"); 
  682.         return(xaFALSE);
  683.         break;
  684.     }
  685.  
  686.     /* POD temp kludge for unknown movies */
  687. /* Debug and testing only
  688. */
  689.     if (movi->compression == MOVI_ICOMP_UNK)
  690.     {
  691.       movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
  692.     }
  693.     else 
  694.     if ( (cmap_true_map_flag == xaFALSE) /* depth 16 and not true_map */
  695.         || (!(xin->load_flag & XA_IN_LOAD_BUF)) )
  696.     {
  697.        if (cmap_true_to_332 == xaTRUE)
  698.              movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
  699.        else    movi->chdr = CMAP_Create_Gray(movi->cmap,&movi->imagec);
  700.     }
  701.  
  702.     if ( (movi->pic==0) && (xin->load_flag & XA_IN_LOAD_BUF))
  703.     {
  704.       movi->pic_size = movi->imagex * movi->imagey;
  705.       if ( (cmap_true_map_flag == xaTRUE) && (movi->depth > 8) )
  706.                 movi->pic = (xaUBYTE *) malloc( 3 * movi->pic_size );
  707.       else movi->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(movi->pic_size) );
  708.       if (movi->pic == 0) TheEnd1("MOVI_Buffer_Action: malloc failed");
  709.     }
  710.   }
  711.  
  712.   return(xaTRUE);
  713. }
  714.  
  715. xaULONG MOVI_Read_Header2(xin,anim_hdr,movi,movi_hdr)
  716. XA_INPUT *xin;
  717. XA_ANIM_HDR *anim_hdr;
  718. XA_ANIM_SETUP *movi;
  719. MOVI_HDR *movi_hdr;
  720. { xaULONG t;
  721.  
  722.   /*** MOVI Header Group ***/
  723.   movi_hdr->i_tracks    = 0;
  724.   movi_hdr->a_tracks    = 0;
  725.   movi_hdr->loop_mode    = 0;
  726.   movi_hdr->num_loops    = 0;
  727.   movi_hdr->optimized    = 0;
  728.   movi_hdr->a_hdr    = 0;
  729.   movi_hdr->i_hdr    = 0;
  730.  
  731.   t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  732.   t             = xin->Read_MSB_U32(xin); /* unk 402e_0000 */
  733.   t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  734.   t             = xin->Read_MSB_U32(xin); /* unk 0002_0001 */
  735.  
  736.  
  737.   { MOVI_I_HDR *i_hdr = (MOVI_I_HDR *)malloc(sizeof(MOVI_I_HDR));
  738.     if (i_hdr == 0) TheEnd1("MOVI: i_hdr malloc err");
  739.  
  740.     movi_hdr->i_hdr     = i_hdr;
  741.     i_hdr->frames    = 0;
  742.     i_hdr->width    = 0;
  743.     i_hdr->height    = 0;
  744.     i_hdr->compression    = 0;
  745.     i_hdr->interlacing    = 0;
  746.     i_hdr->packing    = 0;
  747.     i_hdr->orientation    = 0;
  748.     i_hdr->pixel_aspect    = 0.0;
  749.     i_hdr->fps        = 0.0;
  750.     i_hdr->q_spatial    = 0.0;
  751.     i_hdr->q_temporal    = 0.0;
  752.  
  753.     i_hdr->frames    = xin->Read_MSB_U32(xin);
  754.     i_hdr->compression    = xin->Read_MSB_U32(xin); /* ??? */
  755.     i_hdr->width    = xin->Read_MSB_U32(xin);
  756.     i_hdr->height    = xin->Read_MSB_U32(xin);
  757.  
  758.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0004 */
  759.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0002 */
  760.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0001 */
  761.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  762.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  763.  
  764.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  765.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  766.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  767.     t             = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
  768.  
  769.     t = 0x80; while(t--) (void)xin->Read_U8(xin);    /* video title */
  770.     t = 0x80; while(t--) (void)xin->Read_U8(xin);    /* audio title */
  771.     t = 0x80; while(t--) (void)xin->Read_U8(xin);    /* unknown     */
  772.     t = 0x80; while(t--) (void)xin->Read_U8(xin);    /* unknown     */
  773.  
  774.     i_hdr->fps = 15.0;   /* POD: TBD just a guess */
  775.     if (xa_verbose)
  776.     {
  777.       fprintf(stdout,
  778.         "  Video: %dx%d  comp %d  fps %3.2f\n",
  779.         i_hdr->width, i_hdr->height, i_hdr->compression, i_hdr->fps);
  780.     }
  781.  
  782. /*POD TBD free up i_hdr off and size arrays same for a_hdr */
  783.        /* POD check for 0 frames?? */
  784.     if (i_hdr->frames == 0) TheEnd1("MOVI: Video err");
  785.     i_hdr->off = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
  786.     i_hdr->size = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
  787.  
  788.     UTIL_FPS_2_Time(movi, ((double)(i_hdr->fps)) );
  789.  
  790.     switch(i_hdr->compression)
  791.     {  
  792.       case 1:
  793.         movi->compression = MOVI_ICOMP_MVC1;
  794.         movi->depth = 16;
  795.         movi->imagex = i_hdr->width;
  796.         movi->imagey = i_hdr->height;
  797.         movi->imagex = 4 * ((movi->imagex + 3)/4);
  798.         movi->imagey = 4 * ((movi->imagey + 3)/4);
  799.         break;
  800.  
  801.       default:
  802.         movi->compression = MOVI_ICOMP_UNK;
  803.         movi->depth = 8;
  804.         movi->imagex = i_hdr->width;
  805.         movi->imagey = i_hdr->height;
  806.         break;
  807.     }
  808.  
  809. /* POD this part can be shared with Header3 somehow */
  810.     /* POD temp kludge for unknown movies */
  811.     if (movi->compression == MOVI_ICOMP_UNK)
  812.     {
  813.       movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
  814.     }
  815.     else if ( (cmap_true_map_flag == xaFALSE) /* depth 16 and not true_map */
  816.         || (!(xin->load_flag & XA_IN_LOAD_BUF)) )
  817.     {
  818.        if (cmap_true_to_332 == xaTRUE)
  819.              movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
  820.        else    movi->chdr = CMAP_Create_Gray(movi->cmap,&movi->imagec);
  821.     }
  822.  
  823.     if ( (movi->pic==0) && (xin->load_flag & XA_IN_LOAD_BUF))
  824.     {
  825.       movi->pic_size = movi->imagex * movi->imagey;
  826.       if ( (cmap_true_map_flag == xaTRUE) && (movi->depth > 8) )
  827.                 movi->pic = (xaUBYTE *) malloc( 3 * movi->pic_size );
  828.       else movi->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(movi->pic_size) );
  829.       if (movi->pic == 0) TheEnd1("MOVI_Buffer_Action: malloc failed");
  830.     }
  831.   }
  832.  
  833.   return(xaTRUE);
  834. }
  835.  
  836.  
  837. xaULONG MOVI_Read_Index3(xin,anim_hdr,movi,movi_hdr)
  838. XA_INPUT *xin;
  839. XA_ANIM_HDR *anim_hdr;
  840. XA_ANIM_SETUP *movi;
  841. MOVI_HDR *movi_hdr;
  842. { xaLONG i,t; 
  843.  
  844.   if (movi_hdr->a_hdr)  /* do audio 1st */
  845.   { MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
  846.     for(i=0; i< a_hdr->frames; i++)
  847.     {
  848.        a_hdr->off[i]    = xin->Read_MSB_U32(xin);
  849.        a_hdr->size[i]    = xin->Read_MSB_U32(xin);
  850.        t        = xin->Read_MSB_U32(xin);  /* unk */
  851.        t        = xin->Read_MSB_U32(xin);  /* unk */
  852. DEBUG_LEVEL1 fprintf(stderr,"A: %x %x\n",a_hdr->off[i], a_hdr->size[i]);
  853.     }
  854.   }
  855.   if (movi_hdr->i_hdr) 
  856.   { MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
  857.     for(i=0; i< i_hdr->frames; i++)
  858.     {
  859.        i_hdr->off[i]    = xin->Read_MSB_U32(xin);
  860.        i_hdr->size[i]    = xin->Read_MSB_U32(xin);
  861.        t        = xin->Read_MSB_U32(xin);  /* unk */
  862.        t        = xin->Read_MSB_U32(xin);  /* unk */
  863. DEBUG_LEVEL1 fprintf(stderr,"I: %x %x\n",i_hdr->off[i], i_hdr->size[i]);
  864.     }
  865.  
  866.   }
  867.   return(xaTRUE);
  868. }
  869.  
  870. xaULONG MOVI_Read_Index2(xin,anim_hdr,movi,movi_hdr)
  871. XA_INPUT *xin;
  872. XA_ANIM_HDR *anim_hdr;
  873. XA_ANIM_SETUP *movi;
  874. MOVI_HDR *movi_hdr;
  875. { xaLONG i,t; 
  876.  
  877.   if (movi_hdr->a_hdr)  /* do audio 1st */
  878.   { MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
  879.     for(i=0; i< a_hdr->frames; i++)
  880.     { a_hdr->off[i]    = xin->Read_MSB_U32(xin);
  881.       t        = xin->Read_MSB_U32(xin);  /* unk */
  882.       a_hdr->size[i]    = xin->Read_MSB_U32(xin);
  883.       t        = xin->Read_MSB_U32(xin);  /* unk */
  884.       t        = xin->Read_MSB_U32(xin);  /* unk */
  885.       DEBUG_LEVEL1 fprintf(stderr,"A: %x %x\n",
  886.                 a_hdr->off[i], a_hdr->size[i]);
  887.     }
  888.   }
  889.   if (movi_hdr->i_hdr) 
  890.   { MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
  891.     for(i=0; i< i_hdr->frames; i++)
  892.     {  i_hdr->off[i]    = xin->Read_MSB_U32(xin);
  893.        t        = xin->Read_MSB_U32(xin);  /* unk */
  894.        i_hdr->size[i]    = xin->Read_MSB_U32(xin);
  895.        t        = xin->Read_MSB_U32(xin);  /* unk */
  896.        t        = xin->Read_MSB_U32(xin);  /* unk */
  897.        DEBUG_LEVEL1 fprintf(stderr,"I: %x %x\n",
  898.                 i_hdr->off[i], i_hdr->size[i]);
  899.     }
  900.   }
  901.   return(xaTRUE);
  902. }
  903.  
  904.  
  905. void MOVI_Add_Video_Frames(xin,anim_hdr,movi,movi_hdr)
  906. XA_INPUT *xin;
  907. XA_ANIM_HDR *anim_hdr;
  908. XA_ANIM_SETUP *movi;
  909. MOVI_HDR *movi_hdr;
  910. { MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
  911.   int i;
  912.  
  913.   if (i_hdr == 0) return;
  914.   for(i = 0; i < i_hdr->frames; i++)
  915.   { xaULONG dlta_len;
  916.     XA_ACTION *act;
  917.     ACT_DLTA_HDR *dlta_hdr;
  918.   
  919.     dlta_len = i_hdr->size[i];
  920.  
  921.     act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  922.     if (xin->load_flag & XA_IN_LOAD_FILE)
  923.     { dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  924.       if (dlta_hdr == 0) TheEnd1("MOVI: dlta malloc err");
  925.       act->data = (xaUBYTE *)dlta_hdr;
  926.       dlta_hdr->flags = ACT_SNGL_BUF;
  927.       dlta_hdr->fsize = dlta_len;
  928.       dlta_hdr->fpos  = i_hdr->off[i];
  929.       if (dlta_len > movi->max_fvid_size) movi->max_fvid_size = dlta_len;
  930.     }
  931.     else
  932.     { xaULONG d; xaLONG ret;
  933.       d = dlta_len + (sizeof(ACT_DLTA_HDR));
  934.       dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
  935.       if (dlta_hdr == 0) TheEnd1("MOVI: malloc failed");
  936.       act->data = (xaUBYTE *)dlta_hdr;
  937.       dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  938.       dlta_hdr->fpos = 0; dlta_hdr->fsize = dlta_len;
  939.       ret = xin->Seek_FPos(xin, i_hdr->off[i], 0);
  940.       ret = xin->Read_Block(xin,dlta_hdr->data,dlta_len);
  941.       if (ret < dlta_len) { fprintf(stderr,"MOVI: read err\n"); return; }
  942.     }
  943.     MOVI_Add_Frame(movi->vid_time,movi->vid_timelo,act);
  944.     dlta_hdr->xpos = dlta_hdr->ypos = 0;
  945.     dlta_hdr->xsize = movi->imagex;
  946.     dlta_hdr->ysize = movi->imagey;
  947.  
  948.     switch(movi->compression)
  949.     { case MOVI_ICOMP_JPEG:
  950.     dlta_hdr->special = 0;
  951.     dlta_hdr->extra = (void *)(0x0);
  952.     dlta_hdr->xapi_rev = 0x0001;
  953.     dlta_hdr->delta = JFIF_Decode_JPEG;
  954.     break;
  955.       case MOVI_ICOMP_MVC1:
  956.     dlta_hdr->special = 0;
  957.     dlta_hdr->extra = (void *)(0x0);
  958.     dlta_hdr->xapi_rev = 0x0001;
  959.     dlta_hdr->delta = MOVI_Decode_MVC1;
  960.     break;
  961.       default:
  962.     dlta_hdr->special = 0;
  963.     dlta_hdr->extra = (void *)(0x0);
  964.     dlta_hdr->xapi_rev = 0x0001;
  965.     dlta_hdr->delta = FLI_Decode_BLACK;
  966.     break;
  967.     }
  968.     ACT_Setup_Delta(movi,act,dlta_hdr,xin);
  969.   } /* end of i thru frames */
  970. }
  971.  
  972. /***********
  973.  *
  974.  ***********/
  975. void MOVI_Add_Audio_Frames(xin,anim_hdr,movi,movi_hdr)
  976. XA_INPUT *xin;
  977. XA_ANIM_HDR *anim_hdr;
  978. XA_ANIM_SETUP *movi;
  979. MOVI_HDR *movi_hdr;
  980. { MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
  981.   int i;
  982.  
  983.   if (a_hdr == 0) return;
  984.   for(i = 0; i < a_hdr->frames; i++)
  985.   { xaULONG snd_size = a_hdr->size[i];
  986.  
  987.     if (movi_audio_attempt==xaTRUE)
  988.     { xaLONG ret;
  989.       if (xin->load_flag & XA_IN_LOAD_FILE)
  990.       { xaLONG rets;
  991.     rets = XA_Add_Sound(anim_hdr,0,movi_audio_type, a_hdr->off[i],
  992.                         movi_audio_freq, snd_size,
  993.                         &movi->aud_time,&movi->aud_timelo, 0, 0);
  994.     if (rets==xaFALSE)            movi_audio_attempt = xaFALSE;
  995.     if (snd_size > movi->max_faud_size)    movi->max_faud_size = snd_size;
  996.  
  997.       }
  998.       else
  999.       { xaUBYTE *snd = (xaUBYTE *)malloc(snd_size);
  1000.     if (snd==0) TheEnd1("MOVI: snd malloc err");
  1001.     ret = xin->Seek_FPos( xin, a_hdr->off[i], 0);
  1002.     ret = xin->Read_Block(xin, snd, snd_size);
  1003.     if (ret < snd_size) fprintf(stderr,"MOVI: snd rd err\n");
  1004.     else
  1005.     { int rets;
  1006.       rets = XA_Add_Sound(anim_hdr,snd,movi_audio_type, -1,
  1007.                                         movi_audio_freq, snd_size,
  1008.                                         &movi->aud_time, &movi->aud_timelo, 0, 0);
  1009.       if (rets==xaFALSE) movi_audio_attempt = xaFALSE;
  1010.     }
  1011.       }
  1012.     }
  1013.   } /* end of i thru chunks */
  1014. }
  1015.  
  1016.  
  1017. #define MOVI_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y += 4; } }
  1018. #define MOVI_GET_16(data,dptr) {data = *dptr++ << 8; data |= *dptr++; }
  1019.  
  1020. #define MVC1_COLOR2(dp,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,CAST) \
  1021. { c0 = c2 = c4 = c6 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr);    \
  1022.   p0 = *dp++ << 8; p0 |= *dp++;                        \
  1023.   c1 = c3 = c5 = c7 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr);    }
  1024.  
  1025. #define MVC1_COLOR8(dp,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,CAST) \
  1026. { c0 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr);        \
  1027.   p0 = *dp++ << 8; p0 |= *dp++; c1 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1028.   p0 = *dp++ << 8; p0 |= *dp++; c2 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1029.   p0 = *dp++ << 8; p0 |= *dp++; c3 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1030.   p0 = *dp++ << 8; p0 |= *dp++; c4 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1031.   p0 = *dp++ << 8; p0 |= *dp++; c5 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1032.   p0 = *dp++ << 8; p0 |= *dp++; c6 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
  1033.   p0 = *dp++ << 8; p0 |= *dp++; c7 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); }
  1034.  
  1035.  
  1036. #define MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7) { \
  1037.   *ip++ = (mask & 0x0001)?(c0):(c1);            \
  1038.   *ip++ = (mask & 0x0002)?(c0):(c1);            \
  1039.   *ip++ = (mask & 0x0004)?(c2):(c3);            \
  1040.   *ip   = (mask & 0x0008)?(c2):(c3); ip += row_inc;    \
  1041.   *ip++ = (mask & 0x0010)?(c0):(c1);            \
  1042.   *ip++ = (mask & 0x0020)?(c0):(c1);            \
  1043.   *ip++ = (mask & 0x0040)?(c2):(c3);            \
  1044.   *ip   = (mask & 0x0080)?(c2):(c3); ip += row_inc;    \
  1045.   *ip++ = (mask & 0x0100)?(c4):(c5);            \
  1046.   *ip++ = (mask & 0x0200)?(c4):(c5);            \
  1047.   *ip++ = (mask & 0x0400)?(c6):(c7);            \
  1048.   *ip   = (mask & 0x0800)?(c6):(c7); ip += row_inc;    \
  1049.   *ip++ = (mask & 0x1000)?(c4):(c5);            \
  1050.   *ip++ = (mask & 0x2000)?(c4):(c5);            \
  1051.   *ip++ = (mask & 0x4000)?(c6):(c7);            \
  1052.   *ip   = (mask & 0x8000)?(c6):(c7);            }
  1053.  
  1054.  
  1055. #define MVC1_PIX_2_RGB(pix,r,g,b) { xaULONG ra,ga,ba;        \
  1056.   ra = (pix>>10) & 0x1f; ga = (pix>>5) & 0x1f; ba = pix & 0x1f;    \
  1057.   r = (ra << 3) | (ra >> 2); g = (ga << 3) | (ga >> 2);        \
  1058.   b = (ba << 3) | (ba >> 2);    }
  1059.  
  1060.  
  1061. #define MVC1_RGB2(dp,p0,r,g,b) \
  1062. { MVC1_PIX_2_RGB(p0,r[0],g[0],b[0]);    r[2] = r[4] = r[6] = r[0];    \
  1063.   g[2] = g[4] = g[6] = g[0];    b[2] = b[4] = b[6] = b[0];        \
  1064.   p0 = *dp++ << 8; p0 |= *dp++;                        \
  1065.   MVC1_PIX_2_RGB(p0,r[1],g[1],b[1]);    r[3] = r[5] = r[7] = r[1];    \
  1066.   g[3] = g[5] = g[7] = g[1];    b[3] = b[5] = b[7] = b[1];    }
  1067.  
  1068.  
  1069. #define MVC1_RGB8(dp,p0,r,g,b)    \
  1070. { MVC1_PIX_2_RGB(p0,r[0],g[0],b[0]);    \
  1071.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[1],g[1],b[1]);    \
  1072.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[2],g[2],b[2]);    \
  1073.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[3],g[3],b[3]);    \
  1074.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[4],g[4],b[4]);    \
  1075.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[5],g[5],b[5]);    \
  1076.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[6],g[6],b[6]);    \
  1077.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_RGB(p0,r[7],g[7],b[7]);    }
  1078.  
  1079. #define MVC1_RGB_BLK8(ip,m,r,g,b) { register xaULONG ix;    \
  1080.   ix = (m & 0x0001)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1081.   ix = (m & 0x0002)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1082.   ix = (m & 0x0004)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1083.   ix = (m & 0x0008)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip   = b[ix]; \
  1084.   ip += row_inc;                              \
  1085.   ix = (m & 0x0010)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1086.   ix = (m & 0x0020)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1087.   ix = (m & 0x0040)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1088.   ix = (m & 0x0080)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip   = b[ix]; \
  1089.   ip += row_inc;                              \
  1090.   ix = (m & 0x0100)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1091.   ix = (m & 0x0200)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1092.   ix = (m & 0x0400)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1093.   ix = (m & 0x0800)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip   = b[ix]; \
  1094.   ip += row_inc;                              \
  1095.   ix = (m & 0x1000)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1096.   ix = (m & 0x2000)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1097.   ix = (m & 0x4000)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
  1098.   ix = (m & 0x8000)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip   = b[ix]; }
  1099.  
  1100. #define MVC1_PIX_2_DITH(pix,_r,_g,_b) { \
  1101. _r = (pix & 0x7c00); _g = (pix & 0x03e0); _b = (pix & 0x001f);       \
  1102. _r = _r | (_r >> 5);  _g = (_g << 5) | _g; _b = (_b << 10) | (_b << 5); }
  1103.  
  1104. #define MVC1_DITH2(dp,p0,r,g,b) \
  1105. { MVC1_PIX_2_DITH(p0,r[0],g[0],b[0]);    r[2] = r[4] = r[6] = r[0];    \
  1106.   g[2] = g[4] = g[6] = g[0];    b[2] = b[4] = b[6] = b[0];        \
  1107.   p0 = *dp++ << 8; p0 |= *dp++;                        \
  1108.   MVC1_PIX_2_DITH(p0,r[1],g[1],b[1]);    r[3] = r[5] = r[7] = r[1];    \
  1109.   g[3] = g[5] = g[7] = g[1];    b[3] = b[5] = b[7] = b[1];    }
  1110.  
  1111.  
  1112. #define MVC1_DITH8(dp,p0,r,g,b)    \
  1113. { MVC1_PIX_2_DITH(p0,r[0],g[0],b[0]);    \
  1114.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[1],g[1],b[1]);    \
  1115.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[2],g[2],b[2]);    \
  1116.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[3],g[3],b[3]);    \
  1117.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[4],g[4],b[4]);    \
  1118.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[5],g[5],b[5]);    \
  1119.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[6],g[6],b[6]);    \
  1120.   p0 = *dp++ << 8; p0 |= *dp++;    MVC1_PIX_2_DITH(p0,r[7],g[7],b[7]);    }
  1121.  
  1122.  
  1123. #define MVC1_DITH_GET_RGB(r,g,b,re,ge,be,col) { xaLONG r1,g1,b1; \
  1124.   r1 = (xaLONG)rnglimit[(r + re) >> 7]; \
  1125.   g1 = (xaLONG)rnglimit[(g + ge) >> 7]; \
  1126.   b1 = (xaLONG)rnglimit[(b + be) >> 7]; \
  1127.   col = (r1 & 0xe0) | ((g1 & 0xe0) >> 3) | ((b1 & 0xc0) >> 6); }
  1128.  
  1129. #define MVC1_DITH_GET_ERR(r,g,b,re,ge,be,col,cmap) { \
  1130.   re =  ((xaLONG)(r) - (xaLONG)(cmap[col].red   >> 1)) >> 1; \
  1131.   ge =  ((xaLONG)(g) - (xaLONG)(cmap[col].green >> 1)) >> 1; \
  1132.   be =  ((xaLONG)(b) - (xaLONG)(cmap[col].blue  >> 1)) >> 1; }
  1133.  
  1134.  
  1135. xaULONG MOVI_Decode_MVC1(image,delta,dsize,dec_info)
  1136. xaUBYTE *image;         /* Image Buffer. */
  1137. xaUBYTE *delta;         /* delta data. */
  1138. xaULONG dsize;          /* delta size */
  1139. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1140. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1141.   xaULONG mflag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1142.   xaULONG special = dec_info->special;
  1143.   XA_CHDR *chdr = dec_info->chdr;
  1144.   xaULONG row_inc;
  1145.   xaLONG x = 0, y = 0;
  1146.   xaUBYTE *dptr = delta;
  1147.   xaULONG dither = 0;
  1148.  
  1149.   dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
  1150.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1151.  
  1152.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  1153.     /* POD rethink this */
  1154.   if ((cmap_color_func == 4) && (chdr))
  1155.   { if (cmap_cache == 0) CMAP_Cache_Init(0);
  1156.     if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; }
  1157.   }
  1158.  
  1159.   if (   (!special) && (x11_bytes_pixel==1)
  1160.       && (chdr) && (x11_display_type == XA_PSEUDOCOLOR)
  1161.       && (cmap_color_func != 4)
  1162.       && (cmap_true_to_332 == xaTRUE) && (x11_cmap_size == 256)
  1163.       && (xa_dither_flag==xaTRUE)
  1164.      ) dither = 1;
  1165.  
  1166.   
  1167.   row_inc = (special)?((3*(imagex-4))+1):(imagex - 3);
  1168.  
  1169.   if (special)
  1170.   { while( (dsize > 0) && (y < imagey))
  1171.     { xaUBYTE *ip = (xaUBYTE *)(image + 3 * (y * imagex + x) );
  1172.       xaUBYTE r[8],g[8],b[8];    xaULONG mask,p0;
  1173.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);
  1174.       if (p0 & 0x8000)    { MVC1_RGB8(dptr,p0,r,g,b); dsize -= 18; }
  1175.       else        { MVC1_RGB2(dptr,p0,r,g,b); dsize -=  6; }
  1176.       MVC1_RGB_BLK8(ip,mask,r,g,b);
  1177.       MOVI_BLOCK_INC(x,y,imagex);
  1178.     }
  1179.   }
  1180.   else if (dither)
  1181.   { xaUBYTE *rnglimit = xa_byte_limit;
  1182.     ColorReg *cmap = chdr->cmap;
  1183.     while( (dsize > 0) && (y < imagey))
  1184.     { xaUBYTE *ip0 = (xaUBYTE *)(image + (y * imagex + x) );
  1185.       xaULONG r[8],g[8],b[8];    xaULONG mask,p0;
  1186.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);
  1187.       if (p0 & 0x8000)  { MVC1_DITH8(dptr,p0,r,g,b); dsize -= 12; }
  1188.       else        { MVC1_DITH2(dptr,p0,r,g,b); dsize -=  6; }
  1189.  
  1190.       { xaUBYTE *ip1 = ip0, *ip2, *ip3;
  1191.     xaLONG ix, ra, ga, ba, col, re = 0, ge = 0, be = 0;
  1192.     ip1 += imagex; ip2 = ip1; ip2 += imagex; ip3 = ip2; ip3 += imagex;
  1193.     /** 0 0 */
  1194.         ix = (mask & 0x0001)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1195.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1196.         if (mflag) col = map[col];    ip0[0] = (xaUBYTE)col;
  1197.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1198.     /*  0 1 */
  1199.         ix = (mask & 0x0002)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1200.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1201.         if (mflag) col = map[col];    ip0[1] = (xaUBYTE)col;
  1202.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1203.     /*  1 1 */
  1204.         ix = (mask & 0x0020)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1205.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1206.         if (mflag) col = map[col];    ip1[1] = (xaUBYTE)col;
  1207.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1208.     /*  1 0 */
  1209.         ix = (mask & 0x0010)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1210.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1211.         if (mflag) col = map[col];    ip1[0] = (xaUBYTE)col;
  1212.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1213.     /** 2 0 */
  1214.         ix = (mask & 0x0100)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1215.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1216.         if (mflag) col = map[col];    ip2[0] = (xaUBYTE)col;
  1217.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1218.     /*  3 0 */
  1219.         ix = (mask & 0x1000)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1220.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1221.         if (mflag) col = map[col];    ip3[0] = (xaUBYTE)col;
  1222.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1223.     /*  3 1 */
  1224.         ix = (mask & 0x2000)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1225.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1226.         if (mflag) col = map[col];    ip3[1] = (xaUBYTE)col;
  1227.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1228.     /*  2 1 */
  1229.         ix = (mask & 0x0200)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1230.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1231.         if (mflag) col = map[col];    ip2[1] = (xaUBYTE)col;
  1232.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1233.     /** 2 2 */
  1234.         ix = (mask & 0x0400)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1235.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1236.         if (mflag) col = map[col];    ip2[2] = (xaUBYTE)col;
  1237.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1238.     /*  3 2 */
  1239.         ix = (mask & 0x4000)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1240.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1241.         if (mflag) col = map[col];    ip3[2] = (xaUBYTE)col;
  1242.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1243.     /*  3 3 */
  1244.         ix = (mask & 0x8000)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1245.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1246.         if (mflag) col = map[col];    ip3[3] = (xaUBYTE)col;
  1247.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1248.     /*  2 3 */
  1249.         ix = (mask & 0x0800)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1250.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1251.         if (mflag) col = map[col];    ip2[3] = (xaUBYTE)col;
  1252.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1253.     /** 1 3 */
  1254.         ix = (mask & 0x0080)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1255.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1256.         if (mflag) col = map[col];    ip1[3] = (xaUBYTE)col;
  1257.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1258.     /*  1 2 */
  1259.         ix = (mask & 0x0040)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1260.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1261.         if (mflag) col = map[col];    ip1[2] = (xaUBYTE)col;
  1262.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1263.     /*  0 2 */
  1264.         ix = (mask & 0x0004)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1265.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1266.         if (mflag) col = map[col];    ip0[2] = (xaUBYTE)col;
  1267.         MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
  1268.     /*  0 3 */
  1269.         ix = (mask & 0x0008)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
  1270.         MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
  1271.         if (mflag) col = map[col];    ip0[3] = (xaUBYTE)col;
  1272.       }
  1273.       MOVI_BLOCK_INC(x,y,imagex);
  1274.     }
  1275.   }
  1276.   else if ((x11_bytes_pixel == 1) || (mflag == xaFALSE))
  1277.   { while( (dsize > 0) && (y < imagey))
  1278.     { xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
  1279.       xaUBYTE c0,c1,c2,c3,c4,c5,c6,c7;
  1280.       xaULONG mask,p0;
  1281.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);    dsize -= 6;
  1282.       if (p0 & 0x8000)  { dsize -= 12; 
  1283.       MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE); }
  1284.       else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE)
  1285.       MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
  1286.       MOVI_BLOCK_INC(x,y,imagex);
  1287.     }
  1288.   } /* end depth 8 */
  1289.   else if (x11_bytes_pixel == 4)
  1290.   { 
  1291.     while( (dsize > 0) && (y < imagey))
  1292.     { xaULONG *ip = (xaULONG *)(image + ((y * imagex + x)<<2) );
  1293.       xaULONG c0,c1,c2,c3,c4,c5,c6,c7;
  1294.       xaULONG mask,p0;
  1295.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);    dsize -= 6;
  1296.       if (p0 & 0x8000)  { dsize -= 12; 
  1297.       MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaULONG); }
  1298.       else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaULONG)
  1299.  
  1300.       MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
  1301.       MOVI_BLOCK_INC(x,y,imagex);
  1302.     }
  1303.   } /* end depth 24/32 */
  1304.   else /* if (x11_bytes_pixel == 2) */
  1305.   { while( (dsize > 0) && (y < imagey))
  1306.     { xaUSHORT *ip = (xaUSHORT *)(image + ((y * imagex + x)<<1) );
  1307.       xaUSHORT c0,c1,c2,c3,c4,c5,c6,c7;
  1308.       xaULONG mask,p0;        dsize -= 6;
  1309.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);    dsize -= 6;
  1310.       if (p0 & 0x8000)  { dsize -= 12; 
  1311.       MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUSHORT); }
  1312.       else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUSHORT)
  1313.       MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
  1314.       MOVI_BLOCK_INC(x,y,imagex);
  1315.     }
  1316.   } /* end depth 16 */
  1317.  
  1318.   if (mflag) return(ACT_DLTA_MAPD);
  1319.   else return(ACT_DLTA_NORM);
  1320. }
  1321.  
  1322. xaULONG MOVI_Decode_MVC2(image,delta,dsize,dec_info)
  1323. xaUBYTE *image;         /* Image Buffer. */
  1324. xaUBYTE *delta;         /* delta data. */
  1325. xaULONG dsize;          /* delta size */
  1326. XA_DEC_INFO *dec_info;  /* Decoder Info Header */
  1327. { xaULONG imagex = dec_info->imagex;    xaULONG imagey = dec_info->imagey;
  1328.   xaULONG mflag = dec_info->map_flag;        xaULONG *map = dec_info->map;
  1329.   xaULONG special = dec_info->special;
  1330.   XA_CHDR *chdr = dec_info->chdr;
  1331.   xaULONG row_inc;
  1332.   xaLONG x = 0, y = 0;
  1333.   xaUBYTE *dptr = delta;
  1334.   xaULONG dither = 0;
  1335.  
  1336.   dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
  1337.   if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
  1338.  
  1339.   if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
  1340.     /* POD rethink this */
  1341.   if ((cmap_color_func == 4) && (chdr))
  1342.   { if (cmap_cache == 0) CMAP_Cache_Init(0);
  1343.     if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; }
  1344.   }
  1345.  
  1346.   if (   (!special) && (x11_bytes_pixel==1)
  1347.       && (chdr) && (x11_display_type == XA_PSEUDOCOLOR)
  1348.       && (cmap_color_func != 4)
  1349.       && (cmap_true_to_332 == xaTRUE) && (x11_cmap_size == 256)
  1350.       && (xa_dither_flag==xaTRUE)
  1351.      ) dither = 1;
  1352.  
  1353.   
  1354.   row_inc = (special)?((3*(imagex-4))+1):(imagex - 3);
  1355.  
  1356.   if (special)
  1357.   { fprintf(stderr,"NOT YET\n"); }
  1358.   else if (dither)
  1359.   { fprintf(stderr,"NOT YET\n"); }
  1360.   else if ((x11_bytes_pixel == 1) || (mflag == xaFALSE))
  1361.   { while( (dsize > 0) && (y < imagey))
  1362.     { xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
  1363.       xaUBYTE c0,c1,c2,c3,c4,c5,c6,c7;
  1364.       xaULONG mask,p0;
  1365.       MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);    dsize -= 6;
  1366.       if (p0 & 0x8000)  { dsize -= 12; 
  1367.       MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE); }
  1368.       else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE)
  1369.       MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
  1370.       MOVI_BLOCK_INC(x,y,imagex);
  1371.     }
  1372.   }
  1373.   else if (x11_bytes_pixel == 4)
  1374.   { fprintf(stderr,"NOT YET\n"); }
  1375.   else /* if (x11_bytes_pixel == 2) */
  1376.   { fprintf(stderr,"NOT YET\n"); }
  1377.  
  1378.   if (mflag) return(ACT_DLTA_MAPD);
  1379.   else return(ACT_DLTA_NORM);
  1380. }
  1381.  
  1382. xaULONG MOVI_Get_Color(color,map_flag,map,chdr)
  1383. xaULONG color,map_flag,*map;
  1384. XA_CHDR *chdr;
  1385. {
  1386.   register xaULONG clr,ra,ga,ba,tr,tg,tb;
  1387.  
  1388.   ra = (color >> 10) & 0x1f;
  1389.   ga = (color >>  5) & 0x1f;
  1390.   ba =  color & 0x1f;
  1391.   tr = (ra << 3) | (ra >> 2);
  1392.   tg = (ga << 3) | (ga >> 2);
  1393.   tb = (ba << 3) | (ba >> 2);
  1394.   if (xa_gamma_flag==xaTRUE) { tr = xa_gamma_adj[tr]>>8;  
  1395.      tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; }
  1396.  
  1397.  
  1398.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(tr,tg,tb,8);
  1399.   else
  1400.   { 
  1401.     if ((cmap_color_func == 4) && (chdr))
  1402.     { register xaULONG cache_i = color & 0x7fff;
  1403.  
  1404.       if (cmap_cache[cache_i] == 0xffff)
  1405.       {
  1406.         clr = chdr->coff + 
  1407.        CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,5,5,5,xaTRUE);
  1408.         cmap_cache[cache_i] = (xaUSHORT)clr;
  1409.       }
  1410.       else clr = (xaULONG)cmap_cache[cache_i];
  1411.     }
  1412.     else
  1413.     {
  1414.       if (cmap_true_to_332 == xaTRUE) 
  1415.       clr=CMAP_GET_332(ra,ga,ba,CMAP_SCALE5);
  1416.       else   clr = CMAP_GET_GRAY(ra,ga,ba,CMAP_SCALE10);
  1417.       if (map_flag) clr = map[clr];
  1418.     }
  1419.   }
  1420.   return(clr);
  1421. }
  1422.