From: Vigouroux Caroline
<vigouroux(a)lrde.epita.fr>
To: olena-patches(a)lrde.epita.fr
Subject: milena r1866: Add red getter
URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-04-15 Type Your Name Here <your.mail.here(a)FIXME.com>
Add red getter.
* cmy/fun.hh, hsi/fun.hh, yiq/fun.hh, yuv/fun.hh :
New red getter.
* cmy/my_cmy.hh, hsi/my_hsi.hh, yiq/my_yiq.hh, yuv/my_yuv.hh:
Added inheritance from value.
* cmy/rgb_to_cmy.hh, hsi/rgb_to_hsi.hh, yiq/rgb_to_yiq.hh,
yuv/rgb_to_yuv.hh:
Added inheritance from function_v2v.
* cmy/test.cc, yiq/test.cc, yuv/test.cc : New test.
* cmy/testfun.cc, yiq/testfun.cc, yuv/testfun.cc: New test.
* cmy, hsi, yiq, yuv: New folder.
* color/is_HSI.cc: change.
* color/my_hsi.hh: change.
* color/rgb_to_hsi.hh: change.
* function.hh: New getter.
* testfun.cc: New test.
---
diffstat not available
Index: trunk/milena/sandbox/vigouroux/yuv/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/test.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/yuv/test.cc (revision 1866)
@@ -0,0 +1,28 @@
+#include "my_yuv.hh"
+#include "rgb_to_yuv.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+int main()
+{
+ using namespace mln;
+
+ image2d<value::rgb8> lena;
+ io::ppm::load(lena, "../../../img/lena.ppm");
+
+ image2d< value::yuv_<double, double, double> > lena_hsi
+ = level::transform(lena,
+ fun::v2v::f_rgb_to_yuv_f());
+
+ image2d<value::rgb8> lena_rgb = level::transform(lena_hsi,
+ fun::v2v::f_yuv_to_rgb_3x8);
+}
+
Index: trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yuv/my_yuv.hh (revision 1866)
@@ -0,0 +1,146 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
+#ifndef MLN_VALUE_YUV_HH
+# define MLN_VALUE_YUV_HH
+
+namespace mln
+{
+ namespace value
+ {
+
+ template <typename E>
+ struct YUV
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, //
Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ YUV<E> >
+ {
+ };
+
+ template <typename Y, typename U, typename V>
+ class yuv_ : public YUV< yuv_<Y,U,V> >
+ {
+ public:
+
+ typedef Y y_type;
+ typedef U u_type;
+ typedef V v_type;
+
+ /// Constructor without argument.
+ yuv_()
+ {
+ }
+
+ /// Constructor from component values.
+ yuv_(const Y& y, const U& u, const V& v)
+ : y_(y),
+ u_(u),
+ v_(v)
+ {
+ }
+
+ /// Read-only access to the y component.
+ const Y& y() const
+ {
+ return this->y_;
+ }
+ const U& u() const
+ {
+ return this->u_;
+ }
+ const V& v() const
+ {
+ return this->v_;
+ }
+
+ /// Read-write access to the y component.
+ Y& y()
+ {
+ return this->y_;
+ }
+ U& u()
+ {
+ return this->u_;
+ }
+ V& v()
+ {
+ return this->v_;
+ }
+
+ private:
+ Y y_;
+ U u_;
+ V v_;
+ };
+
+ typedef yuv_<float, float, float> yuv_3x8;
+
+ typedef yuv_<double, double, double> yuv_d;
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+// template <unsigned n>
+// struct yuv
+// {
+// public:
+// /// Constructor without argument.
+// yuv<n>();
+
+// /// Constructor from component values.
+// yuv<n>(double y, double u, double v);
+
+// /// Access to component values.
+// double y() const { return this->y_; }
+// double u() const { return this->u_; }
+// double v() const { return this->v_; }
+
+// /// Set component values.
+// void y(double y)
+// {
+// this->y_ = y;
+// }
+// void u(double u)
+// {
+// this->u_ = u;
+// }
+// void v(double v)
+// {
+// mln_precondition(v >= 0);
+// this->v_ = v;
+// }
+
+// private:
+// double y_;
+// double u_;
+// double v_;
+// };
+
+// template <unsigned n>
+// inline
+// yuv<n>::yuv()
+// :y_(0), u_(0), v_(0)
+// {
+// }
+
+// template <unsigned n>
+// inline
+// yuv<n>::yuv(double y, double u, double v)
+// {
+// mln_precondition(v >= 0);
+// this->y_ = y;
+// this->u_ = u;
+// this->v_ = v;
+// }
+// }
+// }
+
+#endif // ! MLN_VALUE_YUV_HH
Index: trunk/milena/sandbox/vigouroux/yuv/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/fun.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yuv/fun.hh (revision 1866)
@@ -0,0 +1,56 @@
+
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "my_yuv.hh"
+
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_rgb>
+ struct f_yuv_ : public Function_v2v< f_yuv_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_yuv>
+ T_rgb operator()(const T_yuv& yuv) const
+ {
+ int r;
+ int g;
+ int b;
+
+ r = int(yuv.y() + 1.13983 * yuv.v());
+ g = int(yuv.y() - 0.39465 * yuv.u() - 0.58060 * yuv.v());
+ b = int(yuv.y() + 2.03211 * yuv.u());
+
+ struct value::rgb<8> rgb(r, g, b);
+
+ return (rgb);
+ }
+ };
+
+ typedef f_yuv_<value::rgb8> f_yuv_3x8_t;
+
+ f_yuv_3x8_t f_yuv_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/yuv/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/testfun.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/yuv/testfun.cc (revision 1866)
@@ -0,0 +1,30 @@
+#include "my_yuv.hh"
+#include "rgb_to_yuv.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+#include "fun.hh"
+
+int main()
+{
+// typedef mln::value::yuv_d Col;
+ using namespace mln::fun::v2v;
+
+ mln::value::yuv_d col;
+ mln::image2d<mln::value::rgb8> lena;
+ mln::io::ppm::load(lena, "../../../img/lena.ppm");
+
+ mln::image2d<mln::value::yuv_d> lena_yuv = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_yuv_d());
+
+ mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_yuv,
+ f_yuv_3x8);
+}
Index: trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yuv/rgb_to_yuv.hh (revision 1866)
@@ -0,0 +1,74 @@
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/value/int_u.hh>
+#include <mln/math/round.hh>
+
+#include "my_yuv.hh"
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_yuv>
+ struct f_rgb_to_yuv_ : public Function_v2v< f_rgb_to_yuv_<T_yuv> >
+ {
+ typedef T_yuv result;
+
+ template <typename T_rgb>
+ T_yuv operator()(const T_rgb& rgb) const
+ {
+ T_yuv yuv;
+
+ yuv.y() = 0.299 * rgb.red() + 0.587 * rgb.green() + 0.114 * rgb.blue();
+ yuv.u() = 0.436 * (rgb.blue() - yuv.y()) / (1 - 0.114);
+ yuv.v() = 0.615 * (rgb.red() - yuv.y()) / (1 - 0.299);
+
+ return yuv;
+ }
+ };
+
+ typedef f_rgb_to_yuv_< mln::value::yuv_<double, double, double> >
f_rgb_to_yuv_d;
+
+ template <typename T_rgb>
+ struct f_yuv_to_rgb_ : public Function_v2v< f_yuv_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_yuv>
+ T_rgb operator()(const T_yuv& yuv) const
+ {
+ int r;
+ int g;
+ int b;
+
+ r = int(yuv.y() + 1.13983 * yuv.v());
+ g = int(yuv.y() - 0.39465 * yuv.u() - 0.58060 * yuv.v());
+ b = int(yuv.y() + 2.03211 * yuv.u());
+
+ struct value::rgb<8> rgb(r, g, b);
+
+ return (rgb);
+ }
+ };
+
+ typedef f_yuv_to_rgb_<value::rgb8> f_yuv_to_rgb_3x8_t;
+
+ f_yuv_to_rgb_3x8_t f_yuv_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
Index: trunk/milena/sandbox/vigouroux/hsi/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/hsi/fun.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/hsi/fun.hh (revision 1866)
@@ -0,0 +1,64 @@
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "../color/my_hsi.hh"
+
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_rgb>
+ struct f_hsi_ : public Function_v2v< f_hsi_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_hsi>
+ T_rgb operator()(const T_hsi& hsi) const
+ {
+ typedef typename T_rgb::red_t red_t;
+
+ static math::round<red_t> to_r;
+
+ static const float
+ sqrt3_3 = std::sqrt(3) / 3,
+ inv_sqrt6 = 1 / std::sqrt(6),
+ inv_sqrt2 = 1 / std::sqrt(2);
+
+ float
+ h = hsi.hue() / 180.0 * 3.1415,
+ alpha = hsi.sat() * std::cos(h),
+ beta = hsi.sat() * std::sin(h);
+
+
+ red_t r = to_r(sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta);
+
+ T_rgb rgb(r, 0, 0);
+
+ return rgb;
+ }
+ };
+
+ typedef f_hsi_<value::rgb8> f_hsi_3x8_t;
+
+ f_hsi_3x8_t f_hsi_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/hsi/my_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/hsi/my_hsi.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/hsi/my_hsi.hh (revision 1866)
@@ -0,0 +1,93 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
+#ifndef MLN_VALUE_HSI_HH
+# define MLN_VALUE_HSI_HH
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+ template <typename E>
+ struct HSI
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, //
Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ HSI<E> >
+ {
+ };
+
+ template <typename H, typename S, typename I>
+ class hsi_ : public HSI< hsi_<H,S,I> >
+ {
+ public:
+
+ typedef H h_type;
+ typedef S s_type;
+ typedef I i_type;
+
+ /// Constructor without argument.
+ hsi_()
+ {
+ }
+
+ /// Constructor from component values.
+ hsi_(const H& hue, const S& sat, const I& inty)
+ : hue_(hue),
+ sat_(sat),
+ int_(inty)
+ {
+ }
+
+ /// Read-only access to the hue component.
+ const H& hue() const
+ {
+ return this->hue_;
+ }
+ const S& sat() const
+ {
+ return this->sat_;
+ }
+ const I& inty() const
+ {
+ return this->int_;
+ }
+
+ /// Read-write access to the hue component.
+ H& hue()
+ {
+ return this->hue_;
+ }
+ S& sat()
+ {
+ return this->sat_;
+ }
+ I& inty()
+ {
+ return this->int_;
+ }
+
+ private:
+ H hue_;
+ S sat_;
+ I int_;
+ };
+
+ typedef hsi_<float, float, float> hsi_f;
+
+ typedef hsi_<double, double, double> hsi_d;
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_HSI_HH
Index: trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/hsi/rgb_to_hsi.hh (revision 1866)
@@ -0,0 +1,108 @@
+
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "my_hsi.hh"
+
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_hsi>
+ struct f_rgb_to_hsi_ : public Function_v2v< f_rgb_to_hsi_<T_hsi> >
+ {
+ typedef T_hsi result;
+
+ template <typename T_rgb>
+ T_hsi operator()(const T_rgb& rgb) const
+ {
+ // Locals.
+ static const double sqrt3_3 = std::sqrt(3) / 3;
+ static const double inv_sqrt6 = 1 / std::sqrt(6);
+ static const double inv_sqrt2 = 1 / std::sqrt(2);
+
+ T_hsi hsi;
+
+ double alpha = inv_sqrt2 * rgb.green() - inv_sqrt2 * rgb.blue();
+ double beta = 2 * inv_sqrt6 * rgb.red() - inv_sqrt6 * rgb.green() - inv_sqrt6 *
rgb.blue();
+
+
+ float tmp = atan2(beta, alpha) / 3.1415 * 180.0;
+
+ hsi.hue() = atan2(beta, alpha) / 3.1415 * 180.0;
+ if (hsi.hue() < 0)
+ hsi.hue() = hsi.hue() + 360.0;
+ mln_invariant(hsi.hue() >= 0);
+ hsi.sat() = std::sqrt(alpha * alpha + beta * beta);
+ hsi.inty() = sqrt3_3 * rgb.red() + sqrt3_3 * rgb.green() + sqrt3_3 * rgb.blue();
+
+ return hsi;
+ }
+ };
+
+ typedef f_rgb_to_hsi_<value::hsi_f> f_rgb_to_hsi_f_t;
+
+ f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
+
+
+ template <typename T_rgb>
+ struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_hsi>
+ T_rgb operator()(const T_hsi& hsi) const
+ {
+ typedef typename T_rgb::red_t red_t;
+ typedef typename T_rgb::green_t green_t;
+ typedef typename T_rgb::blue_t blue_t;
+
+ static math::round<red_t> to_r;
+ static math::round<green_t> to_g;
+ static math::round<blue_t> to_b;
+
+ static const float
+ sqrt3_3 = std::sqrt(3) / 3,
+ inv_sqrt6 = 1 / std::sqrt(6),
+ inv_sqrt2 = 1 / std::sqrt(2);
+
+ float
+ h = hsi.hue() / 180.0 * 3.1415,
+ alpha = hsi.sat() * std::cos(h),
+ beta = hsi.sat() * std::sin(h);
+
+
+ red_t r = sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta;
+ green_t g = sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta;
+ blue_t b = sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta;
+
+ T_rgb rgb(r, g, b);
+
+ return rgb;
+ }
+ };
+
+ typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
+
+ f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/function.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/function.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/function.hh (revision 1866)
@@ -0,0 +1,119 @@
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+#include <mln/metal/is_a.hh>
+
+#include "color/my_hsi.hh"
+#include <mln/value/rgb.hh>
+
+#include "hsi/fun.hh"
+#include "cmy/fun.hh"
+#include "yuv/fun.hh"
+#include "yiq/fun.hh"
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ template <typename T_red>
+ struct f_get_red_ : public Function_v2v< f_get_red_<T_red> >
+ {
+ typedef T_red result;
+
+ template <typename T_col>
+ T_red operator()(const T_col& col) const
+ {
+ T_red r;
+
+ if (mlc_is_a(T_col, mln::value::HSI)::value == 1)
+ {
+ r = mln::fun::v2v::f_hsi_3x8(col);
+ std::cout << "hsi" << std::endl;
+ }
+// else if (mlc_is_a(T_col, mln::value::CMY)::value == 1)
+// {
+// r = mln::fun::v2v::f_cmy_3x8(col);
+// std::cout << "cmy" << std::endl;
+// }
+// else if (mlc_is_a(T_col, mln::value::YUV)::value == 1)
+// {
+// r = mln::fun::v2v::f_yuv_3x8(col);
+// std::cout << "yuv" << std::endl;
+// }
+// else if (mlc_is_a(T_col, mln::value::YIQ)::value == 1)
+// {
+// r = mln::fun::v2v::f_yiq_3x8(col);
+// std::cout << "yiq" << std::endl;
+// }
+ else
+ {
+// r = mln::fun::v2v::f_cmy_3x8(col);
+ std::cout << "else" << std::endl;
+ }
+ return r;
+ }
+ };
+
+// typedef f_rgb_to_hsi_<value::hsi_f> f_r// gb_to_hsi_f_t;
+
+// f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
+
+
+// template <typename T_rgb>
+// struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
+// {
+// typedef T_rgb result;
+
+// template <typename T_hsi>
+// T_rgb operator()(const T_hsi& hsi) const
+// {
+// typedef typename T_rgb::red_t red_t;
+// typedef typename T_rgb::green_t green_t;
+// typedef typename T_rgb::blue_t blue_t;
+
+// static math::round<red_t> to_r;
+// static math::round<green_t> to_g;
+// static math::round<blue_t> to_b;
+
+// static const float
+// sqrt3_3 = std::sqrt(3) / 3,
+// inv_sqrt6 = 1 / std::sqrt(6),
+// inv_sqrt2 = 1 / std::sqrt(2);
+
+// float
+// h = hsi.hue() / 180.0 * 3.1415,
+// alpha = hsi.sat() * std::cos(h),
+// beta = hsi.sat() * std::sin(h);
+
+
+// red_t r = sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta;
+// green_t g = sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta;
+// blue_t b = sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta;
+
+// T_rgb rgb(r, g, b);
+
+// return rgb;
+// }
+// };
+
+// typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
+
+// f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/cmy/rgb_to_cmy.hh (revision 1866)
@@ -0,0 +1,72 @@
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/value/int_u.hh>
+#include <mln/math/round.hh>
+
+#include "my_cmy.hh"
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_cmy>
+ struct f_rgb_to_cmy_ : public Function_v2v< f_rgb_to_cmy_<T_cmy> >
+ {
+ typedef T_cmy result;
+
+ template <typename T_rgb>
+ T_cmy operator()(const T_rgb& rgb) const
+ {
+ T_cmy cmy;
+
+ cmy.cyan() = 1 - rgb.red();
+ cmy.magenta() = 1 - rgb.green();
+ cmy.yellow() = 1 - rgb.blue();
+
+ return cmy;
+ }
+ };
+
+ typedef f_rgb_to_cmy_< mln::value::cmy_<double, double, double> >
f_rgb_to_cmy_d;
+
+ template <typename T_rgb>
+ struct f_cmy_to_rgb_ : public Function_v2v< f_cmy_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_cmy>
+ T_rgb operator()(const T_cmy& cmy) const
+ {
+ int red;
+ int green;
+ int blue;
+
+ red = int(1 - cmy.cyan());
+ green = int(1 - cmy.magenta());
+ blue = int(1 - cmy.yellow());
+ T_rgb rgb(red, green, blue);
+
+ return rgb;
+ }
+ };
+
+ typedef f_cmy_to_rgb_<value::rgb8> f_cmy_to_rgb_3x8_t;
+
+ f_cmy_to_rgb_3x8_t f_cmy_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/cmy/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/test.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/cmy/test.cc (revision 1866)
@@ -0,0 +1,28 @@
+#include "my_yiq.hh"
+#include "rgb_to_yiq.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+int main()
+{
+ using namespace mln;
+
+ image2d<value::rgb8> lena;
+ io::ppm::load(lena, "../../../img/lena.ppm");
+
+ image2d< value::yiq_<double, double, double> > lena_hsi
+ = level::transform(lena,
+ fun::v2v::f_rgb_to_yiq_d());
+
+ image2d<value::rgb8> lena_rgb = level::transform(lena_hsi,
+ fun::v2v::f_yiq_to_rgb_3x8);
+}
+
Index: trunk/milena/sandbox/vigouroux/cmy/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/fun.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/cmy/fun.hh (revision 1866)
@@ -0,0 +1,52 @@
+
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "my_cmy.hh"
+
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_rgb>
+ struct f_cmy_ : public Function_v2v< f_cmy_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_cmy>
+ T_rgb operator()(const T_cmy& cmy) const
+ {
+ int red;
+
+ red = int(1 - cmy.cyan());
+
+ T_rgb rgb(red, 0, 0);
+
+ return rgb;
+ }
+ };
+
+ typedef f_cmy_<value::rgb8> f_cmy_3x8_t;
+
+ f_cmy_3x8_t f_cmy_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/cmy/my_cmy.hh (revision 1866)
@@ -0,0 +1,147 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
+#ifndef MLN_VALUE_CMY_HH
+# define MLN_VALUE_CMY_HH
+
+namespace mln
+{
+ namespace value
+ {
+
+ template <typename E>
+ struct CMY
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, //
Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ CMY<E> >
+ {
+ };
+
+ template <typename C, typename M, typename Y>
+ class cmy_ : public CMY< cmy_<C,M,Y> >
+ {
+ public:
+
+ typedef C c_type;
+ typedef M m_type;
+ typedef Y y_type;
+
+ /// Constructor without argument.
+ cmy_()
+ {
+ }
+
+ /// Constructor from component values.
+ cmy_(const C& cyan, const M& magenta, const Y& yellow)
+ : cyan_(cyan),
+ magenta_(magenta),
+ yellow_(yellow)
+ {
+ }
+
+ /// Read-only access to the cyan component.
+ const C& cyan() const
+ {
+ return this->cyan_;
+ }
+ const M& magenta() const
+ {
+ return this->magenta_;
+ }
+ const Y& yellow() const
+ {
+ return this->yellow_;
+ }
+
+ /// Read-write access to the y component.
+ C& cyan()
+ {
+ return this->cyan_;
+ }
+ M& magenta()
+ {
+ return this->magenta_;
+ }
+ Y& yellow()
+ {
+ return this->yellow_;
+ }
+
+ private:
+ C cyan_;
+ M magenta_;
+ Y yellow_;
+ };
+
+ typedef cmy_<float, float, float> cmy_3x8;
+
+ typedef cmy_<double, double, double> cmy_d;
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+// template <unsigned n>
+// struct cmy
+// {
+// public:
+// /// Constructor without argument.
+// cmy();
+
+// /// Constructor from component values.
+// cmy(double c, double m, double y);
+
+// /// Access to component values.
+// double c() const { return this->c_; }
+// double m() const { return this->m_; }
+// double y() const { return this->y_; }
+
+// /// Set component values.
+// void c(double c)
+// {
+// mln_precondition(c >= 0);
+// this->c_ = c;
+// }
+// void m(double m)
+// {
+// mln_precondition(m >= 0);
+// this->m_ = m;
+// }
+// void y(double y)
+// {
+// mln_precondition(y >= 0);
+// this->y_ = y;
+// }
+
+// private:
+// double c_;
+// double m_;
+// double y_;
+// };
+
+// template <unsigned n>
+// inline
+// cmy<n>::cmy()
+// :c_(0), m_(0), y_(0)
+// {
+// }
+
+// template <unsigned n>
+// inline
+// cmy<n>::cmy(double c, double m, double y)
+// {
+// mln_precondition(c >= 0);
+// mln_precondition(m >= 0);
+// mln_precondition(y >= 0);
+// this->c_ = c;
+// this->m_ = m;
+// this->y_ = y;
+// }
+
+#endif // ! MLN_VALUE_CMY_HH
Index: trunk/milena/sandbox/vigouroux/cmy/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/cmy/testfun.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/cmy/testfun.cc (revision 1866)
@@ -0,0 +1,30 @@
+#include "my_cmy.hh"
+#include "rgb_to_cmy.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+#include "fun.hh"
+
+int main()
+{
+// typedef mln::value::cmy_d Col;
+ using namespace mln::fun::v2v;
+
+ mln::value::cmy_d col;
+ mln::image2d<mln::value::rgb8> lena;
+ mln::io::ppm::load(lena, "../../../img/lena.ppm");
+
+ mln::image2d<mln::value::cmy_d> lena_cmy = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_cmy_d());
+
+ mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_cmy,
+ f_cmy_3x8);
+}
Index: trunk/milena/sandbox/vigouroux/yiq/test.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/test.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/yiq/test.cc (revision 1866)
@@ -0,0 +1,28 @@
+#include "my_yiq.hh"
+#include "rgb_to_yiq.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+int main()
+{
+ using namespace mln;
+
+ image2d<value::rgb8> lena;
+ io::ppm::load(lena, "../../../img/lena.ppm");
+
+ image2d< value::yiq_<double, double, double> > lena_hsi
+ = level::transform(lena,
+ fun::v2v::f_rgb_to_yiq_d());
+
+ image2d<value::rgb8> lena_rgb = level::transform(lena_hsi,
+ fun::v2v::f_yiq_to_rgb_3x8);
+}
+
Index: trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yiq/my_yiq.hh (revision 1866)
@@ -0,0 +1,146 @@
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include <mln/value/float01_8.hh>
+
+#ifndef MLN_VALUE_YIQ_HH
+# define MLN_VALUE_YIQ_HH
+
+namespace mln
+{
+ namespace value
+ {
+
+ template <typename E>
+ struct YIQ
+ :
+ public internal::value_like_< algebra::vec< 3, float01_8 >, //
Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
+ YIQ<E> >
+ {
+ };
+
+ template <typename Y, typename I, typename Q>
+ class yiq_ : public YIQ< yiq_<Y,I,Q> >
+ {
+ public:
+
+ typedef Y y_type;
+ typedef I i_type;
+ typedef Q q_type;
+
+ /// Constructor without argument.
+ yiq_()
+ {
+ }
+
+ /// Constructor from component values.
+ yiq_(const Y& y, const I& i, const Q& q)
+ : y_(y),
+ i_(i),
+ q_(q)
+ {
+ }
+
+ /// Read-only access to the y component.
+ const Y& y() const
+ {
+ return this->y_;
+ }
+ const I& i() const
+ {
+ return this->i_;
+ }
+ const Q& q() const
+ {
+ return this->q_;
+ }
+
+ /// Read-write access to the y component.
+ Y& y()
+ {
+ return this->y_;
+ }
+ I& i()
+ {
+ return this->i_;
+ }
+ Q& q()
+ {
+ return this->q_;
+ }
+
+ private:
+ Y y_;
+ I i_;
+ Q q_;
+ };
+
+ typedef yiq_<float, float, float> yiq_f;
+
+ typedef yiq_<double, double, double> yiq_d;
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+// template <unsigned n>
+// struct yiq
+// {
+// public:
+// /// Constructor without argument.
+// yiq<n>();
+
+// /// Constructor from component values.
+// yiq<n>(double y, double i, double q);
+
+// /// Access to component values.
+// double y() const { return this->y_; }
+// double i() const { return this->i_; }
+// double q() const { return this->q_; }
+
+// /// Set component values.
+// void y(double y)
+// {
+// this->y_ = y;
+// }
+// void i(double i)
+// {
+// this->i_ = i;
+// }
+// void q(double q)
+// {
+// mln_precondition(q >= 0);
+// this->q_ = q;
+// }
+
+// private:
+// double y_;
+// double i_;
+// double q_;
+// };
+
+// template <unsigned n>
+// inline
+// yiq<n>::yiq()
+// :y_(0), i_(0), q_(0)
+// {
+// }
+
+// template <unsigned n>
+// inline
+// yiq<n>::yiq(double y, double i, double q)
+// {
+// mln_precondition(q >= 0);
+// this->y_ = y;
+// this->i_ = i;
+// this->q_ = q;
+// }
+// }
+// }
+
+#endif // ! MLN_VALUE_YIQ_HH
Index: trunk/milena/sandbox/vigouroux/yiq/fun.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/fun.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yiq/fun.hh (revision 1866)
@@ -0,0 +1,52 @@
+
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/math/round.hh>
+
+#include "my_yiq.hh"
+
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_rgb>
+ struct f_yiq_ : public Function_v2v< f_yiq_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_yiq>
+ T_rgb operator()(const T_yiq& yiq) const
+ {
+ int r;
+
+ r = int(0.87 * yiq.y() + 1.3223 * yiq.i() + 0.5628 * yiq.q());
+
+ T_rgb rgb(r, 0, 0);
+
+ return rgb;
+ }
+ };
+
+ typedef f_yiq_<value::rgb8> f_yiq_3x8_t;
+
+ f_yiq_3x8_t f_yiq_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
Index: trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh (revision 0)
+++ trunk/milena/sandbox/vigouroux/yiq/rgb_to_yiq.hh (revision 1866)
@@ -0,0 +1,76 @@
+#include <cmath>
+
+#include <mln/core/image_if_value.hh>
+#include <mln/core/inplace.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/display/show.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/display/save_and_show.hh>
+#include <mln/level/fill.hh>
+#include <mln/value/int_u.hh>
+#include <mln/math/round.hh>
+
+#include "my_yiq.hh"
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+ template <typename T_yiq>
+ struct f_rgb_to_yiq_ : public Function_v2v< f_rgb_to_yiq_<T_yiq> >
+ {
+ typedef T_yiq result;
+
+ template <typename T_rgb>
+ T_yiq operator()(const T_rgb& rgb) const
+ {
+ T_yiq yiq;
+
+ yiq.y() = 0.1768 * rgb.red() + 0.8130 * rgb.green() + 0.0101 * rgb.blue();
+ yiq.i() = 0.5346 * rgb.red() - 0.2461 * rgb.green() - 0.1791 * rgb.blue();
+ yiq.q() = 0.2474 * rgb.red() - 0.6783 * rgb.green() + 0.4053 * rgb.blue();
+
+ return yiq;
+ }
+ };
+
+ typedef f_rgb_to_yiq_< mln::value::yiq_<double, double, double> >
f_rgb_to_yiq_d;
+
+ template <typename T_rgb>
+ struct f_yiq_to_rgb_ : public Function_v2v< f_yiq_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_yiq>
+ T_rgb operator()(const T_yiq& yiq) const
+ {
+ int r;
+ int g;
+ int b;
+
+ r = int(0.87 * yiq.y() + 1.3223 * yiq.i() + 0.5628 * yiq.q());
+ g = int(1.026 * yiq.y() - 0.2718 * yiq.i() - 0.1458 * yiq.q());
+ b = int(1.186 * yiq.y() - 1.2620 * yiq.i() + 1.8795 * yiq.q());
+
+ struct value::rgb<8> rgb(r, g, b);
+
+ return rgb;
+ }
+ };
+
+ typedef f_yiq_to_rgb_<value::rgb8> f_yiq_to_rgb_3x8_t;
+
+ f_yiq_to_rgb_3x8_t f_yiq_to_rgb_3x8;
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+
+
Index: trunk/milena/sandbox/vigouroux/yiq/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/yiq/testfun.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/yiq/testfun.cc (revision 1866)
@@ -0,0 +1,30 @@
+#include "my_yiq.hh"
+#include "rgb_to_yiq.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+#include "fun.hh"
+
+int main()
+{
+// typedef mln::value::yiq_d Col;
+ using namespace mln::fun::v2v;
+
+ mln::value::yiq_d col;
+ mln::image2d<mln::value::rgb8> lena;
+ mln::io::ppm::load(lena, "../../../img/lena.ppm");
+
+ mln::image2d<mln::value::yiq_d> lena_yiq = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_yiq_d());
+
+ mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_yiq,
+ f_yiq_3x8);
+}
Index: trunk/milena/sandbox/vigouroux/testfun.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/testfun.cc (revision 0)
+++ trunk/milena/sandbox/vigouroux/testfun.cc (revision 1866)
@@ -0,0 +1,30 @@
+#include <mln/value/hsi.hh>
+#include "color/rgb_to_hsi.hh"
+
+#include <cmath>
+
+#include <mln/core/image2d.hh>
+#include <mln/value/rgb.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/math/round.hh>
+#include <mln/level/transform.hh>
+
+#include "function.hh"
+
+int main()
+{
+// typedef mln::value::hsi_d Col;
+ using namespace mln::fun::v2v;
+
+ mln::value::hsi_d col;
+ mln::image2d<mln::value::rgb8> lena;
+ mln::io::ppm::load(lena, "../../img/lena.ppm");
+
+ mln::image2d<mln::value::hsi_f> lena_hsi = mln::level::transform(lena,
+ mln::fun::v2v::f_rgb_to_hsi_f);
+
+ mln::image2d<mln::value::rgb8> lena_rgb = mln::level::transform(lena_hsi,
+ f_get_red_<mln::value::rgb8>());
+}
Index: trunk/milena/sandbox/vigouroux/color/my_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/my_hsi.hh (revision 1865)
+++ trunk/milena/sandbox/vigouroux/color/my_hsi.hh (revision 1866)
@@ -19,9 +19,9 @@
template <typename E>
struct HSI
:
- public internal::value_like_< algebra::vec< 3, float01_<n> >, //
Equivalent.
- algebra::vec< 3, float01_<n> >, // Encoding.
- algebra::vec< 3, float01_<n> >, // Interoperation.
+ public internal::value_like_< algebra::vec< 3, float01_8 >, //
Equivalent.
+ algebra::vec< 3, float01_8 >, // Encoding.
+ algebra::vec< 3, float01_8 >, // Interoperation.
HSI<E> >
{
};
Index: trunk/milena/sandbox/vigouroux/color/is_HSI.cc
===================================================================
--- trunk/milena/sandbox/vigouroux/color/is_HSI.cc (revision 1865)
+++ trunk/milena/sandbox/vigouroux/color/is_HSI.cc (revision 1866)
@@ -8,26 +8,26 @@
int main()
{
- using namespace mln;
- using namespace mln::value;
+// using namespace mln;
+// using namespace mln::value;
- typedef hsi_d C;
- std::cout << mlc_is_a(C, HSI)::value << std::endl;
- std::cout << mlc_is_a(rgb8, HSI)::value << std::endl;
+ typedef mln::value::hsi_d C;
+ std::cout << mlc_is_a(C, mln::value::HSI)::value << std::endl;
+ std::cout << mlc_is_a(mln::value::rgb8, mln::value::HSI)::value <<
std::endl;
- rgb8 c(255, 10, 1);
- rgb8 other(10, 20, 30);
+ mln::value::rgb8 c(255, 10, 1);
+ mln::value::rgb8 other(10, 20, 30);
// Essai en 0 255
- hsi_3x8 c_hsi = fun::v2v::f_rgb_to_hsi_3x8(c);
- rgb8 c2 = fun::v2v::f_hsi_to_rgb_3x8(c_hsi);
- std::cout << "c = " << c << std::endl;
- std::cout << "c2 = " << c2 << std::endl;
+// hsi_3x8 c_hsi = fun::v2v::f_rgb_to_hsi_3x8(c);
+// rgb8 c2 = fun::v2v::f_hsi_to_rgb_3x8(c_hsi);
+// std::cout << "c = " << c << std::endl;
+// std::cout << "c2 = " << c2 << std::endl;
- hsi_3x8 c_cool = fun::v2v::f_rgb_to_hsi_3x8(other);
- rgb8 coucou = fun::v2v::f_hsi_to_rgb_3x8(c_cool);
+// hsi_3x8 c_cool = fun::v2v::f_rgb_to_hsi_3x8(other);
+// rgb8 coucou = fun::v2v::f_hsi_to_rgb_3x8(c_cool);
- std::cout << "c = " << other << std::endl;
- std::cout << "c2 = " << coucou << std::endl;
+// std::cout << "c = " << other << std::endl;
+// std::cout << "c2 = " << coucou << std::endl;
}
Index: trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh
===================================================================
--- trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh (revision 1865)
+++ trunk/milena/sandbox/vigouroux/color/rgb_to_hsi.hh (revision 1866)
@@ -23,7 +23,6 @@
namespace v2v
{
-
template <typename T_hsi>
struct f_rgb_to_hsi_ : public Function_v2v< f_rgb_to_hsi_<T_hsi> >
{