Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

253 lines
7.6 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkAVIWriter.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkWindows.h"
#include "vtkAVIWriter.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#ifdef _MSC_VER
#pragma warning (push, 3)
#endif
#include <vfw.h>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
class vtkAVIWriterInternal
{
public:
PAVISTREAM Stream;
PAVISTREAM StreamCompressed;
PAVIFILE AVIFile;
LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER
HANDLE hDIB; // handle to DIB, temp handle
};
//---------------------------------------------------------------------------
vtkStandardNewMacro(vtkAVIWriter);
vtkCxxRevisionMacro(vtkAVIWriter, "$Revision: 1.3 $");
//---------------------------------------------------------------------------
vtkAVIWriter::vtkAVIWriter()
{
this->Internals = new vtkAVIWriterInternal;
this->Internals->Stream = NULL;
this->Internals->StreamCompressed = NULL;
this->Internals->AVIFile = NULL;
this->Time = 0;
this->Rate = 15;
this->Internals->hDIB = NULL; // handle to DIB, temp handle
}
//---------------------------------------------------------------------------
vtkAVIWriter::~vtkAVIWriter()
{
if (this->Internals->AVIFile)
{
this->End();
}
delete this->Internals;
}
//---------------------------------------------------------------------------
void vtkAVIWriter::Start()
{
// Error checking
this->Error = 1;
if ( this->GetInput() == NULL )
{
vtkErrorMacro(<<"Write:Please specify an input!");
return;
}
if (!this->FileName)
{
vtkErrorMacro(<<"Write:Please specify a FileName");
return;
}
// Fill in image information.
this->GetInput()->UpdateInformation();
int *wExtent = this->GetInput()->GetWholeExtent();
this->GetInput()->SetUpdateExtent(wExtent);
LONG hr;
AVISTREAMINFO strhdr;
AVIFileInit();
// opens AVIFile library
hr = AVIFileOpen(&this->Internals->AVIFile, this->FileName,
OF_WRITE | OF_CREATE, 0L);
if (hr != 0)
{
vtkErrorMacro("Unable to open " << this->FileName);
return;
}
// Fill in the header for the video stream....
// The video stream will run in 15ths of a second....
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = this->Rate;
strhdr.dwQuality = (DWORD) -1;
strhdr.dwSuggestedBufferSize = (wExtent[1] - wExtent[0] + 1)*
(wExtent[3] - wExtent[2] + 1)*3;
SetRect(&strhdr.rcFrame, 0, 0, wExtent[1] - wExtent[0] + 1,
wExtent[3] - wExtent[2] + 1);
// And create the stream;
AVIFileCreateStream(this->Internals->AVIFile, // file pointer
&this->Internals->Stream, // returned stream pointer
&strhdr); // stream header
// do not want to display this dialog
AVICOMPRESSOPTIONS opts;
// AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
memset(&opts, 0, sizeof(opts));
// need to setup opts
opts.fccType = 0;
opts.fccHandler=mmioFOURCC('m','s','v','c');
opts.dwQuality = 10000;
opts.dwBytesPerSecond = 0;
opts.dwFlags = 8;
// if (!AVISaveOptions(NULL, 0,
// 1, &this->Internals->Stream,
// (LPAVICOMPRESSOPTIONS FAR *) &aopts))
// {
// vtkErrorMacro("Unable to save " << this->FileName);
// return;
// }
if (AVIMakeCompressedStream(&this->Internals->StreamCompressed,
this->Internals->Stream,
&opts, NULL) != AVIERR_OK)
{
vtkErrorMacro("Unable to compress " << this->FileName);
return;
}
DWORD dwLen; // size of memory block
int dataWidth = (((wExtent[1] - wExtent[0] + 1)*3+3)/4)*4;
dwLen = sizeof(BITMAPINFOHEADER) + dataWidth*(wExtent[3] - wExtent[2] + 1);
this->Internals->hDIB = ::GlobalAlloc(GHND, dwLen);
this->Internals->lpbi = (LPBITMAPINFOHEADER) ::GlobalLock(this->Internals->hDIB);
this->Internals->lpbi->biSize = sizeof(BITMAPINFOHEADER);
this->Internals->lpbi->biWidth = wExtent[1] - wExtent[0] + 1;
this->Internals->lpbi->biHeight = wExtent[3] - wExtent[2] + 1;
this->Internals->lpbi->biPlanes = 1;
this->Internals->lpbi->biBitCount = 24;
this->Internals->lpbi->biCompression = BI_RGB;
this->Internals->lpbi->biClrUsed = 0;
this->Internals->lpbi->biClrImportant = 0;
this->Internals->lpbi->biSizeImage = dataWidth*(wExtent[3] - wExtent[2] + 1);
if (AVIStreamSetFormat(this->Internals->StreamCompressed, 0,
this->Internals->lpbi, this->Internals->lpbi->biSize))
{
vtkErrorMacro("Unable to format " << this->FileName << " Most likely this means that the video compression scheme you seleted could not handle the data. Try selecting a different compression scheme." );
return;
}
this->Error = 0;
this->Time = 0;
}
//---------------------------------------------------------------------------
void vtkAVIWriter::Write()
{
if (this->Error)
{
return;
}
// get the data
this->GetInput()->UpdateInformation();
int *wExtent = this->GetInput()->GetWholeExtent();
this->GetInput()->SetUpdateExtent(wExtent);
this->GetInput()->Update();
// get the pointer to the data
unsigned char *ptr =
(unsigned char *)(this->GetInput()->GetScalarPointer());
int dataWidth = (((wExtent[1] - wExtent[0] + 1)*3+3)/4)*4;
int srcWidth = (wExtent[1] - wExtent[0] + 1)*3;
// copy the data to the clipboard
unsigned char *dest
= (unsigned char *)this->Internals->lpbi + this->Internals->lpbi->biSize;
int i,j;
for (i = 0; i < this->Internals->lpbi->biHeight; i++)
{
for (j = 0; j < this->Internals->lpbi->biWidth; j++)
{
*dest++ = ptr[2];
*dest++ = ptr[1];
*dest++ = *ptr;
ptr += 3;
}
dest = dest + (dataWidth - srcWidth);
}
AVIStreamWrite(this->Internals->StreamCompressed, // stream pointer
this->Time, // time of this frame
1, // number to write
(LPBYTE) this->Internals->lpbi + // pointer to data
this->Internals->lpbi->biSize,
this->Internals->lpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL, NULL);
this->Time++;
}
//---------------------------------------------------------------------------
void vtkAVIWriter::End()
{
::GlobalUnlock(this->Internals->hDIB);
if (this->Internals->Stream)
{
AVIStreamClose(this->Internals->Stream);
this->Internals->Stream = NULL;
}
if (this->Internals->StreamCompressed)
{
AVIStreamClose(this->Internals->StreamCompressed);
this->Internals->StreamCompressed = NULL;
}
if (this->Internals->AVIFile)
{
AVIFileClose(this->Internals->AVIFile);
this->Internals->AVIFile = NULL;
}
AVIFileExit(); // releases AVIFile library
}
//---------------------------------------------------------------------------
void vtkAVIWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}