home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
Linux
/
Apps
/
xanim.tgz
/
xanim
/
xanim27064
/
xa_replay.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-26
|
31KB
|
985 lines
/*
* xa_replay.c
*
* Copyright (C) 1995,1996,1997 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.
*
*/
/*******************************
* Revision
*
*
********************************/
#include "xa_replay.h"
xaULONG ARM_Read_File();
ARM_FRAME *ARM_Add_Frame();
void ARM_Free_Frame_List();
void ACT_Setup_Delta();
xaULONG ARM_Read_Header();
xaULONG ARM_Read_Index();
void ARM_Read_Frame();
xaULONG ARM_Get_Length();
void ARM_Free_Stuff();
void ARM_Init_Tables();
xaULONG ARM_Decode_MLINES();
/* CODEC ROUTINES */
extern void yuv_to_rgb();
extern void XA_Gen_YUV_Tabs();
extern xaULONG XA_RGB24_To_CLR32();
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();
xaULONG CMAP_Find_Closest();
xaUBYTE *UTIL_RGB_To_FS_Map();
xaUBYTE *UTIL_RGB_To_Map();
void UTIL_FPS_2_Time();
extern XA_ANIM_SETUP *XA_Get_Anim_Setup();
extern XA_Add_Func_To_Free_Chain();
void XA_Free_Anim_Setup();
extern xaULONG XA_find_str();
xaUBYTE *ARM_prev_buff = 0;
xaULONG ARM_prev_buff_size = 0;
xaLONG *ARM_MOVL_X = 0;
xaLONG *ARM_MOVL_Y = 0;
xaULONG arm_audio_attempt;
xaULONG arm_audio_type;
xaULONG arm_audio_freq;
xaULONG arm_audio_chans;
xaULONG arm_audio_bps;
xaULONG XA_Add_Sound();
xaULONG arm_frame_cnt;
ARM_FRAME *arm_frame_start,*arm_frame_cur;
ARM_FRAME *ARM_Add_Frame(time,timelo,act)
xaULONG time,timelo;
XA_ACTION *act;
{
ARM_FRAME *fframe;
fframe = (ARM_FRAME *) malloc(sizeof(ARM_FRAME));
if (fframe == 0) TheEnd1("ARM_Add_Frame: malloc err");
fframe->time = time;
fframe->timelo = timelo;
fframe->act = act;
fframe->next = 0;
if (arm_frame_start == 0) arm_frame_start = fframe;
else arm_frame_cur->next = fframe;
arm_frame_cur = fframe;
arm_frame_cnt++;
return(fframe);
}
void ARM_Free_Frame_List(fframes)
ARM_FRAME *fframes;
{
ARM_FRAME *ftmp;
while(fframes != 0)
{
ftmp = fframes;
fframes = fframes->next;
FREE(ftmp,0xA000);
}
}
xaULONG ARM_Read_File(fname,anim_hdr,audio_attempt)
char *fname;
XA_ANIM_HDR *anim_hdr;
xaULONG audio_attempt; /* xaTRUE if audio is to be attempted */
{ XA_INPUT *xin = anim_hdr->xin;
xaLONG i,t_time;
xaULONG t_timelo;
XA_ANIM_SETUP *arm;
ARM_HDR arm_hdr;
arm = XA_Get_Anim_Setup();
arm->vid_time = XA_GET_TIME( 100 ); /* default */
arm_frame_cnt = 0;
arm_frame_start = 0;
arm_frame_cur = 0;
arm_audio_attempt = audio_attempt;
if (ARM_Read_Header(anim_hdr,xin,arm,&arm_hdr) == xaFALSE)
{
fprintf(stderr,"ARM: read header error\n");
xin->Close_File(xin);
return(xaFALSE);
}
if (ARM_Read_Index(xin,anim_hdr,arm,&arm_hdr)==xaFALSE) return(xaFALSE);
if (xa_verbose)
{
fprintf(stderr,"ARM %dx%dx%d frames %d\n",
arm->imagex,arm->imagey,arm->imagec,arm_frame_cnt);
}
if (arm_frame_cnt == 0)
{
fprintf(stderr,"ARM: No supported video frames exist in this file.\n");
return(xaFALSE);
}
anim_hdr->frame_lst = (XA_FRAME *)
malloc( sizeof(XA_FRAME) * (arm_frame_cnt+1));
if (anim_hdr->frame_lst == NULL) TheEnd1("ARM_Read_File: frame malloc err");
arm_frame_cur = arm_frame_start;
i = 0;
t_time = 0;
t_timelo = 0;
while(arm_frame_cur != 0)
{
if (i > arm_frame_cnt)
{
fprintf(stderr,"ARM_Read_Anim: frame inconsistency %d %d\n",
i,arm_frame_cnt);
break;
}
anim_hdr->frame_lst[i].time_dur = arm_frame_cur->time;
anim_hdr->frame_lst[i].zztime = t_time;
t_time += arm_frame_cur->time;
t_timelo += arm_frame_cur->timelo;
while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
anim_hdr->frame_lst[i].act = arm_frame_cur->act;
arm_frame_cur = arm_frame_cur->next;
i++;
}
anim_hdr->imagex = arm->imagex;
anim_hdr->imagey = arm->imagey;
anim_hdr->imagec = arm->imagec;
anim_hdr->imaged = 8; /* nop */
anim_hdr->frame_lst[i].time_dur = 0;
anim_hdr->frame_lst[i].zztime = -1;
anim_hdr->frame_lst[i].act = 0;
anim_hdr->loop_frame = 0;
if (!(xin->load_flag & XA_IN_LOAD_BUF)) anim_hdr->anim_flags |= ANIM_SNG_BUF;
if (xin->load_flag & XA_IN_LOAD_FILE) anim_hdr->anim_flags |= ANIM_USE_FILE;
anim_hdr->anim_flags |= ANIM_FULL_IM;
anim_hdr->max_fvid_size = arm->max_fvid_size;
anim_hdr->max_faud_size = arm->max_faud_size;
anim_hdr->fname = anim_hdr->name;
if (i > 0)
{
anim_hdr->last_frame = i - 1;
anim_hdr->total_time = anim_hdr->frame_lst[i-1].zztime
+ anim_hdr->frame_lst[i-1].time_dur;
}
else
{
anim_hdr->last_frame = 0;
anim_hdr->total_time = 0;
}
ARM_Free_Frame_List(arm_frame_start);
XA_Free_Anim_Setup(arm);
return(xaTRUE);
} /* end of read file */
#define ARM_MAX_LINE 256
char arm_line[ARM_MAX_LINE];
xaULONG ARM_Read_Line(xin,ptr)
XA_INPUT *xin;
char *ptr;
{ int i = 0;
while( !xin->At_EOF(xin,-1) )
{ int d = xin->Read_U8(xin);
if (d >= 0)
{ ptr[i] = d; i++;
if (i >= ARM_MAX_LINE) return(xaFALSE);
if ( (d == 0x0a) || (d == 0x0d) )
{ ptr[i] = 0;
DEBUG_LEVEL1 fprintf(stderr,"LINE: %s",ptr);
return(xaTRUE);
}
}
else return(xaFALSE);
}
return(xaFALSE);
}
xaULONG ARM_Read_Header(anim_hdr,xin,arm,arm_hdr)
XA_ANIM_HDR *anim_hdr;
XA_INPUT *xin;
XA_ANIM_SETUP *arm;
ARM_HDR *arm_hdr;
{ double tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* ARMovie */
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* name */
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* date/copyright */
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* author/etc */
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* video format */
if (arm_line[0] == '1') arm_hdr->vid_codec = ARM_VIDEO_MOVL_RGB;
else
{ fprintf(stderr,"ARM: Unsupported Video Type: %s,",arm_line);
arm_hdr->vid_codec = ARM_VIDEO_UNK;
}
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* width */
tmpf = atof(arm_line); arm_hdr->width = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* height */
tmpf = atof(arm_line); arm_hdr->height = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* depth */
tmpf = atof(arm_line); arm_hdr->depth = (xaLONG)tmpf;
/* Check Video Precision Line for modifiers */
if (arm_hdr->vid_codec == ARM_VIDEO_MOVL_RGB)
{
if ( (XA_find_str(arm_line,"yuv") == xaTRUE)
|| (XA_find_str(arm_line,"YUV") == xaTRUE) )
arm_hdr->vid_codec = ARM_VIDEO_MOVL_YUV;
}
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* fps */
arm_hdr->fps = atof(arm_line);
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*audio format */
if (arm_audio_attempt == xaTRUE)
{
if (arm_line[0] == '0')
{
arm_hdr->aud_codec = ARM_AUDIO_NONE;
arm_audio_attempt = xaFALSE;
}
else if (arm_line[0] == '1')
{
arm_hdr->aud_codec = ARM_AUDIO_FORM1;
}
else
{
fprintf(stderr,"ARM: Unsupported Audio Type: %s\n",arm_line);
arm_hdr->aud_codec = ARM_AUDIO_UNK;
arm_audio_attempt = xaFALSE;
}
}
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* audio freq */
/* NOTE: this can be fraction HZ - eventually support this or us */
tmpf = atof(arm_line);
{ static unsigned char us[3] = { 0xB5, 0x73, 0x00 };
if (XA_find_str(arm_line,us)==xaTRUE)
{ double freq = (1000000.0 / tmpf) + 0.5;
arm_hdr->aud_freq = (xaLONG)freq;
}
else arm_hdr->aud_freq = (xaLONG)tmpf;
}
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* audio chans */
tmpf = atof(arm_line); arm_hdr->aud_chans = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* audio prec */
tmpf = atof(arm_line); arm_hdr->aud_prec = (xaLONG)tmpf;
/* Check Audio Precision Line for modifiers */
if (arm_audio_attempt == xaTRUE)
{
arm_audio_freq = arm_hdr->aud_freq;
arm_audio_chans = arm_hdr->aud_chans;
if (arm_hdr->aud_prec == 8) arm_audio_bps = 1;
else if (arm_hdr->aud_prec == 16) arm_audio_bps = 2;
else arm_audio_bps = 0;
if ( XA_find_str(arm_line,"linear") == xaTRUE)
{
if (xa_verbose==xaTRUE)
fprintf(stderr,"AUDIO: Signed %dHz chans: %d bits: %d\n",
arm_audio_freq,arm_audio_chans,arm_hdr->aud_prec);
arm_audio_type = XA_AUDIO_SIGNED; /* NOTE: little endian */
}
else if ( XA_find_str(arm_line,"logarithmic") == xaTRUE)
{
if (xa_verbose==xaTRUE)
fprintf(stderr,"AUDIO: LOGARITHMIC %dHz chans: %d bits: %d\n",
arm_audio_freq,arm_audio_chans,arm_hdr->aud_prec);
arm_audio_type = XA_AUDIO_ARMLAW; /* NOTE: little endian */
}
else arm_audio_type = XA_AUDIO_INVALID;
/* paranoia */
if ( (arm_audio_chans > 2) || (arm_audio_chans == 0) )
arm_audio_type = XA_AUDIO_INVALID;
if ( (arm_audio_bps > 2) || (arm_audio_bps == 0) )
arm_audio_type = XA_AUDIO_INVALID;
/* warning and final modifications */
if (arm_audio_type == XA_AUDIO_INVALID)
{
if (arm_audio_attempt == xaTRUE)
fprintf(stderr,"ARM: Audio Type unsupported %d \n",
arm_hdr->aud_codec);
arm_audio_attempt = xaFALSE;
}
else
{
if (arm_audio_chans == 2) arm_audio_type |= XA_AUDIO_STEREO_MSK;
if (arm_audio_bps == 2) arm_audio_type |= XA_AUDIO_BPS_2_MSK;
}
}
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE);/*frames perchnk*/
tmpf = atof(arm_line); arm_hdr->fp_chunk = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* chunk cnt */
tmpf = atof(arm_line); arm_hdr->chunk_cnt = (xaLONG)tmpf;
/* This is necessary so +CF4 will function correctly */
arm->cmap_frame_num = (arm_hdr->chunk_cnt * arm_hdr->fp_chunk)
/ cmap_sample_cnt;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*ev chunk sz */
tmpf = atof(arm_line); arm_hdr->ev_chk_size = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*od chunk sz */
tmpf = atof(arm_line); arm_hdr->od_chk_size = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /* idx offset */
tmpf = atof(arm_line); arm_hdr->idx_offset = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*sprite offset*/
tmpf = atof(arm_line); arm_hdr->sprite_off = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*sprite size*/
tmpf = atof(arm_line); arm_hdr->sprite_size = (xaLONG)tmpf;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*key offset */
tmpf = atof(arm_line); arm_hdr->key_offset = (xaLONG)tmpf;
UTIL_FPS_2_Time(arm, arm_hdr->fps );
/*
switch(arm_hdr->aud_codec)
{
}
*/
arm->depth = arm_hdr->depth;
arm->imagex = arm_hdr->width;
arm->imagey = arm_hdr->height;
XA_Gen_YUV_Tabs(anim_hdr);
ARM_Init_Tables(anim_hdr,arm->imagex,arm->imagey);
if (xa_verbose)
{
fprintf(stderr,"ARM: %dx%dx%x\n",arm->imagex,arm->imagey,arm->depth);
}
if ( (cmap_true_map_flag == xaFALSE) /* depth 16 and not true_map */
|| (!(xin->load_flag & XA_IN_LOAD_BUF)) )
{
if (cmap_true_to_332 == xaTRUE)
arm->chdr = CMAP_Create_332(arm->cmap,&arm->imagec);
else arm->chdr = CMAP_Create_Gray(arm->cmap,&arm->imagec);
}
if ( (arm->pic==0) && (xin->load_flag & XA_IN_LOAD_BUF))
{
arm->pic_size = arm->imagex * arm->imagey;
if ( (cmap_true_map_flag == xaTRUE) && (arm->depth > 8) )
arm->pic = (xaUBYTE *) malloc( 3 * arm->pic_size );
else arm->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(arm->pic_size) );
if (arm->pic == 0) TheEnd1("ARM_Buffer_Action: malloc failed");
}
return(xaTRUE);
}
xaULONG ARM_Read_Index(xin,anim_hdr,arm,arm_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *arm;
ARM_HDR *arm_hdr;
{ xaULONG idx_cnt = arm_hdr->chunk_cnt;
xaULONG i,*idx_off,*idx_vsize,*idx_asize;
idx_off = (xaULONG *)malloc( (idx_cnt + 2) * sizeof(xaULONG) );
idx_vsize = (xaULONG *)malloc( (idx_cnt + 2) * sizeof(xaULONG) );
idx_asize = (xaULONG *)malloc( (idx_cnt + 2) * sizeof(xaULONG) );
DEBUG_LEVEL2 fprintf(stderr," idx offset %08x\n",arm_hdr->idx_offset);
xin->Seek_FPos(xin,arm_hdr->idx_offset,0);
/* Go Through Chunks */
for(i=0; i<=idx_cnt; i++)
{ xaLONG off, vid_size, aud_size, ret;
if (ARM_Read_Line(xin,arm_line) == xaFALSE) return(xaFALSE); /*chunk count*/
ret = sscanf(arm_line,"%d,%d;%d",&off,&vid_size,&aud_size);
DEBUG_LEVEL1
{
fprintf(stderr," (%d) %d) off %08x vid %08x aud %08x\n",ret,i,
off,vid_size,aud_size);
}
idx_off[i] = off;
idx_vsize[i] = vid_size;
idx_asize[i] = aud_size;
} /* end of for */
for(i=0; i<=idx_cnt; i++)
{ xaULONG j; xaULONG tot_dsize = 0;
DEBUG_LEVEL1 fprintf(stderr," idx %d) chunks %d\n",i, arm_hdr->fp_chunk);
/* VIDEO */
xin->Seek_FPos(xin,idx_off[i],0);
for(j=0; j < arm_hdr->fp_chunk; j++)
{ xaULONG fpos,dsize;
fpos = xin->Get_FPos(xin); /* save xin position */
dsize = ARM_Get_Length(xin,arm); /* find length of delta */
xin->Seek_FPos(xin,fpos,0); /* return to xin position */
ARM_Read_Frame(xin,anim_hdr,arm,arm_hdr,dsize);
tot_dsize += dsize;
}
/* AUDIO */
if (arm_audio_attempt == xaTRUE)
{ xaLONG ret, snd_size = (xaLONG)idx_asize[i];
xaULONG snd_off = idx_off[i] + idx_vsize[i];
if (xin->load_flag & XA_IN_LOAD_FILE)
{ xaLONG rets;
rets = XA_Add_Sound(anim_hdr,0,arm_audio_type, snd_off,
arm_audio_freq, snd_size,
&arm->aud_time,&arm->aud_timelo, 0, 0);
if (rets==xaFALSE) arm_audio_attempt = xaFALSE;
if (snd_size > arm->max_faud_size) arm->max_faud_size = snd_size;
}
else
{ xaUBYTE *snd = (xaUBYTE *)malloc(snd_size);
if (snd==0) TheEnd1("ARM: snd malloc err");
xin->Seek_FPos(xin,snd_off,0); /* seek to audio info */
ret = xin->Read_Block(xin, snd, snd_size);
if (ret < snd_size) fprintf(stderr,"ARM: snd rd err(size %x\n",snd_size);
else
{ int rets;
/*NOTE: don't free snd */
rets = XA_Add_Sound(anim_hdr,snd,arm_audio_type, -1,
arm_audio_freq, snd_size,
&arm->aud_time, &arm->aud_timelo, 0, 0);
if (rets==xaFALSE) arm_audio_attempt = xaFALSE;
}
}
} /* end of audio attempt */
}
free(idx_off);
free(idx_vsize);
free(idx_asize);
return(xaTRUE);
}
/* Assuming xin is pointing to start of delta.
* leaves xin just after end of delta.
*/
void ARM_Read_Frame(xin,anim_hdr,arm,arm_hdr,vsize)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *arm;
ARM_HDR *arm_hdr;
xaLONG vsize;
{ XA_ACTION *act;
xaULONG dlta_len = vsize;
ACT_DLTA_HDR *dlta_hdr;
act = ACT_Get_Action(anim_hdr,ACT_DELTA);
if (xin->load_flag & XA_IN_LOAD_FILE)
{
dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
if (dlta_hdr == 0) TheEnd1("ARM: dlta malloc err");
act->data = (xaUBYTE *)dlta_hdr;
dlta_hdr->flags = ACT_SNGL_BUF;
dlta_hdr->fsize = dlta_len;
dlta_hdr->fpos = xin->Get_FPos(xin);
if (dlta_len > arm->max_fvid_size) arm->max_fvid_size = dlta_len;
xin->Seek_FPos(xin,dlta_len,1);
}
else
{ xaULONG d; xaLONG ret;
d = dlta_len + (sizeof(ACT_DLTA_HDR));
dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
if (dlta_hdr == 0) TheEnd1("QT rle: malloc failed");
act->data = (xaUBYTE *)dlta_hdr;
dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
dlta_hdr->fpos = 0; dlta_hdr->fsize = dlta_len;
ret = xin->Read_Block(xin, dlta_hdr->data, dlta_len);
if (ret < dlta_len) { fprintf(stderr,"ARM: read err\n"); return; }
}
ARM_Add_Frame(arm->vid_time,arm->vid_timelo,act);
dlta_hdr->xpos = dlta_hdr->ypos = 0;
dlta_hdr->xsize = arm->imagex;
dlta_hdr->ysize = arm->imagey;
dlta_hdr->special = 0;
if (arm_hdr->vid_codec == ARM_VIDEO_MOVL_YUV)
dlta_hdr->extra = (void *)(ARM_VIDEO_YUV);
else dlta_hdr->extra = (void *)(ARM_VIDEO_RGB);
dlta_hdr->xapi_rev = 0x0001;
dlta_hdr->delta = ARM_Decode_MLINES;
ACT_Setup_Delta(arm,act,dlta_hdr,xin);
}
#define ARM_15YUV(pix,y,u,v) { \
v = (pix >> 10) & 0x1f; u = (pix >> 5) & 0x1f; y = pix & 0x1f; \
u ^= 0x10; v ^= 0x10; \
y = (y << 3) | (y >> 2); u = (u << 3) | (u >> 2); v = (v << 3) | (v >> 2); \
}
#define ARM_16YUV(pix,y,u,v) { \
v = (pix >> 11) & 0x1f; u = (pix >> 6) & 0x1f; y = (pix >> 1) & 0x1f; \
u ^= 0x10; v ^= 0x10; \
y = (y << 3) | (y >> 2); u = (u << 3) | (u >> 2); v = (v << 3) | (v >> 2); \
}
#define ARM_GET_CODE(dp,code) {code = (*dp++); code |= (*dp++) << 8; }
xaULONG ARM_Get_RGB_Pixel(pix,map_flag,map,chdr)
xaULONG pix,map_flag,*map;
XA_CHDR *chdr;
{ xaULONG r,g,b;
r = (pix >> 10) & 0x1f; g = (pix >> 5) & 0x1f; b = pix & 0x1f;
r = (r << 3) | (r >> 2); g = (g << 3) | (g >> 2); b = (b << 3) | (b >> 2);
return( XA_RGB24_To_CLR32(r,g,b,map_flag,map,chdr) );
}
xaULONG ARM_Get_YUV_Pixel(pix,map_flag,map,chdr)
xaULONG pix,map_flag,*map;
XA_CHDR *chdr;
{ xaULONG y,u,v,r,g,b;
v = (pix >> 10) & 0x1f; u = (pix >> 5) & 0x1f; y = pix & 0x1f;
u ^= 0x10; v ^= 0x10;
y = (y << 3) | (y >> 2); u = (u << 3) | (u >> 2); v = (v << 3) | (v >> 2);
yuv_to_rgb(y,u,v,&r,&g,&b);
return( XA_RGB24_To_CLR32(r,g,b,map_flag,map,chdr) );
}
xaULONG ARM_Get_RGB_RGB(pix,ir,ig,ib)
xaULONG pix;
xaULONG *ir,*ig,*ib;
{ xaULONG r,g,b;
r = (pix >> 10) & 0x1f; g = (pix >> 5) & 0x1f; b = pix & 0x1f;
r = (r << 3) | (r >> 2); g = (g << 3) | (g >> 2); b = (b << 3) | (b >> 2);
*ir = r; *ig = g; *ib = b;
return(1);
}
xaULONG ARM_Get_YUV_RGB(pix,ir,ig,ib)
xaULONG pix;
xaULONG *ir,*ig,*ib;
{ xaULONG y,u,v;
v = (pix >> 10) & 0x1f; u = (pix >> 5) & 0x1f; y = pix & 0x1f;
u ^= 0x10; v ^= 0x10;
y = (y << 3) | (y >> 2); u = (u << 3) | (u >> 2); v = (v << 3) | (v >> 2);
yuv_to_rgb(y,u,v,ir,ig,ib);
return(1);
}
/* TEST */
xaULONG
ARM_Decode_MLINES(image,delta,dsize,dec_info)
xaUBYTE *image; /* Image Buffer. */
xaUBYTE *delta; /* delta data. */
xaULONG dsize; /* delta size */
XA_DEC_INFO *dec_info; /* Decoder Info Header */
{ xaULONG imagex = dec_info->imagex; xaULONG imagey = dec_info->imagey;
xaULONG map_flag = dec_info->map_flag; xaULONG *map = dec_info->map;
xaULONG special = dec_info->special; void *extra = dec_info->extra;
XA_CHDR *chdr = dec_info->chdr;
xaUBYTE *dp = delta;
xaULONG special_flag = special & 0x0001;
xaLONG i_cnt,im_size = imagex * imagey;
xaULONG code;
xaUBYTE *pptr = ARM_prev_buff;
xaULONG vid_type = (xaULONG)(extra);
xaULONG (*arm_get_pixel)();
if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
/* Need to copy previous image, since Temporal references it */
{ i_cnt = im_size * ((special_flag)?(3):(x11_bytes_pixel));
memcpy((char *)(pptr),(char *)(image),(i_cnt));
}
/* */
if (special)
{
if (vid_type == ARM_VIDEO_YUV) arm_get_pixel = ARM_Get_YUV_RGB;
else arm_get_pixel = ARM_Get_RGB_RGB;
}
else
{
if (vid_type == ARM_VIDEO_YUV) arm_get_pixel = ARM_Get_YUV_Pixel;
else arm_get_pixel = ARM_Get_RGB_Pixel;
}
i_cnt = 0;
if (special)
{ xaUBYTE *iptr = image;
while(i_cnt < im_size)
{ ARM_GET_CODE(dp,code);
if (code & 0x01)
{ xaULONG test,cnt;
if (code == 0xe601) { i_cnt = im_size; break; } /* End of Frame */
test = code >> 7; cnt = ((code >> 1) & 0x3f) + 2;
if (test < 0x1cc) /* Temporal/Spatial */
{ xaUBYTE *isp;
if (test < 0x120) { isp = pptr; isp += (3 * i_cnt); } /* temporal */
else isp = iptr; /* spatial */
isp += 3 * (ARM_MOVL_X[test] + (ARM_MOVL_Y[test] * imagex));
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) { *iptr++ = *isp++; *iptr++ = *isp++; *iptr++ = *isp++; }
}
else if (test >= 0x1e0)
{ cnt = ((code >> 1) & 0x3ff) + 1;
if (test >=0x1f0) /* New N Pixels */
{ xaLONG arm_bcnt = ((((cnt * 15) + 15) >> 4) << 1); /* dp bytes */
xaLONG arm_b_bnum = 0; xaULONG arm_b_bbuf = 0;
DEBUG_LEVEL1 fprintf(stderr,"New N Pixels %d\n",cnt);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) /* pixels */
{ xaULONG r,g,b; /* Little Endian */
while(arm_b_bnum < 15) { arm_b_bbuf |= (*dp++) << arm_b_bnum;
arm_b_bnum += 8; arm_bcnt--; }
arm_get_pixel(arm_b_bbuf,&r,&g,&b);
*iptr++ = (xaUBYTE)r; *iptr++ = (xaUBYTE)g; *iptr++ = (xaUBYTE)b;
arm_b_bbuf >>= 15; arm_b_bnum -= 15;
}
while(arm_bcnt--) dp++; /* left overs */
} else { iptr += (3 * cnt); i_cnt += cnt; } /* Copy/Skip */
}
else if (test == 0x1cc)
{ xaULONG r,g,b,pixel;
ARM_GET_CODE(dp,pixel);
arm_get_pixel(pixel,&r,&g,&b);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) { *iptr++ = (xaUBYTE)r;
*iptr++ = (xaUBYTE)g; *iptr++ = (xaUBYTE)b; }
} else fprintf(stderr,"ARM decode ERROR: %04x\n",code);
}
else /* New Pixel */
{ xaULONG r,g,b; arm_get_pixel((code>>1),&r,&g,&b); i_cnt++;
*iptr++ = (xaUBYTE)r; *iptr++ = (xaUBYTE)g; *iptr++ = (xaUBYTE)b;
}
}
}
else if ( (x11_bytes_pixel==1) || (map_flag == xaFALSE) )
{ xaUBYTE *iptr = image;
while(i_cnt < im_size)
{ ARM_GET_CODE(dp,code);
if (code & 0x01)
{ xaULONG test,cnt;
if (code == 0xe601) { i_cnt = im_size; break; } /* End of Frame */
test = code >> 7; cnt = ((code >> 1) & 0x3f) + 2;
if (test < 0x1cc) /* Temporal/Spatial */
{ xaUBYTE *isp;
if (test < 0x120) { isp = pptr; isp += i_cnt; } /* temporal */
else isp = iptr; /* spatial */
isp += (ARM_MOVL_X[test] + (ARM_MOVL_Y[test] * imagex));
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = *isp++;
}
else if (test >= 0x1e0)
{ cnt = ((code >> 1) & 0x3ff) + 1;
if (test >=0x1f0) /* New N Pixels */
{ xaLONG arm_bcnt = ((((cnt * 15) + 15) >> 4) << 1); /* dp bytes */
xaLONG arm_b_bnum = 0; xaULONG arm_b_bbuf = 0;
DEBUG_LEVEL1 fprintf(stderr,"New N Pixels %d\n",cnt);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) /* pixels */
{ /* Little Endian */
while(arm_b_bnum < 15) { arm_b_bbuf |= (*dp++) << arm_b_bnum;
arm_b_bnum += 8; arm_bcnt--; }
*iptr++ = (xaUBYTE)arm_get_pixel(arm_b_bbuf,map_flag,map,chdr);
arm_b_bbuf >>= 15; arm_b_bnum -= 15;
}
while(arm_bcnt--) dp++; /* left overs */
} else { iptr += cnt; i_cnt += cnt; } /* Copy/Skip */
}
else if (test == 0x1cc)
{ xaULONG pixel; xaUBYTE d;
ARM_GET_CODE(dp,pixel);
d = (xaUBYTE)arm_get_pixel(pixel,map_flag,map,chdr);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = d;
} else fprintf(stderr,"ARM decode ERROR: %04x\n",code);
}
else /* New Pixel */
{ *iptr++ = (xaUBYTE)arm_get_pixel((code>>1),map_flag,map,chdr); i_cnt++; }
}
} /* end of byte 1 */
else if (x11_bytes_pixel==4)
{ xaULONG *iptr = (xaULONG *)image;
while(i_cnt < im_size)
{ ARM_GET_CODE(dp,code);
if (code & 0x01)
{ xaULONG test,cnt;
if (code == 0xe601) { i_cnt = im_size; break; } /* End of Frame */
test = code >> 7; cnt = ((code >> 1) & 0x3f) + 2;
if (test < 0x1cc) /* Temporal/Spatial */
{ xaULONG *isp;
if (test < 0x120) { isp = (xaULONG *)pptr; isp += i_cnt; }/*temporal */
else isp = (xaULONG *)iptr; /* spatial */
isp += (ARM_MOVL_X[test] + (ARM_MOVL_Y[test] * imagex));
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = *isp++;
}
else if (test >= 0x1e0)
{ cnt = ((code >> 1) & 0x3ff) + 1;
if (test >=0x1f0) /* New N Pixels */
{ xaLONG arm_bcnt = ((((cnt * 15) + 15) >> 4) << 1); /* dp bytes */
xaLONG arm_b_bnum = 0; xaULONG arm_b_bbuf = 0;
DEBUG_LEVEL1 fprintf(stderr,"New N Pixels %d\n",cnt);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) /* pixels */
{ /* Little Endian */
while(arm_b_bnum < 15) { arm_b_bbuf |= (*dp++) << arm_b_bnum;
arm_b_bnum += 8; arm_bcnt--; }
*iptr++ = (xaULONG)arm_get_pixel(arm_b_bbuf,map_flag,map,chdr);
arm_b_bbuf >>= 15; arm_b_bnum -= 15;
}
while(arm_bcnt--) dp++; /* left overs */
} else { iptr += cnt; i_cnt += cnt; } /* Copy/Skip */
}
else if (test == 0x1cc)
{ xaULONG pixel; xaULONG d;
ARM_GET_CODE(dp,pixel);
d = (xaULONG)arm_get_pixel(pixel,map_flag,map,chdr);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = d;
} else fprintf(stderr,"ARM decode ERROR: %04x\n",code);
}
else /* New Pixel */
{ *iptr++ = (xaULONG)arm_get_pixel((code>>1),map_flag,map,chdr); i_cnt++; }
}
} /* end of byte 4 */
else /* if (x11_bytes_pixel==2) */
{ xaUSHORT *iptr = (xaUSHORT *)image;
while(i_cnt < im_size)
{ ARM_GET_CODE(dp,code);
if (code & 0x01)
{ xaULONG test,cnt;
if (code == 0xe601) { i_cnt = im_size; break; } /* End of Frame */
test = code >> 7; cnt = ((code >> 1) & 0x3f) + 2;
if (test < 0x1cc) /* Temporal/Spatial */
{ xaUSHORT *isp;
if (test < 0x120) { isp = (xaUSHORT *)pptr; isp += i_cnt; }/*temporal */
else isp = (xaUSHORT *)iptr; /* spatial */
isp += (ARM_MOVL_X[test] + (ARM_MOVL_Y[test] * imagex));
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = *isp++;
}
else if (test >= 0x1e0)
{ cnt = ((code >> 1) & 0x3ff) + 1;
if (test >=0x1f0) /* New N Pixels */
{ xaLONG arm_bcnt = ((((cnt * 15) + 15) >> 4) << 1); /* dp bytes */
xaLONG arm_b_bnum = 0; xaULONG arm_b_bbuf = 0;
DEBUG_LEVEL1 fprintf(stderr,"New N Pixels %d\n",cnt);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) /* pixels */
{ /* Little Endian */
while(arm_b_bnum < 15) { arm_b_bbuf |= (*dp++) << arm_b_bnum;
arm_b_bnum += 8; arm_bcnt--; }
*iptr++ = (xaUSHORT)arm_get_pixel(arm_b_bbuf,map_flag,map,chdr);
arm_b_bbuf >>= 15; arm_b_bnum -= 15;
}
while(arm_bcnt--) dp++; /* left overs */
} else { iptr += cnt; i_cnt += cnt; } /* Copy/Skip */
}
else if (test == 0x1cc)
{ xaULONG pixel; xaUSHORT d;
ARM_GET_CODE(dp,pixel);
d = (xaUSHORT)arm_get_pixel(pixel,map_flag,map,chdr);
i_cnt += cnt; if (i_cnt >= im_size) cnt -= (i_cnt - im_size);
while(cnt--) *iptr++ = d;
} else fprintf(stderr,"ARM decode ERROR: %04x\n",code);
}
else /* New Pixel */
{ *iptr++ = (xaUSHORT)arm_get_pixel((code>>1),map_flag,map,chdr); i_cnt++; }
}
} /* end of byte 2 */
dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
if (map_flag==xaTRUE) return(ACT_DLTA_MAPD);
else return(ACT_DLTA_NORM);
}
xaULONG ARM_Get_Length(xin,arm)
XA_INPUT *xin;
XA_ANIM_SETUP *arm;
{ xaULONG d_cnt = 0;
xaLONG i = arm->imagex * arm->imagey;
xaULONG code;
while(i > 0)
{
if ( xin->At_EOF(xin,-1) ) return(0);
code = xin->Read_LSB_U16(xin); d_cnt += 2;
if (code & 0x01)
{ xaULONG test,cnt;
if (code == 0xe601) return(d_cnt); /* End of Frame */
test = code >> 7;
cnt = ((code >> 1) & 0x3f) + 2;
if (test < 0x120) { i -= cnt; } /* Temporal */
else if (test < 0x1cc) { i -= cnt; } /* Spatial */
else if (test >= 0x1e0) /* New N Pix */
{ cnt = ((code >> 1) & 0x3ff) + 1;
if (test >=0x1f0) /* New N Pixels */
{ xaULONG bs = ((cnt * 15) + 15) >> 4;
i -= cnt;
while(bs--) { xin->Read_LSB_U16(xin); d_cnt += 2; }
}
else { i -= cnt; } /* Copy/Skip */
}
else if (test == 0x1cc) /* Duplicate */
{
if (cnt <= 2) {fprintf(stderr,"DUP CNT ERR\n"); continue; }
xin->Read_LSB_U16(xin); d_cnt += 2;
i -= cnt;
}
else
{
fprintf(stderr,"ARM Get len error: %04x\n",code);
}
}
else { i--; } /* New Pixel */
}
code = xin->Read_LSB_U16(xin);
if (code == 0xe601) d_cnt += 2;
return(d_cnt);
}
void arm_yuv_to_rgb(iy,iu,iv,ir,ig,ib)
xaULONG iy,iu,iv;
xaULONG *ir,*ig,*ib;
{ float yy,uu,vv;
float u2,u3,v2,v3;
float DD;
float rr,gg,bb;
DD = 255.0;
yy = ((float)(iy)/31.0);
vv = ((float)(iv)/15.0);
uu = ((float)(iu)/15.0);
if (vv > 1.0) vv = -((31.0 - (float)(iv) ) / 15.0);
if (uu > 1.0) uu = -((31.0 - (float)(iu) ) / 15.0);
v2 = vv * 0.701;
u2 = uu * 0.886;
v3 = vv * (0.299 * 0.701 / 0.587);
u3 = uu * (0.114 * 0.886 / 0.587);
bb = (yy + u2);
rr = (yy + v2);
gg = (yy - u3 - v3);
DEBUG_LEVEL1
fprintf(stderr,"rr = %f gg = %f bb = %f\n",rr,gg,bb);
bb *= 255.0;
rr *= 255.0;
gg *= 255.0;
if (bb > 255.0) bb = 255.0; if (bb < 0.0) bb = 0.0;
if (rr > 255.0) rr = 255.0; if (rr < 0.0) rr = 0.0;
if (gg > 255.0) gg = 255.0; if (gg < 0.0) gg = 0.0;
*ir = (xaULONG)(rr);
*ig = (xaULONG)(gg);
*ib = (xaULONG)(bb);
DEBUG_LEVEL1
fprintf(stderr,"YUV %d %d %d RGB %d %d %d\n",iy,iu,iv,*ir,*ig,*ib);
}
/*****************************
* Function To allocate and initialized the following tables and buffers:
*
*********/
void ARM_Init_Tables(anim_hdr,imagex,imagey)
XA_ANIM_HDR *anim_hdr;
xaULONG imagex,imagey;
{ xaULONG i; xaLONG x,y;
XA_Add_Func_To_Free_Chain(anim_hdr,ARM_Free_Stuff);
/* Prev Buffer Allocation */
if (cmap_color_func == 4) i = xaMAX(3,x11_bytes_pixel);
else i = x11_bytes_pixel;
i *= imagex * imagey;
if (ARM_prev_buff == 0)
{ ARM_prev_buff_size = i;
ARM_prev_buff = (xaUBYTE *)malloc( ARM_prev_buff_size );
}
else if (i > ARM_prev_buff_size)
{ ARM_prev_buff_size = i;
ARM_prev_buff = (xaUBYTE *)realloc( ARM_prev_buff, ARM_prev_buff_size );
}
if (ARM_prev_buff == 0) TheEnd1("ARM: prev_buff malloc err");
/* Spatial/Temporal Tables Allocation */
if (ARM_MOVL_X == 0)
{ ARM_MOVL_X = (xaLONG *)malloc( 459 * sizeof(xaLONG) );
if (ARM_MOVL_X==0) TheEnd1("ARM: MOVL_X malloc err");
}
if (ARM_MOVL_Y == 0)
{ ARM_MOVL_Y = (xaLONG *)malloc( 459 * sizeof(xaLONG) );
if (ARM_MOVL_Y==0) TheEnd1("ARM: MOVL_Y malloc err");
}
/* Temporal Encoding */
x = y = -8;
for(i = 0; i < 288; i++)
{ ARM_MOVL_X[i] = x;
ARM_MOVL_Y[i] = y;
x++; if (x > 8) { x = -8; y++; }
if ((x==0) && (y==0)) x++; /* skip x = y = 0 case */
}
/* Spatial Encoding */
x = y = -9;
for(i = 288; i < 459; i++)
{ ARM_MOVL_X[i] = x;
ARM_MOVL_Y[i] = y;
x++; if (x > 9) { x = -9; y++; }
}
}
/*****************************
* Function To Free the following tables and buffers.
*
*********/
void ARM_Free_Stuff()
{
if (ARM_MOVL_X) { free(ARM_MOVL_X); ARM_MOVL_X = 0; }
if (ARM_MOVL_Y) { free(ARM_MOVL_Y); ARM_MOVL_Y = 0; }
if (ARM_prev_buff) { free(ARM_prev_buff); ARM_prev_buff = 0; }
}