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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
45 #define BS_DEF_BLOCK_SIZE (1<<15)
47 const ulong bs_bit_mask[] = {
49 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
50 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
51 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
52 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
53 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
54 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
55 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
56 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
59 void bsBSwapBlock( uchar *start, uchar *end )
61 ulong* data = (ulong*)start;
62 int i, size = (int)(end - start+3)/4;
64 for( i = 0; i < size; i++ )
72 bool bsIsBigEndian( void )
74 return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
77 ///////////////////////// RBaseStream ////////////////////////////
79 bool RBaseStream::IsOpened()
84 void RBaseStream::Allocate()
88 m_start = new uchar[m_block_size + m_unGetsize];
89 m_start+= m_unGetsize;
91 m_end = m_start + m_block_size;
96 RBaseStream::RBaseStream()
98 m_start = m_end = m_current = 0;
100 m_block_size = BS_DEF_BLOCK_SIZE;
101 m_unGetsize = 4; // 32 bits
107 RBaseStream::~RBaseStream()
109 Close(); // Close files
110 Release(); // free buffers
114 void RBaseStream::ReadBlock()
117 assert( m_file != 0 );
122 memcpy( m_start - m_unGetsize, m_end - m_unGetsize, m_unGetsize );
125 SetPos( GetPos() ); // normalize position
127 fseek( m_file, m_block_pos, SEEK_SET );
128 readed = fread( m_start, 1, m_block_size, m_file );
129 m_end = m_start + readed;
130 m_current -= m_block_size;
131 m_block_pos += m_block_size;
133 if( readed == 0 || m_current >= m_end )
136 longjmp( m_jmp_buf, RBS_THROW_EOS );
141 bool RBaseStream::Open( const char* filename )
146 m_file = fopen( filename, "rb" );
156 void RBaseStream::Close()
167 void RBaseStream::Release()
171 delete[] (m_start - m_unGetsize);
173 m_start = m_end = m_current = 0;
177 void RBaseStream::SetBlockSize( int block_size, int unGetsize )
179 assert( unGetsize >= 0 && block_size > 0 &&
180 (block_size & (block_size-1)) == 0 );
182 if( m_start && block_size == m_block_size && unGetsize == m_unGetsize ) return;
184 m_block_size = block_size;
185 m_unGetsize = unGetsize;
190 void RBaseStream::SetPos( int pos )
192 int offset = pos & (m_block_size - 1);
193 int block_pos = pos - offset;
195 assert( IsOpened() && pos >= 0 );
197 if( m_current < m_end && block_pos == m_block_pos - m_block_size )
199 m_current = m_start + offset;
203 m_block_pos = block_pos;
204 m_current = m_start + m_block_size + offset;
209 int RBaseStream::GetPos()
211 assert( IsOpened() );
212 return m_block_pos - m_block_size + (int)(m_current - m_start);
215 void RBaseStream::Skip( int bytes )
217 assert( bytes >= 0 );
221 jmp_buf& RBaseStream::JmpBuf()
227 ///////////////////////// RLByteStream ////////////////////////////
229 RLByteStream::~RLByteStream()
233 int RLByteStream::GetByte()
235 uchar *current = m_current;
238 if( current >= m_end )
244 val = *((uchar*)current);
245 m_current = current + 1;
250 void RLByteStream::GetBytes( void* buffer, int count, int* readed )
252 uchar* data = (uchar*)buffer;
253 assert( count >= 0 );
255 if( readed) *readed = 0;
263 l = (int)(m_end - m_current);
264 if( l > count ) l = count;
268 memcpy( data, m_current, l );
272 if( readed ) *readed += l;
277 //////////// RLByteStream & RMByteStream <Get[d]word>s ////////////////
279 RMByteStream::~RMByteStream()
284 int RLByteStream::GetWord()
286 uchar *current = m_current;
289 if( current+1 < m_end )
291 val = current[0] + (current[1] << 8);
292 m_current = current + 2;
297 val|= GetByte() << 8;
303 int RLByteStream::GetDWord()
305 uchar *current = m_current;
308 if( current+3 < m_end )
310 val = current[0] + (current[1] << 8) +
311 (current[2] << 16) + (current[3] << 24);
312 m_current = current + 4;
317 val |= GetByte() << 8;
318 val |= GetByte() << 16;
319 val |= GetByte() << 24;
325 int RMByteStream::GetWord()
327 uchar *current = m_current;
330 if( current+1 < m_end )
332 val = (current[0] << 8) + current[1];
333 m_current = current + 2;
337 val = GetByte() << 8;
344 int RMByteStream::GetDWord()
346 uchar *current = m_current;
349 if( current+3 < m_end )
351 val = (current[0] << 24) + (current[1] << 16) +
352 (current[2] << 8) + current[3];
353 m_current = current + 4;
357 val = GetByte() << 24;
358 val |= GetByte() << 16;
359 val |= GetByte() << 8;
366 ///////////////////////// RLBitStream ////////////////////////////
368 RLBitStream::~RLBitStream()
373 void RLBitStream::ReadBlock()
375 RBaseStream::ReadBlock();
376 if( bsIsBigEndian() )
377 bsBSwapBlock( m_start, m_end );
381 void RLBitStream::SetPos( int pos )
383 RBaseStream::SetPos(pos);
384 int offset = (int)(m_current - m_end);
385 m_current = m_end + (offset & -4);
386 m_bit_idx = (offset&3)*8;
390 int RLBitStream::GetPos()
392 return RBaseStream::GetPos() + (m_bit_idx >> 3);
396 int RLBitStream::Get( int bits )
398 int bit_idx = m_bit_idx;
399 int new_bit_idx = bit_idx + bits;
400 int mask = new_bit_idx >= 32 ? -1 : 0;
401 ulong* current = (ulong*)m_current;
403 assert( (unsigned)bits < 32 );
405 if( (m_current = (uchar*)(current - mask)) >= m_end )
408 current = ((ulong*)m_current) + mask;
410 m_bit_idx = new_bit_idx & 31;
411 return ((current[0] >> bit_idx) |
412 ((current[1] <<-bit_idx) & mask)) & bs_bit_mask[bits];
415 int RLBitStream::Show( int bits )
417 int bit_idx = m_bit_idx;
418 int new_bit_idx = bit_idx + bits;
419 int mask = new_bit_idx >= 32 ? -1 : 0;
420 ulong* current = (ulong*)m_current;
422 assert( (unsigned)bits < 32 );
424 if( (uchar*)(current - mask) >= m_end )
427 current = ((ulong*)m_current) + mask;
428 m_current = (uchar*)current;
430 return ((current[0] >> bit_idx) |
431 ((current[1] <<-bit_idx) & mask)) & bs_bit_mask[bits];
435 void RLBitStream::Move( int shift )
437 int new_bit_idx = m_bit_idx + shift;
438 m_current += (new_bit_idx >> 5) << 2;
439 m_bit_idx = new_bit_idx & 31;
443 int RLBitStream::GetHuff( const short* table )
450 int table_bits = table[0];
451 val = table[Show(table_bits) + 2];
452 code_bits = val & 15;
455 if( code_bits != 0 ) break;
461 if( val == RBS_HUFF_FORB )
464 longjmp( m_jmp_buf, RBS_THROW_FORB );
470 void RLBitStream::Skip( int bytes )
475 ///////////////////////// RMBitStream ////////////////////////////
478 RMBitStream::~RMBitStream()
483 void RMBitStream::ReadBlock()
485 RBaseStream::ReadBlock();
486 if( !bsIsBigEndian() )
487 bsBSwapBlock( m_start, m_end );
491 void RMBitStream::SetPos( int pos )
493 RBaseStream::SetPos(pos);
494 int offset = (int)(m_current - m_end);
495 m_current = m_end + ((offset - 1) & -4);
496 m_bit_idx = (32 - (offset&3)*8) & 31;
500 int RMBitStream::GetPos()
502 return RBaseStream::GetPos() + ((32 - m_bit_idx) >> 3);
506 int RMBitStream::Get( int bits )
508 int bit_idx = m_bit_idx - bits;
509 int mask = bit_idx >> 31;
510 ulong* current = ((ulong*)m_current) - mask;
512 assert( (unsigned)bits < 32 );
514 if( (m_current = (uchar*)current) >= m_end )
517 current = (ulong*)m_current;
519 m_bit_idx = bit_idx &= 31;
520 return (((current[-1] << -bit_idx) & mask)|
521 (current[0] >> bit_idx)) & bs_bit_mask[bits];
525 int RMBitStream::Show( int bits )
527 int bit_idx = m_bit_idx - bits;
528 int mask = bit_idx >> 31;
529 ulong* current = ((ulong*)m_current) - mask;
531 assert( (unsigned)bits < 32 );
533 if( ((uchar*)current) >= m_end )
535 m_current = (uchar*)current;
537 current = (ulong*)m_current;
540 return (((current[-1]<<-bit_idx) & mask)|
541 (current[0] >> bit_idx)) & bs_bit_mask[bits];
545 int RMBitStream::GetHuff( const short* table )
552 int table_bits = table[0];
553 val = table[Show(table_bits) + 1];
554 code_bits = val & 15;
557 if( code_bits != 0 ) break;
563 if( val == RBS_HUFF_FORB )
566 longjmp( m_jmp_buf, RBS_THROW_FORB );
573 void RMBitStream::Move( int shift )
575 int new_bit_idx = m_bit_idx - shift;
576 m_current -= (new_bit_idx >> 5)<<2;
577 m_bit_idx = new_bit_idx & 31;
581 void RMBitStream::Skip( int bytes )
587 static const int huff_val_shift = 20, huff_code_mask = (1 << huff_val_shift) - 1;
589 bool bsCreateDecodeHuffmanTable( const int* src, short* table, int max_size )
591 const int forbidden_entry = (RBS_HUFF_FORB << 4)|1;
592 int first_bits = src[0];
599 int size = (1 << first_bits) + 1;
602 /* calc bit depths of sub tables */
603 memset( sub_tables, 0, ((size_t)1 << first_bits)*sizeof(sub_tables[0]) );
604 for( i = 1, k = 1; src[k] >= 0; i++ )
606 int code_count = src[k++];
607 int sb = i - first_bits;
612 for( code_count += k; k < code_count; k++ )
614 int code = src[k] & huff_code_mask;
615 sub_tables[code >> sb].bits = sb;
619 /* calc offsets of sub tables and whole size of table */
620 for( i = 0; i < (1 << first_bits); i++ )
622 int b = sub_tables[i].bits;
626 sub_tables[i].offset = size;
631 if( size > max_size )
637 /* fill first table and subtables with forbidden values */
638 for( i = 0; i < size; i++ )
640 table[i] = (short)forbidden_entry;
643 /* write header of first table */
644 table[0] = (short)first_bits;
646 /* fill first table and sub tables */
647 for( i = 1, k = 1; src[k] >= 0; i++ )
649 int code_count = src[k++];
650 for( code_count += k; k < code_count; k++ )
652 int table_bits= first_bits;
654 int code = src[k] & huff_code_mask;
655 int val = src[k] >>huff_val_shift;
658 if( code_bits > table_bits )
660 int idx = code >> (code_bits -= table_bits);
661 code &= (1 << code_bits) - 1;
662 offset = sub_tables[idx].offset;
663 table_bits= sub_tables[idx].bits;
664 /* write header of subtable */
665 table[offset] = (short)table_bits;
666 /* write jump to subtable */
667 table[idx + 1]= (short)(offset << 4);
670 table_bits -= code_bits;
671 assert( table_bits >= 0 );
672 val = (val << 4) | code_bits;
673 offset += (code << table_bits) + 1;
675 for( j = 0; j < (1 << table_bits); j++ )
677 assert( table[offset + j] == forbidden_entry );
678 table[ offset + j ] = (short)val;
686 int* bsCreateSourceHuffmanTable( const uchar* src, int* dst,
687 int max_bits, int first_bits )
689 int i, val_idx, code = 0;
692 for( i = 1, val_idx = max_bits; i <= max_bits; i++ )
694 int code_count = src[i - 1];
697 for( int k = 0; k < code_count; k++ )
699 dst[k + 1] = (src[val_idx + k] << huff_val_shift)|(code + k);
702 dst += code_count + 1;
703 val_idx += code_count;
710 /////////////////////////// WBaseStream /////////////////////////////////
712 // WBaseStream - base class for output streams
713 WBaseStream::WBaseStream()
715 m_start = m_end = m_current = 0;
717 m_block_size = BS_DEF_BLOCK_SIZE;
722 WBaseStream::~WBaseStream()
724 Close(); // Close files
725 Release(); // free buffers
729 bool WBaseStream::IsOpened()
735 void WBaseStream::Allocate()
738 m_start = new uchar[m_block_size];
740 m_end = m_start + m_block_size;
745 void WBaseStream::WriteBlock()
747 int size = (int)(m_current - m_start);
748 assert( m_file != 0 );
750 //fseek( m_file, m_block_pos, SEEK_SET );
751 fwrite( m_start, 1, size, m_file );
754 /*if( written < size ) throw RBS_THROW_EOS;*/
760 bool WBaseStream::Open( const char* filename )
765 m_file = fopen( filename, "wb" );
777 void WBaseStream::Close()
789 void WBaseStream::Release()
795 m_start = m_end = m_current = 0;
799 void WBaseStream::SetBlockSize( int block_size )
801 assert( block_size > 0 && (block_size & (block_size-1)) == 0 );
803 if( m_start && block_size == m_block_size ) return;
805 m_block_size = block_size;
810 int WBaseStream::GetPos()
812 assert( IsOpened() );
813 return m_block_pos + (int)(m_current - m_start);
817 ///////////////////////////// WLByteStream ///////////////////////////////////
819 WLByteStream::~WLByteStream()
823 void WLByteStream::PutByte( int val )
825 *m_current++ = (uchar)val;
826 if( m_current >= m_end )
831 void WLByteStream::PutBytes( const void* buffer, int count )
833 uchar* data = (uchar*)buffer;
835 assert( data && m_current && count >= 0 );
839 int l = (int)(m_end - m_current);
846 memcpy( m_current, data, l );
851 if( m_current == m_end )
857 void WLByteStream::PutWord( int val )
859 uchar *current = m_current;
861 if( current+1 < m_end )
863 current[0] = (uchar)val;
864 current[1] = (uchar)(val >> 8);
865 m_current = current + 2;
866 if( m_current == m_end )
877 void WLByteStream::PutDWord( int val )
879 uchar *current = m_current;
881 if( current+3 < m_end )
883 current[0] = (uchar)val;
884 current[1] = (uchar)(val >> 8);
885 current[2] = (uchar)(val >> 16);
886 current[3] = (uchar)(val >> 24);
887 m_current = current + 4;
888 if( m_current == m_end )
901 ///////////////////////////// WMByteStream ///////////////////////////////////
903 WMByteStream::~WMByteStream()
908 void WMByteStream::PutWord( int val )
910 uchar *current = m_current;
912 if( current+1 < m_end )
914 current[0] = (uchar)(val >> 8);
915 current[1] = (uchar)val;
916 m_current = current + 2;
917 if( m_current == m_end )
928 void WMByteStream::PutDWord( int val )
930 uchar *current = m_current;
932 if( current+3 < m_end )
934 current[0] = (uchar)(val >> 24);
935 current[1] = (uchar)(val >> 16);
936 current[2] = (uchar)(val >> 8);
937 current[3] = (uchar)val;
938 m_current = current + 4;
939 if( m_current == m_end )
952 ///////////////////////////// WMBitStream ///////////////////////////////////
954 WMBitStream::WMBitStream()
961 WMBitStream::~WMBitStream()
966 bool WMBitStream::Open( const char* filename )
969 return WBaseStream::Open( filename );
973 void WMBitStream::ResetBuffer()
980 void WMBitStream::Flush()
984 Put( m_pad_val, m_bit_idx & 7 );
985 *((ulong*&)m_current)++ = m_val;
990 void WMBitStream::Close()
995 WBaseStream::Close();
1000 void WMBitStream::WriteBlock()
1002 if( !bsIsBigEndian() )
1003 bsBSwapBlock( m_start, m_current );
1004 WBaseStream::WriteBlock();
1008 int WMBitStream::GetPos()
1010 return WBaseStream::GetPos() + ((32 - m_bit_idx) >> 3);
1014 void WMBitStream::Put( int val, int bits )
1016 int bit_idx = m_bit_idx - bits;
1017 ulong curval = m_val;
1019 assert( 0 <= bits && bits < 32 );
1021 val &= bs_bit_mask[bits];
1025 curval |= val << bit_idx;
1029 *((ulong*&)m_current)++ = curval | ((unsigned)val >> -bit_idx);
1030 if( m_current >= m_end )
1035 curval = val << bit_idx;
1039 m_bit_idx = bit_idx;
1043 void WMBitStream::PutHuff( int val, const ulong* table )
1045 int min_val = (int)table[0];
1048 assert( (unsigned)val < table[1] );
1050 ulong code = table[val + 2];
1051 assert( code != 0 );
1053 Put( code >> 8, code & 255 );
1057 bool bsCreateEncodeHuffmanTable( const int* src, ulong* table, int max_size )
1060 int min_val = INT_MAX, max_val = INT_MIN;
1063 /* calc min and max values in the table */
1064 for( i = 1, k = 1; src[k] >= 0; i++ )
1066 int code_count = src[k++];
1068 for( code_count += k; k < code_count; k++ )
1070 int val = src[k] >> huff_val_shift;
1078 size = max_val - min_val + 3;
1080 if( size > max_size )
1086 memset( table, 0, size*sizeof(table[0]));
1089 table[1] = size - 2;
1091 for( i = 1, k = 1; src[k] >= 0; i++ )
1093 int code_count = src[k++];
1095 for( code_count += k; k < code_count; k++ )
1097 int val = src[k] >> huff_val_shift;
1098 int code = src[k] & huff_code_mask;
1100 table[val - min_val + 2] = (code << 8) | i;