1 /*M///////////////////////////////////////////////////////////////////////////////////////
\r
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
\r
5 // By downloading, copying, installing or using the software you agree to this license.
\r
6 // If you do not agree to this license, do not download, install,
\r
7 // copy or use the software.
\r
10 // Intel License Agreement
\r
11 // For Open Source Computer Vision Library
\r
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
\r
14 // Third party copyrights are property of their respective owners.
\r
16 // Redistribution and use in source and binary forms, with or without modification,
\r
17 // are permitted provided that the following conditions are met:
\r
19 // * Redistribution's of source code must retain the above copyright notice,
\r
20 // this list of conditions and the following disclaimer.
\r
22 // * Redistribution's in binary form must reproduce the above copyright notice,
\r
23 // this list of conditions and the following disclaimer in the documentation
\r
24 // and/or other materials provided with the distribution.
\r
26 // * The name of Intel Corporation may not be used to endorse or promote products
\r
27 // derived from this software without specific prior written permission.
\r
29 // This software is provided by the copyright holders and contributors "as is" and
\r
30 // any express or implied warranties, including, but not limited to, the implied
\r
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
\r
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
\r
33 // indirect, incidental, special, exemplary, or consequential damages
\r
34 // (including, but not limited to, procurement of substitute goods or services;
\r
35 // loss of use, data, or profits; or business interruption) however caused
\r
36 // and on any theory of liability, whether in contract, strict liability,
\r
37 // or tort (including negligence or otherwise) arising in any way out of
\r
38 // the use of this software, even if advised of the possibility of such damage.
\r
43 // Image.cpp: implementation of the CImage class.
\r
45 //////////////////////////////////////////////////////////////////////
\r
49 #include "vlgrfmts.h"
\r
55 static char THIS_FILE[]=__FILE__;
\r
56 #define new DEBUG_NEW
\r
59 //////////////////////////////////////////////////////////////////////
\r
60 // Construction/Destruction
\r
61 //////////////////////////////////////////////////////////////////////
\r
68 void CImage::Clear()
\r
70 memset( &m_img, 0, sizeof(m_img));
\r
76 void CImage::Destroy()
\r
80 DeleteObject( SelectObject( m_memDC, m_old ));
\r
81 DeleteDC( m_memDC );
\r
92 void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp )
\r
94 assert( bmi && width > 0 && height > 0 &&
\r
95 (bpp == 8 || bpp == 24 || bpp == 32) );
\r
97 BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
\r
99 memset( bmih, 0, sizeof(*bmih));
\r
100 bmih->biSize = sizeof(BITMAPINFOHEADER);
\r
101 bmih->biWidth = width;
\r
102 bmih->biHeight = -abs(height);
\r
103 bmih->biPlanes = 1;
\r
104 bmih->biBitCount = bpp;
\r
105 bmih->biCompression = BI_RGB;
\r
109 RGBQUAD* palette = bmi->bmiColors;
\r
111 for( i = 0; i < 256; i++ )
\r
113 palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
\r
114 palette[i].rgbReserved = 0;
\r
120 bool CImage::Create( int w, int h, int bpp )
\r
122 char buffer[sizeof(BITMAPINFOHEADER) + 1024];
\r
123 BITMAPINFO* bmi = (BITMAPINFO*)buffer;
\r
125 int new_step = (w*(bpp/8) + 3) & -4;
\r
127 assert( bpp == 8 || bpp == 24 || bpp == 32 );
\r
129 if( (m_img.depth & 255)*m_img.nChannels == bpp &&
\r
130 m_img.width == w && m_img.height == h )
\r
137 m_memDC = CreateCompatibleDC(0);
\r
138 FillBitmapInfo( bmi, w, h, bpp );
\r
140 HBITMAP hbmp = CreateDIBSection( m_memDC, bmi, DIB_RGB_COLORS, &data, 0, 0 );
\r
143 DeleteDC( m_memDC );
\r
149 m_old = SelectObject( m_memDC, hbmp );
\r
151 GetObject( hbmp, sizeof(bmp), &bmp );
\r
153 /* prepare IPL header */
\r
154 memset( &m_img, 0, sizeof(m_img));
\r
155 m_img.nSize = sizeof( m_img );
\r
156 m_img.nChannels = bpp/8;
\r
157 m_img.depth = IPL_DEPTH_8U;
\r
158 strncpy( m_img.colorModel, bpp > 8 ? "RGB\0" : "GRAY", 4 );
\r
159 strncpy( m_img.channelSeq, bpp > 8 ? "BGR\0" : "GRAY", 4 );
\r
162 m_img.height = abs(h);
\r
164 m_img.widthStep = (w*(bpp/8) + 3)& -4;
\r
165 m_img.imageSize = m_img.widthStep*m_img.height;
\r
166 m_img.imageData = m_img.imageDataOrigin = (char*)bmp.bmBits;
\r
168 //iplSetBorderMode( &m_img, IPL_BORDER_REPLICATE, IPL_SIDE_ALL, 0 );
\r
174 void CImage::CopyOf( CImage& image, int desired_color )
\r
176 IplImage* img = image.GetImage();
\r
179 CopyOf( img, desired_color );
\r
183 void CImage::CopyOf( IplImage* img, int desired_color )
\r
187 int color = desired_color;
\r
188 if( color < 0 ) color = img->nChannels > 1;
\r
189 Create( iplWidth( img ), iplHeight( img ), color ? 24 : 8 );
\r
190 if( m_img.nChannels == img->nChannels )
\r
192 if( img->origin != m_img.origin )
\r
194 long OldOrg = img->origin;
\r
195 img->origin = m_img.origin;
\r
196 cvMirror( img, &m_img, 0 );
\r
197 img->origin = OldOrg;
\r
201 cvCopy( img, &m_img );
\r
208 tmp_image.Create( m_img.width, m_img.height, img->nChannels*8 );
\r
210 IplImage* tmp_img = tmp_image.GetImage();
\r
211 if( img->origin != m_img.origin )
\r
213 long OldOrg = img->origin;
\r
214 img->origin = tmp_img->origin;
\r
215 cvMirror( img, tmp_img, 0 );
\r
216 img->origin = OldOrg;
\r
220 cvCopy( img, tmp_img );
\r
224 cvCvtColor( tmp_img, &m_img, CV_GRAY2BGR );
\r
226 cvCvtColor( tmp_img, &m_img, CV_BGR2GRAY );
\r
232 static HINSTANCE hdll = 0;
\r
233 static int (__cdecl *gr_fmt_find_filter)( const char* file_name ) = 0;
\r
234 static int (__cdecl *gr_fmt_read_header)( int filter, int* width, int* height, int* color ) = 0;
\r
235 static int (__cdecl *gr_fmt_read_data)( int filter, void* data, int pitch, int color ) = 0;
\r
236 static int (__cdecl *gr_fmt_close_filter)( int filter ) = 0;
\r
237 static int (__cdecl *gr_fmt_write_image)( void* data, int pitch,
\r
238 int width, int height, int color,
\r
239 const char* filename, const char* format ) = 0;
\r
241 bool LoadGrFmtLib()
\r
243 if( hdll != 0 ) return true;
\r
245 // load image formats dll
\r
246 hdll = LoadLibrary( "vlgrfmts.dll");
\r
247 if( !hdll ) return false;
\r
249 (FARPROC&)gr_fmt_find_filter = GetProcAddress( hdll, "gr_fmt_find_filter" );
\r
250 (FARPROC&)gr_fmt_read_header = GetProcAddress( hdll, "gr_fmt_read_header" );
\r
251 (FARPROC&)gr_fmt_read_data = GetProcAddress( hdll, "gr_fmt_read_data" );
\r
252 (FARPROC&)gr_fmt_close_filter= GetProcAddress( hdll, "gr_fmt_close_filter" );
\r
253 (FARPROC&)gr_fmt_write_image = GetProcAddress( hdll, "gr_fmt_write_image" );
\r
255 if( !gr_fmt_find_filter || !gr_fmt_read_header || !gr_fmt_read_data )
\r
257 FreeLibrary( hdll );
\r
265 bool CImage::Load( const char* filename, int desired_color )
\r
268 int width = 0, height = 0;
\r
269 bool result = false;
\r
272 if( gr_fmt_find_filter == 0 ) return false;
\r
274 if( !(filter = gr_fmt_find_filter( filename ))) goto exit;
\r
275 if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit;
\r
277 color = desired_color >= 0 ? desired_color : color > 0;
\r
279 Create( width, height, color ? 24 : 8);
\r
280 if( m_memDC == 0 ) goto exit;
\r
282 result = gr_fmt_read_data( filter, m_img.imageData, m_img.widthStep, color ) != 0;
\r
284 gr_fmt_close_filter( filter );
\r
290 bool CImage::LoadRect( const char* filename,
\r
291 int desired_color, RECT r )
\r
294 int width = 0, height = 0;
\r
295 bool result = false;
\r
297 int r_width = r.right - r.left;
\r
298 int r_height = r.bottom - r.top;
\r
302 if( r_width < 0 || r_height < 0 ) return false;
\r
303 if( gr_fmt_find_filter == 0 ) return false;
\r
305 if( !(filter = gr_fmt_find_filter( filename ))) goto exit;
\r
306 if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit;
\r
308 if( r_width == 0 || r_height == 0 )
\r
314 if( (unsigned)r.left >= (unsigned)width ||
\r
315 (unsigned)r.top >= (unsigned)height ||
\r
316 (unsigned)r.right >= (unsigned)width ||
\r
317 (unsigned)r.bottom >= (unsigned)height ) goto exit;
\r
319 color = desired_color >= 0 ? desired_color : color > 0;
\r
321 Create( r_width, r_height, color ? 24 : 8);
\r
322 if( m_memDC == 0 ) goto exit;
\r
324 if( r.left == 0 && r.top == 0 &&
\r
325 (r_width == 0 || r_width == width) &&
\r
326 (r_height == 0 || r_height == height))
\r
328 tmp = m_img.imageData;
\r
329 tmp_step = m_img.widthStep;
\r
333 tmp_step = (width*m_img.nChannels + 3) & -4;
\r
334 tmp = (char*)malloc( tmp_step * height );
\r
335 if( !tmp ) goto exit;
\r
338 result = gr_fmt_read_data( filter, tmp, tmp_step, color ) != 0;
\r
340 if( result && tmp != m_img.imageData )
\r
343 for( y = 0; y < r_height; y++ )
\r
345 memcpy( m_img.imageData + y*m_img.widthStep,
\r
346 tmp + (r.top + y)*tmp_step + r.left*m_img.nChannels,
\r
347 r_width * m_img.nChannels );
\r
352 gr_fmt_close_filter( filter );
\r
353 if( tmp != 0 && tmp != m_img.imageData ) free( tmp );
\r
358 bool CImage::Save( const char* filename )
\r
360 if( !m_memDC || (m_img.nChannels != 3 && m_img.nChannels != 1) ||
\r
361 m_img.depth != IPL_DEPTH_8U ) return false;
\r
363 return gr_fmt_write_image( m_img.imageData, m_img.widthStep,
\r
364 iplWidth( &m_img ), iplHeight( &m_img ),
\r
365 m_img.nChannels == 3, filename, "BMP" ) != 0;
\r
369 IplImage* CImage::GetImage()
\r
371 return m_memDC != 0 ? &m_img : 0;
\r
375 HDC CImage::GetDC()
\r
381 void CImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
\r
383 if( m_img.width > 0 )
\r
385 uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
\r
386 BITMAPINFO* bmi = (BITMAPINFO*)buffer;
\r
387 int bmp_w = Width();
\r
388 int bmp_h = Height();
\r
390 FillBitmapInfo( bmi, bmp_w, bmp_h, m_img.nChannels*8 );
\r
392 int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
\r
393 int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
\r
395 int res = SetDIBitsToDevice(
\r
396 dc, // handle to DC
\r
397 x, // x-coord of destination upper-left corner
\r
398 y, // y-coord of destination upper-left corner
\r
399 sw, // source rectangle width
\r
400 sh, // source rectangle height
\r
401 from_x, // x-coord of source lower-left corner
\r
402 from_y, // y-coord of source lower-left corner
\r
403 from_y, // first scan line in array
\r
404 sh, // number of scan lines
\r
405 m_img.imageData + from_y*m_img.widthStep/* +
\r
406 from_x*m_img.nChannels*/, // array of DIB bits
\r
407 (BITMAPINFO*)bmi, // bitmap information
\r
408 DIB_RGB_COLORS ); // RGB or palette indexes
\r
412 void CImage::Fill( COLORREF color )
\r
416 HBRUSH br = CreateSolidBrush( color );
\r
418 GetClipBox( m_memDC, &rect );
\r
419 FillRect( m_memDC, &rect, br );
\r
420 DeleteObject( br );
\r
424 void CImage::DrawToHDC( HDC hDCDst, RECT* pDstRect )
\r
426 HDC hDCSrc = GetDC();
\r
428 if( pDstRect == NULL ) return;
\r
429 if( hDCDst == NULL ) return;
\r
430 if( hDCSrc == NULL ) return;
\r
432 if( Width() > pDstRect->right - pDstRect->left )
\r
435 hDCDst, // handle to device context
\r
441 hDCDst, // handle to device context
\r
447 pDstRect->left, pDstRect->top,
\r
448 pDstRect->right - pDstRect->left, pDstRect->bottom - pDstRect->top,
\r
450 m_img.roi ? m_img.roi->xOffset:0 ,
\r
451 m_img.roi ? m_img.roi->yOffset:0,
\r