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.
11 // For Open Source Computer Vision Library
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.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
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.
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.
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.
43 #include "precomp.hpp"
44 #include "bitstrm.hpp"
49 const int BS_DEF_BLOCK_SIZE = 1<<15;
51 bool bsIsBigEndian( void )
53 return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
56 ///////////////////////// RBaseStream ////////////////////////////
58 bool RBaseStream::isOpened()
63 void RBaseStream::allocate()
67 m_start = new uchar[m_block_size];
68 m_end = m_start + m_block_size;
75 RBaseStream::RBaseStream()
77 m_start = m_end = m_current = 0;
79 m_block_size = BS_DEF_BLOCK_SIZE;
85 RBaseStream::~RBaseStream()
87 close(); // Close files
88 release(); // free buffers
92 void RBaseStream::readBlock()
94 setPos( getPos() ); // normalize position
98 if( m_block_pos == 0 && m_current < m_end )
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;
108 if( readed == 0 || m_current >= m_end )
113 bool RBaseStream::open( const string& filename )
118 m_file = fopen( filename.c_str(), "rb" );
128 bool RBaseStream::open( const Mat& buf )
133 CV_Assert(buf.isContinuous());
135 m_end = m_start + buf.cols*buf.rows*buf.elemSize();
143 void RBaseStream::close()
152 m_start = m_end = m_current = 0;
156 void RBaseStream::release()
160 m_start = m_end = m_current = 0;
165 void RBaseStream::setPos( int pos )
167 assert( isOpened() && pos >= 0 );
171 m_current = m_start + pos;
176 int offset = pos % m_block_size;
177 m_block_pos = pos - offset;
178 m_current = m_start + offset;
182 int RBaseStream::getPos()
184 assert( isOpened() );
185 return m_block_pos + (int)(m_current - m_start);
188 void RBaseStream::skip( int bytes )
190 assert( bytes >= 0 );
194 ///////////////////////// RLByteStream ////////////////////////////
196 RLByteStream::~RLByteStream()
200 int RLByteStream::getByte()
202 uchar *current = m_current;
205 if( current >= m_end )
211 CV_Assert(current < m_end);
213 val = *((uchar*)current);
214 m_current = current + 1;
219 int RLByteStream::getBytes( void* buffer, int count )
221 uchar* data = (uchar*)buffer;
223 assert( count >= 0 );
231 l = (int)(m_end - m_current);
232 if( l > count ) l = count;
236 memcpy( data, m_current, l );
246 //////////// RLByteStream & RMByteStream <Get[d]word>s ////////////////
248 RMByteStream::~RMByteStream()
253 int RLByteStream::getWord()
255 uchar *current = m_current;
258 if( current+1 < m_end )
260 val = current[0] + (current[1] << 8);
261 m_current = current + 2;
266 val|= getByte() << 8;
272 int RLByteStream::getDWord()
274 uchar *current = m_current;
277 if( current+3 < m_end )
279 val = current[0] + (current[1] << 8) +
280 (current[2] << 16) + (current[3] << 24);
281 m_current = current + 4;
286 val |= getByte() << 8;
287 val |= getByte() << 16;
288 val |= getByte() << 24;
294 int RMByteStream::getWord()
296 uchar *current = m_current;
299 if( current+1 < m_end )
301 val = (current[0] << 8) + current[1];
302 m_current = current + 2;
306 val = getByte() << 8;
313 int RMByteStream::getDWord()
315 uchar *current = m_current;
318 if( current+3 < m_end )
320 val = (current[0] << 24) + (current[1] << 16) +
321 (current[2] << 8) + current[3];
322 m_current = current + 4;
326 val = getByte() << 24;
327 val |= getByte() << 16;
328 val |= getByte() << 8;
334 /////////////////////////// WBaseStream /////////////////////////////////
336 // WBaseStream - base class for output streams
337 WBaseStream::WBaseStream()
339 m_start = m_end = m_current = 0;
341 m_block_size = BS_DEF_BLOCK_SIZE;
347 WBaseStream::~WBaseStream()
354 bool WBaseStream::isOpened()
360 void WBaseStream::allocate()
363 m_start = new uchar[m_block_size];
365 m_end = m_start + m_block_size;
370 void WBaseStream::writeBlock()
372 int size = (int)(m_current - m_start);
374 assert( isOpened() );
380 size_t sz = m_buf->size();
381 m_buf->resize( sz + size );
382 memcpy( &(*m_buf)[sz], m_start, size );
386 fwrite( m_start, 1, size, m_file );
393 bool WBaseStream::open( const string& filename )
398 m_file = fopen( filename.c_str(), "wb" );
408 bool WBaseStream::open( vector<uchar>& buf )
421 void WBaseStream::close()
435 void WBaseStream::release()
439 m_start = m_end = m_current = 0;
443 int WBaseStream::getPos()
445 assert( isOpened() );
446 return m_block_pos + (int)(m_current - m_start);
450 ///////////////////////////// WLByteStream ///////////////////////////////////
452 WLByteStream::~WLByteStream()
456 void WLByteStream::putByte( int val )
458 *m_current++ = (uchar)val;
459 if( m_current >= m_end )
464 void WLByteStream::putBytes( const void* buffer, int count )
466 uchar* data = (uchar*)buffer;
468 assert( data && m_current && count >= 0 );
472 int l = (int)(m_end - m_current);
479 memcpy( m_current, data, l );
484 if( m_current == m_end )
490 void WLByteStream::putWord( int val )
492 uchar *current = m_current;
494 if( current+1 < m_end )
496 current[0] = (uchar)val;
497 current[1] = (uchar)(val >> 8);
498 m_current = current + 2;
499 if( m_current == m_end )
510 void WLByteStream::putDWord( int val )
512 uchar *current = m_current;
514 if( current+3 < m_end )
516 current[0] = (uchar)val;
517 current[1] = (uchar)(val >> 8);
518 current[2] = (uchar)(val >> 16);
519 current[3] = (uchar)(val >> 24);
520 m_current = current + 4;
521 if( m_current == m_end )
534 ///////////////////////////// WMByteStream ///////////////////////////////////
536 WMByteStream::~WMByteStream()
541 void WMByteStream::putWord( int val )
543 uchar *current = m_current;
545 if( current+1 < m_end )
547 current[0] = (uchar)(val >> 8);
548 current[1] = (uchar)val;
549 m_current = current + 2;
550 if( m_current == m_end )
561 void WMByteStream::putDWord( int val )
563 uchar *current = m_current;
565 if( current+3 < m_end )
567 current[0] = (uchar)(val >> 24);
568 current[1] = (uchar)(val >> 16);
569 current[2] = (uchar)(val >> 8);
570 current[3] = (uchar)val;
571 m_current = current + 4;
572 if( m_current == m_end )