219 lines
7.0 KiB
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*/ |