This is xanim_avi.c in view mode; [Download] [Up]
/* * xanim_avi.c * * Copyright (C) 1993,1994 by Mark Podlipec. * All rights reserved. * * This software may be freely copied, modified and redistributed without * fee for non-commerical purposes provided that this copyright notice is * preserved intact on all copies and modified copies. * * There is no warranty or other guarantee of fitness of this software. * It is provided solely "as is". The author(s) disclaim(s) all * responsibility and liability with respect to this software's usage * or its effect upon hardware or computer systems. * */ /* The following copyright applies to all Ultimotion segments of the code: * * "Copyright International Business Machines Corporation 1994, All rights * reserved. This product uses Ultimotion(tm) IBM video technology." * */ /******************************* * Revision * * 16Aug94 +video chunks of 0 size now properly used as NOP's with timing info. * ********************************/ #include "xanim_avi.h" LONG Is_AVI_File(); ULONG AVI_Read_File(); void AVI_Print_ID(); AVI_FRAME *AVI_Add_Frame(); void AVI_Free_Frame_List(); ULONG RIFF_Read_AVIH(); ULONG RIFF_Read_STRH(); ULONG RIFF_Read_VIDS(); ULONG RIFF_Read_AUDS(); void AVI_Audio_Type(); ULONG AVI_Get_Color(); void AVI_Get_RGBColor(); /* CODEC ROUTINES */ ULONG AVI_Decode_RLE8(); ULONG AVI_Decode_CRAM(); ULONG AVI_Decode_CRAM16(); ULONG AVI_Decode_RGB(); ULONG AVI_Decode_ULTI(); extern ULONG QT_Decode_CVID(); extern void QT_Gen_YUV_Tabs(); ULONG AVI_Get_Ulti_Color(); void AVI_Get_Ulti_rgbColor(); void AVI_ULTI_Gen_YUV(); void AVI_ULTI_LTC(); void AVI_Ulti_Gen_LTC(); ULONG AVI_Ulti_Check(); void CMAP_Cache_Clear(); void CMAP_Cache_Init(); XA_ACTION *ACT_Get_Action(); XA_CHDR *ACT_Get_CMAP(); XA_CHDR *CMAP_Create_332(); XA_CHDR *CMAP_Create_422(); XA_CHDR *CMAP_Create_Gray(); void ACT_Add_CHDR_To_Action(); void ACT_Setup_Mapped(); void ACT_Get_CCMAP(); XA_CHDR *CMAP_Create_CHDR_From_True(); ULONG CMAP_Find_Closest(); UBYTE *UTIL_RGB_To_FS_Map(); UBYTE *UTIL_RGB_To_Map(); ULONG UTIL_Get_MSB_Long(); ULONG UTIL_Get_LSB_Long(); ULONG UTIL_Get_LSB_Short(); /** AVI SOUND STUFF ****/ ULONG avi_audio_attempt; ULONG avi_audio_type; ULONG avi_audio_freq; ULONG avi_audio_chans; ULONG avi_audio_bps; ULONG avi_audio_end; AUDS_HDR auds_hdr; #ifdef POD_AUDIO_BETA void XA_Add_Sound(); #endif ULONG avi_cmap_flag; ULONG avi_cmap_cnt; ULONG avi_cmap_frame_num; ULONG avi_cf2_rmap[256],avi_cf2_gmap[256],avi_cf2_bmap[256]; static LONG ulti_Cr[16],ulti_Cb[16],ulti_CrCb[256]; UBYTE *avi_ulti_tab = 0; #define AVI_MAX_COLORS 256 ColorReg avi_cmap[AVI_MAX_COLORS]; XA_CHDR *avi_chdr; AVI_HDR avi_hdr; AVI_STREAM_HDR strh_hdr; VIDS_HDR vids_hdr; ULONG avi_use_index_flag; ULONG avi_frame_cnt; ULONG avi_imagex,avi_imagey,avi_imagec; ULONG avi_depth,avi_compression; ULONG avi_time,avi_timelo; UBYTE *avi_pic; ULONG avi_pic_size; ULONG avi_max_fsize; AVI_FRAME *avi_frame_start,*avi_frame_cur; AVI_FRAME *AVI_Add_Frame(time,timelo,act) ULONG time,timelo; XA_ACTION *act; { AVI_FRAME *fframe; fframe = (AVI_FRAME *) malloc(sizeof(AVI_FRAME)); if (fframe == 0) TheEnd1("AVI_Add_Frame: malloc err"); fframe->time = time; fframe->timelo = timelo; fframe->act = act; fframe->next = 0; if (avi_frame_start == 0) avi_frame_start = fframe; else avi_frame_cur->next = fframe; avi_frame_cur = fframe; avi_frame_cnt++; return(fframe); } void AVI_Free_Frame_List(fframes) AVI_FRAME *fframes; { AVI_FRAME *ftmp; while(fframes != 0) { ftmp = fframes; fframes = fframes->next; FREE(ftmp,0xA000); } } /* * */ LONG Is_AVI_File(filename) char *filename; { FILE *fin; ULONG data; if ( (fin=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE); data = UTIL_Get_MSB_Long(fin); /* read past size */ fclose(fin); if ( data == RIFF_RIFF ) return(TRUE); return(FALSE); } ULONG AVI_Read_File(fname,anim_hdr) char *fname; XA_ANIM_HDR *anim_hdr; { FILE *fin; LONG i,ret; XA_ACTION *act; if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0) { fprintf(stderr,"can't open AVI File %s for reading\n",fname); return(FALSE); } avi_cmap_flag = 0; avi_cmap_cnt = 0; avi_pic = 0; avi_pic_size = 0; avi_chdr = 0; avi_frame_cnt = 0; avi_frame_start = 0; avi_frame_cur = 0; avi_time = 100; /* default */ avi_timelo = 0; /* default */ avi_max_fsize = 0; avi_imagex = avi_imagey = avi_imagec = 0; avi_compression = 0; avi_use_index_flag = 0; avi_audio_attempt = FALSE; while( !feof(fin) ) { ULONG d,ck_id,ck_size; ck_id = UTIL_Get_MSB_Long(fin); ck_size = UTIL_Get_LSB_Long(fin); DEBUG_LEVEL2 { fprintf(stderr,"AVI cid "); AVI_Print_ID(stderr,ck_id); fprintf(stderr," cksize %08lx\n",ck_size); } switch(ck_id) { case RIFF_RIFF: d = UTIL_Get_MSB_Long(fin); DEBUG_LEVEL2 { fprintf(stderr," RIFF form type "); AVI_Print_ID(stderr,d); fprintf(stderr,"\n"); } break; case RIFF_LIST: d = UTIL_Get_MSB_Long(fin); DEBUG_LEVEL2 { fprintf(stderr," List type "); AVI_Print_ID(stderr,d); fprintf(stderr,"\n"); } break; case RIFF_avih: DEBUG_LEVEL2 fprintf(stderr," AVI_HDR:\n"); if (RIFF_Read_AVIH(fin,ck_size,&avi_hdr)==FALSE) return(FALSE); break; case RIFF_strh: DEBUG_LEVEL2 fprintf(stderr," STRH HDR:\n"); if (RIFF_Read_STRH(fin,ck_size,&strh_hdr)==FALSE) return(FALSE); break; case RIFF_strf: DEBUG_LEVEL2 fprintf(stderr," STRF HDR:\n"); switch(strh_hdr.fcc_type) { case RIFF_vids: if (RIFF_Read_VIDS(fin,ck_size,&vids_hdr)==FALSE) return(FALSE); break; case RIFF_auds: { ULONG ret = RIFF_Read_AUDS(fin,ck_size,&auds_hdr); #ifdef POD_AUDIO_BETA if (xa_audio_enable==TRUE) { if (ret==FALSE) { fprintf(stderr," AVI Audio Type Unsupported\n"); avi_audio_attempt = FALSE; } else avi_audio_attempt = TRUE; } #endif } break; default: fprintf(stderr,"unknown fcc_type at strf"); return(FALSE); break; } break; case RIFF_00iv: case RIFF_00db: case RIFF_00vc: case RIFF_00dc: case RIFF_00dx: case RIFF_00xx: { ACT_DLTA_HDR *dlta_hdr; ULONG d; act = ACT_Get_Action(anim_hdr,ACT_DELTA); if (ck_size & 0x01) ck_size++; if (ck_size == 0) /* NOP wait frame */ { act->type = ACT_NOP; act->data = 0; act->chdr = 0; AVI_Add_Frame( avi_time, avi_timelo, act); break; } if (xa_file_flag==TRUE) { dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR)); if (dlta_hdr == 0) TheEnd1("AVI 00dc: malloc failed"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_SNGL_BUF; dlta_hdr->fpos = ftell(fin); dlta_hdr->fsize = ck_size; fseek(fin,ck_size,1); /* move past this chunk */ if (ck_size > avi_max_fsize) avi_max_fsize = ck_size; } else { d = ck_size + (sizeof(ACT_DLTA_HDR)); dlta_hdr = (ACT_DLTA_HDR *) malloc( d ); if (dlta_hdr == 0) TheEnd1("AVI 00dc: malloc failed"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA; dlta_hdr->fpos = 0; dlta_hdr->fsize = ck_size; ret = fread( dlta_hdr->data, ck_size, 1, fin); if (ret != 1) {fprintf(stderr,"AVI 00dc: read failed\n"); return(FALSE);} } AVI_Add_Frame( avi_time, avi_timelo, act); dlta_hdr->xpos = dlta_hdr->ypos = 0; dlta_hdr->xsize = avi_imagex; dlta_hdr->ysize = avi_imagey; dlta_hdr->special = 0; dlta_hdr->extra = 0; switch(avi_compression) { case RIFF_RLE8: if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_RLE8; else goto AVI_UNSUPPORTED; break; case RIFF_MSVC: case RIFF_CRAM: if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_CRAM; else if (avi_depth ==16) dlta_hdr->delta = AVI_Decode_CRAM16; else goto AVI_UNSUPPORTED; break; case RIFF_ULTI: if (avi_depth == 16) dlta_hdr->delta = AVI_Decode_ULTI; else goto AVI_UNSUPPORTED; break; case RIFF_RGB: if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_RGB; else goto AVI_UNSUPPORTED; break; case RIFF_CVID: if (avi_depth == 24) dlta_hdr->delta = QT_Decode_CVID; else goto AVI_UNSUPPORTED; break; default: AVI_UNSUPPORTED: fprintf(stderr,"AVI: unsupported comp "); AVI_Print_ID(stderr,avi_compression); fprintf(stderr," with depth %ld\n",avi_depth); act->type = ACT_NOP; return(FALSE); break; } if ( (xa_buffer_flag == TRUE) && (act->type != ACT_NOP) ) { ULONG xpos,ypos,xsize,ysize,dlta_flag; if ( (cmap_true_map_flag==FALSE) || (avi_depth <= 8) ) { ULONG map_flag = (x11_display_type & XA_X11_TRUE)?(TRUE):(FALSE); dlta_flag = dlta_hdr->delta(avi_pic,dlta_hdr->data, dlta_hdr->fsize,0,avi_chdr->map,map_flag, avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,0,0); if (!(dlta_flag & ACT_DLTA_MAPD)) map_flag = FALSE; xsize -= xpos; ysize -= ypos; FREE(dlta_hdr,0xA001); act->data = 0; if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP; else ACT_Setup_Mapped(act,avi_pic,avi_chdr,xpos,ypos,xsize, ysize,avi_imagex,avi_imagey,FALSE,0, FALSE,TRUE,map_flag); ACT_Add_CHDR_To_Action(act,avi_chdr); } else /* decode as RGB triplets and then convert to mapped image */ { UBYTE *tpic; dlta_flag = dlta_hdr->delta(avi_pic,dlta_hdr->data, dlta_hdr->fsize,0,0,FALSE, avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0); xpos = ypos = 0; xsize = avi_imagex; ysize = avi_imagey; FREE(dlta_hdr,0xA002); act->data = 0; dlta_hdr = 0; if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP; else { if ( (cmap_true_to_all == TRUE) || ((cmap_true_to_1st == TRUE) && (avi_chdr == 0) ) ) avi_chdr = CMAP_Create_CHDR_From_True(avi_pic,8,8,8, avi_imagex,avi_imagey,avi_cmap,&avi_imagec); else if ( (cmap_true_to_332 == TRUE) && (avi_chdr == 0) ) avi_chdr = CMAP_Create_332(avi_cmap,&avi_imagec); else if ( (cmap_true_to_gray == TRUE) && (avi_chdr == 0) ) avi_chdr = CMAP_Create_Gray(avi_cmap,&avi_imagec); if (cmap_dither_type == CMAP_DITHER_FLOYD) tpic = UTIL_RGB_To_FS_Map(0,avi_pic,avi_chdr, avi_imagex,avi_imagey,FALSE); else tpic = UTIL_RGB_To_Map(0,avi_pic,avi_chdr, avi_imagex,avi_imagey,FALSE); ACT_Setup_Mapped(act,tpic,avi_chdr,xpos,ypos,xsize,ysize, avi_imagex,avi_imagey,FALSE,0,TRUE,TRUE,FALSE); ACT_Add_CHDR_To_Action(act,avi_chdr); } /* end of not NOP */ } /* end of true_map */ } /* end of buffer */ else /* not buffered */ACT_Add_CHDR_To_Action(act,avi_chdr); { /* Also make sure not TRUE, is 332 and special case file_flag */ if ( (cmap_color_func != 0) && (avi_depth > 8) && (!(x11_display_type & XA_X11_TRUE)) ) { if (avi_cmap_flag==0) { ULONG xpos,ypos,xsize,ysize,dlta_flag,psize; UBYTE *cbuf,*data; psize = avi_imagex * avi_imagey; cbuf = (UBYTE *) malloc(3 * psize); if (cbuf == 0) TheEnd1("colorfunc1 malloc err0\n"); memset((char *)(cbuf),0x00,(3 * psize) ); if (xa_file_flag == TRUE) { ULONG pos; data = (UBYTE *)malloc(dlta_hdr->fsize); if (data==0) TheEnd1("colorfunc1 malloc err1\n"); pos = ftell(fin); fseek(fin,dlta_hdr->fpos,0); /* save file pos */ fread(data,dlta_hdr->fsize,1,fin); /* read data*/ fseek(fin,pos,0); /* restore file pos */ } else data = dlta_hdr->data; dlta_flag = dlta_hdr->delta(cbuf,data,dlta_hdr->fsize,0, 0,FALSE,avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0); if (xa_file_flag == TRUE) { free(data); data = 0; } switch(cmap_color_func) { case 4: { avi_chdr = CMAP_Create_CHDR_From_True(cbuf,8,8,8, avi_imagex,avi_imagey,avi_cmap,&avi_imagec); DEBUG_LEVEL1 fprintf(stderr,"CF4: csize = %ld\n",avi_chdr->csize); if (avi_chdr->csize > 128) avi_cmap_flag = 1; if (cbuf) free(cbuf); cbuf = 0; } break; } /* end switch */ } /* first time through */ else /* else cnt til next time */ { avi_cmap_cnt++; if (cmap_sample_cnt && (avi_cmap_cnt >= avi_cmap_frame_num)) { avi_cmap_flag = 0; avi_cmap_cnt = 0; } } } /*color func, true color anim and not TrueDisplay */ ACT_Add_CHDR_To_Action(act,avi_chdr); } /* not bufferd */ } break; case RIFF_01wb: { ULONG snd_size = ck_size; if (ck_size & 0x01) ck_size++; if (ck_size == 0) break; DEBUG_LEVEL2 fprintf(stderr,"01wb audio attemp %lx\n",avi_audio_attempt); #ifdef POD_AUDIO_BETA if (avi_audio_attempt==TRUE) { LONG ret; UBYTE *snd; snd = (UBYTE *)malloc(ck_size); if (snd==0) TheEnd1("AVI: snd malloc err"); ret = fread( snd, ck_size, 1, fin); if (ret != 1) fprintf(stderr,"AVI: snd rd err\n"); else XA_Add_Sound(anim_hdr,snd,avi_audio_type, 0, avi_audio_freq, snd_size ); } else #endif { /* PODNOTE: SEEK?? */ for(i=0; i<ck_size; i++) d = getc(fin); } } break; case RIFF_00pc: { ULONG pc_firstcol,pc_numcols; pc_firstcol = getc(fin); pc_numcols = getc(fin); d = getc(fin); d = getc(fin); for(i = 0; i < pc_numcols; i++) { avi_cmap[i + pc_firstcol].red = (getc(fin) & 0xff); avi_cmap[i + pc_firstcol].green = (getc(fin) & 0xff); avi_cmap[i + pc_firstcol].blue = (getc(fin) & 0xff); d = getc(fin); } act = ACT_Get_Action(anim_hdr,0); AVI_Add_Frame( avi_time ,act); avi_chdr = ACT_Get_CMAP(avi_cmap,avi_imagec,0, avi_imagec,0,8,8,8); ACT_Add_CHDR_To_Action(act,avi_chdr); } break; case RIFF_idx1: case RIFF_vedt: case RIFF_strd: case RIFF_strl: case RIFF_hdrl: case RIFF_vids: case RIFF_JUNK: case RIFF_DISP: case RIFF_ISBJ: case RIFF_00AM: if (ck_size & 0x01) ck_size++; for(i=0; i<ck_size; i++) d = getc(fin); break; default: if ( !feof(fin) ) { AVI_Print_ID(stderr,ck_id); fprintf(stderr," chunk unknown\n"); fseek(fin,0,2); /* goto end of file */ } } /* end of ck_id switch */ } /* while not exitflag */ if (avi_pic != 0) { FREE(avi_pic,0xA003); avi_pic=0; } fclose(fin); if (xa_verbose) { fprintf(stderr,"AVI %ldx%ldx%ld frames %ld codec ", avi_imagex,avi_imagey,avi_imagec,avi_frame_cnt); AVI_Print_ID(stderr,avi_compression); fprintf(stderr," depth=%ld\n",avi_depth); } if (avi_frame_cnt == 0) { fprintf(stderr,"AVI: No supported video frames exist in this file.\n"); return(FALSE); } anim_hdr->frame_lst = (XA_FRAME *) malloc( sizeof(XA_FRAME) * (avi_frame_cnt+1)); if (anim_hdr->frame_lst == NULL) TheEnd1("AVI_Read_File: frame malloc err"); avi_frame_cur = avi_frame_start; i = 0; while(avi_frame_cur != 0) { if (i > avi_frame_cnt) { fprintf(stderr,"AVI_Read_Anim: frame inconsistency %ld %ld\n", i,avi_frame_cnt); break; } anim_hdr->frame_lst[i].time = avi_frame_cur->time; anim_hdr->frame_lst[i].timelo = avi_frame_cur->timelo; anim_hdr->frame_lst[i].act = avi_frame_cur->act; avi_frame_cur = avi_frame_cur->next; i++; } anim_hdr->imagex = avi_imagex; anim_hdr->imagey = avi_imagey; anim_hdr->imagec = avi_imagec; anim_hdr->imaged = 8; /* nop */ anim_hdr->frame_lst[i].time = 0; anim_hdr->frame_lst[i].timelo = 0; anim_hdr->frame_lst[i].act = 0; anim_hdr->loop_frame = 0; if (xa_buffer_flag == FALSE) anim_hdr->anim_flags |= ANIM_SNG_BUF; if (xa_file_flag == TRUE) anim_hdr->anim_flags |= ANIM_USE_FILE; anim_hdr->max_fsize = avi_max_fsize; anim_hdr->fname = anim_hdr->name; if (i > 0) anim_hdr->last_frame = i - 1; else i = 0; AVI_Free_Frame_List(avi_frame_start); return(TRUE); } /* end of read file */ ULONG RIFF_Read_AVIH(fin,size,avi_hdr) FILE *fin; ULONG size; AVI_HDR *avi_hdr; { if (size != 0x38) { fprintf(stderr,"avih: size not 56 size=%ld\n",size); return(FALSE); } avi_hdr->us_frame = UTIL_Get_LSB_Long(fin); avi_hdr->max_bps = UTIL_Get_LSB_Long(fin); avi_hdr->pad_gran = UTIL_Get_LSB_Long(fin); avi_hdr->flags = UTIL_Get_LSB_Long(fin); avi_hdr->tot_frames = UTIL_Get_LSB_Long(fin); avi_hdr->init_frames = UTIL_Get_LSB_Long(fin); avi_hdr->streams = UTIL_Get_LSB_Long(fin); avi_hdr->sug_bsize = UTIL_Get_LSB_Long(fin); avi_hdr->width = UTIL_Get_LSB_Long(fin); avi_hdr->height = UTIL_Get_LSB_Long(fin); avi_hdr->scale = UTIL_Get_LSB_Long(fin); avi_hdr->rate = UTIL_Get_LSB_Long(fin); avi_hdr->start = UTIL_Get_LSB_Long(fin); avi_hdr->length = UTIL_Get_LSB_Long(fin); avi_cmap_frame_num = avi_hdr->tot_frames / cmap_sample_cnt; if (xa_jiffy_flag) { avi_time = xa_jiffy_flag; avi_timelo = 0; } else { double ftime = (double)((avi_hdr->us_frame)/1000.0); /* convert to ms */ avi_time = (ULONG)(ftime); ftime -= (double)(avi_time); avi_timelo = (ftime * (double)(1<<24)); } if (avi_hdr->flags & AVIF_MUSTUSEINDEX) avi_use_index_flag = 1; else avi_use_index_flag = 0; #ifdef POD_AUDIO_BETA if (xa_verbose) { fprintf(stderr," AVI flags: "); if (avi_hdr->flags & AVIF_HASINDEX) fprintf(stderr,"Has_Index "); if (avi_hdr->flags & AVIF_MUSTUSEINDEX) fprintf(stderr,"Use_Index "); if (avi_hdr->flags & AVIF_ISINTERLEAVED) fprintf(stderr,"Interleaved "); if (avi_hdr->flags & AVIF_WASCAPTUREFILE) fprintf(stderr,"Captured "); if (avi_hdr->flags & AVIF_COPYRIGHTED) fprintf(stderr,"Copyrighted "); fprintf(stderr,"\n"); } #endif return(TRUE); } ULONG RIFF_Read_STRH(fin,size,strh_hdr) FILE *fin; ULONG size; AVI_STREAM_HDR *strh_hdr; { ULONG d,tsize; if (size < 0x24) {fprintf(stderr,"strh: size < 36 size = %ld\n",size); return(FALSE);} strh_hdr->fcc_type = UTIL_Get_MSB_Long(fin); strh_hdr->fcc_handler = UTIL_Get_MSB_Long(fin); strh_hdr->flags = UTIL_Get_LSB_Long(fin); strh_hdr->priority = UTIL_Get_LSB_Long(fin); strh_hdr->init_frames = UTIL_Get_LSB_Long(fin); strh_hdr->scale = UTIL_Get_LSB_Long(fin); strh_hdr->rate = UTIL_Get_LSB_Long(fin); strh_hdr->start = UTIL_Get_LSB_Long(fin); strh_hdr->length = UTIL_Get_LSB_Long(fin); strh_hdr->sug_bsize = UTIL_Get_LSB_Long(fin); strh_hdr->quality = UTIL_Get_LSB_Long(fin); strh_hdr->samp_size = UTIL_Get_LSB_Long(fin); tsize = 48; if (size & 0x01) size++; while(tsize < size) { d = getc(fin); tsize++; } DEBUG_LEVEL2 fprintf(stderr,"AVI TEST handler = %08lx",strh_hdr->fcc_handler); return(TRUE); } ULONG RIFF_Read_VIDS(fin,size,vids_hdr) FILE *fin; ULONG size; VIDS_HDR *vids_hdr; { ULONG d,i,tsize; vids_hdr->size = UTIL_Get_LSB_Long(fin); vids_hdr->width = UTIL_Get_LSB_Long(fin); vids_hdr->height = UTIL_Get_LSB_Long(fin); vids_hdr->planes = UTIL_Get_LSB_Short(fin); vids_hdr->bit_cnt = UTIL_Get_LSB_Short(fin); vids_hdr->compression = UTIL_Get_MSB_Long(fin); vids_hdr->image_size = UTIL_Get_LSB_Long(fin); vids_hdr->xpels_meter = UTIL_Get_LSB_Long(fin); vids_hdr->ypels_meter = UTIL_Get_LSB_Long(fin); vids_hdr->num_colors = UTIL_Get_LSB_Long(fin); vids_hdr->imp_colors = UTIL_Get_LSB_Long(fin); avi_compression = vids_hdr->compression; DEBUG_LEVEL2 fprintf(stderr,"VIDS compression = %08lx\n",avi_compression); avi_depth = vids_hdr->bit_cnt; avi_imagex = vids_hdr->width; avi_imagey = vids_hdr->height; avi_imagec = vids_hdr->num_colors; if ( (avi_imagec==0) && (avi_depth <= 8) ) avi_imagec = (1 << avi_depth); vids_hdr->num_colors = avi_imagec; /* re-update struct */ switch(avi_compression) { case RIFF_rgb: avi_compression = RIFF_RGB; break; case RIFF_rle8: avi_compression = RIFF_RLE8; break; case RIFF_rle4: avi_compression = RIFF_RLE4; break; case RIFF_none: avi_compression = RIFF_NONE; break; case RIFF_pack: avi_compression = RIFF_PACK; break; case RIFF_tran: avi_compression = RIFF_TRAN; break; case RIFF_ccc : avi_compression = RIFF_CCC; break; case RIFF_jpeg: avi_compression = RIFF_JPEG; break; case RIFF_rt21: avi_compression = RIFF_RT21; break; case RIFF_CVID: QT_Gen_YUV_Tabs(); /* gen YUV tables and fall through */ case RIFF_MSVC: /* need to be multiple of 4 */ case RIFF_CRAM: /* need to be multiple of 4 */ avi_imagex = 4 * ((avi_imagex + 3)/4); avi_imagey = 4 * ((avi_imagey + 3)/4); break; case RIFF_ULTI: /* need to be multiple of 8 */ avi_imagex = 8 * ((avi_imagex + 7)/8); avi_imagey = 8 * ((avi_imagey + 7)/8); AVI_ULTI_Gen_YUV();/* generate tables */ AVI_Ulti_Gen_LTC(); break; } if (avi_depth <= 8) { for(i=0; i < avi_imagec; i++) { avi_cmap[i].blue = ( getc(fin) ) & 0xff; avi_cmap[i].green = ( getc(fin) ) & 0xff; avi_cmap[i].red = ( getc(fin) ) & 0xff; d = getc(fin); /* pad */ } avi_chdr = ACT_Get_CMAP(avi_cmap,avi_imagec,0,avi_imagec,0,8,8,8); } else if ( (cmap_true_map_flag == FALSE) /* depth 16 and not true_map */ || (xa_buffer_flag == FALSE) ) { if (cmap_true_to_332 == TRUE) avi_chdr = CMAP_Create_332(avi_cmap,&avi_imagec); else avi_chdr = CMAP_Create_Gray(avi_cmap,&avi_imagec); } if ( (avi_pic==0) && (xa_buffer_flag == TRUE)) { avi_pic_size = avi_imagex * avi_imagey; if ( (cmap_true_map_flag == TRUE) && (avi_depth == 16) ) avi_pic = (UBYTE *) malloc( 3 * avi_pic_size ); else avi_pic = (UBYTE *) malloc( XA_PIC_SIZE(avi_pic_size) ); if (avi_pic == 0) TheEnd1("AVI_Buffer_Action: malloc failed"); } /* Read rest of header */ tsize = vids_hdr->num_colors * 4 + 40; if (size & 0x01) size++; while(tsize < size) { d = getc(fin); tsize++; } return(TRUE); } /* * Routine to Decode an AVI CRAM chunk */ #define AVI_CRAM_C1(ip,clr,rdec) { \ *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \ *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \ *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \ *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; } #define AVI_CRAM_C2(ip,flag,cA,cB,rdec) { \ *ip++ =(flag&0x01)?(cB):(cA); *ip++ =(flag&0x02)?(cB):(cA); \ *ip++ =(flag&0x04)?(cB):(cA); *ip =(flag&0x08)?(cB):(cA); ip-=rdec; \ *ip++ =(flag&0x10)?(cB):(cA); *ip++ =(flag&0x20)?(cB):(cA); \ *ip++ =(flag&0x40)?(cB):(cA); *ip =(flag&0x80)?(cB):(cA); } #define AVI_CRAM_C4(ip,flag,cA0,cA1,cB0,cB1,rdec) { \ *ip++ =(flag&0x01)?(cB0):(cA0); *ip++ =(flag&0x02)?(cB0):(cA0); \ *ip++ =(flag&0x04)?(cB1):(cA1); *ip =(flag&0x08)?(cB1):(cA1); ip-=rdec; \ *ip++ =(flag&0x10)?(cB0):(cA0); *ip++ =(flag&0x20)?(cB0):(cA0); \ *ip++ =(flag&0x40)?(cB1):(cA1); *ip =(flag&0x80)?(cB1):(cA1); } #define AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y) { \ if (x < min_x) min_x = x; if (y > max_y) max_y = y; \ if (x > max_x) max_x = x; if (y < min_y) min_y = y; } #define AVI_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y -= 4; } } #define AVI_GET_16(data,dptr) { data = *dptr++; data |= (*dptr++) << 8; } #define AVI_CRAM_rgbC1(ip,r,g,b) { \ *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip++=b; \ *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip =b; } #define AVI_CRAM_rgbC2(ip,flag,rA,gA,bA,rB,gB,bB) { \ if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \ else {*ip++=rA; *ip++=gA; *ip++=bA;} \ if (flag&0x02) {*ip++=rB; *ip++=gB; *ip++=bB;} \ else {*ip++=rA; *ip++=gA; *ip++=bA;} \ if (flag&0x04) {*ip++=rB; *ip++=gB; *ip++=bB;} \ else {*ip++=rA; *ip++=gA; *ip++=bA;} \ if (flag&0x08) {*ip++=rB; *ip++=gB; *ip =bB;} \ else {*ip++=rA; *ip++=gA; *ip =bA;} } #define AVI_CRAM_rgbC4(ip,flag,rA,gA,bA,rB,gB,bB) { \ if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \ else {*ip++=rA; *ip++=gA; *ip++=bA;} \ if (flag&0x02) {*ip++=rB; *ip++=gB; *ip =bB;} \ else {*ip++=rA; *ip++=gA; *ip =bA;} } #define AVI_Get_RGBColor(r,g,b,color) \ { register ULONG _r,_g,_b; \ _r = (color >> 10) & 0x1f; r = (_r << 3) | (_r >> 2); \ _g = (color >> 5) & 0x1f; g = (_g << 3) | (_g >> 2); \ _b = color & 0x1f; b = (_b << 3) | (_b >> 2); \ if (xa_gamma_flag==TRUE) { r = xa_gamma_adj[r]>>8; \ g = xa_gamma_adj[g]>>8; b = xa_gamma_adj[b]>>8; } } ULONG AVI_Decode_CRAM(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* extra info needed to decode delta */ { ULONG row_dec,exitflag,changed,block_cnt; ULONG code0,code1; LONG x,y,min_x,max_x,min_y,max_y; UBYTE *dptr; changed = 0; max_x = max_y = 0; min_x = imagex; min_y = imagey; dptr = delta; row_dec = imagex + 3; x = 0; y = imagey - 1; exitflag = 0; block_cnt = ((imagex * imagey) >> 4) + 1; if (map_flag == TRUE) { if (x11_bytes_pixel == 4) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1; else { if (y < 0) {exitflag = 1; /*fprintf(stderr,"CRAM: ovr err0\n");*/ } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* single block encoded */ { if (code1 >= 0x90) /* 8 color quadrant encoding */ { ULONG cA0,cA1,cB0,cB1; ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) ); cB0 = (ULONG)map[*dptr++]; cA0 = (ULONG)map[*dptr++]; cB1 = (ULONG)map[*dptr++]; cA1 = (ULONG)map[*dptr++]; AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; cB0 = (ULONG)map[*dptr++]; cA0 = (ULONG)map[*dptr++]; cB1 = (ULONG)map[*dptr++]; cA1 = (ULONG)map[*dptr++]; AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else if (code1 < 0x80) /* 2 color encoding */ { register ULONG clr_A,clr_B; ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) ); clr_B = (ULONG)map[*dptr++]; clr_A = (ULONG)map[*dptr++]; AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec); } else /* 1 color encoding */ { ULONG clr = (ULONG)map[code0]; ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) ); AVI_CRAM_C1(i_ptr,clr,row_dec); } AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); changed = 1; AVI_BLOCK_INC(x,y,imagex); } /* end of single block */ } /* end of not term code */ } /* end of not while exit */ } /* end of 4 bytes pixel */ else if (x11_bytes_pixel == 2) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1; else { if (y < 0) {exitflag = 1; /*fprintf(stderr,"CRAM: ovr err1\n");*/ } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* single block encoded */ { if (code1 >= 0x90) /* 8 color quadrant encoding */ { USHORT cA0,cA1,cB0,cB1; USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) ); cB0 = map[*dptr++]; cA0 = map[*dptr++]; cB1 = map[*dptr++]; cA1 = map[*dptr++]; AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; cB0 = map[*dptr++]; cA0 = map[*dptr++]; cB1 = map[*dptr++]; cA1 = map[*dptr++]; AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } /* end of 8 color quadrant encoding */ else if (code1 < 0x80) /* 2 color encoding */ { USHORT clr_A,clr_B; USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) ); clr_B = (USHORT)map[*dptr++]; clr_A = (USHORT)map[*dptr++]; AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec); } /* end of 2 color */ else /* 1 color encoding */ { USHORT clr = (USHORT)map[code0]; USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) ); AVI_CRAM_C1(i_ptr,clr,row_dec); } AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); changed = 1; AVI_BLOCK_INC(x,y,imagex); } /* end of single block */ } /* end of not term code */ } /* end of not while exit */ } /* end of 2 bytes pixel */ else /* (x11_bytes_pixel == 1) */ { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1; else { if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: ovr err2\n");*/ } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* single block encoded */ { if (code1 >= 0x90) /* 8 color quadrant encoding */ { UBYTE cA0,cA1,cB0,cB1; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); cB0 = (UBYTE)map[*dptr++]; cA0 = (UBYTE)map[*dptr++]; cB1 = (UBYTE)map[*dptr++]; cA1 = (UBYTE)map[*dptr++]; AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; cB0 = (UBYTE)map[*dptr++]; cA0 = (UBYTE)map[*dptr++]; cB1 = (UBYTE)map[*dptr++]; cA1 = (UBYTE)map[*dptr++]; AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else if (code1 < 0x80) /* 2 color encoding */ { UBYTE clr_A,clr_B; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); clr_B = (UBYTE)map[*dptr++]; clr_A = (UBYTE)map[*dptr++]; AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec); } else /* 1 color encoding */ { UBYTE clr = (UBYTE)map[code0]; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); AVI_CRAM_C1(i_ptr,clr,row_dec); } AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); changed = 1; AVI_BLOCK_INC(x,y,imagex); } /* end of single block */ } /* end of not term code */ } /* end of not while exit */ } /* end of 1 bytes pixel */ } /* end of map is TRUE */ else { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1; else if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: ovr err3\n");*/ } else { if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* single block encoded */ { if (code1 >= 0x90) /* 8 color quadrant encoding */ { UBYTE cA0,cA1,cB0,cB1; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); cB0 = (UBYTE)*dptr++; cA0 = (UBYTE)*dptr++; cB1 = (UBYTE)*dptr++; cA1 = (UBYTE)*dptr++; AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; cB0 = (UBYTE)*dptr++; cA0 = (UBYTE)*dptr++; cB1 = (UBYTE)*dptr++; cA1 = (UBYTE)*dptr++; AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else if (code1 < 0x80) /* 2 color encoding */ { UBYTE clr_A,clr_B; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); clr_B = (UBYTE)*dptr++; clr_A = (UBYTE)*dptr++; AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec); } /* end of 2 color */ else /* 1 color encoding */ { UBYTE clr = (UBYTE)code0; UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x); AVI_CRAM_C1(i_ptr,clr,row_dec); } AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); changed = 1; AVI_BLOCK_INC(x,y,imagex); } /* end of single block */ } /* end of not term code */ } /* end of not while exit */ } if (xa_optimize_flag == TRUE) { if (changed) { *xs=min_x; *ys=min_y - 3; *xe=max_x + 4; *ye=max_y + 1; } else { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); } } else { *xs = *ys = 0; *xe = imagex; *ye = imagey; } if (map_flag) return(ACT_DLTA_MAPD); else return(ACT_DLTA_NORM); } /* * Routine to Decode an AVI RGB chunk * (i.e. just copy it into the image buffer) * courtesy of Julian Bradfield. */ ULONG AVI_Decode_RGB(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* extra info needed to decode delta */ { ULONG oddflag; UBYTE *dptr = delta; oddflag = imagex & 0x01; if (map_flag == TRUE) { if (x11_bytes_pixel == 4) { LONG x,y = imagey - 1; while ( y >= 0 ) { ULONG *i_ptr = (ULONG *)(image + ((y * imagex)<<2) ); y--; x = imagex; while(x--) *i_ptr++ = (ULONG)map[*dptr++]; if (oddflag) dptr++; } } else if (x11_bytes_pixel == 2) { LONG x,y = imagey - 1; while ( y >= 0 ) { USHORT *i_ptr = (USHORT *)(image + ((y * imagex)<<1) ); y--; x = imagex; while(x--) *i_ptr++ = (USHORT)map[*dptr++]; if (oddflag) dptr++; } } else /* (x11_bytes_pixel == 1) */ { LONG x,y = imagey - 1; while ( y >= 0 ) { UBYTE *i_ptr = (UBYTE *)(image + y * imagex); y--; x = imagex; while(x--) *i_ptr++ = (UBYTE)map[*dptr++]; if (oddflag) dptr++; } } } /* end of map is TRUE */ else { LONG x,y = imagey - 1; while ( y >= 0 ) { UBYTE *i_ptr = (UBYTE *)(image + y * imagex); y--; x = imagex; while(x--) *i_ptr++ = (UBYTE)*dptr++; if (oddflag) dptr++; } } *xs = *ys = 0; *xe = imagex; *ye = imagey; if (map_flag) return(ACT_DLTA_MAPD); else return(ACT_DLTA_NORM); } void AVI_Print_ID(fout,id) FILE *fout; LONG id; { fprintf(fout,"%c", ((id >> 24) & 0xff) ); fprintf(fout,"%c", ((id >> 16) & 0xff) ); fprintf(fout,"%c", ((id >> 8) & 0xff) ); fprintf(fout,"%c(%lx)", (id & 0xff),id); } ULONG AVI_Get_Color(color,map_flag,map,chdr) ULONG color,map_flag,*map; XA_CHDR *chdr; { register ULONG clr,ra,ga,ba,tr,tg,tb; ra = (color >> 10) & 0x1f; ga = (color >> 5) & 0x1f; ba = color & 0x1f; tr = (ra << 3) | (ra >> 2); tg = (ga << 3) | (ga >> 2); tb = (ba << 3) | (ba >> 2); if (xa_gamma_flag==TRUE) { tr = xa_gamma_adj[tr]>>8; tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; } if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,5); else { if ((cmap_color_func == 4) && (chdr)) { register ULONG cache_i = color & 0x7fff; if (cmap_cache == 0) CMAP_Cache_Init(); if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; } if (cmap_cache[cache_i] == 0xffff) { clr = chdr->coff + CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,5,5,5,TRUE); cmap_cache[cache_i] = (USHORT)clr; } else clr = (ULONG)cmap_cache[cache_i]; } else { if (cmap_true_to_332 == TRUE) clr=CMAP_GET_332(ra,ga,ba,CMAP_SCALE5); else clr = CMAP_GET_GRAY(ra,ga,ba,CMAP_SCALE10); if (map_flag) clr = map[clr]; } } return(clr); } ULONG AVI_Decode_RLE8(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ LONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* extra info needed to decode delta */ { ULONG opcode,mod; LONG x,y,min_x,max_x,min_y,max_y; UBYTE *dptr; max_x = max_y = 0; min_x = imagex; min_y = imagey; x = 0; y = imagey - 1; dptr = delta; while( (y >= 0) && (dsize > 0) ) { mod = *dptr++; opcode = *dptr++; dsize-=2; if (mod == 0x00) /* END-OF-LINE */ { if (opcode==0x00) { while(x > imagex) { x -=imagex; y--; } x = 0; y--; } else if (opcode==0x01) /* END Of Image */ { y = -1; } else if (opcode==0x02) /* SKIP */ { ULONG yskip,xskip; xskip = *dptr++; yskip = *dptr++; dsize-=2; x += xskip; y -= yskip; } else /* ABSOLUTE MODE */ { int cnt = opcode; dsize-=cnt; while(x >= imagex) { x -= imagex; y--; } if (y > max_y) max_y = y; if (x < min_x) x = min_x; if (map_flag==TRUE) { if (x11_bytes_pixel==1) { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) ); while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -= imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); } *iptr++ = (UBYTE)map[*dptr++]; x++; } } else if (x11_bytes_pixel==2) { USHORT *iptr = (USHORT *)(image + ((y * imagex + x)<<1) ); while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -= imagex; y--; iptr = (USHORT *)(image+y*imagex+x); } *iptr++ = (USHORT)map[*dptr++]; x++; } } else /* if (x11_bytes_pixel==4) */ { ULONG *iptr = (ULONG *)(image + ((y * imagex + x)<<2) ); while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -= imagex; y--; iptr = (ULONG *)(image+y*imagex+x); } *iptr++ = (ULONG)map[*dptr++]; x++; } } } else { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) ); while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -=imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); } *iptr++ = (UBYTE)(*dptr++); x++; } } if (opcode & 0x01) { dptr++; dsize--; } if (y < min_y) min_y = y; if (x > max_x) x = max_x; } } else /* ENCODED MODE */ { int color,cnt; while(x >= imagex) { x -=imagex; y--; } if (y > max_y) max_y = y; if (x < min_x) x = min_x; cnt = mod; color = (map_flag==TRUE)?(map[opcode]):(opcode); if ( (map_flag==FALSE) || (x11_bytes_pixel==1) ) { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) ); UBYTE clr = (UBYTE)color; while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -=imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); } *iptr++ = clr; x++; } } else if (x11_bytes_pixel==2) { USHORT *iptr = (USHORT *)(image + ((y * imagex + x)<<1) ); USHORT clr = (USHORT)color; while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -=imagex; y--; iptr = (USHORT *)(image+y*imagex+x); } *iptr++ = clr; x++; } } else /* if (x11_bytes_pixel==4) */ { ULONG *iptr = (ULONG *)(image + ((y * imagex + x)<<2) ); ULONG clr = (ULONG)color; while(cnt--) { if (x >= imagex) { max_x = imagex; min_x = 0; x -=imagex; y--; iptr = (ULONG *)(image+y*imagex+x); } *iptr++ = clr; x++; } } if (y < min_y) min_y = y; if (x > max_x) x = max_x; } } /* end of while */ if (xa_optimize_flag == TRUE) { max_x++; if (max_x>imagex) max_x=imagex; max_y++; if (max_y>imagey) max_y=imagey; if ((min_x >= max_x) || (min_y >= max_y)) /* no change */ { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); } else { *xs=min_x; *ys=min_y; *xe=max_x; *ye=max_y; } } else { *xs = *ys = 0; *xe = imagex; *ye = imagey; } if (map_flag) return(ACT_DLTA_MAPD); else return(ACT_DLTA_NORM); } ULONG AVI_Decode_CRAM16(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *tchdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* extra info needed to decode delta */ { ULONG row_dec,exitflag,changed,block_cnt; ULONG code0,code1; LONG x,y,min_x,max_x,min_y,max_y; UBYTE *dptr; XA_CHDR *chdr; if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0; changed = 0; max_x = max_y = 0; min_x = imagex; min_y = imagey; dptr = delta; if (special) row_dec = (3*(imagex+4))-1; else row_dec = imagex + 3; x = 0; y = imagey - 1; exitflag = 0; block_cnt = ((imagex * imagey) >> 4) + 1; if (special == 1) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; } if (y < 0) {exitflag = 1; /* fprintf(stderr,"AVI: CRAM16 ovr err0\n");*/ } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* not skip */ { UBYTE *i_ptr = (UBYTE *)(image + 3 * (y * imagex + x) ); if (code1 < 0x80) /* 2 or 8 color encoding */ { ULONG cA,cB; UBYTE rA0,gA0,bA0,rB0,gB0,bB0; AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB); AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); if (cB & 0x8000) /* Eight Color Encoding */ { UBYTE rA1,gA1,bA1,rB1,gB1,bB1; register flag = code0; AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB); AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr++; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); i_ptr -= row_dec; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr++; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); i_ptr -= row_dec; flag = code1; AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB); AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB); AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr++; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); i_ptr -= row_dec; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr++; flag >>= 2; AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); } else /* Two Color Encoding */ { register ULONG flag = code0; AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr -= row_dec; flag >>= 4; AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr -= row_dec; flag = code1; AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); i_ptr -= row_dec; flag >>= 4; AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); } } /* end of 2 or 8 */ else /* 1 color encoding (80-83) && (>=88)*/ { ULONG cA = (code1<<8) | code0; UBYTE r,g,b; AVI_Get_RGBColor(r,g,b,cA); AVI_CRAM_rgbC1(i_ptr,r,g,b); i_ptr -= row_dec; AVI_CRAM_rgbC1(i_ptr,r,g,b); i_ptr -= row_dec; AVI_CRAM_rgbC1(i_ptr,r,g,b); i_ptr -= row_dec; AVI_CRAM_rgbC1(i_ptr,r,g,b); } changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); AVI_BLOCK_INC(x,y,imagex); } /* end of not skip */ } /* end of not while exit */ } /* end of special */ else { if ( (x11_bytes_pixel == 1) || (map_flag == FALSE) ) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; } if (y < 0) {exitflag = 1; continue; } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* not skip */ { UBYTE *i_ptr = (UBYTE *)(image + (y * imagex + x) ); if (code1 < 0x80) /* 2 or 8 color encoding */ { ULONG cA,cB; UBYTE cA0,cB0; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr); cA0 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr); if (cB & 0x8000) /* Eight Color Encoding */ { UBYTE cA1,cB1; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr); cA1 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr); cA0 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr); AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr); cA1 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else /* Two Color Encoding */ { AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec); } } /* end of 2 or 8 */ else /* 1 color encoding (80-83) && (>=88)*/ { ULONG cA = (code1<<8) | code0; UBYTE clr = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C1(i_ptr,clr,row_dec); } changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); AVI_BLOCK_INC(x,y,imagex); } /* end of not skip */ } /* end of not while exit */ } /* end of 1 bytes pixel */ else if (x11_bytes_pixel == 2) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; } if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: CRAM16 ovr err2\n");*/} if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* not skip */ { USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) ); if (code1 < 0x80) /* 2 or 8 color encoding */ { ULONG cA,cB; USHORT cA0,cB0; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr); cA0 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr); if (cB & 0x8000) /* Eight Color Encoding */ { USHORT cA1,cB1; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr); cA1 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr); cA0 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr); AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr); cA1 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else /* Two Color Encoding */ { AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec); } } /* end of 2 or 8 */ else /* 1 color encoding (80-83) && (>=88)*/ { ULONG cA = (code1<<8) | code0; USHORT clr = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C1(i_ptr,clr,row_dec); } changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); AVI_BLOCK_INC(x,y,imagex); } /* end of not skip */ } /* end of not while exit */ } /* end of 2 bytes pixel */ else if (x11_bytes_pixel == 4) { while(!exitflag) { code0 = *dptr++; code1 = *dptr++; block_cnt--; if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; } if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: CRAM16 ovr err4\n");*/ } if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */ { ULONG skip = ((code1 - 0x84) << 8) + code0; block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex); } else /* not skip */ { ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) ); if (code1 < 0x80) /* 2 or 8 color encoding */ { ULONG cA,cB,cA0,cB0; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = AVI_Get_Color(cB,map_flag,map,chdr); cA0 = AVI_Get_Color(cA,map_flag,map,chdr); if (cB & 0x8000) /* Eight Color Encoding */ { ULONG cA1,cB1; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = AVI_Get_Color(cB,map_flag,map,chdr); cA1 = AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec; AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB0 = AVI_Get_Color(cB,map_flag,map,chdr); cA0 = AVI_Get_Color(cA,map_flag,map,chdr); AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr); cB1 = AVI_Get_Color(cB,map_flag,map,chdr); cA1 = AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec); } else /* Two Color Encoding */ { AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec; AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec); } } /* end of 2 or 8 */ else /* 1 color encoding (80-83) && (>=88)*/ { ULONG cA = (code1<<8) | code0; ULONG clr = AVI_Get_Color(cA,map_flag,map,chdr); AVI_CRAM_C1(i_ptr,clr,row_dec); } changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y); AVI_BLOCK_INC(x,y,imagex); } /* end of not skip */ } /* end of not while exit */ } /* end of 4 bytes pixel */ } /* end of not special */ if (xa_optimize_flag == TRUE) { if (changed) { *xs=min_x; *ys=min_y - 3; *xe=max_x + 4; *ye=max_y + 1; } else { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); } } else { *xs = *ys = 0; *xe = imagex; *ye = imagey; } if (map_flag) return(ACT_DLTA_MAPD); else return(ACT_DLTA_NORM); } #define ULTI_CHROM_NORM 0 #define ULTI_CHROM_UNIQ 1 #define ULTI_STREAM0 0x0 #define ULTI_STREAM1 0x4 #define AVI_ULTI_C2(ip,flag,CST,c0,c1,rinc) { \ *ip++ =(CST)((flag&0x80)?(c1):(c0)); *ip++ =(CST)(flag&0x40)?(c1):(c0); \ *ip++ =(CST)((flag&0x20)?(c1):(c0)); *ip++ =(CST)(flag&0x10)?(c1):(c0); \ ip += rinc; \ *ip++ =(CST)((flag&0x08)?(c1):(c0)); *ip++ =(CST)(flag&0x04)?(c1):(c0); \ *ip++ =(CST)((flag&0x02)?(c1):(c0)); *ip++ =(CST)(flag&0x01)?(c1):(c0); } #define AVI_ULTI_rgbC2(p,msk,r0,r1,g0,g1,b0,b1,rinc) { \ if (msk&0x80) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x40) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x20) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x10) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ p += rinc; \ if (msk&0x08) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x04) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x02) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \ if (msk&0x01) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} } ULONG AVI_Decode_ULTI(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *tchdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* extra info needed to decode delta */ { ULONG r_inc,exitflag,changed,block_cnt; LONG x,y,min_x,max_x,min_y,max_y; UBYTE *dptr; XA_CHDR *chdr; ULONG stream_mode,chrom_mode,chrom_next_uniq; ULONG bhedr,opcode,chrom; stream_mode = ULTI_STREAM0; chrom_mode = ULTI_CHROM_NORM; chrom_next_uniq = FALSE; if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0; changed = 0; max_x = max_y = 0; min_x = imagex; min_y = imagey; dptr = delta; r_inc = imagex - 4; if (special) r_inc *= 3; x = 0; y = 0; exitflag = 0; block_cnt = ((imagex * imagey) >> 6) + 1; while(!exitflag) { ULONG mask; bhedr = *dptr++; if ( (y > imagey) || (block_cnt < 0) ) { exitflag = 1; fprintf(stderr,"y = %ld block_cnt = %ld bhedr = %lx\n",y,block_cnt,bhedr); continue; } else if ( (bhedr & 0xf8) == 0x70) /* ESCAPE */ { switch(bhedr) { case 0x70: /* stream mode toggle */ { ULONG d; d = *dptr++; if (d==0) stream_mode = ULTI_STREAM0; else if (d==1) stream_mode = ULTI_STREAM1; else { fprintf(stderr,"ULTI: stream err %ld\n",stream_mode); TheEnd(); } } break; case 0x71: /* next blk has uniq chrom */ chrom_next_uniq = TRUE; break; case 0x72: /* chrom mode toggle */ chrom_mode = (chrom_mode==ULTI_CHROM_NORM)?(ULTI_CHROM_UNIQ) :(ULTI_CHROM_NORM); break; case 0x73: /* Frame Guard */ exitflag = 1; break; case 0x74: /* Skip */ { ULONG cnt = (ULONG)(*dptr++); block_cnt -= cnt; while(cnt--) { x += 8; if (x>=imagex) { x=0; y += 8; } } } break; default: /* reserved escapes */ fprintf(stderr,"Reserved Escapes %lx\n",bhedr); exitflag = 1; break; } } /* end of escape */ else /* not escape */ { ULONG chrom_flag; ULONG quadrant,msh,tx,ty; block_cnt--; if ( (chrom_mode==ULTI_CHROM_UNIQ) || (chrom_next_uniq == TRUE) ) { chrom_next_uniq = FALSE; chrom_flag = TRUE; chrom = 0; } else { chrom_flag = FALSE; if (bhedr != 0x00) chrom = *dptr++; /* read chrom */ } msh = 8; tx = x; ty = y; for(quadrant=0;quadrant<4;quadrant++) { ULONG tx,ty; /* move to quadrant */ if (quadrant==0) {tx=x; ty=y;} else if (quadrant==1) ty+=4; else if (quadrant==2) tx+=4; else ty-=4; msh -= 2; opcode = ((bhedr >> msh) & 0x03) | stream_mode; /* POSSIBLY TEST FOR 0x04 or 0x00 1st */ switch(opcode) { case 0x04: case 0x00: /* Unchanged quadrant */ /* ??? in unique chrom mode is there a chrom for this quad?? */ break; case 0x05: case 0x01: /* Homogenous/shallow LTC quadrant */ { ULONG angle,y0,y1; if (chrom_flag==TRUE) { chrom = *dptr++; } y0 = *dptr++; angle = (y0 >> 6) & 0x03; y0 &= 0x3f; if (angle == 0) { AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr, y0,y0,y0,y0,chrom,angle); } else { y1 = y0 + 1; if (y1 > 63) y1 = 63; if (angle==3) angle = 12; else if (angle==2) angle = 6; else (angle==2); AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr, y0,y0,y1,y1,chrom,angle); } } break; case 0x02: /* LTC quadrant */ { ULONG angle,ltc_idx,y0,y1,y2,y3; UBYTE *tmp; if (chrom_flag==TRUE) { chrom = *dptr++; } ltc_idx = (*dptr++) << 8; ltc_idx |= (*dptr++); angle = (ltc_idx >> 12) & 0x0f; /* 4 bits angle */ ltc_idx &= 0x0fff; /* index to 4 byte lum table */ tmp = &avi_ulti_tab[ ( ltc_idx << 2 ) ]; y0 = (ULONG)(*tmp++); y1 = (ULONG)(*tmp++); y2 = (ULONG)(*tmp++); y3 = (ULONG)(*tmp++); AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr, y0,y1,y2,y3,chrom,angle); } break; case 0x03: /* Statistical/extended LTC */ { ULONG d; if (chrom_flag==TRUE) { chrom = *dptr++; } d = *dptr++; if (d & 0x80) /* extend LTC */ { ULONG angle,y0,y1,y2,y3; angle = (d >> 4) & 0x07; /* 3 bits angle */ d = (d << 8) | (*dptr++); y0 = (d >> 6) & 0x3f; y1 = d & 0x3f; y2 = (*dptr++) & 0x3f; y3 = (*dptr++) & 0x3f; AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr, y0,y1,y2,y3,chrom,angle); } else /* Statistical pattern */ { ULONG y0,y1; UBYTE flag0,flag1; flag0 = *dptr++; flag1 = (UBYTE)d; y0 = (*dptr++) & 0x3f; y1 = (*dptr++) & 0x3f; /* bit 0 => y0, bit 1 = > y1. */ /* raster scan order MSB = 0 */ if (special) { UBYTE r0,r1,g0,g1,b0,b1; UBYTE *ip = (UBYTE *)(image + 3 * (ty * imagex + tx) ); AVI_Get_Ulti_rgbColor(y0,chrom,&r0,&g0,&b0); AVI_Get_Ulti_rgbColor(y1,chrom,&r1,&g1,&b1); AVI_ULTI_rgbC2(ip,flag1,r0,r1,g0,g1,b0,b1,r_inc); ip += r_inc; AVI_ULTI_rgbC2(ip,flag0,r0,r1,g0,g1,b0,b1,r_inc); } else { ULONG c0,c1; c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr); c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr); if ( (x11_bytes_pixel==1) || (map_flag==FALSE) ) { UBYTE *ip = (UBYTE *)(image + (ty * imagex + tx) ); AVI_ULTI_C2(ip,flag1,UBYTE,c0,c1,r_inc); ip += r_inc; AVI_ULTI_C2(ip,flag0,UBYTE,c0,c1,r_inc); } else if (x11_bytes_pixel==4) { ULONG *ip = (ULONG *)(image + ((ty * imagex + tx)<<2) ); AVI_ULTI_C2(ip,flag1,ULONG,c0,c1,r_inc); ip += r_inc; AVI_ULTI_C2(ip,flag0,ULONG,c0,c1,r_inc); } else /* (x11_bytes_pixel==2) */ { USHORT *ip = (USHORT *)(image + ((ty * imagex + tx)<<1) ); AVI_ULTI_C2(ip,flag1,USHORT,c0,c1,r_inc); ip += r_inc; AVI_ULTI_C2(ip,flag0,USHORT,c0,c1,r_inc); } } } } break; case 0x06: /* Subsampled 4-luminance quadrant */ { ULONG y0,y1,y2,y3; if (chrom_flag==TRUE) { chrom = *dptr++; } y3 = (*dptr++) << 16; y3 |= (*dptr++) << 8; y3 |= (*dptr++); y0 = (y3 >> 18) & 0x3f; /* NW */ y1 = (y3 >> 12) & 0x3f; /* NE */ y2 = (y3 >> 6) & 0x3f; /* SW */ y3 &= 0x3f; /* SE */ AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr, y0,y1,y2,y3,chrom,0x10); } break; case 0x07: /* 16-luminance quadrant */ { ULONG i,d,y[16]; if (chrom_flag==TRUE) { chrom = *dptr++; } d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++); y[0] = (d >> 18) & 0x3f; y[1] = (d >> 12) & 0x3f; y[2] = (d >> 6) & 0x3f; y[3] = d & 0x3f; d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++); y[4] = (d >> 18) & 0x3f; y[5] = (d >> 12) & 0x3f; y[6] = (d >> 6) & 0x3f; y[7] = d & 0x3f; d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++); y[8] = (d >> 18) & 0x3f; y[9] = (d >> 12) & 0x3f; y[10] = (d >> 6) & 0x3f; y[11] = d & 0x3f; d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++); y[12] = (d >> 18) & 0x3f; y[13] = (d >> 12) & 0x3f; y[14] = (d >> 6) & 0x3f; y[15] = d & 0x3f; if (special) { UBYTE r,g,b,*ip = (UBYTE *)(image + 3 * (ty * imagex + tx) ); for(i=0;i<16;i++) { AVI_Get_Ulti_rgbColor(y[i],chrom,&r,&g,&b); *ip++ = r; *ip++ = g; *ip++ = b; if ( (i%4)==3) ip += r_inc; } } else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) ) { UBYTE c,*ip = (UBYTE *)(image + (ty * imagex + tx) ); for(i=0;i<16;i++) { c = (UBYTE)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr); *ip++ = c; if ( (i%4)==3) ip += r_inc; } } else if (x11_bytes_pixel==4) { ULONG c,*ip = (ULONG *)(image + ((ty * imagex + tx)<<2) ); for(i=0;i<16;i++) { c = (ULONG)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr); *ip++ = c; if ( (i%4)==3) ip += r_inc; } } else /* if (x11_bytes_pixel==2) */ { USHORT c,*ip = (USHORT *)(image + ((ty * imagex + tx)<<1) ); for(i=0;i<16;i++) { c = (USHORT)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr); *ip++ = c; if ( (i%4)==3) ip += r_inc; } } } break; default: fprintf(stderr,"Error opcode=%lx\n",opcode); break; } /* end of switch opcode */ } /* end of 4 quadrant */ { x += 8; if (x>=imagex) { x=0; y += 8; } } } /* end of not escape */ } /* end of while */ changed = 1; { *xs = *ys = 0; *xe = imagex; *ye = imagey; } if (map_flag) return(ACT_DLTA_MAPD); else return(ACT_DLTA_NORM); } void AVI_ULTI_Gen_YUV() { float r0,r1,b0,b1; LONG i; r0 = 16384.0 * 1.40200; b0 = 16384.0 * 1.77200; r1 = 16384.0 * -0.71414; b1 = 16384.0 * -0.34414; for(i=0;i<16;i++) { LONG tmp; float cr,cb; tmp = (i & 0x0f); cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0); cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0); ulti_Cr[i] = (LONG)(r0 * (float)(cr) ); ulti_Cb[i] = (LONG)(b0 * (float)(cb) ); } for(i=0;i<256;i++) { LONG tmp; float cr,cb; tmp = (i & 0x0f); cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0); tmp = ( (i>>4) & 0x0f); cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0); ulti_CrCb[i] = (LONG)(b1 * cb + r1 * cr); } } /* > > y = y6 / 63 > > u = (u4 - 5) / 40 > > v = (v4 - 6) / 34 I should have mentioned that these numbers come from inspecting the weird decimals used in the specification: 2.037 should be 2.032 = 63/31 8.226 = 255/31 6.375 = 255/40 7.5 = 255/34 */ void AVI_Get_Ulti_rgbColor(lum,chrom,r,g,b) LONG lum; ULONG chrom; UBYTE *r,*g,*b; { ULONG cr,cb,ra,ga,ba; LONG tmp; if (cmap_true_to_gray == TRUE) { ra = ba = ga = lum; } else { lum <<= 14; cb = (chrom >> 4) & 0x0f; cr = chrom & 0x0f; tmp = (lum + ulti_Cr[cr]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ra = tmp; tmp = (lum + ulti_Cb[cb]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ba = tmp; tmp = (lum + ulti_CrCb[chrom]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ga = tmp; } *r = (UBYTE)( (ra << 2) | (ra >> 4) ); *g = (UBYTE)( (ga << 2) | (ga >> 4) ); *b = (UBYTE)( (ba << 2) | (ba >> 4) ); } ULONG AVI_Get_Ulti_Color(lum,chrom,map_flag,map,chdr) LONG lum; /* 6 bits of lum */ ULONG chrom; /* 8 bits of chrom */ ULONG map_flag,*map; XA_CHDR *chdr; { register ULONG cr,cb,clr,ra,ga,ba,tr,tg,tb; LONG tmp; if (cmap_true_to_gray == TRUE) { ra = ba = ga = lum; } else { LONG lum1 = lum << 14; cb = (chrom >> 4) & 0x0f; cr = chrom & 0x0f; tmp = (lum1 + ulti_Cr[cr]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ra = tmp; tmp = (lum1 + ulti_Cb[cb]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ba = tmp; tmp = (lum1 + ulti_CrCb[chrom]) >> 14; if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63; ga = tmp; } tr = (ra << 2) | (ra >> 4); tg = (ga << 2) | (ga >> 4); tb = (ba << 2) | (ba >> 4); if (xa_gamma_flag==TRUE) { tr = xa_gamma_adj[tr]>>8; tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; } if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,5); else { if ((cmap_color_func == 4) && (chdr)) { register ULONG cache_i = ((lum << 8) | chrom) & 0x3fff; if (cmap_cache == 0) CMAP_Cache_Init(); if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; } if (cmap_cache[cache_i] == 0xffff) { clr = chdr->coff + CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,6,6,6,TRUE); cmap_cache[cache_i] = (USHORT)clr; } else clr = (ULONG)cmap_cache[cache_i]; } else { if (cmap_true_to_332 == TRUE) clr=CMAP_GET_332(tr,tg,tb,CMAP_SCALE8); else clr = CMAP_GET_GRAY(tr,tg,tb,CMAP_SCALE13); if (map_flag) clr = map[clr]; } } return(clr); } #define AVI_ULTI_0000(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; } #define AVI_ULTI_0225(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; } #define AVI_ULTI_0450(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; } #define AVI_ULTI_0675(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c2; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c1; } #define AVI_ULTI_0900(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \ *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; } #define AVI_ULTI_1125(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c2; ip += r_inc; \ *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \ *ip++ =(CST)c1; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; } #define AVI_ULTI_1350(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \ *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \ *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; } #define AVI_ULTI_1575(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \ *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; } #define AVI_ULTI_C4(ip,CST,c0,c1,c2,c3,r_inc) { \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \ *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; } void AVI_ULTI_LTC(image,x,y,imagex,special,map_flag,map,chdr, y0,y1,y2,y3,chrom,angle) UBYTE *image; ULONG x,y,imagex,special,map_flag,*map; XA_CHDR *chdr; ULONG y0,y1,y2,y3,chrom,angle; { ULONG r_inc; if (special) { ULONG i; UBYTE *ip = (UBYTE *)(image + 3 * (y * imagex + x) ); UBYTE r[4],g[4],b[4],*ix,idx[16]; r_inc = 3 * (imagex - 4); if (angle & 0x08) /* reverse */ { angle &= 0x07; AVI_Get_Ulti_rgbColor(y3,chrom,&r[0],&g[0],&b[0]); AVI_Get_Ulti_rgbColor(y2,chrom,&r[1],&g[1],&b[1]); AVI_Get_Ulti_rgbColor(y1,chrom,&r[2],&g[2],&b[2]); AVI_Get_Ulti_rgbColor(y0,chrom,&r[3],&g[3],&b[3]); } else { AVI_Get_Ulti_rgbColor(y0,chrom,&r[0],&g[0],&b[0]); if (y1==y0) {r[1]=r[0]; g[1]=g[0]; b[1]=b[0]; } else AVI_Get_Ulti_rgbColor(y1,chrom,&r[1],&g[1],&b[1]); if (y2==y1) {r[2]=r[1]; g[2]=g[1]; b[2]=b[1]; } else AVI_Get_Ulti_rgbColor(y2,chrom,&r[2],&g[2],&b[2]); if (y3==y2) {r[3]=r[2]; g[3]=g[2]; b[3]=b[2]; } else AVI_Get_Ulti_rgbColor(y3,chrom,&r[3],&g[3],&b[3]); } ix = idx; switch(angle) { case 0: AVI_ULTI_0000(ix,UBYTE,0,1,2,3,1); break; case 1: AVI_ULTI_0225(ix,UBYTE,0,1,2,3,1); break; case 2: AVI_ULTI_0450(ix,UBYTE,0,1,2,3,1); break; case 3: AVI_ULTI_0675(ix,UBYTE,0,1,2,3,1); break; case 4: AVI_ULTI_0900(ix,UBYTE,0,1,2,3,1); break; case 5: AVI_ULTI_1125(ix,UBYTE,0,1,2,3,1); break; case 6: AVI_ULTI_1350(ix,UBYTE,0,1,2,3,1); break; case 7: AVI_ULTI_1575(ix,UBYTE,0,1,2,3,1); break; default: AVI_ULTI_C4(ix,UBYTE,0,1,2,3,1); break; } /* end switch */ for(i=0;i<16;i++) { register ULONG j = idx[i]; *ip++ = r[j]; *ip++ = g[j]; *ip++ = b[j]; if ( (i & 3) == 3 ) ip += r_inc; } } else { ULONG c0,c1,c2,c3; r_inc = imagex - 3; if (angle & 0x08) /* reverse */ { angle &= 0x07; c0 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr); c1 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr); c2 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr); c3 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr); } else { c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr); if (y1==y0) c1 = c0; else c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr); if (y2==y1) c2 = c1; else c2 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr); if (y3==y2) c3 = c2; else c3 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr); } if ( (x11_bytes_pixel == 1) || (map_flag == FALSE) ) { UBYTE *ip = (UBYTE *)(image + (y * imagex + x) ); switch(angle) { case 0: AVI_ULTI_0000(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 1: AVI_ULTI_0225(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 2: AVI_ULTI_0450(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 3: AVI_ULTI_0675(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 4: AVI_ULTI_0900(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 5: AVI_ULTI_1125(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 6: AVI_ULTI_1350(ip,UBYTE,c0,c1,c2,c3,r_inc); break; case 7: AVI_ULTI_1575(ip,UBYTE,c0,c1,c2,c3,r_inc); break; default: AVI_ULTI_C4(ip,UBYTE,c0,c1,c2,c3,r_inc); break; } } else if (x11_bytes_pixel == 4) { ULONG *ip = (ULONG *)(image + ((y * imagex + x) << 2) ); switch(angle) { case 0: AVI_ULTI_0000(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 1: AVI_ULTI_0225(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 2: AVI_ULTI_0450(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 3: AVI_ULTI_0675(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 4: AVI_ULTI_0900(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 5: AVI_ULTI_1125(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 6: AVI_ULTI_1350(ip,ULONG,c0,c1,c2,c3,r_inc); break; case 7: AVI_ULTI_1575(ip,ULONG,c0,c1,c2,c3,r_inc); break; default: AVI_ULTI_C4(ip,ULONG,c0,c1,c2,c3,r_inc); break; } } else /* if (x11_bytes_pixel == 1) */ { USHORT *ip = (USHORT *)(image + ( (y * imagex + x) << 1) ); switch(angle) { case 0: AVI_ULTI_0000(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 1: AVI_ULTI_0225(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 2: AVI_ULTI_0450(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 3: AVI_ULTI_0675(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 4: AVI_ULTI_0900(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 5: AVI_ULTI_1125(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 6: AVI_ULTI_1350(ip,USHORT,c0,c1,c2,c3,r_inc); break; case 7: AVI_ULTI_1575(ip,USHORT,c0,c1,c2,c3,r_inc); break; default: AVI_ULTI_C4(ip,USHORT,c0,c1,c2,c3,r_inc); break; } } /* end of shorts */ } /* end of not special */ } /* end */ ULONG RIFF_Read_AUDS(fin,size,auds_hdr) FILE *fin; LONG size; AUDS_HDR *auds_hdr; { ULONG ret = TRUE; auds_hdr->format = UTIL_Get_LSB_Short(fin); auds_hdr->channels = UTIL_Get_LSB_Short(fin); auds_hdr->rate = UTIL_Get_LSB_Long(fin); auds_hdr->av_bps = UTIL_Get_LSB_Long(fin); auds_hdr->align = UTIL_Get_MSB_Short(fin); auds_hdr->size = UTIL_Get_LSB_Short(fin); DEBUG_LEVEL2 fprintf(stderr,"ret = %lx\n",ret); if (auds_hdr->format == WAVE_FORMAT_PCM) { if (auds_hdr->size == 8) avi_audio_type = XA_AUDIO_LINEAR; else if (auds_hdr->size == 16) avi_audio_type = XA_AUDIO_SIGNED; else avi_audio_type = XA_AUDIO_INVALID; } else if (auds_hdr->format == WAVE_FORMAT_ADPCM) { if (auds_hdr->size == 4) avi_audio_type = XA_AUDIO_ADPCM; else avi_audio_type = XA_AUDIO_INVALID; } else { avi_audio_type = XA_AUDIO_INVALID; ret = FALSE; } avi_audio_freq = auds_hdr->rate; avi_audio_chans = auds_hdr->channels; if (auds_hdr->size == 8) avi_audio_bps = 1; else if (auds_hdr->size == 16) avi_audio_bps = 2; else if (auds_hdr->size == 32) avi_audio_bps = 4; else if (auds_hdr->size == 4) avi_audio_bps = 1; else avi_audio_bps = 1000 + auds_hdr->size; avi_audio_end = 0; if (avi_audio_chans > 2) ret = FALSE; if (avi_audio_bps > 2) ret = FALSE; #ifdef POD_AUDIO_BETA if (xa_verbose) { fprintf(stderr," Audio: "); AVI_Audio_Type(auds_hdr->format); fprintf(stderr," Rate %ld Chans %ld bps %ld\n", avi_audio_freq,avi_audio_chans,auds_hdr->size); } #endif /* modify type */ if (avi_audio_chans==2) avi_audio_type |= XA_AUDIO_STEREO_MSK; if (avi_audio_bps==2) avi_audio_type |= XA_AUDIO_BPS_2_MSK; DEBUG_LEVEL2 fprintf(stderr,"ret = %lx\n",ret); if (size & 01) size++; size -= 16; while(size--) fgetc(fin); return(ret); } void AVI_Audio_Type(type) ULONG type; { switch(type) { case WAVE_FORMAT_PCM: fprintf(stderr,"PCM"); break; case WAVE_FORMAT_ADPCM: fprintf(stderr,"ADPCM"); break; case WAVE_FORMAT_ALAW: fprintf(stderr,"ALAW"); break; case WAVE_FORMAT_MULAW: fprintf(stderr,"ULAW"); break; case WAVE_FORMAT_OKI_ADPCM: fprintf(stderr,"OKI_ADPCM"); break; case IBM_FORMAT_MULAW: fprintf(stderr,"IBM_ULAW"); break; case IBM_FORMAT_ALAW: fprintf(stderr,"IBM_ALAW"); break; case IBM_FORMAT_ADPCM: fprintf(stderr,"IBM_ADPCM"); break; default: fprintf(stderr,"UNK%lx",type); break; } } static UBYTE avi_ulti_lin[11] = {2,3,5,6,7,8,11,14,17,20,255}; static UBYTE avi_ulti_lo[15] = {4,5,6,7,8,11,14,17,20,23,26,29,32,36,255}; static UBYTE avi_ulti_hi[14] = {6,8,11,14,17,20,23,26,29,32,35,40,46,255}; ULONG AVI_Ulti_Check(val,ptr) ULONG val; UBYTE *ptr; { while(*ptr != 255) if ((ULONG)(*ptr++) == val) return(1); return(0); } void AVI_Ulti_Gen_LTC() { LONG ys,ye,ydelta; UBYTE *utab; if (avi_ulti_tab==0) avi_ulti_tab = (UBYTE *)malloc(16384 * sizeof(UBYTE)); else return; if (avi_ulti_tab==0) TheEnd1("AVI_Ulti_Gen_LTC: malloc err"); utab = avi_ulti_tab; for(ys=0; ys <= 63; ys++) { for(ye=ys; ye <= 63; ye++) { ydelta = ye - ys; if (AVI_Ulti_Check(ydelta,avi_ulti_lin)) { ULONG yinc = (ydelta + 1) / 3; *utab++ = ys; *utab++ = ys + yinc; *utab++ = ye - yinc; *utab++ = ye; } if (AVI_Ulti_Check(ydelta,avi_ulti_lo)==1) { LONG y1,y2; float yd = (float)(ydelta); /* 1/4 */ y1 = ye - (LONG)( (2 * yd - 5.0) / 10.0 ); y2 = ye - (LONG)( ( yd - 5.0) / 10.0 ); *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye; /* 1/2 */ y2 = ys + (LONG)( (2 * yd + 5.0) / 10.0 ); *utab++ = ys; *utab++ = y2; *utab++ = y1; *utab++ = ye; /* 3/4 */ y1 = ys + (LONG)( ( yd + 5.0) / 10.0 ); *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye; } if (AVI_Ulti_Check(ydelta,avi_ulti_hi)==1) { *utab++ = ys; *utab++ = ye; *utab++ = ye; *utab++ = ye; *utab++ = ys; *utab++ = ys; *utab++ = ye; *utab++ = ye; *utab++ = ys; *utab++ = ys; *utab++ = ys; *utab++ = ye; } } } DEBUG_LEVEL1 { ULONG i; UBYTE *tmp = avi_ulti_tab; for(i=0;i<4096;i++) { fprintf(stderr,"%02lx %02lx %02lx %02lx\n",tmp[0],tmp[1],tmp[2],tmp[3]); tmp += 4; } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.