* mln/convert/to_qimage.hh: New.
---
milena/ChangeLog | 6 +
milena/mln/convert/to_qimage.hh | 411 +++++++++++++++++++++++++++++++++++++++
2 files changed, 417 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/convert/to_qimage.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index d94e481..4164689 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2010-02-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a routine to convert to a QImage.
+
+ * mln/convert/to_qimage.hh: New.
+
+2010-02-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add box<>::merge.
* mln/core/site_set/box.hh: New member 'merge()'.
diff --git a/milena/mln/convert/to_qimage.hh b/milena/mln/convert/to_qimage.hh
new file mode 100644
index 0000000..9b2f31c
--- /dev/null
+++ b/milena/mln/convert/to_qimage.hh
@@ -0,0 +1,411 @@
+// Copyright (C) 2009 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
+///
+/// Convert a Milena image to a Qimage.
+
+#ifndef MLN_CONVERT_TO_QIMAGE_HH
+# define MLN_CONVERT_TO_QIMAGE_HH
+
+# include <QtGui/QImage>
+
+# include <mln/core/concept/image.hh>
+# include <mln/geom/nrows.hh>
+# include <mln/geom/ncols.hh>
+# include <mln/border/resize.hh>
+
+
+# include <mln/value/qt/rgb32.hh>
+# include <mln/value/rgb8.hh>
+
+
+
+// # undef QT_VERSION
+// # define QT_VERSION 0x040000
+
+
+# if QT_VERSION < 0x040000
+# error "Your version of Qt is too old and is not supported."
+# endif
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+ // Implementation
+
+ namespace implementation
+ {
+
+
+ template <typename I>
+ inline
+ QImage to_qimage_scalar(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+# if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
+ QImage qima(ncols, nrows, QImage::Format_RGB32);
+ uchar * ptr_qima = qima.scanLine(0);
+# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ ++ptr_qima;
+# endif // ! Q_BYTE_ORDER
+# else
+ QImage qima(ncols, nrows, QImage::Format_RGB888);
+ uchar * ptr_qima = qima.scanLine(0);
+# endif // ! QT_VERSION
+
+ const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
+ unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
+
+ // Data is stored as ABGR so we skip the first value which is ignored.
+ for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
+ for (unsigned col = 0; col < ncols; ++col)
+ {
+ const mln_value(I)& v = *ptr_ima++;
+ std::memset(ptr_qima, v, sizeof(mln_value(I)) * 3);
+
+# if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
+ ptr_qima += 4;
+# else
+ ptr_qima += 3;
+# endif // ! QT_VERSION
+ }
+
+ return qima;
+ }
+
+
+
+
+// template <typename I>
+// inline
+// QImage to_qimage_scalar(const Image<I>& ima_)
+// {
+// const I& ima = exact(ima_);
+// mln_precondition(ima.is_valid());
+
+// const int
+// nrows = geom::nrows(ima),
+// ncols = geom::ncols(ima);
+
+// // Required by a one-shot data copy:
+// mln::border::resize(ima, 0);
+
+// QImage qima(ncols, nrows, QImage::Format_RGB888);
+// uchar * ptr_qima = qima.scanLine(0);
+// const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
+// unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
+
+// for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
+// for (unsigned col = 0; col < ncols; ++col)
+// {
+// const mln_value(I)& v = *ptr_ima++;
+
+
+
+// std::memcpy(qima.scanLine(0),
+// ima.buffer(),
+// ima.nelements() * sizeof(mln_value(I)));
+
+// return qima;
+// }
+
+// # endif // ! QT_VERSION
+
+
+
+
+# if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
+
+ template <typename I>
+ inline
+ QImage to_qimage_rgb8(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+ QImage qima(ncols, nrows, QImage::Format_RGB32);
+ uchar * ptr_qima = qima.scanLine(0);
+ const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
+ unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
+
+ for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
+ for (unsigned col = 0; col < ncols; ++col)
+ {
+ const mln::value::rgb8& v = *ptr_ima++;
+# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ // Memory representation : BBGGRRFF
+ *ptr_qima++ = v.blue();
+ *ptr_qima++ = v.green();
+ *ptr_qima = v.red();
+ ptr_qima += 2;
+# else /* Q_BIG_ENDIAN */
+ // Memory representation : FFRRGGBB
+ ++ptr_qima;
+ *ptr_qima++ = v.red();
+ *ptr_qima++ = v.green();
+ *ptr_qima = v.blue();
+# endif // ! Q_BYTE_ORDER
+ }
+
+ return qima;
+ }
+
+# else
+ template <typename I>
+ inline
+ QImage to_qimage_rgb8(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+
+ // Required by a one-shot data copy:
+ mln::border::resize(ima, 0);
+
+ QImage qima(ncols, nrows, QImage::Format_RGB888);
+ std::memcpy(qima.scanLine(0),
+ ima.buffer(),
+ ima.nelements() * 3);
+
+ return qima;
+ }
+# endif // ! QT_VERSION
+
+
+ template <typename I>
+ inline
+ QImage to_qimage_qt_rgb32(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+
+ // Required by a one-shot data copy:
+ mln::border::resize(ima, 0);
+
+ QImage qima(ncols, nrows, QImage::Format_RGB32);
+ std::memcpy(qima.scanLine(0),
+ ima.buffer(),
+ ima.nelements() * 4);
+
+ return qima;
+ }
+
+
+ // Not used by default since it does not create a deep copy.
+ template <typename I>
+ inline
+ QImage to_qimage_qt_rgb32_nocopy(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+
+ // Required by a one-shot data copy:
+ mln::border::resize(ima, 0);
+
+ QImage qima((uchar *)(ima.buffer()), ncols, nrows,
+ QImage::Format_RGB32);
+
+ return qima;
+ }
+
+
+// template <typename I>
+// inline
+// QImage to_qimage_rgb8_3(const Image<I>& ima_)
+// {
+// const I& ima = exact(ima_);
+// mln_precondition(ima.is_valid());
+
+// const int
+// nrows = geom::nrows(ima),
+// ncols = geom::ncols(ima);
+
+// QImage qima(ncols, nrows, QImage::Format_RGB888);
+// uchar * ptr_qima = qima.scanLine(0);
+// const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
+// unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
+
+// for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
+// for (unsigned col = 0; col < ncols; ++col)
+// {
+// const value::rgb8& v = *ptr_ima++;
+// *ptr_qima++ = v.red();
+// *ptr_qima++ = v.green();
+// *ptr_qima++ = v.blue();
+// }
+
+// return qima;
+// }
+
+
+// template <typename I>
+// inline
+// QImage to_qimage_rgb8_4(const Image<I>& ima_)
+// {
+// const I& ima = exact(ima_);
+// mln_precondition(ima.is_valid());
+
+// const int
+// nrows = geom::nrows(ima),
+// ncols = geom::ncols(ima);
+
+
+// // Required by a one-shot data copy:
+// mln::border::resize(ima, 0);
+
+// QImage qima(ncols, nrows, QImage::Format_RGB32);
+// std::memcpy(qima.scanLine(0),
+// ima.buffer(),
+// ima.nelements() * 4);
+
+// return qima;
+// }
+
+
+// template <typename I>
+// inline
+// QImage to_qimage_rgb8_5(const Image<I>& ima_)
+// {
+// const I& ima = exact(ima_);
+// mln_precondition(ima.is_valid());
+
+// const int
+// nrows = geom::nrows(ima),
+// ncols = geom::ncols(ima);
+
+// QImage qima(ncols + 2 * ima.border(),
+// nrows + 2 * ima.border(),
+// QImage::Format_RGB32);
+// std::memcpy(qima.scanLine(0),
+// ima.buffer(),
+// ima.nelements() * 3);
+
+// return qima;
+// }
+
+
+
+ } // end of namespace mln::convert::implementation
+
+
+
+ // Dispatch
+
+ namespace internal
+ {
+
+ template <typename I, typename S>
+ inline
+ QImage to_qimage_dispatch(const Image<I>& ima, const
value::Scalar<S>&)
+ {
+ return implementation::to_qimage_scalar(ima);
+ }
+
+ template <typename I>
+ inline
+ QImage to_qimage_dispatch(const Image<I>& ima, const value::rgb8&)
+ {
+ return implementation::to_qimage_rgb8(ima);
+ }
+
+ template <typename I>
+ inline
+ QImage to_qimage_dispatch(const Image<I>& ima, const
value::qt::rgb32&)
+ {
+ return implementation::to_qimage_qt_rgb32(ima);
+ }
+
+
+ template <typename I, typename V>
+ inline
+ QImage to_qimage_dispatch(const Image<I>& ima, V&)
+ {
+ // Not supported yet!
+ mlc_abort(I)::check();
+ return QImage();
+ }
+
+
+ template <typename I>
+ inline
+ QImage to_qimage_dispatch(const Image<I>& ima)
+ {
+ typedef mln_value(I) V;
+ return to_qimage_dispatch(ima, V());
+ }
+
+ } // end of namespace mln::convert::internal
+
+
+
+ // Facade
+
+ template <typename I>
+ inline
+ QImage to_qimage(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ QImage output = internal::to_qimage_dispatch(ima);
+
+ return output;
+ }
+
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+#endif // ! MLN_CONVERT_TO_QIMAGE_HH
--
1.5.6.5