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