]> SALOME platform Git repositories - modules/visu.git/commitdiff
Salome HOME
Add possibility to create *.AVi file on WNT platfrom with help of native WinAPI tools.
authorabd <abd@opencascade.com>
Fri, 4 Aug 2006 04:53:31 +0000 (04:53 +0000)
committerabd <abd@opencascade.com>
Fri, 4 Aug 2006 04:53:31 +0000 (04:53 +0000)
Using Microsoft Video 1 Codec for compress video files

src/VISU_I/VISU_TimeAnimation.cxx

index b337e3ada5c446474d6bd7cef5ab5a41c5666690..dfe9ff1e53e45eaeea870fa4e2f11dc7729f6775 100644 (file)
 
 #include "VISU_TimeAnimation.h"
 
+#ifdef WNT
+#include <windows.h>
+#include <vfw.h>
+#include <qmessagebox.h>
+#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
 }
 
 //************************************************************************