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 46namespace cv 47{ 48 49const int BS_DEF_BLOCK_SIZE = 1<<15; 50 51bool bsIsBigEndian( void ) 52{ 53 return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0; 54} 55 56///////////////////////// RBaseStream //////////////////////////// 57 58bool RBaseStream::isOpened() 59{ 60 return m_is_opened; 61} 62 63void 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 75RBaseStream::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 85RBaseStream::~RBaseStream() 86{ 87 close(); // Close files 88 release(); // free buffers 89} 90 91 92void 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 113bool 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 128bool 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 143void 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 156void 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 165void 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 182int RBaseStream::getPos() 183{ 184 assert( isOpened() ); 185 return m_block_pos + (int)(m_current - m_start); 186} 187 188void RBaseStream::skip( int bytes ) 189{ 190 assert( bytes >= 0 ); 191 m_current += bytes; 192} 193 194///////////////////////// RLByteStream //////////////////////////// 195 196RLByteStream::~RLByteStream() 197{ 198} 199 200int 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 217int 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 246RMByteStream::~RMByteStream() 247{ 248} 249 250 251int 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 270int 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 292int 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 311int 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 335WBaseStream::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 345WBaseStream::~WBaseStream() 346{ 347 close(); 348 release(); 349} 350 351 352bool WBaseStream::isOpened() 353{ 354 return m_is_opened; 355} 356 357 358void 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 368void 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 391bool 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 406bool 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 419void 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 433void WBaseStream::release() 434{ 435 if( m_start ) 436 delete[] m_start; 437 m_start = m_end = m_current = 0; 438} 439 440 441int WBaseStream::getPos() 442{ 443 assert( isOpened() ); 444 return m_block_pos + (int)(m_current - m_start); 445} 446 447 448///////////////////////////// WLByteStream /////////////////////////////////// 449 450WLByteStream::~WLByteStream() 451{ 452} 453 454void WLByteStream::putByte( int val ) 455{ 456 *m_current++ = (uchar)val; 457 if( m_current >= m_end ) 458 writeBlock(); 459} 460 461 462void 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 488void 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 508void 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 534WMByteStream::~WMByteStream() 535{ 536} 537 538 539void 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 559void 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