Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
March 2011
- 7 participants
 - 277 discussions
 
                        
                            
                                
                            
                            last-svn-commit-804-gea8ad62	scribo/primitive/extract/separators_nonvisible.hh: Cleanup	and improve debug support.
                        
                        
by Guillaume Lazzara 14 Mar '11
                    by Guillaume Lazzara 14 Mar '11
14 Mar '11
                    
                        ---
 scribo/ChangeLog                                   |    5 +
 .../primitive/extract/separators_nonvisible.hh     |  661 ++++++--------------
 2 files changed, 200 insertions(+), 466 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b6f7f1a..d9e7e96 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	* scribo/primitive/extract/separators_nonvisible.hh: Cleanup and
+	improve debug support.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Various small fixes.
 
 	* scribo/filter/object_links_bottom_aligned.hh,
diff --git a/scribo/scribo/primitive/extract/separators_nonvisible.hh b/scribo/scribo/primitive/extract/separators_nonvisible.hh
index 4e31650..c3e227c 100644
--- a/scribo/scribo/primitive/extract/separators_nonvisible.hh
+++ b/scribo/scribo/primitive/extract/separators_nonvisible.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -76,6 +77,7 @@
 
 #include <mln/norm/l1.hh>
 
+#include <scribo/debug/logger.hh>
 #include <scribo/core/object_groups.hh>
 #include <scribo/core/component_set.hh>
 #include <scribo/primitive/extract/components.hh>
@@ -90,19 +92,19 @@
 
 #include <scribo/primitive/link/internal/dmax_default.hh>
 
-#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
 #include <scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh>
 
 #include <scribo/primitive/group/from_double_link_any.hh>
 
 #include <scribo/filter/object_links_top_aligned.hh>
 #include <scribo/filter/object_groups_small.hh>
 #include <scribo/filter/object_links_bottom_aligned.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-#include <scribo/debug/decision_image.hh>
-
-
 
+#include <scribo/core/def/lbl_type.hh>
+#include <scribo/core/line_set.hh>
+#include <scribo/text/extract_lines.hh>
+#include <mln/draw/box.hh>
 
 
 namespace scribo
@@ -115,6 +117,7 @@ namespace scribo
     {
 
       using namespace mln;
+      using namespace scribo::debug;
 
 
       /// \brief Find non visible separators (whitespaces)
@@ -127,269 +130,6 @@ namespace scribo
 
 # ifndef MLN_INCLUDE_ONLY
 
-      namespace internal
-      {
-
-	using namespace primitive::link::internal;
-
-	template <typename L, typename E>
-	class single_dmax_ratio_aligned_functor_base
-	  : public link_single_dmax_ratio_base<L, dmax_default, E>
-	{
-	  typedef link_single_dmax_ratio_base<L, dmax_default, E> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_dmax_ratio_aligned_functor_base(
-	    const mln_ch_value(L,bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor_,
-	    bool debug)
-	    : super_(components,
-		     anchor::Horizontal,
-		     dmax_default(dmax)),
-	      anchor(anchor_),
-	      _debug_(debug)
-	  {
-	    (void) input; // FIXME : remove this argument
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
-
-	    // if (_debug_)
-	    // {
-	    //   debug_ = data::convert(value::rgb8(), input);
-	    //   debug_angle_ = data::convert(value::rgb8(), input);
-	    // }
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    ++p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    ++p;
-	  }
-
-
-	  mln_site(L)
-	  start_point_(unsigned current_object, anchor::Type anchor)
-	  {
-	    return link::internal::compute_anchor(this->components_,
-						  current_object, anchor);
-	  }
-
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    if (!super_::valid_link_(current_object, start_point, p))
-	      return false;
-
-	    box<P> b = this->components_(current_object).bbox();
-
-	    // Distance between the two components.
-	    float dist;
-
-	    // current object is on the left.
-	    if (p[this->direction_] > b.pmax()[this->direction_])
-	      dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]);
-	    // current object is on the right.
-	    else
-	      dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]);
-
-
-	    int ldist = this->components_(current_object).bbox().width();
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < 3 * ldist)
-	    {
-	      return
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return
-	      filter::internal::component_aligned_rad(this->components_,
-						      current_object,
-						      this->labeled_image_(p),
-						      anchor,
-						      min_alpha_rad);
-	  }
-
-	  void validate_link_(unsigned current_object,
-			      const P& start_point,
-			      const P& p,
-			      anchor::Type anchor)
-	  {
-	    super_::validate_link_(current_object, start_point, p, anchor);
-
-	    // if (_debug_)
-	    // {
-	    //   mln_site(L)
-	    // 	p1 = link::internal::compute_anchor(this->components_,
-	    // 					    current_object, anchor),
-	    // 	p2 = link::internal::compute_anchor(this->components_,
-	    // 					    this->labeled_image_(p),
-	    // 			     anchor);
-	    //   mln::draw::line(debug_, p1, p2, literal::green);
-
-
-	    //   float
-	    // 	angle = filter::internal::alignment_angle(this->components_,
-	    // 						  current_object,
-	    // 						  this->labeled_image_(p),
-	    // 						  anchor);
-	    //   angle = (angle * 180.0f) / math::pi;
-	    //   angle = angle * 20.0f + 1.0f;
-	    //   mln::draw::line(debug_angle_, p1, p2,
-	    // 		      value::rgb8(unsigned(angle),
-	    // 				  unsigned(angle),
-	    // 				  unsigned(angle)));
-	    // }
-	  }
-
-	  void invalidate_link_(unsigned current_object,
-				const P& start_point,
-				const P& p,
-				anchor::Type anchor)
-	  {
-	    super_::invalidate_link_(current_object, start_point, p, anchor);
-
-	    // if (_debug_)
-	    // {
-	    //   if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0)
-	    //   {
-	    // 	mln_site(L)
-	    // 	  p1 = link::internal::compute_anchor(this->components_,
-	    // 					      current_object, anchor),
-	    // 	  p2 = link::internal::compute_anchor(this->components_,
-	    // 					      this->labeled_image_(p),
-	    // 			       anchor);
-	    // 	if (this->labeled_image_.domain().has(p2)
-	    // 	    && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300)
-	    // 	{
-	    // 	  mln::draw::line(debug_, p1, p2, literal::red);
-	    // 	}
-
-
-	    // 	float
-	    // 	  angle = filter::internal::alignment_angle(this->components_,
-	    // 						    current_object,
-	    // 						    this->labeled_image_(p),
-	    // 						    anchor);
-	    // 	angle = (angle * 180.0f) / math::pi;
-	    // 	angle = angle * 20.0f + 1.0f;
-	    // 	mln::draw::line(debug_angle_, p1, p2,
-	    // 			value::rgb8(unsigned(angle),
-	    // 				    unsigned(angle),
-	    // 				    unsigned(angle)));
-	    //   }
-	    // }
-	  }
-
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
-
-	  // mln_ch_value(L, value::rgb8) debug_;
-	  // mln_ch_value(L, value::rgb8) debug_angle_;
-	  bool _debug_;
-	};
-
-
-	template <typename L>
-	class single_right_dmax_ratio_aligned_functor
-	  : public single_dmax_ratio_aligned_functor_base<L, single_right_dmax_ratio_aligned_functor<L> >
-	{
-	  typedef single_right_dmax_ratio_aligned_functor<L> self_t;
-	  typedef single_dmax_ratio_aligned_functor_base<L, self_t> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_right_dmax_ratio_aligned_functor(
-	    const mln_ch_value(L, bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor,
-	    bool debug)
-	    : super_(input, components, dmax, min_angle,
-		     max_angle, anchor, debug)
-	  {
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    ++p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    ++p;
-	  }
-
-	};
-
-
-	template <typename L>
-	class single_left_dmax_ratio_aligned_functor
-	  : public single_dmax_ratio_aligned_functor_base<L, single_left_dmax_ratio_aligned_functor<L> >
-	{
-	  typedef single_left_dmax_ratio_aligned_functor<L> self_t;
-	  typedef single_dmax_ratio_aligned_functor_base<L, self_t> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_left_dmax_ratio_aligned_functor(
-	    const mln_ch_value(L, bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor,
-	    bool debug)
-	    : super_(input, components, dmax, min_angle,
-		     max_angle, anchor, debug)
-	  {
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    --p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    --p;
-	  }
-
-
-	};
-
-      } // end of namespace scribo::primitive::extract::internal
-
-
-
-
       // FACADE
 
       template <typename I>
@@ -403,7 +143,9 @@ namespace scribo
 	typedef mln_value(I) Vi;
 	mlc_is(Vi,bool)::check();
 
-	bool _debug_ = false;
+	typedef scribo::def::lbl_type V;
+	typedef mln_ch_value(I,V) L;
+
 	unsigned
 	  min_angle = 3,
 	  max_angle = 5,
@@ -414,33 +156,30 @@ namespace scribo
 
 	gt.start();
 
+	bool _debug_ = logger().is_at_level(AuxiliaryResults);
 
-	// // Remove horizontal lines.
-	// t.restart();
-
-	// mln_concrete(I) hlines = primitive::extract::lines_h_pattern(in, 50, 3);
-	// mln_concrete(I) input = primitive::remove::separators(in, hlines);
+	// Closing structural - Connect characters.
+	t.start();
 
-	// t_ = t;
-	// std::cout << "Horizontal lines removed - " << t_ << std::endl;
+	// line_set<L> lines = text::extract_lines(in, c8());
 
+	// mln_concrete(I) input_clo;
+	// initialize(input_clo, in);
+	// data::fill(input_clo, false);
 
-	// Closing structural - Connect characters.
-	t.start();
+	// for_all_lines(l, lines)
+	//   draw::box(input_clo, lines(l).bbox(), true);
 
 	win::hline2d vl(17);
 	mln_concrete(I) input_clo = morpho::closing::structural(in, vl);
 
+
+
 	float t_ = t;
 	std::cout << "closing_structural - " << t_ << std::endl;
 
-	// if (_debug_)
-	// {
-	//   // Restore input orientation.
-	//   input = scribo::preprocessing::rotate_90(input, false);
-
-	//   io::pbm::save(input_clo, "input_clo.pbm");
-	// }
+	// Debug
+	logger().log_image(AuxiliaryResults, input_clo, "input_clo");
 
 	// Rotate (OK)
 	t.restart();
@@ -451,8 +190,6 @@ namespace scribo
 
 
 	/// Finding components.
-	typedef value::int_u16 V;
-	typedef mln_ch_value(I,V) L;
 
 	t.restart();
 	V ncomponents;
@@ -462,11 +199,11 @@ namespace scribo
 	t_ = t;
 	std::cout << "extract::components - " << t_ << std::endl;
 
-	// if (_debug_)
-	//   io::pgm::save(data::convert(value::int_u8(), components.labeled_image()),
-	// 		"lbl.pgm");
-
-
+	// Debug
+	logger().log_image(AuxiliaryResults,
+			   data::convert(value::int_u8(),
+					 components.labeled_image()),
+			   "lbl");
 	unsigned dmax = 5;
 
 	t.restart();
@@ -475,46 +212,47 @@ namespace scribo
 	object_links<L> top_left, bot_left;
 
 
+	typedef link::internal::dmax_default Dmax_F;
 	// Top
 	{
 	  // Right
-	  internal::single_right_dmax_ratio_aligned_functor<L>
-	    functor(input_clo, components, dmax, min_angle, max_angle,
-		    anchor::TopStrictLeft, _debug_);
-//    top_right = primitive::link::impl::compute_fastest(functor, anchor::TopStrictLeft);
+	  link::internal::single_right_dmax_ratio_aligned_functor<L,Dmax_F>
+	    functor(components, Dmax_F(dmax), min_angle, max_angle,
+		    anchor::TopStrictLeft);
 	  top_right = primitive::link::compute(functor, anchor::TopStrictLeft);
 
 	  t.stop();
 
-
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(functor.debug_, "right_top.ppm");
-	  //   io::ppm::save(functor.debug_angle_, "right_top_angle.ppm");
-	  // }
+	  // Debug
+	  logger().log_image(AuxiliaryResults, functor.debug_, "right_top");
+	  logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			     "right_top_angle");
 
 	  t.resume();
 
 	  // Left
-	  internal::single_left_dmax_ratio_aligned_functor<L>
-	    lfunctor(input_clo, components, dmax, min_angle, max_angle,
-		     anchor::TopStrictLeft, _debug_);
+	  link::internal::single_left_dmax_ratio_aligned_functor<L,Dmax_F>
+	    lfunctor(components, Dmax_F(dmax), min_angle, max_angle,
+		     anchor::TopStrictLeft);
 	  top_left = primitive::link::compute(lfunctor, anchor::TopStrictLeft);
 
 
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(lfunctor.debug_, "left_top.ppm");
-	  //   io::ppm::save(lfunctor.debug_angle_, "left_top_angle.ppm");
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "left_top");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "left_top_angle");
 
-	  //   mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
-	  //   data::paste((lfunctor.debug_ | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
-	  // 		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
+	    mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
+	    data::paste((lfunctor.debug_
+			 | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
+	    		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
 
-	  //   io::ppm::save(output, "left_right_top.ppm");
-	  // }
+	    logger().log_image(AuxiliaryResults, output, "left_right_top");
+	  }
 
 	  t.resume();
 	}
@@ -523,38 +261,43 @@ namespace scribo
 	// Bottom
 	{
 	  // Right
-	  internal::single_right_dmax_ratio_aligned_functor<L>
-	    functor(input_clo, components, dmax, min_angle, max_angle,
-		    anchor::BottomStrictRight, _debug_);
+	  link::internal::single_right_dmax_ratio_aligned_functor<L,Dmax_F>
+	    functor(components, Dmax_F(dmax), min_angle, max_angle,
+		    anchor::BottomStrictRight);
 	  bot_right = primitive::link::compute(functor, anchor::BottomStrictRight);
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(functor.debug_, "right_bot.ppm");
-	  //   io::ppm::save(functor.debug_angle_, "right_bot_angle.ppm");
-	  // }
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "right_bot");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "right_bot_angle");
+	  }
 
 	  t.resume();
 
 	  // Left
-	  internal::single_left_dmax_ratio_aligned_functor<L>
-	    lfunctor(input_clo, components, dmax, min_angle, max_angle,
-		     anchor::BottomStrictRight, _debug_);
+	  link::internal::single_left_dmax_ratio_aligned_functor<L,Dmax_F>
+	    lfunctor(components, Dmax_F(dmax), min_angle, max_angle,
+		     anchor::BottomStrictRight);
 	  bot_left = primitive::link::compute(lfunctor, anchor::BottomStrictRight);
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(lfunctor.debug_, "left_bot.ppm");
-	  //   io::ppm::save(lfunctor.debug_angle_, "left_bot_angle.ppm");
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "left_bot");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "left_bot_angle");
 
-	  //   mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
-	  //   data::paste((lfunctor.debug_ | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
-	  // 		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
+	    mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
+	    data::paste((lfunctor.debug_
+	    		 | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
+	    		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
 
-	  //   io::ppm::save(output, "left_right_bot.ppm");
-	  // }
+	    logger().log_image(AuxiliaryResults, output, "left_right_bot");
+	  }
 	}
 
 
@@ -631,113 +374,113 @@ namespace scribo
 	std::cout << "Drawing output image - " << t_ << std::endl;
 
 
-	// if (_debug_)
-	// {
-	//   // Restore input orientation.
-	//   mln_concrete(I) input = scribo::preprocessing::rotate_90(in, false);
-
-
-	//   // Debug group bboxes (includes all bboxes before filtering)
-	//   util::array<accu::shape::bbox<point2d> >
-	//     btop_accu(top_groups.nelements()),
-	//     bbot_accu(bot_groups.nelements());
-
-
-	//   for_all_groups(c, top_groups)
-	//   {
-	//     btop_accu(top_groups(c)).take(components(c).bbox());
-	//     bbot_accu(bot_groups(c)).take(components(c).bbox());
-	//   }
-
-	//   mln_ch_value(I, value::rgb8)
-	//     wo_filtering = data::convert(value::rgb8(), input);
-
-	//   for_all_comp_data(d, btop_accu)
-	//   {
-	//     if (btop_accu(d).is_valid())
-	//     {
-	//       mln::draw::line(wo_filtering,
-	// 		      btop_accu(d).to_result().pmin(),
-	// 		      point2d(btop_accu(d).to_result().pmin().row(),
-	// 			      btop_accu(d).to_result().pmax().col()),
-	// 		      literal::green);
-
-	//     }
-	//   }
-
-	//   for_all_comp_data(d, bbot_accu)
-	//   {
-	//     if (bbot_accu(d).is_valid())
-	//     {
-	//       mln::draw::line(wo_filtering,
-	// 		      point2d(bbot_accu(d).to_result().pmax().row(),
-	// 			      bbot_accu(d).to_result().pmin().col()),
-	// 		      bbot_accu(d).to_result().pmax(),
-	// 		      literal::green);
-	//     }
-
-	//   }
-	//   io::ppm::save(wo_filtering, "wo_filtering.ppm");
-
-	//   mln_ch_value(I, value::rgb8) both = data::convert(value::rgb8(), input);
-
-	//   for_all_comp_data(d, top_accu)
-	//   {
-	//     if (top_accu(d).is_valid()  ||  btop_accu(d).is_valid())
-	//     {
-	//       if (top_accu(d).is_valid())
-	//       {
-	// 	  mln::draw::line(both,
-	// 			  top_accu(d).to_result().pmin(),
-	// 			  point2d(top_accu(d).to_result().pmin().row(),
-	// 				  top_accu(d).to_result().pmax().col()),
-	// 			  literal::green);
-	//       }
-	//       else
-	// 	if (btop_accu(d).is_valid())
-	// 	  mln::draw::line(both,
-	// 			  btop_accu(d).to_result().pmin(),
-	// 			  point2d(btop_accu(d).to_result().pmin().row(),
-	// 				  btop_accu(d).to_result().pmax().col()),
-	// 			  literal::yellow);
-
-	//     }
-	//     if (bot_accu(d).is_valid() ||  bbot_accu(d).is_valid())
-	//     {
-	//       if (bot_accu(d).is_valid())
-	//       {
-	// 	  mln::draw::line(both,
-	// 			  point2d(bot_accu(d).to_result().pmax().row(),
-	// 				  bot_accu(d).to_result().pmin().col()),
-	// 			  bot_accu(d).to_result().pmax(),
-	// 			  literal::green);
-	//       }
-	//       else
-	// 	if (bbot_accu(d).is_valid())
-	// 	  mln::draw::line(both,
-	// 			  point2d(bbot_accu(d).to_result().pmax().row(),
-	// 				  bbot_accu(d).to_result().pmin().col()),
-	// 			  bbot_accu(d).to_result().pmax(),
-	// 			  literal::yellow);
-	//     }
-
-	//   }
-
-	//   io::ppm::save(both, "both.ppm");
-	//   io::pbm::save(separators, "separators.pbm");
-	// }
+	if (_debug_)
+	{
+	  // Restore input orientation.
+	  mln_concrete(I) input = scribo::preprocessing::rotate_90(in, false);
+
 
+	  // Debug group bboxes (includes all bboxes before filtering)
+	  util::array<accu::shape::bbox<point2d> >
+	    btop_accu(top_groups.nelements()),
+	    bbot_accu(bot_groups.nelements());
 
-	// Hit or miss
-	{
-	  // if (_debug_)
+
+	  for_all_groups(c, top_groups)
+	  {
+	    btop_accu(top_groups(c)).take(components(c).bbox());
+	    bbot_accu(bot_groups(c)).take(components(c).bbox());
+	  }
+
+	  mln_ch_value(I, value::rgb8)
+	    wo_filtering = data::convert(value::rgb8(), input);
+
+	  for_all_comp_data(d, btop_accu)
+	  {
+	    if (btop_accu(d).is_valid())
+	    {
+	      mln::draw::line(wo_filtering,
+			      btop_accu(d).to_result().pmin(),
+			      point2d(btop_accu(d).to_result().pmin().row(),
+				      btop_accu(d).to_result().pmax().col()),
+			      literal::green);
+
+	    }
+	  }
+
+	  for_all_comp_data(d, bbot_accu)
+	  {
+	    if (bbot_accu(d).is_valid())
+	    {
+	      mln::draw::line(wo_filtering,
+			      point2d(bbot_accu(d).to_result().pmax().row(),
+				      bbot_accu(d).to_result().pmin().col()),
+			      bbot_accu(d).to_result().pmax(),
+			      literal::green);
+	    }
+	  }
+	  logger().log_image(AuxiliaryResults, wo_filtering, "wo_filtering");
+
+	  // mln_ch_value(I, value::rgb8) both = data::convert(value::rgb8(), input);
+
+	  // for_all_comp_data(d, top_accu)
 	  // {
-	  //   mln_concrete(I) input_with_seps = duplicate(input_clo);
-	  //   data::paste(separators | pw::value(separators), input_with_seps);
+	  //   if (top_accu(d).is_valid()  ||  btop_accu(d).is_valid())
+	  //   {
+	  //     if (top_accu(d).is_valid())
+	  //     {
+	  // 	  mln::draw::line(both,
+	  // 			  top_accu(d).to_result().pmin(),
+	  // 			  point2d(top_accu(d).to_result().pmin().row(),
+	  // 				  top_accu(d).to_result().pmax().col()),
+	  // 			  literal::green);
+	  //     }
+	  //     else
+	  // 	if (btop_accu(d).is_valid())
+	  // 	  mln::draw::line(both,
+	  // 			  btop_accu(d).to_result().pmin(),
+	  // 			  point2d(btop_accu(d).to_result().pmin().row(),
+	  // 				  btop_accu(d).to_result().pmax().col()),
+	  // 			  literal::yellow);
+
+	  //   }
+	  //   if (bot_accu(d).is_valid() ||  bbot_accu(d).is_valid())
+	  //   {
+	  //     if (bot_accu(d).is_valid())
+	  //     {
+	  // 	  mln::draw::line(both,
+	  // 			  point2d(bot_accu(d).to_result().pmax().row(),
+	  // 				  bot_accu(d).to_result().pmin().col()),
+	  // 			  bot_accu(d).to_result().pmax(),
+	  // 			  literal::green);
+	  //     }
+	  //     else
+	  // 	if (bbot_accu(d).is_valid())
+	  // 	  mln::draw::line(both,
+	  // 			  point2d(bbot_accu(d).to_result().pmax().row(),
+	  // 				  bbot_accu(d).to_result().pmin().col()),
+	  // 			  bbot_accu(d).to_result().pmax(),
+	  // 			  literal::yellow);
+	  //   }
 
-	  //   io::pbm::save(input_with_seps, "input_with_seps.pbm");
 	  // }
 
+	  // logger().log_image(AuxiliaryResults,
+	  // 				    both, "both");
+	  logger().log_image(AuxiliaryResults, separators, "separators");
+	}
+
+
+	// Hit or miss
+	{
+	  if (_debug_)
+	  {
+	    mln_concrete(I) input_with_seps = duplicate(input_clo);
+	    data::paste(separators | pw::value(separators), input_with_seps);
+
+	    logger().log_image(AuxiliaryResults, input_with_seps, "input_with_seps");
+	  }
+
 	  t.restart();
 	  unsigned length = 25;
 
@@ -778,18 +521,22 @@ namespace scribo
 
 	  extension::adjust_fill(tmp, 21, 0);
 
-	  value::int_u8 *sep_lbl_ptr = sep_lbl.buffer() + sep_lbl.index_of_point(sep_lbl.domain().pmin());
-	  bool *separators_ptr = separators.buffer() + separators.index_of_point(separators.domain().pmin());
+	  value::int_u8 *sep_lbl_ptr = sep_lbl.buffer()
+	    + sep_lbl.index_of_point(sep_lbl.domain().pmin());
+	  bool *separators_ptr = separators.buffer()
+	    + separators.index_of_point(separators.domain().pmin());
 	  unsigned *tmp_ptr = tmp.buffer() + tmp.index_of_point(tmp.domain().pmin());;
 	  int idx1 = tmp.delta_index(dp1);
 	  int idx2 = tmp.delta_index(dp2);
 
-	  unsigned nrows = separators.nrows();
-	  unsigned ncols = separators.ncols();
+	  unsigned
+	    nrows = separators.nrows(),
+	    ncols = separators.ncols();
 
-	  unsigned row_idx_sep_lbl = sep_lbl.delta_index(dpoint2d(+1, - ncols));
-	  unsigned row_idx_separators = separators.delta_index(dpoint2d(+1, - ncols));
-	  unsigned row_idx_tmp = tmp.delta_index(dpoint2d(+1, - ncols));
+	  unsigned
+	    row_idx_sep_lbl = sep_lbl.delta_index(dpoint2d(+1, - ncols)),
+	    row_idx_separators = separators.delta_index(dpoint2d(+1, - ncols)),
+	    row_idx_tmp = tmp.delta_index(dpoint2d(+1, - ncols));
 
 	  for (unsigned row = 0; row < nrows; ++row)
 	  {
@@ -833,29 +580,11 @@ namespace scribo
 
 	  mln_concrete(I) output = data::convert(bool(), sep_lbl);
 
-	  // if (_debug_)
-	  // {
-	  //   io::pbm::save(output, "separators_hom.pbm");
-	  //   io::pbm::save(separators, "separators_filtered.pbm");
-
-	  //   // value::int_u16 ncomps;
-	  //   // component_set<L> comps = primitive::extract::components(output, c8(), ncomps);
-	  //   // mln_ch_value(I, value::rgb8) both;
-
-	  //   // both = data::convert(value::rgb8(), input);
-
-	  //   // // Needed since the rotated image origin is (0,0).
-	  //   // dpoint2d dp(input.domain().pcenter() - input_clo.domain().pcenter());
-
-	  //   // for_all_comps(c, comps)
-	  //   // {
-	  //   //   box2d b = geom::rotate(comps(c).bbox(), -90, input_clo.domain().pcenter());
-	  //   //   mln::draw::line(both,
-	  //   // 		      b.pmin() + dp,
-	  //   // 		      b.pmax() + dp,
-	  //   // 		      literal::green);
-	  //   // }
-	  // }
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, output,
+			       "separators_filtered");
+	  }
 
 	  gt.stop();
 	  t_ = gt;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            last-svn-commit-804-geae112f	scribo/primitive/extract/separators_nonvisible.hh: Cleanup	and improve debug support.
                        
                        
by Guillaume Lazzara 14 Mar '11
                    by Guillaume Lazzara 14 Mar '11
14 Mar '11
                    
                        ---
 scribo/ChangeLog                                   |    5 +
 .../primitive/extract/separators_nonvisible.hh     |  661 ++++++--------------
 2 files changed, 200 insertions(+), 466 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b6f7f1a..d9e7e96 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	* scribo/primitive/extract/separators_nonvisible.hh: Cleanup and
+	improve debug support.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Various small fixes.
 
 	* scribo/filter/object_links_bottom_aligned.hh,
diff --git a/scribo/scribo/primitive/extract/separators_nonvisible.hh b/scribo/scribo/primitive/extract/separators_nonvisible.hh
index 4e31650..c3e227c 100644
--- a/scribo/scribo/primitive/extract/separators_nonvisible.hh
+++ b/scribo/scribo/primitive/extract/separators_nonvisible.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -76,6 +77,7 @@
 
 #include <mln/norm/l1.hh>
 
+#include <scribo/debug/logger.hh>
 #include <scribo/core/object_groups.hh>
 #include <scribo/core/component_set.hh>
 #include <scribo/primitive/extract/components.hh>
@@ -90,19 +92,19 @@
 
 #include <scribo/primitive/link/internal/dmax_default.hh>
 
-#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
 #include <scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh>
 
 #include <scribo/primitive/group/from_double_link_any.hh>
 
 #include <scribo/filter/object_links_top_aligned.hh>
 #include <scribo/filter/object_groups_small.hh>
 #include <scribo/filter/object_links_bottom_aligned.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-#include <scribo/debug/decision_image.hh>
-
-
 
+#include <scribo/core/def/lbl_type.hh>
+#include <scribo/core/line_set.hh>
+#include <scribo/text/extract_lines.hh>
+#include <mln/draw/box.hh>
 
 
 namespace scribo
@@ -115,6 +117,7 @@ namespace scribo
     {
 
       using namespace mln;
+      using namespace scribo::debug;
 
 
       /// \brief Find non visible separators (whitespaces)
@@ -127,269 +130,6 @@ namespace scribo
 
 # ifndef MLN_INCLUDE_ONLY
 
-      namespace internal
-      {
-
-	using namespace primitive::link::internal;
-
-	template <typename L, typename E>
-	class single_dmax_ratio_aligned_functor_base
-	  : public link_single_dmax_ratio_base<L, dmax_default, E>
-	{
-	  typedef link_single_dmax_ratio_base<L, dmax_default, E> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_dmax_ratio_aligned_functor_base(
-	    const mln_ch_value(L,bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor_,
-	    bool debug)
-	    : super_(components,
-		     anchor::Horizontal,
-		     dmax_default(dmax)),
-	      anchor(anchor_),
-	      _debug_(debug)
-	  {
-	    (void) input; // FIXME : remove this argument
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
-
-	    // if (_debug_)
-	    // {
-	    //   debug_ = data::convert(value::rgb8(), input);
-	    //   debug_angle_ = data::convert(value::rgb8(), input);
-	    // }
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    ++p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    ++p;
-	  }
-
-
-	  mln_site(L)
-	  start_point_(unsigned current_object, anchor::Type anchor)
-	  {
-	    return link::internal::compute_anchor(this->components_,
-						  current_object, anchor);
-	  }
-
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    if (!super_::valid_link_(current_object, start_point, p))
-	      return false;
-
-	    box<P> b = this->components_(current_object).bbox();
-
-	    // Distance between the two components.
-	    float dist;
-
-	    // current object is on the left.
-	    if (p[this->direction_] > b.pmax()[this->direction_])
-	      dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]);
-	    // current object is on the right.
-	    else
-	      dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]);
-
-
-	    int ldist = this->components_(current_object).bbox().width();
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < 3 * ldist)
-	    {
-	      return
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return
-	      filter::internal::component_aligned_rad(this->components_,
-						      current_object,
-						      this->labeled_image_(p),
-						      anchor,
-						      min_alpha_rad);
-	  }
-
-	  void validate_link_(unsigned current_object,
-			      const P& start_point,
-			      const P& p,
-			      anchor::Type anchor)
-	  {
-	    super_::validate_link_(current_object, start_point, p, anchor);
-
-	    // if (_debug_)
-	    // {
-	    //   mln_site(L)
-	    // 	p1 = link::internal::compute_anchor(this->components_,
-	    // 					    current_object, anchor),
-	    // 	p2 = link::internal::compute_anchor(this->components_,
-	    // 					    this->labeled_image_(p),
-	    // 			     anchor);
-	    //   mln::draw::line(debug_, p1, p2, literal::green);
-
-
-	    //   float
-	    // 	angle = filter::internal::alignment_angle(this->components_,
-	    // 						  current_object,
-	    // 						  this->labeled_image_(p),
-	    // 						  anchor);
-	    //   angle = (angle * 180.0f) / math::pi;
-	    //   angle = angle * 20.0f + 1.0f;
-	    //   mln::draw::line(debug_angle_, p1, p2,
-	    // 		      value::rgb8(unsigned(angle),
-	    // 				  unsigned(angle),
-	    // 				  unsigned(angle)));
-	    // }
-	  }
-
-	  void invalidate_link_(unsigned current_object,
-				const P& start_point,
-				const P& p,
-				anchor::Type anchor)
-	  {
-	    super_::invalidate_link_(current_object, start_point, p, anchor);
-
-	    // if (_debug_)
-	    // {
-	    //   if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0)
-	    //   {
-	    // 	mln_site(L)
-	    // 	  p1 = link::internal::compute_anchor(this->components_,
-	    // 					      current_object, anchor),
-	    // 	  p2 = link::internal::compute_anchor(this->components_,
-	    // 					      this->labeled_image_(p),
-	    // 			       anchor);
-	    // 	if (this->labeled_image_.domain().has(p2)
-	    // 	    && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300)
-	    // 	{
-	    // 	  mln::draw::line(debug_, p1, p2, literal::red);
-	    // 	}
-
-
-	    // 	float
-	    // 	  angle = filter::internal::alignment_angle(this->components_,
-	    // 						    current_object,
-	    // 						    this->labeled_image_(p),
-	    // 						    anchor);
-	    // 	angle = (angle * 180.0f) / math::pi;
-	    // 	angle = angle * 20.0f + 1.0f;
-	    // 	mln::draw::line(debug_angle_, p1, p2,
-	    // 			value::rgb8(unsigned(angle),
-	    // 				    unsigned(angle),
-	    // 				    unsigned(angle)));
-	    //   }
-	    // }
-	  }
-
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
-
-	  // mln_ch_value(L, value::rgb8) debug_;
-	  // mln_ch_value(L, value::rgb8) debug_angle_;
-	  bool _debug_;
-	};
-
-
-	template <typename L>
-	class single_right_dmax_ratio_aligned_functor
-	  : public single_dmax_ratio_aligned_functor_base<L, single_right_dmax_ratio_aligned_functor<L> >
-	{
-	  typedef single_right_dmax_ratio_aligned_functor<L> self_t;
-	  typedef single_dmax_ratio_aligned_functor_base<L, self_t> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_right_dmax_ratio_aligned_functor(
-	    const mln_ch_value(L, bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor,
-	    bool debug)
-	    : super_(input, components, dmax, min_angle,
-		     max_angle, anchor, debug)
-	  {
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    ++p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    ++p;
-	  }
-
-	};
-
-
-	template <typename L>
-	class single_left_dmax_ratio_aligned_functor
-	  : public single_dmax_ratio_aligned_functor_base<L, single_left_dmax_ratio_aligned_functor<L> >
-	{
-	  typedef single_left_dmax_ratio_aligned_functor<L> self_t;
-	  typedef single_dmax_ratio_aligned_functor_base<L, self_t> super_;
-
-	public:
-	  typedef mln_site(L) P;
-
-	  single_left_dmax_ratio_aligned_functor(
-	    const mln_ch_value(L, bool)& input,
-	    const component_set<L>& components,
-	    unsigned dmax,
-	    float min_angle,
-	    float max_angle,
-	    anchor::Type anchor,
-	    bool debug)
-	    : super_(input, components, dmax, min_angle,
-		     max_angle, anchor, debug)
-	  {
-	  }
-
-	  void compute_next_site_(P& p)
-	  {
-	    --p.col();
-	  }
-
-	  void compute_next_site_f_(unsigned& p)
-	  {
-	    --p;
-	  }
-
-
-	};
-
-      } // end of namespace scribo::primitive::extract::internal
-
-
-
-
       // FACADE
 
       template <typename I>
@@ -403,7 +143,9 @@ namespace scribo
 	typedef mln_value(I) Vi;
 	mlc_is(Vi,bool)::check();
 
-	bool _debug_ = false;
+	typedef scribo::def::lbl_type V;
+	typedef mln_ch_value(I,V) L;
+
 	unsigned
 	  min_angle = 3,
 	  max_angle = 5,
@@ -414,33 +156,30 @@ namespace scribo
 
 	gt.start();
 
+	bool _debug_ = logger().is_at_level(AuxiliaryResults);
 
-	// // Remove horizontal lines.
-	// t.restart();
-
-	// mln_concrete(I) hlines = primitive::extract::lines_h_pattern(in, 50, 3);
-	// mln_concrete(I) input = primitive::remove::separators(in, hlines);
+	// Closing structural - Connect characters.
+	t.start();
 
-	// t_ = t;
-	// std::cout << "Horizontal lines removed - " << t_ << std::endl;
+	// line_set<L> lines = text::extract_lines(in, c8());
 
+	// mln_concrete(I) input_clo;
+	// initialize(input_clo, in);
+	// data::fill(input_clo, false);
 
-	// Closing structural - Connect characters.
-	t.start();
+	// for_all_lines(l, lines)
+	//   draw::box(input_clo, lines(l).bbox(), true);
 
 	win::hline2d vl(17);
 	mln_concrete(I) input_clo = morpho::closing::structural(in, vl);
 
+
+
 	float t_ = t;
 	std::cout << "closing_structural - " << t_ << std::endl;
 
-	// if (_debug_)
-	// {
-	//   // Restore input orientation.
-	//   input = scribo::preprocessing::rotate_90(input, false);
-
-	//   io::pbm::save(input_clo, "input_clo.pbm");
-	// }
+	// Debug
+	logger().log_image(AuxiliaryResults, input_clo, "input_clo");
 
 	// Rotate (OK)
 	t.restart();
@@ -451,8 +190,6 @@ namespace scribo
 
 
 	/// Finding components.
-	typedef value::int_u16 V;
-	typedef mln_ch_value(I,V) L;
 
 	t.restart();
 	V ncomponents;
@@ -462,11 +199,11 @@ namespace scribo
 	t_ = t;
 	std::cout << "extract::components - " << t_ << std::endl;
 
-	// if (_debug_)
-	//   io::pgm::save(data::convert(value::int_u8(), components.labeled_image()),
-	// 		"lbl.pgm");
-
-
+	// Debug
+	logger().log_image(AuxiliaryResults,
+			   data::convert(value::int_u8(),
+					 components.labeled_image()),
+			   "lbl");
 	unsigned dmax = 5;
 
 	t.restart();
@@ -475,46 +212,47 @@ namespace scribo
 	object_links<L> top_left, bot_left;
 
 
+	typedef link::internal::dmax_default Dmax_F;
 	// Top
 	{
 	  // Right
-	  internal::single_right_dmax_ratio_aligned_functor<L>
-	    functor(input_clo, components, dmax, min_angle, max_angle,
-		    anchor::TopStrictLeft, _debug_);
-//    top_right = primitive::link::impl::compute_fastest(functor, anchor::TopStrictLeft);
+	  link::internal::single_right_dmax_ratio_aligned_functor<L,Dmax_F>
+	    functor(components, Dmax_F(dmax), min_angle, max_angle,
+		    anchor::TopStrictLeft);
 	  top_right = primitive::link::compute(functor, anchor::TopStrictLeft);
 
 	  t.stop();
 
-
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(functor.debug_, "right_top.ppm");
-	  //   io::ppm::save(functor.debug_angle_, "right_top_angle.ppm");
-	  // }
+	  // Debug
+	  logger().log_image(AuxiliaryResults, functor.debug_, "right_top");
+	  logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			     "right_top_angle");
 
 	  t.resume();
 
 	  // Left
-	  internal::single_left_dmax_ratio_aligned_functor<L>
-	    lfunctor(input_clo, components, dmax, min_angle, max_angle,
-		     anchor::TopStrictLeft, _debug_);
+	  link::internal::single_left_dmax_ratio_aligned_functor<L,Dmax_F>
+	    lfunctor(components, Dmax_F(dmax), min_angle, max_angle,
+		     anchor::TopStrictLeft);
 	  top_left = primitive::link::compute(lfunctor, anchor::TopStrictLeft);
 
 
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(lfunctor.debug_, "left_top.ppm");
-	  //   io::ppm::save(lfunctor.debug_angle_, "left_top_angle.ppm");
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "left_top");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "left_top_angle");
 
-	  //   mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
-	  //   data::paste((lfunctor.debug_ | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
-	  // 		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
+	    mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
+	    data::paste((lfunctor.debug_
+			 | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
+	    		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
 
-	  //   io::ppm::save(output, "left_right_top.ppm");
-	  // }
+	    logger().log_image(AuxiliaryResults, output, "left_right_top");
+	  }
 
 	  t.resume();
 	}
@@ -523,38 +261,43 @@ namespace scribo
 	// Bottom
 	{
 	  // Right
-	  internal::single_right_dmax_ratio_aligned_functor<L>
-	    functor(input_clo, components, dmax, min_angle, max_angle,
-		    anchor::BottomStrictRight, _debug_);
+	  link::internal::single_right_dmax_ratio_aligned_functor<L,Dmax_F>
+	    functor(components, Dmax_F(dmax), min_angle, max_angle,
+		    anchor::BottomStrictRight);
 	  bot_right = primitive::link::compute(functor, anchor::BottomStrictRight);
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(functor.debug_, "right_bot.ppm");
-	  //   io::ppm::save(functor.debug_angle_, "right_bot_angle.ppm");
-	  // }
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "right_bot");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "right_bot_angle");
+	  }
 
 	  t.resume();
 
 	  // Left
-	  internal::single_left_dmax_ratio_aligned_functor<L>
-	    lfunctor(input_clo, components, dmax, min_angle, max_angle,
-		     anchor::BottomStrictRight, _debug_);
+	  link::internal::single_left_dmax_ratio_aligned_functor<L,Dmax_F>
+	    lfunctor(components, Dmax_F(dmax), min_angle, max_angle,
+		     anchor::BottomStrictRight);
 	  bot_left = primitive::link::compute(lfunctor, anchor::BottomStrictRight);
 	  t.stop();
 
-	  // if (_debug_)
-	  // {
-	  //   io::ppm::save(lfunctor.debug_, "left_bot.ppm");
-	  //   io::ppm::save(lfunctor.debug_angle_, "left_bot_angle.ppm");
+	  // Debug
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, functor.debug_, "left_bot");
+	    logger().log_image(AuxiliaryResults, functor.debug_angle_,
+			       "left_bot_angle");
 
-	  //   mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
-	  //   data::paste((lfunctor.debug_ | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
-	  // 		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
+	    mln_ch_value(I, value::rgb8) output = duplicate(functor.debug_);
+	    data::paste((lfunctor.debug_
+	    		 | (pw::value(lfunctor.debug_) != pw::cst(literal::black)))
+	    		| (pw::value(lfunctor.debug_) != pw::cst(literal::white)), output);
 
-	  //   io::ppm::save(output, "left_right_bot.ppm");
-	  // }
+	    logger().log_image(AuxiliaryResults, output, "left_right_bot");
+	  }
 	}
 
 
@@ -631,113 +374,113 @@ namespace scribo
 	std::cout << "Drawing output image - " << t_ << std::endl;
 
 
-	// if (_debug_)
-	// {
-	//   // Restore input orientation.
-	//   mln_concrete(I) input = scribo::preprocessing::rotate_90(in, false);
-
-
-	//   // Debug group bboxes (includes all bboxes before filtering)
-	//   util::array<accu::shape::bbox<point2d> >
-	//     btop_accu(top_groups.nelements()),
-	//     bbot_accu(bot_groups.nelements());
-
-
-	//   for_all_groups(c, top_groups)
-	//   {
-	//     btop_accu(top_groups(c)).take(components(c).bbox());
-	//     bbot_accu(bot_groups(c)).take(components(c).bbox());
-	//   }
-
-	//   mln_ch_value(I, value::rgb8)
-	//     wo_filtering = data::convert(value::rgb8(), input);
-
-	//   for_all_comp_data(d, btop_accu)
-	//   {
-	//     if (btop_accu(d).is_valid())
-	//     {
-	//       mln::draw::line(wo_filtering,
-	// 		      btop_accu(d).to_result().pmin(),
-	// 		      point2d(btop_accu(d).to_result().pmin().row(),
-	// 			      btop_accu(d).to_result().pmax().col()),
-	// 		      literal::green);
-
-	//     }
-	//   }
-
-	//   for_all_comp_data(d, bbot_accu)
-	//   {
-	//     if (bbot_accu(d).is_valid())
-	//     {
-	//       mln::draw::line(wo_filtering,
-	// 		      point2d(bbot_accu(d).to_result().pmax().row(),
-	// 			      bbot_accu(d).to_result().pmin().col()),
-	// 		      bbot_accu(d).to_result().pmax(),
-	// 		      literal::green);
-	//     }
-
-	//   }
-	//   io::ppm::save(wo_filtering, "wo_filtering.ppm");
-
-	//   mln_ch_value(I, value::rgb8) both = data::convert(value::rgb8(), input);
-
-	//   for_all_comp_data(d, top_accu)
-	//   {
-	//     if (top_accu(d).is_valid()  ||  btop_accu(d).is_valid())
-	//     {
-	//       if (top_accu(d).is_valid())
-	//       {
-	// 	  mln::draw::line(both,
-	// 			  top_accu(d).to_result().pmin(),
-	// 			  point2d(top_accu(d).to_result().pmin().row(),
-	// 				  top_accu(d).to_result().pmax().col()),
-	// 			  literal::green);
-	//       }
-	//       else
-	// 	if (btop_accu(d).is_valid())
-	// 	  mln::draw::line(both,
-	// 			  btop_accu(d).to_result().pmin(),
-	// 			  point2d(btop_accu(d).to_result().pmin().row(),
-	// 				  btop_accu(d).to_result().pmax().col()),
-	// 			  literal::yellow);
-
-	//     }
-	//     if (bot_accu(d).is_valid() ||  bbot_accu(d).is_valid())
-	//     {
-	//       if (bot_accu(d).is_valid())
-	//       {
-	// 	  mln::draw::line(both,
-	// 			  point2d(bot_accu(d).to_result().pmax().row(),
-	// 				  bot_accu(d).to_result().pmin().col()),
-	// 			  bot_accu(d).to_result().pmax(),
-	// 			  literal::green);
-	//       }
-	//       else
-	// 	if (bbot_accu(d).is_valid())
-	// 	  mln::draw::line(both,
-	// 			  point2d(bbot_accu(d).to_result().pmax().row(),
-	// 				  bbot_accu(d).to_result().pmin().col()),
-	// 			  bbot_accu(d).to_result().pmax(),
-	// 			  literal::yellow);
-	//     }
-
-	//   }
-
-	//   io::ppm::save(both, "both.ppm");
-	//   io::pbm::save(separators, "separators.pbm");
-	// }
+	if (_debug_)
+	{
+	  // Restore input orientation.
+	  mln_concrete(I) input = scribo::preprocessing::rotate_90(in, false);
+
 
+	  // Debug group bboxes (includes all bboxes before filtering)
+	  util::array<accu::shape::bbox<point2d> >
+	    btop_accu(top_groups.nelements()),
+	    bbot_accu(bot_groups.nelements());
 
-	// Hit or miss
-	{
-	  // if (_debug_)
+
+	  for_all_groups(c, top_groups)
+	  {
+	    btop_accu(top_groups(c)).take(components(c).bbox());
+	    bbot_accu(bot_groups(c)).take(components(c).bbox());
+	  }
+
+	  mln_ch_value(I, value::rgb8)
+	    wo_filtering = data::convert(value::rgb8(), input);
+
+	  for_all_comp_data(d, btop_accu)
+	  {
+	    if (btop_accu(d).is_valid())
+	    {
+	      mln::draw::line(wo_filtering,
+			      btop_accu(d).to_result().pmin(),
+			      point2d(btop_accu(d).to_result().pmin().row(),
+				      btop_accu(d).to_result().pmax().col()),
+			      literal::green);
+
+	    }
+	  }
+
+	  for_all_comp_data(d, bbot_accu)
+	  {
+	    if (bbot_accu(d).is_valid())
+	    {
+	      mln::draw::line(wo_filtering,
+			      point2d(bbot_accu(d).to_result().pmax().row(),
+				      bbot_accu(d).to_result().pmin().col()),
+			      bbot_accu(d).to_result().pmax(),
+			      literal::green);
+	    }
+	  }
+	  logger().log_image(AuxiliaryResults, wo_filtering, "wo_filtering");
+
+	  // mln_ch_value(I, value::rgb8) both = data::convert(value::rgb8(), input);
+
+	  // for_all_comp_data(d, top_accu)
 	  // {
-	  //   mln_concrete(I) input_with_seps = duplicate(input_clo);
-	  //   data::paste(separators | pw::value(separators), input_with_seps);
+	  //   if (top_accu(d).is_valid()  ||  btop_accu(d).is_valid())
+	  //   {
+	  //     if (top_accu(d).is_valid())
+	  //     {
+	  // 	  mln::draw::line(both,
+	  // 			  top_accu(d).to_result().pmin(),
+	  // 			  point2d(top_accu(d).to_result().pmin().row(),
+	  // 				  top_accu(d).to_result().pmax().col()),
+	  // 			  literal::green);
+	  //     }
+	  //     else
+	  // 	if (btop_accu(d).is_valid())
+	  // 	  mln::draw::line(both,
+	  // 			  btop_accu(d).to_result().pmin(),
+	  // 			  point2d(btop_accu(d).to_result().pmin().row(),
+	  // 				  btop_accu(d).to_result().pmax().col()),
+	  // 			  literal::yellow);
+
+	  //   }
+	  //   if (bot_accu(d).is_valid() ||  bbot_accu(d).is_valid())
+	  //   {
+	  //     if (bot_accu(d).is_valid())
+	  //     {
+	  // 	  mln::draw::line(both,
+	  // 			  point2d(bot_accu(d).to_result().pmax().row(),
+	  // 				  bot_accu(d).to_result().pmin().col()),
+	  // 			  bot_accu(d).to_result().pmax(),
+	  // 			  literal::green);
+	  //     }
+	  //     else
+	  // 	if (bbot_accu(d).is_valid())
+	  // 	  mln::draw::line(both,
+	  // 			  point2d(bbot_accu(d).to_result().pmax().row(),
+	  // 				  bbot_accu(d).to_result().pmin().col()),
+	  // 			  bbot_accu(d).to_result().pmax(),
+	  // 			  literal::yellow);
+	  //   }
 
-	  //   io::pbm::save(input_with_seps, "input_with_seps.pbm");
 	  // }
 
+	  // logger().log_image(AuxiliaryResults,
+	  // 				    both, "both");
+	  logger().log_image(AuxiliaryResults, separators, "separators");
+	}
+
+
+	// Hit or miss
+	{
+	  if (_debug_)
+	  {
+	    mln_concrete(I) input_with_seps = duplicate(input_clo);
+	    data::paste(separators | pw::value(separators), input_with_seps);
+
+	    logger().log_image(AuxiliaryResults, input_with_seps, "input_with_seps");
+	  }
+
 	  t.restart();
 	  unsigned length = 25;
 
@@ -778,18 +521,22 @@ namespace scribo
 
 	  extension::adjust_fill(tmp, 21, 0);
 
-	  value::int_u8 *sep_lbl_ptr = sep_lbl.buffer() + sep_lbl.index_of_point(sep_lbl.domain().pmin());
-	  bool *separators_ptr = separators.buffer() + separators.index_of_point(separators.domain().pmin());
+	  value::int_u8 *sep_lbl_ptr = sep_lbl.buffer()
+	    + sep_lbl.index_of_point(sep_lbl.domain().pmin());
+	  bool *separators_ptr = separators.buffer()
+	    + separators.index_of_point(separators.domain().pmin());
 	  unsigned *tmp_ptr = tmp.buffer() + tmp.index_of_point(tmp.domain().pmin());;
 	  int idx1 = tmp.delta_index(dp1);
 	  int idx2 = tmp.delta_index(dp2);
 
-	  unsigned nrows = separators.nrows();
-	  unsigned ncols = separators.ncols();
+	  unsigned
+	    nrows = separators.nrows(),
+	    ncols = separators.ncols();
 
-	  unsigned row_idx_sep_lbl = sep_lbl.delta_index(dpoint2d(+1, - ncols));
-	  unsigned row_idx_separators = separators.delta_index(dpoint2d(+1, - ncols));
-	  unsigned row_idx_tmp = tmp.delta_index(dpoint2d(+1, - ncols));
+	  unsigned
+	    row_idx_sep_lbl = sep_lbl.delta_index(dpoint2d(+1, - ncols)),
+	    row_idx_separators = separators.delta_index(dpoint2d(+1, - ncols)),
+	    row_idx_tmp = tmp.delta_index(dpoint2d(+1, - ncols));
 
 	  for (unsigned row = 0; row < nrows; ++row)
 	  {
@@ -833,29 +580,11 @@ namespace scribo
 
 	  mln_concrete(I) output = data::convert(bool(), sep_lbl);
 
-	  // if (_debug_)
-	  // {
-	  //   io::pbm::save(output, "separators_hom.pbm");
-	  //   io::pbm::save(separators, "separators_filtered.pbm");
-
-	  //   // value::int_u16 ncomps;
-	  //   // component_set<L> comps = primitive::extract::components(output, c8(), ncomps);
-	  //   // mln_ch_value(I, value::rgb8) both;
-
-	  //   // both = data::convert(value::rgb8(), input);
-
-	  //   // // Needed since the rotated image origin is (0,0).
-	  //   // dpoint2d dp(input.domain().pcenter() - input_clo.domain().pcenter());
-
-	  //   // for_all_comps(c, comps)
-	  //   // {
-	  //   //   box2d b = geom::rotate(comps(c).bbox(), -90, input_clo.domain().pcenter());
-	  //   //   mln::draw::line(both,
-	  //   // 		      b.pmin() + dp,
-	  //   // 		      b.pmax() + dp,
-	  //   // 		      literal::green);
-	  //   // }
-	  // }
+	  if (_debug_)
+	  {
+	    logger().log_image(AuxiliaryResults, output,
+			       "separators_filtered");
+	  }
 
 	  gt.stop();
 	  t_ = gt;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* scribo/filter/object_links_bottom_aligned.hh,
	* scribo/filter/object_links_top_aligned.hh,
	* src/debug/show_links_bottom_aligned.cc,
	* src/debug/show_links_top_aligned.cc: Update call to
	linking routine.
	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
	* scribo/preprocessing/rotate_90.hh,
	* scribo/text/extract_lines.hh,
	* src/debug/show_stoppers.cc: Revamp.
	* scribo/primitive/extract/horizontal_separators.hh: Actually use
	horizontal routine.
	* scribo/primitive/extract/separators.hh: Adjust borders.
	* scribo/primitive/identify.hh: Disable for now.
	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
	* src/content_in_doc.cc: Add more usage information.
	* src/debug/show_links_center_aligned.cc: Update anchor value.
	* src/debug/show_text_lines.cc: Add XML output.
	* src/preprocessing/rotate.cc,
	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
---
 scribo/ChangeLog                                   |   36 +++++++++++++++++
 .../scribo/filter/object_links_bottom_aligned.hh   |    8 ++--
 .../filter/object_links_non_aligned_simple.hh      |    3 +-
 scribo/scribo/filter/object_links_top_aligned.hh   |    7 ++-
 scribo/scribo/preprocessing/rotate_90.hh           |   25 +++++++-----
 .../primitive/extract/horizontal_separators.hh     |   27 +++++++------
 scribo/scribo/primitive/extract/separators.hh      |    9 ++++-
 scribo/scribo/primitive/identify.hh                |   30 +++++++-------
 .../primitive/link/with_single_right_link.hh       |   16 +++++---
 .../primitive/link/with_single_right_link_top.hh   |   28 +++++++-------
 scribo/scribo/text/extract_lines.hh                |   21 ++++++----
 scribo/src/content_in_doc.cc                       |    3 +-
 scribo/src/debug/show_links_bottom_aligned.cc      |   16 ++++---
 scribo/src/debug/show_links_center_aligned.cc      |    6 +-
 scribo/src/debug/show_links_top_aligned.cc         |   18 ++++----
 scribo/src/debug/show_stoppers.cc                  |   42 ++++++++++++++-----
 scribo/src/debug/show_text_lines.cc                |   17 ++++++--
 scribo/src/preprocessing/rotate.cc                 |    1 +
 scribo/src/preprocessing/rotate_90.cc              |    1 +
 19 files changed, 202 insertions(+), 112 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 5705c05..5ad1ca7 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,41 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Various small fixes.
+
+	* scribo/filter/object_links_bottom_aligned.hh,
+	* scribo/filter/object_links_top_aligned.hh,
+	* src/debug/show_links_bottom_aligned.cc,
+	* src/debug/show_links_top_aligned.cc: Update call to
+	linking routine.
+
+	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
+
+	* scribo/preprocessing/rotate_90.hh,
+	* scribo/text/extract_lines.hh,
+	* src/debug/show_stoppers.cc: Revamp.
+
+	* scribo/primitive/extract/horizontal_separators.hh: Actually use
+	horizontal routine.
+
+	* scribo/primitive/extract/separators.hh: Adjust borders.
+
+	* scribo/primitive/identify.hh: Disable for now.
+
+	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
+
+	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
+
+	* src/content_in_doc.cc: Add more usage information.
+
+	* src/debug/show_links_center_aligned.cc: Update anchor value.
+
+	* src/debug/show_text_lines.cc: Add XML output.
+
+	* src/preprocessing/rotate.cc,
+	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Introduce a new component linking method.
 
 	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
diff --git a/scribo/scribo/filter/object_links_bottom_aligned.hh b/scribo/scribo/filter/object_links_bottom_aligned.hh
index ba8ff31..2329f37 100644
--- a/scribo/scribo/filter/object_links_bottom_aligned.hh
+++ b/scribo/scribo/filter/object_links_bottom_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -38,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -97,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Bottom, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Bottom);
 
       trace::exiting("scribo::filter::object_links_bottom_aligned");
       return output;
diff --git a/scribo/scribo/filter/object_links_non_aligned_simple.hh b/scribo/scribo/filter/object_links_non_aligned_simple.hh
index 2381d88..5abf598 100644
--- a/scribo/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/scribo/filter/object_links_non_aligned_simple.hh
@@ -103,8 +103,7 @@ namespace scribo
 
       const component_set<L>& comps = links.components();
 
-      object_links<L> output(links);
-
+      object_links<L> output = links.duplicate();
 
       float max_alpha_rad = (max_alpha / 180.0f) * math::pi;
 
diff --git a/scribo/scribo/filter/object_links_top_aligned.hh b/scribo/scribo/filter/object_links_top_aligned.hh
index 57e8d40..48598c6 100644
--- a/scribo/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/scribo/filter/object_links_top_aligned.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -37,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -96,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Top, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Top);
 
       trace::exiting("scribo::filter::object_links_top_aligned");
       return output;
diff --git a/scribo/scribo/preprocessing/rotate_90.hh b/scribo/scribo/preprocessing/rotate_90.hh
index 96c0469..523b82f 100644
--- a/scribo/scribo/preprocessing/rotate_90.hh
+++ b/scribo/scribo/preprocessing/rotate_90.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -98,11 +99,13 @@ namespace scribo
 
       const mln_value(I)* in_ptr = input.buffer();
 
-      unsigned in_ncols = geom::ncols(input) + 2 * input.border();
-      unsigned in_nrows = geom::nrows(input) + 2 * input.border();
+      unsigned
+	in_ncols = geom::ncols(input) + 2 * input.border(),
+	in_nrows = geom::nrows(input) + 2 * input.border();
 
-      unsigned out_ncols = geom::ncols(output);
-      unsigned out_nrows = geom::nrows(output);
+      unsigned
+	out_ncols = geom::ncols(output) + 2 * input.border(),
+	out_nrows = geom::nrows(output) + 2 * input.border();
 
       int
 	out_next_offset,
@@ -112,21 +115,21 @@ namespace scribo
 
       if (positive) // +90 deg
       {
-	dpoint2d dp(- out_nrows - 2 * output.border(), - 1);
+	dpoint2d dp(out_nrows, + 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
 
-	out_ptr += 2 * output.border() + out_ncols - 1;
+	out_ptr += output.delta_index(dpoint2d(out_nrows - 1, 0));
       }
       else // -90 deg
       {
-	dpoint2d dp(out_nrows + 2 * output.border(), + 1);
+	dpoint2d dp(- out_nrows, - 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
 
-	out_ptr += output.delta_index(dpoint2d(out_nrows + 2 * output.border() - 1, 0));
+	out_ptr += out_ncols - 1;
       }
 
       for (unsigned row = 0; row < in_nrows; ++row)
diff --git a/scribo/scribo/primitive/extract/horizontal_separators.hh b/scribo/scribo/primitive/extract/horizontal_separators.hh
index 9a6ea39..95db09e 100644
--- a/scribo/scribo/primitive/extract/horizontal_separators.hh
+++ b/scribo/scribo/primitive/extract/horizontal_separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -23,17 +24,17 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
-# define SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
 
 /// \file
 ///
-/// Extract vertical separators.
+/// Extract horizontal separators.
 
 # include <mln/core/concept/image.hh>
 # include <mln/arith/plus.hh>
 
-# include <scribo/primitive/extract/lines_v_pattern.hh>
+# include <scribo/primitive/extract/lines_h_pattern.hh>
 
 
 namespace scribo
@@ -47,7 +48,7 @@ namespace scribo
 
       using namespace mln;
 
-      /// \brief Extract vertical separators.
+      /// \brief Extract horizontal separators.
       /*!
        *
        * \param[in]     input       A binary image.
@@ -59,7 +60,7 @@ namespace scribo
        */
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input, unsigned line_length);
+      horizontal_separators(const Image<I>& input, unsigned line_length);
 
 
 
@@ -68,19 +69,19 @@ namespace scribo
 
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input_, unsigned line_length)
+      horizontal_separators(const Image<I>& input_, unsigned line_length)
       {
-	trace::entering("scribo::primitive::extract::vertical_separators");
+	trace::entering("scribo::primitive::extract::horizontal_separators");
 
 	const I& input = exact(input_);
 	mlc_is(mln_value(I), bool)::check();
 	mln_precondition(input.is_valid());
 
 	mln_concrete(I)
-	  vlines = extract::lines_v_pattern(input, line_length, 3);
+	  hlines = extract::lines_h_pattern(input, line_length, 3);
 
-	trace::exiting("scribo::primitive::extract::vertical_separators");
-	return vlines;
+	trace::exiting("scribo::primitive::extract::horizontal_separators");
+	return hlines;
       }
 
 
@@ -92,4 +93,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
diff --git a/scribo/scribo/primitive/extract/separators.hh b/scribo/scribo/primitive/extract/separators.hh
index 2ba22b4..316f806 100644
--- a/scribo/scribo/primitive/extract/separators.hh
+++ b/scribo/scribo/primitive/extract/separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -82,6 +83,12 @@ namespace scribo
 	  vlines = extract::lines_v_pattern(input, line_length, 3);
 	hlines += vlines;
 
+	// FIXME: UGLY! We should not do that!
+	// Restore border size.
+	// Previous treatments may have changed it.
+	border::resize(hlines, border::thickness);
+	border::resize(input, border::thickness);
+
 	trace::exiting("scribo::primitive::extract::separators");
 	return hlines;
       }
diff --git a/scribo/scribo/primitive/identify.hh b/scribo/scribo/primitive/identify.hh
index 1bed712..6aa6ad3 100644
--- a/scribo/scribo/primitive/identify.hh
+++ b/scribo/scribo/primitive/identify.hh
@@ -28,7 +28,8 @@
 
 /*! \brief try to determine the type of a component.
 
-\fixme Add support for more component type (graphic, images, ...)
+\fixme Write it and add support for component type (graphic, images,
+...)
  */
 
 # include <mln/trace/all.hh>
@@ -48,24 +49,25 @@ namespace scribo
 
       mln_assertion(comps.is_valid());
 
-      component_set<L> output = comps.duplicate();
+      // component_set<L> output = comps.duplicate();
 
-      for_all_comps(c, comps)
-	if (comps(c).is_valid())
-	{
-	  float
-	    min = comps(c).bbox().height(),
-	    max = comps(c).bbox().width();
+      // for_all_comps(c, comps)
+      // 	if (comps(c).is_valid())
+      // 	{
+      // 	  float
+      // 	    min = comps(c).bbox().height(),
+      // 	    max = comps(c).bbox().width();
 
-	  if (comps(c).bbox().width() < comps(c).bbox().height())
-	    std::swap(min, max);
+      // 	  if (comps(c).bbox().width() < comps(c).bbox().height())
+      // 	    std::swap(min, max);
 
-	  if (max/min > 10)
-	    output(c).update_type(component::LineSeparator);
-	}
+      // 	  if (max/min > 10)
+      // 	    output(c).update_type(component::LineSeparator);
+      // 	}
 
       mln::trace::exiting("scribo::primitive::identify");
-      return output;
+      //return output;
+      return comps;
     }
 
 # ifndef MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/primitive/link/with_single_right_link.hh b/scribo/scribo/primitive/link/with_single_right_link.hh
index e1abdcf..bc7942b 100644
--- a/scribo/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -28,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -71,7 +72,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance);
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter);
 
 
       /// \overload
@@ -123,7 +125,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance)
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link");
 
@@ -132,7 +135,7 @@ namespace scribo
 	internal::single_right_functor<L>
 	  functor(components, neighb_max_distance);
 
-	object_links<L> output = compute(functor, anchor::MassCenter);
+	object_links<L> output = compute(functor, anchor);
 
 	trace::exiting("scribo::primitive::link::with_single_right_link");
 	return output;
@@ -144,7 +147,8 @@ namespace scribo
       object_links<L>
       with_single_right_link(const component_set<L>& components)
       {
-	return with_single_right_link(components, mln_max(unsigned));
+	return with_single_right_link(components, mln_max(unsigned),
+				      anchor::MassCenter);
       }
 
 
diff --git a/scribo/scribo/primitive/link/with_single_right_link_top.hh b/scribo/scribo/primitive/link/with_single_right_link_top.hh
index 6d26114..ada6650 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_top.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_top.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -29,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -60,10 +60,10 @@ namespace scribo
     namespace link
     {
 
-      /// \brief Link objects with their right neighbor if exists.
+      /// \brief Link components with their right neighbor if exists.
       /// Lookup startup point is the object top center.
       ///
-      /// \param[in] objects An object image.
+      /// \param[in] components A component set.
       /// \param[in] The maximum distance allowed to seach a neighbor object.
       ///
       /// \return Object links data.
@@ -71,7 +71,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance);
 
 
@@ -80,7 +80,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects);
+      with_single_right_link_top(const component_set<L>& components);
 
 
 
@@ -104,9 +104,9 @@ namespace scribo
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_top_functor(const component_set<L>& objects,
+	  single_right_top_functor(const component_set<L>& components,
 				   unsigned dmax)
-	    : super_(objects, dmax, anchor::Horizontal)
+	    : super_(components, dmax, anchor::Horizontal)
 	  {
 	  }
 
@@ -126,15 +126,15 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link_top");
 
-	mln_precondition(objects.is_valid());
+	mln_precondition(components.is_valid());
 
 	internal::single_right_top_functor<L>
-	  functor(objects, neighb_max_distance);
+	  functor(components, neighb_max_distance);
 
 	object_links<L> output = compute(functor, anchor::Top);
 
@@ -146,9 +146,9 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects)
+      with_single_right_link_top(const component_set<L>& components)
       {
-	return with_single_right_link_top(objects, mln_max(unsigned));
+	return with_single_right_link_top(components, mln_max(unsigned));
       }
 
 
diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh
index 9949d09..e69a249 100644
--- a/scribo/scribo/text/extract_lines.hh
+++ b/scribo/scribo/text/extract_lines.hh
@@ -120,14 +120,19 @@ namespace scribo
 	comps.add_separators(separators);
 
       /// Linking potential comps
-      object_links<L> left_link
-	= primitive::link::with_single_left_link_dmax_ratio(comps,
-							    primitive::link::internal::dmax_width_and_height(1),
-							    anchor::MassCenter);
-      object_links<L> right_link
-	= primitive::link::with_single_right_link_dmax_ratio(comps,
-							     primitive::link::internal::dmax_width_and_height(1),
-							     anchor::MassCenter);
+      object_links<L>
+	left_link = primitive::link::with_single_left_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
+
+      object_links<L>
+	right_link = primitive::link::with_single_right_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
 
       // Validating left and right links.
       object_links<L>
diff --git a/scribo/src/content_in_doc.cc b/scribo/src/content_in_doc.cc
index 81ec4fb..c879504 100644
--- a/scribo/src/content_in_doc.cc
+++ b/scribo/src/content_in_doc.cc
@@ -57,7 +57,8 @@ const char *args_desc[][2] =
   { "pmin_col", "Col index of the top left corner of the Region of interest." },
   { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
   { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
-  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)" },
+  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)."
+    "An empty language will disable OCR." },
   { "find_lines", "Find vertical lines. (Default 1)" },
   { "find_whitespaces", "Find whitespaces separators. (Default 1)" },
   { "K", "Sauvola's binarization threshold parameter. (Default: 0.34)" },
diff --git a/scribo/src/debug/show_links_bottom_aligned.cc b/scribo/src/debug/show_links_bottom_aligned.cc
index bf858dc..634551b 100644
--- a/scribo/src/debug/show_links_bottom_aligned.cc
+++ b/scribo/src/debug/show_links_bottom_aligned.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -40,8 +41,8 @@
 #include <scribo/core/component_set.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_bottom.hh>
-#include <scribo/filter/object_links_bottom_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
 #include <scribo/debug/usage.hh>
@@ -82,19 +83,20 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_bottom(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_bottom_aligned(right_links, atof(argv[3]));
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictBottomCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::bottom,
-					      atoi(argv[2]));
+					      anchor::StrictBottomCenter);
+
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_links_center_aligned.cc b/scribo/src/debug/show_links_center_aligned.cc
index 727e7e9..9c358d9 100644
--- a/scribo/src/debug/show_links_center_aligned.cc
+++ b/scribo/src/debug/show_links_center_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -91,7 +91,7 @@ int main(int argc, char* argv[])
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-      					      scribo::debug::center);
+      					      anchor::Center);
 
   io::ppm::save(decision_image, argv[3]);
 
diff --git a/scribo/src/debug/show_links_top_aligned.cc b/scribo/src/debug/show_links_top_aligned.cc
index 9efcb6d..5ffcb70 100644
--- a/scribo/src/debug/show_links_top_aligned.cc
+++ b/scribo/src/debug/show_links_top_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -39,10 +39,11 @@
 #include <mln/io/ppm/save.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_top.hh>
-#include <scribo/filter/object_links_top_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
+#include <scribo/debug/links_image.hh>
 #include <scribo/debug/usage.hh>
 
 
@@ -82,20 +83,19 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_top(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_top_aligned(right_links, atof(argv[3]));
-
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictTopCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::top,
-					      atoi(argv[2]));
+					      anchor::StrictTopCenter);
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_stoppers.cc b/scribo/src/debug/show_stoppers.cc
index a108da1..0e7fe0f 100644
--- a/scribo/src/debug/show_stoppers.cc
+++ b/scribo/src/debug/show_stoppers.cc
@@ -25,8 +25,11 @@
 #include <scribo/primitive/extract/lines_v_pattern.hh>
 #include <scribo/primitive/extract/separators_nonvisible.hh>
 #include <scribo/debug/usage.hh>
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/debug/bboxes_image.hh>
+#include <scribo/core/document.hh>
+#include <scribo/core/def/lbl_type.hh>
 
+#include <scribo/io/xml/save.hh>
 
 const char *args_desc[][2] =
 {
@@ -41,10 +44,11 @@ int main(int argc, char *argv[])
 {
   using namespace mln;
 
-  if (argc != 7 && argc != 5)
+  if (argc != 8 && argc != 6)
     return scribo::debug::usage(argv,
 				"Extract horizontal, vertical lines and stoppers",
-				"input.pbm output.pbm input_wo_seps.pbm output.ppm length delta",
+				"input.pbm out_seps.pbm out_in_wo_seps.pbm "
+				"out_seps_bbox.ppm out_visible_seps.pbm length delta",
 				args_desc);
 
   trace::entering("main");
@@ -56,20 +60,22 @@ int main(int argc, char *argv[])
   unsigned
     length = 101,
     delta = 4;
-  if (argc > 5)
+  if (argc > 6)
   {
-    length = atoi(argv[5]);
-    delta = atoi(argv[6]);
+    length = atoi(argv[6]);
+    delta = atoi(argv[7]);
   }
 
   util::timer t;
 
   t.start();
   image2d<bool>
-    h_lines = scribo::primitive::extract::lines_h_pattern(input, length, delta);
+    h_lines = scribo::primitive::extract::lines_h_pattern(input, length,
+							  delta);
 
   image2d<bool>
-    v_lines = scribo::primitive::extract::lines_v_pattern(input, length, delta);
+    v_lines = scribo::primitive::extract::lines_v_pattern(input, length,
+							  delta);
 
   v_lines += h_lines;
 
@@ -87,18 +93,32 @@ int main(int argc, char *argv[])
   image2d<value::int_u8> lbl = labeling::foreground(v_lines, c4(), nlabels);
   mln::util::array<box2d>
     bbox = labeling::compute(accu::shape::bbox<point2d>(), lbl, nlabels);
-  scribo::debug::save_bboxes_image(input, bbox, argv[4], literal::red);
+  io::ppm::save(scribo::debug::bboxes_image(input, bbox, literal::red),
+		argv[4]);
+
+  // Save visible separators
+  mln::io::pbm::save(v_lines, argv[5]);
 
   t.resume();
 
   // Non visible separators
-  v_lines += scribo::primitive::extract::separators_nonvisible(input);
+  image2d<bool>
+    nonvisible = scribo::primitive::extract::separators_nonvisible(input);
 
   t.stop();
   std::cout << t << "s" << std::endl;
 
+  // // Saving stoppers data to XML
+  // typedef image2d<scribo::def::lbl_type> L;
+  // scribo::document<L> doc(argv[1]);
+  // doc.open();
+  // doc.set_whitespace_separators(nonvisible);
+  // doc.set_line_separators(v_lines);
+  // scribo::io::xml::save(doc, argv[5], scribo::io::xml::Full);
+
   // Save binary image.
-  io::pbm::save(v_lines, argv[2]);
+  v_lines += nonvisible;
+  mln::io::pbm::save(v_lines, argv[2]);
 
   trace::exiting("main");
 }
diff --git a/scribo/src/debug/show_text_lines.cc b/scribo/src/debug/show_text_lines.cc
index d5a5c8f..1da0d66 100644
--- a/scribo/src/debug/show_text_lines.cc
+++ b/scribo/src/debug/show_text_lines.cc
@@ -32,20 +32,20 @@
 #include <mln/pw/all.hh>
 #include <mln/core/image/dmorph/image_if.hh>
 #include <mln/data/convert.hh>
+#include <mln/literal/colors.hh>
 
 #include <scribo/text/recognition.hh>
 
 #include <scribo/debug/usage.hh>
 
+#include <scribo/core/document.hh>
 #include <scribo/core/component_set.hh>
 #include <scribo/core/object_links.hh>
 #include <scribo/core/object_groups.hh>
 
 #include <scribo/text/extract_lines.hh>
 
-#include <scribo/io/text_boxes/save.hh>
-
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/io/xml/save.hh>
 
 
 const char *args_desc[][2] =
@@ -60,10 +60,10 @@ int main(int argc, char* argv[])
   using namespace scribo;
   using namespace mln;
 
-  if (argc != 6)
+  if (argc != 7)
     return scribo::debug::usage(argv,
 				"Show text lines",
-				"input.pbm input_seps.pbm out.ppm out.pbm comps.pbm",
+				"input.pbm input_seps.pbm out_text_boxes.ppm out_text_boxes.pbm out_text_comps.pbm out_lines.xml",
 				args_desc);
 
   trace::entering("main");
@@ -119,5 +119,12 @@ int main(int argc, char* argv[])
     mln::io::pbm::save(output, argv[5]);
   }
 
+  // Saving stoppers data to XML
+  document<L> doc(argv[1]);
+  doc.open();
+  doc.set_paragraphs(scribo::make::paragraph(lines));
+  scribo::io::xml::save(doc, argv[6], scribo::io::xml::Full);
+
+
   trace::exiting("main");
 }
diff --git a/scribo/src/preprocessing/rotate.cc b/scribo/src/preprocessing/rotate.cc
index 2910684..c0b599b 100644
--- a/scribo/src/preprocessing/rotate.cc
+++ b/scribo/src/preprocessing/rotate.cc
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
 
   typedef image2d<value::rgb8> I;
   I ima;
+  Magick::InitializeMagick(0);
   io::magick::load(ima, argv[1]);
 
   image2d<value::rgb8>
diff --git a/scribo/src/preprocessing/rotate_90.cc b/scribo/src/preprocessing/rotate_90.cc
index c5e9536..23625a9 100644
--- a/scribo/src/preprocessing/rotate_90.cc
+++ b/scribo/src/preprocessing/rotate_90.cc
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
 				"input.* output.ppm <positive>",
 				args_desc);
 
+  Magick::InitializeMagick(0);
 
   typedef image2d<value::rgb8> I;
   I ima;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* scribo/filter/object_links_bottom_aligned.hh,
	* scribo/filter/object_links_top_aligned.hh,
	* src/debug/show_links_bottom_aligned.cc,
	* src/debug/show_links_top_aligned.cc: Update call to
	linking routine.
	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
	* scribo/preprocessing/rotate_90.hh,
	* scribo/text/extract_lines.hh,
	* src/debug/show_stoppers.cc: Revamp.
	* scribo/primitive/extract/horizontal_separators.hh: Actually use
	horizontal routine.
	* scribo/primitive/extract/separators.hh: Adjust borders.
	* scribo/primitive/identify.hh: Disable for now.
	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
	* src/content_in_doc.cc: Add more usage information.
	* src/debug/show_links_center_aligned.cc: Update anchor value.
	* src/debug/show_text_lines.cc: Add XML output.
	* src/preprocessing/rotate.cc,
	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
---
 scribo/ChangeLog                                   |   36 +++++++++++++++++
 .../scribo/filter/object_links_bottom_aligned.hh   |    8 ++--
 .../filter/object_links_non_aligned_simple.hh      |    3 +-
 scribo/scribo/filter/object_links_top_aligned.hh   |    7 ++-
 scribo/scribo/preprocessing/rotate_90.hh           |   25 +++++++-----
 .../primitive/extract/horizontal_separators.hh     |   27 +++++++------
 scribo/scribo/primitive/extract/separators.hh      |    9 ++++-
 scribo/scribo/primitive/identify.hh                |   30 +++++++-------
 .../primitive/link/with_single_right_link.hh       |   16 +++++---
 .../primitive/link/with_single_right_link_top.hh   |   28 +++++++-------
 scribo/scribo/text/extract_lines.hh                |   21 ++++++----
 scribo/src/content_in_doc.cc                       |    3 +-
 scribo/src/debug/show_links_bottom_aligned.cc      |   16 ++++---
 scribo/src/debug/show_links_center_aligned.cc      |    6 +-
 scribo/src/debug/show_links_top_aligned.cc         |   18 ++++----
 scribo/src/debug/show_stoppers.cc                  |   42 ++++++++++++++-----
 scribo/src/debug/show_text_lines.cc                |   17 ++++++--
 scribo/src/preprocessing/rotate.cc                 |    1 +
 scribo/src/preprocessing/rotate_90.cc              |    1 +
 19 files changed, 202 insertions(+), 112 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 3399b01..b6f7f1a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,41 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Various small fixes.
+
+	* scribo/filter/object_links_bottom_aligned.hh,
+	* scribo/filter/object_links_top_aligned.hh,
+	* src/debug/show_links_bottom_aligned.cc,
+	* src/debug/show_links_top_aligned.cc: Update call to
+	linking routine.
+
+	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
+
+	* scribo/preprocessing/rotate_90.hh,
+	* scribo/text/extract_lines.hh,
+	* src/debug/show_stoppers.cc: Revamp.
+
+	* scribo/primitive/extract/horizontal_separators.hh: Actually use
+	horizontal routine.
+
+	* scribo/primitive/extract/separators.hh: Adjust borders.
+
+	* scribo/primitive/identify.hh: Disable for now.
+
+	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
+
+	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
+
+	* src/content_in_doc.cc: Add more usage information.
+
+	* src/debug/show_links_center_aligned.cc: Update anchor value.
+
+	* src/debug/show_text_lines.cc: Add XML output.
+
+	* src/preprocessing/rotate.cc,
+	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Introduce a new component linking method.
 
 	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
diff --git a/scribo/scribo/filter/object_links_bottom_aligned.hh b/scribo/scribo/filter/object_links_bottom_aligned.hh
index ba8ff31..2329f37 100644
--- a/scribo/scribo/filter/object_links_bottom_aligned.hh
+++ b/scribo/scribo/filter/object_links_bottom_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -38,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -97,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Bottom, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Bottom);
 
       trace::exiting("scribo::filter::object_links_bottom_aligned");
       return output;
diff --git a/scribo/scribo/filter/object_links_non_aligned_simple.hh b/scribo/scribo/filter/object_links_non_aligned_simple.hh
index 2381d88..5abf598 100644
--- a/scribo/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/scribo/filter/object_links_non_aligned_simple.hh
@@ -103,8 +103,7 @@ namespace scribo
 
       const component_set<L>& comps = links.components();
 
-      object_links<L> output(links);
-
+      object_links<L> output = links.duplicate();
 
       float max_alpha_rad = (max_alpha / 180.0f) * math::pi;
 
diff --git a/scribo/scribo/filter/object_links_top_aligned.hh b/scribo/scribo/filter/object_links_top_aligned.hh
index 57e8d40..48598c6 100644
--- a/scribo/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/scribo/filter/object_links_top_aligned.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -37,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -96,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Top, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Top);
 
       trace::exiting("scribo::filter::object_links_top_aligned");
       return output;
diff --git a/scribo/scribo/preprocessing/rotate_90.hh b/scribo/scribo/preprocessing/rotate_90.hh
index 96c0469..523b82f 100644
--- a/scribo/scribo/preprocessing/rotate_90.hh
+++ b/scribo/scribo/preprocessing/rotate_90.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -98,11 +99,13 @@ namespace scribo
 
       const mln_value(I)* in_ptr = input.buffer();
 
-      unsigned in_ncols = geom::ncols(input) + 2 * input.border();
-      unsigned in_nrows = geom::nrows(input) + 2 * input.border();
+      unsigned
+	in_ncols = geom::ncols(input) + 2 * input.border(),
+	in_nrows = geom::nrows(input) + 2 * input.border();
 
-      unsigned out_ncols = geom::ncols(output);
-      unsigned out_nrows = geom::nrows(output);
+      unsigned
+	out_ncols = geom::ncols(output) + 2 * input.border(),
+	out_nrows = geom::nrows(output) + 2 * input.border();
 
       int
 	out_next_offset,
@@ -112,21 +115,21 @@ namespace scribo
 
       if (positive) // +90 deg
       {
-	dpoint2d dp(- out_nrows - 2 * output.border(), - 1);
+	dpoint2d dp(out_nrows, + 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
 
-	out_ptr += 2 * output.border() + out_ncols - 1;
+	out_ptr += output.delta_index(dpoint2d(out_nrows - 1, 0));
       }
       else // -90 deg
       {
-	dpoint2d dp(out_nrows + 2 * output.border(), + 1);
+	dpoint2d dp(- out_nrows, - 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
 
-	out_ptr += output.delta_index(dpoint2d(out_nrows + 2 * output.border() - 1, 0));
+	out_ptr += out_ncols - 1;
       }
 
       for (unsigned row = 0; row < in_nrows; ++row)
diff --git a/scribo/scribo/primitive/extract/horizontal_separators.hh b/scribo/scribo/primitive/extract/horizontal_separators.hh
index 9a6ea39..95db09e 100644
--- a/scribo/scribo/primitive/extract/horizontal_separators.hh
+++ b/scribo/scribo/primitive/extract/horizontal_separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -23,17 +24,17 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
-# define SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
 
 /// \file
 ///
-/// Extract vertical separators.
+/// Extract horizontal separators.
 
 # include <mln/core/concept/image.hh>
 # include <mln/arith/plus.hh>
 
-# include <scribo/primitive/extract/lines_v_pattern.hh>
+# include <scribo/primitive/extract/lines_h_pattern.hh>
 
 
 namespace scribo
@@ -47,7 +48,7 @@ namespace scribo
 
       using namespace mln;
 
-      /// \brief Extract vertical separators.
+      /// \brief Extract horizontal separators.
       /*!
        *
        * \param[in]     input       A binary image.
@@ -59,7 +60,7 @@ namespace scribo
        */
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input, unsigned line_length);
+      horizontal_separators(const Image<I>& input, unsigned line_length);
 
 
 
@@ -68,19 +69,19 @@ namespace scribo
 
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input_, unsigned line_length)
+      horizontal_separators(const Image<I>& input_, unsigned line_length)
       {
-	trace::entering("scribo::primitive::extract::vertical_separators");
+	trace::entering("scribo::primitive::extract::horizontal_separators");
 
 	const I& input = exact(input_);
 	mlc_is(mln_value(I), bool)::check();
 	mln_precondition(input.is_valid());
 
 	mln_concrete(I)
-	  vlines = extract::lines_v_pattern(input, line_length, 3);
+	  hlines = extract::lines_h_pattern(input, line_length, 3);
 
-	trace::exiting("scribo::primitive::extract::vertical_separators");
-	return vlines;
+	trace::exiting("scribo::primitive::extract::horizontal_separators");
+	return hlines;
       }
 
 
@@ -92,4 +93,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
diff --git a/scribo/scribo/primitive/extract/separators.hh b/scribo/scribo/primitive/extract/separators.hh
index 2ba22b4..316f806 100644
--- a/scribo/scribo/primitive/extract/separators.hh
+++ b/scribo/scribo/primitive/extract/separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -82,6 +83,12 @@ namespace scribo
 	  vlines = extract::lines_v_pattern(input, line_length, 3);
 	hlines += vlines;
 
+	// FIXME: UGLY! We should not do that!
+	// Restore border size.
+	// Previous treatments may have changed it.
+	border::resize(hlines, border::thickness);
+	border::resize(input, border::thickness);
+
 	trace::exiting("scribo::primitive::extract::separators");
 	return hlines;
       }
diff --git a/scribo/scribo/primitive/identify.hh b/scribo/scribo/primitive/identify.hh
index 1bed712..6aa6ad3 100644
--- a/scribo/scribo/primitive/identify.hh
+++ b/scribo/scribo/primitive/identify.hh
@@ -28,7 +28,8 @@
 
 /*! \brief try to determine the type of a component.
 
-\fixme Add support for more component type (graphic, images, ...)
+\fixme Write it and add support for component type (graphic, images,
+...)
  */
 
 # include <mln/trace/all.hh>
@@ -48,24 +49,25 @@ namespace scribo
 
       mln_assertion(comps.is_valid());
 
-      component_set<L> output = comps.duplicate();
+      // component_set<L> output = comps.duplicate();
 
-      for_all_comps(c, comps)
-	if (comps(c).is_valid())
-	{
-	  float
-	    min = comps(c).bbox().height(),
-	    max = comps(c).bbox().width();
+      // for_all_comps(c, comps)
+      // 	if (comps(c).is_valid())
+      // 	{
+      // 	  float
+      // 	    min = comps(c).bbox().height(),
+      // 	    max = comps(c).bbox().width();
 
-	  if (comps(c).bbox().width() < comps(c).bbox().height())
-	    std::swap(min, max);
+      // 	  if (comps(c).bbox().width() < comps(c).bbox().height())
+      // 	    std::swap(min, max);
 
-	  if (max/min > 10)
-	    output(c).update_type(component::LineSeparator);
-	}
+      // 	  if (max/min > 10)
+      // 	    output(c).update_type(component::LineSeparator);
+      // 	}
 
       mln::trace::exiting("scribo::primitive::identify");
-      return output;
+      //return output;
+      return comps;
     }
 
 # ifndef MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/primitive/link/with_single_right_link.hh b/scribo/scribo/primitive/link/with_single_right_link.hh
index e1abdcf..bc7942b 100644
--- a/scribo/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -28,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -71,7 +72,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance);
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter);
 
 
       /// \overload
@@ -123,7 +125,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance)
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link");
 
@@ -132,7 +135,7 @@ namespace scribo
 	internal::single_right_functor<L>
 	  functor(components, neighb_max_distance);
 
-	object_links<L> output = compute(functor, anchor::MassCenter);
+	object_links<L> output = compute(functor, anchor);
 
 	trace::exiting("scribo::primitive::link::with_single_right_link");
 	return output;
@@ -144,7 +147,8 @@ namespace scribo
       object_links<L>
       with_single_right_link(const component_set<L>& components)
       {
-	return with_single_right_link(components, mln_max(unsigned));
+	return with_single_right_link(components, mln_max(unsigned),
+				      anchor::MassCenter);
       }
 
 
diff --git a/scribo/scribo/primitive/link/with_single_right_link_top.hh b/scribo/scribo/primitive/link/with_single_right_link_top.hh
index 6d26114..ada6650 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_top.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_top.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -29,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -60,10 +60,10 @@ namespace scribo
     namespace link
     {
 
-      /// \brief Link objects with their right neighbor if exists.
+      /// \brief Link components with their right neighbor if exists.
       /// Lookup startup point is the object top center.
       ///
-      /// \param[in] objects An object image.
+      /// \param[in] components A component set.
       /// \param[in] The maximum distance allowed to seach a neighbor object.
       ///
       /// \return Object links data.
@@ -71,7 +71,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance);
 
 
@@ -80,7 +80,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects);
+      with_single_right_link_top(const component_set<L>& components);
 
 
 
@@ -104,9 +104,9 @@ namespace scribo
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_top_functor(const component_set<L>& objects,
+	  single_right_top_functor(const component_set<L>& components,
 				   unsigned dmax)
-	    : super_(objects, dmax, anchor::Horizontal)
+	    : super_(components, dmax, anchor::Horizontal)
 	  {
 	  }
 
@@ -126,15 +126,15 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link_top");
 
-	mln_precondition(objects.is_valid());
+	mln_precondition(components.is_valid());
 
 	internal::single_right_top_functor<L>
-	  functor(objects, neighb_max_distance);
+	  functor(components, neighb_max_distance);
 
 	object_links<L> output = compute(functor, anchor::Top);
 
@@ -146,9 +146,9 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects)
+      with_single_right_link_top(const component_set<L>& components)
       {
-	return with_single_right_link_top(objects, mln_max(unsigned));
+	return with_single_right_link_top(components, mln_max(unsigned));
       }
 
 
diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh
index 9949d09..e69a249 100644
--- a/scribo/scribo/text/extract_lines.hh
+++ b/scribo/scribo/text/extract_lines.hh
@@ -120,14 +120,19 @@ namespace scribo
 	comps.add_separators(separators);
 
       /// Linking potential comps
-      object_links<L> left_link
-	= primitive::link::with_single_left_link_dmax_ratio(comps,
-							    primitive::link::internal::dmax_width_and_height(1),
-							    anchor::MassCenter);
-      object_links<L> right_link
-	= primitive::link::with_single_right_link_dmax_ratio(comps,
-							     primitive::link::internal::dmax_width_and_height(1),
-							     anchor::MassCenter);
+      object_links<L>
+	left_link = primitive::link::with_single_left_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
+
+      object_links<L>
+	right_link = primitive::link::with_single_right_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
 
       // Validating left and right links.
       object_links<L>
diff --git a/scribo/src/content_in_doc.cc b/scribo/src/content_in_doc.cc
index 81ec4fb..c879504 100644
--- a/scribo/src/content_in_doc.cc
+++ b/scribo/src/content_in_doc.cc
@@ -57,7 +57,8 @@ const char *args_desc[][2] =
   { "pmin_col", "Col index of the top left corner of the Region of interest." },
   { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
   { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
-  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)" },
+  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)."
+    "An empty language will disable OCR." },
   { "find_lines", "Find vertical lines. (Default 1)" },
   { "find_whitespaces", "Find whitespaces separators. (Default 1)" },
   { "K", "Sauvola's binarization threshold parameter. (Default: 0.34)" },
diff --git a/scribo/src/debug/show_links_bottom_aligned.cc b/scribo/src/debug/show_links_bottom_aligned.cc
index bf858dc..634551b 100644
--- a/scribo/src/debug/show_links_bottom_aligned.cc
+++ b/scribo/src/debug/show_links_bottom_aligned.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -40,8 +41,8 @@
 #include <scribo/core/component_set.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_bottom.hh>
-#include <scribo/filter/object_links_bottom_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
 #include <scribo/debug/usage.hh>
@@ -82,19 +83,20 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_bottom(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_bottom_aligned(right_links, atof(argv[3]));
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictBottomCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::bottom,
-					      atoi(argv[2]));
+					      anchor::StrictBottomCenter);
+
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_links_center_aligned.cc b/scribo/src/debug/show_links_center_aligned.cc
index 727e7e9..9c358d9 100644
--- a/scribo/src/debug/show_links_center_aligned.cc
+++ b/scribo/src/debug/show_links_center_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -91,7 +91,7 @@ int main(int argc, char* argv[])
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-      					      scribo::debug::center);
+      					      anchor::Center);
 
   io::ppm::save(decision_image, argv[3]);
 
diff --git a/scribo/src/debug/show_links_top_aligned.cc b/scribo/src/debug/show_links_top_aligned.cc
index 9efcb6d..5ffcb70 100644
--- a/scribo/src/debug/show_links_top_aligned.cc
+++ b/scribo/src/debug/show_links_top_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -39,10 +39,11 @@
 #include <mln/io/ppm/save.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_top.hh>
-#include <scribo/filter/object_links_top_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
+#include <scribo/debug/links_image.hh>
 #include <scribo/debug/usage.hh>
 
 
@@ -82,20 +83,19 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_top(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_top_aligned(right_links, atof(argv[3]));
-
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictTopCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::top,
-					      atoi(argv[2]));
+					      anchor::StrictTopCenter);
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_stoppers.cc b/scribo/src/debug/show_stoppers.cc
index a108da1..0e7fe0f 100644
--- a/scribo/src/debug/show_stoppers.cc
+++ b/scribo/src/debug/show_stoppers.cc
@@ -25,8 +25,11 @@
 #include <scribo/primitive/extract/lines_v_pattern.hh>
 #include <scribo/primitive/extract/separators_nonvisible.hh>
 #include <scribo/debug/usage.hh>
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/debug/bboxes_image.hh>
+#include <scribo/core/document.hh>
+#include <scribo/core/def/lbl_type.hh>
 
+#include <scribo/io/xml/save.hh>
 
 const char *args_desc[][2] =
 {
@@ -41,10 +44,11 @@ int main(int argc, char *argv[])
 {
   using namespace mln;
 
-  if (argc != 7 && argc != 5)
+  if (argc != 8 && argc != 6)
     return scribo::debug::usage(argv,
 				"Extract horizontal, vertical lines and stoppers",
-				"input.pbm output.pbm input_wo_seps.pbm output.ppm length delta",
+				"input.pbm out_seps.pbm out_in_wo_seps.pbm "
+				"out_seps_bbox.ppm out_visible_seps.pbm length delta",
 				args_desc);
 
   trace::entering("main");
@@ -56,20 +60,22 @@ int main(int argc, char *argv[])
   unsigned
     length = 101,
     delta = 4;
-  if (argc > 5)
+  if (argc > 6)
   {
-    length = atoi(argv[5]);
-    delta = atoi(argv[6]);
+    length = atoi(argv[6]);
+    delta = atoi(argv[7]);
   }
 
   util::timer t;
 
   t.start();
   image2d<bool>
-    h_lines = scribo::primitive::extract::lines_h_pattern(input, length, delta);
+    h_lines = scribo::primitive::extract::lines_h_pattern(input, length,
+							  delta);
 
   image2d<bool>
-    v_lines = scribo::primitive::extract::lines_v_pattern(input, length, delta);
+    v_lines = scribo::primitive::extract::lines_v_pattern(input, length,
+							  delta);
 
   v_lines += h_lines;
 
@@ -87,18 +93,32 @@ int main(int argc, char *argv[])
   image2d<value::int_u8> lbl = labeling::foreground(v_lines, c4(), nlabels);
   mln::util::array<box2d>
     bbox = labeling::compute(accu::shape::bbox<point2d>(), lbl, nlabels);
-  scribo::debug::save_bboxes_image(input, bbox, argv[4], literal::red);
+  io::ppm::save(scribo::debug::bboxes_image(input, bbox, literal::red),
+		argv[4]);
+
+  // Save visible separators
+  mln::io::pbm::save(v_lines, argv[5]);
 
   t.resume();
 
   // Non visible separators
-  v_lines += scribo::primitive::extract::separators_nonvisible(input);
+  image2d<bool>
+    nonvisible = scribo::primitive::extract::separators_nonvisible(input);
 
   t.stop();
   std::cout << t << "s" << std::endl;
 
+  // // Saving stoppers data to XML
+  // typedef image2d<scribo::def::lbl_type> L;
+  // scribo::document<L> doc(argv[1]);
+  // doc.open();
+  // doc.set_whitespace_separators(nonvisible);
+  // doc.set_line_separators(v_lines);
+  // scribo::io::xml::save(doc, argv[5], scribo::io::xml::Full);
+
   // Save binary image.
-  io::pbm::save(v_lines, argv[2]);
+  v_lines += nonvisible;
+  mln::io::pbm::save(v_lines, argv[2]);
 
   trace::exiting("main");
 }
diff --git a/scribo/src/debug/show_text_lines.cc b/scribo/src/debug/show_text_lines.cc
index d5a5c8f..1da0d66 100644
--- a/scribo/src/debug/show_text_lines.cc
+++ b/scribo/src/debug/show_text_lines.cc
@@ -32,20 +32,20 @@
 #include <mln/pw/all.hh>
 #include <mln/core/image/dmorph/image_if.hh>
 #include <mln/data/convert.hh>
+#include <mln/literal/colors.hh>
 
 #include <scribo/text/recognition.hh>
 
 #include <scribo/debug/usage.hh>
 
+#include <scribo/core/document.hh>
 #include <scribo/core/component_set.hh>
 #include <scribo/core/object_links.hh>
 #include <scribo/core/object_groups.hh>
 
 #include <scribo/text/extract_lines.hh>
 
-#include <scribo/io/text_boxes/save.hh>
-
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/io/xml/save.hh>
 
 
 const char *args_desc[][2] =
@@ -60,10 +60,10 @@ int main(int argc, char* argv[])
   using namespace scribo;
   using namespace mln;
 
-  if (argc != 6)
+  if (argc != 7)
     return scribo::debug::usage(argv,
 				"Show text lines",
-				"input.pbm input_seps.pbm out.ppm out.pbm comps.pbm",
+				"input.pbm input_seps.pbm out_text_boxes.ppm out_text_boxes.pbm out_text_comps.pbm out_lines.xml",
 				args_desc);
 
   trace::entering("main");
@@ -119,5 +119,12 @@ int main(int argc, char* argv[])
     mln::io::pbm::save(output, argv[5]);
   }
 
+  // Saving stoppers data to XML
+  document<L> doc(argv[1]);
+  doc.open();
+  doc.set_paragraphs(scribo::make::paragraph(lines));
+  scribo::io::xml::save(doc, argv[6], scribo::io::xml::Full);
+
+
   trace::exiting("main");
 }
diff --git a/scribo/src/preprocessing/rotate.cc b/scribo/src/preprocessing/rotate.cc
index 2910684..c0b599b 100644
--- a/scribo/src/preprocessing/rotate.cc
+++ b/scribo/src/preprocessing/rotate.cc
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
 
   typedef image2d<value::rgb8> I;
   I ima;
+  Magick::InitializeMagick(0);
   io::magick::load(ima, argv[1]);
 
   image2d<value::rgb8>
diff --git a/scribo/src/preprocessing/rotate_90.cc b/scribo/src/preprocessing/rotate_90.cc
index c5e9536..23625a9 100644
--- a/scribo/src/preprocessing/rotate_90.cc
+++ b/scribo/src/preprocessing/rotate_90.cc
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
 				"input.* output.ppm <positive>",
 				args_desc);
 
+  Magick::InitializeMagick(0);
 
   typedef image2d<value::rgb8> I;
   I ima;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* scribo/filter/object_links_bottom_aligned.hh,
	* scribo/filter/object_links_top_aligned.hh,
	* src/debug/show_links_bottom_aligned.cc,
	* src/debug/show_links_top_aligned.cc: Update call to
	linking routine.
	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
	* scribo/preprocessing/rotate_90.hh,
	* scribo/text/extract_lines.hh,
	* src/debug/show_stoppers.cc: Revamp.
	* scribo/primitive/extract/horizontal_separators.hh: Actually use
	horizontal routine.
	* scribo/primitive/extract/separators.hh: Adjust borders.
	* scribo/primitive/identify.hh: Disable for now.
	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
	* src/content_in_doc.cc: Add more usage information.
	* src/debug/show_links_center_aligned.cc: Update anchor value.
	* src/debug/show_text_lines.cc: Add XML output.
	* src/preprocessing/rotate.cc,
	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
---
 scribo/ChangeLog                                   |   36 +++++++++++++++++
 .../scribo/filter/object_links_bottom_aligned.hh   |    8 ++--
 .../filter/object_links_non_aligned_simple.hh      |    3 +-
 scribo/scribo/filter/object_links_top_aligned.hh   |    7 ++-
 scribo/scribo/preprocessing/rotate_90.hh           |   25 +++++++-----
 .../primitive/extract/horizontal_separators.hh     |   27 +++++++------
 scribo/scribo/primitive/extract/separators.hh      |    9 ++++-
 scribo/scribo/primitive/identify.hh                |   30 +++++++-------
 .../primitive/link/with_single_right_link.hh       |   16 +++++---
 .../primitive/link/with_single_right_link_top.hh   |   28 +++++++-------
 scribo/scribo/text/extract_lines.hh                |   21 ++++++----
 scribo/src/content_in_doc.cc                       |    3 +-
 scribo/src/debug/show_links_bottom_aligned.cc      |   16 ++++---
 scribo/src/debug/show_links_center_aligned.cc      |    6 +-
 scribo/src/debug/show_links_top_aligned.cc         |   18 ++++----
 scribo/src/debug/show_stoppers.cc                  |   42 ++++++++++++++-----
 scribo/src/debug/show_text_lines.cc                |   17 ++++++--
 scribo/src/preprocessing/rotate.cc                 |    1 +
 scribo/src/preprocessing/rotate_90.cc              |    1 +
 19 files changed, 202 insertions(+), 112 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 3399b01..b6f7f1a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,41 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Various small fixes.
+
+	* scribo/filter/object_links_bottom_aligned.hh,
+	* scribo/filter/object_links_top_aligned.hh,
+	* src/debug/show_links_bottom_aligned.cc,
+	* src/debug/show_links_top_aligned.cc: Update call to
+	linking routine.
+
+	* scribo/filter/object_links_non_aligned_simple.hh: Copy data.
+
+	* scribo/preprocessing/rotate_90.hh,
+	* scribo/text/extract_lines.hh,
+	* src/debug/show_stoppers.cc: Revamp.
+
+	* scribo/primitive/extract/horizontal_separators.hh: Actually use
+	horizontal routine.
+
+	* scribo/primitive/extract/separators.hh: Adjust borders.
+
+	* scribo/primitive/identify.hh: Disable for now.
+
+	* scribo/primitive/link/with_single_right_link.hh: Add anchor argument.
+
+	* scribo/primitive/link/with_single_right_link_top.hh: Rename arguments.
+
+	* src/content_in_doc.cc: Add more usage information.
+
+	* src/debug/show_links_center_aligned.cc: Update anchor value.
+
+	* src/debug/show_text_lines.cc: Add XML output.
+
+	* src/preprocessing/rotate.cc,
+	* src/preprocessing/rotate_90.cc: Initialize ImageMagick.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Introduce a new component linking method.
 
 	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
diff --git a/scribo/scribo/filter/object_links_bottom_aligned.hh b/scribo/scribo/filter/object_links_bottom_aligned.hh
index ba8ff31..2329f37 100644
--- a/scribo/scribo/filter/object_links_bottom_aligned.hh
+++ b/scribo/scribo/filter/object_links_bottom_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -38,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -97,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Bottom, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Bottom);
 
       trace::exiting("scribo::filter::object_links_bottom_aligned");
       return output;
diff --git a/scribo/scribo/filter/object_links_non_aligned_simple.hh b/scribo/scribo/filter/object_links_non_aligned_simple.hh
index 2381d88..5abf598 100644
--- a/scribo/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/scribo/filter/object_links_non_aligned_simple.hh
@@ -103,8 +103,7 @@ namespace scribo
 
       const component_set<L>& comps = links.components();
 
-      object_links<L> output(links);
-
+      object_links<L> output = links.duplicate();
 
       float max_alpha_rad = (max_alpha / 180.0f) * math::pi;
 
diff --git a/scribo/scribo/filter/object_links_top_aligned.hh b/scribo/scribo/filter/object_links_top_aligned.hh
index 57e8d40..48598c6 100644
--- a/scribo/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/scribo/filter/object_links_top_aligned.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -37,7 +38,7 @@
 # include <scribo/core/macros.hh>
 # include <scribo/core/object_links.hh>
 
-# include <scribo/filter/object_links_non_aligned_simple.hh>
+# include <scribo/filter/object_links_aligned.hh>
 
 namespace scribo
 {
@@ -96,7 +97,7 @@ namespace scribo
       mln_precondition(links.is_valid());
 
       object_links<L>
-	output = object_links_non_aligned_simple(links, anchor::Top, max_alpha);
+	output = object_links_aligned(links, max_alpha, anchor::Top);
 
       trace::exiting("scribo::filter::object_links_top_aligned");
       return output;
diff --git a/scribo/scribo/preprocessing/rotate_90.hh b/scribo/scribo/preprocessing/rotate_90.hh
index 96c0469..523b82f 100644
--- a/scribo/scribo/preprocessing/rotate_90.hh
+++ b/scribo/scribo/preprocessing/rotate_90.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -98,11 +99,13 @@ namespace scribo
 
       const mln_value(I)* in_ptr = input.buffer();
 
-      unsigned in_ncols = geom::ncols(input) + 2 * input.border();
-      unsigned in_nrows = geom::nrows(input) + 2 * input.border();
+      unsigned
+	in_ncols = geom::ncols(input) + 2 * input.border(),
+	in_nrows = geom::nrows(input) + 2 * input.border();
 
-      unsigned out_ncols = geom::ncols(output);
-      unsigned out_nrows = geom::nrows(output);
+      unsigned
+	out_ncols = geom::ncols(output) + 2 * input.border(),
+	out_nrows = geom::nrows(output) + 2 * input.border();
 
       int
 	out_next_offset,
@@ -112,21 +115,21 @@ namespace scribo
 
       if (positive) // +90 deg
       {
-	dpoint2d dp(- out_nrows - 2 * output.border(), - 1);
+	dpoint2d dp(out_nrows, + 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
 
-	out_ptr += 2 * output.border() + out_ncols - 1;
+	out_ptr += output.delta_index(dpoint2d(out_nrows - 1, 0));
       }
       else // -90 deg
       {
-	dpoint2d dp(out_nrows + 2 * output.border(), + 1);
+	dpoint2d dp(- out_nrows, - 1);
 	out_next_offset = output.delta_index(dp);
 
-	out_next_p_offset = output.delta_index(dpoint2d(-1, 0));
+	out_next_p_offset = output.delta_index(dpoint2d(+1, 0));
 
-	out_ptr += output.delta_index(dpoint2d(out_nrows + 2 * output.border() - 1, 0));
+	out_ptr += out_ncols - 1;
       }
 
       for (unsigned row = 0; row < in_nrows; ++row)
diff --git a/scribo/scribo/primitive/extract/horizontal_separators.hh b/scribo/scribo/primitive/extract/horizontal_separators.hh
index 9a6ea39..95db09e 100644
--- a/scribo/scribo/primitive/extract/horizontal_separators.hh
+++ b/scribo/scribo/primitive/extract/horizontal_separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -23,17 +24,17 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
-# define SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
 
 /// \file
 ///
-/// Extract vertical separators.
+/// Extract horizontal separators.
 
 # include <mln/core/concept/image.hh>
 # include <mln/arith/plus.hh>
 
-# include <scribo/primitive/extract/lines_v_pattern.hh>
+# include <scribo/primitive/extract/lines_h_pattern.hh>
 
 
 namespace scribo
@@ -47,7 +48,7 @@ namespace scribo
 
       using namespace mln;
 
-      /// \brief Extract vertical separators.
+      /// \brief Extract horizontal separators.
       /*!
        *
        * \param[in]     input       A binary image.
@@ -59,7 +60,7 @@ namespace scribo
        */
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input, unsigned line_length);
+      horizontal_separators(const Image<I>& input, unsigned line_length);
 
 
 
@@ -68,19 +69,19 @@ namespace scribo
 
       template <typename I>
       mln_concrete(I)
-      vertical_separators(const Image<I>& input_, unsigned line_length)
+      horizontal_separators(const Image<I>& input_, unsigned line_length)
       {
-	trace::entering("scribo::primitive::extract::vertical_separators");
+	trace::entering("scribo::primitive::extract::horizontal_separators");
 
 	const I& input = exact(input_);
 	mlc_is(mln_value(I), bool)::check();
 	mln_precondition(input.is_valid());
 
 	mln_concrete(I)
-	  vlines = extract::lines_v_pattern(input, line_length, 3);
+	  hlines = extract::lines_h_pattern(input, line_length, 3);
 
-	trace::exiting("scribo::primitive::extract::vertical_separators");
-	return vlines;
+	trace::exiting("scribo::primitive::extract::horizontal_separators");
+	return hlines;
       }
 
 
@@ -92,4 +93,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_EXTRACT_VERTICAL_SEPARATORS_HH
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_HORIZONTAL_SEPARATORS_HH
diff --git a/scribo/scribo/primitive/extract/separators.hh b/scribo/scribo/primitive/extract/separators.hh
index 2ba22b4..316f806 100644
--- a/scribo/scribo/primitive/extract/separators.hh
+++ b/scribo/scribo/primitive/extract/separators.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -82,6 +83,12 @@ namespace scribo
 	  vlines = extract::lines_v_pattern(input, line_length, 3);
 	hlines += vlines;
 
+	// FIXME: UGLY! We should not do that!
+	// Restore border size.
+	// Previous treatments may have changed it.
+	border::resize(hlines, border::thickness);
+	border::resize(input, border::thickness);
+
 	trace::exiting("scribo::primitive::extract::separators");
 	return hlines;
       }
diff --git a/scribo/scribo/primitive/identify.hh b/scribo/scribo/primitive/identify.hh
index 1bed712..6aa6ad3 100644
--- a/scribo/scribo/primitive/identify.hh
+++ b/scribo/scribo/primitive/identify.hh
@@ -28,7 +28,8 @@
 
 /*! \brief try to determine the type of a component.
 
-\fixme Add support for more component type (graphic, images, ...)
+\fixme Write it and add support for component type (graphic, images,
+...)
  */
 
 # include <mln/trace/all.hh>
@@ -48,24 +49,25 @@ namespace scribo
 
       mln_assertion(comps.is_valid());
 
-      component_set<L> output = comps.duplicate();
+      // component_set<L> output = comps.duplicate();
 
-      for_all_comps(c, comps)
-	if (comps(c).is_valid())
-	{
-	  float
-	    min = comps(c).bbox().height(),
-	    max = comps(c).bbox().width();
+      // for_all_comps(c, comps)
+      // 	if (comps(c).is_valid())
+      // 	{
+      // 	  float
+      // 	    min = comps(c).bbox().height(),
+      // 	    max = comps(c).bbox().width();
 
-	  if (comps(c).bbox().width() < comps(c).bbox().height())
-	    std::swap(min, max);
+      // 	  if (comps(c).bbox().width() < comps(c).bbox().height())
+      // 	    std::swap(min, max);
 
-	  if (max/min > 10)
-	    output(c).update_type(component::LineSeparator);
-	}
+      // 	  if (max/min > 10)
+      // 	    output(c).update_type(component::LineSeparator);
+      // 	}
 
       mln::trace::exiting("scribo::primitive::identify");
-      return output;
+      //return output;
+      return comps;
     }
 
 # ifndef MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/primitive/link/with_single_right_link.hh b/scribo/scribo/primitive/link/with_single_right_link.hh
index e1abdcf..bc7942b 100644
--- a/scribo/scribo/primitive/link/with_single_right_link.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -28,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -71,7 +72,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance);
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter);
 
 
       /// \overload
@@ -123,7 +125,8 @@ namespace scribo
       inline
       object_links<L>
       with_single_right_link(const component_set<L>& components,
-			     unsigned neighb_max_distance)
+			     unsigned neighb_max_distance,
+			     anchor::Type anchor = anchor::MassCenter)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link");
 
@@ -132,7 +135,7 @@ namespace scribo
 	internal::single_right_functor<L>
 	  functor(components, neighb_max_distance);
 
-	object_links<L> output = compute(functor, anchor::MassCenter);
+	object_links<L> output = compute(functor, anchor);
 
 	trace::exiting("scribo::primitive::link::with_single_right_link");
 	return output;
@@ -144,7 +147,8 @@ namespace scribo
       object_links<L>
       with_single_right_link(const component_set<L>& components)
       {
-	return with_single_right_link(components, mln_max(unsigned));
+	return with_single_right_link(components, mln_max(unsigned),
+				      anchor::MassCenter);
       }
 
 
diff --git a/scribo/scribo/primitive/link/with_single_right_link_top.hh b/scribo/scribo/primitive/link/with_single_right_link_top.hh
index 6d26114..ada6650 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_top.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_top.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -29,7 +29,7 @@
 
 /// \file
 ///
-/// Link text objects with their right neighbor.
+/// Link components with their right neighbor.
 
 
 # include <mln/core/concept/image.hh>
@@ -60,10 +60,10 @@ namespace scribo
     namespace link
     {
 
-      /// \brief Link objects with their right neighbor if exists.
+      /// \brief Link components with their right neighbor if exists.
       /// Lookup startup point is the object top center.
       ///
-      /// \param[in] objects An object image.
+      /// \param[in] components A component set.
       /// \param[in] The maximum distance allowed to seach a neighbor object.
       ///
       /// \return Object links data.
@@ -71,7 +71,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance);
 
 
@@ -80,7 +80,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects);
+      with_single_right_link_top(const component_set<L>& components);
 
 
 
@@ -104,9 +104,9 @@ namespace scribo
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_top_functor(const component_set<L>& objects,
+	  single_right_top_functor(const component_set<L>& components,
 				   unsigned dmax)
-	    : super_(objects, dmax, anchor::Horizontal)
+	    : super_(components, dmax, anchor::Horizontal)
 	  {
 	  }
 
@@ -126,15 +126,15 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects,
+      with_single_right_link_top(const component_set<L>& components,
 				 unsigned neighb_max_distance)
       {
 	trace::entering("scribo::primitive::link::with_single_right_link_top");
 
-	mln_precondition(objects.is_valid());
+	mln_precondition(components.is_valid());
 
 	internal::single_right_top_functor<L>
-	  functor(objects, neighb_max_distance);
+	  functor(components, neighb_max_distance);
 
 	object_links<L> output = compute(functor, anchor::Top);
 
@@ -146,9 +146,9 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_top(const component_set<L>& objects)
+      with_single_right_link_top(const component_set<L>& components)
       {
-	return with_single_right_link_top(objects, mln_max(unsigned));
+	return with_single_right_link_top(components, mln_max(unsigned));
       }
 
 
diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh
index 9949d09..e69a249 100644
--- a/scribo/scribo/text/extract_lines.hh
+++ b/scribo/scribo/text/extract_lines.hh
@@ -120,14 +120,19 @@ namespace scribo
 	comps.add_separators(separators);
 
       /// Linking potential comps
-      object_links<L> left_link
-	= primitive::link::with_single_left_link_dmax_ratio(comps,
-							    primitive::link::internal::dmax_width_and_height(1),
-							    anchor::MassCenter);
-      object_links<L> right_link
-	= primitive::link::with_single_right_link_dmax_ratio(comps,
-							     primitive::link::internal::dmax_width_and_height(1),
-							     anchor::MassCenter);
+      object_links<L>
+	left_link = primitive::link::with_single_left_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
+
+      object_links<L>
+	right_link = primitive::link::with_single_right_link_dmax_ratio(
+	  comps,
+	  primitive::link::internal::dmax_width_and_height(1),
+//	  primitive::link::internal::dmax_default(1),
+	  anchor::MassCenter);
 
       // Validating left and right links.
       object_links<L>
diff --git a/scribo/src/content_in_doc.cc b/scribo/src/content_in_doc.cc
index 81ec4fb..c879504 100644
--- a/scribo/src/content_in_doc.cc
+++ b/scribo/src/content_in_doc.cc
@@ -57,7 +57,8 @@ const char *args_desc[][2] =
   { "pmin_col", "Col index of the top left corner of the Region of interest." },
   { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
   { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
-  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)" },
+  { "language", "Language to be used for the text recognition. [eng|fra] (Default: eng)."
+    "An empty language will disable OCR." },
   { "find_lines", "Find vertical lines. (Default 1)" },
   { "find_whitespaces", "Find whitespaces separators. (Default 1)" },
   { "K", "Sauvola's binarization threshold parameter. (Default: 0.34)" },
diff --git a/scribo/src/debug/show_links_bottom_aligned.cc b/scribo/src/debug/show_links_bottom_aligned.cc
index bf858dc..634551b 100644
--- a/scribo/src/debug/show_links_bottom_aligned.cc
+++ b/scribo/src/debug/show_links_bottom_aligned.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of Olena.
 //
@@ -40,8 +41,8 @@
 #include <scribo/core/component_set.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_bottom.hh>
-#include <scribo/filter/object_links_bottom_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
 #include <scribo/debug/usage.hh>
@@ -82,19 +83,20 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_bottom(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_bottom_aligned(right_links, atof(argv[3]));
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictBottomCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::bottom,
-					      atoi(argv[2]));
+					      anchor::StrictBottomCenter);
+
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_links_center_aligned.cc b/scribo/src/debug/show_links_center_aligned.cc
index 727e7e9..9c358d9 100644
--- a/scribo/src/debug/show_links_center_aligned.cc
+++ b/scribo/src/debug/show_links_center_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -91,7 +91,7 @@ int main(int argc, char* argv[])
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-      					      scribo::debug::center);
+      					      anchor::Center);
 
   io::ppm::save(decision_image, argv[3]);
 
diff --git a/scribo/src/debug/show_links_top_aligned.cc b/scribo/src/debug/show_links_top_aligned.cc
index 9efcb6d..5ffcb70 100644
--- a/scribo/src/debug/show_links_top_aligned.cc
+++ b/scribo/src/debug/show_links_top_aligned.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -39,10 +39,11 @@
 #include <mln/io/ppm/save.hh>
 
 #include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/with_single_right_link_top.hh>
-#include <scribo/filter/object_links_top_aligned.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+#include <scribo/filter/object_links_aligned.hh>
 
 #include <scribo/debug/alignment_decision_image.hh>
+#include <scribo/debug/links_image.hh>
 #include <scribo/debug/usage.hh>
 
 
@@ -82,20 +83,19 @@ int main(int argc, char* argv[])
 
   // Finding right links.
   object_links<L> right_links
-    = primitive::link::with_single_right_link_top(components, atoi(argv[2]));
+    = primitive::link::with_single_right_link(components, atoi(argv[2]));
 
   // Filtering.
   object_links<L> filtered_links
-    = filter::object_links_top_aligned(right_links, atof(argv[3]));
-
+    = filter::object_links_aligned(right_links, atof(argv[3]),
+				   anchor::StrictTopCenter);
 
   // Debug image.
   image2d<value::rgb8> decision_image
     = scribo::debug::alignment_decision_image(input,
 					      right_links,
 					      filtered_links,
-					      scribo::debug::top,
-					      atoi(argv[2]));
+					      anchor::StrictTopCenter);
   io::ppm::save(decision_image, argv[4]);
 
 }
diff --git a/scribo/src/debug/show_stoppers.cc b/scribo/src/debug/show_stoppers.cc
index a108da1..0e7fe0f 100644
--- a/scribo/src/debug/show_stoppers.cc
+++ b/scribo/src/debug/show_stoppers.cc
@@ -25,8 +25,11 @@
 #include <scribo/primitive/extract/lines_v_pattern.hh>
 #include <scribo/primitive/extract/separators_nonvisible.hh>
 #include <scribo/debug/usage.hh>
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/debug/bboxes_image.hh>
+#include <scribo/core/document.hh>
+#include <scribo/core/def/lbl_type.hh>
 
+#include <scribo/io/xml/save.hh>
 
 const char *args_desc[][2] =
 {
@@ -41,10 +44,11 @@ int main(int argc, char *argv[])
 {
   using namespace mln;
 
-  if (argc != 7 && argc != 5)
+  if (argc != 8 && argc != 6)
     return scribo::debug::usage(argv,
 				"Extract horizontal, vertical lines and stoppers",
-				"input.pbm output.pbm input_wo_seps.pbm output.ppm length delta",
+				"input.pbm out_seps.pbm out_in_wo_seps.pbm "
+				"out_seps_bbox.ppm out_visible_seps.pbm length delta",
 				args_desc);
 
   trace::entering("main");
@@ -56,20 +60,22 @@ int main(int argc, char *argv[])
   unsigned
     length = 101,
     delta = 4;
-  if (argc > 5)
+  if (argc > 6)
   {
-    length = atoi(argv[5]);
-    delta = atoi(argv[6]);
+    length = atoi(argv[6]);
+    delta = atoi(argv[7]);
   }
 
   util::timer t;
 
   t.start();
   image2d<bool>
-    h_lines = scribo::primitive::extract::lines_h_pattern(input, length, delta);
+    h_lines = scribo::primitive::extract::lines_h_pattern(input, length,
+							  delta);
 
   image2d<bool>
-    v_lines = scribo::primitive::extract::lines_v_pattern(input, length, delta);
+    v_lines = scribo::primitive::extract::lines_v_pattern(input, length,
+							  delta);
 
   v_lines += h_lines;
 
@@ -87,18 +93,32 @@ int main(int argc, char *argv[])
   image2d<value::int_u8> lbl = labeling::foreground(v_lines, c4(), nlabels);
   mln::util::array<box2d>
     bbox = labeling::compute(accu::shape::bbox<point2d>(), lbl, nlabels);
-  scribo::debug::save_bboxes_image(input, bbox, argv[4], literal::red);
+  io::ppm::save(scribo::debug::bboxes_image(input, bbox, literal::red),
+		argv[4]);
+
+  // Save visible separators
+  mln::io::pbm::save(v_lines, argv[5]);
 
   t.resume();
 
   // Non visible separators
-  v_lines += scribo::primitive::extract::separators_nonvisible(input);
+  image2d<bool>
+    nonvisible = scribo::primitive::extract::separators_nonvisible(input);
 
   t.stop();
   std::cout << t << "s" << std::endl;
 
+  // // Saving stoppers data to XML
+  // typedef image2d<scribo::def::lbl_type> L;
+  // scribo::document<L> doc(argv[1]);
+  // doc.open();
+  // doc.set_whitespace_separators(nonvisible);
+  // doc.set_line_separators(v_lines);
+  // scribo::io::xml::save(doc, argv[5], scribo::io::xml::Full);
+
   // Save binary image.
-  io::pbm::save(v_lines, argv[2]);
+  v_lines += nonvisible;
+  mln::io::pbm::save(v_lines, argv[2]);
 
   trace::exiting("main");
 }
diff --git a/scribo/src/debug/show_text_lines.cc b/scribo/src/debug/show_text_lines.cc
index d5a5c8f..1da0d66 100644
--- a/scribo/src/debug/show_text_lines.cc
+++ b/scribo/src/debug/show_text_lines.cc
@@ -32,20 +32,20 @@
 #include <mln/pw/all.hh>
 #include <mln/core/image/dmorph/image_if.hh>
 #include <mln/data/convert.hh>
+#include <mln/literal/colors.hh>
 
 #include <scribo/text/recognition.hh>
 
 #include <scribo/debug/usage.hh>
 
+#include <scribo/core/document.hh>
 #include <scribo/core/component_set.hh>
 #include <scribo/core/object_links.hh>
 #include <scribo/core/object_groups.hh>
 
 #include <scribo/text/extract_lines.hh>
 
-#include <scribo/io/text_boxes/save.hh>
-
-#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/io/xml/save.hh>
 
 
 const char *args_desc[][2] =
@@ -60,10 +60,10 @@ int main(int argc, char* argv[])
   using namespace scribo;
   using namespace mln;
 
-  if (argc != 6)
+  if (argc != 7)
     return scribo::debug::usage(argv,
 				"Show text lines",
-				"input.pbm input_seps.pbm out.ppm out.pbm comps.pbm",
+				"input.pbm input_seps.pbm out_text_boxes.ppm out_text_boxes.pbm out_text_comps.pbm out_lines.xml",
 				args_desc);
 
   trace::entering("main");
@@ -119,5 +119,12 @@ int main(int argc, char* argv[])
     mln::io::pbm::save(output, argv[5]);
   }
 
+  // Saving stoppers data to XML
+  document<L> doc(argv[1]);
+  doc.open();
+  doc.set_paragraphs(scribo::make::paragraph(lines));
+  scribo::io::xml::save(doc, argv[6], scribo::io::xml::Full);
+
+
   trace::exiting("main");
 }
diff --git a/scribo/src/preprocessing/rotate.cc b/scribo/src/preprocessing/rotate.cc
index 2910684..c0b599b 100644
--- a/scribo/src/preprocessing/rotate.cc
+++ b/scribo/src/preprocessing/rotate.cc
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
 
   typedef image2d<value::rgb8> I;
   I ima;
+  Magick::InitializeMagick(0);
   io::magick::load(ima, argv[1]);
 
   image2d<value::rgb8>
diff --git a/scribo/src/preprocessing/rotate_90.cc b/scribo/src/preprocessing/rotate_90.cc
index c5e9536..23625a9 100644
--- a/scribo/src/preprocessing/rotate_90.cc
+++ b/scribo/src/preprocessing/rotate_90.cc
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
 				"input.* output.ppm <positive>",
 				args_desc);
 
+  Magick::InitializeMagick(0);
 
   typedef image2d<value::rgb8> I;
   I ima;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            last-svn-commit-803-gcb7a3bf Introduce a new	component linking method.
                        
                        
by Guillaume Lazzara 14 Mar '11
                    by Guillaume Lazzara 14 Mar '11
14 Mar '11
                    
                        	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
	New.
	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
	Cleanup.
---
 scribo/ChangeLog                                   |   11 +
 .../link_single_dmax_ratio_aligned_base.hh         |  268 ++++++++++++++++++++
 ...=> with_single_left_link_dmax_ratio_aligned.hh} |  109 ++------
 .../with_single_right_link_dmax_ratio_aligned.hh   |   69 +-----
 4 files changed, 317 insertions(+), 140 deletions(-)
 create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
 copy scribo/scribo/primitive/link/{with_single_right_link_dmax_ratio_aligned.hh => with_single_left_link_dmax_ratio_aligned.hh} (59%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 10a8269..5705c05 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,16 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Introduce a new component linking method.
+
+	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
+	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
+	New.
+
+	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
+	Cleanup.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Spread anchor value to more methods in link functors.
 
 	* scribo/primitive/link/internal/find_link.hh,
diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
new file mode 100644
index 0000000..56879bb
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
@@ -0,0 +1,268 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License.  This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using bounding box center,
+/// a proportional max distance and alignment criterion.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+# include <mln/util/array.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/line.hh>
+# include <mln/literal/colors.hh>
+# include <mln/norm/l1.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/dmax_functor.hh>
+
+# include <scribo/debug/logger.hh>
+
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/filter/internal/component_aligned.hh>
+
+
+namespace scribo
+{
+
+  namespace primitive
+  {
+
+    namespace link
+    {
+
+      namespace internal
+      {
+	using namespace scribo::debug;
+
+
+	template <typename L, typename F, typename E>
+	class link_single_dmax_ratio_aligned_base
+	  : public link_single_dmax_ratio_base<L, F, E>
+	{
+	  typedef link_single_dmax_ratio_base<L, F, E> super_;
+
+	public:
+	  typedef mln_site(L) P;
+
+	  link_single_dmax_ratio_aligned_base(
+	    const component_set<L>& components,
+	    const DMax_Functor<F>& dmax_f,
+	    float min_angle,
+	    float max_angle,
+	    anchor::Type anchor)
+	    : super_(components, anchor::Horizontal, exact(dmax_f)),
+	      debug_anchor_(anchor)
+	  {
+	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
+	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
+
+#  ifndef SCRIBO_NDEBUG
+	    if (scribo::debug::logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      initialize(debug_, components.labeled_image());
+	      data::fill(debug_, literal::black);
+	      data::fill((debug_
+			  | (pw::value(components.labeled_image()) != 0u)).rw(),
+			 literal::white);
+	      debug_angle_ = duplicate(debug_);
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void compute_next_site_(P& p)
+	  {
+	    ++p.col();
+	  }
+
+
+	  mln_site(L)
+	  start_point_(unsigned current_object, anchor::Type anchor)
+	  {
+	    return link::internal::compute_anchor(this->components_,
+						  current_object, anchor);
+	  }
+
+
+	  inline
+	  bool
+	  valid_link_(unsigned current_object,
+		      const P& start_point,
+		      const P& p,
+		      anchor::Type anchor)
+	  {
+	    if (!super_::valid_link_(current_object, start_point, p, anchor))
+	      return false;
+
+	    // Distance between the two components.
+	    float dist;// = math::abs(p[this->direction_] - start_point[this->direction_]);
+
+	    box<P> b = this->components_(current_object).bbox();
+	    if (p[this->direction_] > b.pmax()[this->direction_])
+	      dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]);
+	    // current object is on the right.
+	    else
+	      dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]);
+
+
+	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
+
+
+	    // Components are really close, so the angle is more permissive.
+	    if (dist < ldist * 3)
+	    {
+	      return
+		filter::internal::component_aligned_rad(this->components_,
+							current_object,
+							this->labeled_image_(p),
+							anchor,
+							max_alpha_rad);
+	    }
+
+
+	    // Components are really far, so the angle is less permissive.
+	    return
+	      filter::internal::component_aligned_rad(this->components_,
+						      current_object,
+						      this->labeled_image_(p),
+						      anchor,
+						      min_alpha_rad);
+	  }
+
+
+	  void validate_link_(unsigned current_object,
+			      const P& start_point,
+			      const P& p,
+			      anchor::Type anchor)
+	  {
+	    super_::validate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      mln_site(L)
+	    	p1 = link::internal::compute_anchor(this->components_,
+	    					    current_object, debug_anchor_),
+	    	p2 = link::internal::compute_anchor(this->components_,
+	    					    this->labeled_image_(p),
+						    debug_anchor_);
+	      mln::draw::line(debug_, p1, p2, literal::green);
+
+
+	      float
+	    	angle = filter::internal::alignment_angle(this->components_,
+	    						  current_object,
+	    						  this->labeled_image_(p),
+	    						  anchor);
+	      angle = (angle * 180.0f) / math::pi;
+	      angle = angle * 20.0f + 1.0f;
+	      mln::draw::line(debug_angle_, p1, p2,
+	    		      value::rgb8(unsigned(angle),
+	    				  unsigned(angle),
+	    				  unsigned(angle)));
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void invalidate_link_(unsigned current_object,
+				const P& start_point,
+				const P& p,
+				anchor::Type anchor)
+	  {
+	    super_::invalidate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0)
+	      {
+	    	mln_site(L)
+	    	  p1 = link::internal::compute_anchor(this->components_,
+	    					      current_object, debug_anchor_),
+	    	  p2 = link::internal::compute_anchor(this->components_,
+	    					      this->labeled_image_(p),
+	    			       debug_anchor_);
+
+		// Arbitrary check to avoid large lines drawn over the whole page.
+	    	if (this->labeled_image_.domain().has(p2)
+	    	    && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300)
+	    	{
+	    	  mln::draw::line(debug_, p1, p2, literal::red);
+	    	}
+
+
+	    	float
+	    	  angle = filter::internal::alignment_angle(this->components_,
+	    						    current_object,
+	    						    this->labeled_image_(p),
+	    						    anchor);
+	    	angle = (angle * 180.0f) / math::pi;
+	    	angle = angle * 20.0f + 1.0f;
+	    	mln::draw::line(debug_angle_, p1, p2,
+	    			value::rgb8(unsigned(angle),
+	    				    unsigned(angle),
+	    				    unsigned(angle)));
+	      }
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  float min_alpha_rad;
+	  float max_alpha_rad;
+
+	  // Anchor used for debug output!
+	  anchor::Type debug_anchor_;
+
+	  mln_ch_value(L, value::rgb8) debug_;
+	  mln_ch_value(L, value::rgb8) debug_angle_;
+	};
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+      } // end of namespace scribo::primitive::link::internal
+
+    } // end of namespace scribo::primitive::link
+
+  } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
similarity index 59%
copy from scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
copy to scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
index feba5f2..146ae17 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -24,12 +24,12 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
 
 /// \file
 ///
-/// Link text objects with their right neighbor according to a maximum
+/// Link text objects with their left neighbor according to a maximum
 /// distance.
 
 # include <mln/core/concept/image.hh>
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -62,7 +62,7 @@ namespace scribo
     namespace link
     {
 
-      /*! \brief Link objects with their right neighbor if exists.
+      /*! \brief Link objects with their left neighbor if exists.
 
 	  \param[in] components A component set.
 	  \param[in] dmax_ratio Size ratio defining the maximum lookup
@@ -82,7 +82,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle,
@@ -93,7 +93,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle);
@@ -105,7 +105,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components);
 
 
@@ -118,84 +118,33 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
-	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	class single_left_dmax_ratio_aligned_functor
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_left_dmax_ratio_aligned_functor<L,F> >
 	{
-	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef single_left_dmax_ratio_aligned_functor<L,F> self_t;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_dmax_ratio_aligned_functor(
+	  single_left_dmax_ratio_aligned_functor(
 	    const component_set<L>& components,
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
 	  {
-	    ++p.col();
+	    --p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
@@ -208,22 +157,22 @@ namespace scribo
       template <typename L, typename F>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	const DMax_Functor<F>& dmax_f,
 	float min_angle, float max_angle,
 	anchor::Type anchor)
       {
-	trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::entering("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 
 	mln_precondition(components.is_valid());
 
-	internal::single_right_dmax_ratio_aligned_functor<L,F>
+	internal::single_left_dmax_ratio_aligned_functor<L,F>
 	  functor(components, dmax_f, min_angle, max_angle, anchor);
 
 	object_links<L> output = compute(functor, anchor);
 
-	trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::exiting("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 	return output;
       }
 
@@ -232,13 +181,13 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components,
+	  with_single_left_link_dmax_ratio_aligned(components,
 						    internal::dmax_default(dmax_ratio),
 						    min_angle,
 						    max_angle,
@@ -249,11 +198,11 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components, 3, 3, 10);
+	  with_single_left_link_dmax_ratio_aligned(components, 3, 3, 10);
       }
 
 
@@ -265,4 +214,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
index feba5f2..dcf804e 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -118,13 +118,13 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
 	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_right_dmax_ratio_aligned_functor<L,F> >
 	{
 	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
@@ -134,18 +134,10 @@ namespace scribo
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
@@ -153,49 +145,6 @@ namespace scribo
 	    ++p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            last-svn-commit-802-g282de70 Introduce a new	component linking method.
                        
                        
by Guillaume Lazzara 14 Mar '11
                    by Guillaume Lazzara 14 Mar '11
14 Mar '11
                    
                        	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
	New.
	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
	Cleanup.
---
 scribo/ChangeLog                                   |   11 +
 .../link_single_dmax_ratio_aligned_base.hh         |  268 ++++++++++++++++++++
 ...=> with_single_left_link_dmax_ratio_aligned.hh} |  109 ++------
 .../with_single_right_link_dmax_ratio_aligned.hh   |   69 +-----
 4 files changed, 317 insertions(+), 140 deletions(-)
 create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
 copy scribo/scribo/primitive/link/{with_single_right_link_dmax_ratio_aligned.hh => with_single_left_link_dmax_ratio_aligned.hh} (59%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index fc78930..3399b01 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,16 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Introduce a new component linking method.
+
+	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
+	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
+	New.
+
+	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
+	Cleanup.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Spread anchor value to more methods in link functors.
 
 	* scribo/primitive/link/internal/find_link.hh,
diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
new file mode 100644
index 0000000..56879bb
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
@@ -0,0 +1,268 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License.  This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using bounding box center,
+/// a proportional max distance and alignment criterion.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+# include <mln/util/array.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/line.hh>
+# include <mln/literal/colors.hh>
+# include <mln/norm/l1.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/dmax_functor.hh>
+
+# include <scribo/debug/logger.hh>
+
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/filter/internal/component_aligned.hh>
+
+
+namespace scribo
+{
+
+  namespace primitive
+  {
+
+    namespace link
+    {
+
+      namespace internal
+      {
+	using namespace scribo::debug;
+
+
+	template <typename L, typename F, typename E>
+	class link_single_dmax_ratio_aligned_base
+	  : public link_single_dmax_ratio_base<L, F, E>
+	{
+	  typedef link_single_dmax_ratio_base<L, F, E> super_;
+
+	public:
+	  typedef mln_site(L) P;
+
+	  link_single_dmax_ratio_aligned_base(
+	    const component_set<L>& components,
+	    const DMax_Functor<F>& dmax_f,
+	    float min_angle,
+	    float max_angle,
+	    anchor::Type anchor)
+	    : super_(components, anchor::Horizontal, exact(dmax_f)),
+	      debug_anchor_(anchor)
+	  {
+	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
+	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
+
+#  ifndef SCRIBO_NDEBUG
+	    if (scribo::debug::logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      initialize(debug_, components.labeled_image());
+	      data::fill(debug_, literal::black);
+	      data::fill((debug_
+			  | (pw::value(components.labeled_image()) != 0u)).rw(),
+			 literal::white);
+	      debug_angle_ = duplicate(debug_);
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void compute_next_site_(P& p)
+	  {
+	    ++p.col();
+	  }
+
+
+	  mln_site(L)
+	  start_point_(unsigned current_object, anchor::Type anchor)
+	  {
+	    return link::internal::compute_anchor(this->components_,
+						  current_object, anchor);
+	  }
+
+
+	  inline
+	  bool
+	  valid_link_(unsigned current_object,
+		      const P& start_point,
+		      const P& p,
+		      anchor::Type anchor)
+	  {
+	    if (!super_::valid_link_(current_object, start_point, p, anchor))
+	      return false;
+
+	    // Distance between the two components.
+	    float dist;// = math::abs(p[this->direction_] - start_point[this->direction_]);
+
+	    box<P> b = this->components_(current_object).bbox();
+	    if (p[this->direction_] > b.pmax()[this->direction_])
+	      dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]);
+	    // current object is on the right.
+	    else
+	      dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]);
+
+
+	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
+
+
+	    // Components are really close, so the angle is more permissive.
+	    if (dist < ldist * 3)
+	    {
+	      return
+		filter::internal::component_aligned_rad(this->components_,
+							current_object,
+							this->labeled_image_(p),
+							anchor,
+							max_alpha_rad);
+	    }
+
+
+	    // Components are really far, so the angle is less permissive.
+	    return
+	      filter::internal::component_aligned_rad(this->components_,
+						      current_object,
+						      this->labeled_image_(p),
+						      anchor,
+						      min_alpha_rad);
+	  }
+
+
+	  void validate_link_(unsigned current_object,
+			      const P& start_point,
+			      const P& p,
+			      anchor::Type anchor)
+	  {
+	    super_::validate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      mln_site(L)
+	    	p1 = link::internal::compute_anchor(this->components_,
+	    					    current_object, debug_anchor_),
+	    	p2 = link::internal::compute_anchor(this->components_,
+	    					    this->labeled_image_(p),
+						    debug_anchor_);
+	      mln::draw::line(debug_, p1, p2, literal::green);
+
+
+	      float
+	    	angle = filter::internal::alignment_angle(this->components_,
+	    						  current_object,
+	    						  this->labeled_image_(p),
+	    						  anchor);
+	      angle = (angle * 180.0f) / math::pi;
+	      angle = angle * 20.0f + 1.0f;
+	      mln::draw::line(debug_angle_, p1, p2,
+	    		      value::rgb8(unsigned(angle),
+	    				  unsigned(angle),
+	    				  unsigned(angle)));
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void invalidate_link_(unsigned current_object,
+				const P& start_point,
+				const P& p,
+				anchor::Type anchor)
+	  {
+	    super_::invalidate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0)
+	      {
+	    	mln_site(L)
+	    	  p1 = link::internal::compute_anchor(this->components_,
+	    					      current_object, debug_anchor_),
+	    	  p2 = link::internal::compute_anchor(this->components_,
+	    					      this->labeled_image_(p),
+	    			       debug_anchor_);
+
+		// Arbitrary check to avoid large lines drawn over the whole page.
+	    	if (this->labeled_image_.domain().has(p2)
+	    	    && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300)
+	    	{
+	    	  mln::draw::line(debug_, p1, p2, literal::red);
+	    	}
+
+
+	    	float
+	    	  angle = filter::internal::alignment_angle(this->components_,
+	    						    current_object,
+	    						    this->labeled_image_(p),
+	    						    anchor);
+	    	angle = (angle * 180.0f) / math::pi;
+	    	angle = angle * 20.0f + 1.0f;
+	    	mln::draw::line(debug_angle_, p1, p2,
+	    			value::rgb8(unsigned(angle),
+	    				    unsigned(angle),
+	    				    unsigned(angle)));
+	      }
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  float min_alpha_rad;
+	  float max_alpha_rad;
+
+	  // Anchor used for debug output!
+	  anchor::Type debug_anchor_;
+
+	  mln_ch_value(L, value::rgb8) debug_;
+	  mln_ch_value(L, value::rgb8) debug_angle_;
+	};
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+      } // end of namespace scribo::primitive::link::internal
+
+    } // end of namespace scribo::primitive::link
+
+  } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
similarity index 59%
copy from scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
copy to scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
index feba5f2..146ae17 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -24,12 +24,12 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
 
 /// \file
 ///
-/// Link text objects with their right neighbor according to a maximum
+/// Link text objects with their left neighbor according to a maximum
 /// distance.
 
 # include <mln/core/concept/image.hh>
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -62,7 +62,7 @@ namespace scribo
     namespace link
     {
 
-      /*! \brief Link objects with their right neighbor if exists.
+      /*! \brief Link objects with their left neighbor if exists.
 
 	  \param[in] components A component set.
 	  \param[in] dmax_ratio Size ratio defining the maximum lookup
@@ -82,7 +82,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle,
@@ -93,7 +93,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle);
@@ -105,7 +105,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components);
 
 
@@ -118,84 +118,33 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
-	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	class single_left_dmax_ratio_aligned_functor
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_left_dmax_ratio_aligned_functor<L,F> >
 	{
-	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef single_left_dmax_ratio_aligned_functor<L,F> self_t;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_dmax_ratio_aligned_functor(
+	  single_left_dmax_ratio_aligned_functor(
 	    const component_set<L>& components,
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
 	  {
-	    ++p.col();
+	    --p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
@@ -208,22 +157,22 @@ namespace scribo
       template <typename L, typename F>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	const DMax_Functor<F>& dmax_f,
 	float min_angle, float max_angle,
 	anchor::Type anchor)
       {
-	trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::entering("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 
 	mln_precondition(components.is_valid());
 
-	internal::single_right_dmax_ratio_aligned_functor<L,F>
+	internal::single_left_dmax_ratio_aligned_functor<L,F>
 	  functor(components, dmax_f, min_angle, max_angle, anchor);
 
 	object_links<L> output = compute(functor, anchor);
 
-	trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::exiting("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 	return output;
       }
 
@@ -232,13 +181,13 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components,
+	  with_single_left_link_dmax_ratio_aligned(components,
 						    internal::dmax_default(dmax_ratio),
 						    min_angle,
 						    max_angle,
@@ -249,11 +198,11 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components, 3, 3, 10);
+	  with_single_left_link_dmax_ratio_aligned(components, 3, 3, 10);
       }
 
 
@@ -265,4 +214,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
index feba5f2..dcf804e 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -118,13 +118,13 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
 	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_right_dmax_ratio_aligned_functor<L,F> >
 	{
 	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
@@ -134,18 +134,10 @@ namespace scribo
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
@@ -153,49 +145,6 @@ namespace scribo
 	    ++p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            last-svn-commit-802-g80b10b6 Introduce a new	component linking method.
                        
                        
by Guillaume Lazzara 14 Mar '11
                    by Guillaume Lazzara 14 Mar '11
14 Mar '11
                    
                        	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
	New.
	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
	Cleanup.
---
 scribo/ChangeLog                                   |   11 +
 .../link_single_dmax_ratio_aligned_base.hh         |  268 ++++++++++++++++++++
 ...=> with_single_left_link_dmax_ratio_aligned.hh} |  109 ++------
 .../with_single_right_link_dmax_ratio_aligned.hh   |   69 +-----
 4 files changed, 317 insertions(+), 140 deletions(-)
 create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
 copy scribo/scribo/primitive/link/{with_single_right_link_dmax_ratio_aligned.hh => with_single_left_link_dmax_ratio_aligned.hh} (59%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index fc78930..3399b01 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,16 @@
 2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Introduce a new component linking method.
+
+	* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh,
+	* scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh:
+	New.
+
+	* scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh:
+	Cleanup.
+
+2011-03-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Spread anchor value to more methods in link functors.
 
 	* scribo/primitive/link/internal/find_link.hh,
diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
new file mode 100644
index 0000000..56879bb
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh
@@ -0,0 +1,268 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License.  This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using bounding box center,
+/// a proportional max distance and alignment criterion.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+# include <mln/util/array.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/line.hh>
+# include <mln/literal/colors.hh>
+# include <mln/norm/l1.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/dmax_functor.hh>
+
+# include <scribo/debug/logger.hh>
+
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/filter/internal/component_aligned.hh>
+
+
+namespace scribo
+{
+
+  namespace primitive
+  {
+
+    namespace link
+    {
+
+      namespace internal
+      {
+	using namespace scribo::debug;
+
+
+	template <typename L, typename F, typename E>
+	class link_single_dmax_ratio_aligned_base
+	  : public link_single_dmax_ratio_base<L, F, E>
+	{
+	  typedef link_single_dmax_ratio_base<L, F, E> super_;
+
+	public:
+	  typedef mln_site(L) P;
+
+	  link_single_dmax_ratio_aligned_base(
+	    const component_set<L>& components,
+	    const DMax_Functor<F>& dmax_f,
+	    float min_angle,
+	    float max_angle,
+	    anchor::Type anchor)
+	    : super_(components, anchor::Horizontal, exact(dmax_f)),
+	      debug_anchor_(anchor)
+	  {
+	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
+	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
+
+#  ifndef SCRIBO_NDEBUG
+	    if (scribo::debug::logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      initialize(debug_, components.labeled_image());
+	      data::fill(debug_, literal::black);
+	      data::fill((debug_
+			  | (pw::value(components.labeled_image()) != 0u)).rw(),
+			 literal::white);
+	      debug_angle_ = duplicate(debug_);
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void compute_next_site_(P& p)
+	  {
+	    ++p.col();
+	  }
+
+
+	  mln_site(L)
+	  start_point_(unsigned current_object, anchor::Type anchor)
+	  {
+	    return link::internal::compute_anchor(this->components_,
+						  current_object, anchor);
+	  }
+
+
+	  inline
+	  bool
+	  valid_link_(unsigned current_object,
+		      const P& start_point,
+		      const P& p,
+		      anchor::Type anchor)
+	  {
+	    if (!super_::valid_link_(current_object, start_point, p, anchor))
+	      return false;
+
+	    // Distance between the two components.
+	    float dist;// = math::abs(p[this->direction_] - start_point[this->direction_]);
+
+	    box<P> b = this->components_(current_object).bbox();
+	    if (p[this->direction_] > b.pmax()[this->direction_])
+	      dist = math::abs(p[this->direction_] - b.pmax()[this->direction_]);
+	    // current object is on the right.
+	    else
+	      dist = math::abs(p[this->direction_] - b.pmin()[this->direction_]);
+
+
+	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
+
+
+	    // Components are really close, so the angle is more permissive.
+	    if (dist < ldist * 3)
+	    {
+	      return
+		filter::internal::component_aligned_rad(this->components_,
+							current_object,
+							this->labeled_image_(p),
+							anchor,
+							max_alpha_rad);
+	    }
+
+
+	    // Components are really far, so the angle is less permissive.
+	    return
+	      filter::internal::component_aligned_rad(this->components_,
+						      current_object,
+						      this->labeled_image_(p),
+						      anchor,
+						      min_alpha_rad);
+	  }
+
+
+	  void validate_link_(unsigned current_object,
+			      const P& start_point,
+			      const P& p,
+			      anchor::Type anchor)
+	  {
+	    super_::validate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      mln_site(L)
+	    	p1 = link::internal::compute_anchor(this->components_,
+	    					    current_object, debug_anchor_),
+	    	p2 = link::internal::compute_anchor(this->components_,
+	    					    this->labeled_image_(p),
+						    debug_anchor_);
+	      mln::draw::line(debug_, p1, p2, literal::green);
+
+
+	      float
+	    	angle = filter::internal::alignment_angle(this->components_,
+	    						  current_object,
+	    						  this->labeled_image_(p),
+	    						  anchor);
+	      angle = (angle * 180.0f) / math::pi;
+	      angle = angle * 20.0f + 1.0f;
+	      mln::draw::line(debug_angle_, p1, p2,
+	    		      value::rgb8(unsigned(angle),
+	    				  unsigned(angle),
+	    				  unsigned(angle)));
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  void invalidate_link_(unsigned current_object,
+				const P& start_point,
+				const P& p,
+				anchor::Type anchor)
+	  {
+	    super_::invalidate_link_(current_object, start_point, p, anchor);
+
+#  ifndef SCRIBO_NDEBUG
+	    if (logger().is_at_level(debug::AuxiliaryResults))
+	    {
+	      if (this->labeled_image_.domain().has(p) && this->labeled_image_(p) != 0)
+	      {
+	    	mln_site(L)
+	    	  p1 = link::internal::compute_anchor(this->components_,
+	    					      current_object, debug_anchor_),
+	    	  p2 = link::internal::compute_anchor(this->components_,
+	    					      this->labeled_image_(p),
+	    			       debug_anchor_);
+
+		// Arbitrary check to avoid large lines drawn over the whole page.
+	    	if (this->labeled_image_.domain().has(p2)
+	    	    && norm::l1_distance(p1.to_vec(), p2.to_vec()) < 300)
+	    	{
+	    	  mln::draw::line(debug_, p1, p2, literal::red);
+	    	}
+
+
+	    	float
+	    	  angle = filter::internal::alignment_angle(this->components_,
+	    						    current_object,
+	    						    this->labeled_image_(p),
+	    						    anchor);
+	    	angle = (angle * 180.0f) / math::pi;
+	    	angle = angle * 20.0f + 1.0f;
+	    	mln::draw::line(debug_angle_, p1, p2,
+	    			value::rgb8(unsigned(angle),
+	    				    unsigned(angle),
+	    				    unsigned(angle)));
+	      }
+	    }
+#  endif // ! SCRIBO_NDEBUG
+	  }
+
+	  float min_alpha_rad;
+	  float max_alpha_rad;
+
+	  // Anchor used for debug output!
+	  anchor::Type debug_anchor_;
+
+	  mln_ch_value(L, value::rgb8) debug_;
+	  mln_ch_value(L, value::rgb8) debug_angle_;
+	};
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+      } // end of namespace scribo::primitive::link::internal
+
+    } // end of namespace scribo::primitive::link
+
+  } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_BASE_HH_
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
similarity index 59%
copy from scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
copy to scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
index feba5f2..146ae17 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -24,12 +24,12 @@
 // exception does not however invalidate any other reasons why the
 // executable file might be covered by the GNU General Public License.
 
-#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
-# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#ifndef SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
+# define SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
 
 /// \file
 ///
-/// Link text objects with their right neighbor according to a maximum
+/// Link text objects with their left neighbor according to a maximum
 /// distance.
 
 # include <mln/core/concept/image.hh>
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -62,7 +62,7 @@ namespace scribo
     namespace link
     {
 
-      /*! \brief Link objects with their right neighbor if exists.
+      /*! \brief Link objects with their left neighbor if exists.
 
 	  \param[in] components A component set.
 	  \param[in] dmax_ratio Size ratio defining the maximum lookup
@@ -82,7 +82,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle,
@@ -93,7 +93,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle);
@@ -105,7 +105,7 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components);
 
 
@@ -118,84 +118,33 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
-	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	class single_left_dmax_ratio_aligned_functor
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_left_dmax_ratio_aligned_functor<L,F> >
 	{
-	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef single_left_dmax_ratio_aligned_functor<L,F> self_t;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
 
-	  single_right_dmax_ratio_aligned_functor(
+	  single_left_dmax_ratio_aligned_functor(
 	    const component_set<L>& components,
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
 	  {
-	    ++p.col();
+	    --p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
@@ -208,22 +157,22 @@ namespace scribo
       template <typename L, typename F>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	const DMax_Functor<F>& dmax_f,
 	float min_angle, float max_angle,
 	anchor::Type anchor)
       {
-	trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::entering("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 
 	mln_precondition(components.is_valid());
 
-	internal::single_right_dmax_ratio_aligned_functor<L,F>
+	internal::single_left_dmax_ratio_aligned_functor<L,F>
 	  functor(components, dmax_f, min_angle, max_angle, anchor);
 
 	object_links<L> output = compute(functor, anchor);
 
-	trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio_aligned");
+	trace::exiting("scribo::primitive::link::with_single_left_link_dmax_ratio_aligned");
 	return output;
       }
 
@@ -232,13 +181,13 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components,
 	float dmax_ratio,
 	float min_angle, float max_angle)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components,
+	  with_single_left_link_dmax_ratio_aligned(components,
 						    internal::dmax_default(dmax_ratio),
 						    min_angle,
 						    max_angle,
@@ -249,11 +198,11 @@ namespace scribo
       template <typename L>
       inline
       object_links<L>
-      with_single_right_link_dmax_ratio_aligned(
+      with_single_left_link_dmax_ratio_aligned(
 	const component_set<L>& components)
       {
 	return
-	  with_single_right_link_dmax_ratio_aligned(components, 3, 3, 10);
+	  with_single_left_link_dmax_ratio_aligned(components, 3, 3, 10);
       }
 
 
@@ -265,4 +214,4 @@ namespace scribo
 
 } // end of namespace scribo
 
-#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_RIGHT_LINK_DMAX_RATIO_ALIGNED_HH
+#endif // ! SCRIBO_PRIMITIVE_LINK_WITH_SINGLE_LEFT_LINK_DMAX_RATIO_ALIGNED_HH
diff --git a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
index feba5f2..dcf804e 100644
--- a/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
+++ b/scribo/scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of Olena.
 //
@@ -46,7 +46,7 @@
 
 # include <scribo/primitive/link/internal/dmax_default.hh>
 # include <scribo/primitive/link/internal/find_link.hh>
-# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh>
 
 # include <scribo/primitive/link/compute.hh>
 
@@ -118,13 +118,13 @@ namespace scribo
 
 	// Functor
 
+
 	template <typename L, typename F>
 	class single_right_dmax_ratio_aligned_functor
-	  : public link_single_dmax_ratio_base<L, F,
-					       single_right_dmax_ratio_aligned_functor<L,F> >
+	  : public link_single_dmax_ratio_aligned_base<L, F, single_right_dmax_ratio_aligned_functor<L,F> >
 	{
 	  typedef single_right_dmax_ratio_aligned_functor<L,F> self_t;
-	  typedef link_single_dmax_ratio_base<L, F, self_t> super_;
+	  typedef link_single_dmax_ratio_aligned_base<L, F, self_t> super_;
 
 	public:
 	  typedef mln_site(L) P;
@@ -134,18 +134,10 @@ namespace scribo
 	    const DMax_Functor<F>& dmax_f,
 	    float min_angle,
 	    float max_angle,
-	    anchor::Type anchor_)
-	    : super_(components, exact(dmax_f), anchor::Horizontal),
-	      anchor(anchor_)
+	    anchor::Type anchor)
+	    : super_(components, dmax_f, min_angle,
+		     max_angle, anchor)
 	  {
-	    std::cout << "min_angle = " << min_angle
-		      << " - max_angle = " << max_angle
-		      << std::endl;
-	    std::cout << "min_angle_rad = " << min_alpha_rad
-		      << " - max_angle_rad = " << max_alpha_rad
-		      << std::endl;
-	    min_alpha_rad = (min_angle / 180.0f) * math::pi;
-	    max_alpha_rad = (max_angle / 180.0f) * math::pi;
 	  }
 
 	  void compute_next_site_(P& p)
@@ -153,49 +145,6 @@ namespace scribo
 	    ++p.col();
 	  }
 
-
-	  inline
-	  bool
-	  valid_link_(unsigned current_object,
-		      const P& start_point,
-		      const P& p)
-	  {
-	    bool super_b = super_::valid_link_(current_object,
-					       start_point, p);
-
-	    // Distance between the two components.
-	    float dist = math::abs(p[this->direction_] - start_point[this->direction_]);
-
-
-	    unsigned ldist = this->components_(current_object).bbox().width() / 2;
-
-
-	    // Components are really close, so the angle is more permissive.
-	    if (dist < (ldist + ldist * 0.2))
-	    {
-	      return super_b
-		&&
-		filter::internal::component_aligned_rad(this->components_,
-							current_object,
-							this->labeled_image_(p),
-							anchor,
-							max_alpha_rad);
-	    }
-
-
-	    // Components are really far, so the angle is less permissive.
-	    return super_b
-	      && filter::internal::component_aligned_rad(this->components_,
-							 current_object,
-							 this->labeled_image_(p),
-							 anchor,
-							 min_alpha_rad);
-	  }
-
-	  float min_alpha_rad;
-	  float max_alpha_rad;
-	  anchor::Type anchor;
-
 	};
 
       } // end of namespace scribo::primitive::link::internal
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    14 Mar '11
                    
                        This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch next-build-test has been updated
       via  c4bfdc8ca94fc3283920876a447bf21b1efaf9bb (commit)
      from  aa2987c992651c0e83baafe445f1555f93ae08ca (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
c4bfdc8 Deactivate erroneous assertion in regional_maxima.hh.
-----------------------------------------------------------------------
Summary of changes:
 ChangeLog                              |    6 ++++++
 milena/mln/labeling/regional_maxima.hh |    4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)
hooks/post-receive
-- 
Olena, a generic and efficient image processing platform
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            last-svn-commit-764-gaa9b739 Deactivate erroneous	assertion in regional_maxima.hh.
                        
                        
by Thierry Geraud 14 Mar '11
                    by Thierry Geraud 14 Mar '11
14 Mar '11
                    
                        ---
 ChangeLog                              |    6 ++++++
 milena/mln/labeling/regional_maxima.hh |    4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 686b84a..3eb76e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-03-14  Thierry GERAUD  <thierry.geraud(a)lrde.epita.fr>
+
+	* milena/mln/labeling/regional_maxima.hh
+	(do_no_union_): Deactivate assertion since it is
+	not verified for all cases.
+
 2011-01-18  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
 	* configure.ac: Make Boost dependency optional.
diff --git a/milena/mln/labeling/regional_maxima.hh b/milena/mln/labeling/regional_maxima.hh
index a3c12eb..861066f 100644
--- a/milena/mln/labeling/regional_maxima.hh
+++ b/milena/mln/labeling/regional_maxima.hh
@@ -97,8 +97,8 @@ namespace mln
 	bool labels_(unsigned p) const            { return attr.element(p); }
 	bool equiv_(unsigned n, unsigned p) const { return input.element(n) ==
 	    input.element(p); }
-	void do_no_union_(unsigned n, unsigned p) { mln_invariant(input.element(n) >
-								  input.element(p));
+	void do_no_union_(unsigned n, unsigned p) { // mln_invariant(input.element(n) >
+	  //	  input.element(p));
 	  attr.element(p) = false;
 	  (void) n;
 	}
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0