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 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
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
00149 *ptr_qima++ = v.blue();
00150 *ptr_qima++ = v.green();
00151 *ptr_qima = v.red();
00152 ptr_qima += 2;
00153 # else
00154
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
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
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 }
00223
00224
00225
00226
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
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 }
00272
00273
00274
00275
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 }
00296
00297 }
00298
00299 #endif // ! MLN_CONVERT_TO_QIMAGE_HH