Home | History | Annotate | Download | only in src
      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 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Third party copyrights are property of their respective owners.
     16 //
     17 // Redistribution and use in source and binary forms, with or without modification,
     18 // are permitted provided that the following conditions are met:
     19 //
     20 //   * Redistribution's of source code must retain the above copyright notice,
     21 //     this list of conditions and the following disclaimer.
     22 //
     23 //   * Redistribution's in binary form must reproduce the above copyright notice,
     24 //     this list of conditions and the following disclaimer in the documentation
     25 //     and/or other materials provided with the distribution.
     26 //
     27 //   * The name of the copyright holders may not be used to endorse or promote products
     28 //     derived from this software without specific prior written permission.
     29 //
     30 // This software is provided by the copyright holders and contributors "as is" and
     31 // any express or implied warranties, including, but not limited to, the implied
     32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     33 // In no event shall the Intel Corporation or contributors be liable for any direct,
     34 // indirect, incidental, special, exemplary, or consequential damages
     35 // (including, but not limited to, procurement of substitute goods or services;
     36 // loss of use, data, or profits; or business interruption) however caused
     37 // and on any theory of liability, whether in contract, strict liability,
     38 // or tort (including negligence or otherwise) arising in any way out of
     39 // the use of this software, even if advised of the possibility of such damage.
     40 //
     41 //M*/
     42 
     43 #include "precomp.hpp"
     44 #include "bitstrm.hpp"
     45 
     46 namespace cv
     47 {
     48 
     49 const int BS_DEF_BLOCK_SIZE = 1<<15;
     50 
     51 bool  bsIsBigEndian( void )
     52 {
     53     return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
     54 }
     55 
     56 /////////////////////////  RBaseStream ////////////////////////////
     57 
     58 bool  RBaseStream::isOpened()
     59 {
     60     return m_is_opened;
     61 }
     62 
     63 void  RBaseStream::allocate()
     64 {
     65     if( !m_allocated )
     66     {
     67         m_start = new uchar[m_block_size];
     68         m_end = m_start + m_block_size;
     69         m_current = m_end;
     70         m_allocated = true;
     71     }
     72 }
     73 
     74 
     75 RBaseStream::RBaseStream()
     76 {
     77     m_start = m_end = m_current = 0;
     78     m_file = 0;
     79     m_block_size = BS_DEF_BLOCK_SIZE;
     80     m_is_opened = false;
     81     m_allocated = false;
     82 }
     83 
     84 
     85 RBaseStream::~RBaseStream()
     86 {
     87     close();    // Close files
     88     release();  // free  buffers
     89 }
     90 
     91 
     92 void  RBaseStream::readBlock()
     93 {
     94     setPos( getPos() ); // normalize position
     95 
     96     if( m_file == 0 )
     97     {
     98         if( m_block_pos == 0 && m_current < m_end )
     99             return;
    100         throw RBS_THROW_EOS;
    101     }
    102 
    103     fseek( m_file, m_block_pos, SEEK_SET );
    104     size_t readed = fread( m_start, 1, m_block_size, m_file );
    105     m_end = m_start + readed;
    106     m_current = m_start;
    107 
    108     if( readed == 0 || m_current >= m_end )
    109         throw RBS_THROW_EOS;
    110 }
    111 
    112 
    113 bool  RBaseStream::open( const String& filename )
    114 {
    115     close();
    116     allocate();
    117 
    118     m_file = fopen( filename.c_str(), "rb" );
    119     if( m_file )
    120     {
    121         m_is_opened = true;
    122         setPos(0);
    123         readBlock();
    124     }
    125     return m_file != 0;
    126 }
    127 
    128 bool  RBaseStream::open( const Mat& buf )
    129 {
    130     close();
    131     if( buf.empty() )
    132         return false;
    133     CV_Assert(buf.isContinuous());
    134     m_start = buf.data;
    135     m_end = m_start + buf.cols*buf.rows*buf.elemSize();
    136     m_allocated = false;
    137     m_is_opened = true;
    138     setPos(0);
    139 
    140     return true;
    141 }
    142 
    143 void  RBaseStream::close()
    144 {
    145     if( m_file )
    146     {
    147         fclose( m_file );
    148         m_file = 0;
    149     }
    150     m_is_opened = false;
    151     if( !m_allocated )
    152         m_start = m_end = m_current = 0;
    153 }
    154 
    155 
    156 void  RBaseStream::release()
    157 {
    158     if( m_allocated )
    159         delete[] m_start;
    160     m_start = m_end = m_current = 0;
    161     m_allocated = false;
    162 }
    163 
    164 
    165 void  RBaseStream::setPos( int pos )
    166 {
    167     assert( isOpened() && pos >= 0 );
    168 
    169     if( !m_file )
    170     {
    171         m_current = m_start + pos;
    172         m_block_pos = 0;
    173         return;
    174     }
    175 
    176     int offset = pos % m_block_size;
    177     m_block_pos = pos - offset;
    178     m_current = m_start + offset;
    179 }
    180 
    181 
    182 int  RBaseStream::getPos()
    183 {
    184     assert( isOpened() );
    185     return m_block_pos + (int)(m_current - m_start);
    186 }
    187 
    188 void  RBaseStream::skip( int bytes )
    189 {
    190     assert( bytes >= 0 );
    191     m_current += bytes;
    192 }
    193 
    194 /////////////////////////  RLByteStream ////////////////////////////
    195 
    196 RLByteStream::~RLByteStream()
    197 {
    198 }
    199 
    200 int  RLByteStream::getByte()
    201 {
    202     uchar *current = m_current;
    203     int   val;
    204 
    205     if( current >= m_end )
    206     {
    207         readBlock();
    208         current = m_current;
    209     }
    210 
    211     val = *((uchar*)current);
    212     m_current = current + 1;
    213     return val;
    214 }
    215 
    216 
    217 int RLByteStream::getBytes( void* buffer, int count )
    218 {
    219     uchar*  data = (uchar*)buffer;
    220     int readed = 0;
    221     assert( count >= 0 );
    222 
    223     while( count > 0 )
    224     {
    225         int l;
    226 
    227         for(;;)
    228         {
    229             l = (int)(m_end - m_current);
    230             if( l > count ) l = count;
    231             if( l > 0 ) break;
    232             readBlock();
    233         }
    234         memcpy( data, m_current, l );
    235         m_current += l;
    236         data += l;
    237         count -= l;
    238         readed += l;
    239     }
    240     return readed;
    241 }
    242 
    243 
    244 ////////////  RLByteStream & RMByteStream <Get[d]word>s ////////////////
    245 
    246 RMByteStream::~RMByteStream()
    247 {
    248 }
    249 
    250 
    251 int  RLByteStream::getWord()
    252 {
    253     uchar *current = m_current;
    254     int   val;
    255 
    256     if( current+1 < m_end )
    257     {
    258         val = current[0] + (current[1] << 8);
    259         m_current = current + 2;
    260     }
    261     else
    262     {
    263         val = getByte();
    264         val|= getByte() << 8;
    265     }
    266     return val;
    267 }
    268 
    269 
    270 int  RLByteStream::getDWord()
    271 {
    272     uchar *current = m_current;
    273     int   val;
    274 
    275     if( current+3 < m_end )
    276     {
    277         val = current[0] + (current[1] << 8) +
    278               (current[2] << 16) + (current[3] << 24);
    279         m_current = current + 4;
    280     }
    281     else
    282     {
    283         val = getByte();
    284         val |= getByte() << 8;
    285         val |= getByte() << 16;
    286         val |= getByte() << 24;
    287     }
    288     return val;
    289 }
    290 
    291 
    292 int  RMByteStream::getWord()
    293 {
    294     uchar *current = m_current;
    295     int   val;
    296 
    297     if( current+1 < m_end )
    298     {
    299         val = (current[0] << 8) + current[1];
    300         m_current = current + 2;
    301     }
    302     else
    303     {
    304         val = getByte() << 8;
    305         val|= getByte();
    306     }
    307     return val;
    308 }
    309 
    310 
    311 int  RMByteStream::getDWord()
    312 {
    313     uchar *current = m_current;
    314     int   val;
    315 
    316     if( current+3 < m_end )
    317     {
    318         val = (current[0] << 24) + (current[1] << 16) +
    319               (current[2] << 8) + current[3];
    320         m_current = current + 4;
    321     }
    322     else
    323     {
    324         val = getByte() << 24;
    325         val |= getByte() << 16;
    326         val |= getByte() << 8;
    327         val |= getByte();
    328     }
    329     return val;
    330 }
    331 
    332 /////////////////////////// WBaseStream /////////////////////////////////
    333 
    334 // WBaseStream - base class for output streams
    335 WBaseStream::WBaseStream()
    336 {
    337     m_start = m_end = m_current = 0;
    338     m_file = 0;
    339     m_block_size = BS_DEF_BLOCK_SIZE;
    340     m_is_opened = false;
    341     m_buf = 0;
    342 }
    343 
    344 
    345 WBaseStream::~WBaseStream()
    346 {
    347     close();
    348     release();
    349 }
    350 
    351 
    352 bool  WBaseStream::isOpened()
    353 {
    354     return m_is_opened;
    355 }
    356 
    357 
    358 void  WBaseStream::allocate()
    359 {
    360     if( !m_start )
    361         m_start = new uchar[m_block_size];
    362 
    363     m_end = m_start + m_block_size;
    364     m_current = m_start;
    365 }
    366 
    367 
    368 void  WBaseStream::writeBlock()
    369 {
    370     int size = (int)(m_current - m_start);
    371 
    372     assert( isOpened() );
    373     if( size == 0 )
    374         return;
    375 
    376     if( m_buf )
    377     {
    378         size_t sz = m_buf->size();
    379         m_buf->resize( sz + size );
    380         memcpy( &(*m_buf)[sz], m_start, size );
    381     }
    382     else
    383     {
    384         fwrite( m_start, 1, size, m_file );
    385     }
    386     m_current = m_start;
    387     m_block_pos += size;
    388 }
    389 
    390 
    391 bool  WBaseStream::open( const String& filename )
    392 {
    393     close();
    394     allocate();
    395 
    396     m_file = fopen( filename.c_str(), "wb" );
    397     if( m_file )
    398     {
    399         m_is_opened = true;
    400         m_block_pos = 0;
    401         m_current = m_start;
    402     }
    403     return m_file != 0;
    404 }
    405 
    406 bool  WBaseStream::open( std::vector<uchar>& buf )
    407 {
    408     close();
    409     allocate();
    410 
    411     m_buf = &buf;
    412     m_is_opened = true;
    413     m_block_pos = 0;
    414     m_current = m_start;
    415 
    416     return true;
    417 }
    418 
    419 void  WBaseStream::close()
    420 {
    421     if( m_is_opened )
    422         writeBlock();
    423     if( m_file )
    424     {
    425         fclose( m_file );
    426         m_file = 0;
    427     }
    428     m_buf = 0;
    429     m_is_opened = false;
    430 }
    431 
    432 
    433 void  WBaseStream::release()
    434 {
    435     if( m_start )
    436         delete[] m_start;
    437     m_start = m_end = m_current = 0;
    438 }
    439 
    440 
    441 int  WBaseStream::getPos()
    442 {
    443     assert( isOpened() );
    444     return m_block_pos + (int)(m_current - m_start);
    445 }
    446 
    447 
    448 ///////////////////////////// WLByteStream ///////////////////////////////////
    449 
    450 WLByteStream::~WLByteStream()
    451 {
    452 }
    453 
    454 void WLByteStream::putByte( int val )
    455 {
    456     *m_current++ = (uchar)val;
    457     if( m_current >= m_end )
    458         writeBlock();
    459 }
    460 
    461 
    462 void WLByteStream::putBytes( const void* buffer, int count )
    463 {
    464     uchar* data = (uchar*)buffer;
    465 
    466     assert( data && m_current && count >= 0 );
    467 
    468     while( count )
    469     {
    470         int l = (int)(m_end - m_current);
    471 
    472         if( l > count )
    473             l = count;
    474 
    475         if( l > 0 )
    476         {
    477             memcpy( m_current, data, l );
    478             m_current += l;
    479             data += l;
    480             count -= l;
    481         }
    482         if( m_current == m_end )
    483             writeBlock();
    484     }
    485 }
    486 
    487 
    488 void WLByteStream::putWord( int val )
    489 {
    490     uchar *current = m_current;
    491 
    492     if( current+1 < m_end )
    493     {
    494         current[0] = (uchar)val;
    495         current[1] = (uchar)(val >> 8);
    496         m_current = current + 2;
    497         if( m_current == m_end )
    498             writeBlock();
    499     }
    500     else
    501     {
    502         putByte(val);
    503         putByte(val >> 8);
    504     }
    505 }
    506 
    507 
    508 void WLByteStream::putDWord( int val )
    509 {
    510     uchar *current = m_current;
    511 
    512     if( current+3 < m_end )
    513     {
    514         current[0] = (uchar)val;
    515         current[1] = (uchar)(val >> 8);
    516         current[2] = (uchar)(val >> 16);
    517         current[3] = (uchar)(val >> 24);
    518         m_current = current + 4;
    519         if( m_current == m_end )
    520             writeBlock();
    521     }
    522     else
    523     {
    524         putByte(val);
    525         putByte(val >> 8);
    526         putByte(val >> 16);
    527         putByte(val >> 24);
    528     }
    529 }
    530 
    531 
    532 ///////////////////////////// WMByteStream ///////////////////////////////////
    533 
    534 WMByteStream::~WMByteStream()
    535 {
    536 }
    537 
    538 
    539 void WMByteStream::putWord( int val )
    540 {
    541     uchar *current = m_current;
    542 
    543     if( current+1 < m_end )
    544     {
    545         current[0] = (uchar)(val >> 8);
    546         current[1] = (uchar)val;
    547         m_current = current + 2;
    548         if( m_current == m_end )
    549             writeBlock();
    550     }
    551     else
    552     {
    553         putByte(val >> 8);
    554         putByte(val);
    555     }
    556 }
    557 
    558 
    559 void WMByteStream::putDWord( int val )
    560 {
    561     uchar *current = m_current;
    562 
    563     if( current+3 < m_end )
    564     {
    565         current[0] = (uchar)(val >> 24);
    566         current[1] = (uchar)(val >> 16);
    567         current[2] = (uchar)(val >> 8);
    568         current[3] = (uchar)val;
    569         m_current = current + 4;
    570         if( m_current == m_end )
    571             writeBlock();
    572     }
    573     else
    574     {
    575         putByte(val >> 24);
    576         putByte(val >> 16);
    577         putByte(val >> 8);
    578         putByte(val);
    579     }
    580 }
    581 
    582 }
    583