Fix CVEs for opencv 2.4
[platform/upstream/opencv.git] / modules / highgui / src / bitstrm.cpp
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     CV_Assert(current < m_end);
212
213     val = *((uchar*)current);
214     m_current = current + 1;
215     return val;
216 }
217
218
219 int RLByteStream::getBytes( void* buffer, int count )
220 {
221     uchar*  data = (uchar*)buffer;
222     int readed = 0;
223     assert( count >= 0 );
224
225     while( count > 0 )
226     {
227         int l;
228
229         for(;;)
230         {
231             l = (int)(m_end - m_current);
232             if( l > count ) l = count;
233             if( l > 0 ) break;
234             readBlock();
235         }
236         memcpy( data, m_current, l );
237         m_current += l;
238         data += l;
239         count -= l;
240         readed += l;
241     }
242     return readed;
243 }
244
245
246 ////////////  RLByteStream & RMByteStream <Get[d]word>s ////////////////
247
248 RMByteStream::~RMByteStream()
249 {
250 }
251
252
253 int  RLByteStream::getWord()
254 {
255     uchar *current = m_current;
256     int   val;
257
258     if( current+1 < m_end )
259     {
260         val = current[0] + (current[1] << 8);
261         m_current = current + 2;
262     }
263     else
264     {
265         val = getByte();
266         val|= getByte() << 8;
267     }
268     return val;
269 }
270
271
272 int  RLByteStream::getDWord()
273 {
274     uchar *current = m_current;
275     int   val;
276
277     if( current+3 < m_end )
278     {
279         val = current[0] + (current[1] << 8) +
280               (current[2] << 16) + (current[3] << 24);
281         m_current = current + 4;
282     }
283     else
284     {
285         val = getByte();
286         val |= getByte() << 8;
287         val |= getByte() << 16;
288         val |= getByte() << 24;
289     }
290     return val;
291 }
292
293
294 int  RMByteStream::getWord()
295 {
296     uchar *current = m_current;
297     int   val;
298
299     if( current+1 < m_end )
300     {
301         val = (current[0] << 8) + current[1];
302         m_current = current + 2;
303     }
304     else
305     {
306         val = getByte() << 8;
307         val|= getByte();
308     }
309     return val;
310 }
311
312
313 int  RMByteStream::getDWord()
314 {
315     uchar *current = m_current;
316     int   val;
317
318     if( current+3 < m_end )
319     {
320         val = (current[0] << 24) + (current[1] << 16) +
321               (current[2] << 8) + current[3];
322         m_current = current + 4;
323     }
324     else
325     {
326         val = getByte() << 24;
327         val |= getByte() << 16;
328         val |= getByte() << 8;
329         val |= getByte();
330     }
331     return val;
332 }
333
334 /////////////////////////// WBaseStream /////////////////////////////////
335
336 // WBaseStream - base class for output streams
337 WBaseStream::WBaseStream()
338 {
339     m_start = m_end = m_current = 0;
340     m_file = 0;
341     m_block_size = BS_DEF_BLOCK_SIZE;
342     m_is_opened = false;
343     m_buf = 0;
344 }
345
346
347 WBaseStream::~WBaseStream()
348 {
349     close();
350     release();
351 }
352
353
354 bool  WBaseStream::isOpened()
355 {
356     return m_is_opened;
357 }
358
359
360 void  WBaseStream::allocate()
361 {
362     if( !m_start )
363         m_start = new uchar[m_block_size];
364
365     m_end = m_start + m_block_size;
366     m_current = m_start;
367 }
368
369
370 void  WBaseStream::writeBlock()
371 {
372     int size = (int)(m_current - m_start);
373
374     assert( isOpened() );
375     if( size == 0 )
376         return;
377
378     if( m_buf )
379     {
380         size_t sz = m_buf->size();
381         m_buf->resize( sz + size );
382         memcpy( &(*m_buf)[sz], m_start, size );
383     }
384     else
385     {
386         fwrite( m_start, 1, size, m_file );
387     }
388     m_current = m_start;
389     m_block_pos += size;
390 }
391
392
393 bool  WBaseStream::open( const string& filename )
394 {
395     close();
396     allocate();
397
398     m_file = fopen( filename.c_str(), "wb" );
399     if( m_file )
400     {
401         m_is_opened = true;
402         m_block_pos = 0;
403         m_current = m_start;
404     }
405     return m_file != 0;
406 }
407
408 bool  WBaseStream::open( vector<uchar>& buf )
409 {
410     close();
411     allocate();
412
413     m_buf = &buf;
414     m_is_opened = true;
415     m_block_pos = 0;
416     m_current = m_start;
417
418     return true;
419 }
420
421 void  WBaseStream::close()
422 {
423     if( m_is_opened )
424         writeBlock();
425     if( m_file )
426     {
427         fclose( m_file );
428         m_file = 0;
429     }
430     m_buf = 0;
431     m_is_opened = false;
432 }
433
434
435 void  WBaseStream::release()
436 {
437     if( m_start )
438         delete[] m_start;
439     m_start = m_end = m_current = 0;
440 }
441
442
443 int  WBaseStream::getPos()
444 {
445     assert( isOpened() );
446     return m_block_pos + (int)(m_current - m_start);
447 }
448
449
450 ///////////////////////////// WLByteStream ///////////////////////////////////
451
452 WLByteStream::~WLByteStream()
453 {
454 }
455
456 void WLByteStream::putByte( int val )
457 {
458     *m_current++ = (uchar)val;
459     if( m_current >= m_end )
460         writeBlock();
461 }
462
463
464 void WLByteStream::putBytes( const void* buffer, int count )
465 {
466     uchar* data = (uchar*)buffer;
467
468     assert( data && m_current && count >= 0 );
469
470     while( count )
471     {
472         int l = (int)(m_end - m_current);
473
474         if( l > count )
475             l = count;
476
477         if( l > 0 )
478         {
479             memcpy( m_current, data, l );
480             m_current += l;
481             data += l;
482             count -= l;
483         }
484         if( m_current == m_end )
485             writeBlock();
486     }
487 }
488
489
490 void WLByteStream::putWord( int val )
491 {
492     uchar *current = m_current;
493
494     if( current+1 < m_end )
495     {
496         current[0] = (uchar)val;
497         current[1] = (uchar)(val >> 8);
498         m_current = current + 2;
499         if( m_current == m_end )
500             writeBlock();
501     }
502     else
503     {
504         putByte(val);
505         putByte(val >> 8);
506     }
507 }
508
509
510 void WLByteStream::putDWord( int val )
511 {
512     uchar *current = m_current;
513
514     if( current+3 < m_end )
515     {
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 )
522             writeBlock();
523     }
524     else
525     {
526         putByte(val);
527         putByte(val >> 8);
528         putByte(val >> 16);
529         putByte(val >> 24);
530     }
531 }
532
533
534 ///////////////////////////// WMByteStream ///////////////////////////////////
535
536 WMByteStream::~WMByteStream()
537 {
538 }
539
540
541 void WMByteStream::putWord( int val )
542 {
543     uchar *current = m_current;
544
545     if( current+1 < m_end )
546     {
547         current[0] = (uchar)(val >> 8);
548         current[1] = (uchar)val;
549         m_current = current + 2;
550         if( m_current == m_end )
551             writeBlock();
552     }
553     else
554     {
555         putByte(val >> 8);
556         putByte(val);
557     }
558 }
559
560
561 void WMByteStream::putDWord( int val )
562 {
563     uchar *current = m_current;
564
565     if( current+3 < m_end )
566     {
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 )
573             writeBlock();
574     }
575     else
576     {
577         putByte(val >> 24);
578         putByte(val >> 16);
579         putByte(val >> 8);
580         putByte(val);
581     }
582 }
583
584 }