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