+++ /dev/null
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-// By downloading, copying, installing or using the software you agree to this license.
-// If you do not agree to this license, do not download, install,
-// copy or use the software.
-//
-//
-// Intel License Agreement
-// For Open Source Computer Vision Library
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistribution's of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// * Redistribution's in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// * The name of Intel Corporation may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-#include "_highgui.h"
-
-#include <vfw.h>
-#if _MSC_VER >= 1200
-#pragma warning( disable: 4711 )
-#endif
-
-#if defined WIN64 && defined EM64T && defined _MSC_VER && !defined __ICL
-#pragma optimize("",off)
-#endif
-
-/********************* Capturing video from AVI via VFW ************************/
-
-static BITMAPINFOHEADER icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB )
-{
- BITMAPINFOHEADER bmih;
- memset( &bmih, 0, sizeof(bmih));
- bmih.biSize = sizeof(bmih);
- bmih.biWidth = width;
- bmih.biHeight = height;
- bmih.biBitCount = (WORD)bpp;
- bmih.biCompression = compression;
- bmih.biPlanes = 1;
-
- return bmih;
-}
-
-
-static void icvInitCapture_VFW()
-{
- static int isInitialized = 0;
- if( !isInitialized )
- {
- AVIFileInit();
- isInitialized = 1;
- }
-}
-
-
-class CvCaptureAVI_VFW : public CvCapture
-{
-public:
- CvCaptureAVI_VFW()
- {
- init();
- }
-
- virtual ~CvCaptureAVI_VFW()
- {
- close();
- }
-
- virtual bool open( const char* filename );
- virtual void close();
-
- virtual double getProperty(int);
- virtual bool setProperty(int, double);
- virtual bool grabFrame();
- virtual IplImage* retrieveFrame();
-
-protected:
- void init();
-
- PAVIFILE avifile;
- PAVISTREAM avistream;
- PGETFRAME getframe;
- AVISTREAMINFO aviinfo;
- BITMAPINFOHEADER * bmih;
- CvSlice film_range;
- double fps;
- int pos;
- int data_offset;
- IplImage* frame;
- CvSize size;
-};
-
-
-void CvCaptureAVI_VFW::init()
-{
- avifile = 0;
- avistream = 0;
- getframe = 0;
- memset( &aviinfo, 0, sizeof(aviinfo) );
- bmih = 0;
- film_range = cvSlice(0,0);
- fps = 0;
- pos = 0;
- data_offset = 0;
- frame = 0;
- size = cvSize(0,0);
-}
-
-
-void CvCaptureAVI_VFW::close()
-{
- if( getframe )
- AVIStreamGetFrameClose( getframe );
-
- if( avistream )
- AVIStreamRelease( avistream );
-
- if( avifile )
- AVIFileRelease( avifile );
-
- cvReleaseImage( &frame );
- init();
-}
-
-
-bool CvCaptureAVI_VFW::open( const char* filename )
-{
- close();
- icvInitCapture_VFW();
-
- if( !filename )
- return false;
-
- HRESULT hr = AVIFileOpen( &avifile, filename, OF_READ, NULL );
- if( SUCCEEDED(hr))
- {
- hr = AVIFileGetStream( avifile, &avistream, streamtypeVIDEO, 0 );
- if( SUCCEEDED(hr))
- {
- hr = AVIStreamInfo( avistream, &aviinfo, sizeof(aviinfo));
- if( SUCCEEDED(hr))
- {
- //int fcc = aviinfo.fccHandler;
- data_offset = 0;
- size.width = aviinfo.rcFrame.right - aviinfo.rcFrame.left;
- size.height = aviinfo.rcFrame.bottom - aviinfo.rcFrame.top;
- BITMAPINFOHEADER bmih = icvBitmapHeader( size.width, size.height, 24 );
-
- film_range.start_index = (int)aviinfo.dwStart;
- film_range.end_index = film_range.start_index + (int)aviinfo.dwLength;
- fps = (double)aviinfo.dwRate/aviinfo.dwScale;
- pos = film_range.start_index;
- getframe = AVIStreamGetFrameOpen( avistream, &bmih );
- if( getframe != 0 )
- return true;
- }
- }
- }
-
- close();
- return false;
-}
-
-bool CvCaptureAVI_VFW::grabFrame()
-{
- if( avistream )
- bmih = (BITMAPINFOHEADER*)AVIStreamGetFrame( getframe, pos++ );
- return bmih != 0;
-}
-
-IplImage* CvCaptureAVI_VFW::retrieveFrame()
-{
- if( avistream && bmih )
- {
- IplImage src;
- cvInitImageHeader( &src, cvSize( bmih->biWidth, bmih->biHeight ),
- IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
- cvSetData( &src, (char*)(bmih + 1) + data_offset, src.widthStep );
- if( !frame || frame->width != src.width || frame->height != src.height )
- {
- cvReleaseImage( &frame );
- frame = cvCreateImage( cvGetSize(&src), 8, 3 );
- }
-
- cvFlip( &src, frame, 0 );
- return frame;
- }
-
- return 0;
-}
-
-double CvCaptureAVI_VFW::getProperty( int property_id )
-{
- switch( property_id )
- {
- case CV_CAP_PROP_POS_MSEC:
- return cvRound(pos*1000./fps);
- case CV_CAP_PROP_POS_FRAMES:
- return pos;
- case CV_CAP_PROP_POS_AVI_RATIO:
- return (pos - film_range.start_index)/
- (film_range.end_index - film_range.start_index + 1e-10);
- case CV_CAP_PROP_FRAME_WIDTH:
- return size.width;
- case CV_CAP_PROP_FRAME_HEIGHT:
- return size.height;
- case CV_CAP_PROP_FPS:
- return fps;
- case CV_CAP_PROP_FOURCC:
- return aviinfo.fccHandler;
- case CV_CAP_PROP_FRAME_COUNT:
- return film_range.end_index - film_range.start_index;
- }
- return 0;
-}
-
-bool CvCaptureAVI_VFW::setProperty( int property_id, double value )
-{
- switch( property_id )
- {
- case CV_CAP_PROP_POS_MSEC:
- case CV_CAP_PROP_POS_FRAMES:
- case CV_CAP_PROP_POS_AVI_RATIO:
- {
- switch( property_id )
- {
- case CV_CAP_PROP_POS_MSEC:
- pos = cvRound(value*fps*0.001);
- break;
- case CV_CAP_PROP_POS_AVI_RATIO:
- pos = cvRound(value*(film_range.end_index -
- film_range.start_index) +
- film_range.start_index);
- break;
- default:
- pos = cvRound(value);
- }
- if( pos < film_range.start_index )
- pos = film_range.start_index;
- if( pos > film_range.end_index )
- pos = film_range.end_index;
- }
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-CvCapture* cvCreateFileCapture_VFW (const char* filename)
-{
- CvCaptureAVI_VFW* capture = new CvCaptureAVI_VFW;
- if( capture->open(filename) )
- return capture;
- delete capture;
- return 0;
-}
-
-
-/********************* Capturing video from camera via VFW *********************/
-
-class CvCaptureCAM_VFW : public CvCapture
-{
-public:
- CvCaptureCAM_VFW() { init(); }
- virtual ~CvCaptureCAM_VFW() { close(); }
-
- virtual bool open( int index );
- virtual void close();
- virtual double getProperty(int);
- virtual bool setProperty(int, double) { return false; }
- virtual bool grabFrame();
- virtual IplImage* retrieveFrame();
-
-protected:
- void init();
- void closeHIC();
- static LRESULT PASCAL frameCallback( HWND hWnd, VIDEOHDR* hdr );
-
- CAPDRIVERCAPS caps;
- HWND capWnd;
- VIDEOHDR* hdr;
- DWORD fourcc;
- HIC hic;
- IplImage* frame;
-};
-
-
-void CvCaptureCAM_VFW::init()
-{
- memset( &caps, 0, sizeof(caps) );
- capWnd = 0;
- hdr = 0;
- fourcc = 0;
- hic = 0;
- frame = 0;
-}
-
-void CvCaptureCAM_VFW::closeHIC()
-{
- if( hic )
- {
- ICDecompressEnd( hic );
- ICClose( hic );
- hic = 0;
- }
-}
-
-
-LRESULT PASCAL CvCaptureCAM_VFW::frameCallback( HWND hWnd, VIDEOHDR* hdr )
-{
- CvCaptureCAM_VFW* capture = 0;
-
- if (!hWnd) return FALSE;
-
- capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd);
- capture->hdr = hdr;
-
- return (LRESULT)TRUE;
-}
-
-
-// Initialize camera input
-bool CvCaptureCAM_VFW::open( int wIndex )
-{
- char szDeviceName[80];
- char szDeviceVersion[80];
- HWND hWndC = 0;
-
- close();
-
- if( (unsigned)wIndex >= 10 )
- wIndex = 0;
-
- for( ; wIndex < 10; wIndex++ )
- {
- if( capGetDriverDescription( wIndex, szDeviceName,
- sizeof (szDeviceName), szDeviceVersion,
- sizeof (szDeviceVersion)))
- {
- hWndC = capCreateCaptureWindow ( "My Own Capture Window",
- WS_POPUP | WS_CHILD, 0, 0, 320, 240, 0, 0);
- if( capDriverConnect (hWndC, wIndex))
- break;
- DestroyWindow( hWndC );
- hWndC = 0;
- }
- }
-
- if( hWndC )
- {
- capWnd = hWndC;
- hdr = 0;
- hic = 0;
- fourcc = (DWORD)-1;
-
- memset( &caps, 0, sizeof(caps));
- capDriverGetCaps( hWndC, &caps, sizeof(&caps));
- ::MoveWindow( hWndC, 0, 0, 320, 240, TRUE );
- capSetUserData( hWndC, (size_t)this );
- capSetCallbackOnFrame( hWndC, frameCallback );
- CAPTUREPARMS p;
- capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
- p.dwRequestMicroSecPerFrame = 66667/2;
- capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
- //capPreview( hWndC, 1 );
- capPreviewScale(hWndC,FALSE);
- capPreviewRate(hWndC,1);
- }
- return capWnd != 0;
-}
-
-
-void CvCaptureCAM_VFW::close()
-{
- if( capWnd )
- {
- capSetCallbackOnFrame( capWnd, NULL );
- capDriverDisconnect( capWnd );
- DestroyWindow( capWnd );
- closeHIC();
- }
- cvReleaseImage( &frame );
- init();
-}
-
-
-bool CvCaptureCAM_VFW::grabFrame()
-{
- if( capWnd )
- {
- SendMessage( capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
- return true;
- }
- return false;
-}
-
-
-IplImage* CvCaptureCAM_VFW::retrieveFrame()
-{
- BITMAPINFO vfmt;
- memset( &vfmt, 0, sizeof(vfmt));
- BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
- int sz, prevWidth, prevHeight;
-
- if( !capWnd )
- return 0;
-
- sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt));
- prevWidth = frame ? frame->width : 0;
- prevHeight = frame ? frame->height : 0;
-
- if( !hdr || hdr->lpData == 0 || sz == 0 )
- return 0;
-
- if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight )
- {
- cvReleaseImage( &frame );
- frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 );
- }
-
- if( vfmt.bmiHeader.biCompression != BI_RGB ||
- vfmt.bmiHeader.biBitCount != 24 )
- {
- BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
-
- if( hic == 0 || fourcc != vfmt0.biCompression ||
- prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight )
- {
- closeHIC();
- hic = ICOpen( MAKEFOURCC('V','I','D','C'),
- vfmt0.biCompression, ICMODE_DECOMPRESS );
- if( hic )
- {
- if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK )
- {
- closeHIC();
- return 0;
- }
- }
- }
-
- if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData,
- &vfmt1, frame->imageData ) != ICERR_OK )
- {
- closeHIC();
- return 0;
- }
-
- cvFlip( frame, frame, 0 );
- }
- else
- {
- IplImage src;
- cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight),
- IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
- cvSetData( &src, hdr->lpData, src.widthStep );
- cvFlip( &src, frame, 0 );
- }
-
- return frame;
-}
-
-
-double CvCaptureCAM_VFW::getProperty( int property_id )
-{
- switch( property_id )
- {
- case CV_CAP_PROP_FRAME_WIDTH:
- return frame ? frame->width : 0;
- case CV_CAP_PROP_FRAME_HEIGHT:
- return frame ? frame->height : 0;
- case CV_CAP_PROP_FOURCC:
- return fourcc;
- }
- return 0;
-}
-
-
-CvCapture* cvCreateCameraCapture_VFW( int index )
-{
- CvCaptureCAM_VFW* capture = new CvCaptureCAM_VFW;
-
- if( capture->open( index ))
- return capture;
-
- delete capture;
- return 0;
-}
-
-
-/*************************** writing AVIs ******************************/
-
-class CvVideoWriter_VFW : public CvVideoWriter
-{
-public:
- CvVideoWriter_VFW() { init(); }
- virtual ~CvVideoWriter_VFW() { close(); }
-
- virtual bool open( const char* filename, int fourcc,
- double fps, CvSize frameSize, bool isColor );
- virtual void close();
- virtual bool writeFrame( const IplImage* );
-
-protected:
- void init();
- bool createStreams( CvSize frameSize, bool isColor );
-
- PAVIFILE avifile;
- PAVISTREAM compressed;
- PAVISTREAM uncompressed;
- double fps;
- IplImage* tempFrame;
- long pos;
- int fourcc;
-};
-
-
-void CvVideoWriter_VFW::init()
-{
- avifile = 0;
- compressed = uncompressed = 0;
- fps = 0;
- tempFrame = 0;
- pos = 0;
- fourcc = 0;
-}
-
-void CvVideoWriter_VFW::close()
-{
- if( uncompressed )
- AVIStreamRelease( uncompressed );
- if( compressed )
- AVIStreamRelease( compressed );
- if( avifile )
- AVIFileRelease( avifile );
- cvReleaseImage( &tempFrame );
- init();
-}
-
-
-// philipg. Made this code capable of writing 8bpp gray scale bitmaps
-struct BITMAPINFO_8Bit
-{
- BITMAPINFOHEADER bmiHeader;
- RGBQUAD bmiColors[256];
-};
-
-
-bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, CvSize frameSize, bool isColor )
-{
- close();
-
- icvInitCapture_VFW();
- if( AVIFileOpen( &avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK )
- {
- fourcc = _fourcc;
- fps = _fps;
- if( frameSize.width > 0 && frameSize.height > 0 &&
- !createStreams( frameSize, isColor ) )
- {
- close();
- return false;
- }
- }
- return true;
-}
-
-
-bool CvVideoWriter_VFW::createStreams( CvSize frameSize, bool isColor )
-{
- if( !avifile )
- return false;
- AVISTREAMINFO aviinfo;
-
- BITMAPINFO_8Bit bmih;
- bmih.bmiHeader = icvBitmapHeader( frameSize.width, frameSize.height, isColor ? 24 : 8 );
- for( int i = 0; i < 256; i++ )
- {
- bmih.bmiColors[i].rgbBlue = (BYTE)i;
- bmih.bmiColors[i].rgbGreen = (BYTE)i;
- bmih.bmiColors[i].rgbRed = (BYTE)i;
- bmih.bmiColors[i].rgbReserved = 0;
- }
-
- memset( &aviinfo, 0, sizeof(aviinfo));
- aviinfo.fccType = streamtypeVIDEO;
- aviinfo.fccHandler = 0;
- // use highest possible accuracy for dwRate/dwScale
- aviinfo.dwScale = (DWORD)((double)0x7FFFFFFF / fps);
- aviinfo.dwRate = cvRound(fps * aviinfo.dwScale);
- aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0;
- aviinfo.rcFrame.right = frameSize.width;
- aviinfo.rcFrame.bottom = frameSize.height;
-
- if( AVIFileCreateStream( avifile, &uncompressed, &aviinfo ) == AVIERR_OK )
- {
- AVICOMPRESSOPTIONS copts, *pcopts = &copts;
- copts.fccType = streamtypeVIDEO;
- copts.fccHandler = fourcc != -1 ? fourcc : 0;
- copts.dwKeyFrameEvery = 1;
- copts.dwQuality = (DWORD)-1;
- copts.dwBytesPerSecond = 0;
- copts.dwFlags = AVICOMPRESSF_VALID;
- copts.lpFormat = &bmih;
- copts.cbFormat = (isColor ? sizeof(BITMAPINFOHEADER) : sizeof(bmih));
- copts.lpParms = 0;
- copts.cbParms = 0;
- copts.dwInterleaveEvery = 0;
-
- if( fourcc != -1 || AVISaveOptions( 0, 0, 1, &uncompressed, &pcopts ) == TRUE )
- {
- if( AVIMakeCompressedStream( &compressed, uncompressed, pcopts, 0 ) == AVIERR_OK &&
- AVIStreamSetFormat( compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK )
- {
- fps = fps;
- fourcc = (int)copts.fccHandler;
- frameSize = frameSize;
- tempFrame = cvCreateImage( frameSize, 8, (isColor ? 3 : 1) );
- return true;
- }
- }
- }
- return false;
-}
-
-
-bool CvVideoWriter_VFW::writeFrame( const IplImage* image )
-{
- bool result = false;
- CV_FUNCNAME( "CvVideoWriter_VFW::writeFrame" );
-
- __BEGIN__;
-
- if( !image )
- EXIT;
-
- if( !compressed && !createStreams( cvGetSize(image), image->nChannels > 1 ))
- EXIT;
-
- if( image->width != tempFrame->width || image->height != tempFrame->height )
- CV_ERROR( CV_StsUnmatchedSizes,
- "image size is different from the currently set frame size" );
-
- if( image->nChannels != tempFrame->nChannels ||
- image->depth != tempFrame->depth ||
- image->origin == 0 ||
- image->widthStep != cvAlign(image->width*image->nChannels*((image->depth & 255)/8), 4))
- {
- cvConvertImage( image, tempFrame, image->origin == 0 ? CV_CVTIMG_FLIP : 0 );
- image = (const IplImage*)tempFrame;
- }
-
- result = AVIStreamWrite( compressed, pos++, 1, image->imageData,
- image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK;
-
- __END__;
-
- return result;
-}
-
-CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc,
- double fps, CvSize frameSize, int isColor )
-{
- CvVideoWriter_VFW* writer = new CvVideoWriter_VFW;
- if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))
- return writer;
- delete writer;
- return 0;
-}