LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
lsstGil.h
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008, 2009, 2010 LSST Corporation.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 
30 #if !defined(GIL_LSST_H)
31 #define GIL_LSST_H 1
32 /*
33  * Extend the gil types to provide non-scaling float/int32 images, type bits32[fs]_noscale
34  */
35 #include "boost/mpl/assert.hpp"
36 #include "boost/mpl/bool.hpp"
37 #include "boost/mpl/if.hpp"
38 #include "boost/type_traits/is_same.hpp"
39 
40 //#define BOOST_GIL_USE_CONCEPT_CHECK 1
41 
42 #if defined(__ICC)
43 #pragma warning (push)
44 #pragma warning (disable: 68)
45 #pragma warning (disable: 304)
46 #endif
47 
48 #include "boost/gil/gil_all.hpp"
49 
50 #if defined(__ICC)
51 #pragma warning (pop)
52 #endif
53 
54 namespace lsst { namespace afw { namespace image {
55 
57 //
58 // We want to be able to call operator+= in the global namespace, but define it in lsst::afw::image.
59 // To make this possible, at least one of its arguments must be in lsst::afw::image, so we define
60 // this type to make the argument lookup ("Koenig Lookup") work smoothly
61 //
62 struct pair2I : public std::pair<int, int> {
63  explicit pair2I(int first, int second) : std::pair<int, int>(first, second) {}
64  pair2I(std::pair<int, int> pair) : std::pair<int, int>(pair) {}
65 };
66 
73 template <typename T>
74 boost::gil::memory_based_2d_locator<T>& operator+=(boost::gil::memory_based_2d_locator<T> &loc, pair2I off) {
75  return (loc += boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
76 }
81 template <typename T>
82 boost::gil::memory_based_2d_locator<T>& operator-=(boost::gil::memory_based_2d_locator<T> &loc, pair2I off) {
83  return (loc -= boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
84 }
85 
86 }}} // namespace lsst::afw::image
87 
92 template <typename T>
93 boost::gil::memory_based_2d_locator<T>& operator+=(boost::gil::memory_based_2d_locator<T> &loc,
94  std::pair<int, int> off) {
95  return (loc += boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
96 }
101 template <typename T>
102 boost::gil::memory_based_2d_locator<T>& operator-=(boost::gil::memory_based_2d_locator<T> &loc,
103  std::pair<int, int> off) {
104  return (loc -= boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
105 }
106 
107 namespace boost { namespace gil {
108 /*
109  * Define types that are pure (un)signed long, without scaling into [0, 1]
110  */
111 typedef uint64_t bits64;
112 typedef int64_t bits64s;
113 
114 GIL_DEFINE_BASE_TYPEDEFS(64, gray)
115 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64, dev2n, devicen_t<2>, devicen_layout_t<2>)
116 GIL_DEFINE_BASE_TYPEDEFS(64s, gray)
117 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64s, dev2n, devicen_t<2>, devicen_layout_t<2>)
118 
119 /*
120  * Define a type that's a pure float, without scaling into [0, 1]
121  */
122 typedef float bits32f_noscale;
123 
124 GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, gray)
125 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
126 
127 template<> struct channel_multiplier<bits32f_noscale> : public std::binary_function<bits32f_noscale,bits32f_noscale,bits32f_noscale> {
128  bits32f_noscale operator()(bits32f_noscale a, bits32f_noscale b) const { return a*b; }
129 };
130 
131 /*
132  * Define a type that's a pure double, without scaling into [0, 1]
133  */
134 typedef double bits64f_noscale;
135 
136 GIL_DEFINE_BASE_TYPEDEFS(64f_noscale, gray)
137 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
138 
139 /************************************************************************************************************/
140 //
141 // Conversions that don't scale
142 //
143 template <typename DstChannelV>
144 struct channel_converter<bits32f_noscale, DstChannelV> :
145  public std::unary_function<bits32f_noscale,DstChannelV> {
146  DstChannelV operator()(bits32f_noscale x) const { return DstChannelV(x + 0.5f); }
147 };
148 
149 template <typename SrcChannelV>
150 struct channel_converter<SrcChannelV,bits32f_noscale> :
151  public std::unary_function<SrcChannelV,bits32f_noscale> {
152  bits32f_noscale operator()(SrcChannelV x) const { return bits32f_noscale(x); }
153 };
154 
155 template <typename DstChannelV>
156 struct channel_converter<bits64f_noscale, DstChannelV> :
157  public std::unary_function<bits64f_noscale,DstChannelV> {
158  DstChannelV operator()(bits64f_noscale x) const { return DstChannelV(x + 0.5f); }
159 };
160 
161 template <typename SrcChannelV>
162 struct channel_converter<SrcChannelV,bits64f_noscale> :
163  public std::unary_function<SrcChannelV,bits64f_noscale> {
164  bits64f_noscale operator()(SrcChannelV x) const { return bits64f_noscale(x); }
165 };
166 
167 //
168 // Totally specialised templates to resolve ambiguities
169 //
170 #define LSST_CONVERT_NOOP(T1, T2) \
171 template <> \
172 struct channel_converter<T1, T2> : public std::unary_function<T1, T2> { \
173  T2 operator()(T1 x) const { return static_cast<T2>(x); } \
174 }; \
175 \
176 template <> \
177 struct channel_converter<T2, T1> : public std::unary_function<T2, T1> { \
178  T1 operator()(T2 x) const { return static_cast<T1>(x); } \
179 }
180 
181 LSST_CONVERT_NOOP(bits32f_noscale, bits64f_noscale);
182 
183 LSST_CONVERT_NOOP(unsigned char, short);
184 LSST_CONVERT_NOOP(unsigned char, unsigned short);
185 LSST_CONVERT_NOOP(unsigned char, int);
186 LSST_CONVERT_NOOP(unsigned short, short);
187 LSST_CONVERT_NOOP(unsigned short, int);
188 LSST_CONVERT_NOOP(short, int);
189 
190 #undef LSST_CONVERT_NOOP
191 
192 /************************************************************************************************************/
194 //
195 // These are in the boost::gil namespace in order to permit Koenig lookup
196 //
197 #define LSST_BOOST_GIL_OP_EQUALS(TYPE, OP) \
198 template<typename T2> \
199 TYPE##_pixel_t& operator OP##=(TYPE##_pixel_t& lhs, T2 rhs) { return (lhs = lhs OP rhs); }
200 
201 #define LSST_BOOST_GIL_OP_EQUALS_ALL(PIXTYPE) \
202  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, +) \
203  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, -) \
204  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, *) \
205  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, /) \
206  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, &) \
207  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, |)
208 
209 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8)
210 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8s)
211 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16)
212 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16s)
213 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32)
214 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32s)
215 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32f_noscale)
216 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64)
217 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64s)
218 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64f_noscale)
219 
220 #undef LSST_BOOST_GIL_OP_EQUALS
221 #undef LSST_BOOST_GIL_OP_EQUALS_ALL
222 
223 } } // namespace boost::gil
224 
225 
226 /************************************************************************************************************/
227 
228 namespace lsst { namespace afw { namespace image { namespace detail {
229  //
230  // Map typenames to gil's types
231  //
232 #if defined(__ICC)
233 #pragma warning (push)
234 #pragma warning (disable: 304)
235 #endif
236 
237  template<typename T, bool rescale=false> struct types_traits {
238  BOOST_MPL_ASSERT_MSG(boost::mpl::bool_<false>::value,
239  I_DO_NOT_KNOW_HOW_TO_MAP_THIS_TYPE_TO_A_GIL_TYPE,
240  ()
241  );
242  };
243 #if defined(__ICC)
244 #pragma warning (pop)
245 #endif
246 
247  template<> struct types_traits<unsigned char, false> {
248  typedef boost::gil::gray8_image_t image_t;
249  typedef boost::gil::gray8_view_t view_t;
250  typedef boost::gil::gray8c_view_t const_view_t;
251  typedef boost::gil::channel_traits<char>::reference reference;
252  typedef boost::gil::channel_traits<char>::const_reference const_reference;
253  };
254 
255  template<> struct types_traits<short, false> {
256  typedef boost::gil::gray16s_image_t image_t;
257  typedef boost::gil::gray16s_view_t view_t;
258  typedef boost::gil::gray16sc_view_t const_view_t;
259  typedef boost::gil::channel_traits<short>::reference reference;
260  typedef boost::gil::channel_traits<short>::const_reference const_reference;
261  };
262 
263  template<> struct types_traits<unsigned short, false> {
264  typedef boost::gil::gray16_image_t image_t;
265  typedef boost::gil::gray16_view_t view_t;
266  typedef boost::gil::gray16c_view_t const_view_t;
267  typedef boost::gil::channel_traits<unsigned short>::reference reference;
268  typedef boost::gil::channel_traits<unsigned short>::const_reference const_reference;
269  };
270 
271  template<> struct types_traits<int, false> {
272  typedef boost::gil::gray32s_image_t image_t;
273  typedef boost::gil::gray32s_view_t view_t;
274  typedef boost::gil::gray32sc_view_t const_view_t;
275  typedef boost::gil::channel_traits<int>::reference reference;
276  typedef boost::gil::channel_traits<int>::const_reference const_reference;
277  };
278 
279  template<> struct types_traits<unsigned int, false> {
280  typedef boost::gil::gray32_image_t image_t;
281  typedef boost::gil::gray32_view_t view_t;
282  typedef boost::gil::gray32c_view_t const_view_t;
283  typedef boost::gil::channel_traits<int>::reference reference;
284  typedef boost::gil::channel_traits<int>::const_reference const_reference;
285  };
286 
287  template<> struct types_traits<float, false> {
288  typedef boost::gil::gray32f_noscale_image_t image_t;
289  typedef boost::gil::gray32f_noscale_view_t view_t;
290  typedef boost::gil::gray32f_noscalec_view_t const_view_t;
291  typedef boost::gil::channel_traits<float>::reference reference;
292  typedef boost::gil::channel_traits<float>::const_reference const_reference;
293  };
294 
295  template<> struct types_traits<long, false> {
296  typedef boost::gil::gray64s_image_t image_t;
297  typedef boost::gil::gray64s_view_t view_t;
298  typedef boost::gil::gray64sc_view_t const_view_t;
299  typedef boost::gil::channel_traits<long>::reference reference;
300  typedef boost::gil::channel_traits<long>::const_reference const_reference;
301  };
302 
303  template<> struct types_traits<unsigned long, false> {
304  typedef boost::gil::gray64_image_t image_t;
305  typedef boost::gil::gray64_view_t view_t;
306  typedef boost::gil::gray64c_view_t const_view_t;
307  typedef boost::gil::channel_traits<long>::reference reference;
308  typedef boost::gil::channel_traits<long>::const_reference const_reference;
309  };
310 
311  namespace {
312  struct unknown {}; // two unused and unimplemented types
313  struct unknown_u {};
314  /*
315  * Return long long type (as type) if it's a synonym for boost::int64_t
316  * We also need unsigned long long (as type_u), because "unsigned unknown" won't compile
317  */
318  struct CheckBoost64 {
319  typedef boost::mpl::if_<boost::is_same<long long, boost::int64_t>,
320  long long, struct unknown>::type type;
321  typedef boost::mpl::if_<boost::is_same<long long, boost::int64_t>,
322  unsigned long long, struct unknown_u>::type type_u;
323  };
324  }
325 
326  template<> struct types_traits<CheckBoost64::type, false> {
327  typedef boost::gil::gray64s_image_t image_t;
328  typedef boost::gil::gray64s_view_t view_t;
329  typedef boost::gil::gray64sc_view_t const_view_t;
330  typedef boost::gil::channel_traits<long>::reference reference;
331  typedef boost::gil::channel_traits<long>::const_reference const_reference;
332  };
333 
334  template<> struct types_traits<CheckBoost64::type_u, false> {
335  typedef boost::gil::gray64_image_t image_t;
336  typedef boost::gil::gray64_view_t view_t;
337  typedef boost::gil::gray64c_view_t const_view_t;
338  typedef boost::gil::channel_traits<long>::reference reference;
339  typedef boost::gil::channel_traits<long>::const_reference const_reference;
340  };
341 
342  template<> struct types_traits<double, false> {
343  typedef boost::gil::gray64f_noscale_image_t image_t;
344  typedef boost::gil::gray64f_noscale_view_t view_t;
345  typedef boost::gil::gray64f_noscalec_view_t const_view_t;
346  typedef boost::gil::channel_traits<double>::reference reference;
347  typedef boost::gil::channel_traits<double>::const_reference const_reference;
348  };
349 
350  template<typename T>
351  struct const_iterator_type {
352  typedef typename boost::gil::const_iterator_type<T>::type type;
353  };
354 
355  template<typename T>
356  struct const_locator_type { // should assert that T is a locator
357  typedef typename T::const_t type;
358  };
359 
360  typedef boost::gil::point2<std::ptrdiff_t> difference_type; // type used to advance locators
361 }}}} // namespace lsst::afw::image::detail
362 
363 namespace boost { namespace gil {
364 
367 template <typename View1, typename View2, typename View3, typename ViewDest, typename F> GIL_FORCEINLINE
368 F transform_pixels(const View1& src1, const View2& src2,const View3& src3,const ViewDest& dst, F fun) {
369  for (std::ptrdiff_t y=0; y<dst.height(); ++y) {
370  typename View1::x_iterator srcIt1=src1.row_begin(y);
371  typename View2::x_iterator srcIt2=src2.row_begin(y);
372  typename View3::x_iterator srcIt3=src3.row_begin(y);
373  typename ViewDest::x_iterator dstIt=dst.row_begin(y);
374  for (std::ptrdiff_t x=0; x<dst.width(); ++x)
375  dstIt[x]=fun(srcIt1[x],srcIt2[x],srcIt3[x]);
376  }
377  return fun;
378 }
379 
382 template <typename View1, typename View2, typename View3, typename View4, typename ViewDest, typename F> GIL_FORCEINLINE
383 F transform_pixels(const View1& src1, const View2& src2,const View3& src3,const View4& src4,const ViewDest& dst, F fun) {
384  for (std::ptrdiff_t y=0; y<dst.height(); ++y) {
385  typename View1::x_iterator srcIt1=src1.row_begin(y);
386  typename View2::x_iterator srcIt2=src2.row_begin(y);
387  typename View3::x_iterator srcIt3=src3.row_begin(y);
388  typename View4::x_iterator srcIt4=src4.row_begin(y);
389  typename ViewDest::x_iterator dstIt=dst.row_begin(y);
390  for (std::ptrdiff_t x=0; x<dst.width(); ++x)
391  dstIt[x]=fun(srcIt1[x],srcIt2[x],srcIt3[x],srcIt4[x]);
392  }
393  return fun;
394 }
395 }} // namespace boost::gil
397 #endif
int y
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:429
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:439
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
int x
afw::table::Key< double > b
void operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Definition: Image.cc:854
void operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Definition: Image.cc:847