Files
Work/avifile/Compressor.cpp
2024-08-07 09:12:07 -04:00

140 lines
3.9 KiB
C++

#include <avifile/Compressor.hpp>
/*
* open - open the specified compressor
* @param - fccHandler requested compressor
* @return - bool indicates success or failure
*/
bool Compressor::open(const FOURCC &fccHandler)
{
close();
mhIC=ICOpen(FOURCC("vidc"),fccHandler,ICMODE_COMPRESS);
if(!isOkay())return false;
ICGetInfo(mhIC,&mCompressorInfo.getICINFO(),mCompressorInfo.size());
::printf(String("[Compressor::open]")+mCompressorInfo.toString());
return true;
}
/*
* close - close down the compressor
* @param - none
* @return - none
*/
void Compressor::close(void)
{
if(!isOkay())return;
compressEnd();
ICClose(mhIC);
mhIC=0;
}
/*
* getFormat - get the output format for source bitmap
* @param - srcBitmap source bitmap
* @param - dstBitmap output format
* @return - bool success or failure
*/
bool Compressor::getFormat(AVIBitmap &srcBitmap,AVIBitmap &dstBitmap)
{
if(!isOkay())return false;
if(ICERR_OK!=ICCompressGetFormat(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
::printf("[Compressor::getFormat] Input:\n%s\n",srcBitmap.toString().str());
::printf("[Compressor::getFormat] Output:\n%s\n",dstBitmap.toString().str());
return true;
}
/*
* compressQuery - determine if compressor can compress given input format into desired output format
* @param - srcBitmap source bitmap
* @param - dstBitmap desired output format
* @return - bool success or failure
*/
bool Compressor::compressQuery(AVIBitmap &srcBitmap,AVIBitmap &dstBitmap)
{
if(!isOkay())return false;
if(ICERR_OK!=ICCompressQuery(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
return true;
}
/*
* compressQuery - determine if compressor can compress given input format into any output format
* @param - srcBitmap source bitmap
* @return - bool success or failure
*/
bool Compressor::compressQuery(AVIBitmap &srcBitmap)
{
if(!isOkay())return false;
if(ICERR_OK!=ICCompressQuery(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)0))return false;
return true;
}
/*
* compressBegin - prepare driver to start compressing
* @param - srcBitmap contains input format
* @param - dstBitmap contains compressed formnat
* @return - bool indicating success or failure of call
*/
bool Compressor::compressBegin(AVIBitmap &srcBitmap,AVIBitmap &dstBitmap)
{
if(isInCompress())compressEnd();
try
{
if(ICERR_OK!=ICCompressBegin(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
mIsInCompress=true;
return true;
}
catch(...)
{
::OutputDebugString("[Compressor::compress] Caught exception during compress begin.\n");
return false;
}
}
/*
* compressEnd - finish compressing
* @param - none
* @return - none
*/
void Compressor::compressEnd(void)
{
if(!isOkay()||!isInCompress())return;
ICCompressEnd(mhIC);
mIsInCompress=false;
}
/*
* compress - compress a frame
* @param - srcBitmap contains input format
* @param - srcMovieData contains input data to be compressed
* @param - dstBitmap contains compressed formnat
* @param - dstMovieData contains compressed data
* @return - bool indicating success or failure of call
*/
bool Compressor::compress(AVIBitmap &srcBitmap,MovieData &srcMovieData,AVIBitmap &dstBitmap,MovieData &dstMovieData,DWORD dwFrameNumber)
{
DWORD dwFlags;
DWORD dwFrameSize;
if(!isOkay())return false;
dwFrameSize=0;
if(ICERR_OK!=ICCompressQuery(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)0))return false;
if(ICERR_OK!=ICCompressGetFormat(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
if(!isInCompress()&&!compressBegin(srcBitmap,dstBitmap))return false;
dwFrameSize=ICCompressGetSize(mhIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap);
dstMovieData.size(dwFrameSize);
if(!dstMovieData.size())return false;
if(!mCompressorInfo.hasCrunch())dwFrameSize=0;
ICCompress(mhIC,
ICCOMPRESS_KEYFRAME,
(BITMAPINFOHEADER*)dstBitmap,&dstMovieData[0],
(BITMAPINFOHEADER*)srcBitmap,&srcMovieData[0],
0, // Reserved
&dwFlags,
dwFrameNumber,
dwFrameSize,
mQuality,
0,
0);
return true;
}