Move the sources to trunk
[opencv] / apps / Common / Camera.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/// Camera.cpp: implementation of the CCamera class.
41 //
42 //////////////////////////////////////////////////////////////////////
43
44 #include "stdafx.h"
45 #include "Camera.h"
46 #include <assert.h>
47
48 #ifdef _DEBUG
49 #undef THIS_FILE
50 static char THIS_FILE[]=__FILE__;
51 #define new DEBUG_NEW
52 #endif
53
54 //////////////////////////////////////////////////////////////////////
55 // Construction/Destruction
56 //////////////////////////////////////////////////////////////////////
57
58 CCamera::CCamera()
59 {
60     m_capWnd = 0;
61     m_isRunning = false;
62     m_hic = 0;
63     m_fourcc = -1;
64 }
65
66 CCamera::~CCamera()
67 {
68     Uninitialize();
69 }
70
71
72 void CCamera::UpdateParent( bool whole )
73 {
74     HWND parent = GetParent( m_capWnd );
75     RECT r = { 0, 0, 0, 0 };
76     IplImage* img = m_frame.GetImage();
77
78     if( img )
79     {
80         r.right = img->width;
81         r.bottom = img->height;
82     }
83     
84     InvalidateRect( parent, whole ? 0 : &r, whole );
85     UpdateWindow( parent );
86 }
87
88
89 // Frame callback
90 LRESULT PASCAL FrameCallbackProc( HWND hWnd, VIDEOHDR* hdr ) 
91
92     BITMAPINFO vfmt;
93     CCamera* camera = (CCamera*)capGetUserData(hWnd);
94     int sz;
95
96     if (!hWnd) return FALSE;
97         if (camera && !camera->IsRunning() ) return FALSE;
98         
99     sz = capGetVideoFormat( hWnd, &vfmt, sizeof(vfmt));
100     
101     if( hdr && hdr->lpData && sz != 0 && camera )
102         camera->PutCompressedFrame( hdr, &vfmt );
103
104     return (LRESULT)TRUE; 
105 }
106
107
108 void CCamera::OnFrame()
109 {
110     UpdateParent(0);
111 }
112
113 void CCamera::PutCompressedFrame( VIDEOHDR* hdr, BITMAPINFO* vfmt )
114 {
115     long code = ICERR_OK;
116     char* frame_data = (char*)hdr->lpData;
117         
118     if( vfmt->bmiHeader.biCompression != BI_RGB ||
119         vfmt->bmiHeader.biBitCount != 24 )
120     {
121         BITMAPINFOHEADER& vfmt0 = vfmt->bmiHeader;
122         BITMAPINFOHEADER vfmt1;
123         code = ICERR_ERROR;
124
125         memset( &vfmt1, 0, sizeof(vfmt1));
126         vfmt1.biSize = sizeof(vfmt1);
127         vfmt1.biWidth = vfmt0.biWidth;
128         vfmt1.biHeight = vfmt0.biHeight;
129         vfmt1.biBitCount = 24;
130         vfmt1.biCompression = BI_RGB;
131         vfmt1.biPlanes = 1;
132
133         if( m_hic == 0 || m_fourcc != vfmt0.biCompression || m_frame.GetImage() == 0 ||
134             vfmt0.biWidth != m_frame.GetImage()->width ||
135             vfmt0.biHeight != m_frame.GetImage()->height )
136         {
137             if( m_hic )
138             {
139                 ICDecompressEnd( m_hic );
140                 ICClose( m_hic );
141             }
142             m_hic = ICOpen( MAKEFOURCC('V','I','D','C'),
143                           vfmt0.biCompression, ICMODE_DECOMPRESS );
144
145             if( m_hic && ICDecompressBegin( m_hic, &vfmt0, &vfmt1 ) == ICERR_OK )
146             {
147                 m_frame.Create( vfmt0.biWidth, vfmt0.biHeight, 24 );
148                 m_frame.GetImage()->origin = IPL_ORIGIN_BL;
149
150                 code = ICDecompress( m_hic, 0, &vfmt0, hdr->lpData,
151                                      &vfmt1, m_frame.GetImage()->imageData );
152             }
153         }
154     }
155     else
156     {
157         m_frame.Create( vfmt->bmiHeader.biWidth, vfmt->bmiHeader.biHeight, 24 );
158         memcpy( m_frame.GetImage()->imageData, hdr->lpData, m_frame.GetImage()->imageSize );
159     }
160
161     /*m_frame.GetImage()->origin = IPL_ORIGIN_BL;*/
162     cvFlip( m_frame.GetImage(), m_frame.GetImage(), 0 );
163
164     OnFrame();
165
166
167
168 // Initialize camera input
169 bool  CCamera::Initialize( int width, int height, int format, HWND parent, int wIndex )
170 {
171     char szDeviceName[80];
172     char szDeviceVersion[80];
173     HWND hWndC = 0;
174     
175     if( (unsigned)wIndex < 10 )
176         goto init_camera;
177
178     for( wIndex = 0; wIndex < 10; wIndex++ ) 
179     {
180 init_camera:        
181         if( capGetDriverDescription( wIndex, szDeviceName, 
182             sizeof (szDeviceName), szDeviceVersion, 
183             sizeof (szDeviceVersion))) 
184         {
185             hWndC = capCreateCaptureWindow ( "My Own Capture Window", 
186                   WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, parent, 0);
187
188             if( capDriverConnect (hWndC, wIndex))
189             {
190                 /*BITMAPINFO bmi;
191  
192                 //capPreviewRate(hWndC, 66);  // rate, in milliseconds
193                 memset( &bmi.bmiHeader, 0, sizeof(bmi.bmiHeader));
194                 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
195                 bmi.bmiHeader.biBitCount = format == 0 ? 24 : 12;
196                 bmi.bmiHeader.biWidth = width;
197                 bmi.bmiHeader.biHeight = height;
198                 bmi.bmiHeader.biPlanes = 1;
199                 bmi.bmiHeader.biCompression = format;
200                 bmi.bmiHeader.biSizeImage = ((bmi.bmiHeader.biWidth*
201                                               bmi.bmiHeader.biBitCount/8 + 3)&-4)*
202                                               bmi.bmiHeader.biHeight;
203                 if( format == -1 || capSetVideoFormat( hWndC, &bmi, sizeof(bmi)-4)) break;
204                 capDriverDisconnect( hWndC );*/
205                 break;
206             }
207             DestroyWindow( hWndC );
208             hWndC = 0;
209         }
210     }
211     
212     if( hWndC )
213     {
214         m_capWnd = hWndC;
215         
216         memset( &m_caps, 0, sizeof(m_caps));
217         capDriverGetCaps( hWndC, &m_caps, sizeof(m_caps));
218         capSetUserData( hWndC, (long)this );
219         capSetCallbackOnFrame( m_capWnd, FrameCallbackProc ); 
220         ::MoveWindow( m_capWnd, 0, 0, 1, 1, TRUE );
221         CAPTUREPARMS p;
222         capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
223         p.dwRequestMicroSecPerFrame = 1;
224         capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
225         capPreviewScale(hWndC,FALSE);
226         capPreviewRate(hWndC,1);
227     }
228     return m_capWnd != 0;
229 }
230
231
232 // Uninitialize camera input
233 void  CCamera::Uninitialize()
234 {
235     Stop();
236     capSetCallbackOnFrame( m_capWnd, NULL ); 
237     capDriverDisconnect( m_capWnd );
238     DestroyWindow( m_capWnd );
239
240     if( m_hic )
241     {
242         ICDecompressEnd( m_hic );
243         ICClose( m_hic );
244         m_hic = 0;
245     }
246 }
247
248 // Start capture
249 void  CCamera::Start()
250 {
251     if( m_capWnd )
252     {
253         m_isRunning = true;
254     }
255 }
256
257 // Stop capture
258 void  CCamera::Stop()
259 {
260     if( m_capWnd )
261     {
262         m_isRunning = false;
263     }
264 }
265
266
267 void  CCamera::VideoFormatDlg()
268 {
269     if( m_capWnd && m_caps.fHasDlgVideoFormat )
270     {
271         capDlgVideoFormat( m_capWnd );
272     }
273 }
274
275
276 void  CCamera::VideoSourceDlg()
277 {
278     if( m_capWnd && m_caps.fHasDlgVideoSource )
279     {
280         capDlgVideoSource( m_capWnd );
281     }
282 }