00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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 offset = ima.delta_index(dpoint2d(+1, - ncols));
00090 unsigned padding = 0;
00091 # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
00092 ++ptr_qima;
00093 # endif // ! Q_BYTE_ORDER
00094 # else
00095 QImage qima(ncols, nrows, QImage::Format_RGB888);
00096 uchar * ptr_qima = qima.bits();
00097 unsigned padding = ncols % 4;
00098 # endif // ! QT_VERSION
00099
00100 const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
00101 unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
00102
00103
00104 for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
00105 {
00106 for (unsigned col = 0; col < ncols; ++col)
00107 {
00108 const mln_value(I)& v = *ptr_ima++;
00109 std::memset(ptr_qima, v, sizeof(mln_value(I)) * 3);
00110
00111 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
00112 ptr_qima += 4;
00113 # else
00114 ptr_qima += 3;
00115 # endif // ! QT_VERSION
00116 }
00117 ptr_qima += padding;
00118 }
00119
00120 return qima;
00121 }
00122
00123
00124
00125 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
00126
00127 template <typename I>
00128 inline
00129 QImage to_qimage_rgb8(const Image<I>& ima_)
00130 {
00131 const I& ima = exact(ima_);
00132 mln_precondition(ima.is_valid());
00133
00134 const int
00135 nrows = geom::nrows(ima),
00136 ncols = geom::ncols(ima);
00137
00138 QImage qima(ncols, nrows, QImage::Format_RGB32);
00139 uchar * ptr_qima = qima.scanLine(0);
00140 const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
00141 unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
00142
00143 for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
00144 {
00145 for (unsigned col = 0; col < ncols; ++col)
00146 {
00147 const mln::value::rgb8& v = *ptr_ima++;
00148 # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
00149
00150 *ptr_qima++ = v.blue();
00151 *ptr_qima++ = v.green();
00152 *ptr_qima = v.red();
00153 ptr_qima += 2;
00154 # else
00155
00156 ++ptr_qima;
00157 *ptr_qima++ = v.red();
00158 *ptr_qima++ = v.green();
00159 *ptr_qima = v.blue();
00160 # endif // ! Q_BYTE_ORDER
00161 }
00162 }
00163
00164 return qima;
00165 }
00166
00167 # else
00168 template <typename I>
00169 inline
00170 QImage to_qimage_rgb8(const Image<I>& ima_)
00171 {
00172 const I& ima = exact(ima_);
00173 mln_precondition(ima.is_valid());
00174
00175 const int
00176 nrows = geom::nrows(ima),
00177 ncols = geom::ncols(ima);
00178
00179
00180 typedef mln_site(I) P;
00181 typedef mln_dpsite(P) DP;
00182
00183
00184 mln::border::resize(ima, 0);
00185
00186 unsigned
00187 offset = ima.delta_index(DP(+1, 0)),
00188 line_offset = 0;
00189
00190 QImage qima(ncols, nrows, QImage::Format_RGB888);
00191 for (int i = 0 ; i < qima.height(); ++i, line_offset += offset)
00192 std::memcpy(qima.scanLine(i),
00193 ima.buffer() + line_offset,
00194 ima.ncols() * 3);
00195
00196 return qima;
00197 }
00198 # endif // ! QT_VERSION
00199
00200
00201 template <typename I>
00202 inline
00203 QImage to_qimage_qt_rgb32(const Image<I>& ima_)
00204 {
00205 const I& ima = exact(ima_);
00206 mln_precondition(ima.is_valid());
00207
00208 const int
00209 nrows = geom::nrows(ima),
00210 ncols = geom::ncols(ima);
00211
00212
00213
00214 mln::border::resize(ima, 0);
00215
00216 QImage qima(ncols, nrows, QImage::Format_RGB32);
00217 std::memcpy(qima.bits(), ima.buffer(), ima.nelements() * 4);
00218
00219 return qima;
00220 }
00221
00222
00223 }
00224
00225
00226
00227
00228
00229 namespace internal
00230 {
00231
00232 template <typename I, typename S>
00233 inline
00234 QImage to_qimage_dispatch(const Image<I>& ima, const value::Scalar<S>&)
00235 {
00236 return impl::to_qimage_scalar(ima);
00237 }
00238
00239 template <typename I>
00240 inline
00241 QImage to_qimage_dispatch(const Image<I>& ima, const value::rgb8&)
00242 {
00243 return impl::to_qimage_rgb8(ima);
00244 }
00245
00246 template <typename I>
00247 inline
00248 QImage to_qimage_dispatch(const Image<I>& ima, const value::qt::rgb32&)
00249 {
00250 return impl::to_qimage_qt_rgb32(ima);
00251 }
00252
00253
00254 template <typename I, typename V>
00255 inline
00256 QImage to_qimage_dispatch(const Image<I>& ima, V&)
00257 {
00258
00259 mlc_abort(I)::check();
00260 return QImage();
00261 }
00262
00263
00264 template <typename I>
00265 inline
00266 QImage to_qimage_dispatch(const Image<I>& ima)
00267 {
00268 typedef mln_value(I) V;
00269 return to_qimage_dispatch(ima, V());
00270 }
00271
00272 }
00273
00274
00275
00276
00277
00278 template <typename I>
00279 inline
00280 QImage to_qimage(const Image<I>& ima_)
00281 {
00282 trace::entering("convert::to_qimage");
00283
00284 const I& ima = exact(ima_);
00285 mln_precondition(ima.is_valid());
00286
00287 QImage output = internal::to_qimage_dispatch(ima);
00288
00289 trace::exiting("convert::to_qimage");
00290 return output;
00291 }
00292
00293
00294 # endif // ! MLN_INCLUDE_ONLY
00295
00296 }
00297
00298 }
00299
00300 #endif // ! MLN_CONVERT_TO_QIMAGE_HH