Home | History | Annotate | Download | only in highgui
      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*/
     41 
     42 //
     43 //  Loading and saving IPL images.
     44 //
     45 
     46 #include "_highgui.h"
     47 #include "grfmts.h"
     48 
     49 #if 0
     50 /****************************************************************************************\
     51 *                              Path class (list of search folders)                       *
     52 \****************************************************************************************/
     53 
     54 class  CvFilePath
     55 {
     56 public:
     57     CvFilePath();
     58     ~CvFilePath();
     59 
     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 );
     65 
     66     // add folder to the path
     67     bool Add( const char* path );
     68 
     69     // clear the path
     70     void Clear();
     71 
     72     // return the path - string, where folders are separated by ';'
     73     const char* Get() const { return m_path; };
     74 
     75     // find the file in the path
     76     const char* Find( const char* filename, char* buffer ) const;
     77 
     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;
     82 
     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;
     86 
     87 protected:
     88 
     89     char* m_path;
     90     int m_maxsize;
     91     int m_len;
     92 };
     93 
     94 
     95 void CvFilePath::Clear()
     96 {
     97     delete[] m_path;
     98     m_maxsize = m_len = 0;
     99 }
    100 
    101 
    102 CvFilePath::CvFilePath()
    103 {
    104     m_path = 0;
    105     m_maxsize = m_len = 0;
    106 }
    107 
    108 
    109 CvFilePath::~CvFilePath()
    110 {
    111     Clear();
    112 }
    113 
    114 
    115 bool  CvFilePath::Add( const char* path )
    116 {
    117     char buffer[_MAX_PATH + 1];
    118     int len = Preprocess( path, buffer );
    119 
    120     if( len < 0 )
    121         return false;
    122 
    123     if( m_len + len + 3 // +1 for one more ';',
    124                         // another +1 for possible additional '/',
    125                         // and the last +1 is for '\0'
    126                       > m_maxsize )
    127     {
    128         int new_size = (m_len + len + 3 + 1023) & -1024;
    129         char* new_path = new char[new_size];
    130 
    131         if( m_path )
    132         {
    133             memcpy( new_path, m_path, m_len );
    134             delete[] m_path;
    135         }
    136 
    137         m_path = new_path;
    138         m_maxsize = new_size;
    139     }
    140 
    141     m_path[m_len++] = ';';
    142     memcpy( m_path + m_len, buffer, len );
    143     m_len += len;
    144 
    145     if( m_path[m_len] != '/' )
    146         m_path[m_len++] = '/';
    147 
    148     m_path[m_len] = '\0'; // '\0' is not counted in m_len.
    149 
    150     return true;
    151 }
    152 
    153 
    154 const char* CvFilePath::First( int& len ) const
    155 {
    156     const char* path = (const char*)(m_path ? m_path : "");
    157     const char* path_end = path;
    158 
    159     while( *path_end && *path_end != ';' )
    160         path_end++;
    161 
    162     len = path_end - path;
    163     return path;
    164 }
    165 
    166 
    167 const char* CvFilePath::Next( const char* folder, int& len ) const
    168 {
    169     if( !folder || folder < m_path || folder >= m_path + m_len )
    170         return 0;
    171 
    172     folder = strchr( folder, ';' );
    173     if( folder )
    174     {
    175         const char* folder_end = ++folder;
    176         while( *folder_end && *folder_end != ';' )
    177             folder_end++;
    178 
    179         len = folder_end - folder;
    180     }
    181 
    182     return folder;
    183 }
    184 
    185 
    186 const char* CvFilePath::Find( const char* filename, char* buffer ) const
    187 {
    188     char path0[_MAX_PATH + 1];
    189     int len = Preprocess( filename, path0 );
    190     int folder_len = 0;
    191     const char* folder = First( folder_len );
    192     char* name_only = 0;
    193     char* name = path0;
    194     FILE* f = 0;
    195 
    196     if( len < 0 )
    197         return 0;
    198 
    199     do
    200     {
    201         if( folder_len + len <= _MAX_PATH )
    202         {
    203             memcpy( buffer, folder, folder_len );
    204             strcpy( buffer + folder_len, name );
    205 
    206             f = fopen( buffer, "rb" );
    207             if( f )
    208                 break;
    209         }
    210 
    211         if( name != name_only )
    212         {
    213             name_only = strrchr( path0, '/' );
    214             if( !name_only )
    215                 name_only = path0;
    216             else
    217                 name_only++;
    218             len = strlen( name_only );
    219             name = name_only;
    220         }
    221     }
    222     while( (folder = Next( folder, folder_len )) != 0 );
    223 
    224     filename = 0;
    225 
    226     if( f )
    227     {
    228         filename = (const char*)buffer;
    229         fclose(f);
    230     }
    231 
    232     return filename;
    233 }
    234 
    235 
    236 int CvFilePath::Preprocess( const char* str, char* buffer )
    237 {
    238     int i;
    239 
    240     if( !str || !buffer )
    241         return -1;
    242 
    243     for( i = 0; i <= _MAX_PATH; i++ )
    244     {
    245         buffer[i] = str[i];
    246 
    247         if( isalnum(str[i])) // fast check to skip most of characters
    248             continue;
    249 
    250         if( str[i] == '\0' )
    251             break;
    252 
    253         if( str[i] == '\\' ) // convert back slashes to simple slashes
    254                              // (for Win32-*NIX compatibility)
    255             buffer[i] = '/';
    256 
    257         if (str[i] == '*' || str[i] == '?' || str[i] == '\"' ||
    258             str[i] == '>' || str[i] == '<' ||
    259             str[i] == ';' || /* used as a separator in the path */
    260         #ifndef WIN32
    261             str[i] == ',' || str[i] == '%' ||
    262         #endif
    263             str[i] == '|')
    264             return -1;
    265     }
    266 
    267     return i <= _MAX_PATH ? i : -1;
    268 }
    269 #endif
    270 
    271 /****************************************************************************************\
    272 *                              Image Readers & Writers Class                             *
    273 \****************************************************************************************/
    274 
    275 class  CvImageFilters
    276 {
    277 public:
    278 
    279     CvImageFilters();
    280     ~CvImageFilters();
    281 
    282     GrFmtReader* FindReader( const char* filename ) const;
    283     GrFmtWriter* FindWriter( const char* filename ) const;
    284 
    285     //const CvFilePath& Path() const { return (const CvFilePath&)m_path; };
    286     //CvFilePath& Path() { return m_path; };
    287 
    288 protected:
    289 
    290     GrFmtFactoriesList*  m_factories;
    291 };
    292 
    293 
    294 CvImageFilters::CvImageFilters()
    295 {
    296     m_factories = new GrFmtFactoriesList;
    297 
    298 #ifdef HAVE_IMAGEIO
    299     m_factories->AddFactory( new GrFmtImageIO() );
    300 #endif
    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() );
    306 #ifdef HAVE_PNG
    307     m_factories->AddFactory( new GrFmtPng() );
    308 #endif
    309 #ifdef HAVE_JASPER
    310     m_factories->AddFactory( new GrFmtJpeg2000() );
    311 #endif
    312 #ifdef HAVE_ILMIMF
    313     m_factories->AddFactory( new GrFmtExr() );
    314 #endif
    315 }
    316 
    317 
    318 CvImageFilters::~CvImageFilters()
    319 {
    320     delete m_factories;
    321 }
    322 
    323 
    324 GrFmtReader* CvImageFilters::FindReader( const char* filename ) const
    325 {
    326     return m_factories->FindReader( filename );
    327 }
    328 
    329 
    330 GrFmtWriter* CvImageFilters::FindWriter( const char* filename ) const
    331 {
    332     return m_factories->FindWriter( filename );
    333 }
    334 
    335 /****************************************************************************************\
    336 *                         HighGUI loading & saving function implementation               *
    337 \****************************************************************************************/
    338 
    339 static int icvSetCXCOREBindings(void)
    340 {
    341     return CV_SET_IMAGE_IO_FUNCTIONS();
    342 }
    343 
    344 int cxcore_bindings_initialized = icvSetCXCOREBindings();
    345 
    346 // global image I/O filters
    347 static CvImageFilters  g_Filters;
    348 
    349 #if 0
    350 CV_IMPL void
    351 cvAddSearchPath( const char* path )
    352 {
    353     CV_FUNCNAME( "cvAddSearchPath" );
    354 
    355     __BEGIN__;
    356 
    357     if( !path || strlen(path) == 0 )
    358         CV_ERROR( CV_StsNullPtr, "Null path" );
    359 
    360     g_Filters.AddPath( path );
    361 
    362     __END__;
    363 }
    364 #endif
    365 
    366 CV_IMPL int
    367 cvHaveImageReader( const char* filename )
    368 {
    369     GrFmtReader* reader = g_Filters.FindReader( filename );
    370     if( reader ) {
    371         delete reader;
    372         return 1;
    373     }
    374     return 0;
    375 }
    376 
    377 CV_IMPL int cvHaveImageWriter( const char* filename )
    378 {
    379     GrFmtWriter* writer = g_Filters.FindWriter( filename );
    380     if( writer ) {
    381         delete writer;
    382         return 1;
    383     }
    384     return 0;
    385 }
    386 
    387 static void*
    388 icvLoadImage( const char* filename, int flags, bool load_as_matrix )
    389 {
    390     GrFmtReader* reader = 0;
    391     IplImage* image = 0;
    392     CvMat hdr, *matrix = 0;
    393     int depth = 8;
    394 
    395     CV_FUNCNAME( "cvLoadImage" );
    396 
    397     __BEGIN__;
    398 
    399     CvSize size;
    400     int iscolor;
    401     int cn;
    402 
    403     if( !filename || strlen(filename) == 0 )
    404         CV_ERROR( CV_StsNullPtr, "null filename" );
    405 
    406     reader = g_Filters.FindReader( filename );
    407     if( !reader )
    408         EXIT;
    409 
    410     if( !reader->ReadHeader() )
    411         EXIT;
    412 
    413     size.width = reader->GetWidth();
    414     size.height = reader->GetHeight();
    415 
    416     if( flags == -1 )
    417         iscolor = reader->IsColor();
    418     else
    419     {
    420         if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||
    421            ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && reader->IsColor()) )
    422             iscolor = 1;
    423         else
    424             iscolor = 0;
    425 
    426         if( (flags & CV_LOAD_IMAGE_ANYDEPTH) != 0 )
    427         {
    428             reader->UseNativeDepth(true);
    429             depth = reader->GetDepth();
    430         }
    431     }
    432 
    433     cn = iscolor ? 3 : 1;
    434 
    435     if( load_as_matrix )
    436     {
    437         int type;
    438         if(reader->IsFloat() && depth != 8)
    439             type = CV_32F;
    440         else
    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) ));
    443     }
    444     else
    445     {
    446         int type;
    447         if(reader->IsFloat() && depth != 8)
    448             type = IPL_DEPTH_32F;
    449         else
    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 );
    453     }
    454 
    455     if( !reader->ReadData( matrix->data.ptr, matrix->step, iscolor ))
    456     {
    457         if( load_as_matrix )
    458             cvReleaseMat( &matrix );
    459         else
    460             cvReleaseImage( &image );
    461         EXIT;
    462     }
    463 
    464     __END__;
    465 
    466     delete reader;
    467 
    468     if( cvGetErrStatus() < 0 )
    469     {
    470         if( load_as_matrix )
    471             cvReleaseMat( &matrix );
    472         else
    473             cvReleaseImage( &image );
    474     }
    475 
    476     return load_as_matrix ? (void*)matrix : (void*)image;
    477 }
    478 
    479 
    480 CV_IMPL IplImage*
    481 cvLoadImage( const char* filename, int iscolor )
    482 {
    483     return (IplImage*)icvLoadImage( filename, iscolor, false );
    484 }
    485 
    486 CV_IMPL CvMat*
    487 cvLoadImageM( const char* filename, int iscolor )
    488 {
    489     return (CvMat*)icvLoadImage( filename, iscolor, true );
    490 }
    491 
    492 
    493 CV_IMPL int
    494 cvSaveImage( const char* filename, const CvArr* arr )
    495 {
    496     int origin = 0;
    497     GrFmtWriter* writer = 0;
    498     CvMat *temp = 0, *temp2 = 0;
    499 
    500     CV_FUNCNAME( "cvSaveImage" );
    501 
    502     __BEGIN__;
    503 
    504     CvMat stub, *image;
    505     int channels, ipl_depth;
    506 
    507     if( !filename || strlen(filename) == 0 )
    508         CV_ERROR( CV_StsNullPtr, "null filename" );
    509 
    510     CV_CALL( image = cvGetMat( arr, &stub ));
    511 
    512     if( CV_IS_IMAGE( arr ))
    513         origin = ((IplImage*)arr)->origin;
    514 
    515     channels = CV_MAT_CN( image->type );
    516     if( channels != 1 && channels != 3 && channels != 4 )
    517         CV_ERROR( CV_BadNumChannels, "" );
    518 
    519     writer = g_Filters.FindWriter( filename );
    520     if( !writer )
    521         CV_ERROR( CV_StsError, "could not find a filter for the specified extension" );
    522 
    523     if( origin )
    524     {
    525         CV_CALL( temp = cvCreateMat(image->rows, image->cols, image->type) );
    526         CV_CALL( cvFlip( image, temp, 0 ));
    527         image = temp;
    528     }
    529 
    530     ipl_depth = cvCvToIplDepth(image->type);
    531 
    532     if( !writer->IsFormatSupported(ipl_depth) )
    533     {
    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 ));
    538         image = temp2;
    539         ipl_depth = IPL_DEPTH_8U;
    540     }
    541 
    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" );
    545 
    546     __END__;
    547 
    548     delete writer;
    549     cvReleaseMat( &temp );
    550     cvReleaseMat( &temp2 );
    551 
    552     return cvGetErrStatus() >= 0;
    553 }
    554 
    555 /* End of file. */
    556