00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #ifndef MLN_ACCU_TRANSFORM_LINE_HH
00028 # define MLN_ACCU_TRANSFORM_LINE_HH
00029 
00042 
00043 # include <mln/core/concept/image.hh>
00044 # include <mln/core/concept/meta_accumulator.hh>
00045 # include <mln/extension/adjust.hh>
00046 
00047 
00048 namespace mln
00049 {
00050 
00051   namespace accu
00052   {
00053 
00054 
00055     template <typename A, typename I>
00056     mln_ch_value(I, mln_result(A))
00057     transform_line(const Accumulator<A>& a,
00058                    const Image<I>& input,
00059                    unsigned length, unsigned dir);
00060 
00061     template <typename A, typename I>
00062     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00063     transform_line(const Meta_Accumulator<A>& a,
00064                    const Image<I>& input,
00065                    unsigned length, unsigned dir);
00066 
00067 
00068 
00069 # ifndef MLN_INCLUDE_ONLY
00070 
00071 
00072     
00073 
00074 
00075     namespace internal
00076     {
00077 
00078       template <typename A, typename I>
00079       void
00080       transform_line_tests(const Accumulator<A>& a_, const Image<I>& input_)
00081       {
00082         A a = exact(a_);
00083         const I& input = exact(input_);
00084 
00085         mln_precondition(input.is_valid());
00086         mln_psite(I)* p;
00087         mln_precondition(sizeof(a.take(input(*p)), 0) == sizeof(int));
00088 
00089         (void) p;
00090         (void) a;
00091         (void) input;
00092       }
00093 
00094     } 
00095 
00096 
00097 
00098     
00099 
00100 
00101     namespace impl
00102     {
00103 
00104       namespace generic
00105       {
00106 
00107         template <typename A, typename I>
00108         inline
00109         mln_ch_value(I, mln_result(A))
00110         transform_line(const Accumulator<A>& a_,
00111                        const Image<I>& input_,
00112                        unsigned length, unsigned dir)
00113         {
00114           trace::entering("accu::impl::transform_line");
00115 
00116           const I& input = exact(input_);
00117           A a = exact(a_);
00118 
00119           internal::transform_line_tests(a, input);
00120 
00121           extension::adjust(input, length / 2); 
00122 
00123           mln_ch_value(I, mln_result(A)) output;
00124           initialize(output, input);
00125 
00126           typedef mln_psite(I) P;
00127           const P
00128             pmin = input.domain().pmin(),
00129             pmax = input.domain().pmax();
00130           const def::coord
00131             pmax_dir = pmax[dir],
00132             pmin_dir = pmin[dir];
00133 
00134           P p = pmin, 
00135             qt, qu;
00136           def::coord& p_dir  = p [dir];
00137           def::coord& qt_dir = qt[dir];
00138           def::coord& qu_dir = qu[dir];
00139 
00140           do
00141             {
00142 
00143               
00144               
00145 
00146               qt = p;
00147               qt_dir = p_dir - length / 2;
00148               qu = qt;
00149               a.init();
00150 
00151               for (unsigned i = 0; i < length; ++i)
00152                 {
00153                   if (input.has(qt))
00154                     a.take(input(qt));
00155                   qt_dir++;
00156                 }
00157               if (input.has(p))
00158                 output(p) = a.to_result();
00159 
00160               
00161               
00162 
00163               while (p_dir < pmax_dir)
00164                 {
00165                   if (input.has(qt))
00166                     a.take(input(qt));
00167                   qt_dir++;
00168 
00169                   if (input.has(qu))
00170                     a.untake(input(qu));
00171                   qu_dir++;
00172 
00173                   ++p_dir;
00174                   if (input.has(p))
00175                     output(p) = a.to_result();
00176                 }
00177 
00178               
00179               
00180 
00181               p_dir = pmin_dir;
00182 
00183               for (int c = P::dim - 1; c >= 0; --c)
00184                 {
00185                   if (c == int(dir))
00186                     continue;
00187                   if (p[c] != pmax[c])
00188                     {
00189                       ++p[c];
00190                       break;
00191                     }
00192                   p[c] = pmin[c];
00193                 }
00194 
00195             } while (p != pmin);
00196 
00197           trace::exiting("accu::impl::transform_line");
00198           return output;
00199         }
00200 
00201       } 
00202 
00203 
00204       template <typename A, typename I>
00205       inline
00206       mln_ch_value(I, mln_result(A))
00207       transform_line_fastest(const Accumulator<A>& a_,
00208                              const Image<I>& input_,
00209                              unsigned length, unsigned dir)
00210       {
00211         trace::entering("accu::impl::transform_line_fastest");
00212 
00213         const I& input = exact(input_);
00214         A a = exact(a_);
00215 
00216         internal::transform_line_tests(a, input);
00217 
00218         extension::adjust(input, length / 2); 
00219 
00220         mln_ch_value(I, mln_result(A)) output;
00221         initialize(output, input);
00222 
00223         typedef mln_psite(I) P;
00224         const P
00225           pmin = input.domain().pmin(),
00226           pmax = input.domain().pmax();
00227         const def::coord
00228           pmax_dir = pmax[dir],
00229           pmin_dir = pmin[dir];
00230 
00231         P p = pmin; 
00232         def::coord& p_dir  = p[dir];
00233         
00234         
00235         mln_delta(P) dp(literal::zero);
00236         dp[dir] = 1;
00237         int step = input.delta_index(dp);
00238 
00239         do
00240           {
00241             
00242             
00243 
00244             unsigned o_p = input.index_of_point(p);
00245             unsigned o_qt = o_p - (length / 2) * step;
00246             unsigned o_qu = o_qt;
00247             a.init();
00248 
00249             for (unsigned i = 0; i < length; ++i)
00250               
00251               
00252               
00253               {
00254                 a.take(input.element(o_qt));
00255                 o_qt += step;
00256               }
00257             output.element(o_p) = a.to_result();
00258 
00259             
00260             
00261 
00262             while (p_dir < pmax_dir)
00263               
00264               
00265               
00266               {
00267                 a.take(input.element(o_qt));
00268                 o_qt += step;
00269 
00270                 a.untake(input.element(o_qu));
00271                 o_qu += step;
00272 
00273                 ++p_dir;
00274                 o_p += step;
00275                 output.element(o_p) = a.to_result();
00276               }
00277 
00278             
00279             
00280 
00281             p_dir = pmin_dir;
00282 
00283             for (int c = P::dim - 1; c >= 0; --c)
00284               {
00285                 if (c == int(dir))
00286                   continue;
00287                 if (p[c] != pmax[c])
00288                   {
00289                     ++p[c];
00290                     break;
00291                   }
00292                 p[c] = pmin[c];
00293               }
00294 
00295           } while (p != pmin);
00296         
00297         trace::exiting("accu::impl::transform_line_fastest");
00298         return output;
00299       }
00300 
00301       
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430     } 
00431 
00432 
00433 
00434 
00435     
00436 
00437 
00438     namespace internal
00439     {
00440 
00441       template <typename A, typename I>
00442       inline
00443       mln_ch_value(I, mln_result(A))
00444       transform_line_dispatch(trait::image::speed::any,
00445                               trait::accumulator::when_pix::any,
00446                               const Accumulator<A>& a,
00447                               const Image<I>& input,
00448                               unsigned length, unsigned dir)
00449       {
00450         return impl::generic::transform_line(a,
00451                                              input,
00452                                              length, dir);
00453       }
00454 
00455       template <typename A, typename I>
00456       inline
00457       mln_ch_value(I, mln_result(A))
00458       transform_line_dispatch(trait::image::speed::fastest,
00459                               trait::accumulator::when_pix::use_none,
00460                               const Accumulator<A>& a,
00461                               const Image<I>& input,
00462                               unsigned length, unsigned dir)
00463       {
00464         return impl::transform_line_fastest(a,
00465                                             input,
00466                                             length, dir);
00467       }
00468 
00469       template <typename A, typename I>
00470       inline
00471       mln_ch_value(I, mln_result(A))
00472       transform_line_dispatch(trait::image::speed::fastest,
00473                               trait::accumulator::when_pix::use_v,
00474                               const Accumulator<A>& a,
00475                               const Image<I>& input,
00476                               unsigned length, unsigned dir)
00477       {
00478         return impl::transform_line_fastest(a,
00479                                             input,
00480                                             length, dir);
00481       }
00482 
00483       template <typename A, typename I>
00484       inline
00485       mln_ch_value(I, mln_result(A))
00486       transform_line_dispatch(const Accumulator<A>& a,
00487                               const Image<I>& input,
00488                               unsigned length, unsigned dir)
00489       {
00490         return transform_line_dispatch(mln_trait_image_speed(I)(),
00491                                        mln_trait_accumulator_when_pix(A)(),
00492                                        a, input, length, dir);
00493       }
00494 
00495     } 
00496 
00497 
00498 
00499 
00500     
00501 
00502 
00503     template <typename A, typename I>
00504     inline
00505     mln_ch_value(I, mln_result(A))
00506     transform_line(const Accumulator<A>& a,
00507                    const Image<I>& input,
00508                    unsigned length, unsigned dir)
00509     {
00510       trace::entering("accu::transform_line");
00511 
00512       internal::transform_line_tests(a, input);
00513 
00514       extension::adjust(input, length / 2); 
00515 
00516       mln_ch_value(I, mln_result(A)) output;
00517       output = internal::transform_line_dispatch(a, input, length, dir);
00518 
00519       trace::exiting("accu::transform_line");
00520       return output;
00521     }
00522 
00523 
00524     template <typename A, typename I>
00525     inline
00526     mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00527     transform_line(const Meta_Accumulator<A>& a,
00528                    const Image<I>& input,
00529                    unsigned length, unsigned dir)
00530     {
00531       trace::entering("accu::transform_line");
00532 
00533       typedef mln_accu_with(A, mln_value(I)) A_;
00534       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00535 
00536       internal::transform_line_tests(a_, input);
00537           
00538       mln_ch_value(I, mln_result(A_)) output;
00539       output = internal::transform_line_dispatch(a_, input, length, dir);
00540 
00541       trace::exiting("accu::transform_line");
00542       return output;
00543     }
00544 
00545 
00546 # endif // ! MLN_INCLUDE_ONLY
00547 
00548   } 
00549 
00550 } 
00551 
00552 
00553 #endif // ! MLN_ACCU_TRANSFORM_LINE_HH