34 #ifndef __INCLUDE_MIST_FIGURE_FUSION__
35 #define __INCLUDE_MIST_FIGURE_FUSION__
38 #ifndef __INCLUDE_MIST_H__
42 #ifndef __INCLUDE_MIST_THREAD__
43 #include "../thread.h"
46 #ifndef __INCLUDE_MIST_LIMITS__
47 #include "../limits.h"
57 namespace __fusion_controller__
59 template <
int DIMENSION >
62 template <
class Array >
63 inline static typename Array::value_type &at( Array &in,
typename Array::size_type _1,
typename Array::size_type _2,
typename Array::size_type _3 )
65 return( in( _1, _2, _3 ) );
68 template <
class Array >
69 inline static typename Array::size_type size1(
const Array &in ){
return( in.size1( ) ); }
71 template <
class Array >
72 inline static typename Array::size_type size2(
const Array &in ){
return( in.size2( ) ); }
74 template <
class Array >
75 inline static typename Array::size_type size3(
const Array &in ){
return( in.size3( ) ); }
79 struct __access__< 2 >
81 template <
class Array >
82 inline static typename Array::value_type &at( Array &in,
typename Array::size_type _1,
typename Array::size_type _2,
typename Array::size_type _3 )
84 return( in( _2, _1, _3 ) );
87 template <
class Array >
88 inline static typename Array::size_type size1(
const Array &in ){
return( in.size2( ) ); }
90 template <
class Array >
91 inline static typename Array::size_type size2(
const Array &in ){
return( in.size1( ) ); }
93 template <
class Array >
94 inline static typename Array::size_type size3(
const Array &in ){
return( in.size3( ) ); }
98 struct __access__< 3 >
100 template <
class Array >
101 inline static typename Array::value_type &at( Array &in,
typename Array::size_type _1,
typename Array::size_type _2,
typename Array::size_type _3 )
103 return( in( _2, _3, _1 ) );
106 template <
class Array >
107 inline static typename Array::size_type size1(
const Array &in ){
return( in.size3( ) ); }
109 template <
class Array >
110 inline static typename Array::size_type size2(
const Array &in ){
return( in.size1( ) ); }
112 template <
class Array >
113 inline static typename Array::size_type size3(
const Array &in ){
return( in.size2( ) ); }
120 template <
class Array1,
class Array2 >
121 static void pre_process(
const Array1 &in, Array2 &out )
123 typedef typename Array2::size_type size_type;
124 typedef typename Array2::value_type value_type;
127 for( size_type i = 0 ; i < in.size( ) ; i++ )
129 out[ i ] = in[ i ] > 0 ? infinity : 0;
133 template <
class Array >
134 static void post_process( Array &in )
136 typedef typename Array::size_type size_type;
137 typedef typename Array::value_type value_type;
139 for( size_type i = 0 ; i < in.size( ) ; i++ )
141 in[ i ] = in[ i ] > 0 ? 1 : 0;
145 template <
class Array,
int DIMENSION >
146 static void transform( Array &in,
typename Array::size_type length,
typename Array::size_type thread_id,
typename Array::size_type thread_num, __access__< DIMENSION > dmy )
148 typedef typename Array::size_type size_type;
149 typedef typename Array::value_type value_type;
150 typedef typename Array::difference_type difference_type;
151 typedef __access__< DIMENSION > access;
153 difference_type i1, i2, i3, l;
155 difference_type _1 = access::size1( in );
156 difference_type _2 = access::size2( in );
157 difference_type _3 = access::size3( in );
161 for( i3 = 0 ; i3 < _3 ; i3++ )
163 for( i2 = thread_id ; i2 < _2 ; i2 += thread_num )
165 for( i1 = 0, l = 0 ; i1 < _1 ; i1++ )
167 value_type &v = access::at( in, i1, i2, i3 );
174 v =
static_cast< value_type
>( l );
179 l =
static_cast< difference_type
>( v ) - 1;
183 for( i1 = _1 - 1, l = 0 ; i1 >= 0 ; i1-- )
185 value_type &v = access::at( in, i1, i2, i3 );
192 v =
static_cast< value_type
>( l );
197 l =
static_cast< difference_type
>( v ) - 1;
208 template <
class Array1,
class Array2 >
209 static void pre_process(
const Array1 &in, Array2 &out )
211 typedef typename Array2::size_type size_type;
212 typedef typename Array2::value_type value_type;
215 for( size_type i = 0 ; i < in.size( ) ; i++ )
217 out[ i ] = in[ i ] > 0 ? infinity : 0;
221 template <
class Array >
222 static void post_process( Array &in )
224 typedef typename Array::size_type size_type;
225 typedef typename Array::value_type value_type;
228 for( size_type i = 0 ; i < in.size( ) ; i++ )
230 in[ i ] = in[ i ] == infinity ? 1 : 0;
234 template <
class Array,
int DIMENSION >
235 static void transform( Array &in,
typename Array::size_type length,
typename Array::size_type thread_id,
typename Array::size_type thread_num, __access__< DIMENSION > dmy )
237 typedef typename Array::size_type size_type;
238 typedef typename Array::value_type value_type;
239 typedef typename Array::difference_type difference_type;
240 typedef __access__< DIMENSION > access;
242 difference_type i1, i2, i3, l;
244 difference_type _1 = access::size1( in );
245 difference_type _2 = access::size2( in );
246 difference_type _3 = access::size3( in );
250 for( i3 = 0 ; i3 < _3 ; i3++ )
252 for( i2 = thread_id ; i2 < _2 ; i2 += thread_num )
254 for( i1 = 0, l = 0 ; i1 < _1 ; i1++ )
256 value_type &v = access::at( in, i1, i2, i3 );
261 else if( v == infinity )
265 v =
static_cast< value_type
>( l );
271 v =
static_cast< value_type
>( l );
276 l =
static_cast< difference_type
>( v ) - 1;
280 for( i1 = _1 - 1, l = 0 ; i1 >= 0 ; i1-- )
282 value_type &v = access::at( in, i1, i2, i3 );
287 else if( v == infinity )
291 v =
static_cast< value_type
>( l );
297 v =
static_cast< value_type
>( l );
302 l =
static_cast< difference_type
>( v ) - 1;
312 template <
class T,
class Fusion >
313 class fusion_thread :
public mist::thread< fusion_thread< T, Fusion > >
317 typedef typename base::thread_exit_type thread_exit_type;
318 typedef typename T::size_type size_type;
319 typedef typename T::value_type value_type;
331 void setup_parameters( T &in, size_type axis, size_type len, size_type thread_id, size_type thread_num )
336 thread_id_ = thread_id;
337 thread_num_ = thread_num;
340 void setup_axis( size_type axis )
345 fusion_thread( size_type
id = 0, size_type num = 1 )
346 : thread_id_( id ), thread_num_( num ), in_( NULL ), length_( 1 ), axis_( 0 )
352 virtual thread_exit_type thread_function( )
398 template <
class Array1,
class Array2,
class Fusion >
399 bool fusion(
const Array1 &in, Array2 &out,
typename Array1::size_type length,
typename Array1::size_type thread_num, Fusion
fusion )
406 typedef typename Array2::size_type size_type;
407 typedef typename Array2::value_type value_type;
408 typedef __fusion_controller__::fusion_thread< Array2, Fusion > fusion_thread;
410 if( thread_num == 0 )
412 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
415 out.resize( in.size1( ), in.size2( ), in.size3( ) );
416 out.reso1( in.reso1( ) );
417 out.reso2( in.reso2( ) );
418 out.reso3( in.reso3( ) );
422 Fusion::pre_process( in, out );
424 fusion_thread *
thread =
new fusion_thread[ thread_num ];
426 if( in.width( ) > 1 )
429 for( i = 0 ; i < thread_num ; i++ )
431 thread[ i ].setup_parameters( out, 1, length, i, thread_num );
437 if( in.height( ) > 1 )
440 for( i = 0 ; i < thread_num ; i++ )
442 thread[ i ].setup_parameters( out, 2, length, i, thread_num );
448 if( in.depth( ) > 1 )
451 for( i = 0 ; i < thread_num ; i++ )
453 thread[ i ].setup_parameters( out, 3, length, i, thread_num );
461 Fusion::post_process( out );
487 template <
class Array1,
class Array2 >
488 bool expand_mdt(
const Array1 &in, Array2 &out,
typename Array1::size_type length = 1,
typename Array1::size_type thread_num = 0 )
505 template <
class Array1,
class Array2 >
506 bool shrink_mdt(
const Array1 &in, Array2 &out,
typename Array1::size_type length = 1,
typename Array1::size_type thread_num = 0 )
524 #endif // __INCLUDE_MIST_FIGURE_FUSION__