- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

bitmap.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
33
34 #ifndef __INCLUDE_BITMAP_H__
35 #define __INCLUDE_BITMAP_H__
36
37
38 #ifndef __INCLUDE_MIST_CONF_H__
39 #include "config/mist_conf.h"
40 #endif
41
42 #ifndef __INCLUDE_MIST_H__
43 #include "mist.h"
44 #endif
45
46 #ifndef __INCLUDE_MIST_COLOR_H__
47 #include "config/color.h"
48 #endif
49
50
51
52 // mist名前空間の始まり
53 _MIST_BEGIN
54
55 template < size_t BITS >
56 struct bitmap_type
57 {
58 typedef bgr< unsigned char > value_type;
59 };
60
61 template < >
62 struct bitmap_type< 8 >
63 {
64 typedef unsigned char value_type;
65 };
66
67
79 template < size_t BITS, class Allocator = std::allocator< unsigned char > >
80 class bitmap : public array< unsigned char, Allocator >
81 {
82 public:
83 typedef typename bitmap_type< BITS >::value_type value_type;
84 typedef value_type* pointer;
85 typedef value_type& reference;
86 typedef const value_type& const_reference;
87 typedef const value_type* const_pointer;
88 typedef typename Allocator::size_type size_type;
89 typedef typename Allocator::difference_type difference_type;
90
91
92 protected:
93 typedef array< unsigned char, Allocator > base;
94 size_type size1_;
95 size_type size2_;
96 size_type nbytes_;
97
99 static size_type pixel_bytes( )
100 {
101 return( BITS / 8 );
102 }
103
105 static size_type num_bytes( size_type width )
106 {
107 width = width * pixel_bytes( );
108 if( width % 4 > 0 )
109 {
110 width += 4 - ( width % 4 );
111 }
112 return( width );
113 }
114
115 public:
129 bool resize( size_type num1, size_type num2, size_type dmy1 = 0 )
130 {
131 nbytes_ = num_bytes( num1 );
132 if( base::resize( nbytes_ * num2 ) )
133 {
134 size1_ = num1;
135 size2_ = num2;
136 return( true );
137 }
138 else
139 {
140 size1_ = size2_ = nbytes_ = 0;
141 return( false );
142 }
143 }
144
155 bool trim( size_type x, size_type y, difference_type w = -1, difference_type h = -1 )
156 {
157 difference_type w_ = width( );
158 difference_type h_ = height( );
159 if( w_ <= static_cast< difference_type >( x ) || w_ < static_cast< difference_type >( x + w ) )
160 {
161 return( false );
162 }
163 else if( h_ <= static_cast< difference_type >( y ) || h_ < static_cast< difference_type >( y + h ) )
164 {
165 return( false );
166 }
167 else if( w_ == w && h_ == h )
168 {
169 return( true );
170 }
171
172 if( w < 0 )
173 {
174 w = w_ - x;
175 }
176 if( h < 0 )
177 {
178 h = h_ - y;
179 }
180
181
182 if( base::is_memory_shared( ) )
183 {
184 // 外部メモリを利用している場合
185 bitmap o( *this );
186 if( resize( w, h ) )
187 {
188 for( difference_type j = 0 ; j < h ; j++ )
189 {
190 for( difference_type i = 0 ; i < w ; i++ )
191 {
192 operator ()( i, j ) = o( i + x, j + y );
193 }
194 }
195 }
196 else
197 {
198 return( false );
199 }
200 }
201 else
202 {
203 bitmap o( w, h );
204 for( difference_type j = 0 ; j < h ; j++ )
205 {
206 for( difference_type i = 0 ; i < w ; i++ )
207 {
208 o( i, j ) = operator ()( i + x, j + y );
209 }
210 }
211
212 swap( o );
213 }
214
215 return( true );
216 }
217
218
228 bool swap( bitmap &a )
229 {
230 if( base::swap( a ) )
231 {
232 size_type _dmy_size1 = size1_;
233 size_type _dmy_size2 = size2_;
234 size1_ = a.size1_;
235 size2_ = a.size2_;
236 a.size1_ = _dmy_size1;
237 a.size2_ = _dmy_size2;
238 return( true );
239 }
240 else
241 {
242 return( false );
243 }
244 }
245
246
251 void clear( )
252 {
253 base::clear( );
254 size1_ = size2_ = 0;
255 }
256
257
258 size_type size1( ) const { return( size1_ ); }
259 size_type size2( ) const { return( size2_ ); }
260 size_type width( ) const { return( size1_ ); }
261 size_type height( ) const { return( size2_ ); }
262
263 size_type size( ) const { return( size1_ * size2_ ); }
264
265 public:
276 template < size_t BBITS, class AAlocator >
277 const bitmap& operator =( const bitmap< BBITS, AAlocator > &o )
278 {
279 if( resize( o.size1( ), o.size2( ) ) )
280 {
281 for( size_type j = 0 ; j < size2_ ; j++ )
282 {
283 for( size_type i = 0 ; i < size1_ ; i++ )
284 {
285 operator ()( i, j ) = o( i, j );
286 }
287 }
288 }
289
290 return( *this );
291 }
292
293
304 template < class TT, class AAlocator >
305 const bitmap& operator =( const array2< TT, AAlocator > &o )
306 {
307 if( resize( o.size1( ), o.size2( ) ) )
308 {
309 for( size_type j = 0 ; j < size2_ ; j++ )
310 {
311 for( size_type i = 0 ; i < size1_ ; i++ )
312 {
313 operator ()( i, j ) = o( i, j );
314 }
315 }
316 }
317
318 return( *this );
319 }
320
321
331 const bitmap& operator =( const bitmap &o )
332 {
333 if( this == &o ) return( *this );
334
335 base::operator =( o );
336 size1_ = o.size1_;
337 size2_ = o.size2_;
338
339 return( *this );
340 }
341
342 // 要素へのアクセス
343 protected:
351 pointer paccess( size_type i, size_type j )
352 {
353 return( reinterpret_cast< pointer >( base::data_ + i * pixel_bytes( ) + j * nbytes_ ) );
354 }
355
363 const_pointer paccess( size_type i, size_type j ) const
364 {
365 return( reinterpret_cast< const_pointer >( base::data_ + i * pixel_bytes( ) + j * nbytes_ ) );
366 }
367
368 public:
377 reference operator []( size_type index )
378 {
379 _CHECK_ACCESS_VIOLATION1U_( index )
380 size_type j = index / size1_;
381 size_type i = index - j * size1_;
382 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
383 }
384
385
394 reference operator []( size_type index ) const
395 {
396 _CHECK_ACCESS_VIOLATION1U_( index )
397 size_type j = index / size1_;
398 size_type i = index - j * size1_;
399 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
400 }
401
402
413 reference at( size_type i, size_type j, size_type dmy = 0 )
414 {
415 _CHECK_ACCESS_VIOLATION2U_( i, j )
416 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
417 }
418
419
430 const_reference at( size_type i, size_type j, size_type dmy = 0 ) const
431 {
432 _CHECK_ACCESS_VIOLATION2U_( i, j )
433 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
434 }
435
436
447 reference operator ()( size_type i, size_type j, size_type dmy = 0 )
448 {
449 _CHECK_ACCESS_VIOLATION2U_( i, j )
450 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
451 }
452
453
464 const_reference operator ()( size_type i, size_type j, size_type dmy = 0 ) const
465 {
466 _CHECK_ACCESS_VIOLATION2U_( i, j )
467 return( reinterpret_cast< reference >( base::data_[ i * pixel_bytes( ) + j * nbytes_ ] ) );
468 }
469
470
471 public:
473 bitmap( ) : base( ), size1_( 0 ), size2_( 0 ), nbytes_( 0 ) {}
474
476 explicit bitmap( const Allocator &a ) : base( a ), size1_( 0 ), size2_( 0 ), nbytes_( 0 ) {}
477
479 bitmap( size_type num1, size_type num2 ) : base( num_bytes( num1 ) * num2 ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
480 {
481 if( base::empty( ) ) size1_ = size2_ = nbytes_ = 0;
482 }
483
485 bitmap( size_type num1, size_type num2, const Allocator &a ) : base( num_bytes( num1 ) * num2, a ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
486 {
487 if( base::empty( ) ) size1_ = size2_ = nbytes_ = 0;
488 }
489
490
492 bitmap( size_type num1, size_type num2, const value_type &val ) : base( num_bytes( num1 ) * num2, val ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
493 {
494 if( base::empty( ) ) size1_ = size2_ = nbytes_ = 0;
495 }
496
498 bitmap( size_type num1, size_type num2, const value_type &val, const Allocator &a ) : base( num_bytes( num1 ) * num2, val, a ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
499 {
500 if( base::empty( ) ) size1_ = size2_ = nbytes_ = 0;
501 }
502
503
505 bitmap( size_type num1, size_type num2, void *ptr, size_type mem_available ) : base( num_bytes( num1 ) * num2, reinterpret_cast< unsigned char * >( ptr ), mem_available ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
506 {
507 if( base::empty( ) ) size1_ = size2_ = nbytes_ = 0;
508 }
509
511 bitmap( size_type num1, size_type num2, const value_type &val, void *ptr, size_type mem_available ) : base( num_bytes( num1 ) * num2, reinterpret_cast< unsigned char * >( ptr ), mem_available ), size1_( num1 ), size2_( num2 ), nbytes_( num_bytes( num1 ) )
512 {
513 if( base::empty( ) )
514 {
515 size1_ = size2_ = nbytes_ = 0;
516 }
517 else
518 {
519 for( size_type j = 0 ; j < size2_ ; j++ )
520 {
521 for( size_type i = 0 ; i < size1_ ; i++ )
522 {
523 operator ()( i, j ) = val;
524 }
525 }
526 }
527 }
528
529
534 template < size_t BBITS, class AAlocator >
535 bitmap( const bitmap< BBITS, AAlocator > &o ) : base( ), size1_( 0 ), size2_( 0 ), nbytes_( 0 )
536 {
537 if( resize( o.size1( ), o.size2( ) ) )
538 {
539 for( size_type j = 0 ; j < size2( ) ; j++ )
540 {
541 for( size_type i = 0 ; i < size1( ) ; i++ )
542 {
543 operator ()( i, j ) = o( i, j );
544 }
545 }
546 }
547 }
548
549
554 template < class TT, class AAlocator >
555 bitmap( const array2< TT, AAlocator > &o ) : base( ), size1_( 0 ), size2_( 0 ), nbytes_( 0 )
556 {
557 if( resize( o.size1( ), o.size2( ) ) )
558 {
559 for( size_type j = 0 ; j < size2( ) ; j++ )
560 {
561 for( size_type i = 0 ; i < size1( ) ; i++ )
562 {
563 operator ()( i, j ) = o( i, j );
564 }
565 }
566 }
567 }
568
570 bitmap( const bitmap< BITS, Allocator > &o ) : base( o ), size1_( o.size1_ ), size2_( o.size2_ ), nbytes_( o.nbytes_ ) {}
571 };
572
573
574
588 template < size_t BITS, class Allocator >
589 inline std::ostream &operator <<( std::ostream &out, const bitmap< BITS, Allocator > &a )
590 {
591 typename bitmap< BITS, Allocator >::size_type i, j;
592 for( j = 0 ; j < a.size2( ) ; j++ )
593 {
594 if( j != 0 )
595 {
596 out << std::endl;
597 }
598 for( i = 0 ; i < a.size1( ) ; i++ )
599 {
600 out << a( i, j );
601 if( i != a.size1( ) - 1 ) out << ", ";
602 }
603 }
604
605 return( out );
606 }
607
608
609
610 // mist名前空間の終わり
611 _MIST_END
612
613
614 #endif // __INCLUDE_MIST_H__
615