1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
43 // Loading and saving IPL images.
50 /****************************************************************************************\
51 * Path class (list of search folders) *
52 \****************************************************************************************/
60 // preprocess folder or file name - calculate its length,
61 // check for invalid symbols in the name and substitute
62 // all backslashes with simple slashes.
63 // the result is put into the specified buffer
64 static int Preprocess( const char* filename, char* buffer );
66 // add folder to the path
67 bool Add( const char* path );
72 // return the path - string, where folders are separated by ';'
73 const char* Get() const { return m_path; };
75 // find the file in the path
76 const char* Find( const char* filename, char* buffer ) const;
78 // return the first folder from the path
79 // the returned string is not terminated by '\0'!!!
80 // its length is returned via len parameter
81 const char* First( int& len ) const;
83 // return the folder, next in the path after the specified folder.
84 // see also note to First() method
85 const char* Next( const char* folder, int& len ) const;
95 void CvFilePath::Clear()
98 m_maxsize = m_len = 0;
102 CvFilePath::CvFilePath()
105 m_maxsize = m_len = 0;
109 CvFilePath::~CvFilePath()
115 bool CvFilePath::Add( const char* path )
117 char buffer[_MAX_PATH + 1];
118 int len = Preprocess( path, buffer );
123 if( m_len + len + 3 // +1 for one more ';',
124 // another +1 for possible additional '/',
125 // and the last +1 is for '\0'
128 int new_size = (m_len + len + 3 + 1023) & -1024;
129 char* new_path = new char[new_size];
133 memcpy( new_path, m_path, m_len );
138 m_maxsize = new_size;
141 m_path[m_len++] = ';';
142 memcpy( m_path + m_len, buffer, len );
145 if( m_path[m_len] != '/' )
146 m_path[m_len++] = '/';
148 m_path[m_len] = '\0'; // '\0' is not counted in m_len.
154 const char* CvFilePath::First( int& len ) const
156 const char* path = (const char*)(m_path ? m_path : "");
157 const char* path_end = path;
159 while( *path_end && *path_end != ';' )
162 len = path_end - path;
167 const char* CvFilePath::Next( const char* folder, int& len ) const
169 if( !folder || folder < m_path || folder >= m_path + m_len )
172 folder = strchr( folder, ';' );
175 const char* folder_end = ++folder;
176 while( *folder_end && *folder_end != ';' )
179 len = folder_end - folder;
186 const char* CvFilePath::Find( const char* filename, char* buffer ) const
188 char path0[_MAX_PATH + 1];
189 int len = Preprocess( filename, path0 );
191 const char* folder = First( folder_len );
201 if( folder_len + len <= _MAX_PATH )
203 memcpy( buffer, folder, folder_len );
204 strcpy( buffer + folder_len, name );
206 f = fopen( buffer, "rb" );
211 if( name != name_only )
213 name_only = strrchr( path0, '/' );
218 len = strlen( name_only );
222 while( (folder = Next( folder, folder_len )) != 0 );
228 filename = (const char*)buffer;
236 int CvFilePath::Preprocess( const char* str, char* buffer )
240 if( !str || !buffer )
243 for( i = 0; i <= _MAX_PATH; i++ )
247 if( isalnum(str[i])) // fast check to skip most of characters
253 if( str[i] == '\\' ) // convert back slashes to simple slashes
254 // (for Win32-*NIX compatibility)
257 if (str[i] == '*' || str[i] == '?' || str[i] == '\"' ||
258 str[i] == '>' || str[i] == '<' ||
259 str[i] == ';' || /* used as a separator in the path */
261 str[i] == ',' || str[i] == '%' ||
267 return i <= _MAX_PATH ? i : -1;
271 /****************************************************************************************\
272 * Image Readers & Writers Class *
273 \****************************************************************************************/
282 GrFmtReader* FindReader( const char* filename ) const;
283 GrFmtWriter* FindWriter( const char* filename ) const;
285 //const CvFilePath& Path() const { return (const CvFilePath&)m_path; };
286 //CvFilePath& Path() { return m_path; };
290 GrFmtFactoriesList* m_factories;
294 CvImageFilters::CvImageFilters()
296 m_factories = new GrFmtFactoriesList;
299 m_factories->AddFactory( new GrFmtImageIO() );
301 m_factories->AddFactory( new GrFmtBmp() );
302 m_factories->AddFactory( new GrFmtJpeg() );
303 m_factories->AddFactory( new GrFmtSunRaster() );
304 m_factories->AddFactory( new GrFmtPxM() );
305 m_factories->AddFactory( new GrFmtTiff() );
307 m_factories->AddFactory( new GrFmtPng() );
310 m_factories->AddFactory( new GrFmtJpeg2000() );
313 m_factories->AddFactory( new GrFmtExr() );
318 CvImageFilters::~CvImageFilters()
324 GrFmtReader* CvImageFilters::FindReader( const char* filename ) const
326 return m_factories->FindReader( filename );
330 GrFmtWriter* CvImageFilters::FindWriter( const char* filename ) const
332 return m_factories->FindWriter( filename );
335 /****************************************************************************************\
336 * HighGUI loading & saving function implementation *
337 \****************************************************************************************/
339 static int icvSetCXCOREBindings(void)
341 return CV_SET_IMAGE_IO_FUNCTIONS();
344 int cxcore_bindings_initialized = icvSetCXCOREBindings();
346 // global image I/O filters
347 static CvImageFilters g_Filters;
351 cvAddSearchPath( const char* path )
353 CV_FUNCNAME( "cvAddSearchPath" );
357 if( !path || strlen(path) == 0 )
358 CV_ERROR( CV_StsNullPtr, "Null path" );
360 g_Filters.AddPath( path );
367 cvHaveImageReader( const char* filename )
369 GrFmtReader* reader = g_Filters.FindReader( filename );
377 CV_IMPL int cvHaveImageWriter( const char* filename )
379 GrFmtWriter* writer = g_Filters.FindWriter( filename );
388 icvLoadImage( const char* filename, int flags, bool load_as_matrix )
390 GrFmtReader* reader = 0;
392 CvMat hdr, *matrix = 0;
395 CV_FUNCNAME( "cvLoadImage" );
403 if( !filename || strlen(filename) == 0 )
404 CV_ERROR( CV_StsNullPtr, "null filename" );
406 reader = g_Filters.FindReader( filename );
410 if( !reader->ReadHeader() )
413 size.width = reader->GetWidth();
414 size.height = reader->GetHeight();
417 iscolor = reader->IsColor();
420 if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||
421 ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && reader->IsColor()) )
426 if( (flags & CV_LOAD_IMAGE_ANYDEPTH) != 0 )
428 reader->UseNativeDepth(true);
429 depth = reader->GetDepth();
433 cn = iscolor ? 3 : 1;
438 if(reader->IsFloat() && depth != 8)
441 type = ( depth <= 8 ) ? CV_8U : ( depth <= 16 ) ? CV_16U : CV_32S;
442 CV_CALL( matrix = cvCreateMat( size.height, size.width, CV_MAKETYPE(type, cn) ));
447 if(reader->IsFloat() && depth != 8)
448 type = IPL_DEPTH_32F;
450 type = ( depth <= 8 ) ? IPL_DEPTH_8U : ( depth <= 16 ) ? IPL_DEPTH_16U : IPL_DEPTH_32S;
451 CV_CALL( image = cvCreateImage( size, type, cn ));
452 matrix = cvGetMat( image, &hdr );
455 if( !reader->ReadData( matrix->data.ptr, matrix->step, iscolor ))
458 cvReleaseMat( &matrix );
460 cvReleaseImage( &image );
468 if( cvGetErrStatus() < 0 )
471 cvReleaseMat( &matrix );
473 cvReleaseImage( &image );
476 return load_as_matrix ? (void*)matrix : (void*)image;
481 cvLoadImage( const char* filename, int iscolor )
483 return (IplImage*)icvLoadImage( filename, iscolor, false );
487 cvLoadImageM( const char* filename, int iscolor )
489 return (CvMat*)icvLoadImage( filename, iscolor, true );
494 cvSaveImage( const char* filename, const CvArr* arr )
497 GrFmtWriter* writer = 0;
498 CvMat *temp = 0, *temp2 = 0;
500 CV_FUNCNAME( "cvSaveImage" );
505 int channels, ipl_depth;
507 if( !filename || strlen(filename) == 0 )
508 CV_ERROR( CV_StsNullPtr, "null filename" );
510 CV_CALL( image = cvGetMat( arr, &stub ));
512 if( CV_IS_IMAGE( arr ))
513 origin = ((IplImage*)arr)->origin;
515 channels = CV_MAT_CN( image->type );
516 if( channels != 1 && channels != 3 && channels != 4 )
517 CV_ERROR( CV_BadNumChannels, "" );
519 writer = g_Filters.FindWriter( filename );
521 CV_ERROR( CV_StsError, "could not find a filter for the specified extension" );
525 CV_CALL( temp = cvCreateMat(image->rows, image->cols, image->type) );
526 CV_CALL( cvFlip( image, temp, 0 ));
530 ipl_depth = cvCvToIplDepth(image->type);
532 if( !writer->IsFormatSupported(ipl_depth) )
534 assert( writer->IsFormatSupported(IPL_DEPTH_8U) );
535 CV_CALL( temp2 = cvCreateMat(image->rows,
536 image->cols, CV_MAKETYPE(CV_8U,channels)) );
537 CV_CALL( cvConvertImage( image, temp2 ));
539 ipl_depth = IPL_DEPTH_8U;
542 if( !writer->WriteImage( image->data.ptr, image->step, image->width,
543 image->height, ipl_depth, channels ))
544 CV_ERROR( CV_StsError, "could not save the image" );
549 cvReleaseMat( &temp );
550 cvReleaseMat( &temp2 );
552 return cvGetErrStatus() >= 0;