| /*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*/ |
| |
| // |
| // Loading and saving IPL images. |
| // |
| |
| #include "_highgui.h" |
| #include "grfmts.h" |
| |
| #if 0 |
| /****************************************************************************************\ |
| * Path class (list of search folders) * |
| \****************************************************************************************/ |
| |
| class CvFilePath |
| { |
| public: |
| CvFilePath(); |
| ~CvFilePath(); |
| |
| // preprocess folder or file name - calculate its length, |
| // check for invalid symbols in the name and substitute |
| // all backslashes with simple slashes. |
| // the result is put into the specified buffer |
| static int Preprocess( const char* filename, char* buffer ); |
| |
| // add folder to the path |
| bool Add( const char* path ); |
| |
| // clear the path |
| void Clear(); |
| |
| // return the path - string, where folders are separated by ';' |
| const char* Get() const { return m_path; }; |
| |
| // find the file in the path |
| const char* Find( const char* filename, char* buffer ) const; |
| |
| // return the first folder from the path |
| // the returned string is not terminated by '\0'!!! |
| // its length is returned via len parameter |
| const char* First( int& len ) const; |
| |
| // return the folder, next in the path after the specified folder. |
| // see also note to First() method |
| const char* Next( const char* folder, int& len ) const; |
| |
| protected: |
| |
| char* m_path; |
| int m_maxsize; |
| int m_len; |
| }; |
| |
| |
| void CvFilePath::Clear() |
| { |
| delete[] m_path; |
| m_maxsize = m_len = 0; |
| } |
| |
| |
| CvFilePath::CvFilePath() |
| { |
| m_path = 0; |
| m_maxsize = m_len = 0; |
| } |
| |
| |
| CvFilePath::~CvFilePath() |
| { |
| Clear(); |
| } |
| |
| |
| bool CvFilePath::Add( const char* path ) |
| { |
| char buffer[_MAX_PATH + 1]; |
| int len = Preprocess( path, buffer ); |
| |
| if( len < 0 ) |
| return false; |
| |
| if( m_len + len + 3 // +1 for one more ';', |
| // another +1 for possible additional '/', |
| // and the last +1 is for '\0' |
| > m_maxsize ) |
| { |
| int new_size = (m_len + len + 3 + 1023) & -1024; |
| char* new_path = new char[new_size]; |
| |
| if( m_path ) |
| { |
| memcpy( new_path, m_path, m_len ); |
| delete[] m_path; |
| } |
| |
| m_path = new_path; |
| m_maxsize = new_size; |
| } |
| |
| m_path[m_len++] = ';'; |
| memcpy( m_path + m_len, buffer, len ); |
| m_len += len; |
| |
| if( m_path[m_len] != '/' ) |
| m_path[m_len++] = '/'; |
| |
| m_path[m_len] = '\0'; // '\0' is not counted in m_len. |
| |
| return true; |
| } |
| |
| |
| const char* CvFilePath::First( int& len ) const |
| { |
| const char* path = (const char*)(m_path ? m_path : ""); |
| const char* path_end = path; |
| |
| while( *path_end && *path_end != ';' ) |
| path_end++; |
| |
| len = path_end - path; |
| return path; |
| } |
| |
| |
| const char* CvFilePath::Next( const char* folder, int& len ) const |
| { |
| if( !folder || folder < m_path || folder >= m_path + m_len ) |
| return 0; |
| |
| folder = strchr( folder, ';' ); |
| if( folder ) |
| { |
| const char* folder_end = ++folder; |
| while( *folder_end && *folder_end != ';' ) |
| folder_end++; |
| |
| len = folder_end - folder; |
| } |
| |
| return folder; |
| } |
| |
| |
| const char* CvFilePath::Find( const char* filename, char* buffer ) const |
| { |
| char path0[_MAX_PATH + 1]; |
| int len = Preprocess( filename, path0 ); |
| int folder_len = 0; |
| const char* folder = First( folder_len ); |
| char* name_only = 0; |
| char* name = path0; |
| FILE* f = 0; |
| |
| if( len < 0 ) |
| return 0; |
| |
| do |
| { |
| if( folder_len + len <= _MAX_PATH ) |
| { |
| memcpy( buffer, folder, folder_len ); |
| strcpy( buffer + folder_len, name ); |
| |
| f = fopen( buffer, "rb" ); |
| if( f ) |
| break; |
| } |
| |
| if( name != name_only ) |
| { |
| name_only = strrchr( path0, '/' ); |
| if( !name_only ) |
| name_only = path0; |
| else |
| name_only++; |
| len = strlen( name_only ); |
| name = name_only; |
| } |
| } |
| while( (folder = Next( folder, folder_len )) != 0 ); |
| |
| filename = 0; |
| |
| if( f ) |
| { |
| filename = (const char*)buffer; |
| fclose(f); |
| } |
| |
| return filename; |
| } |
| |
| |
| int CvFilePath::Preprocess( const char* str, char* buffer ) |
| { |
| int i; |
| |
| if( !str || !buffer ) |
| return -1; |
| |
| for( i = 0; i <= _MAX_PATH; i++ ) |
| { |
| buffer[i] = str[i]; |
| |
| if( isalnum(str[i])) // fast check to skip most of characters |
| continue; |
| |
| if( str[i] == '\0' ) |
| break; |
| |
| if( str[i] == '\\' ) // convert back slashes to simple slashes |
| // (for Win32-*NIX compatibility) |
| buffer[i] = '/'; |
| |
| if (str[i] == '*' || str[i] == '?' || str[i] == '\"' || |
| str[i] == '>' || str[i] == '<' || |
| str[i] == ';' || /* used as a separator in the path */ |
| #ifndef WIN32 |
| str[i] == ',' || str[i] == '%' || |
| #endif |
| str[i] == '|') |
| return -1; |
| } |
| |
| return i <= _MAX_PATH ? i : -1; |
| } |
| #endif |
| |
| /****************************************************************************************\ |
| * Image Readers & Writers Class * |
| \****************************************************************************************/ |
| |
| class CvImageFilters |
| { |
| public: |
| |
| CvImageFilters(); |
| ~CvImageFilters(); |
| |
| GrFmtReader* FindReader( const char* filename ) const; |
| GrFmtWriter* FindWriter( const char* filename ) const; |
| |
| //const CvFilePath& Path() const { return (const CvFilePath&)m_path; }; |
| //CvFilePath& Path() { return m_path; }; |
| |
| protected: |
| |
| GrFmtFactoriesList* m_factories; |
| }; |
| |
| |
| CvImageFilters::CvImageFilters() |
| { |
| m_factories = new GrFmtFactoriesList; |
| |
| #ifdef HAVE_IMAGEIO |
| m_factories->AddFactory( new GrFmtImageIO() ); |
| #endif |
| m_factories->AddFactory( new GrFmtBmp() ); |
| m_factories->AddFactory( new GrFmtJpeg() ); |
| m_factories->AddFactory( new GrFmtSunRaster() ); |
| m_factories->AddFactory( new GrFmtPxM() ); |
| m_factories->AddFactory( new GrFmtTiff() ); |
| #ifdef HAVE_PNG |
| m_factories->AddFactory( new GrFmtPng() ); |
| #endif |
| #ifdef HAVE_JASPER |
| m_factories->AddFactory( new GrFmtJpeg2000() ); |
| #endif |
| #ifdef HAVE_ILMIMF |
| m_factories->AddFactory( new GrFmtExr() ); |
| #endif |
| } |
| |
| |
| CvImageFilters::~CvImageFilters() |
| { |
| delete m_factories; |
| } |
| |
| |
| GrFmtReader* CvImageFilters::FindReader( const char* filename ) const |
| { |
| return m_factories->FindReader( filename ); |
| } |
| |
| |
| GrFmtWriter* CvImageFilters::FindWriter( const char* filename ) const |
| { |
| return m_factories->FindWriter( filename ); |
| } |
| |
| /****************************************************************************************\ |
| * HighGUI loading & saving function implementation * |
| \****************************************************************************************/ |
| |
| static int icvSetCXCOREBindings(void) |
| { |
| return CV_SET_IMAGE_IO_FUNCTIONS(); |
| } |
| |
| int cxcore_bindings_initialized = icvSetCXCOREBindings(); |
| |
| // global image I/O filters |
| static CvImageFilters g_Filters; |
| |
| #if 0 |
| CV_IMPL void |
| cvAddSearchPath( const char* path ) |
| { |
| CV_FUNCNAME( "cvAddSearchPath" ); |
| |
| __BEGIN__; |
| |
| if( !path || strlen(path) == 0 ) |
| CV_ERROR( CV_StsNullPtr, "Null path" ); |
| |
| g_Filters.AddPath( path ); |
| |
| __END__; |
| } |
| #endif |
| |
| CV_IMPL int |
| cvHaveImageReader( const char* filename ) |
| { |
| GrFmtReader* reader = g_Filters.FindReader( filename ); |
| if( reader ) { |
| delete reader; |
| return 1; |
| } |
| return 0; |
| } |
| |
| CV_IMPL int cvHaveImageWriter( const char* filename ) |
| { |
| GrFmtWriter* writer = g_Filters.FindWriter( filename ); |
| if( writer ) { |
| delete writer; |
| return 1; |
| } |
| return 0; |
| } |
| |
| static void* |
| icvLoadImage( const char* filename, int flags, bool load_as_matrix ) |
| { |
| GrFmtReader* reader = 0; |
| IplImage* image = 0; |
| CvMat hdr, *matrix = 0; |
| int depth = 8; |
| |
| CV_FUNCNAME( "cvLoadImage" ); |
| |
| __BEGIN__; |
| |
| CvSize size; |
| int iscolor; |
| int cn; |
| |
| if( !filename || strlen(filename) == 0 ) |
| CV_ERROR( CV_StsNullPtr, "null filename" ); |
| |
| reader = g_Filters.FindReader( filename ); |
| if( !reader ) |
| EXIT; |
| |
| if( !reader->ReadHeader() ) |
| EXIT; |
| |
| size.width = reader->GetWidth(); |
| size.height = reader->GetHeight(); |
| |
| if( flags == -1 ) |
| iscolor = reader->IsColor(); |
| else |
| { |
| if( (flags & CV_LOAD_IMAGE_COLOR) != 0 || |
| ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && reader->IsColor()) ) |
| iscolor = 1; |
| else |
| iscolor = 0; |
| |
| if( (flags & CV_LOAD_IMAGE_ANYDEPTH) != 0 ) |
| { |
| reader->UseNativeDepth(true); |
| depth = reader->GetDepth(); |
| } |
| } |
| |
| cn = iscolor ? 3 : 1; |
| |
| if( load_as_matrix ) |
| { |
| int type; |
| if(reader->IsFloat() && depth != 8) |
| type = CV_32F; |
| else |
| type = ( depth <= 8 ) ? CV_8U : ( depth <= 16 ) ? CV_16U : CV_32S; |
| CV_CALL( matrix = cvCreateMat( size.height, size.width, CV_MAKETYPE(type, cn) )); |
| } |
| else |
| { |
| int type; |
| if(reader->IsFloat() && depth != 8) |
| type = IPL_DEPTH_32F; |
| else |
| type = ( depth <= 8 ) ? IPL_DEPTH_8U : ( depth <= 16 ) ? IPL_DEPTH_16U : IPL_DEPTH_32S; |
| CV_CALL( image = cvCreateImage( size, type, cn )); |
| matrix = cvGetMat( image, &hdr ); |
| } |
| |
| if( !reader->ReadData( matrix->data.ptr, matrix->step, iscolor )) |
| { |
| if( load_as_matrix ) |
| cvReleaseMat( &matrix ); |
| else |
| cvReleaseImage( &image ); |
| EXIT; |
| } |
| |
| __END__; |
| |
| delete reader; |
| |
| if( cvGetErrStatus() < 0 ) |
| { |
| if( load_as_matrix ) |
| cvReleaseMat( &matrix ); |
| else |
| cvReleaseImage( &image ); |
| } |
| |
| return load_as_matrix ? (void*)matrix : (void*)image; |
| } |
| |
| |
| CV_IMPL IplImage* |
| cvLoadImage( const char* filename, int iscolor ) |
| { |
| return (IplImage*)icvLoadImage( filename, iscolor, false ); |
| } |
| |
| CV_IMPL CvMat* |
| cvLoadImageM( const char* filename, int iscolor ) |
| { |
| return (CvMat*)icvLoadImage( filename, iscolor, true ); |
| } |
| |
| |
| CV_IMPL int |
| cvSaveImage( const char* filename, const CvArr* arr ) |
| { |
| int origin = 0; |
| GrFmtWriter* writer = 0; |
| CvMat *temp = 0, *temp2 = 0; |
| |
| CV_FUNCNAME( "cvSaveImage" ); |
| |
| __BEGIN__; |
| |
| CvMat stub, *image; |
| int channels, ipl_depth; |
| |
| if( !filename || strlen(filename) == 0 ) |
| CV_ERROR( CV_StsNullPtr, "null filename" ); |
| |
| CV_CALL( image = cvGetMat( arr, &stub )); |
| |
| if( CV_IS_IMAGE( arr )) |
| origin = ((IplImage*)arr)->origin; |
| |
| channels = CV_MAT_CN( image->type ); |
| if( channels != 1 && channels != 3 && channels != 4 ) |
| CV_ERROR( CV_BadNumChannels, "" ); |
| |
| writer = g_Filters.FindWriter( filename ); |
| if( !writer ) |
| CV_ERROR( CV_StsError, "could not find a filter for the specified extension" ); |
| |
| if( origin ) |
| { |
| CV_CALL( temp = cvCreateMat(image->rows, image->cols, image->type) ); |
| CV_CALL( cvFlip( image, temp, 0 )); |
| image = temp; |
| } |
| |
| ipl_depth = cvCvToIplDepth(image->type); |
| |
| if( !writer->IsFormatSupported(ipl_depth) ) |
| { |
| assert( writer->IsFormatSupported(IPL_DEPTH_8U) ); |
| CV_CALL( temp2 = cvCreateMat(image->rows, |
| image->cols, CV_MAKETYPE(CV_8U,channels)) ); |
| CV_CALL( cvConvertImage( image, temp2 )); |
| image = temp2; |
| ipl_depth = IPL_DEPTH_8U; |
| } |
| |
| if( !writer->WriteImage( image->data.ptr, image->step, image->width, |
| image->height, ipl_depth, channels )) |
| CV_ERROR( CV_StsError, "could not save the image" ); |
| |
| __END__; |
| |
| delete writer; |
| cvReleaseMat( &temp ); |
| cvReleaseMat( &temp2 ); |
| |
| return cvGetErrStatus() >= 0; |
| } |
| |
| /* End of file. */ |