From 8dd8d0ff38affe9ed7f38636d75014a5ae7f7fd0 Mon Sep 17 00:00:00 2001 From: abd Date: Fri, 4 Aug 2006 04:53:31 +0000 Subject: [PATCH] Add possibility to create *.AVi file on WNT platfrom with help of native WinAPI tools. Using Microsoft Video 1 Codec for compress video files --- src/VISU_I/VISU_TimeAnimation.cxx | 271 ++++++++++++++++++++++-------- 1 file changed, 203 insertions(+), 68 deletions(-) diff --git a/src/VISU_I/VISU_TimeAnimation.cxx b/src/VISU_I/VISU_TimeAnimation.cxx index b337e3ad..dfe9ff1e 100644 --- a/src/VISU_I/VISU_TimeAnimation.cxx +++ b/src/VISU_I/VISU_TimeAnimation.cxx @@ -23,6 +23,12 @@ #include "VISU_TimeAnimation.h" +#ifdef WNT +#include +#include +#include +#endif + #include "VISUConfig.hh" #include "VISU_Result_i.hh" @@ -650,63 +656,74 @@ void VISU_TimeAnimation::run() msleep(delay); qApp->lock(); - if (isDumping) { + if (isDumping) + { // We must unlock mutex for some time before grabbing to allow view updating qApp->unlock(); msleep(delay); qApp->lock(); if(!(myFieldsLst[0].myField)) // break, if field was deleted. - break; + break; if (myDumpFormat.compare("AVI") != 0) { - QString aFile(myDumpPath); - QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]); - int aPos = -1; - while ((aPos = aName.find(".")) > -1 ) - aName.replace(aPos, 1, "_"); - aFile += aName; - aFile += "."; - aFile += myDumpFormat.lower(); - myView->dumpViewToFormat(aFile,myDumpFormat); - } else { - QFileInfo aFileInfo(myDumpPath); - QString aDirPath = aFileInfo.dirPath(true); - QString aBaseName = aFileInfo.fileName(); - - switch (myFrame) { - case 0: - break; - case 1: - myFileIndex += 5; - break; - default: - if (myProportional) { - double p = (myFieldsLst[0].myTiming[myFrame] - - myFieldsLst[0].myTiming[myFrame-1]) / aOneVal; - myFileIndex += (long) (5*p); - } else { - myFileIndex += 5; - } - } - - QString aFile = aDirPath + QDir::separator() + aBaseName; - aFile += "_"; - aFile += QString("%1").arg(myFileIndex).rightJustify(8, '0'); - aFile += ".jpeg"; - - /* check image size is divisable 16 - myView->dumpViewToFormat(aFile,"JPEG"); - */ - SUIT_ViewWindow* aView = myView; - QImage img = aView->dumpView(); - if (!img.isNull()) { - int width = img.width(); width = (width/16)*16; - int height = img.height(); height = (height/16)*16; - QImage copy = img.copy(0, 0, width, height); - if (copy.save(aFile, "JPEG")) { - anIndexList.append(myFileIndex); - aNbFiles++; - } - } + QString aFile(myDumpPath); + QString aName = QString("%1").arg(myFieldsLst[0].myTiming[myFrame]); + int aPos = -1; + while ((aPos = aName.find(".")) > -1 ) + aName.replace(aPos, 1, "_"); + aFile += aName; + aFile += "."; + aFile += myDumpFormat.lower(); + myView->dumpViewToFormat(aFile,myDumpFormat); + } + else + { + QFileInfo aFileInfo(myDumpPath); + QString aDirPath = aFileInfo.dirPath(true); + QString aBaseName = aFileInfo.fileName(); + + switch (myFrame) { + case 0: + break; + case 1: + myFileIndex += 5; + break; + default: + if (myProportional) { + double p = (myFieldsLst[0].myTiming[myFrame] - + myFieldsLst[0].myTiming[myFrame-1]) / aOneVal; + myFileIndex += (long) (5*p); + } else { + myFileIndex += 5; + } + } + + QString aFile = aDirPath + QDir::separator() + aBaseName; + aFile += "_"; + aFile += QString("%1").arg(myFileIndex).rightJustify(8, '0'); +#ifndef WNT + aFile += ".jpeg"; +#else + aFile += ".bmp"; +#endif + + /* check image size is divisable 16 + myView->dumpViewToFormat(aFile,"JPEG"); + */ + SUIT_ViewWindow* aView = myView; + QImage img = aView->dumpView(); + if (!img.isNull()) { + int width = img.width(); width = (width/16)*16; + int height = img.height(); height = (height/16)*16; + QImage copy = img.copy(0, 0, width, height); +#ifndef WNT + if (copy.save(aFile, "JPEG")) { +#else + if (copy.save(aFile, "BMP")) { +#endif + anIndexList.append(myFileIndex); + aNbFiles++; + } + } } } @@ -715,37 +732,43 @@ void VISU_TimeAnimation::run() myFrame++; if (myFrame == myFieldsLst[0].myNbFrames) { if (!myCycling) { - myIsActive = false; - myFrame--; - break; - } else - myFrame = 0; + myIsActive = false; + myFrame--; + break; + } + else + myFrame = 0; } } // make AVI file if need - if (isDumping && myDumpFormat.compare("AVI") == 0) { + if (isDumping && myDumpFormat.compare("AVI") == 0) + { double aFPS = 17.3 * mySpeed; QFileInfo aFileInfo(myDumpPath); QString aDirPath = aFileInfo.dirPath(true); QString aBaseName = aFileInfo.fileName(); +#ifndef WNT // add missing files - if (anIndexList.count() > 1) { + if (anIndexList.count() > 1) + { QString aFFile = aDirPath + QDir::separator() + aBaseName; aFFile += QString("_%1.jpeg"); int aStartIndex = anIndexList[0], anEndIndex; - for (int i = 1; i < anIndexList.count(); i++) { - anEndIndex = anIndexList[i]; - QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0')); - QStringList aCommands; - for (int j = aStartIndex+1; j < anEndIndex; j++) { - QString aFile = aFFile.arg(QString::number(j).rightJustify(8, '0')); - aCommands.append(QString("ln -s %1 %2").arg(aCurFile).arg(aFile)); - } - system(aCommands.join(" ; \\\n").latin1()); - aStartIndex = anEndIndex; + for (int i = 1; i < anIndexList.count(); i++) + { + anEndIndex = anIndexList[i]; + QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0')); + QStringList aCommands; + for (int j = aStartIndex+1; j < anEndIndex; j++) + { + QString aFile = aFFile.arg(QString::number(j).rightJustify(8, '0')); + aCommands.append(QString("ln -s %1 %2").arg(aCurFile).arg(aFile)); + } + system(aCommands.join(" ; \\\n").latin1()); + aStartIndex = anEndIndex; } } @@ -772,6 +795,114 @@ void VISU_TimeAnimation::run() aCmd += " | xargs rm"; aCmd += " )"; system(aCmd.latin1()); +#else + + //create avi file + IAVIFile *pfile; + AVIFileInit(); + HRESULT hr = AVIFileOpen( &pfile, myDumpPath.latin1(), OF_WRITE|OF_CREATE, NULL ); + if ( hr!=AVIERR_OK ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "Can't Open Avi file", 1 ); + } + + if (anIndexList.count() > 1) + { + QString aFFile = aDirPath + QDir::separator() + aBaseName; + aFFile += QString("_%1.bmp"); + int aStartIndex = anIndexList[0], anEndIndex; + + QImage anImage; + + IAVIStream *ps = 0; + IAVIStream *psCompressed = 0; + int index = 0; + + QStringList FileToDelete; + + for (int i = 1; i < anIndexList.count(); i++) + { + anEndIndex = anIndexList[i]; + QString aCurFile = aFFile.arg(QString::number(aStartIndex).rightJustify(8, '0')); + + //load current image + HBITMAP hbm=(HBITMAP)LoadImage(NULL,aCurFile.latin1(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION ); + + DIBSECTION dibs; int sbm = GetObject(hbm,sizeof(dibs),&dibs); + if ( sbm == 0 ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "BAD Param DIB", 1 ); + } + + for (int j = aStartIndex+1; j < anEndIndex; j++) + { + // if no avi stream - create it + if ( !ps ) + { + AVISTREAMINFO strhdr; ZeroMemory( &strhdr, sizeof( strhdr ) ); + strhdr.fccType = streamtypeVIDEO;// stream type + strhdr.fccHandler = 0; + strhdr.dwScale = 10; + strhdr.dwRate = 173 * mySpeed; + strhdr.dwSuggestedBufferSize = dibs.dsBmih.biSizeImage; + SetRect(&strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight); + hr=AVIFileCreateStream( pfile, &ps, &strhdr ); + if ( hr!=AVIERR_OK ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "Can't create video stream", 1 ); + break; + } + } + // if no avi compressed stream - create it + if ( !psCompressed ) + { + AVICOMPRESSOPTIONS opts; ZeroMemory( &opts, sizeof( opts ) ); + opts.fccHandler=mmioFOURCC('C','V','I','D'); + //opts.fccHandler=mmioFOURCC('M','P','4','2'); + //opts.dwQuality = -1; + hr = AVIMakeCompressedStream( &psCompressed, ps, &opts, NULL ); + if ( hr != AVIERR_OK ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "Can't create video compressed stream", 1 ); + break; + } + hr = AVIStreamSetFormat( psCompressed, 0, &dibs.dsBmih, dibs.dsBmih.biSize+dibs.dsBmih.biClrUsed*sizeof(RGBQUAD)); + if ( hr != AVIERR_OK ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "Can't set format to compressed stream", 1 ); + break; + } + } + // add image to avi stream + hr = AVIStreamWrite( psCompressed, index, 1, dibs.dsBm.bmBits, dibs.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); + if ( hr!=AVIERR_OK ) + { + AVIFileExit(); + QMessageBox::information( NULL, "INFO", "Can't add frame to stream ", 1 ); + break; + } + index++; + + } + aStartIndex = anEndIndex; + FileToDelete.append( aCurFile ); + } + + // close all streams and avi file + AVIStreamRelease( psCompressed ); + AVIStreamRelease( ps ); + AVIFileRelease( pfile ); + AVIFileExit(); + + //delete temporary pictures (bmp) + system( QDir::convertSeparators(QString( "del %1_* /f /q" ).arg( myDumpPath )).latin1() ); + } +#endif } emit stopped(); @@ -845,6 +976,7 @@ std::string VISU_TimeAnimation::setDumpFormat(const char* theFormat) //------------------------------------------------------------------------ bool VISU_TimeAnimation::checkAVIMaker() const { +#ifndef WNT QStrList aDumpFormats = QImageIO::outputFormats(); if (aDumpFormats.find("JPEG") < 0) return false; @@ -853,6 +985,9 @@ bool VISU_TimeAnimation::checkAVIMaker() const aCmd += " >& /dev/null"; int iErr = system(aCmd.latin1()); return (iErr == 0); +#else + return true; +#endif } //************************************************************************ -- 2.39.2