• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

to_qimage.hh

00001 // Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00029 
00030 #ifndef MLN_CONVERT_TO_QIMAGE_HH
00031 # define MLN_CONVERT_TO_QIMAGE_HH
00032 
00033 # include <QtGui/QImage>
00034 
00035 # include <mln/core/concept/image.hh>
00036 # include <mln/geom/nrows.hh>
00037 # include <mln/geom/ncols.hh>
00038 # include <mln/border/resize.hh>
00039 
00040 
00041 # include <mln/value/qt/rgb32.hh>
00042 # include <mln/value/rgb8.hh>
00043 
00044 // FIXME: not generic.
00045 # include <mln/core/alias/dpoint2d.hh>
00046 
00047 # if QT_VERSION < 0x040000
00048 #  error "Your version of Qt is too old and is not supported."
00049 # endif
00050 
00051 
00052 namespace mln
00053 {
00054 
00055   namespace convert
00056   {
00057 
00060     //
00061     template <typename I>
00062     inline
00063     QImage
00064     to_qimage(const Image<I>& ima);
00065 
00066 
00067 # ifndef MLN_INCLUDE_ONLY
00068 
00069     // Implementation
00070 
00071     namespace impl
00072     {
00073 
00074 
00075       template <typename I>
00076       inline
00077       QImage to_qimage_scalar(const Image<I>& ima_)
00078       {
00079         const I& ima = exact(ima_);
00080         mln_precondition(ima.is_valid());
00081 
00082         const unsigned
00083           nrows = geom::nrows(ima),
00084           ncols = geom::ncols(ima);
00085 
00086 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
00087         QImage qima(ncols, nrows, QImage::Format_RGB32);
00088         uchar * ptr_qima = qima.bits();
00089         unsigned padding = 0;
00090 #  if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
00091         ++ptr_qima;
00092 #  endif // ! Q_BYTE_ORDER
00093 # else
00094         QImage qima(ncols, nrows, QImage::Format_RGB888);
00095         uchar * ptr_qima = qima.bits();
00096         unsigned padding = ncols % 4;
00097 # endif // ! QT_VERSION
00098 
00099         const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
00100         unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
00101 
00102         // Data is stored as ABGR so we skip the first value which is ignored.
00103         for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
00104         {
00105           for (unsigned col = 0; col < ncols; ++col)
00106           {
00107             const mln_value(I)& v = *ptr_ima++;
00108             std::memset(ptr_qima, v, sizeof(mln_value(I)) * 3);
00109 
00110 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
00111             ptr_qima += 4;
00112 # else
00113             ptr_qima += 3;
00114 # endif // ! QT_VERSION
00115           }
00116           ptr_qima += padding;
00117         }
00118 
00119         return qima;
00120       }
00121 
00122 
00123 
00124 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
00125 
00126       template <typename I>
00127       inline
00128       QImage to_qimage_rgb8(const Image<I>& ima_)
00129       {
00130         const I& ima = exact(ima_);
00131         mln_precondition(ima.is_valid());
00132 
00133         const int
00134           nrows = geom::nrows(ima),
00135           ncols = geom::ncols(ima);
00136 
00137         QImage qima(ncols, nrows, QImage::Format_RGB32);
00138         uchar * ptr_qima = qima.scanLine(0);
00139         const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
00140         unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
00141 
00142         for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
00143         {
00144           for (unsigned col = 0; col < ncols; ++col)
00145           {
00146             const mln::value::rgb8& v = *ptr_ima++;
00147 #  if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
00148             // Memory representation : BBGGRRFF
00149             *ptr_qima++ = v.blue();
00150             *ptr_qima++ = v.green();
00151             *ptr_qima = v.red();
00152             ptr_qima += 2;
00153 #  else /* Q_BIG_ENDIAN */
00154             // Memory representation : FFRRGGBB
00155             ++ptr_qima;
00156             *ptr_qima++ = v.red();
00157             *ptr_qima++ = v.green();
00158             *ptr_qima = v.blue();
00159 #  endif // ! Q_BYTE_ORDER
00160           }
00161         }
00162 
00163         return qima;
00164       }
00165 
00166 # else
00167       template <typename I>
00168       inline
00169       QImage to_qimage_rgb8(const Image<I>& ima_)
00170       {
00171         const I& ima = exact(ima_);
00172         mln_precondition(ima.is_valid());
00173 
00174         const int
00175           nrows = geom::nrows(ima),
00176           ncols = geom::ncols(ima);
00177 
00178 
00179         typedef mln_site(I) P;
00180         typedef mln_dpsite(P) DP;
00181 
00182         // Required by a one-shot data copy:
00183         mln::border::resize(ima, 0);
00184 
00185         unsigned
00186           offset = ima.delta_index(DP(+1, 0)),
00187           line_offset = 0;
00188 
00189         QImage qima(ncols, nrows, QImage::Format_RGB888);
00190         for (int i = 0 ; i < qima.height(); ++i, line_offset += offset)
00191           std::memcpy(qima.scanLine(i),
00192                       ima.buffer() + line_offset,
00193                       ima.ncols() * 3);
00194 
00195         return qima;
00196       }
00197 # endif // ! QT_VERSION
00198 
00199 
00200       template <typename I>
00201       inline
00202       QImage to_qimage_qt_rgb32(const Image<I>& ima_)
00203       {
00204         const I& ima = exact(ima_);
00205         mln_precondition(ima.is_valid());
00206 
00207         const int
00208           nrows = geom::nrows(ima),
00209           ncols = geom::ncols(ima);
00210 
00211 
00212         // Required by a one-shot data copy:
00213         mln::border::resize(ima, 0);
00214 
00215         QImage qima(ncols, nrows, QImage::Format_RGB32);
00216         std::memcpy(qima.bits(), ima.buffer(), ima.nelements() * 4);
00217 
00218         return qima;
00219       }
00220 
00221 
00222     } // end of namespace mln::convert::impl
00223 
00224 
00225 
00226     // Dispatch
00227 
00228     namespace internal
00229     {
00230 
00231       template <typename I, typename S>
00232       inline
00233       QImage to_qimage_dispatch(const Image<I>& ima, const value::Scalar<S>&)
00234       {
00235         return impl::to_qimage_scalar(ima);
00236       }
00237 
00238       template <typename I>
00239       inline
00240       QImage to_qimage_dispatch(const Image<I>& ima, const value::rgb8&)
00241       {
00242         return impl::to_qimage_rgb8(ima);
00243       }
00244 
00245       template <typename I>
00246       inline
00247       QImage to_qimage_dispatch(const Image<I>& ima, const value::qt::rgb32&)
00248       {
00249         return impl::to_qimage_qt_rgb32(ima);
00250       }
00251 
00252 
00253       template <typename I, typename V>
00254       inline
00255       QImage to_qimage_dispatch(const Image<I>& ima, V&)
00256       {
00257         // Not supported yet!
00258         mlc_abort(I)::check();
00259         return QImage();
00260       }
00261 
00262 
00263       template <typename I>
00264       inline
00265       QImage to_qimage_dispatch(const Image<I>& ima)
00266       {
00267         typedef mln_value(I) V;
00268         return to_qimage_dispatch(ima, V());
00269       }
00270 
00271     } // end of namespace mln::convert::internal
00272 
00273 
00274 
00275     // Facade
00276 
00277     template <typename I>
00278     inline
00279     QImage to_qimage(const Image<I>& ima_)
00280     {
00281       trace::entering("convert::to_qimage");
00282 
00283       const I& ima = exact(ima_);
00284       mln_precondition(ima.is_valid());
00285 
00286       QImage output = internal::to_qimage_dispatch(ima);
00287 
00288       trace::exiting("convert::to_qimage");
00289       return output;
00290     }
00291 
00292 
00293 # endif // ! MLN_INCLUDE_ONLY
00294 
00295   } // end of namespace mln::convert
00296 
00297 } // end of namespace mln
00298 
00299 #endif // ! MLN_CONVERT_TO_QIMAGE_HH

Generated on Tue Oct 4 2011 15:24:42 for Milena (Olena) by  doxygen 1.7.1