/* ##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*/