reman3/Rayman_X/cpa/tempgrp/VDO/DecompressFunc.c

219 lines
7.0 KiB
C

/* ##C_FILE#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FILE : DecompressFunc.h
DESCRIPTION : Implementation file of module of AVI management : VDO
Set of functions in charge of searching for a video unshrinker and using it.
This module avoids the use of the high level function "AVIStreamGetFrame"
VERSION : 1.00/Nicolas Meyer/Creation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ##INCLUDE#----------------------------------------------------------------------------
Includes Files
---------------------------------------------------------------------------------------*/
#include "DecompressFunc.h"
/* ##GLOBVAR#----------------------------------------------------------------------------
Globale variable declaration
---------------------------------------------------------------------------------------*/
static LPBITMAPINFOHEADER gpBmpInfoHdrOut;
static LPBITMAPINFOHEADER gpBmpInfoHdrIn;
static PAVISTREAM gpAviStream;
static ICINFO gicInfo;
static HIC ghIC;
static unsigned char* gpchDataIn;
static unsigned char* gpchDataOut;
static long gnIndiceFrameLast;
static unsigned long gnNbKeyFrame;
static long* gpIndiceKeyFrame;
static unsigned long gnIndiceLastKey;
/* ##F===================================================================================
NAME : DecompressDesInitModule
DESCRIPTION : uninit the uncompression video module
INPUT :
OUTPUT : BOOL
=========================================================================================
CREATION : Nicolas Meyer
LAST MODIFICATIONS : Date/Author/Modification (5 maximum)
=======================================================================================*/
BOOL DecompressDesInitModule( )
{
BOOL bResult;
bResult = TRUE;
if( ICDecompressEnd( ghIC ) != ICERR_OK ) {
bResult = FALSE;
}
if( ICClose( ghIC ) != ICERR_OK ) {
bResult = FALSE;
}
if( gpBmpInfoHdrOut )
free( gpBmpInfoHdrOut );
if( gpchDataIn )
free( gpchDataIn );
if( gpIndiceKeyFrame )
free( gpIndiceKeyFrame );
memset( & gicInfo, 0, sizeof(ICINFO) );
ghIC = NULL;
gpBmpInfoHdrOut = NULL;
gpBmpInfoHdrIn = NULL;
gpAviStream = NULL;
gpchDataIn = NULL;
gpchDataOut = NULL;
gnIndiceFrameLast = -1;
gnNbKeyFrame = 0;
return bResult;
}/*DecompressDesInitModule*/
/* ##F===================================================================================
NAME : DecompressInitModule
DESCRIPTION : init the uncompression video module, returns TRUE or FALSE depending
of the success or failure of the operation
INPUT : LPBITMAPINFOHEADER pbiIn
LPAVISTREAMINFO pAviStrInfoIn
PAVISTREAM ppAviStream
OUTPUT : BOOL
=========================================================================================
CREATION : Nicolas Meyer
LAST MODIFICATIONS : Date/Author/Modification (5 maximum)
=======================================================================================*/
BOOL DecompressInitModule( LPBITMAPINFOHEADER pBmpInfoHdrIn, LPAVISTREAMINFO pAviStrInfoIn, PAVISTREAM pAviStream )
{
unsigned long nCpt;
unsigned long nIndiceKey;
unsigned long nResult;
long nTemp;
BITMAPINFOHEADER BmpInfoHdrOut;
ghIC = NULL;
if( ! pBmpInfoHdrIn )
return FALSE;
if( ! pAviStrInfoIn )
return FALSE;
if( ! pAviStream )
return FALSE;
ghIC = ICGetDisplayFormat( NULL,
pBmpInfoHdrIn,
& BmpInfoHdrOut,
pBmpInfoHdrIn->biBitCount,
0,
0 );
if( ! ghIC )
return FALSE;
if( ( nResult = ICGetInfo( ghIC, & gicInfo, sizeof(ICINFO) ) ) != sizeof(ICINFO) ) {
ICClose( ghIC );
return FALSE;
}
gpBmpInfoHdrIn = pBmpInfoHdrIn;
gpAviStream = pAviStream;
if( BmpInfoHdrOut.biSizeImage ) {
gpBmpInfoHdrOut = (LPBITMAPINFOHEADER)malloc( BmpInfoHdrOut.biSizeImage + sizeof(BITMAPINFOHEADER) );
gpchDataOut = (unsigned char*)( gpBmpInfoHdrOut + 1 );
}
else {
gpBmpInfoHdrOut = (LPBITMAPINFOHEADER)malloc( BmpInfoHdrOut.biBitCount * BmpInfoHdrOut.biWidth * BmpInfoHdrOut.biHeight >> 3 + sizeof(BITMAPINFOHEADER) );
gpchDataOut = (unsigned char*)( gpBmpInfoHdrOut + 1 );
}
memcpy( gpBmpInfoHdrOut, & BmpInfoHdrOut, sizeof(BITMAPINFOHEADER) );
if( gpBmpInfoHdrIn->biSizeImage )
gpchDataIn = (unsigned char*)malloc( gpBmpInfoHdrIn->biSizeImage );
else
gpchDataIn = (unsigned char*)malloc( gpBmpInfoHdrIn->biBitCount * gpBmpInfoHdrIn->biWidth * gpBmpInfoHdrIn->biHeight >> 3 );
if( ( nResult = ICDecompressBegin( ghIC, gpBmpInfoHdrIn, gpBmpInfoHdrOut ) ) != ICERR_OK ) {
memset( & gicInfo, 0, sizeof(ICINFO) );
ICClose( ghIC );
return FALSE;
}
gnNbKeyFrame = 0;
for( nCpt = 0; nCpt < pAviStrInfoIn->dwLength; /*nCpt++*/ ) {
if( ( nTemp = AVIStreamFindSample( gpAviStream,
(long)nCpt,
FIND_KEY | FIND_NEXT ) ) != -1 ) {
gnNbKeyFrame++;
nCpt = (unsigned long)nTemp + 1;
}
else
break;
}
gpIndiceKeyFrame = (long*)malloc( gnNbKeyFrame * sizeof(long) );
for( nIndiceKey = 0, nCpt = 0; nIndiceKey < gnNbKeyFrame; nIndiceKey++ ) {
gpIndiceKeyFrame[ nIndiceKey ] = AVIStreamFindSample( gpAviStream,
(long)nCpt,
FIND_KEY | FIND_NEXT );
nCpt = gpIndiceKeyFrame[ nIndiceKey ] + 1;
}
gnIndiceFrameLast = -1;
gnIndiceLastKey = 0;
}/*DecompressInitModule*/
/* ##F===================================================================================
NAME : DecompressGetFrame
DESCRIPTION : return a pointer on uncompressed datas
INPUT : long nIndiceFrame
OUTPUT : LPBITMAPINFOHEADER
=========================================================================================
CREATION : Nicolas Meyer
LAST MODIFICATIONS : Date/Author/Modification (5 maximum)
=======================================================================================*/
LPBITMAPINFOHEADER DecompressGetFrame( long nIndiceFrame )
{
long nSamplesRead;
long nBytesRead;
long nResult;
long nDifKeyNext;
long nDifCur;
// nDifKeyLast = abs( nIndiceFrame - gpIndiceKeyFrame[ gnIndiceLastKey ] );
if( gnIndiceFrameLast >= nIndiceFrame )
return gpBmpInfoHdrOut;
else
if( gnIndiceFrameLast == -1 )
gnIndiceFrameLast++;
// Find the position of the "KeyFrame"
while( gnIndiceLastKey < gnNbKeyFrame ) {
if( ( nIndiceFrame >= gpIndiceKeyFrame[ gnIndiceLastKey ] ) &&
( nIndiceFrame < gpIndiceKeyFrame[ gnIndiceLastKey + 1 ] ) )
break;
else {
gnIndiceLastKey++;
gnIndiceFrameLast = gpIndiceKeyFrame[ gnIndiceLastKey ];
}
}
// find the most favourable strategy
nDifKeyNext = abs( nIndiceFrame - gpIndiceKeyFrame[ gnIndiceLastKey + 1 ] );
nDifCur = abs( nIndiceFrame - gnIndiceFrameLast );
if( nDifCur >= nDifKeyNext )
gnIndiceFrameLast = gpIndiceKeyFrame[ gnIndiceLastKey + 1 ];
do {
nResult = AVIStreamRead( gpAviStream,
gnIndiceFrameLast++,
1,
gpchDataIn,
gpBmpInfoHdrIn->biSizeImage,
& nBytesRead,
& nSamplesRead );
nResult = ICDecompress( ghIC,
ICDECOMPRESS_HURRYUP,
gpBmpInfoHdrIn,
gpchDataIn,
gpBmpInfoHdrOut,
gpchDataOut );
}
while( gnIndiceFrameLast < nIndiceFrame + 1 );
gnIndiceFrameLast--;
return gpBmpInfoHdrOut;
}/*DecompressGetFrame*/