Files
Work/avifile/scraps.txt
2024-08-07 09:12:07 -04:00

1052 lines
32 KiB
Plaintext

bool createAVIFile(const String &pathAVIFile,Block<Bitmap> &images)
{
File aviFile(pathAVIFile,"w+b");
AVIMainHeader aviMainHeader;
AVIStreamHeader aviStreamHeader;
AVIFormatHeader aviFormatHeader;
AVIMovieHeader aviMovieHeader;
RIFFHeader riffHeader;
BITMAPINFO *pBitmapInfo;
DWORD position;
DWORD currentPosition;
DWORD sizeHeader;
DWORD totalFileSize;
if(!images.size())return false;
Bitmap &bitmap=images[0];
riffHeader.write(aviFile);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4;
aviFile.write("hdrl");
aviMainHeader.microSecondsPerFrame(10000);
aviMainHeader.maxBytesPerSecond(7100);
aviMainHeader.granularity(0);
// aviMainHeader.flags(2064);
aviMainHeader.flags(0);
aviMainHeader.totalFrames(images.size());
aviMainHeader.initialFrames(0);
aviMainHeader.streams(2);
aviMainHeader.suggestedBufferSize(12800);
aviMainHeader.width(bitmap.width());
aviMainHeader.height(bitmap.height());
// aviMainHeader.hasIndex(0);
// aviMainHeader.mustUseIndex(0);
// aviMainHeader.isInterleaved(0);
// aviMainHeader.wasCaptureFile(0);
// aviMainHeader.isCopyrighted(0);
aviMainHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4; // this is a placeholder, we'll write in the header size later
aviFile.write("strl");
aviStreamHeader.fccType(FOURCC("vids"));
aviStreamHeader.fccHandler(FOURCC("msvc"));
aviStreamHeader.flags(0);
aviStreamHeader.priority(0);
aviStreamHeader.language(0);
aviStreamHeader.initialFrames(0);
aviStreamHeader.scale(1);
aviStreamHeader.rate(1);
aviStreamHeader.start(0);
aviStreamHeader.length(images.size());
aviStreamHeader.suggestedBufferSize(8192);
aviStreamHeader.quality(0);
aviStreamHeader.sampleSize(0);
aviStreamHeader.frame(Rect(0,0,bitmap.width(),bitmap.height()));
aviStreamHeader.write(aviFile);
aviFormatHeader.streamType(StreamType::Video);
AVIBitmap &aviBitmap=aviFormatHeader.getBitmap();
(BitmapInfo&)aviBitmap=bitmap.getPalette();
pBitmapInfo=bitmap.getInfoPtr();
aviBitmap.width(bitmap.width());
aviBitmap.height(bitmap.height());
aviBitmap.planes(bitmap.planes());
aviBitmap.bitCount((BitmapInfo::BitsPerPixel)bitmap.bitCount());
aviBitmap.compression(BitmapInfo::BiRGB);
aviBitmap.sizeImage(pBitmapInfo->bmiHeader.biSizeImage);
aviBitmap.xPelsPerMeter(pBitmapInfo->bmiHeader.biXPelsPerMeter);
aviBitmap.yPelsPerMeter(pBitmapInfo->bmiHeader.biYPelsPerMeter);
aviBitmap.colorUsed(pBitmapInfo->bmiHeader.biClrUsed);
aviBitmap.colorImportant(pBitmapInfo->bmiHeader.biClrImportant);
aviFormatHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4;
aviFile.write("movi");
for(int index=0;index<images.size();index++)
{
aviMovieHeader.insert(&MovieData(MovieData::DIBUnCompressed));
Bitmap &bitmap=images[index];
MovieData &movieData=aviMovieHeader[index];
movieData.streamNumber(index);
movieData.size(bitmap.getInfoPtr()->bmiHeader.biSizeImage);
::memcpy(&movieData[0],bitmap.getDataPtr(),bitmap.getInfoPtr()->bmiHeader.biSizeImage);
}
aviMovieHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
totalFileSize=aviFile.tell();
aviFile.rewind();
riffHeader.size(totalFileSize-RIFFHeader::sizeHeader());
riffHeader.write(aviFile);
aviFile.close();
return true;
}
bool createAVIFile(const String &pathAVIFile,Block<Bitmap> &images)
{
File aviFile(pathAVIFile,"w+b");
AVIMainHeader aviMainHeader;
AVIStreamHeader aviStreamHeader;
AVIFormatHeader aviFormatHeader;
AVIMovieHeader aviMovieHeader;
RIFFHeader riffHeader;
BITMAPINFO *pBitmapInfo;
DWORD position;
DWORD currentPosition;
DWORD sizeHeader;
DWORD totalFileSize;
if(!images.size())return false;
Bitmap &bitmap=images[0];
riffHeader.write(aviFile);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4;
aviFile.write("hdrl");
aviMainHeader.microSecondsPerFrame(10000);
aviMainHeader.maxBytesPerSecond(7100);
aviMainHeader.granularity(0);
// aviMainHeader.flags(2064);
aviMainHeader.flags(0);
aviMainHeader.totalFrames(images.size());
aviMainHeader.initialFrames(0);
aviMainHeader.streams(2);
aviMainHeader.suggestedBufferSize(12800);
aviMainHeader.width(bitmap.width());
aviMainHeader.height(bitmap.height());
// aviMainHeader.hasIndex(0);
// aviMainHeader.mustUseIndex(0);
// aviMainHeader.isInterleaved(0);
// aviMainHeader.wasCaptureFile(0);
// aviMainHeader.isCopyrighted(0);
aviMainHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4; // this is a placeholder, we'll write in the header size later
aviFile.write("strl");
aviStreamHeader.fccType(FOURCC("vids"));
aviStreamHeader.fccHandler(FOURCC("msvc"));
aviStreamHeader.flags(0);
aviStreamHeader.priority(0);
aviStreamHeader.language(0);
aviStreamHeader.initialFrames(0);
aviStreamHeader.scale(1);
aviStreamHeader.rate(1);
aviStreamHeader.start(0);
aviStreamHeader.length(images.size());
aviStreamHeader.suggestedBufferSize(8192);
aviStreamHeader.quality(0);
aviStreamHeader.sampleSize(0);
aviStreamHeader.frame(Rect(0,0,bitmap.width(),bitmap.height()));
aviStreamHeader.write(aviFile);
aviFormatHeader.streamType(StreamType::Video);
AVIBitmap &aviBitmap=aviFormatHeader.getBitmap();
(BitmapInfo&)aviBitmap=bitmap.getPalette();
pBitmapInfo=bitmap.getInfoPtr();
aviBitmap.width(bitmap.width());
aviBitmap.height(bitmap.height());
aviBitmap.planes(bitmap.planes());
aviBitmap.bitCount((BitmapInfo::BitsPerPixel)bitmap.bitCount());
aviBitmap.compression(BitmapInfo::BiRGB);
aviBitmap.sizeImage(pBitmapInfo->bmiHeader.biSizeImage);
aviBitmap.xPelsPerMeter(pBitmapInfo->bmiHeader.biXPelsPerMeter);
aviBitmap.yPelsPerMeter(pBitmapInfo->bmiHeader.biYPelsPerMeter);
aviBitmap.colorUsed(pBitmapInfo->bmiHeader.biClrUsed);
aviBitmap.colorImportant(pBitmapInfo->bmiHeader.biClrImportant);
aviFormatHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
aviFile.write("LIST");
position=aviFile.tell();
aviFile+=4;
aviFile.write("movi");
for(int index=0;index<images.size();index++)
{
aviMovieHeader.insert(&MovieData(MovieData::DIBUnCompressed));
Bitmap &bitmap=images[index];
MovieData &movieData=aviMovieHeader[index];
movieData.streamNumber(index);
movieData.size(bitmap.getInfoPtr()->bmiHeader.biSizeImage);
::memcpy(&movieData[0],bitmap.getDataPtr(),bitmap.getInfoPtr()->bmiHeader.biSizeImage);
}
aviMovieHeader.write(aviFile);
sizeHeader=aviFile.tell()-position;
currentPosition=aviFile.tell();
aviFile.seek(position,File::SeekSet);
aviFile.write(sizeHeader);
aviFile.seek(currentPosition,File::SeekSet);
totalFileSize=aviFile.tell();
aviFile.rewind();
riffHeader.size(totalFileSize-RIFFHeader::sizeHeader());
riffHeader.write(aviFile);
aviFile.close();
return true;
}
bool proto2(const String &pathAVIFile)
{
VideoCodec videoCodec;
ICMOpen icmOpen;
ICMInfo icmInfo;
ICMDecompress icmDecompress;
WORD streamCount;
WORD frameCount(0);
AVIFile aviFile(pathAVIFile);
AVIStreamData &aviStreamData=(AVIStreamData&)aviFile;
if(0==(streamCount=aviStreamData.size()))return FALSE;
::OutputDebugString(String("FCCType:")+aviStreamData[0].fccType().toString()+String("\n"));
::OutputDebugString(String("FCCHandler:")+aviStreamData[0].fccHandler().toString()+String("\n"));
FOURCC driverName("mrle");
Block<DriverName> driverNames;
videoCodec.enumerateDrivers(driverNames);
for(int index=0;index<driverNames.size();index++)
{
::OutputDebugString(driverNames[index].driverName()+String("\n"));
}
if(!(VideoCodec::OkResult==videoCodec.openDriver(driverName)))return false;
icmOpen.fccType(aviStreamData[0].fccType());
icmOpen.fccHandler(aviStreamData[0].fccHandler());
icmOpen.flags(ICMOpen::DeCompress);
icmOpen.version(1);
videoCodec.driverLoad();
videoCodec.driverEnable();
videoCodec.driverProc(icmOpen);
videoCodec.driverProc(icmInfo);
// videoCodec.icmConfigure(::GetFocus());
for(short streamIndex=0;streamIndex<streamCount;streamIndex++)
{
if(!StreamType::Video==aviStreamData[streamIndex].streamType())continue;
AVIBitmap &aviBitmap=aviStreamData[streamIndex].getBitmap();
AVIBitmap dstBitmap(aviBitmap);
dstBitmap.compression(BI_RGB);
dstBitmap.sizeImage(dstBitmap.width()*dstBitmap.height());
dstBitmap.colorUsed(aviBitmap.colorUsed());
if(VideoCodec::FailResult==videoCodec.canDecompress(aviBitmap))continue;
WORD movieCount(((AVIMovieHeader&)aviFile).size());
for(short movieIndex=0;movieIndex<movieCount;movieIndex++)
{
MovieData &srcMovieData=((AVIMovieHeader&)aviFile)[movieIndex];
if(!((srcMovieData.streamNumber()==streamIndex)&&
(MovieData::DIBCompressed==srcMovieData.dataType()||
MovieData::IV==srcMovieData.dataType()||
MovieData::DIBUnCompressed==srcMovieData.dataType())))continue;
String pathFileName;
MovieData dstMovieData;
dstMovieData.dataType(srcMovieData.dataType());
dstMovieData.streamNumber(srcMovieData.streamNumber());
::sprintf(pathFileName,"FRM%05d.BMP",frameCount++);
if(VideoCodec::OkResult!=videoCodec.decompressFrame(aviBitmap,dstBitmap,srcMovieData,dstMovieData))
{
::printf("Error decompressing frame\n");
continue;
}
Bitmap imageBitmap(pathFileName,(BitmapInfo&)dstBitmap,(GlobalData<BYTE>&)dstMovieData);
imageBitmap.saveBitmap();
}
}
videoCodec.closeDriver();
return FALSE;
}
bool proto1(void)
{
VideoCodec videoCodec;
ICMOpen icmOpen;
ICMInfo icmInfo;
ICMDecompress icmDecompress;
WORD streamCount;
WORD frameCount(0);
String commandLine;
// if(!(VideoCodec::OkResult==videoCodec.openDriver(FOURCC("I420"))))return FALSE;
// lpszCmdLine="D:\\CAPTURE1.AVI";
commandLine="D:\\CAPTURE2.AVI";
// commandLine="c:\\winnt\\clock.avi";
AVIFile aviFile(commandLine);
AVIStreamData &aviStreamData=(AVIStreamData&)aviFile;
if(0==(streamCount=aviStreamData.size()))return FALSE;
::OutputDebugString(String("FCCType:")+aviStreamData[0].fccType().toString()+String("\n"));
::OutputDebugString(String("FCCHandler:")+aviStreamData[0].fccHandler().toString()+String("\n"));
icmOpen.fccType(aviStreamData[0].fccType());
// icmOpen.fccType(FOURCC("vidc"));
icmOpen.fccHandler(aviStreamData[0].fccHandler());
// icmOpen.fccType(aviStreamData[0].fccType());
// icmOpen.fccHandler(FOURCC("DIVX"));
icmOpen.flags(ICMOpen::DeCompress);
icmOpen.version(1);
videoCodec.driverLoad();
videoCodec.driverEnable();
videoCodec.driverProc(icmOpen);
videoCodec.driverProc(icmInfo);
// videoCodec.icmConfigure(::GetFocus());
for(short streamIndex=0;streamIndex<streamCount;streamIndex++)
{
if(!StreamType::Video==aviStreamData[streamIndex].streamType())continue;
AVIBitmap &aviBitmap=(AVIBitmap&)(aviStreamData[streamIndex]);
AVIBitmap dstBitmap(aviBitmap);
dstBitmap.compression(BI_RGB);
dstBitmap.sizeImage(dstBitmap.width()*dstBitmap.height());
dstBitmap.colorUsed(0);
// if(VideoCodec::FailResult==videoCodec.canDecompress(aviBitmap))continue;
WORD movieCount(((AVIMovieHeader&)aviFile).size());
for(short movieIndex=0;movieIndex<movieCount;movieIndex++)
{
MovieData &srcMovieData=((AVIMovieHeader&)aviFile)[movieIndex];
if(!((srcMovieData.streamNumber()==streamIndex)&&
(MovieData::DIBCompressed==srcMovieData.dataType()||
MovieData::IV==srcMovieData.dataType()||
MovieData::DIBUnCompressed==srcMovieData.dataType())))continue;
File outfile;
outfile.open("d:\\frame.dvsd","wb");
outfile.write((char*)&srcMovieData[0],srcMovieData.size());
String pathFileName;
MovieData dstMovieData;
dstMovieData.dataType(srcMovieData.dataType());
dstMovieData.streamNumber(srcMovieData.streamNumber());
::sprintf(pathFileName,"FRM%05d.BMP",frameCount++);
Bitmap imageBitmap(pathFileName,(BitmapInfo&)aviBitmap,(GlobalData<BYTE>&)srcMovieData);
imageBitmap.saveBitmap();
if(VideoCodec::OkResult!=videoCodec.decompressFrame(aviBitmap,dstBitmap,srcMovieData,dstMovieData))
{
::printf("Error decompressing frame\n");
continue;
}
// Bitmap imageBitmap(pathFileName,(BitmapInfo&)dstBitmap,(GlobalData<BYTE>&)dstMovieData);
// imageBitmap.saveBitmap();
}
}
videoCodec.closeDriver();
return FALSE;
}
bool createAVIFile(const String &pathAVIFile,Block<SmartPointer<JPGImage> >&images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
pFile=0;
pStream=0;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
JPGImage &image=*images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=image.getBitmapInfo().sizeImage();
SetRect(&aviStreamInfo.rcFrame,0,0,image.width(),image.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
hResult=AVIStreamSetFormat(pStream,0,&image.getBitmapInfo().getBITMAPINFOHEADER(),
image.getBitmapInfo().getBITMAPINFOHEADER().biSize+(image.getBitmapInfo().getBITMAPINFOHEADER().biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
JPGImage &image=*images[index];
GlobalData<BYTE> rawData;
image.getRawData(rawData);
hResult=AVIStreamWrite(pStream,index,1,
&rawData[0],
rawData.size(),
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
int PASCAL WinMain(HINSTANCE /*hInstance*/,HINSTANCE /*hPrevInstance*/,LPSTR lpszCmdLine,int /*nCmdShow*/)
{
Block<SmartPointer<JPGImage> > images;
images.insert(&SmartPointer<JPGImage>());
images[0]=new JPGImage();
images[0].disposition(PointerDisposition::Delete);
images[0]->decode("d:\\im000256.jpg");
createAVIFile("d:\\foo.avi",images);
// return proto2("c:\\winnt\\clock.avi");
// return proto2("d:\\foo.avi");
// return proto2("d:\\avi\\capture2.avi");
// return createAVI("d:\\foo.avi");
return 0;
}
void testCompression()
{
// FOURCC fccType("vidc");
// FOURCC fccHandler("divx");
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
GlobalData<BYTE> rawImage;
JPGImage jpgImage;
jpgImage.decode("d:\\im000256.jpg");
jpgImage.saveBitmap("d:\\im000256.bmp");
jpgImage.getRawData(rawImage);
Bitmap bm("d:\\im000256.bmp");
(BitmapInfo&)srcBitmap=*bm.getInfoPtr();
// (BitmapInfo&)srcBitmap=jpgImage.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
// (BitmapInfo&)srcBitmap=BitmapInfo(*bm.getInfoPtr());
// srcBitmap.sizeImage(srcBitmap.width()*(srcBitmap.height()<0?-srcBitmap.height():srcBitmap.height()));
// srcBitmap.compression(BitmapInfo::BiRGB);
// srcBitmap.compression(FOURCC("divx").toDWORD());
// if(!canCompress("divx",srcBitmap,dstBitmap))return;
// compress("divx",srcBitmap,rawImage,dstBitmap);
// compress("msvc",srcBitmap,rawImage,dstBitmap);
MovieData srcMovieData;
MovieData dstMovieData;
srcMovieData=rawImage;
compress2("msvc",srcBitmap,srcMovieData,dstBitmap,dstMovieData);
return ;
}
bool canCompress(const String &driverName,AVIBitmap &srcBitmap,AVIBitmap &dstBitmap);
bool compress(const String &driverName,AVIBitmap &srcBitmap,GlobalData<BYTE> &rawData,AVIBitmap &dstBitmap);
bool canCompress(const String &driverName,AVIBitmap &srcBitmap,AVIBitmap &dstBitmap)
{
VideoCodec videoCodec;
if(!(VideoCodec::OkResult==videoCodec.openDriver(FOURCC(driverName))))return false;
videoCodec.driverLoad();
videoCodec.driverEnable();
if(VideoCodec::OkResult!=videoCodec.canCompress(srcBitmap))return false;
return true;
}
bool compress(const String &driverName,AVIBitmap &srcBitmap,GlobalData<BYTE> &rawData,AVIBitmap &dstBitmap)
{
ICMOpen icmOpen;
ICMInfo icmInfo;
VideoCodec videoCodec;
MovieData srcMovieData;
MovieData dstMovieData;
icmOpen.fccType(FOURCC("vidc"));
icmOpen.fccHandler(FOURCC(driverName));
icmOpen.flags(ICMOpen::Compress);
icmOpen.version(1);
if(!(VideoCodec::OkResult==videoCodec.openDriver(FOURCC(driverName))))return false;
videoCodec.driverLoad();
videoCodec.driverEnable();
videoCodec.driverProc(icmOpen);
videoCodec.driverProc(icmInfo);
if(VideoCodec::OkResult!=videoCodec.canCompress(srcBitmap))return false;
srcMovieData=rawData;
return VideoCodec::OkResult==videoCodec.compressFrame(srcBitmap,dstBitmap,srcMovieData,dstMovieData);
}
//#include <avifile/avifile.hpp>
//#include <avifile/mainhdr.hpp>
//#include <avifile/vidc.hpp>
//#include <avifile/riffhdr.hpp>
/* Block<SmartPointer<JPGImage> > images;
images.insert(&SmartPointer<JPGImage>());
images[0]=new JPGImage();
images[0].disposition(PointerDisposition::Delete);
images[0]->decode("d:\\im000256.jpg");
createAVIFile("d:\\im00256.avi",images); */
/*
JPGImage jpgImage;
jpgImage.decode("d:\\im000256.jpg");
jpgImage.resample(640,480);
jpgImage.saveBitmap("d:\\im000256.bmp");
images.insert(&Bitmap());
images[0]="d:\\im000256.bmp";
createAVIFile("d:\\im00256.avi",FOURCC("msvc"),images);
*/
//
// ********************************************************************************************
// *************************************************************************************************
bool createAVIFile(const String &pathAVIFile,Block<Bitmap> &images);
bool createAVIFile(const String &pathAVIFile,const FOURCC &fccHandler,Block<Bitmap> &images);
bool createAVIFile(const String &pathAVIFile,const FOURCC &fccHandler,Block<SmartPointer<JPGImage> >&images);
bool createAVIFile(const String &pathAVIFile,Block<SmartPointer<JPGImage> >&images);
bool canCompress(const FOURCC &fccHandler,AVIBitmap &srcBitmap,AVIBitmap &dstBitmap);
bool compress(const FOURCC &fccHandler,AVIBitmap &srcBitmap,MovieData &srcMovieData,AVIBitmap &dstBitmap,MovieData &dstMovieData);
void getImageData(JPGImage &jpgImage,MovieData &movieData);
void copyRow(RGB888 *pDstArray,RGB888 *pSrcArray,int length);
void proto1(void);
void proto2(void);
void proto2(void);
void proto2()
{
Block<SmartPointer<JPGImage> > images;
Block<String> fileList;
PathFind pathFind;
// String rootDir="d:\\captures\\";
String rootDir="d:\\photos\\nov2002\\";
pathFind.fileList(rootDir+String("*.jpg"),fileList);
for(int index=0;index<fileList.size()&&index<30;index++)
{
String pathJPGFile;
pathJPGFile=rootDir+fileList[index];
images.insert(&SmartPointer<JPGImage>());
images[index]=new JPGImage();
images[index]->decode(pathJPGFile);
images[index]->resample(640,480);
}
createAVIFile("d:\\capture.avi",FOURCC("cvid"),images);
// createAVIFile("d:\\capture.avi",images);
/*
Block<SmartPointer<JPGImage> > images;
images.insert(&SmartPointer<JPGImage>());
images[0]=::new JPGImage();
images[0].disposition(PointerDisposition::Delete);
images[0]->decode("d:\\photos\\nov2002\\im000257.jpg");
images[0]->resample(640,480);
createAVIFile("d:\\capture.avi",FOURCC("cvid"),images); // Cinepak Codec by Radius
*/
}
void proto1(void)
{
Block<Bitmap> images;
Block<String> fileList;
PathFind pathFind;
// String rootDir="d:\\captures\\";
String rootDir="d:\\photos\\nov2002\\";
pathFind.fileList(rootDir+String("*.jpg"),fileList);
for(int index=0;index<fileList.size()&&index<30;index++)
{
String pathJPGFile;
String pathBMPFile;
JPGImage jpgImage;
pathJPGFile=rootDir+fileList[index];
pathBMPFile=rootDir+fileList[index].betweenString(0,'.')+String(".bmp");
jpgImage.decode(pathJPGFile);
jpgImage.resample(640,480);
jpgImage.saveBitmap(pathBMPFile);
images.insert(&Bitmap());
images[index]=pathBMPFile;
}
createAVIFile("d:\\capture.avi",FOURCC("msvc"),images);
// createAVIFile("d:\\capture.avi",images);
}
bool createAVIFile(const String &pathAVIFile,const FOURCC &fccHandler,Block<SmartPointer<JPGImage> >&images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
bool flip;
pFile=0;
pStream=0;
flip=false;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
JPGImage &image=*images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=image.getBitmapInfo().sizeImage();
SetRect(&aviStreamInfo.rcFrame,0,0,image.width(),image.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
if(canCompress(fccHandler,srcBitmap,dstBitmap))
{
hResult=AVIStreamSetFormat(pStream,0,&dstBitmap.getBITMAPINFOHEADER(),
dstBitmap.getBITMAPINFOHEADER().biSize+(dstBitmap.getBITMAPINFOHEADER().biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
MovieData srcMovieData;
MovieData dstMovieData;
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
JPGImage &image=*images[index];
getImageData(image,srcMovieData);
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
compress(fccHandler,srcBitmap,srcMovieData,dstBitmap,dstMovieData);
hResult=AVIStreamWrite(pStream,index,1,
&dstMovieData[0],
dstMovieData.size(),
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
bool createAVIFile(const String &pathAVIFile,Block<SmartPointer<JPGImage> >&images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
bool flip;
pFile=0;
pStream=0;
flip=false;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
JPGImage &image=*images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=image.getBitmapInfo().sizeImage();
SetRect(&aviStreamInfo.rcFrame,0,0,image.width(),image.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
AVIBitmap srcBitmap;
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
hResult=AVIStreamSetFormat(pStream,0,&srcBitmap.getBITMAPINFOHEADER(),
srcBitmap.getBITMAPINFOHEADER().biSize+(srcBitmap.getBITMAPINFOHEADER().biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
MovieData srcMovieData;
AVIBitmap srcBitmap;
JPGImage &image=*images[index];
getImageData(image,srcMovieData);
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
hResult=AVIStreamWrite(pStream,index,1,
&srcMovieData[0],
srcMovieData.size(),
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
void getImageData(JPGImage &jpgImage,MovieData &movieData)
{
if(jpgImage.getBitmapInfo().height()<0)
{
Array<RGB888> &rgbArray=jpgImage.getRGBArray();
Array<RGB888> tmpArray;
tmpArray.size(rgbArray.size());
jpgImage.getBitmapInfo().height(-jpgImage.getBitmapInfo().height());
for(int row=0;row<jpgImage.height();row++)
copyRow(&tmpArray[row*jpgImage.getBitmapInfo().width()],
&rgbArray[(jpgImage.getBitmapInfo().height()-row)*
jpgImage.getBitmapInfo().width()-
jpgImage.getBitmapInfo().width()],
jpgImage.getBitmapInfo().width());
movieData.size(tmpArray.size()*3);
::memcpy(&movieData[0],&tmpArray[0],tmpArray.size()*3);
}
else
{
Array<RGB888> &rgbArray=jpgImage.getRGBArray();
movieData.size(rgbArray.size()*3);
::memcpy(&movieData[0],&rgbArray[0],rgbArray.size()*3);
}
}
void copyRow(RGB888 *pDstArray,RGB888 *pSrcArray,int length)
{
for(unsigned long count=0;count<length;count++)*pDstArray++=*pSrcArray++;
}
/*
bool createAVIFile(const String &pathAVIFile,const FOURCC &fccHandler,Block<SmartPointer<JPGImage> >&images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
bool flip;
pFile=0;
pStream=0;
flip=false;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
JPGImage &image=*images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=image.getBitmapInfo().sizeImage();
SetRect(&aviStreamInfo.rcFrame,0,0,image.width(),image.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
if(canCompress(fccHandler,srcBitmap,dstBitmap))
{
hResult=AVIStreamSetFormat(pStream,0,&dstBitmap.getBITMAPINFOHEADER(),
dstBitmap.getBITMAPINFOHEADER().biSize+(dstBitmap.getBITMAPINFOHEADER().biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
MovieData srcMovieData;
MovieData dstMovieData;
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
JPGImage &image=*images[index];
GlobalData<BYTE> rawData;
image.getRawData(rawData);
srcMovieData=rawData;
(BitmapInfo&)srcBitmap=image.getBitmapInfo();
if(srcBitmap.height()<0)srcBitmap.height(-srcBitmap.height());
compress(fccHandler,srcBitmap,srcMovieData,dstBitmap,dstMovieData);
hResult=AVIStreamWrite(pStream,index,1,
&dstMovieData[0],
dstMovieData.size(),
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
*/
bool createAVIFile(const String &pathAVIFile,Block<Bitmap> &images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
pFile=0;
pStream=0;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
Bitmap bitmap=images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=bitmap.getInfoPtr()->bmiHeader.biSizeImage;
SetRect(&aviStreamInfo.rcFrame,0,0,bitmap.width(),bitmap.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
hResult=AVIStreamSetFormat(pStream,0,&bitmap.getInfoPtr()->bmiHeader,bitmap.getInfoPtr()->bmiHeader.biSize+(bitmap.getInfoPtr()->bmiHeader.biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
Bitmap &bitmap=images[index];
hResult=AVIStreamWrite(pStream,index,1,
bitmap.ptrData(),
bitmap.getInfoPtr()->bmiHeader.biSizeImage,
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
bool createAVIFile(const String &pathAVIFile,const FOURCC &fccType,Block<Bitmap> &images)
{
PAVIFILE pFile;
PAVISTREAM pStream;
AVISTREAMINFO aviStreamInfo;
HRESULT hResult;
pFile=0;
pStream=0;
if(!images.size())return false;
AVIFileInit();
hResult=AVIFileOpen(&pFile,pathAVIFile,OF_WRITE|OF_CREATE,NULL);
if(hResult!=AVIERR_OK)return false;
Bitmap bitmap=images[0];
::memset(&aviStreamInfo,0,sizeof(AVISTREAMINFO));
aviStreamInfo.fccType=streamtypeVIDEO;
aviStreamInfo.fccHandler=0;
aviStreamInfo.dwScale=1;
aviStreamInfo.dwRate=1;
aviStreamInfo.dwSuggestedBufferSize=bitmap.getInfoPtr()->bmiHeader.biSizeImage;
SetRect(&aviStreamInfo.rcFrame,0,0,bitmap.width(),bitmap.height());
hResult=AVIFileCreateStream(pFile,&pStream,&aviStreamInfo);
if(hResult==AVIERR_OK)
{
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
(BitmapInfo&)srcBitmap=*bitmap.getInfoPtr();
if(canCompress(fccType,srcBitmap,dstBitmap))
{
hResult=AVIStreamSetFormat(pStream,0,&dstBitmap.getBITMAPINFOHEADER(),dstBitmap.getBITMAPINFOHEADER().biSize+(dstBitmap.getBITMAPINFOHEADER().biClrUsed*sizeof(RGBQUAD)));
if(hResult==AVIERR_OK)
{
for(int index=0;index<images.size();index++)
{
Bitmap &bitmap=images[index];
MovieData srcMovieData;
MovieData dstMovieData;
AVIBitmap srcBitmap;
AVIBitmap dstBitmap;
srcMovieData.size(bitmap.getInfoPtr()->bmiHeader.biSizeImage);
::memcpy(&srcMovieData[0],bitmap.getDataPtr(),bitmap.getInfoPtr()->bmiHeader.biSizeImage);
(BitmapInfo&)srcBitmap=*bitmap.getInfoPtr();
compress(fccType,srcBitmap,srcMovieData,dstBitmap,dstMovieData);
hResult=AVIStreamWrite(pStream,index,1,
&dstMovieData[0],
dstMovieData.size(),
AVIIF_KEYFRAME,0,0);
if(hResult!=AVIERR_OK)break;
}
}
}
}
if(pStream)AVIStreamClose(pStream);
if(pFile)AVIFileClose(pFile);
AVIFileExit();
return true;
}
bool canCompress(const FOURCC &fccHandler,AVIBitmap &srcBitmap,AVIBitmap &dstBitmap)
{
HIC hIC;
hIC=ICOpen(FOURCC("vidc"),fccHandler,ICMODE_COMPRESS);
if(ICERR_OK!=ICCompressQuery(hIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)0))return false;
if(ICERR_OK!=ICCompressGetFormat(hIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
ICClose(hIC);
return true;
}
bool compress(const FOURCC &fccHandler,AVIBitmap &srcBitmap,MovieData &srcMovieData,AVIBitmap &dstBitmap,MovieData &dstMovieData)
{
DWORD dwFlags;
DWORD ckid;
DWORD dwQuality;
HIC hIC;
dwQuality=100;
hIC=ICOpen(FOURCC("vidc"),fccHandler,ICMODE_COMPRESS);
if(ICERR_OK!=ICCompressQuery(hIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)0))return false;
if(ICERR_OK!=ICCompressGetFormat(hIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
if(ICERR_OK!=ICCompressBegin(hIC,(BITMAPINFO*)srcBitmap,(BITMAPINFO*)dstBitmap))return false;
dstMovieData.size(dstBitmap.sizeImage());
if(!dstMovieData.size())return false;
ICCompress(hIC,
ICCOMPRESS_KEYFRAME,
(BITMAPINFOHEADER*)dstBitmap,&dstMovieData[0],
(BITMAPINFOHEADER*)srcBitmap,&srcMovieData[0],
&ckid,
&dwFlags,
1,
0,
dwQuality,
0,
0);
if(ICERR_OK!=ICCompressEnd(hIC))return false;
ICClose(hIC);
return true;
}
void makeAVI()
{
QuickSort<String> stringSorter;
Block<String> fileList;
PathFind pathFind;
// String rootDir="d:\\photos\\nov2002\\";
String rootDir="d:\\captures\\";
AVIGenerator aviGenerator;
pathFind.fileList(rootDir+String("*.jpg"),fileList);
stringSorter.sortItems(fileList);
for(int index=0;index<fileList.size();index++)fileList[index]=rootDir+fileList[index];
aviGenerator.setResample(Point(640,480));
aviGenerator.createAVIFile("d:\\capture.avi",FOURCC("cvid"),fileList);
// aviGenerator.createAVIFile("d:\\capture.avi",fileList);
}
void makeAVI(void);
void proto();