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