Olena-patches
Threads by month
- ----- 2025 -----
- 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
April 2011
- 4 participants
- 107 discussions

last-svn-commit-695-g9dd5ec1 Add function visualization in the mean region widget.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
* lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh: Add
mouseclick support for function visualization.
---
milena/sandbox/ChangeLog | 8 +++
.../gui/segmentation2dt/src/mean_regions_widget.cc | 62 +++++++++++++++++++-
.../gui/segmentation2dt/src/mean_regions_widget.hh | 5 ++
3 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 4f62abc..07874a9 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,13 @@
2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add function visualization in the mean region widget.
+
+ * lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh: Add
+ mouseclick support for function visualization.
+
+2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Allow to save results filtered differently in the 3D segmentation
tool.
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc
index 5a255fe..5756458 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.cc
@@ -63,6 +63,16 @@ namespace igr
connect(viewer_, SIGNAL(slider_valueChanged(int)),
data_, SLOT(compute_new_mean_regions_image(int)));
+ // Plot widget related settings.
+ connect(viewer_->scene(), SIGNAL(mouse_pressed(const QPointF&)),
+ this, SLOT(mouse_click_slot(const QPointF&)));
+
+ connect(viewer_->scene(), SIGNAL(mouse_click(const QPointF&)),
+ this, SLOT(mouse_click_slot(const QPointF&)));
+
+ plot_widget_ = new plot_widget();
+ plot_widget_->hide();
+
emit task_ready();
}
@@ -75,6 +85,14 @@ namespace igr
disconnect(viewer_, SIGNAL(slider_valueChanged(int)),
data_, SLOT(compute_new_mean_regions_image(int)));
+ // Plot widget related settings.
+ disconnect(viewer_->scene(), SIGNAL(mouse_pressed(const QPointF&)),
+ this, SLOT(mouse_click_slot(const QPointF&)));
+
+ disconnect(viewer_->scene(), SIGNAL(mouse_click(const QPointF&)),
+ this, SLOT(mouse_click_slot(const QPointF&)));
+
+ delete plot_widget_;
}
@@ -93,14 +111,14 @@ namespace igr
bool mean_regions_widget::has_mouseover_data(const QPointF& p) const
{
point3d p3d(viewer_->current_slice(), p.y(), p.x());
- return data_->mean_regions().domain().has(p3d);
+ return data_->mean_regions_smooth().domain().has(p3d);
}
float mean_regions_widget::compute_mouseover_data(const QPointF& p) const
{
point3d p3d(viewer_->current_slice(), p.y(), p.x());
- return float(data_->mean_regions()(p3d));
+ return float(data_->mean_regions_smooth()(p3d));
}
@@ -109,11 +127,51 @@ namespace igr
disconnect(sender(), SIGNAL(finished()),
this, SLOT(task_finished_slot()));
+ // Preparing x data for plot widget.
+ xData_.resize(data_->mean_regions_smooth().nslis());
+ for (int i = 0; i < xData_.size(); ++i)
+ xData_[i] = i;
+
+
this->already_computed_ = true;
// Result already refreshed and displayed.
}
+ void mean_regions_widget::mouse_click_slot(const QPointF& p)
+ {
+ if (has_mouseover_data(p))
+ {
+ point3d p3d = point3d(0, p.y(), p.x());
+
+ plot_widget_->clear();
+
+ QString title(tr("Function for region %1").arg(data_->seg_smooth()(p3d)));
+ plot_widget_->set_title(title);
+
+ // Copy the data into the curves.
+
+ QwtArray<double> yData;
+ yData.resize(data_->in_nslis());
+
+ // Result of the morpholocial filter.
+ for (int i = 0; i < yData.size(); ++i, ++p3d[0])
+ yData[i] = data_->mean_regions_smooth()(p3d);
+
+ plot_widget_->add_curve(tr("Morphological filtering."),
+ xData_, yData, QPen(Qt::green, 3));
+
+ // Ready to replot.
+ plot_widget_->replot();
+
+
+ // Display result.
+ plot_widget_->show();
+ plot_widget_->raise();
+ }
+ }
+
+
} // end of namespace igr::segmentation
} // end of namespace igr
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh
index 8d78cb5..6ff7a15 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mean_regions_widget.hh
@@ -30,6 +30,7 @@
# include <ui_mean_regions_widget.h>
# include <src/task_widget.hh>
+# include <src/plot_widget.hh>
namespace igr
@@ -55,11 +56,15 @@ namespace igr
private slots:
void task_finished_slot();
+ void mouse_click_slot(const QPointF& p);
private: // Members
virtual void run_task_(task_handler& handler);
private: // Attributes
+ QwtArray<double> xData_;
+
+ plot_widget *plot_widget_;
};
--
1.5.6.5
1
0

last-svn-commit-694-gaa8417d Allow to save results filtered differently in the 3D segmentation tool.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
* lazzara/igr/gui/segmentation2dt/src/mln_data.cc,
* lazzara/igr/gui/segmentation2dt/src/mln_data.hh: Add more
temporary images.
* lazzara/igr/gui/segmentation2dt/src/save_widget.cc: Add
checkboxes to select which image to save.
* lazzara/igr/gui/segmentation2dt/src/seg_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/seg_widget.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/seg.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/seg.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc:
Compute non-filtered and linearly filtered image.
* lazzara/igr/gui/segmentation2dt/src/task_widget.cc: Avoid a warning.
* lazzara/igr/gui/segmentation2dt/src/tools/save.cc
* lazzara/igr/gui/segmentation2dt/src/tools/save.hh: Allow to save
more images.
* lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui,
* lazzara/igr/gui/segmentation2dt/ui/save_widget.ui: Update widgets.
* lazzara/igr/gui/shared/include/function_means.hh,
* lazzara/igr/gui/shared/include/mean_function_per_region.hh,
* lazzara/igr/gui/shared/include/normalization.hh: Add missing
inlines.
* lazzara/igr/gui/shared/include/mean_regions.hh,
* lazzara/igr/gui/shared/include/time_smooth_morpho.hh: Add
missing includes.
---
milena/sandbox/ChangeLog | 37 +++++++
.../igr/gui/segmentation2dt/src/mln_data.cc | 112 +++++++++++++++-----
.../igr/gui/segmentation2dt/src/mln_data.hh | 50 ++++++---
.../igr/gui/segmentation2dt/src/save_widget.cc | 21 ++++
.../igr/gui/segmentation2dt/src/seg_widget.cc | 30 ++++--
.../igr/gui/segmentation2dt/src/seg_widget.hh | 3 +-
.../igr/gui/segmentation2dt/src/task_widget.cc | 2 +-
.../gui/segmentation2dt/src/tools/mean_regions.cc | 72 +++++++++++--
.../igr/gui/segmentation2dt/src/tools/save.cc | 90 +++++++++++++---
.../igr/gui/segmentation2dt/src/tools/save.hh | 12 ++-
.../igr/gui/segmentation2dt/src/tools/seg.cc | 60 +++++++++--
.../igr/gui/segmentation2dt/src/tools/seg.hh | 10 ++-
.../igr/gui/segmentation2dt/ui/plot_widget.ui | 20 ++++
.../igr/gui/segmentation2dt/ui/save_widget.ui | 80 +++++++++++++--
.../igr/gui/shared/include/function_means.hh | 1 -
.../gui/shared/include/mean_function_per_region.hh | 2 +-
.../lazzara/igr/gui/shared/include/mean_regions.hh | 2 +
.../igr/gui/shared/include/normalization.hh | 1 -
.../igr/gui/shared/include/time_smooth_morpho.hh | 2 +
19 files changed, 508 insertions(+), 99 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 677070c..4f62abc 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,42 @@
2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Allow to save results filtered differently in the 3D segmentation
+ tool.
+
+ * lazzara/igr/gui/segmentation2dt/src/mln_data.cc,
+ * lazzara/igr/gui/segmentation2dt/src/mln_data.hh: Add more
+ temporary images.
+
+ * lazzara/igr/gui/segmentation2dt/src/save_widget.cc: Add
+ checkboxes to select which image to save.
+
+ * lazzara/igr/gui/segmentation2dt/src/seg_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/seg_widget.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/seg.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/seg.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc:
+ Compute non-filtered and linearly filtered image.
+
+ * lazzara/igr/gui/segmentation2dt/src/task_widget.cc: Avoid a warning.
+
+ * lazzara/igr/gui/segmentation2dt/src/tools/save.cc
+ * lazzara/igr/gui/segmentation2dt/src/tools/save.hh: Allow to save
+ more images.
+
+ * lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui,
+ * lazzara/igr/gui/segmentation2dt/ui/save_widget.ui: Update widgets.
+
+ * lazzara/igr/gui/shared/include/function_means.hh,
+ * lazzara/igr/gui/shared/include/mean_function_per_region.hh,
+ * lazzara/igr/gui/shared/include/normalization.hh: Add missing
+ inlines.
+
+ * lazzara/igr/gui/shared/include/mean_regions.hh,
+ * lazzara/igr/gui/shared/include/time_smooth_morpho.hh: Add
+ missing includes.
+
+2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* lazzara/igr/gui/segmentation/src/main_window.cc: Avoid a warning
in 2D segmentation tool.
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
index c294c73..f8dc7c8 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
@@ -295,19 +295,19 @@ namespace igr
}
- void mln_data::update_seg(const image3d<seg_data_t>& seg,
- const seg_data_t& nregion)
+ void mln_data::update_seg_smooth(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion)
{
- update_seg(seg, nregion, 0);
+ update_seg_smooth(seg, nregion, 0);
}
- void mln_data::update_seg(const image3d<seg_data_t>& seg,
- const seg_data_t& nregion,
- int sli)
+ void mln_data::update_seg_smooth(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion,
+ int sli)
{
- seg_ = seg;
- initialize(seg_dsp_, seg_);
+ seg_smooth_ = seg;
+ initialize(seg_dsp_, seg_smooth_);
// This random function was found here:
// http://en.wikipedia.org/wiki/Random_number_generation
@@ -324,8 +324,8 @@ namespace igr
for_all(p)
{
value::hsl_<float,float,float> hsl__(
- h_values[seg_(p)],
-// (unsigned(seg_(p)) * 10) % 359 + 1,
+ h_values[seg_smooth_(p)],
+// (unsigned(seg_smooth_(p)) * 10) % 359 + 1,
1,
unsigned(in_(p)) * .002745f); // = 1 / 255 * 0.7);
convert::from_to(hsl__, seg_dsp_(p));
@@ -334,22 +334,51 @@ namespace igr
// Make sure there is no border!
extension::adjust(seg_dsp_, 0);
- nregion_ = nregion;
+ nregion_smooth_ = nregion;
emit image_layer_count(seg_dsp_.nslis());
compute_new_seg_image(sli);
}
- void mln_data::update_mean_regions(const image3d<input_data_t>& mean_regions)
+
+ void mln_data::update_seg(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion)
{
- update_mean_regions(mean_regions, 0);
+ seg_ = seg;
+ nregion_ = nregion;
}
- void mln_data::update_mean_regions(const image3d<input_data_t>& mean_regions,
- int sli)
+ void mln_data::update_seg_smooth_linear(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion)
+ {
+ seg_smooth_linear_ = seg;
+ nregion_smooth_linear_ = nregion;
+ }
+
+
+ void mln_data::update_mean_regions(const image3d<input_data_t>& mean_regions)
{
mean_regions_ = mean_regions;
+ }
+
+
+ void mln_data::update_mean_regions_smooth_linear(const image3d<input_data_t>& mean_regions)
+ {
+ mean_regions_smooth_linear_ = mean_regions;
+ }
+
+
+ void mln_data::update_mean_regions_smooth(const image3d<input_data_t>& mean_regions)
+ {
+ update_mean_regions_smooth(mean_regions, 0);
+ }
+
+
+ void mln_data::update_mean_regions_smooth(const image3d<input_data_t>& mean_regions,
+ int sli)
+ {
+ mean_regions_smooth_ = mean_regions;
mean_regions_dsp_ = data::convert(dsp_data_t(),
data::stretch(value::int_u8(),
mean_regions));
@@ -368,7 +397,7 @@ namespace igr
}
- const mln_data::in_t&
+ const in_t&
mln_data::in() const
{
return in_;
@@ -380,38 +409,50 @@ namespace igr
}
- const mln_data::ref_mean_t&
+ const ref_mean_t&
mln_data::ref_mean() const
{
return ref_mean_;
}
- const mln_data::norm_smooth_t&
+ const norm_smooth_t&
mln_data::norm() const
{
return norm_;
}
- const mln_data::norm_smooth_t&
+ const norm_smooth_t&
mln_data::norm_smooth() const
{
return norm_smooth_;
}
- const mln_data::norm_smooth_t&
+ const norm_smooth_t&
mln_data::norm_smooth_linear() const
{
return norm_smooth_linear_;
}
- const mln_data::seg_t&
+ const seg_t&
mln_data::seg() const
{
return seg_;
}
+ const seg_t&
+ mln_data::seg_smooth_linear() const
+ {
+ return seg_smooth_linear_;
+ }
+
+ const seg_t&
+ mln_data::seg_smooth() const
+ {
+ return seg_smooth_;
+ }
+
unsigned mln_data::seg_nslis() const
{
return seg_.nslis();
@@ -422,24 +463,45 @@ namespace igr
return nregion_;
}
+ const seg_data_t& mln_data::nregion_smooth_linear() const
+ {
+ return nregion_smooth_linear_;
+ }
+
+ const seg_data_t& mln_data::nregion_smooth() const
+ {
+ return nregion_smooth_;
+ }
- const mln_data::seg_dsp_t& mln_data::seg_dsp() const
+ const seg_dsp_t& mln_data::seg_dsp() const
{
return seg_dsp_;
}
- mln_data::seg_dsp_t& mln_data::seg_dsp()
+ seg_dsp_t& mln_data::seg_dsp()
{
return seg_dsp_;
}
- const mln_data::mean_regions_t&
+ const mean_regions_t&
mln_data::mean_regions() const
{
return mean_regions_;
}
- const mln_data::mean_regions_dsp_t&
+ const mean_regions_t&
+ mln_data::mean_regions_smooth_linear() const
+ {
+ return mean_regions_smooth_linear_;
+ }
+
+ const mean_regions_t&
+ mln_data::mean_regions_smooth() const
+ {
+ return mean_regions_smooth_;
+ }
+
+ const mean_regions_dsp_t&
mln_data::mean_regions_dsp() const
{
return mean_regions_dsp_;
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
index 6f1776f..bc75ecb 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
@@ -26,22 +26,23 @@ namespace igr
};
+ typedef image3d<igr::input_data_t> in_t;
+ typedef image3d<igr::dsp_data_t> in_dsp_t;
+ typedef image2d<igr::mean_t> ref_mean_t;
+ typedef image2d<igr::dsp_data_t> ref_mean_dsp_t;
+ typedef image3d<igr::smoothed_data_t> norm_smooth_t;
+ typedef image3d<igr::dsp_data_t> norm_smooth_dsp_t;
+ typedef image3d<igr::seg_data_t> seg_t;
+ typedef image3d<igr::dsp_data_t> seg_dsp_t;
+ typedef image3d<igr::input_data_t> mean_regions_t;
+ typedef image3d<igr::dsp_data_t> mean_regions_dsp_t;
+
+
class mln_data : public QObject
{
Q_OBJECT;
public:
- typedef image3d<igr::input_data_t> in_t;
- typedef image3d<igr::dsp_data_t> in_dsp_t;
- typedef image2d<igr::mean_t> ref_mean_t;
- typedef image2d<igr::dsp_data_t> ref_mean_dsp_t;
- typedef image3d<igr::smoothed_data_t> norm_smooth_t;
- typedef image3d<igr::dsp_data_t> norm_smooth_dsp_t;
- typedef image3d<igr::seg_data_t> seg_t;
- typedef image3d<igr::dsp_data_t> seg_dsp_t;
- typedef image3d<igr::input_data_t> mean_regions_t;
- typedef image3d<igr::dsp_data_t> mean_regions_dsp_t;
-
mln_data();
~mln_data();
@@ -83,12 +84,19 @@ namespace igr
void update_norm_smooth(const image3d<smoothed_data_t>& norm_smooth);
void update_norm_smooth_linear(const image3d<smoothed_data_t>& norm_smooth_linear);
+ void update_seg_smooth(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion);
+ void update_seg_smooth(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion, int sli);
void update_seg(const image3d<seg_data_t>& seg,
- const seg_data_t& nregion);
- void update_seg(const image3d<seg_data_t>& seg,
- const seg_data_t& nregion, int sli);
+ const seg_data_t& nregion);
+ void update_seg_smooth_linear(const image3d<seg_data_t>& seg,
+ const seg_data_t& nregion);
+
void update_mean_regions(const image3d<input_data_t>& mean_regions);
- void update_mean_regions(const image3d<input_data_t>& mean_regions, int sli);
+ void update_mean_regions_smooth_linear(const image3d<input_data_t>& mean_regions);
+ void update_mean_regions_smooth(const image3d<input_data_t>& mean_regions);
+ void update_mean_regions_smooth(const image3d<input_data_t>& mean_regions, int sli);
const std::string& filename() const;
@@ -104,13 +112,19 @@ namespace igr
const norm_smooth_t& norm_smooth_linear() const;
const seg_t& seg() const;
+ const seg_t& seg_smooth_linear() const;
+ const seg_t& seg_smooth() const;
unsigned seg_nslis() const;
const seg_data_t& nregion() const;
+ const seg_data_t& nregion_smooth_linear() const;
+ const seg_data_t& nregion_smooth() const;
const seg_dsp_t& seg_dsp() const;
seg_dsp_t& seg_dsp();
const mean_regions_t& mean_regions() const;
+ const mean_regions_t& mean_regions_smooth_linear() const;
+ const mean_regions_t& mean_regions_smooth() const;
const mean_regions_dsp_t& mean_regions_dsp() const;
const log_data& logs() const;
@@ -173,10 +187,16 @@ namespace igr
norm_smooth_t norm_smooth_linear_;
seg_t seg_;
+ seg_t seg_smooth_linear_;
+ seg_t seg_smooth_;
seg_dsp_t seg_dsp_;
igr::seg_data_t nregion_;
+ igr::seg_data_t nregion_smooth_linear_;
+ igr::seg_data_t nregion_smooth_;
mean_regions_t mean_regions_;
+ mean_regions_t mean_regions_smooth_linear_;
+ mean_regions_t mean_regions_smooth_;
mean_regions_dsp_t mean_regions_dsp_;
log_data logs_;
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
index 8d87133..576c6ba 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
@@ -113,13 +113,34 @@ namespace igr
if (logCBox->isChecked())
selected.append(tools::Log);
+
if (meanFunCBox->isChecked())
+ {
selected.append(tools::MeanFunctions);
+
+ if (meanFunNonFilteredCBox->isChecked())
+ selected.append(tools::MeanFunctionsNonFiltered);
+ if (meanFunLinearFilterCBox->isChecked())
+ selected.append(tools::MeanFunctionsLinearFilter);
+ if (meanFunMorphoFilterCBox->isChecked())
+ selected.append(tools::MeanFunctionsMorphoFilter);
+ }
+
if (refImaCBox->isChecked())
selected.append(tools::RefImage);
+
if (segImaCBox->isChecked())
+ {
selected.append(tools::SegImage);
+ if (segImaNonFilteredCBox->isChecked())
+ selected.append(tools::SegImageNonFiltered);
+ if (segImaLinearFilterCBox->isChecked())
+ selected.append(tools::SegImageLinearFilter);
+ if (segImaMorphoFilterCBox->isChecked())
+ selected.append(tools::SegImageMorphoFilter);
+ }
+
return selected;
}
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
index 6891432..ff49690 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
@@ -43,7 +43,8 @@ namespace igr
{
seg_widget::seg_widget(QWidget *parent)
- : Task_Widget(parent)
+ : Task_Widget(parent),
+ compute_preview_(false), preview_computed_(false)
{
setupUi(this);
}
@@ -63,6 +64,7 @@ namespace igr
connect(viewer_, SIGNAL(slider_valueChanged(int)),
data_, SLOT(compute_new_seg_image(int)));
+ compute_preview_ = true;
emit task_ready();
}
@@ -73,6 +75,7 @@ namespace igr
set_data_and_connections();
clearBtn->setEnabled(false);
nregion_lbl->setText("");
+ preview_computed_ = false;
viewer_->set_image_layer_count(data_->in_nslis());
}
@@ -105,7 +108,7 @@ namespace igr
void seg_widget::run_task_(task_handler& handler)
{
tools::seg*
- task = new tools::seg(data_, get_lambda_value());
+ task = new tools::seg(data_, get_lambda_value(), compute_preview_, preview_computed_);
connect(&handler, SIGNAL(finished()),
this, SLOT(task_finished_slot()));
@@ -118,8 +121,8 @@ namespace igr
{
point3d p3d(viewer_->current_slice(), p.y(), p.x());
- if (clearBtn->isEnabled()) // A segmentation have been computed
- return data_->seg().domain().has(p3d);
+ if (preview_computed_) // A segmentation have been computed
+ return data_->seg_smooth().domain().has(p3d);
else
return data_->norm_smooth().domain().has(p3d);
}
@@ -128,8 +131,8 @@ namespace igr
float seg_widget::compute_mouseover_data(const QPointF& p) const
{
point3d p3d(viewer_->current_slice(), p.y(), p.x());
- if (clearBtn->isEnabled()) // A segmentation have been computed
- return float(data_->seg()(p3d));
+ if (preview_computed_) // A segmentation have been computed
+ return float(data_->seg_smooth()(p3d));
else
return float(data_->norm_smooth()(p3d));
}
@@ -163,8 +166,14 @@ namespace igr
this, SLOT(task_finished_slot()));
clearBtn->setEnabled(true);
- this->already_computed_ = true;
- nregion_lbl->setText(tr("%1 regions").arg(data_->nregion()));
+ if (!compute_preview_)
+ this->already_computed_ = true;
+ else
+ {
+ compute_preview_ = false;
+ preview_computed_ = true;
+ }
+ nregion_lbl->setText(tr("%1 regions").arg(data_->nregion_smooth()));
// Result already refreshed and displayed.
}
@@ -172,26 +181,31 @@ namespace igr
void seg_widget::on_filter_1_clicked(bool)
{
this->already_computed_ = false;
+ preview_computed_ = false;
}
void seg_widget::on_filter_2_clicked(bool)
{
this->already_computed_ = false;
+ preview_computed_ = false;
}
void seg_widget::on_filter_3_clicked(bool)
{
this->already_computed_ = false;
+ preview_computed_ = false;
}
void seg_widget::on_filter_4_clicked(bool)
{
this->already_computed_ = false;
+ preview_computed_ = false;
}
void seg_widget::on_filter_5_clicked(bool)
{
this->already_computed_ = false;
+ preview_computed_ = false;
}
} // end of namespace igr::segmentation
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.hh
index bed5e24..26e35fe 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.hh
@@ -68,7 +68,8 @@ namespace igr
unsigned get_lambda_value() const;
private: // Attributes
-
+ bool compute_preview_;
+ bool preview_computed_;
};
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_widget.cc
index e3ddce5..c8e6cbc 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_widget.cc
@@ -55,7 +55,7 @@ namespace igr
handler.no_op();
}
- void Task_Widget::run_task_(task_handler& handler)
+ void Task_Widget::run_task_(task_handler& /*handler*/)
{
qDebug() << "WARNING: task_widget::run_task_ should not be called...";
}
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
index 8245a70..6ae3b47 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
@@ -32,23 +32,75 @@ namespace igr
void mean_regions::run()
{
- seg_data_t nregion = data_->nregion();
- image3d<seg_data_t>
- seg_packed = labeling::pack(data_->seg(), nregion);
+ // No filter
+ {
+ // FIXME: computed twice? here and in save.cc ?
+ seg_data_t nregion = data_->nregion();
+ image3d<seg_data_t>
+ seg_packed = labeling::pack(data_->seg(), nregion);
- emit next_step();
+ emit next_step();
+
+ data_->update_seg(seg_packed, nregion);
+
+ emit next_step();
+
+ image3d<input_data_t>
+ means = shared::mean_regions(data_->in(),
+ data_->seg(), data_->nregion());
+
+ emit next_step();
- data_->update_seg(seg_packed, nregion);
+ data_->update_mean_regions(means);
+ }
emit next_step();
- image3d<input_data_t>
- means = shared::mean_regions(data_->in(),
- data_->seg(), data_->nregion());
+ // Linear filter
+ {
+ // FIXME: computed twice? here and in save.cc ?
+ seg_data_t nregion = data_->nregion_smooth_linear();
+ image3d<seg_data_t>
+ seg_packed = labeling::pack(data_->seg_smooth_linear(), nregion);
+
+ emit next_step();
+
+ data_->update_seg_smooth_linear(seg_packed, nregion);
+
+ emit next_step();
+
+ image3d<input_data_t>
+ means = shared::mean_regions(data_->in(),
+ data_->seg_smooth_linear(), data_->nregion_smooth_linear());
+
+ emit next_step();
+
+ data_->update_mean_regions_smooth_linear(means);
+ }
emit next_step();
- data_->update_mean_regions(means);
+ // Morpho filter
+ {
+ // FIXME: computed twice? here and in save.cc ?
+ seg_data_t nregion = data_->nregion_smooth();
+ image3d<seg_data_t>
+ seg_packed = labeling::pack(data_->seg_smooth(), nregion);
+
+ emit next_step();
+
+ data_->update_seg_smooth(seg_packed, nregion);
+
+ emit next_step();
+
+ image3d<input_data_t>
+ means = shared::mean_regions(data_->in(),
+ data_->seg_smooth(), data_->nregion_smooth());
+
+ emit next_step();
+
+ data_->update_mean_regions_smooth(means);
+ }
}
@@ -60,7 +112,7 @@ namespace igr
unsigned mean_regions::step_count() const
{
- return 4;
+ return 12;
}
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
index 23e38d1..185ed86 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
@@ -104,6 +104,20 @@ namespace igr
return true;
}
+ void save::save_mean_funs(const seg_t& pseg, const seg_data_t& pnlabels,
+ const mean_regions_t& mean_regions, const QString& prefix)
+ {
+ QString output_base = basedir_ + "/" + prefix;
+ util::array<util::array<input_data_t> >
+ functions = shared::mean_function_per_region(mean_regions, pseg, pnlabels);
+
+ for (unsigned i = 1; i < functions.nelements(); ++i)
+ {
+ QString name = output_base + "_l" + QString::number(i) + ".plot";
+ mln::io::plot::save(functions[i], name.toStdString());
+ }
+ }
+
void save::run()
{
@@ -111,12 +125,19 @@ namespace igr
QString basename = f.baseName();
QString output;
-
- seg_data_t packed_nlabels;
- image3d<seg_data_t> packed_seg;
- if (selected_.contains(SegImage) || selected_.contains(MeanFunctions))
- packed_seg = labeling::pack(data_->seg(), packed_nlabels);
+// seg_data_t pnlabels, pnlabels_smooth, pnlabels_smooth_linear;
+// image3d<seg_data_t>
+// pseg, pseg_smooth, pseg_smooth_linear;
+
+ // Preparing some common data.
+// if (selected_.contains(SegImageNonFiltered) || selected_.contains(MeanFunctionsNonFiltered))
+// pseg = labeling::pack(data_->seg(), pnlabels);
+// if (selected_.contains(SegImageLinearFilter) || selected_.contains(MeanFunctionsLinearFilter))
+// pseg_smooth_linear = labeling::pack(data_->seg_smooth_linear(), pnlabels_smooth_linear);
+// if (selected_.contains(SegImageMorphoFilter) || selected_.contains(MeanFunctionsMorphoFilter))
+// pseg_smooth = labeling::pack(data_->seg_smooth(), pnlabels_smooth);
+
foreach(SavedData e, selected_)
{
@@ -135,24 +156,57 @@ namespace igr
emit next_step();
break;
- case SegImage:
- output = basedir_ + "/" + basename + "_segmentation.raw";
- io::raw::save(packed_seg, output.toStdString());
+
+ // Segmentations
+
+ case SegImageNonFiltered:
+ output = basedir_ + "/" + basename + "_segmentation_non_filtered.raw";
+ io::raw::save(data_->seg(), output.toStdString());
+ emit next_step();
+ break;
+
+ case SegImageLinearFilter:
+ output = basedir_ + "/" + basename + "_segmentation_linear_filter.raw";
+ io::raw::save(data_->seg_smooth_linear(), output.toStdString());
emit next_step();
break;
+ case SegImageMorphoFilter:
+ output = basedir_ + "/" + basename + "_segmentation_morpho_filter.raw";
+ io::raw::save(data_->seg_smooth(), output.toStdString());
+ emit next_step();
+ break;
+
+
+ // Mean functions
+
+ case MeanFunctionsNonFiltered:
+ save_mean_funs(data_->seg(), data_->nregion(), data_->mean_regions(),
+ basename + "_non_filtered");
+ emit next_step();
+ break;
+
+ case MeanFunctionsLinearFilter:
+ save_mean_funs(data_->seg_smooth_linear(), data_->nregion_smooth_linear(),
+ data_->mean_regions_smooth_linear(),
+ basename + "_linear_filter");
+ emit next_step();
+ break;
+
+ case MeanFunctionsMorphoFilter:
+ save_mean_funs(data_->seg_smooth(), data_->nregion_smooth(),
+ data_->mean_regions_smooth(),
+ basename + "_morpho_filter");
+ emit next_step();
+ break;
+
+
+ default:
+ case SegImage:
case MeanFunctions:
- QString output_base = basedir_ + "/" + basename;
- util::array<util::array<input_data_t> >
- functions = shared::mean_function_per_region(data_->mean_regions(),
- packed_seg, packed_nlabels);
-
- for (unsigned i = 1; i < functions.nelements(); ++i)
- {
- QString name = output_base + "_l" + QString::number(i) + ".plot";
- io::plot::save(functions[i], name.toStdString());
- }
+ // Nothing.
emit next_step();
+ break;
}
}
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
index fc30282..53b61fe 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
@@ -26,7 +26,13 @@ namespace igr
Log,
RefImage,
SegImage,
- MeanFunctions
+ SegImageNonFiltered,
+ SegImageLinearFilter,
+ SegImageMorphoFilter,
+ MeanFunctions,
+ MeanFunctionsNonFiltered,
+ MeanFunctionsLinearFilter,
+ MeanFunctionsMorphoFilter
};
@@ -59,6 +65,10 @@ namespace igr
private: // Members
bool save_log(const QString& output);
+ void save_mean_funs(const seg_t& pseg,
+ const seg_data_t& pnlabels,
+ const mean_regions_t& mean_regions,
+ const QString& prefix);
private: // attributes
mln_data* data_;
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
index b57a52f..3769dc4 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
@@ -34,9 +34,20 @@ namespace igr
- seg::seg(mln_data* data, unsigned lambda)
- : data_(data), lambda_(lambda)
+ seg::seg(mln_data* data, unsigned lambda,
+ bool compute_preview, bool preview_computed)
+ : data_(data), lambda_(lambda),
+ compute_preview_(compute_preview),
+ preview_computed_(preview_computed)
{
+ // Setting step_count according to options.
+ if (compute_preview)
+ step_count_ = 3;
+ else
+ if (preview_computed)
+ step_count_ = 6;
+ else
+ step_count_ = 9;
}
@@ -45,12 +56,11 @@ namespace igr
}
- void seg::run()
+ const image3d<seg_data_t> seg::compute_seg(const image3d<igr::smoothed_data_t>& norm,
+ seg_data_t& nregion)
{
- seg_data_t nregion;
image2d<seg_data_t>
- tmp = shared::time_segmentation(data_->norm_smooth(),
- nregion, lambda_);
+ tmp = shared::time_segmentation(norm, nregion, lambda_);
emit next_step();
@@ -58,7 +68,41 @@ namespace igr
emit next_step();
- data_->update_seg(wsd, nregion);
+ return wsd;
+ }
+
+
+ void seg::run()
+ {
+ // Compute result on morpho smooth image only.
+ if (compute_preview_ || !preview_computed_)
+ {
+ seg_data_t nregion;
+ image3d<seg_data_t> wsd = compute_seg(data_->norm_smooth(), nregion);
+ data_->update_seg_smooth(wsd, nregion);
+ }
+
+ if (!compute_preview_)
+ {
+ if (!preview_computed_)
+ emit next_step();
+
+ // Non filtered image.
+ {
+ seg_data_t nregion;
+ image3d<seg_data_t> wsd = compute_seg(data_->norm(), nregion);
+ data_->update_seg(wsd, nregion);
+ }
+
+ emit next_step();
+
+ // Linearly filtered image.
+ {
+ seg_data_t nregion;
+ image3d<seg_data_t> wsd = compute_seg(data_->norm_smooth_linear(), nregion);
+ data_->update_seg_smooth_linear(wsd, nregion);
+ }
+ }
}
@@ -70,7 +114,7 @@ namespace igr
unsigned seg::step_count() const
{
- return 3;
+ return step_count_;
}
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
index 0e3d75e..f2efc90 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
@@ -26,7 +26,8 @@ namespace igr
Q_OBJECT;
public:
- seg(mln_data* data, unsigned lambda);
+ seg(mln_data* data, unsigned lambda,
+ bool compute_preview, bool preview_computed);
~seg();
void run();
@@ -46,9 +47,16 @@ namespace igr
/// @}
+ private: // methods
+ const image3d<seg_data_t> compute_seg(const image3d<igr::smoothed_data_t>& norm,
+ seg_data_t& nregion);
+
private: // attributes
mln_data* data_;
unsigned lambda_;
+ bool compute_preview_;
+ bool preview_computed_;
+ unsigned step_count_;
};
} // end of namespace igr::segmentation::tools
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui b/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui
index adbc296..18d8e91 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/plot_widget.ui
@@ -71,6 +71,26 @@
</widget>
</item>
<item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="savePlotBtn_" >
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Save plot</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_2" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/save_widget.ui b/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/save_widget.ui
index c832560..641cea6 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/save_widget.ui
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/ui/save_widget.ui
@@ -6,7 +6,7 @@
<x>0</x>
<y>0</y>
<width>370</width>
- <height>362</height>
+ <height>470</height>
</rect>
</property>
<property name="sizePolicy" >
@@ -161,23 +161,87 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item>
- <widget class="QCheckBox" name="segImaCBox" >
- <property name="text" >
+ <widget class="QGroupBox" name="segImaCBox" >
+ <property name="title" >
<string>Segmentation image</string>
</property>
- <property name="checked" >
+ <property name="checkable" >
<bool>true</bool>
</property>
+ <layout class="QVBoxLayout" name="verticalLayout_5" >
+ <item>
+ <widget class="QCheckBox" name="segImaNonFilteredCBox" >
+ <property name="text" >
+ <string>Non-filtered</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="segImaLinearFilterCBox" >
+ <property name="text" >
+ <string>Linear filter</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="segImaMorphoFilterCBox" >
+ <property name="text" >
+ <string>Morphological filter</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="meanFunCBox" >
- <property name="text" >
- <string>Mean function per region </string>
+ <widget class="QGroupBox" name="meanFunCBox" >
+ <property name="title" >
+ <string>Mean function per region</string>
</property>
- <property name="checked" >
+ <property name="checkable" >
<bool>true</bool>
</property>
+ <layout class="QVBoxLayout" name="verticalLayout_4" >
+ <item>
+ <widget class="QCheckBox" name="meanFunNonFilteredCBox" >
+ <property name="text" >
+ <string>Non-filtered</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="meanFunLinearFilterCBox" >
+ <property name="text" >
+ <string>Linear filter</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="meanFunMorphoFilterCBox" >
+ <property name="text" >
+ <string>Morphological filter</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
diff --git a/milena/sandbox/lazzara/igr/gui/shared/include/function_means.hh b/milena/sandbox/lazzara/igr/gui/shared/include/function_means.hh
index bdc2098..18cb65a 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/include/function_means.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/include/function_means.hh
@@ -49,7 +49,6 @@ namespace igr
/// Compute from slice \p sli_first to \p sli_last included.
//
template <typename V>
- inline
image2d<float>
function_means(const image3d<V>& ima, int sli_first, int sli_last);
diff --git a/milena/sandbox/lazzara/igr/gui/shared/include/mean_function_per_region.hh b/milena/sandbox/lazzara/igr/gui/shared/include/mean_function_per_region.hh
index b0adcfc..75da3a8 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/include/mean_function_per_region.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/include/mean_function_per_region.hh
@@ -30,6 +30,7 @@
#ifndef IGR_SHARED_INCLUDE_MEAN_FUNCTION_PER_REGION_HH
# define IGR_SHARED_INCLUDE_MEAN_FUNCTION_PER_REGION_HH
+# include <mln/core/var.hh>
# include <mln/core/image/image3d.hh>
# include <mln/core/image/dmorph/slice_image.hh>
@@ -49,7 +50,6 @@ namespace igr
/// Compute from slice \p sli_first to \p sli_last included.
//
template <typename V, typename L>
- inline
util::array<util::array<V> >
mean_function_per_region(const image3d<V>& ima,
const image3d<L>& lbl, const L& nregion);
diff --git a/milena/sandbox/lazzara/igr/gui/shared/include/mean_regions.hh b/milena/sandbox/lazzara/igr/gui/shared/include/mean_regions.hh
index 85a2e7d..6872683 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/include/mean_regions.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/include/mean_regions.hh
@@ -34,6 +34,8 @@
# include <mln/core/image/image2d.hh>
# include <mln/core/image/dmorph/slice_image.hh>
+# include <mln/core/var.hh>
+
# include <mln/data/paste.hh>
# include <mln/labeling/mean_values.hh>
# include <mln/labeling/pack.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/shared/include/normalization.hh b/milena/sandbox/lazzara/igr/gui/shared/include/normalization.hh
index 6ec41a2..e4d91eb 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/include/normalization.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/include/normalization.hh
@@ -56,7 +56,6 @@ namespace igr
/// number of slices of \p input.
//
template <typename V1, typename V2>
- inline
image3d<float>
normalization(const image3d<V1>& ima, const image2d<V2>& mean);
diff --git a/milena/sandbox/lazzara/igr/gui/shared/include/time_smooth_morpho.hh b/milena/sandbox/lazzara/igr/gui/shared/include/time_smooth_morpho.hh
index 4515e16..27331a0 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/include/time_smooth_morpho.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/include/time_smooth_morpho.hh
@@ -31,6 +31,8 @@
# define IGR_SHARED_INCLUDE_TIME_SMOOTH_MORPHO_HH
# include <mln/core/image/image3d.hh>
+# include <mln/accu/stat/mean.hh>
+# include <mln/accu/image/all.hh>
# include <mln/morpho/closing/structural.hh>
# include <mln/morpho/opening/structural.hh>
# include <mln/win/sline3d.hh>
--
1.5.6.5
1
0

last-svn-commit-693-g181a278 lazzara/igr/gui/segmentation/src/main_window.cc: Avoid a warning in 2D segmentation tool.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
---
milena/sandbox/ChangeLog | 5 +++++
.../igr/gui/segmentation/src/main_window.cc | 2 +-
2 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 705ecda..677070c 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,10 @@
2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * lazzara/igr/gui/segmentation/src/main_window.cc: Avoid a warning
+ in 2D segmentation tool.
+
+2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add missing defines in headers.
* lazzara/igr/gui/segmentation/src/crop_widget.hh,
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
index a225daf..6f064cb 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
@@ -152,7 +152,7 @@ namespace igr
}
- void main_window::clear_information_slot(const QPointF& p)
+ void main_window::clear_information_slot(const QPointF&)
{
point_info_->setText("");
}
--
1.5.6.5
1
0

11 Apr '11
* lazzara/igr/gui/segmentation/src/crop_widget.hh,
* lazzara/igr/gui/segmentation2dt/src/plot_widget.hh,
* lazzara/igr/gui/viewer/src/main_window.hh: Here.
---
milena/sandbox/ChangeLog | 8 ++++++++
.../igr/gui/segmentation/src/crop_widget.hh | 1 +
.../igr/gui/segmentation2dt/src/plot_widget.hh | 1 +
.../lazzara/igr/gui/viewer/src/main_window.hh | 1 +
4 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 5477ab3..705ecda 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,13 @@
2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add missing defines in headers.
+
+ * lazzara/igr/gui/segmentation/src/crop_widget.hh,
+ * lazzara/igr/gui/segmentation2dt/src/plot_widget.hh,
+ * lazzara/igr/gui/viewer/src/main_window.hh: Here.
+
+2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Split compilation of files including Milena's headers.
* lazzara/igr/gui/segmentation/segmentation.pro,
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.hh
index 16f78f3..c5145a3 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.hh
@@ -24,6 +24,7 @@
// executable file might be covered by the GNU General Public License.
#ifndef IGR_SEGMENTATION_SRC_CROP_WIDGET_HH
+# define IGR_SEGMENTATION_SRC_CROP_WIDGET_HH
# include <QtGui>
# include <ui_crop_widget.h>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/plot_widget.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/plot_widget.hh
index a5674dd..bdfce62 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/plot_widget.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/plot_widget.hh
@@ -24,6 +24,7 @@
// executable file might be covered by the GNU General Public License.
#ifndef IGR_SEGMENTATION_SRC_PLOT_WIDGET_HH
+# define IGR_SEGMENTATION_SRC_PLOT_WIDGET_HH
# include <QtGui>
# include <ui_plot_widget.h>
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/src/main_window.hh b/milena/sandbox/lazzara/igr/gui/viewer/src/main_window.hh
index 76db858..b555257 100644
--- a/milena/sandbox/lazzara/igr/gui/viewer/src/main_window.hh
+++ b/milena/sandbox/lazzara/igr/gui/viewer/src/main_window.hh
@@ -24,6 +24,7 @@
// executable file might be covered by the GNU General Public License.
#ifndef IGR_VIEWER_SRC_MAIN_WINDOW_HH
+# define IGR_VIEWER_SRC_MAIN_WINDOW_HH
# include <QtGui>
# include <ui_main_window.h>
--
1.5.6.5
1
0

last-svn-commit-691-g687f97b Split compilation of files including Milena's headers.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
* lazzara/igr/gui/segmentation/segmentation.pro,
* lazzara/igr/gui/segmentation/src/crop_widget.cc,
* lazzara/igr/gui/segmentation/src/edit_seg_widget.cc,
* lazzara/igr/gui/segmentation/src/edit_seg_widget.hh,
* lazzara/igr/gui/segmentation/src/load_widget.cc,
* lazzara/igr/gui/segmentation/src/main.cc,
* lazzara/igr/gui/segmentation/src/main_window.cc,
* lazzara/igr/gui/segmentation/src/mln_data.cc,
* lazzara/igr/gui/segmentation/src/mln_data.hh,
* lazzara/igr/gui/segmentation/src/save_widget.cc,
* lazzara/igr/gui/segmentation/src/seg_widget.cc,
* lazzara/igr/gui/segmentation/src/task_handler.hh,
* lazzara/igr/gui/segmentation/src/tools/crop.cc,
* lazzara/igr/gui/segmentation/src/tools/crop.hh,
* lazzara/igr/gui/segmentation/src/tools/edit_seg.cc,
* lazzara/igr/gui/segmentation/src/tools/edit_seg.hh,
* lazzara/igr/gui/segmentation/src/tools/load.cc,
* lazzara/igr/gui/segmentation/src/tools/load.hh,
* lazzara/igr/gui/segmentation/src/tools/save.cc,
* lazzara/igr/gui/segmentation/src/tools/save.hh,
* lazzara/igr/gui/segmentation/src/tools/seg.cc,
* lazzara/igr/gui/segmentation/src/tools/seg.hh,
* lazzara/igr/gui/segmentation2dt/segmentation2dt.pro,
* lazzara/igr/gui/segmentation2dt/src/crop_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/load_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/main.cc,
* lazzara/igr/gui/segmentation2dt/src/main_window.cc,
* lazzara/igr/gui/segmentation2dt/src/mln_data.cc,
* lazzara/igr/gui/segmentation2dt/src/mln_data.hh,
* lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/save_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/seg_widget.cc,
* lazzara/igr/gui/segmentation2dt/src/task_handler.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/crop.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/crop.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/load.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/load.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/save.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/save.hh,
* lazzara/igr/gui/segmentation2dt/src/tools/seg.cc,
* lazzara/igr/gui/segmentation2dt/src/tools/seg.hh,
* lazzara/igr/gui/shared/src/color.hh,
* lazzara/igr/gui/shared/src/igr_types.hh,
* lazzara/igr/gui/shared/src/image_viewer.hh,
* lazzara/igr/gui/viewer/src/main.cc,
* lazzara/igr/gui/viewer/src/mln_data.cc,
* lazzara/igr/gui/viewer/src/mln_data.hh,
* lazzara/igr/gui/viewer/src/mln_widgets.cc,
* lazzara/igr/gui/viewer/viewer.pro: Split compilation of files
including Milena's headers.
---
milena/sandbox/ChangeLog | 62 +++++++++++++++++
.../lazzara/igr/gui/segmentation/segmentation.pro | 55 +++++++++++++--
.../igr/gui/segmentation/src/crop_widget.cc | 1 -
.../igr/gui/segmentation/src/edit_seg_widget.cc | 1 -
.../igr/gui/segmentation/src/edit_seg_widget.hh | 4 -
.../igr/gui/segmentation/src/load_widget.cc | 1 -
.../lazzara/igr/gui/segmentation/src/main.cc | 1 +
.../igr/gui/segmentation/src/main_window.cc | 1 -
.../lazzara/igr/gui/segmentation/src/mln_data.cc | 3 +-
.../lazzara/igr/gui/segmentation/src/mln_data.hh | 4 -
.../igr/gui/segmentation/src/save_widget.cc | 1 -
.../lazzara/igr/gui/segmentation/src/seg_widget.cc | 1 -
.../igr/gui/segmentation/src/task_handler.hh | 4 -
.../lazzara/igr/gui/segmentation/src/tools/crop.cc | 4 -
.../lazzara/igr/gui/segmentation/src/tools/crop.hh | 4 -
.../igr/gui/segmentation/src/tools/edit_seg.cc | 6 +-
.../igr/gui/segmentation/src/tools/edit_seg.hh | 4 -
.../lazzara/igr/gui/segmentation/src/tools/load.cc | 4 -
.../lazzara/igr/gui/segmentation/src/tools/load.hh | 4 -
.../lazzara/igr/gui/segmentation/src/tools/save.cc | 6 +-
.../lazzara/igr/gui/segmentation/src/tools/save.hh | 4 -
.../lazzara/igr/gui/segmentation/src/tools/seg.cc | 6 +-
.../lazzara/igr/gui/segmentation/src/tools/seg.hh | 4 -
.../igr/gui/segmentation2dt/segmentation2dt.pro | 72 ++++++++++++++++++--
.../igr/gui/segmentation2dt/src/crop_widget.cc | 1 -
.../igr/gui/segmentation2dt/src/load_widget.cc | 1 -
.../lazzara/igr/gui/segmentation2dt/src/main.cc | 4 +-
.../igr/gui/segmentation2dt/src/main_window.cc | 1 -
.../igr/gui/segmentation2dt/src/mln_data.cc | 2 +-
.../igr/gui/segmentation2dt/src/mln_data.hh | 4 -
.../gui/segmentation2dt/src/norm_smooth_widget.cc | 2 +-
.../igr/gui/segmentation2dt/src/ref_mean_widget.cc | 1 -
.../igr/gui/segmentation2dt/src/save_widget.cc | 1 -
.../igr/gui/segmentation2dt/src/seg_widget.cc | 1 -
.../igr/gui/segmentation2dt/src/task_handler.hh | 4 -
.../igr/gui/segmentation2dt/src/tools/crop.cc | 4 -
.../igr/gui/segmentation2dt/src/tools/crop.hh | 4 -
.../igr/gui/segmentation2dt/src/tools/load.cc | 4 -
.../igr/gui/segmentation2dt/src/tools/load.hh | 4 -
.../gui/segmentation2dt/src/tools/mean_regions.cc | 4 -
.../gui/segmentation2dt/src/tools/mean_regions.hh | 4 -
.../gui/segmentation2dt/src/tools/norm_smooth.cc | 4 -
.../gui/segmentation2dt/src/tools/norm_smooth.hh | 4 -
.../igr/gui/segmentation2dt/src/tools/ref_mean.cc | 4 -
.../igr/gui/segmentation2dt/src/tools/ref_mean.hh | 4 -
.../igr/gui/segmentation2dt/src/tools/save.cc | 5 +-
.../igr/gui/segmentation2dt/src/tools/save.hh | 4 -
.../igr/gui/segmentation2dt/src/tools/seg.cc | 6 +-
.../igr/gui/segmentation2dt/src/tools/seg.hh | 5 +-
milena/sandbox/lazzara/igr/gui/shared/src/color.hh | 7 +--
.../lazzara/igr/gui/shared/src/igr_types.hh | 4 -
.../lazzara/igr/gui/shared/src/image_viewer.hh | 7 +--
milena/sandbox/lazzara/igr/gui/viewer/src/main.cc | 4 +-
.../sandbox/lazzara/igr/gui/viewer/src/mln_data.cc | 20 +++++-
.../sandbox/lazzara/igr/gui/viewer/src/mln_data.hh | 22 +++++-
.../lazzara/igr/gui/viewer/src/mln_widgets.cc | 2 -
milena/sandbox/lazzara/igr/gui/viewer/viewer.pro | 25 +++++--
57 files changed, 257 insertions(+), 173 deletions(-)
delete mode 100644 milena/sandbox/lazzara/igr/gui/viewer/src/mln_widgets.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 44c82e9..5477ab3 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,65 @@
+2010-11-15 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Split compilation of files including Milena's headers.
+
+ * lazzara/igr/gui/segmentation/segmentation.pro,
+ * lazzara/igr/gui/segmentation/src/crop_widget.cc,
+ * lazzara/igr/gui/segmentation/src/edit_seg_widget.cc,
+ * lazzara/igr/gui/segmentation/src/edit_seg_widget.hh,
+ * lazzara/igr/gui/segmentation/src/load_widget.cc,
+ * lazzara/igr/gui/segmentation/src/main.cc,
+ * lazzara/igr/gui/segmentation/src/main_window.cc,
+ * lazzara/igr/gui/segmentation/src/mln_data.cc,
+ * lazzara/igr/gui/segmentation/src/mln_data.hh,
+ * lazzara/igr/gui/segmentation/src/save_widget.cc,
+ * lazzara/igr/gui/segmentation/src/seg_widget.cc,
+ * lazzara/igr/gui/segmentation/src/task_handler.hh,
+ * lazzara/igr/gui/segmentation/src/tools/crop.cc,
+ * lazzara/igr/gui/segmentation/src/tools/crop.hh,
+ * lazzara/igr/gui/segmentation/src/tools/edit_seg.cc,
+ * lazzara/igr/gui/segmentation/src/tools/edit_seg.hh,
+ * lazzara/igr/gui/segmentation/src/tools/load.cc,
+ * lazzara/igr/gui/segmentation/src/tools/load.hh,
+ * lazzara/igr/gui/segmentation/src/tools/save.cc,
+ * lazzara/igr/gui/segmentation/src/tools/save.hh,
+ * lazzara/igr/gui/segmentation/src/tools/seg.cc,
+ * lazzara/igr/gui/segmentation/src/tools/seg.hh,
+ * lazzara/igr/gui/segmentation2dt/segmentation2dt.pro,
+ * lazzara/igr/gui/segmentation2dt/src/crop_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/load_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/main.cc,
+ * lazzara/igr/gui/segmentation2dt/src/main_window.cc,
+ * lazzara/igr/gui/segmentation2dt/src/mln_data.cc,
+ * lazzara/igr/gui/segmentation2dt/src/mln_data.hh,
+ * lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/save_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/seg_widget.cc,
+ * lazzara/igr/gui/segmentation2dt/src/task_handler.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/crop.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/crop.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/load.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/load.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/save.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/save.hh,
+ * lazzara/igr/gui/segmentation2dt/src/tools/seg.cc,
+ * lazzara/igr/gui/segmentation2dt/src/tools/seg.hh,
+ * lazzara/igr/gui/shared/src/color.hh,
+ * lazzara/igr/gui/shared/src/igr_types.hh,
+ * lazzara/igr/gui/shared/src/image_viewer.hh,
+ * lazzara/igr/gui/viewer/src/main.cc,
+ * lazzara/igr/gui/viewer/src/mln_data.cc,
+ * lazzara/igr/gui/viewer/src/mln_data.hh,
+ * lazzara/igr/gui/viewer/src/mln_widgets.cc,
+ * lazzara/igr/gui/viewer/viewer.pro: Split compilation of files
+ including Milena's headers.
+
2010-02-09 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a tool for anapath filtering.
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/segmentation.pro b/milena/sandbox/lazzara/igr/gui/segmentation/segmentation.pro
index ef8dd61..4a0f003 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/segmentation.pro
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/segmentation.pro
@@ -6,20 +6,61 @@ TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include
-INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena /lrde/dev/linux-x86/stable/gdcm/include
+INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena
-DEFINES= NDEBUG
+DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
QMAKE_CXX += -O2
#LIBS += -L/home/inca/local/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib
-LIBS += -L/lrde/dev/linux-x86/stable/gdcm/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib
-
+LIBS += -lgdcmCommon -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lqwt-qt4
# Input
-HEADERS += src/main_window.hh ../shared/src/image_viewer.hh ../shared/src/internal/interactive_scene.hh src/mln_data.hh src/tools/crop.hh src/task_handler.hh src/crop_widget.hh src/task_widget.hh src/load_widget.hh src/seg_widget.hh src/tools/seg.hh src/tools/edit_seg.hh src/edit_seg_widget.hh src/save_widget.hh src/tools/save.hh src/tools/load.hh
-FORMS += ui/main_window.ui ../shared/ui/image_viewer.ui ui/crop_widget.ui ui/load_widget.ui ui/seg_widget.ui ui/edit_seg_widget.ui ui/save_widget.ui
-SOURCES += src/main.cc ../shared/src/internal/interactive_scene.cc src/mln_widgets.cc src/task_handler.cc src/main_window.cc src/task_widget.cc
+HEADERS += \
+ src/main_window.hh \
+ ../shared/src/image_viewer.hh \
+ ../shared/src/internal/interactive_scene.hh \
+ src/mln_data.hh \
+ src/tools/crop.hh \
+ src/task_handler.hh \
+ src/crop_widget.hh \
+ src/task_widget.hh \
+ src/load_widget.hh \
+ src/seg_widget.hh \
+ src/tools/seg.hh \
+ src/tools/edit_seg.hh \
+ src/edit_seg_widget.hh \
+ src/save_widget.hh \
+ src/tools/save.hh \
+ src/tools/load.hh
+
+FORMS += \
+ ui/main_window.ui \
+ ../shared/ui/image_viewer.ui \
+ ui/crop_widget.ui \
+ ui/load_widget.ui \
+ ui/seg_widget.ui \
+ ui/edit_seg_widget.ui \
+ ui/save_widget.ui
+
+SOURCES += \
+ src/main.cc \
+ ../shared/src/internal/interactive_scene.cc \
+ ../shared/src/image_viewer.cc \
+ src/crop_widget.cc \
+ src/edit_seg_widget.cc \
+ src/save_widget.cc \
+ src/load_widget.cc \
+ src/seg_widget.cc \
+ src/tools/crop.cc \
+ src/tools/edit_seg.cc \
+ src/tools/load.cc \
+ src/tools/save.cc \
+ src/tools/seg.cc \
+ src/mln_data.cc \
+ src/task_handler.cc \
+ src/main_window.cc \
+ src/task_widget.cc
RESOURCES = ../shared/shared.qrc
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.cc
index 4b0dafd..6b56a12 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/crop_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/crop_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.cc
index f662eda..523996f 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/edit_seg_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.hh
index 9f988a1..fa62601 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/edit_seg_widget.hh
@@ -31,10 +31,6 @@
# include <src/task_widget.hh>
# include <shared/src/igr_types.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <mln/util/array.hh>
# include <mln/util/set.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/load_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/load_widget.cc
index 48d9b25..a9073f3 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/load_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/load_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/load_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/main.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/main.cc
index 59b332a..503c751 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/main.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/main.cc
@@ -26,6 +26,7 @@
#include <QApplication>
#include <QtGui>
+#undef MLN_WO_GLOBAL_VARS
#include <src/main_window.hh>
int main(int argc, char *argv[])
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
index d36f608..a225daf 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/main_window.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/main_window.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.cc
index efba25b..6c8ea01 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.cc
@@ -1,4 +1,5 @@
-#define INCLUDE_MLN_FILES
+#include <QtCore>
+
#include <src/mln_data.hh>
#include <mln/core/image/dmorph/slice_image.hh>
#include <mln/core/image/image3d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.hh
index f295dd9..13995d5 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/mln_data.hh
@@ -4,10 +4,6 @@
#include <QtCore/QObject>
#include <QtCore/QPointF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/save_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/save_widget.cc
index 3e4b5b8..75d34d4 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/save_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/save_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/save_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/seg_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/seg_widget.cc
index 88b7d92..0dcb5fc 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/seg_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/seg_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/seg_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/task_handler.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/task_handler.hh
index 48d6bb5..d62a62c 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/task_handler.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/task_handler.hh
@@ -5,10 +5,6 @@
# include <QtCore/QObject>
# include <QtGui/QProgressDialog>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <src/task.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.cc
index a974d82..4692b8d 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.cc
@@ -1,9 +1,5 @@
#include <src/tools/crop.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/data/fill.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.hh
index 40f4729..a19f89c 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/crop.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.cc
index cd4dad0..3e14ea8 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.cc
@@ -1,11 +1,9 @@
+#include <QtCore>
+
#include <src/tools/edit_seg.hh>
#include <shared/src/igr_types.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/data/fill.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.hh
index e77de50..9e28b97 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/edit_seg.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/util/array.hh>
# include <mln/util/set.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.cc
index 92f82bc..e9815a2 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.cc
@@ -1,9 +1,5 @@
#include <src/tools/load.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/data/fill.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.hh
index 64a0e30..9e30d18 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/load.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.cc
index 7954105..a4877ca 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.cc
@@ -1,8 +1,6 @@
-#include <src/tools/save.hh>
+#include <QtCore>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
+#include <src/tools/save.hh>
#include <mln/core/image/image3d.hh>
#include <mln/core/image/dmorph/slice_image.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.hh
index ed90b06..11cc805 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/save.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.cc b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.cc
index 7a4b003..4fb8898 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.cc
@@ -1,8 +1,6 @@
-#include <src/tools/seg.hh>
+#include <QtCore>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
+#include <src/tools/seg.hh>
#include <mln/core/image/image3d.hh>
#include <mln/core/image/image2d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.hh b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.hh
index 1f7c478..b974042 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation/src/tools/seg.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/segmentation2dt.pro b/milena/sandbox/lazzara/igr/gui/segmentation2dt/segmentation2dt.pro
index 8781b33..d7ce7e6 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/segmentation2dt.pro
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/segmentation2dt.pro
@@ -6,20 +6,80 @@ TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include
-INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena /lrde/dev/linux-x86/stable/gdcm/include
+INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena
-DEFINES= NDEBUG
+DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
QMAKE_CXX += -O2
#LIBS += -L/home/inca/local/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib -lqwt-qt4
-LIBS += -L/lrde/dev/linux-x86/stable/gdcm/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib -lqwt-qt4
+LIBS += -lgdcmCommon -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lqwt-qt4
+
+
+
# Input
-HEADERS += src/main_window.hh ../shared/src/image_viewer.hh ../shared/src/internal/interactive_scene.hh src/mln_data.hh src/tools/crop.hh src/task_handler.hh src/crop_widget.hh src/task_widget.hh src/load_widget.hh src/seg_widget.hh src/tools/seg.hh src/save_widget.hh src/tools/save.hh src/ref_mean_widget.hh src/tools/ref_mean.hh src/tools/norm_smooth.hh src/norm_smooth_widget.hh src/mean_regions_widget.hh src/tools/mean_regions.hh src/tools/load.hh src/plot_widget.hh src/plot.hh
-FORMS += ui/main_window.ui ../shared/ui/image_viewer.ui ui/crop_widget.ui ui/load_widget.ui ui/seg_widget.ui ui/save_widget.ui ui/ref_mean_widget.ui ui/norm_smooth_widget.ui ui/mean_regions_widget.ui ui/plot_widget.ui
-SOURCES += src/main.cc ../shared/src/internal/interactive_scene.cc src/mln_widgets.cc src/task_handler.cc src/main_window.cc src/task_widget.cc src/plot_widget.cc src/plot.cc
+HEADERS += \
+ src/main_window.hh \
+ ../shared/src/image_viewer.hh \
+ ../shared/src/internal/interactive_scene.hh \
+ src/mln_data.hh \
+ src/tools/crop.hh \
+ src/task_handler.hh \
+ src/crop_widget.hh \
+ src/task_widget.hh \
+ src/load_widget.hh \
+ src/seg_widget.hh \
+ src/tools/seg.hh \
+ src/save_widget.hh \
+ src/tools/save.hh \
+ src/ref_mean_widget.hh \
+ src/tools/ref_mean.hh \
+ src/tools/norm_smooth.hh \
+ src/norm_smooth_widget.hh \
+ src/mean_regions_widget.hh \
+ src/tools/mean_regions.hh \
+ src/tools/load.hh \
+ src/plot_widget.hh \
+ src/plot.hh
+
+FORMS += \
+ ui/main_window.ui \
+ ../shared/ui/image_viewer.ui \
+ ui/crop_widget.ui \
+ ui/load_widget.ui \
+ ui/seg_widget.ui \
+ ui/save_widget.ui \
+ ui/ref_mean_widget.ui \
+ ui/norm_smooth_widget.ui \
+ ui/mean_regions_widget.ui \
+ ui/plot_widget.ui
+
+SOURCES += \
+ src/main.cc \
+ ../shared/src/internal/interactive_scene.cc \
+ ../shared/src/image_viewer.cc \
+ src/crop_widget.cc \
+ src/save_widget.cc \
+ src/load_widget.cc \
+ src/seg_widget.cc \
+ src/ref_mean_widget.cc \
+ src/norm_smooth_widget.cc \
+ src/mean_regions_widget.cc \
+ src/tools/crop.cc \
+ src/tools/seg.cc \
+ src/tools/save.cc \
+ src/tools/ref_mean.cc \
+ src/tools/norm_smooth.cc \
+ src/tools/mean_regions.cc \
+ src/tools/load.cc \
+ src/mln_data.cc \
+ src/task_handler.cc \
+ src/main_window.cc \
+ src/task_widget.cc \
+ src/plot_widget.cc \
+ src/plot.cc
RESOURCES = ../shared/shared.qrc
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/crop_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/crop_widget.cc
index ba90c64..67a51b7 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/crop_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/crop_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/crop_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/load_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/load_widget.cc
index 6969ed5..27787b0 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/load_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/load_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/load_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main.cc
index 59b332a..132d270 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -26,6 +27,7 @@
#include <QApplication>
#include <QtGui>
+#undef MLN_WO_GLOBAL_VARS
#include <src/main_window.hh>
int main(int argc, char *argv[])
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main_window.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main_window.cc
index 0da6059..00e95de 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main_window.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/main_window.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/main_window.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
index e90b236..c294c73 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.cc
@@ -1,4 +1,4 @@
-#define INCLUDE_MLN_FILES
+#include <QtCore>
#include <src/mln_data.hh>
#include <mln/core/image/dmorph/slice_image.hh>
#include <mln/core/image/image3d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
index 4dcdf81..6f1776f 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/mln_data.hh
@@ -4,10 +4,6 @@
#include <QtCore/QObject>
#include <QtCore/QPointF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image2d.hh>
#include <mln/core/image/image3d.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc
index cad1e7f..682206e 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/norm_smooth_widget.cc
@@ -23,7 +23,7 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
+
#include <QtCore>
#include <QtGui>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc
index bc7b456..61d8e21 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/ref_mean_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/ref_mean_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
index edf270a..8d87133 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/save_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/save_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
index aaf9c1d..6891432 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/seg_widget.cc
@@ -23,7 +23,6 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-//#define INCLUDE_MLN_FILES
#include <QtCore>
#include <QtGui>
#include <src/seg_widget.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_handler.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_handler.hh
index 48d6bb5..d62a62c 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_handler.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/task_handler.hh
@@ -5,10 +5,6 @@
# include <QtCore/QObject>
# include <QtGui/QProgressDialog>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <src/task.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.cc
index a974d82..4692b8d 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.cc
@@ -1,9 +1,5 @@
#include <src/tools/crop.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/data/fill.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.hh
index 40f4729..a19f89c 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/crop.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.cc
index 92f82bc..e9815a2 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.cc
@@ -1,9 +1,5 @@
#include <src/tools/load.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/data/fill.hh>
#include <shared/src/igr_types.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.hh
index 64a0e30..9e30d18 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/load.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
index 64353d3..8245a70 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.cc
@@ -1,7 +1,3 @@
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <src/tools/mean_regions.hh>
#include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh
index a20057b..2d7ff5e 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/mean_regions.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc
index 9a1ddb3..16751ce 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.cc
@@ -1,7 +1,3 @@
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <src/tools/norm_smooth.hh>
#include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh
index fc4d1e8..ce74aa1 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/norm_smooth.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc
index 31e9d21..42fd288 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.cc
@@ -1,7 +1,3 @@
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <src/tools/ref_mean.hh>
#include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh
index dc39810..e8decf7 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/ref_mean.hh
@@ -3,10 +3,6 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
index 37a5608..23e38d1 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.cc
@@ -3,12 +3,9 @@
#include <src/tools/save.hh>
#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <mln/core/image/dmorph/slice_image.hh>
#include <mln/data/fill.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
index 01d8560..fc30282 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/save.hh
@@ -4,10 +4,6 @@
# include <QtCore/QRectF>
# include <QtCore/QString>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
index d72cb50..b57a52f 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.cc
@@ -1,8 +1,6 @@
-#include <src/tools/seg.hh>
+#include <QtCore>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
+#include <src/tools/seg.hh>
#include <mln/core/image/image3d.hh>
#include <mln/core/image/image2d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
index 963b6a8..0e3d75e 100644
--- a/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/segmentation2dt/src/tools/seg.hh
@@ -3,11 +3,8 @@
# include <QtCore/QRectF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/core/alias/box3d.hh>
+# include <mln/core/image/image3d.hh>
# include <src/task.hh>
# include <src/mln_data.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/shared/src/color.hh b/milena/sandbox/lazzara/igr/gui/shared/src/color.hh
index 980d3bb..cf62577 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/src/color.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/src/color.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -30,10 +31,6 @@
#ifndef MLN_DEMO_SRC_COLOR_HH
# define MLN_DEMO_SRC_COLOR_HH
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
//# if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
# include <mln/value/qt/rgb32.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/shared/src/igr_types.hh b/milena/sandbox/lazzara/igr/gui/shared/src/igr_types.hh
index da64d22..5154b6b 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/src/igr_types.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/src/igr_types.hh
@@ -3,10 +3,6 @@
# include <shared/src/color.hh>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <mln/value/label_16.hh>
# include <mln/value/int_u12.hh>
# include <mln/value/int_u8.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/shared/src/image_viewer.hh b/milena/sandbox/lazzara/igr/gui/shared/src/image_viewer.hh
index c9623b8..5996b1e 100644
--- a/milena/sandbox/lazzara/igr/gui/shared/src/image_viewer.hh
+++ b/milena/sandbox/lazzara/igr/gui/shared/src/image_viewer.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -32,10 +33,6 @@
# include <ui_image_viewer.h>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
# include <src/igr_types.hh>
# include <mln/core/image/image2d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/src/main.cc b/milena/sandbox/lazzara/igr/gui/viewer/src/main.cc
index 4678229..46674c1 100644
--- a/milena/sandbox/lazzara/igr/gui/viewer/src/main.cc
+++ b/milena/sandbox/lazzara/igr/gui/viewer/src/main.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -26,6 +27,7 @@
#include <QApplication>
#include <QtGui>
+#undef MLN_WO_GLOBAL_VARS
#include <src/main_window.hh>
int main(int argc, char *argv[])
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.cc b/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.cc
index e43fa15..7579c62 100644
--- a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.cc
+++ b/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.cc
@@ -1,4 +1,22 @@
-#define INCLUDE_MLN_FILES
+// Copyright (C) 2009, 2010 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/>.
+
+#include <QtCore>
+
#include <src/mln_data.hh>
#include <mln/core/image/dmorph/slice_image.hh>
#include <mln/core/image/image3d.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.hh b/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.hh
index 9c78742..57ee01f 100644
--- a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.hh
+++ b/milena/sandbox/lazzara/igr/gui/viewer/src/mln_data.hh
@@ -1,13 +1,27 @@
+// Copyright (C) 2009, 2010 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/>.
+
+
#ifndef IGR_VIEWER_SRC_MLN_DATA_HH
# define IGR_VIEWER_SRC_MLN_DATA_HH
#include <QtCore/QObject>
#include <QtCore/QPointF>
-# ifndef INCLUDE_MLN_FILES
-# define MLN_INCLUDE_ONLY
-# endif
-
#include <mln/core/image/image3d.hh>
#include <shared/src/igr_types.hh>
#include <mln/value/int_u12.hh>
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_widgets.cc b/milena/sandbox/lazzara/igr/gui/viewer/src/mln_widgets.cc
deleted file mode 100644
index 2ac5c66..0000000
--- a/milena/sandbox/lazzara/igr/gui/viewer/src/mln_widgets.cc
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <shared/src/image_viewer.cc>
-#include <src/mln_data.cc>
diff --git a/milena/sandbox/lazzara/igr/gui/viewer/viewer.pro b/milena/sandbox/lazzara/igr/gui/viewer/viewer.pro
index f4ffc14..b384b8f 100644
--- a/milena/sandbox/lazzara/igr/gui/viewer/viewer.pro
+++ b/milena/sandbox/lazzara/igr/gui/viewer/viewer.pro
@@ -5,19 +5,32 @@
TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
-INCLUDEPATH += . src ../shared ../ $(OLN)/milena /lrde/dev/linux-x86/stable/gdcm/include
+INCLUDEPATH += . src ../shared ../ $(OLN)/milena
#INCLUDEPATH += . src ../shared ../ $(OLN)/milena /home/inca/local/include
-DEFINES= NDEBUG
+DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
#LIBS += -L/home/inca/local/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib
-LIBS += -L/lrde/dev/linux-x86/stable/gdcm/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib
+LIBS += -lgdcmCommon -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lqwt-qt4
# Input
-HEADERS += src/main_window.hh ../shared/src/image_viewer.hh ../shared/src/internal/interactive_scene.hh src/mln_data.hh
-FORMS += ui/main_window.ui ../shared/ui/image_viewer.ui
-SOURCES += src/main.cc src/main_window.cc ../shared/src/internal/interactive_scene.cc src/mln_widgets.cc
+HEADERS += \
+ src/main_window.hh \
+ ../shared/src/image_viewer.hh \
+ ../shared/src/internal/interactive_scene.hh \
+ src/mln_data.hh
+
+FORMS += \
+ ui/main_window.ui \
+ ../shared/ui/image_viewer.ui
+
+SOURCES += \
+ src/main.cc \
+ src/main_window.cc \
+ ../shared/src/internal/interactive_scene.cc \
+ ../shared/src/image_viewer.cc \
+ src/mln_data.cc
RESOURCES = ../shared/shared.qrc
--
1.5.6.5
1
0

last-svn-commit-690-g62569b3 Add an image loader in the anapath GUI.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
* sandbox/lazzara/igr/gui/anapath/src/tools/load.cc
* sandbox/lazzara/igr/gui/anapath/src/tools/load.hh
---
milena/ChangeLog | 7 +++
.../lazzara/igr/gui/anapath/src/tools/load.cc | 55 ++++++++++++++++++++
.../lazzara/igr/gui/anapath/src/tools/load.hh | 49 +++++++++++++++++
3 files changed, 111 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6d5de98..23fa923 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add an image loader in the anapath GUI.
+
+ * sandbox/lazzara/igr/gui/anapath/src/tools/load.cc
+ * sandbox/lazzara/igr/gui/anapath/src/tools/load.hh
+
2010-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
* mln/io/pnm/save.hh: Add a fixme related to an ICE with GCC
diff --git a/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.cc b/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.cc
new file mode 100644
index 0000000..48b1f46
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.cc
@@ -0,0 +1,55 @@
+#include <src/tools/load.hh>
+#include <mln/util/timer.hh>
+#include <shared/include/io/magick.hh>
+
+namespace igr
+{
+
+ namespace anapath
+ {
+
+ namespace tools
+ {
+
+ load::load(mln_data* data)
+ : data_(data)
+ {
+ }
+
+
+ void load::start(const QString& filename)
+ {
+ filename_ = filename;
+ QThread::start();
+ }
+
+
+ void load::run()
+ {
+ // Closing previous open image.
+ if (data_->input)
+ data_->input->close();
+ delete data_->input;
+
+
+ // Open new image.
+ data_->input = 0;
+
+ util::timer t;
+ t.start();
+
+ large_image_t *tmp = new large_image_t(filename_.toStdString());
+ if (! tmp->is_valid())
+ emit error(tmp->info_hook().error.c_str());
+
+ t.stop();
+ std::cout << "image loaded - " << t << std::endl;
+
+ data_->input = tmp;
+ }
+
+ } // end of namespace igr::anapath::tools
+
+ } // end of namespace igr::anapath
+
+} // end of namespace igr
diff --git a/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.hh b/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.hh
new file mode 100644
index 0000000..cfaa6d9
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/anapath/src/tools/load.hh
@@ -0,0 +1,49 @@
+#ifndef IGR_ANAPATH_SRC_TOOLS_LOAD_HH
+# define IGR_ANAPATH_SRC_TOOLS_LOAD_HH
+
+#include <QtCore>
+
+#include <src/mln_data.hh>
+
+namespace igr
+{
+
+ namespace anapath
+ {
+
+ namespace tools
+ {
+
+
+ class load : public QThread
+ {
+ Q_OBJECT;
+
+ typedef io::magick::large_image<mln::value::rgb8> large_image_t;
+
+ public:
+
+ load(mln_data *data);
+ void start(const QString& filename);
+
+ virtual void run();
+
+ signals:
+ void error(const QString& msg);
+
+ private: // members
+
+ private: // attributes
+ mln_data* data_;
+ QString filename_;
+ };
+
+
+
+ } // end of namespace igr::anapath::tools
+
+ } // end of namespace igr::anapath
+
+} // end of namespace igr
+
+#endif // !IGR_ANAPATH_SRC_TOOLS_LOAD_HH
--
1.5.6.5
1
0
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 igr has been created
at dab5d674ff5a32dbbba0dbe53543864f89d405cc (commit)
- Log -----------------------------------------------------------------
dab5d67 mln/io/dicom/load.hh: Fix invalid image loading.
881edd2 Use int_u16 instead of int_u12.
04cf923 Add more from_to overloads.
1b4ffab Fix Paths in scripts and build systems.
722f33d Update build system to use MLN_WO_GLOBAL_VARS.
8df88e3 Move IGR code from milena/sandbox to igr's private module.
319827a lazzara/igr/gui/segmentation/src/task_widget.cc: Avoid a warning.
90ac1e4 Update code with nslices() instead of nslis().
a0aa478 Store loaded image with double value type.
27c8f05 Add save button for function plots.
9dd5ec1 Add function visualization in the mean region widget.
aa8417d Allow to save results filtered differently in the 3D segmentation tool.
181a278 lazzara/igr/gui/segmentation/src/main_window.cc: Avoid a warning in 2D segmentation tool.
a54cebf Add missing defines in headers.
687f97b Split compilation of files including Milena's headers.
62569b3 Add an image loader in the anapath GUI.
1d4349d Fix compilation
522f81f Add a tool to superpose segmentation images.
b6b6df1 Update GUI according last IGR's needs.
cdda6fe Add specific routines in mln.
adea41d Add a tool for anapath filtering.
ed2fd90 Remove deprecated IGR's segmentation tool.
b394deb Improve IGR's segmentation tools.
1e5f309 Improve 2D+t segmentation tool.
6374b5e Improve the display of the normalized image.
9b9e09a Thread image loading.
db74d4f Cleanup I/O and documentation in IGR's code.
f1c1798 Add new GUIs for IGR.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0

05 Apr '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 unstable/scribo has been updated
via f5a185dfd59d5ed9f804d92262899f0cada75631 (commit)
via f553aa713bf237a24615fa71bd1e21e67fe37de4 (commit)
via 78843e4f50230c6019cd151c18e27e8090a2c177 (commit)
via ddcab202ab8ccfac3b4ead5b19e69a0d0ecd58b5 (commit)
via af0fa024f48e7449fa1355c7e752d297b9fb2781 (commit)
via b8e866eb546766ab5028bc4c1f018db95dccd855 (commit)
via 0012ddf9c6f6b0e233b280f73cc79efc1feee114 (commit)
via 9cfcb85e161a9bc030cd64ce24c4fa53012b04f8 (commit)
via 59dd55445ad87980e12ad98e57f5c3ad4093637b (commit)
from 57a4952e7ad3d3abda896726c512f4e95bc504cd (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 -----------------------------------------------------------------
f5a185d Regen generated files.
f553aa7 configure.ac: Configure scribo/tests/estim.
78843e4 Compute font and boldness data.
ddcab20 mln/accu/stat/median_h.hh: Add missing operator=().
af0fa02 configure.ac: configure scribo/tests/primitive/extract.
b8e866e Add a new alignments extraction routine.
0012ddf Update dmax functors interface.
9cfcb85 Various fixes in Scribo.
59dd554 scribo/text/extract_lines_wo_merge.hh: New line extraction routine.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 12 +-
configure.ac | 2 +
milena/ChangeLog | 4 +
milena/mln/accu/stat/median_h.hh | 19 +-
scribo/ChangeLog | 144 +++
scribo/headers.mk | 13 +
scribo/scribo/core/component_features_data.hh | 68 ++
scribo/scribo/core/component_info.hh | 40 +-
scribo/scribo/core/component_set.hh | 21 +-
scribo/scribo/core/def/color_type.hh | 48 +
scribo/scribo/core/line_info.hh | 174 +++-
scribo/scribo/core/line_set.hh | 17 +
scribo/scribo/core/object_groups.hh | 14 +-
scribo/scribo/core/object_links.hh | 11 +
scribo/scribo/core/paragraph_info.hh | 102 ++-
scribo/scribo/core/paragraph_set.hh | 11 +
scribo/scribo/debug/links_image.hh | 9 +-
scribo/scribo/debug/text_color_image.hh | 100 ++
scribo/scribo/estim/components_features.hh | 169 +++
scribo/scribo/estim/font_boldness.hh | 215 ++++
scribo/scribo/estim/font_color.hh | 206 ++++
scribo/scribo/estim/internal/compute_skeleton.hh | 112 ++
scribo/scribo/filter/object_groups_small.hh | 30 +-
scribo/scribo/filter/objects_h_thick.hh | 42 +-
scribo/scribo/filter/objects_h_thin.hh | 6 +-
scribo/scribo/filter/objects_v_thick.hh | 42 +-
scribo/scribo/filter/objects_v_thin.hh | 6 +-
.../io/xml/internal/extended_page_xml_visitor.hh | 9 +-
scribo/scribo/io/xml/internal/full_xml_visitor.hh | 33 +-
scribo/scribo/preprocessing/rotate_90.hh | 2 +
scribo/scribo/primitive/extract/alignments.hh | 1106 ++++++++++++++++++++
scribo/scribo/primitive/extract/components.hh | 70 +-
scribo/scribo/primitive/extract/non_text.hh | 2 -
.../scribo/primitive/link/internal/dmax_default.hh | 16 +-
.../primitive/link/internal/dmax_functor_base.hh | 13 +-
.../scribo/primitive/link/internal/dmax_hrules.hh | 100 ++
.../link/internal/dmax_width_and_height.hh | 11 +-
.../primitive/link/internal/dmax_width_only.hh | 7 +-
.../primitive/link/internal/link_functor_base.hh | 7 +-
.../link_single_dmax_ratio_aligned_base.hh | 5 -
.../link_single_dmax_ratio_aligned_delta_base.hh | 159 +++
.../link/internal/link_single_dmax_ratio_base.hh | 3 +-
.../link/merge_double_link_closest_aligned.hh | 157 +++
scribo/scribo/text/extract_lines.hh | 30 +-
scribo/scribo/text/extract_lines_with_features.hh | 131 +++
scribo/scribo/text/extract_lines_wo_merge.hh | 189 ++++
scribo/scribo/toolchain/content_in_doc.hh | 4 +-
.../toolchain/internal/content_in_doc_functor.hh | 3 +-
scribo/src/debug/Makefile.am | 16 +
scribo/src/debug/show_components_boldness.cc | 72 ++
scribo/src/debug/show_components_color.cc | 73 ++
scribo/src/debug/show_groups_bboxes.cc | 16 +-
scribo/src/debug/show_lines_boldness.cc | 199 ++++
scribo/src/preprocessing/denoise_fg.cc | 6 +-
scribo/src/primitive/extract/Makefile.am | 11 +
scribo/src/primitive/extract/alignments.cc | 89 ++
scribo/tests/Makefile.am | 5 +-
scribo/tests/data.hh.in | 6 +-
scribo/tests/estim/Makefile.am | 29 +
scribo/tests/estim/font_boldness.cc | 46 +
scribo/tests/estim/font_color.cc | 48 +
scribo/tests/img/alignment_1.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_2.png | Bin 0 -> 3147 bytes
scribo/tests/img/alignment_3.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_4.png | Bin 0 -> 3155 bytes
scribo/tests/img/phillip.pbm | Bin 0 -> 1633 bytes
scribo/tests/img/phillip.ppm | 5 +
scribo/tests/primitive/Makefile.am | 4 +-
scribo/tests/primitive/extract/Makefile.am | 33 +
scribo/tests/primitive/extract/alignment_1.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_2.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_3.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_4.ref.pbm | 5 +
scribo/tests/primitive/extract/alignments.cc | 76 ++
scribo/tests/toolchain/nepomuk/Makefile.am | 2 +
scribo/tests/unit_test/unit-tests.mk | 24 +
76 files changed, 4314 insertions(+), 160 deletions(-)
create mode 100644 scribo/scribo/core/component_features_data.hh
create mode 100644 scribo/scribo/core/def/color_type.hh
create mode 100644 scribo/scribo/debug/text_color_image.hh
create mode 100644 scribo/scribo/estim/components_features.hh
create mode 100644 scribo/scribo/estim/font_boldness.hh
create mode 100644 scribo/scribo/estim/font_color.hh
create mode 100644 scribo/scribo/estim/internal/compute_skeleton.hh
create mode 100644 scribo/scribo/primitive/extract/alignments.hh
create mode 100644 scribo/scribo/primitive/link/internal/dmax_hrules.hh
create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
create mode 100644 scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
create mode 100644 scribo/scribo/text/extract_lines_with_features.hh
create mode 100644 scribo/scribo/text/extract_lines_wo_merge.hh
create mode 100644 scribo/src/debug/show_components_boldness.cc
create mode 100644 scribo/src/debug/show_components_color.cc
create mode 100644 scribo/src/debug/show_lines_boldness.cc
create mode 100644 scribo/src/primitive/extract/alignments.cc
create mode 100644 scribo/tests/estim/Makefile.am
create mode 100644 scribo/tests/estim/font_boldness.cc
create mode 100644 scribo/tests/estim/font_color.cc
create mode 100644 scribo/tests/img/alignment_1.png
create mode 100644 scribo/tests/img/alignment_2.png
create mode 100644 scribo/tests/img/alignment_3.png
create mode 100644 scribo/tests/img/alignment_4.png
create mode 100644 scribo/tests/img/phillip.pbm
create mode 100644 scribo/tests/img/phillip.ppm
create mode 100644 scribo/tests/primitive/extract/Makefile.am
create mode 100644 scribo/tests/primitive/extract/alignment_1.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_2.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_3.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_4.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignments.cc
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* headers.mk,
* tests/unit_test/unit-tests.mk: Regen.
---
scribo/ChangeLog | 7 +++++++
scribo/headers.mk | 13 +++++++++++++
scribo/tests/unit_test/unit-tests.mk | 24 ++++++++++++++++++++++++
3 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 2fc8d6d..fa834fa 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,12 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Regen generated files.
+
+ * headers.mk,
+ * tests/unit_test/unit-tests.mk: Regen.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Compute font and boldness data.
* scribo/core/component_features_data.hh,
diff --git a/scribo/headers.mk b/scribo/headers.mk
index ebe14ee..47b4bdd 100644
--- a/scribo/headers.mk
+++ b/scribo/headers.mk
@@ -19,12 +19,14 @@ scribo/convert/from_qimage.hh \
scribo/convert/to_base64.hh \
scribo/core/all.hh \
scribo/core/central_sites.hh \
+scribo/core/component_features_data.hh \
scribo/core/component_info.hh \
scribo/core/component_set.hh \
scribo/core/concept/dmax_functor.hh \
scribo/core/concept/link_functor.hh \
scribo/core/concept/serializable.hh \
scribo/core/concept/serialize_visitor.hh \
+scribo/core/def/color_type.hh \
scribo/core/def/lbl_type.hh \
scribo/core/document.hh \
scribo/core/erase_objects.hh \
@@ -59,11 +61,16 @@ scribo/debug/save_comp_diff.hh \
scribo/debug/save_label_image.hh \
scribo/debug/save_table_image.hh \
scribo/debug/text_areas_image.hh \
+scribo/debug/text_color_image.hh \
scribo/debug/usage.hh \
scribo/draw/all.hh \
scribo/draw/bounding_box_links.hh \
scribo/draw/bounding_boxes.hh \
scribo/draw/groups_bboxes.hh \
+scribo/estim/components_features.hh \
+scribo/estim/font_boldness.hh \
+scribo/estim/font_color.hh \
+scribo/estim/internal/compute_skeleton.hh \
scribo/estim/object_groups_v_thickness.hh \
scribo/filter/all.hh \
scribo/filter/common/objects_photo.hh \
@@ -134,6 +141,7 @@ scribo/preprocessing/homogeneous_contrast.hh \
scribo/preprocessing/rotate_90.hh \
scribo/preprocessing/split_bg_fg.hh \
scribo/primitive/all.hh \
+scribo/primitive/extract/alignments.hh \
scribo/primitive/extract/all.hh \
scribo/primitive/extract/canvas.hh \
scribo/primitive/extract/cells.hh \
@@ -178,6 +186,7 @@ scribo/primitive/link/compute_several.hh \
scribo/primitive/link/internal/compute_anchor.hh \
scribo/primitive/link/internal/dmax_default.hh \
scribo/primitive/link/internal/dmax_functor_base.hh \
+scribo/primitive/link/internal/dmax_hrules.hh \
scribo/primitive/link/internal/dmax_width_and_height.hh \
scribo/primitive/link/internal/dmax_width_only.hh \
scribo/primitive/link/internal/find_link.hh \
@@ -186,8 +195,10 @@ scribo/primitive/link/internal/link_functor_base.hh \
scribo/primitive/link/internal/link_several_dmax_base.hh \
scribo/primitive/link/internal/link_single_dmax_base.hh \
scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh \
+scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh \
scribo/primitive/link/internal/link_single_dmax_ratio_base.hh \
scribo/primitive/link/merge_double_link.hh \
+scribo/primitive/link/merge_double_link_closest_aligned.hh \
scribo/primitive/link/with_graph.hh \
scribo/primitive/link/with_rag.hh \
scribo/primitive/link/with_several_graphes.hh \
@@ -230,6 +241,8 @@ scribo/text/all.hh \
scribo/text/clean.hh \
scribo/text/clean_inplace.hh \
scribo/text/extract_lines.hh \
+scribo/text/extract_lines_with_features.hh \
+scribo/text/extract_lines_wo_merge.hh \
scribo/text/link_lines.hh \
scribo/text/look_like_text_lines.hh \
scribo/text/merging.hh \
diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk
index 3785fab..c654084 100644
--- a/scribo/tests/unit_test/unit-tests.mk
+++ b/scribo/tests/unit_test/unit-tests.mk
@@ -106,12 +106,14 @@ scribo_canvas_integral_browsing \
scribo_convert_to_base64 \
scribo_core_all \
scribo_core_central_sites \
+scribo_core_component_features_data \
scribo_core_component_info \
scribo_core_component_set \
scribo_core_concept_dmax_functor \
scribo_core_concept_link_functor \
scribo_core_concept_serializable \
scribo_core_concept_serialize_visitor \
+scribo_core_def_color_type \
scribo_core_def_lbl_type \
scribo_core_document \
scribo_core_erase_objects \
@@ -146,12 +148,16 @@ scribo_debug_save_comp_diff \
scribo_debug_save_label_image \
scribo_debug_save_table_image \
scribo_debug_text_areas_image \
+scribo_debug_text_color_image \
scribo_debug_usage \
scribo_draw_all \
scribo_draw_bounding_box_links \
scribo_draw_bounding_boxes \
scribo_draw_groups_bboxes \
+scribo_estim_components_features \
+scribo_estim_font_boldness \
scribo_estim_font_color \
+scribo_estim_internal_compute_skeleton \
scribo_estim_object_groups_v_thickness \
scribo_filter_all \
scribo_filter_common_objects_photo \
@@ -220,6 +226,7 @@ scribo_preprocessing_homogeneous_contrast \
scribo_preprocessing_rotate_90 \
scribo_preprocessing_split_bg_fg \
scribo_primitive_all \
+scribo_primitive_extract_alignments \
scribo_primitive_extract_all \
scribo_primitive_extract_canvas \
scribo_primitive_extract_cells \
@@ -263,6 +270,7 @@ scribo_primitive_link_compute \
scribo_primitive_link_internal_compute_anchor \
scribo_primitive_link_internal_dmax_default \
scribo_primitive_link_internal_dmax_functor_base \
+scribo_primitive_link_internal_dmax_hrules \
scribo_primitive_link_internal_dmax_width_and_height \
scribo_primitive_link_internal_dmax_width_only \
scribo_primitive_link_internal_find_link \
@@ -270,8 +278,10 @@ scribo_primitive_link_internal_link_functor_base \
scribo_primitive_link_internal_link_several_dmax_base \
scribo_primitive_link_internal_link_single_dmax_base \
scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base \
+scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base \
scribo_primitive_link_internal_link_single_dmax_ratio_base \
scribo_primitive_link_merge_double_link \
+scribo_primitive_link_merge_double_link_closest_aligned \
scribo_primitive_link_with_graph \
scribo_primitive_link_with_rag \
scribo_primitive_link_with_several_graphes \
@@ -312,6 +322,8 @@ scribo_text_all \
scribo_text_clean \
scribo_text_clean_inplace \
scribo_text_extract_lines \
+scribo_text_extract_lines_with_features \
+scribo_text_extract_lines_wo_merge \
scribo_text_link_lines \
scribo_text_look_like_text_lines \
scribo_text_merging \
@@ -338,12 +350,14 @@ scribo_canvas_integral_browsing_SOURCES = scribo_canvas_integral_browsing.cc
scribo_convert_to_base64_SOURCES = scribo_convert_to_base64.cc
scribo_core_all_SOURCES = scribo_core_all.cc
scribo_core_central_sites_SOURCES = scribo_core_central_sites.cc
+scribo_core_component_features_data_SOURCES = scribo_core_component_features_data.cc
scribo_core_component_info_SOURCES = scribo_core_component_info.cc
scribo_core_component_set_SOURCES = scribo_core_component_set.cc
scribo_core_concept_dmax_functor_SOURCES = scribo_core_concept_dmax_functor.cc
scribo_core_concept_link_functor_SOURCES = scribo_core_concept_link_functor.cc
scribo_core_concept_serializable_SOURCES = scribo_core_concept_serializable.cc
scribo_core_concept_serialize_visitor_SOURCES = scribo_core_concept_serialize_visitor.cc
+scribo_core_def_color_type_SOURCES = scribo_core_def_color_type.cc
scribo_core_def_lbl_type_SOURCES = scribo_core_def_lbl_type.cc
scribo_core_document_SOURCES = scribo_core_document.cc
scribo_core_erase_objects_SOURCES = scribo_core_erase_objects.cc
@@ -378,12 +392,16 @@ scribo_debug_save_comp_diff_SOURCES = scribo_debug_save_comp_diff.cc
scribo_debug_save_label_image_SOURCES = scribo_debug_save_label_image.cc
scribo_debug_save_table_image_SOURCES = scribo_debug_save_table_image.cc
scribo_debug_text_areas_image_SOURCES = scribo_debug_text_areas_image.cc
+scribo_debug_text_color_image_SOURCES = scribo_debug_text_color_image.cc
scribo_debug_usage_SOURCES = scribo_debug_usage.cc
scribo_draw_all_SOURCES = scribo_draw_all.cc
scribo_draw_bounding_box_links_SOURCES = scribo_draw_bounding_box_links.cc
scribo_draw_bounding_boxes_SOURCES = scribo_draw_bounding_boxes.cc
scribo_draw_groups_bboxes_SOURCES = scribo_draw_groups_bboxes.cc
+scribo_estim_components_features_SOURCES = scribo_estim_components_features.cc
+scribo_estim_font_boldness_SOURCES = scribo_estim_font_boldness.cc
scribo_estim_font_color_SOURCES = scribo_estim_font_color.cc
+scribo_estim_internal_compute_skeleton_SOURCES = scribo_estim_internal_compute_skeleton.cc
scribo_estim_object_groups_v_thickness_SOURCES = scribo_estim_object_groups_v_thickness.cc
scribo_filter_all_SOURCES = scribo_filter_all.cc
scribo_filter_common_objects_photo_SOURCES = scribo_filter_common_objects_photo.cc
@@ -452,6 +470,7 @@ scribo_preprocessing_homogeneous_contrast_SOURCES = scribo_preprocessing_homogen
scribo_preprocessing_rotate_90_SOURCES = scribo_preprocessing_rotate_90.cc
scribo_preprocessing_split_bg_fg_SOURCES = scribo_preprocessing_split_bg_fg.cc
scribo_primitive_all_SOURCES = scribo_primitive_all.cc
+scribo_primitive_extract_alignments_SOURCES = scribo_primitive_extract_alignments.cc
scribo_primitive_extract_all_SOURCES = scribo_primitive_extract_all.cc
scribo_primitive_extract_canvas_SOURCES = scribo_primitive_extract_canvas.cc
scribo_primitive_extract_cells_SOURCES = scribo_primitive_extract_cells.cc
@@ -495,6 +514,7 @@ scribo_primitive_link_compute_SOURCES = scribo_primitive_link_compute.cc
scribo_primitive_link_internal_compute_anchor_SOURCES = scribo_primitive_link_internal_compute_anchor.cc
scribo_primitive_link_internal_dmax_default_SOURCES = scribo_primitive_link_internal_dmax_default.cc
scribo_primitive_link_internal_dmax_functor_base_SOURCES = scribo_primitive_link_internal_dmax_functor_base.cc
+scribo_primitive_link_internal_dmax_hrules_SOURCES = scribo_primitive_link_internal_dmax_hrules.cc
scribo_primitive_link_internal_dmax_width_and_height_SOURCES = scribo_primitive_link_internal_dmax_width_and_height.cc
scribo_primitive_link_internal_dmax_width_only_SOURCES = scribo_primitive_link_internal_dmax_width_only.cc
scribo_primitive_link_internal_find_link_SOURCES = scribo_primitive_link_internal_find_link.cc
@@ -502,8 +522,10 @@ scribo_primitive_link_internal_link_functor_base_SOURCES = scribo_primitive_link
scribo_primitive_link_internal_link_several_dmax_base_SOURCES = scribo_primitive_link_internal_link_several_dmax_base.cc
scribo_primitive_link_internal_link_single_dmax_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_base.cc
scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base.cc
+scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base.cc
scribo_primitive_link_internal_link_single_dmax_ratio_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_base.cc
scribo_primitive_link_merge_double_link_SOURCES = scribo_primitive_link_merge_double_link.cc
+scribo_primitive_link_merge_double_link_closest_aligned_SOURCES = scribo_primitive_link_merge_double_link_closest_aligned.cc
scribo_primitive_link_with_graph_SOURCES = scribo_primitive_link_with_graph.cc
scribo_primitive_link_with_rag_SOURCES = scribo_primitive_link_with_rag.cc
scribo_primitive_link_with_several_graphes_SOURCES = scribo_primitive_link_with_several_graphes.cc
@@ -544,6 +566,8 @@ scribo_text_all_SOURCES = scribo_text_all.cc
scribo_text_clean_SOURCES = scribo_text_clean.cc
scribo_text_clean_inplace_SOURCES = scribo_text_clean_inplace.cc
scribo_text_extract_lines_SOURCES = scribo_text_extract_lines.cc
+scribo_text_extract_lines_with_features_SOURCES = scribo_text_extract_lines_with_features.cc
+scribo_text_extract_lines_wo_merge_SOURCES = scribo_text_extract_lines_wo_merge.cc
scribo_text_link_lines_SOURCES = scribo_text_link_lines.cc
scribo_text_look_like_text_lines_SOURCES = scribo_text_look_like_text_lines.cc
scribo_text_merging_SOURCES = scribo_text_merging.cc
--
1.5.6.5
1
0

last-svn-commit-832-gb8e866e Add a new alignments extraction routine.
by Guillaume Lazzara 05 Apr '11
by Guillaume Lazzara 05 Apr '11
05 Apr '11
* scribo/primitive/extract/alignments.hh,
* scribo/primitive/link/internal/dmax_hrules.hh,
* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh,
* scribo/primitive/link/merge_double_link_closest_aligned.hh: New.
* src/primitive/extract/alignments.cc: New example.
* tests/data.hh.in: Add a new macro.
* tests/img/alignment_1.png,
* tests/img/alignment_2.png,
* tests/img/alignment_3.png,
* tests/img/alignment_4.png,
* tests/primitive/extract/alignment_1.ref.pbm,
* tests/primitive/extract/alignment_2.ref.pbm,
* tests/primitive/extract/alignment_3.ref.pbm,
* tests/primitive/extract/alignment_4.ref.pbm: New auxiliary data
for tests.
* src/primitive/extract/Makefile.am,
* tests/primitive/Makefile.am,
* tests/primitive/extract/Makefile.am: Add new targets.
* tests/primitive/extract/alignments.cc: New test.
---
scribo/ChangeLog | 29 +
scribo/scribo/primitive/extract/alignments.hh | 1106 ++++++++++++++++++++
.../scribo/primitive/link/internal/dmax_hrules.hh | 100 ++
.../link_single_dmax_ratio_aligned_delta_base.hh | 159 +++
.../link/merge_double_link_closest_aligned.hh | 157 +++
scribo/src/primitive/extract/Makefile.am | 11 +
scribo/src/primitive/extract/alignments.cc | 89 ++
scribo/tests/data.hh.in | 6 +-
scribo/tests/img/alignment_1.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_2.png | Bin 0 -> 3147 bytes
scribo/tests/img/alignment_3.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_4.png | Bin 0 -> 3155 bytes
scribo/tests/primitive/Makefile.am | 4 +-
scribo/tests/primitive/extract/Makefile.am | 33 +
scribo/tests/primitive/extract/alignment_1.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_2.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_3.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_4.ref.pbm | 5 +
scribo/tests/primitive/extract/alignments.cc | 76 ++
19 files changed, 1788 insertions(+), 2 deletions(-)
create mode 100644 scribo/scribo/primitive/extract/alignments.hh
create mode 100644 scribo/scribo/primitive/link/internal/dmax_hrules.hh
create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
create mode 100644 scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
create mode 100644 scribo/src/primitive/extract/alignments.cc
create mode 100644 scribo/tests/img/alignment_1.png
create mode 100644 scribo/tests/img/alignment_2.png
create mode 100644 scribo/tests/img/alignment_3.png
create mode 100644 scribo/tests/img/alignment_4.png
create mode 100644 scribo/tests/primitive/extract/Makefile.am
create mode 100644 scribo/tests/primitive/extract/alignment_1.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_2.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_3.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_4.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignments.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 8acfc4e..4592e73 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,34 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a new alignments extraction routine.
+
+ * scribo/primitive/extract/alignments.hh,
+ * scribo/primitive/link/internal/dmax_hrules.hh,
+ * scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh,
+ * scribo/primitive/link/merge_double_link_closest_aligned.hh: New.
+
+ * src/primitive/extract/alignments.cc: New example.
+
+ * tests/data.hh.in: Add a new macro.
+
+ * tests/img/alignment_1.png,
+ * tests/img/alignment_2.png,
+ * tests/img/alignment_3.png,
+ * tests/img/alignment_4.png,
+ * tests/primitive/extract/alignment_1.ref.pbm,
+ * tests/primitive/extract/alignment_2.ref.pbm,
+ * tests/primitive/extract/alignment_3.ref.pbm,
+ * tests/primitive/extract/alignment_4.ref.pbm: New auxiliary data
+ for tests.
+
+ * src/primitive/extract/Makefile.am,
+ * tests/primitive/Makefile.am,
+ * tests/primitive/extract/Makefile.am: Add new targets.
+
+ * tests/primitive/extract/alignments.cc: New test.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update dmax functors interface.
* scribo/primitive/link/internal/dmax_default.hh,
diff --git a/scribo/scribo/primitive/extract/alignments.hh b/scribo/scribo/primitive/extract/alignments.hh
new file mode 100644
index 0000000..5314683
--- /dev/null
+++ b/scribo/scribo/primitive/extract/alignments.hh
@@ -0,0 +1,1106 @@
+// 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_EXTRACT_ALIGNMENTS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_ALIGNMENTS_HH
+
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/data/convert.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/int_u.hh>
+#include <mln/literal/colors.hh>
+
+#include <mln/util/array.hh>
+#include <mln/util/couple.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/labeling/colorize.hh>
+
+#include <mln/util/couple.hh>
+
+#include <scribo/core/def/lbl_type.hh>
+#include <scribo/primitive/extract/components.hh>
+#include <scribo/filter/object_links_aligned.hh>
+#include <scribo/filter/object_groups_small.hh>
+#include <scribo/preprocessing/denoise_fg.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/link/internal/link_single_dmax_ratio_aligned_delta_base.hh>
+#include <scribo/primitive/link/internal/dmax_default.hh>
+#include <scribo/primitive/link/internal/dmax_hrules.hh>
+#include <scribo/primitive/link/merge_double_link_closest_aligned.hh>
+
+#include <scribo/debug/usage.hh>
+#include <scribo/debug/links_image.hh>
+
+
+#include <scribo/core/document.hh>
+#include <scribo/core/component_set.hh>
+#include <scribo/core/line_set.hh>
+#include <scribo/primitive/extract/components.hh>
+#include <scribo/primitive/group/from_single_link.hh>
+#include <scribo/primitive/group/apply.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
+#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
+#include <scribo/primitive/link/merge_double_link.hh>
+#include <scribo/primitive/link/internal/dmax_width_and_height.hh>
+
+#include <scribo/preprocessing/rotate_90.hh>
+#include <scribo/filter/object_links_bbox_h_ratio.hh>
+
+# include <scribo/primitive/extract/separators.hh>
+# include <scribo/primitive/extract/vertical_separators.hh>
+# include <scribo/primitive/extract/horizontal_separators.hh>
+# include <scribo/primitive/extract/separators_nonvisible.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace extract
+ {
+
+ /*! \brief Find page delimitors from tabstops and whitespaces.
+
+ \pre Separators should be removed from input document image .
+
+ \pre Text in \p doc must be constructed from Components
+ grouped by lines with a very strict criterion in order to keep
+ spaces between words and paragraphs. This first grouping is
+ necessary to avoid false positive (e.g. inside the text
+ blocks).
+
+ \pre \p doc must have text (has_text() returns true).
+
+
+ Internal description :
+ ----------------------
+
+ 1) Build an image of line bboxes
+ 2) For TOP and BOTTOM
+ 2.a) Link bboxes. Links are validated only if :
+ - Alignment difference is less than \p delta_pixel.
+ - Bboxes are not too far
+ - No component is located at 5 pixels along the aligned side.
+ 2.b) Invalidates groups if there are less than 3 links
+ 2.c) Invalidates groups if a component is located at a specific
+ distance from the aligned side.
+
+ This method handles skewed alignments and draw skew lines if
+ possible. Examples :
+
+ |x |x
+ | x \x
+ | x -> \x
+ | x \x
+
+
+ \fixme Because the first link step at step 2.a check aligment
+ between only 2 components and not the whole group, we may
+ retrieve alignment patterns such this one :
+
+ |x
+ | x
+ | x
+ | x
+ |x
+
+ Here, the 'x' are aligned pair by pair but globally they are
+ not. Here we cannot draw skewed lines without processing every
+ links and look for that pattern. More over, in step 2.c
+ alignment is validated by looking for other components in the
+ supposed "whitespace area" from the aligned side. With such an
+ alignment there are more chances that a component intersect
+ with that line. Here, we would like to split links/alignement
+ in two groups in order to get something like that :
+
+ \x
+ \x
+ \x
+ /x
+ /x
+
+
+
+ \param[in] doc A document information with text lines.
+
+ \param[in] dmax_ratio The ratio used to compute the maximum
+ lookup distance while linking up components.
+
+ \param[in] delta_pixel The maximum number of pixels allowed
+ for alignment delta precision.
+
+ */
+ template <typename L>
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ alignments(const document<L>& doc,
+ float dmax_ratio, unsigned delta_pixel);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::extract
+
+ } // end of namespace scribo::primitive
+
+
+
+
+ namespace internal
+ {
+
+ template <typename V>
+ point2d
+ point_row_adjust(const point2d& pi, const image2d<V>& ima)
+ {
+ if (ima.domain().has(pi))
+ return pi;
+
+ point2d po = pi;
+
+ if (po.row() < ima.domain().pmin().row())
+ while (!ima.domain().has(po))
+ ++po.row();
+ else
+ while (!ima.domain().has(po))
+ --po.row();
+
+ return po;
+ }
+
+ template <typename V>
+ point2d
+ point_col_adjust(const point2d& pi, const image2d<V>& ima)
+ {
+ if (ima.domain().has(pi))
+ return pi;
+
+ point2d po = pi;
+
+ if (po.col() < ima.domain().pmin().col())
+ while (!ima.domain().has(po))
+ ++po.col();
+ else
+ while (!ima.domain().has(po))
+ --po.col();
+
+ return po;
+ }
+
+ } // end of namespace scribo::internal
+
+
+
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ template <typename L, typename F>
+ class single_right_dmax_ratio_aligned_delta_functor
+ : public link_single_dmax_ratio_aligned_delta_base<L, F, single_right_dmax_ratio_aligned_delta_functor<L,F> >
+ {
+ typedef single_right_dmax_ratio_aligned_delta_functor<L,F> self_t;
+ typedef link_single_dmax_ratio_aligned_delta_base<L, F, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_dmax_ratio_aligned_delta_functor(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ unsigned delta,
+ anchor::Direction delta_direction,
+ const L& bbox_ima,
+ unsigned delta_ws_lookup)
+ : super_(components, dmax_f, delta, delta_direction),
+ bbox_ima_(bbox_ima), delta_ws_lookup_(delta_ws_lookup)
+ {
+ debug_ = data::convert(value::rgb8(), data::convert(bool(), bbox_ima));
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+
+ 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;
+
+ mln_value(L) nbh = this->labeled_image_(p);
+
+ switch(anchor)
+ {
+ // Top
+ case anchor::StrictTopCenter:
+ {
+ point2d p(std::min(this->components_(current_object).bbox().pmin().row(),
+ this->components_(nbh).bbox().pmin().row()) - delta_ws_lookup_,
+ this->components_(current_object).bbox().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() <= this->components_(nbh).bbox().pmax().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ ++p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ // Bottom
+ case anchor::StrictBottomCenter:
+ {
+ point2d p(std::max(this->components_(current_object).bbox().pmax().row(),
+ this->components_(nbh).bbox().pmax().row()) + delta_ws_lookup_,
+ this->components_(current_object).bbox().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() <= this->components_(nbh).bbox().pmax().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ ++p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ default:
+ trace::warning("anchor not handled!");
+ }
+
+ return false;
+ }
+
+
+ L bbox_ima_;
+ unsigned delta_ws_lookup_;
+
+ image2d<value::rgb8> debug_;
+ };
+
+
+ template <typename L, typename F>
+ class single_left_dmax_ratio_aligned_delta_functor
+ : public link_single_dmax_ratio_aligned_delta_base<L, F, single_left_dmax_ratio_aligned_delta_functor<L,F> >
+ {
+ typedef single_left_dmax_ratio_aligned_delta_functor<L,F> self_t;
+ typedef link_single_dmax_ratio_aligned_delta_base<L, F, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_dmax_ratio_aligned_delta_functor(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ unsigned delta,
+ anchor::Direction delta_direction,
+ const L& bbox_ima,
+ unsigned delta_ws_lookup)
+ : super_(components, dmax_f, delta, delta_direction),
+ bbox_ima_(bbox_ima), delta_ws_lookup_(delta_ws_lookup)
+ {
+ debug_ = data::convert(value::rgb8(), data::convert(bool(), bbox_ima));
+ }
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+
+ 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;
+
+ mln_value(L) nbh = this->labeled_image_(p);
+
+ switch (anchor)
+ {
+
+ // Top
+ case anchor::StrictTopCenter:
+ {
+ point2d p(std::min(this->components_(nbh).bbox().pmin().row(),
+ this->components_(current_object).bbox().pmin().row()) - delta_ws_lookup_,
+ this->components_(current_object).bbox().pmax().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() > this->components_(nbh).bbox().pmin().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ --p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ // Bottom
+ case anchor::StrictBottomCenter:
+ {
+ point2d p(std::max(this->components_(nbh).bbox().pmax().row(),
+ this->components_(current_object).bbox().pmax().row()) + delta_ws_lookup_,
+ this->components_(current_object).bbox().pmax().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() > this->components_(nbh).bbox().pmin().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ --p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ default:
+ trace::warning("anchor not handled!");
+ }
+
+ return false;
+ }
+
+
+ L bbox_ima_;
+ unsigned delta_ws_lookup_;
+
+ image2d<value::rgb8> debug_;
+ };
+
+
+ } // end of namespace scribo::primitive::link::internal
+
+ } // end of namespace scribo::primitive::link
+
+
+ namespace extract
+ {
+
+ namespace internal
+ {
+
+ template <typename L>
+ bool pass_comp_criterion(const line_info<L>& line)
+ {
+ return line.bbox().height() < 301;// (line.pixel_area() < 10000);
+ }
+
+
+
+ bool
+ is_valid_left_right_skewed_delimitor(const box2d& brot,
+ const image2d<bool> input,
+ unsigned local_delta)
+ {
+ if (brot.pmax().col() - brot.pmin().col() > 6)
+ {
+ point2d
+ p1 = brot.pmin(),
+ p2 = brot.pmax();
+
+ // Handle left to right alignment
+ p1.col() -= local_delta;
+ p2.col() -= local_delta;
+ p_line2d l2d(p1, p2);
+ mln_piter_(p_line2d) p(l2d);
+ for_all(p)
+ if (input(p))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool
+ is_valid_right_left_skewed_delimitor(const box2d& brot,
+ const image2d<bool> input,
+ unsigned local_delta)
+ {
+ if (brot.pmax().col() - brot.pmin().col() > 6)
+ {
+ point2d
+ p1 = brot.pmin(),
+ p2 = brot.pmax();
+
+ // Handle right to left alignment
+ p1.col() = brot.pmax().col() - local_delta;
+ p2.col() = brot.pmin().col() - local_delta;
+ p_line2d l2d(p1, p2);
+ mln_piter_(p_line2d) p(l2d);
+ for_all(p)
+ if (input(p))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ box2d fast_rotate_positive(const box2d& box, const box2d& rbox)
+ {
+ box2d b(point2d(box.pmin().col(),
+ rbox.ncols() - box.pmin().row() - 1),
+ point2d(box.pmax().col(),
+ rbox.ncols() - box.pmax().row() - 1));
+ return b;
+ }
+
+ box2d fast_rotate_negative(const box2d& box, const box2d& rbox)
+ {
+ // std::cout << point2d(rbox.ncols() - box.pmin().col() - 1,
+ // box.pmin().row())
+ // << " - "
+ // << point2d(rbox.ncols() - box.pmax().col() - 1,
+ // box.pmax().row()) << std::endl;
+
+ // std::cout << box << " - " << rbox << std::endl;
+
+ // box2d b(point2d(rbox.ncols() - box.pmin().col() - 1,
+ // box.pmin().row()),
+ // point2d(rbox.ncols() - box.pmax().col() - 1,
+ // box.pmax().row()));
+
+ mln::def::coord max_row = rbox.ncols() - box.pmin().col() - 1;
+ mln::def::coord min_row = rbox.ncols() - box.pmax().col() - 1;
+// if (min_row > max_row)
+ //std::swap(min_row, max_row);
+
+ box2d b(point2d(min_row,
+ box.pmin().row()),
+ point2d(max_row,
+ box.pmax().row()));
+
+ return b;
+ }
+
+ } // end of namespace scribo::primitive::extract
+
+
+ /////////////
+ // FACADES //
+ /////////////
+
+
+ template <typename L>
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ alignments(const document<L>& doc,
+ float dmax_ratio, unsigned delta_pixel)
+ {
+ trace::entering("scribo::primitive::extract::alignments");
+ mln_precondition(doc.is_valid());
+ mln_precondition(doc.has_text());
+ const mln_ch_value(L,bool)& input = doc.binary_image();
+
+ unsigned min_card = 3;
+ unsigned delta = 5;
+
+ // 0. Get low level structures in document data.
+ typedef mln_value(L) V;
+ const object_groups<L>& groups = doc.paragraphs().lines().groups();
+ const line_set<L>& lines = doc.lines();
+
+
+ // 1. Construct an image of group bounding boxes.
+ //
+ // This image is used later to group bounding boxes. It is
+ // rotated in order to make grouping faster (linear memory
+ // reading).
+ //
+ box2d rbbox = box2d(input.domain().pmin(),
+ point2d(input.domain().pmax().col(),
+ input.domain().pmax().row()));
+
+ L bbox_ima(rbbox);
+ data::fill(bbox_ima, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_valid()
+ && internal::pass_comp_criterion(lines(l)))
+ mln::draw::box(bbox_ima,
+ internal::fast_rotate_positive(lines(l).bbox(),
+ rbbox),
+ lines(l).id().value());
+
+
+ // Compute component information
+ //
+ // FIXME: not useful since we have all required information
+ // in the line_set. However a component_set is needed in link
+ // functors...
+ component_set<L>
+ components = component_set<L>(bbox_ima, lines.nelements());
+
+
+ // Dmax functor used for TOP and BOTTOM links.
+ primitive::link::internal::dmax_hrules dmax_func(dmax_ratio, 100);
+
+
+ // Output image
+ image2d<bool> delimitors;
+ initialize(delimitors, input);
+ data::fill(delimitors, false);
+
+# ifndef SCRIBO_NDEBUG
+ image2d<value::rgb8> debug;
+ initialize(debug, components.labeled_image());
+ data::fill(debug, literal::black);
+ scribo::draw::bounding_boxes(debug, components, literal::blue);
+# endif // ! SCRIBO_NDEBUG
+
+
+
+
+ // 2.1. BEGIN OF TOP LINKS PROCESSING
+ {
+ object_links<L> top_links;
+
+ object_groups<L>
+ top_groups,
+ old_top_groups;
+
+ util::array<unsigned> top_group_size;
+
+ typedef mln::accu::stat::median_h<value::int_u<12u> > median_t;
+ mln::util::array<median_t>
+ top_median_char_width,
+ top_median_char_space;
+
+ mln::util::array<unsigned> top_max_char_width;
+
+
+
+ // 2.1.1. Find TOP links.
+ {
+ object_links<L> right, left;
+
+ // link right
+ {
+ primitive::link::internal::single_right_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical, bbox_ima, delta);
+
+ right = primitive::link::compute(functor, anchor::StrictTopCenter);
+ }
+
+ // Link left
+ {
+ primitive::link::internal::single_left_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical, bbox_ima, delta);
+
+ left = primitive::link::compute(functor, anchor::StrictTopCenter);
+ }
+
+ // Merge links
+ top_links = primitive::link::merge_double_link_closest_aligned(left, right,
+ anchor::StrictTopCenter);
+
+ // Remove groups with not enough links.
+ old_top_groups = primitive::group::from_single_link(top_links);
+ top_groups = filter::object_groups_small(old_top_groups, min_card,
+ top_group_size);
+
+
+ // Compute char_width and char_space statistics.
+ //
+ // Here, we also compute max_char_width, in case other
+ // statistics are not significant enough for next steps.
+ //
+ // To avoid biased statistics, char_space and char_width are
+ // used from lines with at least 2 components.
+ //
+ top_median_char_space.resize(top_groups.nelements());
+ top_median_char_width.resize(top_groups.nelements());
+ top_max_char_width.resize(top_groups.nelements());
+
+ for_all_groups(g, top_groups)
+ if (top_groups.is_valid(g))
+ {
+ if (lines(g).card() > 1)
+ {
+ top_median_char_space(top_groups(g)).take(lines(g).char_space());
+ top_median_char_width(top_groups(g)).take(lines(g).char_width());
+ }
+ else if (top_max_char_width(top_groups(g)) < lines(g).char_width())
+ top_max_char_width(top_groups(g)) = lines(g).char_width();
+ }
+
+ }
+
+
+ // 2.1.2. Check TOP whitespaces
+ {
+ util::array<accu::shape::bbox<point2d> >
+ group_bbox(top_groups.nelements());
+
+ // Compute group bboxes
+ for_all_links(l, top_links)
+ if (top_links.is_valid(l))
+ {
+ point2d p = components(top_links(l)).bbox().pmax();
+ p.row() = components(top_links(l)).bbox().pmin().row();
+
+ if (top_groups.is_valid(l)
+ && top_group_size(old_top_groups(l)) > 2)
+ {
+ group_bbox(top_groups(l)).take(p);
+ group_bbox(top_groups(l)).take(components(l).bbox().pmin());
+
+# ifndef SCRIBO_NDEBUG
+ // Draw first component bbox.
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(top_links(l)).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+# endif // ! SCRIBO_NDEBUG
+ }
+
+# ifndef SCRIBO_NDEBUG
+ else if (top_group_size(old_top_groups(l)) > 1)
+ {
+ mln::draw::line(debug,
+ components(l).bbox().pmin(),
+ p,
+ literal::orange);
+
+ // Draw first component bbox.
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(top_links(l)).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ }
+# endif // ! SCRIBO_NDEBUG
+ }
+
+
+ // Looking for whitespaces (if needed)
+ for_all_elements(c, group_bbox)
+ if (group_bbox(c).to_result().is_valid())
+ {
+ unsigned ldelta = delta;
+ // Handle low connection groups.
+ if (top_group_size(c) >= 3 && top_group_size(c) < 5)
+ {
+ // Stats are not reliable, prefer using max char width.
+ if (top_median_char_width(c).card() == 0)
+ ldelta = top_max_char_width(c) * 2;
+ else
+ ldelta = 1.2 * top_median_char_width(c) + top_median_char_space(c);
+
+ point2d p(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima);
+
+ // Checking whitespace area
+ for (; p.col() <= group_bbox(c).to_result().pmax().col()
+ && (bbox_ima(p) == 0);)
+ ++p.col();
+
+ if (bbox_ima(p) != 0)
+ {
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::red);
+# endif // ! SCRIBO_NDEBUG
+
+ continue;
+ }
+ }
+
+
+ box2d
+ brot = internal::fast_rotate_negative(group_bbox(c).to_result(),
+ rbbox);
+
+ // Checking if the delimitor is skewed.
+ if (internal::is_valid_left_right_skewed_delimitor(brot, input,
+ delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmin().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() - delta), delimitors),
+ true);
+ }
+ else if (internal::is_valid_right_left_skewed_delimitor(brot, input,
+ delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmin().col() - delta), delimitors),
+ true);
+ }
+ else
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(point2d(brot.pmin().row(),
+ brot.pmin().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(point2d(brot.pmax().row(),
+ brot.pmin().col() - delta), delimitors),
+ true);
+ }
+
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::green);
+# endif // ! SCRIBO_NDEBUG
+
+ }
+ }
+
+ } // END OF TOP LINKS PROCESSING
+
+
+
+ // 2.2. BEGIN OF BOTTOM LINKS PROCESSING
+ {
+ object_links<L> bot_links;
+
+ object_groups<L>
+ bot_groups,
+ old_bot_groups;
+
+ util::array<unsigned> bot_group_size;
+
+ typedef mln::accu::stat::median_h<value::int_u<12u> > median_t;
+ mln::util::array<median_t>
+ bot_median_char_width,
+ bot_median_char_space;
+
+ mln::util::array<unsigned> bot_max_char_width;
+
+ // 2.2.1. Find BOTTOM links.
+ {
+ object_links<L> right, left;
+
+ // link right
+ {
+ primitive::link::internal::single_right_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical,
+ bbox_ima, delta);
+
+ right = primitive::link::compute(functor, anchor::StrictBottomCenter);
+ }
+
+ // Link left
+ {
+ primitive::link::internal::single_left_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical,
+ bbox_ima, delta);
+
+ left = primitive::link::compute(functor, anchor::StrictBottomCenter);
+ }
+
+ // Merge links
+ bot_links = primitive::link::merge_double_link_closest_aligned(left, right,
+ anchor::StrictBottomCenter);
+
+ // Remove groups with not enough links.
+ old_bot_groups = primitive::group::from_single_link(bot_links);
+ bot_groups = filter::object_groups_small(old_bot_groups, min_card,
+ bot_group_size);
+
+ bot_median_char_space.resize(bot_groups.nelements());
+ bot_median_char_width.resize(bot_groups.nelements());
+ bot_max_char_width.resize(bot_groups.nelements());
+
+ for_all_groups(g, bot_groups)
+ if (bot_groups.is_valid(g))
+ {
+ if (lines(g).card() > 1)
+ {
+ bot_median_char_space(bot_groups(g)).take(lines(g).char_space());
+ bot_median_char_width(bot_groups(g)).take(lines(g).char_width());
+ }
+ // This data will be used if alignments are made with single
+ // components only.
+ else if (bot_max_char_width(bot_groups(g)) < lines(g).char_width())
+ bot_max_char_width(bot_groups(g)) = lines(g).char_width();
+ }
+ }
+
+
+ // 2.2.2. Check BOTTOM whitespaces
+ {
+ util::array<accu::shape::bbox<point2d> >
+ group_bbox(bot_groups.nelements());
+
+ // Compute group bboxes
+ for_all_links(l, bot_links)
+ if (bot_links.is_valid(l))
+ {
+ point2d p = components(l).bbox().pmin();
+ p.row() = components(l).bbox().pmax().row();
+
+ if (bot_groups.is_valid(l)
+ && bot_group_size(old_bot_groups(l)) > 2)
+ {
+ group_bbox(bot_groups(l)).take(p);
+ group_bbox(bot_groups(l)).take(
+ components(bot_links(l)).bbox().pmax());
+
+# ifndef SCRIBO_NDEBUG
+ // Draw first component box
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[lines(l).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(bot_links(l)).component_ids()[lines(bot_links(l)).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+# endif // ! SCRIBO_NDEBUG
+ }
+
+# ifndef SCRIBO_NDEBUG
+ else if (bot_group_size(old_bot_groups(l)) > 1)
+ {
+ mln::draw::line(debug,
+ p,
+ components(bot_links(l)).bbox().pmax(),
+ literal::orange);
+
+ // Draw first component box
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[lines(l).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(bot_links(l)).component_ids()[lines(bot_links(l)).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+ }
+# endif // ! SCRIBO_NDEBUG
+ }
+
+
+ // Looking for whitespaces
+ for_all_elements(c, group_bbox)
+ if (group_bbox(c).is_valid())
+ {
+ unsigned ldelta = delta;
+ if (bot_group_size(c) >= 3 && bot_group_size(c) < 5)
+ {
+ // Stats are not reliable, prefer using max char width.
+ if (bot_median_char_width(c).card() == 0)
+ ldelta = bot_max_char_width(c) * 2;
+ else
+ ldelta = 1.2 * bot_median_char_width(c)
+ + bot_median_char_space(c);
+
+ point2d p(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima);
+
+ // Checking whitespace area
+ for (; p.col() <= group_bbox(c).to_result().pmax().col()
+ && (bbox_ima(p) == 0);)
+ ++p.col();
+
+ if (bbox_ima(p) != 0)
+ {
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::red);
+# endif // ! SCRIBO_NDEBUG
+
+ continue;
+ }
+ }
+
+ box2d
+ brot = internal::fast_rotate_negative(group_bbox(c).to_result(),
+ rbbox);
+
+ if (internal::is_valid_left_right_skewed_delimitor(brot, input,
+ - delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmin().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ true);
+ }
+ else if (internal::is_valid_right_left_skewed_delimitor(brot,
+ input,
+ - delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmin().col() + delta),
+ delimitors),
+ true);
+ }
+ else
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ true);
+ }
+
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::green);
+# endif // ! SCRIBO_NDEBUG
+ }
+ }
+
+ } // END OF BOTTOM LINKS PROCESSING
+
+
+ V ndelim;
+ component_set<L>
+ delim_comps = primitive::extract::components(delimitors, c8(), ndelim);
+
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ output(delim_comps, delimitors);
+
+# ifndef SCRIBO_NDEBUG
+ debug = preprocessing::rotate_90(debug, true);
+ debug::logger().log_image(debug::All,
+ debug, "alignments_debug");
+# endif // ! SCRIBO_NDEBUG
+
+ trace::exiting("scribo::primitive::extract::alignments");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::extract
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_ALIGNMENTS_HH
diff --git a/scribo/scribo/primitive/link/internal/dmax_hrules.hh b/scribo/scribo/primitive/link/internal/dmax_hrules.hh
new file mode 100644
index 0000000..24de6ca
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/dmax_hrules.hh
@@ -0,0 +1,100 @@
+// 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_DMAX_HRULES_HH
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_DMAX_HRULES_HH
+
+/// \file
+///
+/// Default class for dmax functors.
+
+# include <scribo/primitive/link/internal/dmax_functor_base.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+
+ /// \brief Base class for dmax functors.
+ class dmax_hrules : public dmax_functor_base<dmax_hrules>
+ {
+ typedef dmax_functor_base<dmax_hrules> super_;
+
+ public:
+ dmax_hrules(float dmax_factor, unsigned fixed_dmax);
+ float compute_(const box2d& b) const;
+
+ protected:
+ using super_::dmax_factor_;
+ unsigned fixed_dmax_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ inline
+ dmax_hrules::dmax_hrules(float dmax_factor, unsigned fixed_dmax)
+ : super_(dmax_factor), fixed_dmax_(fixed_dmax)
+ {
+ }
+
+
+ inline
+ float
+ dmax_hrules::compute_(const box2d& b) const
+ {
+ float
+ w = b.width();
+
+ if (w < 15)
+ return fixed_dmax_;
+
+ return (w / 2.0f) + (dmax_factor_ * w);
+ }
+
+
+# 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_DMAX_HRULES_HH
diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
new file mode 100644
index 0000000..c7ef021
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
@@ -0,0 +1,159 @@
+// 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_DELTA_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_DELTA_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_delta_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_delta_base(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ int delta_pixel,
+ anchor::Direction delta_direction)
+ : super_(components, anchor::Horizontal, exact(dmax_f)),
+ delta_pixel_(delta_pixel), delta_direction_(delta_direction)
+ {
+
+ }
+
+
+ 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;
+
+ // We can assume that the current site 'p' points to an
+ // object different from the background.
+
+ mln_site(L)
+ p1 = compute_anchor(this->components_, current_object, anchor),
+ p2 = compute_anchor(this->components_, this->labeled_image_(p),
+ anchor);
+
+ return std::abs(p1[this->delta_direction_]
+ - p2[this->delta_direction_]) <= delta_pixel_;
+ }
+
+
+ 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);
+ }
+
+ 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);
+ }
+
+ int delta_pixel_;
+ anchor::Direction delta_direction_;
+ };
+
+
+# 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_DELTA_BASE_HH_
diff --git a/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh b/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
new file mode 100644
index 0000000..6c6e67f
--- /dev/null
+++ b/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
@@ -0,0 +1,157 @@
+// 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.
+
+/// \file
+///
+/// \brief Merge two object links data based on distance and angle.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
+# define SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
+
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/filter/internal/alignment_angle.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Merge two object links data based on distance and angle.
+
+ Performs an 'OR' operation on the links according distance and
+ angle criterion.
+
+ If a component has several incoming links, only the link for
+ which the the object is the closest or the angle performed
+ between the two bboxes is the lower, will be preserved.
+ */
+ template <typename L>
+ object_links<L>
+ merge_double_link_closest_aligned(const object_links<L>& left,
+ const object_links<L>& right,
+ anchor::Type anchor_angle);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ object_links<L>
+ merge_double_link_closest_aligned(const object_links<L>& left,
+ const object_links<L>& right,
+ anchor::Type anchor_angle)
+ {
+ trace::entering("scribo::primitive::link::merge_double_link_closest_aligned");
+ mln_precondition(left.is_valid());
+ mln_precondition(right.is_valid());
+
+
+ const component_set<L>& components = left.components();
+
+ mln::util::array<mln::util::couple<unsigned, float> > align_data;
+ align_data.resize(value::next(left.nelements()));
+ for (unsigned i = 0; i < align_data.nelements(); ++i)
+ {
+ align_data(i).first() = mln_max(unsigned);
+ align_data(i).second() = 360;
+ }
+
+ object_links<L> output = right.duplicate();
+
+ // Init alignment data.
+ for_all_links(l, output)
+ if (right(l) != l)
+ {
+ //FIXME Handle the case when a component is included in another one ?
+
+ // Update distance
+ align_data(l).first()
+ = std::abs(components(l).bbox().pcenter().col()
+ - components(right(l)).bbox().pcenter().col());
+
+ // Update angle
+ align_data(l).second()
+ = filter::internal::alignment_angle(components,
+ l,
+ right(l),
+ anchor_angle);
+ }
+ else
+ {
+ // Update distance
+ align_data(l).first() = mln_max(unsigned);
+
+ // Update angle
+ align_data(l).second() = 360.f;
+ }
+
+
+
+ // Trying to improve results with left links.
+ for_all_links(l, left)
+ if (left(l) != l && left(l) != right(l))
+ {
+ unsigned dh = std::abs(components(l).bbox().pcenter().col()
+ - components(left(l)).bbox().pcenter().col());
+
+ float alpha
+ = filter::internal::alignment_angle(components,
+ l,
+ left(l),
+ anchor_angle);
+
+ if (right(left(l)) == left(l))
+ {
+ output(left(l)) = l;
+ //output.update_link(left(l), l);
+ }
+ else if ((dh < align_data(left(l)).first() * 0.66f)
+ || (alpha < align_data(left(l)).second()))
+ {
+ output(left(l)) = l;
+ //output.update_link(left(l), l);
+ align_data(left(l)).first() = dh;
+ align_data(left(l)).second() = alpha;
+ }
+ }
+
+ trace::exiting("scribo::primitive::link::merge_double_link_closest_aligned");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
diff --git a/scribo/src/primitive/extract/Makefile.am b/scribo/src/primitive/extract/Makefile.am
index 22d6bfd..fef405a 100644
--- a/scribo/src/primitive/extract/Makefile.am
+++ b/scribo/src/primitive/extract/Makefile.am
@@ -34,3 +34,14 @@ separators_nonvisible_SOURCES = separators_nonvisible.cc
thick_vlines_SOURCES = thick_vlines.cc
thick_hlines_SOURCES = thick_hlines.cc
lines_pattern_SOURCES = lines_pattern.cc
+
+
+if HAVE_MAGICKXX
+
+ noinst_PROGRAMS += alignments
+ alignments_SOURCES = alignments.cc
+ alignments_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS)
+ alignments_LDFLAGS = $(AM_LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+endif HAVE_MAGICKXX
\ No newline at end of file
diff --git a/scribo/src/primitive/extract/alignments.cc b/scribo/src/primitive/extract/alignments.cc
new file mode 100644
index 0000000..2508ec9
--- /dev/null
+++ b/scribo/src/primitive/extract/alignments.cc
@@ -0,0 +1,89 @@
+// 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.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/data/convert.hh>
+#include <mln/util/timer.hh>
+
+#include <scribo/text/extract_lines_wo_merge.hh>
+#include <scribo/primitive/extract/alignments.hh>
+#include <scribo/debug/usage.hh>
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", "A binary image without vertical or horizontal separators." },
+ { "output.pbm", "Output image." },
+ { "enable_debug", "0 or 1 (default 0)" },
+ {0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo;
+
+ if (argc != 3 && argc != 4)
+ return scribo::debug::usage(argv,
+ "Extract delimitors based on alignments.",
+ "input.pbm output.pbm [enable_debug]",
+ args_desc);
+
+ trace::entering("main");
+
+ if (argc > 3 && atoi(argv[3]))
+ scribo::debug::logger().set_level(scribo::debug::All);
+
+ float dmax_ratio = 3;
+ unsigned delta_pixel = 3;
+
+ typedef image2d<scribo::def::lbl_type> L;
+ document<L> doc(argv[1]);
+ doc.open();
+
+ // Vertical and horizontal separators
+ image2d<bool> input = data::convert(bool(), doc.image());
+ image2d<bool> separators = primitive::extract::separators(input, 81);
+ input = primitive::remove::separators(input, separators);
+ input = preprocessing::denoise_fg(input, c8(), 3);
+ doc.set_binary_image(input);
+
+ // Extract lines
+ line_set<L>
+ lines = scribo::text::extract_lines_wo_merge(doc, c8(), separators);
+ doc.set_paragraphs(scribo::make::paragraph(lines));
+
+ util::timer t;
+ t.start();
+ mln::util::couple<component_set<L>, mln_ch_value_(L,bool)>
+ res = primitive::extract::alignments(doc, dmax_ratio, delta_pixel);
+ t.stop();
+ std::cout << t << std::endl;
+
+ io::pbm::save(res.second(), argv[2]);
+
+ trace::exiting("main");
+}
diff --git a/scribo/tests/data.hh.in b/scribo/tests/data.hh.in
index 6a6f95f..501fbea 100644
--- a/scribo/tests/data.hh.in
+++ b/scribo/tests/data.hh.in
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2011 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -36,4 +37,7 @@
/// \brief The absolute path to the img directory of Scribo.
# define SCRIBO_IMG_DIR "@abs_top_srcdir@/scribo/tests/img"
+/// \brief The absolute path to the test directory of Scribo.
+# define SCRIBO_TESTS_DIR "@abs_top_srcdir@/scribo/tests/"
+
#endif // ! SCRIBO_TESTS_DATA_HH
diff --git a/scribo/tests/img/alignment_1.png b/scribo/tests/img/alignment_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4592429963506e1c987e2b18b0969ad04a9bde0
GIT binary patch
literal 3145
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_2.png b/scribo/tests/img/alignment_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c828bb44984051f862879836b2904a1176695c2
GIT binary patch
literal 3147
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_3.png b/scribo/tests/img/alignment_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..67c20308a0693278a5c16af4f4f9f014f30a2f8b
GIT binary patch
literal 3145
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_4.png b/scribo/tests/img/alignment_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..df3d395baa7c9f0fa905c6e7d941b36ee3ab705e
GIT binary patch
literal 3155
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/primitive/Makefile.am b/scribo/tests/primitive/Makefile.am
index 82c773a..2b88bed 100644
--- a/scribo/tests/primitive/Makefile.am
+++ b/scribo/tests/primitive/Makefile.am
@@ -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.
#
@@ -17,5 +18,6 @@
include $(top_srcdir)/scribo/tests/tests.mk
SUBDIRS = \
+ extract \
link
diff --git a/scribo/tests/primitive/extract/Makefile.am b/scribo/tests/primitive/extract/Makefile.am
new file mode 100644
index 0000000..97eb43f
--- /dev/null
+++ b/scribo/tests/primitive/extract/Makefile.am
@@ -0,0 +1,33 @@
+# 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/>.
+
+include $(top_srcdir)/scribo/tests/tests.mk
+
+check_PROGRAMS =
+
+if HAVE_MAGICKXX
+
+check_PROGRAMS = alignments
+alignments_SOURCES = alignments.cc
+alignments_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS) \
+ -DSCRIBO_NDEBUG
+alignments_LDFLAGS = $(LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+
+endif HAVE_MAGICKXX
+
+TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/primitive/extract/alignment_1.ref.pbm b/scribo/tests/primitive/extract/alignment_1.ref.pbm
new file mode 100644
index 0000000..ad657f2
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_1.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_2.ref.pbm b/scribo/tests/primitive/extract/alignment_2.ref.pbm
new file mode 100644
index 0000000..e1e07c3
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_2.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_3.ref.pbm b/scribo/tests/primitive/extract/alignment_3.ref.pbm
new file mode 100644
index 0000000..0bd1d34
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_3.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_4.ref.pbm b/scribo/tests/primitive/extract/alignment_4.ref.pbm
new file mode 100644
index 0000000..a0830ea
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_4.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignments.cc b/scribo/tests/primitive/extract/alignments.cc
new file mode 100644
index 0000000..7bd82fb
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignments.cc
@@ -0,0 +1,76 @@
+// 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.
+
+// \file
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/io/pbm/load.hh>
+
+#include <scribo/core/document.hh>
+#include <scribo/core/paragraph_set.hh>
+#include <scribo/text/extract_lines_wo_merge.hh>
+#include <scribo/primitive/extract/alignments.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using namespace scribo;
+
+ typedef image2d<scribo::def::lbl_type> L;
+
+ for (unsigned i = 1; i < 5; ++i)
+ {
+ std::ostringstream os;
+ os << SCRIBO_IMG_DIR << "/alignment_" << i << ".png";
+
+ document<L> doc(os.str().c_str());
+ doc.open();
+ doc.set_binary_image(data::convert(bool(), doc.image()));
+
+ // Extract lines
+ line_set<L>
+ lines = scribo::text::extract_lines_wo_merge(doc, c8());
+ doc.set_paragraphs(scribo::make::paragraph(lines));
+
+ // Find alignments
+ mln::util::couple<component_set<L>, mln_ch_value_(L,bool)>
+ res = primitive::extract::alignments(doc, 3, 3);
+
+ std::ostringstream os_out;
+ image2d<bool> ref;
+ os_out << SCRIBO_TESTS_DIR << "/primitive/extract/alignment_"
+ << i << ".ref.pbm";
+
+ io::pbm::save(res.second(), "res.pbm");
+ io::pbm::load(ref, os_out.str().c_str());
+
+ mln_assertion(ref == res.second());
+ }
+
+}
--
1.5.6.5
1
0