$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
to_qimage.hh
1 // Copyright (C) 2010, 2012 EPITA Research and Development Laboratory
2 // (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
30 
31 #ifndef MLN_CONVERT_TO_QIMAGE_HH
32 # define MLN_CONVERT_TO_QIMAGE_HH
33 
34 # include <QtGui/QImage>
35 
36 # include <mln/core/concept/image.hh>
37 # include <mln/geom/nrows.hh>
38 # include <mln/geom/ncols.hh>
39 # include <mln/border/resize.hh>
40 
41 
42 # include <mln/value/qt/rgb32.hh>
43 # include <mln/value/rgb8.hh>
44 
45 // FIXME: not generic.
46 # include <mln/core/alias/dpoint2d.hh>
47 
48 # if QT_VERSION < 0x040000
49 # error "Your version of Qt is too old and is not supported."
50 # endif
51 
52 
53 namespace mln
54 {
55 
56  namespace convert
57  {
58 
61  //
62  template <typename I>
63  inline
64  QImage
65  to_qimage(const Image<I>& ima);
66 
67 
68 # ifndef MLN_INCLUDE_ONLY
69 
70  // Implementation
71 
72  namespace impl
73  {
74 
75 
76  template <typename I>
77  inline
78  QImage to_qimage_scalar(const Image<I>& ima_)
79  {
80  const I& ima = exact(ima_);
81  mln_precondition(ima.is_valid());
82 
83  const unsigned
84  nrows = geom::nrows(ima),
85  ncols = geom::ncols(ima);
86 
87 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
88  QImage qima(ncols, nrows, QImage::Format_RGB32);
89  uchar * ptr_qima = qima.bits();
90  unsigned padding = 0;
91 # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
92  ++ptr_qima;
93 # endif // ! Q_BYTE_ORDER
94 # else
95  QImage qima(ncols, nrows, QImage::Format_RGB888);
96  uchar * ptr_qima = qima.bits();
97  unsigned padding = ncols % 4;
98 # endif // ! QT_VERSION
99 
100  const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
101  unsigned offset = ima.delta_offset(dpoint2d(+1, - ncols));
102 
103  // Data is stored as ABGR so we skip the first value which is ignored.
104  for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
105  {
106  for (unsigned col = 0; col < ncols; ++col)
107  {
108  const mln_value(I)& v = *ptr_ima++;
109  std::memset(ptr_qima, v, sizeof(mln_value(I)) * 3);
110 
111 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
112  ptr_qima += 4;
113 # else
114  ptr_qima += 3;
115 # endif // ! QT_VERSION
116  }
117  ptr_qima += padding;
118  }
119 
120  return qima;
121  }
122 
123 
124 
125 # if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
126 
127  template <typename I>
128  inline
129  QImage to_qimage_rgb8(const Image<I>& ima_)
130  {
131  const I& ima = exact(ima_);
132  mln_precondition(ima.is_valid());
133 
134  const int
135  nrows = geom::nrows(ima),
136  ncols = geom::ncols(ima);
137 
138  QImage qima(ncols, nrows, QImage::Format_RGB32);
139  uchar * ptr_qima = qima.scanLine(0);
140  const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
141  unsigned offset = ima.delta_offset(dpoint2d(+1, - ncols));
142 
143  for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
144  {
145  for (unsigned col = 0; col < ncols; ++col)
146  {
147  const mln::value::rgb8& v = *ptr_ima++;
148 # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
149  // Memory representation : BBGGRRFF
150  *ptr_qima++ = v.blue();
151  *ptr_qima++ = v.green();
152  *ptr_qima = v.red();
153  ptr_qima += 2;
154 # else /* Q_BIG_ENDIAN */
155  // Memory representation : FFRRGGBB
156  ++ptr_qima;
157  *ptr_qima++ = v.red();
158  *ptr_qima++ = v.green();
159  *ptr_qima = v.blue();
160 # endif // ! Q_BYTE_ORDER
161  }
162  }
163 
164  return qima;
165  }
166 
167 # else
168  template <typename I>
169  inline
170  QImage to_qimage_rgb8(const Image<I>& ima_)
171  {
172  const I& ima = exact(ima_);
173  mln_precondition(ima.is_valid());
174 
175  const int
176  nrows = geom::nrows(ima),
177  ncols = geom::ncols(ima);
178 
179 
180  typedef mln_site(I) P;
181  typedef mln_dpsite(P) DP;
182 
183  // Required by a one-shot data copy:
184  mln::border::resize(ima, 0);
185 
186  unsigned
187  offset = ima.delta_offset(DP(+1, 0)),
188  line_offset = 0;
189 
190  QImage qima(ncols, nrows, QImage::Format_RGB888);
191  for (int i = 0 ; i < qima.height(); ++i, line_offset += offset)
192  std::memcpy(qima.scanLine(i),
193  ima.buffer() + line_offset,
194  ima.ncols() * 3);
195 
196  return qima;
197  }
198 # endif // ! QT_VERSION
199 
200 
201  template <typename I>
202  inline
203  QImage to_qimage_qt_rgb32(const Image<I>& ima_)
204  {
205  const I& ima = exact(ima_);
206  mln_precondition(ima.is_valid());
207 
208  const int
209  nrows = geom::nrows(ima),
210  ncols = geom::ncols(ima);
211 
212 
213  // Required by a one-shot data copy:
214  mln::border::resize(ima, 0);
215 
216  QImage qima(ncols, nrows, QImage::Format_RGB32);
217  std::memcpy(qima.bits(), ima.buffer(), ima.nelements() * 4);
218 
219  return qima;
220  }
221 
222 
223  } // end of namespace mln::convert::impl
224 
225 
226 
227  // Dispatch
228 
229  namespace internal
230  {
231 
232  template <typename I, typename S>
233  inline
234  QImage to_qimage_dispatch(const Image<I>& ima, const value::Scalar<S>&)
235  {
236  return impl::to_qimage_scalar(ima);
237  }
238 
239  template <typename I>
240  inline
241  QImage to_qimage_dispatch(const Image<I>& ima, const value::rgb8&)
242  {
243  return impl::to_qimage_rgb8(ima);
244  }
245 
246  template <typename I>
247  inline
248  QImage to_qimage_dispatch(const Image<I>& ima, const value::qt::rgb32&)
249  {
250  return impl::to_qimage_qt_rgb32(ima);
251  }
252 
253 
254  template <typename I, typename V>
255  inline
256  QImage to_qimage_dispatch(const Image<I>& ima, V&)
257  {
258  (void) ima;
259 
260  // Not supported yet!
261  mlc_abort(I)::check();
262  return QImage();
263  }
264 
265 
266  template <typename I>
267  inline
268  QImage to_qimage_dispatch(const Image<I>& ima)
269  {
270  typedef mln_value(I) V;
271  return to_qimage_dispatch(ima, V());
272  }
273 
274  } // end of namespace mln::convert::internal
275 
276 
277 
278  // Facade
279 
280  template <typename I>
281  inline
282  QImage to_qimage(const Image<I>& ima_)
283  {
284  mln_trace("convert::to_qimage");
285 
286  const I& ima = exact(ima_);
287  mln_precondition(ima.is_valid());
288 
289  QImage output = internal::to_qimage_dispatch(ima);
290 
291  return output;
292  }
293 
294 
295 # endif // ! MLN_INCLUDE_ONLY
296 
297  } // end of namespace mln::convert
298 
299 } // end of namespace mln
300 
301 #endif // ! MLN_CONVERT_TO_QIMAGE_HH