Milena (Olena)
User documentation 2.0a Id
|
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 (void) ima; 00258 00259 // Not supported yet! 00260 mlc_abort(I)::check(); 00261 return QImage(); 00262 } 00263 00264 00265 template <typename I> 00266 inline 00267 QImage to_qimage_dispatch(const Image<I>& ima) 00268 { 00269 typedef mln_value(I) V; 00270 return to_qimage_dispatch(ima, V()); 00271 } 00272 00273 } // end of namespace mln::convert::internal 00274 00275 00276 00277 // Facade 00278 00279 template <typename I> 00280 inline 00281 QImage to_qimage(const Image<I>& ima_) 00282 { 00283 trace::entering("convert::to_qimage"); 00284 00285 const I& ima = exact(ima_); 00286 mln_precondition(ima.is_valid()); 00287 00288 QImage output = internal::to_qimage_dispatch(ima); 00289 00290 trace::exiting("convert::to_qimage"); 00291 return output; 00292 } 00293 00294 00295 # endif // ! MLN_INCLUDE_ONLY 00296 00297 } // end of namespace mln::convert 00298 00299 } // end of namespace mln 00300 00301 #endif // ! MLN_CONVERT_TO_QIMAGE_HH