home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
Linux
/
Apps
/
xanim.tgz
/
xanim
/
xanim27064
/
xa_movi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-26
|
47KB
|
1,422 lines
/*
* xa_movi.c
*
* Copyright (C) 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_movi.h"
xaULONG MOVI_Read_File();
MOVI_FRAME *MOVI_Add_Frame();
void MOVI_Free_Frame_List();
void ACT_Setup_Delta();
float MOVI_Read_Float();
xaULONG MOVI_Read_Int();
xaULONG MOVI_Read_I_Compression();
xaULONG MOVI_Read_A_Compression();
xaULONG MOVI_Read_Header();
xaULONG MOVI_Read_Header2();
xaULONG MOVI_Read_Header3();
xaULONG MOVI_Parse_MOVI_HDR();
xaULONG MOVI_Parse_MOVI_I_HDR();
xaULONG MOVI_Parse_MOVI_A_HDR();
xaULONG MOVI_Read_Index2();
xaULONG MOVI_Read_Index3();
void MOVI_Add_Video_Frames();
void MOVI_Add_Audio_Frames();
xaULONG MOVI_Get_Color();
extern void CMAP_Cache_Init();
extern void CMAP_Cache_Clear();
extern void JPG_Setup_Samp_Limit_Table();
/* CODEC ROUTINES */
xaULONG MOVI_Decode_MVC1();
extern xaULONG JFIF_Decode_JPEG();
extern xaULONG FLI_Decode_BLACK();
extern void XA_Gen_YUV_Tabs();
extern JPG_Alloc_MCU_Bufs();
extern jpg_search_marker();
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();
void XA_Free_Anim_Setup();
extern xaLONG xa_dither_flag;
extern xaUBYTE *xa_byte_limit;
static xaULONG movi_audio_attempt;
static xaULONG movi_audio_type;
static xaULONG movi_audio_freq;
static xaULONG movi_audio_chans;
static xaULONG movi_audio_bps;
xaULONG XA_Add_Sound();
#define MOVI_ICOMP_UNK 0
#define MOVI_ICOMP_MVC1 1
#define MOVI_ICOMP_MVC2 2
#define MOVI_ICOMP_JPEG 10
#define MOVI_ACOMP_UNK 0
#define MOVI_ACOMP_100 100
#define MOVI_ACOMP_401 401
#define MOVI_ACOMP_402 402
static xaULONG movi_frame_cnt;
static MOVI_FRAME *movi_frame_start,*movi_frame_cur;
MOVI_FRAME *MOVI_Add_Frame(time,timelo,act)
xaULONG time,timelo;
XA_ACTION *act;
{
MOVI_FRAME *fframe;
fframe = (MOVI_FRAME *) malloc(sizeof(MOVI_FRAME));
if (fframe == 0) TheEnd1("MOVI_Add_Frame: malloc err");
fframe->time = time;
fframe->timelo = timelo;
fframe->act = act;
fframe->next = 0;
if (movi_frame_start == 0) movi_frame_start = fframe;
else movi_frame_cur->next = fframe;
movi_frame_cur = fframe;
movi_frame_cnt++;
return(fframe);
}
void MOVI_Free_Frame_List(fframes)
MOVI_FRAME *fframes;
{
MOVI_FRAME *ftmp;
while(fframes != 0)
{
ftmp = fframes;
fframes = fframes->next;
FREE(ftmp,0xA000);
}
}
xaULONG MOVI_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 *movi;
MOVI_HDR movi_hdr;
movi = XA_Get_Anim_Setup();
movi->vid_time = XA_GET_TIME( 100 ); /* default */
movi->compression = MOVI_ICOMP_UNK;
movi_frame_cnt = 0;
movi_frame_start = 0;
movi_frame_cur = 0;
movi_audio_attempt = audio_attempt;
movi_hdr.version = 0;
movi_hdr.a_hdr = 0;
movi_hdr.i_hdr = 0;
if (MOVI_Read_Header(xin,anim_hdr,movi,&movi_hdr) == xaFALSE)
{ xin->Close_File(xin);
return(xaFALSE);
}
if (movi_hdr.version == 3)
{ if (MOVI_Read_Index3(xin,anim_hdr,movi,&movi_hdr)==xaFALSE)
return(xaFALSE);
}
else if (movi_hdr.version == 2)
{ if (MOVI_Read_Index2(xin,anim_hdr,movi,&movi_hdr)==xaFALSE)
return(xaFALSE);
}
else
{ xin->Close_File(xin);
return(xaFALSE);
}
movi->cmap_frame_num = movi_hdr.i_hdr->frames / cmap_sample_cnt;
MOVI_Add_Video_Frames(xin,anim_hdr,movi,&movi_hdr);
MOVI_Add_Audio_Frames(xin,anim_hdr,movi,&movi_hdr);
xin->Close_File(xin);
if (movi_hdr.a_hdr)
{ if (movi_hdr.a_hdr->off)
{ free(movi_hdr.a_hdr->off);
free(movi_hdr.a_hdr->size);
}
free(movi_hdr.a_hdr); movi_hdr.a_hdr = 0;
}
if (movi_hdr.i_hdr)
{ if (movi_hdr.i_hdr->off)
{ free(movi_hdr.i_hdr->off);
free(movi_hdr.i_hdr->size);
}
free(movi_hdr.i_hdr); movi_hdr.i_hdr = 0;
}
if (movi_frame_cnt == 0)
{
fprintf(stderr,"MOVI: No supported video frames exist in this file.\n");
return(xaFALSE);
}
anim_hdr->frame_lst = (XA_FRAME *)
malloc( sizeof(XA_FRAME) * (movi_frame_cnt+1));
if (anim_hdr->frame_lst == NULL) TheEnd1("MOVI_Read_File: frame malloc err");
movi_frame_cur = movi_frame_start;
i = 0;
t_time = 0;
t_timelo = 0;
while(movi_frame_cur != 0)
{
if (i > movi_frame_cnt)
{
fprintf(stderr,"MOVI_Read_Anim: frame inconsistency %d %d\n",
i,movi_frame_cnt);
break;
}
anim_hdr->frame_lst[i].time_dur = movi_frame_cur->time;
anim_hdr->frame_lst[i].zztime = t_time;
t_time += movi_frame_cur->time;
t_timelo += movi_frame_cur->timelo;
while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
anim_hdr->frame_lst[i].act = movi_frame_cur->act;
movi_frame_cur = movi_frame_cur->next;
i++;
}
anim_hdr->imagex = movi->imagex;
anim_hdr->imagey = movi->imagey;
anim_hdr->imagec = movi->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 = movi->max_fvid_size;
anim_hdr->max_faud_size = movi->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;
}
MOVI_Free_Frame_List(movi_frame_start);
XA_Free_Anim_Setup(movi);
/* POD TBD Free movi_hdr */
return(xaTRUE);
} /* end of read file */
/********************
*
*********************/
float MOVI_Read_Float(xin,size)
XA_INPUT *xin;
xaULONG size;
{ float fret = 0.0;
float scale = 0.1;
/** integer part */
while(size--)
{ xaULONG dat = xin->Read_U8(xin);
DEBUG_LEVEL1 fprintf(stderr,"<%x>",dat);
if ( (dat >= 0x30) && (dat <= 0x39))
fret = (10.0 * fret) + (float)(dat - 0x30);
else if (dat <= 0) return(fret);
else break;
}
/** fractional part */
DEBUG_LEVEL1 fprintf(stderr,"<.>");
while(size--)
{ xaULONG dat = xin->Read_U8(xin);
DEBUG_LEVEL1 fprintf(stderr,"<%x>",dat);
if ( (dat >= 0x30) && (dat <= 0x39))
{
fret += scale * (float)(dat - 0x30);
scale /= 10.0;
}
else break;
}
DEBUG_LEVEL1 fprintf(stderr,"size %x\n",size);
return(fret);
}
/********************
*
*********************/
xaULONG MOVI_Read_Int(xin,size)
XA_INPUT *xin;
xaULONG size;
{ xaULONG ret = 0;
while(size--)
{ xaULONG dat = xin->Read_U8(xin);
if ( (dat >= 0x30) && (dat <= 0x39)) ret = (10 * ret) + (dat - 0x30);
else break;
}
return(ret);
}
/********************
*
*********************/
xaULONG MOVI_Read_I_Compression(xin,size)
XA_INPUT *xin;
xaULONG size;
{ xaULONG ret = 0;
if (size >= 256)
{ fprintf(stderr,"MOVI: string to long %d\n",size);
while(size--) (void)(xin->Read_U8(xin));
}
else
{ char tbuf[256]; char *p = tbuf;
while(size--) *p++ = (char)(xin->Read_U8(xin) & 0xff);
if (strcmp(tbuf,"1") == 0) ret = MOVI_ICOMP_MVC1;
else if (strcmp(tbuf,"10") == 0) ret = MOVI_ICOMP_JPEG;
else if (strcmp(tbuf,"MVC2") == 0) ret = MOVI_ICOMP_MVC2;
else
{ fprintf(stderr," MOVI: unknown video codec (%s)\n",tbuf);
ret = MOVI_ICOMP_UNK;
}
}
return(ret);
}
/********************
*
*********************/
xaULONG MOVI_Read_A_Compression(xin,size)
XA_INPUT *xin;
xaULONG size;
{ xaULONG ret = 0;
if (size >= 256)
{ fprintf(stderr,"MOVI: string to long %d\n",size);
while(size--) (void)(xin->Read_U8(xin));
}
else
{ char tbuf[256]; char *p = tbuf;
while(size--) *p++ = (char)(xin->Read_U8(xin) & 0xff);
if (strcmp(tbuf,"100") == 0) ret = MOVI_ACOMP_100;
else if (strcmp(tbuf,"401") == 0) ret = MOVI_ACOMP_401;
else if (strcmp(tbuf,"402") == 0) ret = MOVI_ACOMP_402;
else
{ fprintf(stderr," MOVI: unknown audio codec (%s)\n",tbuf);
ret = MOVI_ACOMP_UNK;
}
}
return(ret);
}
/********************
*
*********************/
xaULONG MOVI_Parse_MOVI_HDR(xin,movi_hdr,buf,size)
XA_INPUT *xin;
MOVI_HDR *movi_hdr;
char *buf;
xaULONG size;
{
if (strcmp(buf,"__NUM_I_TRACKS") == 0)
movi_hdr->i_tracks = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"__NUM_A_TRACKS") == 0)
movi_hdr->a_tracks = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"LOOP_MODE") == 0)
movi_hdr->loop_mode = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"NUM_LOOPS") == 0)
movi_hdr->num_loops = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"OPTIMIZED") == 0)
movi_hdr->optimized = MOVI_Read_Int(xin,size);
else /* unknown */
{
fprintf(stderr,"MOVI: unknown HDR var %s with size %d\n",buf,size);
while(size--) (void)xin->Read_U8(xin);
}
return(xaTRUE);
}
/********************
*
*********************/
xaULONG MOVI_Parse_MOVI_A_HDR(xin,a_hdr,buf,size)
XA_INPUT *xin;
MOVI_A_HDR *a_hdr;
char *buf;
xaULONG size;
{
if (strcmp(buf,"__DIR_COUNT") == 0)
a_hdr->frames = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"SAMPLE_WIDTH") == 0)
a_hdr->width = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"NUM_CHANNELS") == 0)
a_hdr->chans = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"AUDIO_FORMAT") == 0)
a_hdr->format = MOVI_Read_A_Compression(xin,size);
else if (strcmp(buf,"SAMPLE_RATE") == 0)
a_hdr->rate = MOVI_Read_Float(xin,size);
else if (strcmp(buf,"COMPRESSION") == 0)
a_hdr->compression = MOVI_Read_A_Compression(xin,size);
else /* unknown */
{
fprintf(stderr,"MOVI: unknown A_HDR var %s with size %d\n",buf,size);
while(size--) (void)xin->Read_U8(xin);
}
return(xaTRUE);
}
/********************
*
*********************/
xaULONG MOVI_Parse_MOVI_I_HDR(xin,i_hdr,buf,size)
XA_INPUT *xin;
MOVI_I_HDR *i_hdr;
char *buf;
xaULONG size;
{
if (strcmp(buf,"__DIR_COUNT") == 0)
i_hdr->frames = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"WIDTH") == 0)
i_hdr->width = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"HEIGHT") == 0)
i_hdr->height = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"COMPRESSION") == 0)
i_hdr->compression = MOVI_Read_I_Compression(xin,size);
else if (strcmp(buf,"INTERLACING") == 0)
i_hdr->interlacing = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"PACKING") == 0)
i_hdr->packing = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"ORIENTATION") == 0)
i_hdr->orientation = MOVI_Read_Int(xin,size);
else if (strcmp(buf,"PIXEL_ASPECT") == 0)
i_hdr->pixel_aspect = MOVI_Read_Float(xin,size);
else if (strcmp(buf,"FPS") == 0)
i_hdr->fps = MOVI_Read_Float(xin,size);
else if (strcmp(buf,"Q_SPATIAL") == 0)
i_hdr->q_spatial = MOVI_Read_Float(xin,size);
else if (strcmp(buf,"Q_TEMPORAL") == 0)
i_hdr->q_temporal = MOVI_Read_Float(xin,size);
else /* unknown */
{
fprintf(stderr,"MOVI: unknown I HDR var %s with size %d\n",buf,size);
while(size--) (void)xin->Read_U8(xin);
}
return(xaTRUE);
}
xaULONG MOVI_Read_Header(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ xaULONG t,version;
t = xin->Read_MSB_U32(xin); /* skip MOVI */
/* Really have no clue about this, BUT some have
*
* MOVI 0000_00003 0000_0000 => MOVI_Read_Header3
*
* MOVI 0002_width hite_0000 => MOVI_Read_Header2
*/
version = xin->Read_MSB_U16(xin);
if (version == 0)
{ version = xin->Read_MSB_U16(xin);
if (version == 3)
{ movi_hdr->version = 3;
t = xin->Read_MSB_U32(xin); /* unknown */
return( MOVI_Read_Header3(xin,anim_hdr,movi,movi_hdr) );
}
}
else if (version == 2)
{ movi_hdr->version = 2;
t = xin->Read_MSB_U16(xin); /* width */
t = xin->Read_MSB_U16(xin); /* height */
t = xin->Read_MSB_U16(xin); /* unknown */
return( MOVI_Read_Header2(xin,anim_hdr,movi,movi_hdr) );
}
/* fall through cases */
fprintf(stderr,"MOVI: Unknown format variation\n");
return(xaFALSE);
}
xaULONG MOVI_Read_Header3(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ xaULONG t,size;
xaULONG vars;
char buf[16];
/*** MOVI Header Group ***/
movi_hdr->i_tracks = 0;
movi_hdr->a_tracks = 0;
movi_hdr->loop_mode = 0;
movi_hdr->num_loops = 0;
movi_hdr->optimized = 0;
movi_hdr->a_hdr = 0;
movi_hdr->i_hdr = 0;
t = xin->Read_MSB_U32(xin); /* unk */
vars = xin->Read_MSB_U32(xin); /* num of variables */
t = xin->Read_MSB_U32(xin); /* unk */
while(vars--)
{ int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
size = xin->Read_MSB_U32(xin); /* size */
DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
if (MOVI_Parse_MOVI_HDR(xin,movi_hdr,buf,size)==xaFALSE) return(xaFALSE);
}
/*** MOVI Audio Header Group ***/
if (movi_hdr->a_tracks > 1)
{ fprintf(stderr,"MOVI: multiple audio tracks not yet tolerated\n");
return(xaFALSE);
}
if (movi_hdr->a_tracks == 1) /* assume audio is optional */
{ MOVI_A_HDR *a_hdr = (MOVI_A_HDR *)malloc(sizeof(MOVI_A_HDR));
if (a_hdr == 0) TheEnd1("MOVI: a_hdr malloc err");
/* POD TBD - free up MOVI_A_HDR and MOVI_I_HDR at end of read */
movi_hdr->a_hdr = a_hdr;
a_hdr->frames = 0;
a_hdr->width = 0;
a_hdr->chans = 0;
a_hdr->format = 0;
a_hdr->rate = 0.0;
a_hdr->compression = 0;
t = xin->Read_MSB_U32(xin); /* unk */
vars = xin->Read_MSB_U32(xin); /* num of variables */
t = xin->Read_MSB_U32(xin); /* unk */
while(vars--)
{ int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
size = xin->Read_MSB_U32(xin); /* size */
DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
if (MOVI_Parse_MOVI_A_HDR(xin,a_hdr,buf,size)==xaFALSE) return(xaFALSE);
}
if (xa_verbose)
{
fprintf(stdout,
" Audio: freq %5.1f chans %d bps %d form %d comp %d\n",
a_hdr->rate, a_hdr->chans, a_hdr->width, a_hdr->format,
a_hdr->compression);
}
/* POD check for 0 frames?? */
if (a_hdr->frames == 0) TheEnd1("MOVI: Audio err");
a_hdr->off = (xaULONG *)malloc( a_hdr->frames * sizeof(xaULONG) );
a_hdr->size = (xaULONG *)malloc( a_hdr->frames * sizeof(xaULONG) );
movi_audio_freq = (xaULONG)a_hdr->rate;
movi_audio_chans = a_hdr->chans;
movi_audio_bps = a_hdr->width;
movi_audio_type = XA_AUDIO_INVALID;
if ( (a_hdr->compression == MOVI_ACOMP_100)
&& (a_hdr->format == MOVI_ACOMP_401))
{
movi_audio_type = XA_AUDIO_SIGNED;
}
else if ( (a_hdr->compression == MOVI_ACOMP_100)
&& (a_hdr->format == MOVI_ACOMP_402))
{
movi_audio_type = XA_AUDIO_LINEAR;
}
if ( (movi_audio_bps > 2) || (movi_audio_bps == 0) )
movi_audio_type = XA_AUDIO_INVALID;
if (movi_audio_chans == 2) movi_audio_type |= XA_AUDIO_STEREO_MSK;
if (movi_audio_bps == 2)
{
movi_audio_type |= XA_AUDIO_BPS_2_MSK;
movi_audio_type |= XA_AUDIO_BIGEND_MSK;
}
if (movi_audio_type == XA_AUDIO_INVALID)
{
if (movi_audio_attempt == xaTRUE)
fprintf(stderr,"MOVI: Audio Type unsupported %d \n",
a_hdr->compression);
movi_audio_attempt = xaFALSE;
}
} /* end audio group */
/*** MOVI Video Header Group ***/
if (movi_hdr->i_tracks > 1)
{ fprintf(stderr,"MOVI: multiple video tracks not yet tolerated\n");
return(xaFALSE);
}
if (movi_hdr->i_tracks == 1)
{ MOVI_I_HDR *i_hdr = (MOVI_I_HDR *)malloc(sizeof(MOVI_I_HDR));
if (i_hdr == 0) TheEnd1("MOVI: i_hdr malloc err");
movi_hdr->i_hdr = i_hdr;
i_hdr->frames = 0;
i_hdr->width = 0;
i_hdr->height = 0;
i_hdr->compression = 0;
i_hdr->interlacing = 0;
i_hdr->packing = 0;
i_hdr->orientation = 0;
i_hdr->pixel_aspect = 0.0;
i_hdr->fps = 0.0;
i_hdr->q_spatial = 0.0;
i_hdr->q_temporal = 0.0;
t = xin->Read_MSB_U32(xin); /* unk */
vars = xin->Read_MSB_U32(xin); /* num of variables */
t = xin->Read_MSB_U32(xin); /* unk */
while(vars--)
{ int i; for(i=0;i<16;i++) buf[i] = xin->Read_U8(xin);
size = xin->Read_MSB_U32(xin); /* size */
DEBUG_LEVEL1 fprintf(stderr," MOVI: size %x buf %s\n",size,buf);
if (MOVI_Parse_MOVI_I_HDR(xin,i_hdr,buf,size)==xaFALSE) return(xaFALSE);
}
if (xa_verbose)
{
fprintf(stdout, " Video: %dx%d codec ", i_hdr->width, i_hdr->height);
switch(i_hdr->compression)
{ case MOVI_ICOMP_MVC1: fprintf(stdout,"MVC1"); break;
case MOVI_ICOMP_MVC2: fprintf(stdout,"MVC2"); break;
case MOVI_ICOMP_JPEG: fprintf(stdout,"JPEG"); break;
default: fprintf(stdout,"unk(%d)",i_hdr->compression);
}
fprintf(stdout," frames %d fps %3.2f\n",i_hdr->frames,i_hdr->fps);
}
/* POD check for 0 frames?? */
if (i_hdr->frames == 0) TheEnd1("MOVI: Video err");
i_hdr->off = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
i_hdr->size = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
UTIL_FPS_2_Time(movi, ((double)(i_hdr->fps)) );
switch(i_hdr->compression)
{
case MOVI_ICOMP_JPEG:
movi->compression = MOVI_ICOMP_JPEG;
movi->depth = 24;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
movi->imagex = 4 * ((movi->imagex + 3)/4);
movi->imagey = 4 * ((movi->imagey + 3)/4);
XA_Gen_YUV_Tabs(anim_hdr);
JPG_Alloc_MCU_Bufs(anim_hdr,movi->imagex,0,xaFALSE);
JPG_Setup_Samp_Limit_Table(anim_hdr);
break;
case MOVI_ICOMP_MVC1:
movi->compression = MOVI_ICOMP_MVC1;
movi->depth = 16;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
movi->imagex = 4 * ((movi->imagex + 3)/4);
movi->imagey = 4 * ((movi->imagey + 3)/4);
JPG_Setup_Samp_Limit_Table(anim_hdr);
break;
case MOVI_ICOMP_MVC2:
movi->compression = MOVI_ICOMP_UNK;
movi->depth = 8;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
fprintf(stderr," MOVI: Video Codec MVC2 not supported\n");
return(xaFALSE);
break;
default:
movi->compression = MOVI_ICOMP_UNK;
movi->depth = 8;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
fprintf(stderr," MOVI: Unknown Video Codec not supported\n");
return(xaFALSE);
break;
}
/* POD temp kludge for unknown movies */
/* Debug and testing only
*/
if (movi->compression == MOVI_ICOMP_UNK)
{
movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
}
else
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)
movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
else movi->chdr = CMAP_Create_Gray(movi->cmap,&movi->imagec);
}
if ( (movi->pic==0) && (xin->load_flag & XA_IN_LOAD_BUF))
{
movi->pic_size = movi->imagex * movi->imagey;
if ( (cmap_true_map_flag == xaTRUE) && (movi->depth > 8) )
movi->pic = (xaUBYTE *) malloc( 3 * movi->pic_size );
else movi->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(movi->pic_size) );
if (movi->pic == 0) TheEnd1("MOVI_Buffer_Action: malloc failed");
}
}
return(xaTRUE);
}
xaULONG MOVI_Read_Header2(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ xaULONG t;
/*** MOVI Header Group ***/
movi_hdr->i_tracks = 0;
movi_hdr->a_tracks = 0;
movi_hdr->loop_mode = 0;
movi_hdr->num_loops = 0;
movi_hdr->optimized = 0;
movi_hdr->a_hdr = 0;
movi_hdr->i_hdr = 0;
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 402e_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0002_0001 */
{ MOVI_I_HDR *i_hdr = (MOVI_I_HDR *)malloc(sizeof(MOVI_I_HDR));
if (i_hdr == 0) TheEnd1("MOVI: i_hdr malloc err");
movi_hdr->i_hdr = i_hdr;
i_hdr->frames = 0;
i_hdr->width = 0;
i_hdr->height = 0;
i_hdr->compression = 0;
i_hdr->interlacing = 0;
i_hdr->packing = 0;
i_hdr->orientation = 0;
i_hdr->pixel_aspect = 0.0;
i_hdr->fps = 0.0;
i_hdr->q_spatial = 0.0;
i_hdr->q_temporal = 0.0;
i_hdr->frames = xin->Read_MSB_U32(xin);
i_hdr->compression = xin->Read_MSB_U32(xin); /* ??? */
i_hdr->width = xin->Read_MSB_U32(xin);
i_hdr->height = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk 0000_0004 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0002 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0001 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = xin->Read_MSB_U32(xin); /* unk 0000_0000 */
t = 0x80; while(t--) (void)xin->Read_U8(xin); /* video title */
t = 0x80; while(t--) (void)xin->Read_U8(xin); /* audio title */
t = 0x80; while(t--) (void)xin->Read_U8(xin); /* unknown */
t = 0x80; while(t--) (void)xin->Read_U8(xin); /* unknown */
i_hdr->fps = 15.0; /* POD: TBD just a guess */
if (xa_verbose)
{
fprintf(stdout,
" Video: %dx%d comp %d fps %3.2f\n",
i_hdr->width, i_hdr->height, i_hdr->compression, i_hdr->fps);
}
/*POD TBD free up i_hdr off and size arrays same for a_hdr */
/* POD check for 0 frames?? */
if (i_hdr->frames == 0) TheEnd1("MOVI: Video err");
i_hdr->off = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
i_hdr->size = (xaULONG *)malloc( i_hdr->frames * sizeof(xaULONG) );
UTIL_FPS_2_Time(movi, ((double)(i_hdr->fps)) );
switch(i_hdr->compression)
{
case 1:
movi->compression = MOVI_ICOMP_MVC1;
movi->depth = 16;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
movi->imagex = 4 * ((movi->imagex + 3)/4);
movi->imagey = 4 * ((movi->imagey + 3)/4);
break;
default:
movi->compression = MOVI_ICOMP_UNK;
movi->depth = 8;
movi->imagex = i_hdr->width;
movi->imagey = i_hdr->height;
break;
}
/* POD this part can be shared with Header3 somehow */
/* POD temp kludge for unknown movies */
if (movi->compression == MOVI_ICOMP_UNK)
{
movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
}
else 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)
movi->chdr = CMAP_Create_332(movi->cmap,&movi->imagec);
else movi->chdr = CMAP_Create_Gray(movi->cmap,&movi->imagec);
}
if ( (movi->pic==0) && (xin->load_flag & XA_IN_LOAD_BUF))
{
movi->pic_size = movi->imagex * movi->imagey;
if ( (cmap_true_map_flag == xaTRUE) && (movi->depth > 8) )
movi->pic = (xaUBYTE *) malloc( 3 * movi->pic_size );
else movi->pic = (xaUBYTE *) malloc( XA_PIC_SIZE(movi->pic_size) );
if (movi->pic == 0) TheEnd1("MOVI_Buffer_Action: malloc failed");
}
}
return(xaTRUE);
}
xaULONG MOVI_Read_Index3(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ xaLONG i,t;
if (movi_hdr->a_hdr) /* do audio 1st */
{ MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
for(i=0; i< a_hdr->frames; i++)
{
a_hdr->off[i] = xin->Read_MSB_U32(xin);
a_hdr->size[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
t = xin->Read_MSB_U32(xin); /* unk */
DEBUG_LEVEL1 fprintf(stderr,"A: %x %x\n",a_hdr->off[i], a_hdr->size[i]);
}
}
if (movi_hdr->i_hdr)
{ MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
for(i=0; i< i_hdr->frames; i++)
{
i_hdr->off[i] = xin->Read_MSB_U32(xin);
i_hdr->size[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
t = xin->Read_MSB_U32(xin); /* unk */
DEBUG_LEVEL1 fprintf(stderr,"I: %x %x\n",i_hdr->off[i], i_hdr->size[i]);
}
}
return(xaTRUE);
}
xaULONG MOVI_Read_Index2(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ xaLONG i,t;
if (movi_hdr->a_hdr) /* do audio 1st */
{ MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
for(i=0; i< a_hdr->frames; i++)
{ a_hdr->off[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
a_hdr->size[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
t = xin->Read_MSB_U32(xin); /* unk */
DEBUG_LEVEL1 fprintf(stderr,"A: %x %x\n",
a_hdr->off[i], a_hdr->size[i]);
}
}
if (movi_hdr->i_hdr)
{ MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
for(i=0; i< i_hdr->frames; i++)
{ i_hdr->off[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
i_hdr->size[i] = xin->Read_MSB_U32(xin);
t = xin->Read_MSB_U32(xin); /* unk */
t = xin->Read_MSB_U32(xin); /* unk */
DEBUG_LEVEL1 fprintf(stderr,"I: %x %x\n",
i_hdr->off[i], i_hdr->size[i]);
}
}
return(xaTRUE);
}
void MOVI_Add_Video_Frames(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ MOVI_I_HDR *i_hdr = movi_hdr->i_hdr;
int i;
if (i_hdr == 0) return;
for(i = 0; i < i_hdr->frames; i++)
{ xaULONG dlta_len;
XA_ACTION *act;
ACT_DLTA_HDR *dlta_hdr;
dlta_len = i_hdr->size[i];
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("MOVI: dlta malloc err");
act->data = (xaUBYTE *)dlta_hdr;
dlta_hdr->flags = ACT_SNGL_BUF;
dlta_hdr->fsize = dlta_len;
dlta_hdr->fpos = i_hdr->off[i];
if (dlta_len > movi->max_fvid_size) movi->max_fvid_size = dlta_len;
}
else
{ xaULONG d; xaLONG ret;
d = dlta_len + (sizeof(ACT_DLTA_HDR));
dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
if (dlta_hdr == 0) TheEnd1("MOVI: 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->Seek_FPos(xin, i_hdr->off[i], 0);
ret = xin->Read_Block(xin,dlta_hdr->data,dlta_len);
if (ret < dlta_len) { fprintf(stderr,"MOVI: read err\n"); return; }
}
MOVI_Add_Frame(movi->vid_time,movi->vid_timelo,act);
dlta_hdr->xpos = dlta_hdr->ypos = 0;
dlta_hdr->xsize = movi->imagex;
dlta_hdr->ysize = movi->imagey;
switch(movi->compression)
{ case MOVI_ICOMP_JPEG:
dlta_hdr->special = 0;
dlta_hdr->extra = (void *)(0x0);
dlta_hdr->xapi_rev = 0x0001;
dlta_hdr->delta = JFIF_Decode_JPEG;
break;
case MOVI_ICOMP_MVC1:
dlta_hdr->special = 0;
dlta_hdr->extra = (void *)(0x0);
dlta_hdr->xapi_rev = 0x0001;
dlta_hdr->delta = MOVI_Decode_MVC1;
break;
default:
dlta_hdr->special = 0;
dlta_hdr->extra = (void *)(0x0);
dlta_hdr->xapi_rev = 0x0001;
dlta_hdr->delta = FLI_Decode_BLACK;
break;
}
ACT_Setup_Delta(movi,act,dlta_hdr,xin);
} /* end of i thru frames */
}
/***********
*
***********/
void MOVI_Add_Audio_Frames(xin,anim_hdr,movi,movi_hdr)
XA_INPUT *xin;
XA_ANIM_HDR *anim_hdr;
XA_ANIM_SETUP *movi;
MOVI_HDR *movi_hdr;
{ MOVI_A_HDR *a_hdr = movi_hdr->a_hdr;
int i;
if (a_hdr == 0) return;
for(i = 0; i < a_hdr->frames; i++)
{ xaULONG snd_size = a_hdr->size[i];
if (movi_audio_attempt==xaTRUE)
{ xaLONG ret;
if (xin->load_flag & XA_IN_LOAD_FILE)
{ xaLONG rets;
rets = XA_Add_Sound(anim_hdr,0,movi_audio_type, a_hdr->off[i],
movi_audio_freq, snd_size,
&movi->aud_time,&movi->aud_timelo, 0, 0);
if (rets==xaFALSE) movi_audio_attempt = xaFALSE;
if (snd_size > movi->max_faud_size) movi->max_faud_size = snd_size;
}
else
{ xaUBYTE *snd = (xaUBYTE *)malloc(snd_size);
if (snd==0) TheEnd1("MOVI: snd malloc err");
ret = xin->Seek_FPos( xin, a_hdr->off[i], 0);
ret = xin->Read_Block(xin, snd, snd_size);
if (ret < snd_size) fprintf(stderr,"MOVI: snd rd err\n");
else
{ int rets;
rets = XA_Add_Sound(anim_hdr,snd,movi_audio_type, -1,
movi_audio_freq, snd_size,
&movi->aud_time, &movi->aud_timelo, 0, 0);
if (rets==xaFALSE) movi_audio_attempt = xaFALSE;
}
}
}
} /* end of i thru chunks */
}
#define MOVI_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y += 4; } }
#define MOVI_GET_16(data,dptr) {data = *dptr++ << 8; data |= *dptr++; }
#define MVC1_COLOR2(dp,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,CAST) \
{ c0 = c2 = c4 = c6 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; \
c1 = c3 = c5 = c7 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); }
#define MVC1_COLOR8(dp,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,CAST) \
{ c0 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c1 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c2 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c3 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c4 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c5 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c6 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); \
p0 = *dp++ << 8; p0 |= *dp++; c7 = (CAST)MOVI_Get_Color(p0,mflag,map,chdr); }
#define MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7) { \
*ip++ = (mask & 0x0001)?(c0):(c1); \
*ip++ = (mask & 0x0002)?(c0):(c1); \
*ip++ = (mask & 0x0004)?(c2):(c3); \
*ip = (mask & 0x0008)?(c2):(c3); ip += row_inc; \
*ip++ = (mask & 0x0010)?(c0):(c1); \
*ip++ = (mask & 0x0020)?(c0):(c1); \
*ip++ = (mask & 0x0040)?(c2):(c3); \
*ip = (mask & 0x0080)?(c2):(c3); ip += row_inc; \
*ip++ = (mask & 0x0100)?(c4):(c5); \
*ip++ = (mask & 0x0200)?(c4):(c5); \
*ip++ = (mask & 0x0400)?(c6):(c7); \
*ip = (mask & 0x0800)?(c6):(c7); ip += row_inc; \
*ip++ = (mask & 0x1000)?(c4):(c5); \
*ip++ = (mask & 0x2000)?(c4):(c5); \
*ip++ = (mask & 0x4000)?(c6):(c7); \
*ip = (mask & 0x8000)?(c6):(c7); }
#define MVC1_PIX_2_RGB(pix,r,g,b) { xaULONG ra,ga,ba; \
ra = (pix>>10) & 0x1f; ga = (pix>>5) & 0x1f; ba = pix & 0x1f; \
r = (ra << 3) | (ra >> 2); g = (ga << 3) | (ga >> 2); \
b = (ba << 3) | (ba >> 2); }
#define MVC1_RGB2(dp,p0,r,g,b) \
{ MVC1_PIX_2_RGB(p0,r[0],g[0],b[0]); r[2] = r[4] = r[6] = r[0]; \
g[2] = g[4] = g[6] = g[0]; b[2] = b[4] = b[6] = b[0]; \
p0 = *dp++ << 8; p0 |= *dp++; \
MVC1_PIX_2_RGB(p0,r[1],g[1],b[1]); r[3] = r[5] = r[7] = r[1]; \
g[3] = g[5] = g[7] = g[1]; b[3] = b[5] = b[7] = b[1]; }
#define MVC1_RGB8(dp,p0,r,g,b) \
{ MVC1_PIX_2_RGB(p0,r[0],g[0],b[0]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[1],g[1],b[1]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[2],g[2],b[2]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[3],g[3],b[3]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[4],g[4],b[4]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[5],g[5],b[5]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[6],g[6],b[6]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_RGB(p0,r[7],g[7],b[7]); }
#define MVC1_RGB_BLK8(ip,m,r,g,b) { register xaULONG ix; \
ix = (m & 0x0001)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0002)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0004)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0008)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip = b[ix]; \
ip += row_inc; \
ix = (m & 0x0010)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0020)?(0):(1); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0040)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0080)?(2):(3); *ip++ = r[ix]; *ip++ = g[ix]; *ip = b[ix]; \
ip += row_inc; \
ix = (m & 0x0100)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0200)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0400)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x0800)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip = b[ix]; \
ip += row_inc; \
ix = (m & 0x1000)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x2000)?(4):(5); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x4000)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip++ = b[ix]; \
ix = (m & 0x8000)?(6):(7); *ip++ = r[ix]; *ip++ = g[ix]; *ip = b[ix]; }
#define MVC1_PIX_2_DITH(pix,_r,_g,_b) { \
_r = (pix & 0x7c00); _g = (pix & 0x03e0); _b = (pix & 0x001f); \
_r = _r | (_r >> 5); _g = (_g << 5) | _g; _b = (_b << 10) | (_b << 5); }
#define MVC1_DITH2(dp,p0,r,g,b) \
{ MVC1_PIX_2_DITH(p0,r[0],g[0],b[0]); r[2] = r[4] = r[6] = r[0]; \
g[2] = g[4] = g[6] = g[0]; b[2] = b[4] = b[6] = b[0]; \
p0 = *dp++ << 8; p0 |= *dp++; \
MVC1_PIX_2_DITH(p0,r[1],g[1],b[1]); r[3] = r[5] = r[7] = r[1]; \
g[3] = g[5] = g[7] = g[1]; b[3] = b[5] = b[7] = b[1]; }
#define MVC1_DITH8(dp,p0,r,g,b) \
{ MVC1_PIX_2_DITH(p0,r[0],g[0],b[0]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[1],g[1],b[1]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[2],g[2],b[2]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[3],g[3],b[3]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[4],g[4],b[4]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[5],g[5],b[5]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[6],g[6],b[6]); \
p0 = *dp++ << 8; p0 |= *dp++; MVC1_PIX_2_DITH(p0,r[7],g[7],b[7]); }
#define MVC1_DITH_GET_RGB(r,g,b,re,ge,be,col) { xaLONG r1,g1,b1; \
r1 = (xaLONG)rnglimit[(r + re) >> 7]; \
g1 = (xaLONG)rnglimit[(g + ge) >> 7]; \
b1 = (xaLONG)rnglimit[(b + be) >> 7]; \
col = (r1 & 0xe0) | ((g1 & 0xe0) >> 3) | ((b1 & 0xc0) >> 6); }
#define MVC1_DITH_GET_ERR(r,g,b,re,ge,be,col,cmap) { \
re = ((xaLONG)(r) - (xaLONG)(cmap[col].red >> 1)) >> 1; \
ge = ((xaLONG)(g) - (xaLONG)(cmap[col].green >> 1)) >> 1; \
be = ((xaLONG)(b) - (xaLONG)(cmap[col].blue >> 1)) >> 1; }
xaULONG MOVI_Decode_MVC1(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 mflag = dec_info->map_flag; xaULONG *map = dec_info->map;
xaULONG special = dec_info->special;
XA_CHDR *chdr = dec_info->chdr;
xaULONG row_inc;
xaLONG x = 0, y = 0;
xaUBYTE *dptr = delta;
xaULONG dither = 0;
dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
/* POD rethink this */
if ((cmap_color_func == 4) && (chdr))
{ if (cmap_cache == 0) CMAP_Cache_Init(0);
if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; }
}
if ( (!special) && (x11_bytes_pixel==1)
&& (chdr) && (x11_display_type == XA_PSEUDOCOLOR)
&& (cmap_color_func != 4)
&& (cmap_true_to_332 == xaTRUE) && (x11_cmap_size == 256)
&& (xa_dither_flag==xaTRUE)
) dither = 1;
row_inc = (special)?((3*(imagex-4))+1):(imagex - 3);
if (special)
{ while( (dsize > 0) && (y < imagey))
{ xaUBYTE *ip = (xaUBYTE *)(image + 3 * (y * imagex + x) );
xaUBYTE r[8],g[8],b[8]; xaULONG mask,p0;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);
if (p0 & 0x8000) { MVC1_RGB8(dptr,p0,r,g,b); dsize -= 18; }
else { MVC1_RGB2(dptr,p0,r,g,b); dsize -= 6; }
MVC1_RGB_BLK8(ip,mask,r,g,b);
MOVI_BLOCK_INC(x,y,imagex);
}
}
else if (dither)
{ xaUBYTE *rnglimit = xa_byte_limit;
ColorReg *cmap = chdr->cmap;
while( (dsize > 0) && (y < imagey))
{ xaUBYTE *ip0 = (xaUBYTE *)(image + (y * imagex + x) );
xaULONG r[8],g[8],b[8]; xaULONG mask,p0;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr);
if (p0 & 0x8000) { MVC1_DITH8(dptr,p0,r,g,b); dsize -= 12; }
else { MVC1_DITH2(dptr,p0,r,g,b); dsize -= 6; }
{ xaUBYTE *ip1 = ip0, *ip2, *ip3;
xaLONG ix, ra, ga, ba, col, re = 0, ge = 0, be = 0;
ip1 += imagex; ip2 = ip1; ip2 += imagex; ip3 = ip2; ip3 += imagex;
/** 0 0 */
ix = (mask & 0x0001)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip0[0] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 0 1 */
ix = (mask & 0x0002)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip0[1] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 1 1 */
ix = (mask & 0x0020)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip1[1] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 1 0 */
ix = (mask & 0x0010)?(0):(1); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip1[0] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/** 2 0 */
ix = (mask & 0x0100)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip2[0] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 3 0 */
ix = (mask & 0x1000)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip3[0] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 3 1 */
ix = (mask & 0x2000)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip3[1] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 2 1 */
ix = (mask & 0x0200)?(4):(5); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip2[1] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/** 2 2 */
ix = (mask & 0x0400)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip2[2] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 3 2 */
ix = (mask & 0x4000)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip3[2] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 3 3 */
ix = (mask & 0x8000)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip3[3] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 2 3 */
ix = (mask & 0x0800)?(6):(7); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip2[3] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/** 1 3 */
ix = (mask & 0x0080)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip1[3] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 1 2 */
ix = (mask & 0x0040)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip1[2] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 0 2 */
ix = (mask & 0x0004)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip0[2] = (xaUBYTE)col;
MVC1_DITH_GET_ERR(ra,ga,ba,re,ge,be,col,cmap);
/* 0 3 */
ix = (mask & 0x0008)?(2):(3); ra = r[ix]; ga = g[ix]; ba = b[ix];
MVC1_DITH_GET_RGB(ra,ga,ba,re,ge,be,col);
if (mflag) col = map[col]; ip0[3] = (xaUBYTE)col;
}
MOVI_BLOCK_INC(x,y,imagex);
}
}
else if ((x11_bytes_pixel == 1) || (mflag == xaFALSE))
{ while( (dsize > 0) && (y < imagey))
{ xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
xaUBYTE c0,c1,c2,c3,c4,c5,c6,c7;
xaULONG mask,p0;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr); dsize -= 6;
if (p0 & 0x8000) { dsize -= 12;
MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE); }
else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE)
MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
MOVI_BLOCK_INC(x,y,imagex);
}
} /* end depth 8 */
else if (x11_bytes_pixel == 4)
{
while( (dsize > 0) && (y < imagey))
{ xaULONG *ip = (xaULONG *)(image + ((y * imagex + x)<<2) );
xaULONG c0,c1,c2,c3,c4,c5,c6,c7;
xaULONG mask,p0;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr); dsize -= 6;
if (p0 & 0x8000) { dsize -= 12;
MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaULONG); }
else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaULONG)
MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
MOVI_BLOCK_INC(x,y,imagex);
}
} /* end depth 24/32 */
else /* if (x11_bytes_pixel == 2) */
{ while( (dsize > 0) && (y < imagey))
{ xaUSHORT *ip = (xaUSHORT *)(image + ((y * imagex + x)<<1) );
xaUSHORT c0,c1,c2,c3,c4,c5,c6,c7;
xaULONG mask,p0; dsize -= 6;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr); dsize -= 6;
if (p0 & 0x8000) { dsize -= 12;
MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUSHORT); }
else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUSHORT)
MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
MOVI_BLOCK_INC(x,y,imagex);
}
} /* end depth 16 */
if (mflag) return(ACT_DLTA_MAPD);
else return(ACT_DLTA_NORM);
}
xaULONG MOVI_Decode_MVC2(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 mflag = dec_info->map_flag; xaULONG *map = dec_info->map;
xaULONG special = dec_info->special;
XA_CHDR *chdr = dec_info->chdr;
xaULONG row_inc;
xaLONG x = 0, y = 0;
xaUBYTE *dptr = delta;
xaULONG dither = 0;
dec_info->xs = dec_info->ys = 0; dec_info->xe = imagex; dec_info->ye = imagey;
if (dec_info->skip_flag > 0) return(ACT_DLTA_DROP);
if (chdr) { if (chdr->new_chdr) chdr = chdr->new_chdr; }
/* POD rethink this */
if ((cmap_color_func == 4) && (chdr))
{ if (cmap_cache == 0) CMAP_Cache_Init(0);
if (chdr != cmap_cache_chdr) { CMAP_Cache_Clear(); cmap_cache_chdr = chdr; }
}
if ( (!special) && (x11_bytes_pixel==1)
&& (chdr) && (x11_display_type == XA_PSEUDOCOLOR)
&& (cmap_color_func != 4)
&& (cmap_true_to_332 == xaTRUE) && (x11_cmap_size == 256)
&& (xa_dither_flag==xaTRUE)
) dither = 1;
row_inc = (special)?((3*(imagex-4))+1):(imagex - 3);
if (special)
{ fprintf(stderr,"NOT YET\n"); }
else if (dither)
{ fprintf(stderr,"NOT YET\n"); }
else if ((x11_bytes_pixel == 1) || (mflag == xaFALSE))
{ while( (dsize > 0) && (y < imagey))
{ xaUBYTE *ip = (xaUBYTE *)(image + (y * imagex + x) );
xaUBYTE c0,c1,c2,c3,c4,c5,c6,c7;
xaULONG mask,p0;
MOVI_GET_16(mask,dptr); MOVI_GET_16(p0,dptr); dsize -= 6;
if (p0 & 0x8000) { dsize -= 12;
MVC1_COLOR8(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE); }
else MVC1_COLOR2(dptr,p0,c0,c1,c2,c3,c4,c5,c6,c7,mflag,map,chdr,xaUBYTE)
MVC1_BLK8(ip,mask,c0,c1,c2,c3,c4,c5,c6,c7);
MOVI_BLOCK_INC(x,y,imagex);
}
}
else if (x11_bytes_pixel == 4)
{ fprintf(stderr,"NOT YET\n"); }
else /* if (x11_bytes_pixel == 2) */
{ fprintf(stderr,"NOT YET\n"); }
if (mflag) return(ACT_DLTA_MAPD);
else return(ACT_DLTA_NORM);
}
xaULONG MOVI_Get_Color(color,map_flag,map,chdr)
xaULONG color,map_flag,*map;
XA_CHDR *chdr;
{
register xaULONG 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==xaTRUE) { 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(tr,tg,tb,8);
else
{
if ((cmap_color_func == 4) && (chdr))
{ register xaULONG cache_i = color & 0x7fff;
if (cmap_cache[cache_i] == 0xffff)
{
clr = chdr->coff +
CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,5,5,5,xaTRUE);
cmap_cache[cache_i] = (xaUSHORT)clr;
}
else clr = (xaULONG)cmap_cache[cache_i];
}
else
{
if (cmap_true_to_332 == xaTRUE)
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);
}