LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
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 
23 /*
24  * Types and classes to interface lsst::afw::image to boost::gil
25  *
26  * Tell doxygen to (usually) ignore this file
27  */
29 
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 {
58 namespace afw {
59 namespace image {
60 
62 //
63 /* We want to be able to call operator+= in the global namespace, but define it in lsst::afw::image.
64  * To make this possible, at least one of its arguments must be in lsst::afw::image, so we define
65  * this type to make the argument lookup ("Koenig Lookup") work smoothly
66  */
67 struct pair2I : public std::pair<int, int> {
68  explicit pair2I(int first, int second) : std::pair<int, int>(first, second) {}
69  pair2I(std::pair<int, int> pair) : std::pair<int, int>(pair) {}
70 };
71 
78 template <typename T>
79 boost::gil::memory_based_2d_locator<T>& operator+=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
80  return (loc += boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
81 }
86 template <typename T>
87 boost::gil::memory_based_2d_locator<T>& operator-=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
88  return (loc -= boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
89 }
90 } // namespace image
91 } // namespace afw
92 } // namespace lsst
93 
94 namespace boost {
95 namespace gil {
100 template <typename T>
101 memory_based_2d_locator<T>& operator+=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
102  return (loc += point2<std::ptrdiff_t>(off.first, off.second));
103 }
108 template <typename T>
109 memory_based_2d_locator<T>& operator-=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
110  return (loc -= point2<std::ptrdiff_t>(off.first, off.second));
111 }
112 
113 /*
114  * Define types that are pure (un)signed long, without scaling into [0, 1]
115  */
116 typedef uint64_t bits64;
117 typedef int64_t bits64s;
118 
119 GIL_DEFINE_BASE_TYPEDEFS(64, bits64, gray)
120 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64, bits64, dev2n, devicen_t<2>, devicen_layout_t<2>)
121 GIL_DEFINE_BASE_TYPEDEFS(64s, bits64s, gray)
122 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64s, bits64s, dev2n, devicen_t<2>, devicen_layout_t<2>)
123 
124 /*
125  * Define a type that's a pure float, without scaling into [0, 1]
126  */
127 typedef float bits32f_noscale;
128 
129 GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, bits32f_noscale, gray)
130 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, bits32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
131 
132 template <>
133 struct channel_multiplier<bits32f_noscale>
134  : public std::binary_function<bits32f_noscale, bits32f_noscale, bits32f_noscale> {
135  bits32f_noscale operator()(bits32f_noscale a, bits32f_noscale b) const { return a * b; }
136 };
137 
138 /*
139  * Define a type that's a pure double, without scaling into [0, 1]
140  */
141 typedef double bits64f_noscale;
142 
143 GIL_DEFINE_BASE_TYPEDEFS(64f_noscale, bits64f_noscale, gray)
144 GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64f_noscale, bits64f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
145 
146 //
147 // Conversions that don't scale
148 //
149 template <typename DstChannelV>
150 struct channel_converter<bits32f_noscale, DstChannelV>
151  : public std::unary_function<bits32f_noscale, DstChannelV> {
152  DstChannelV operator()(bits32f_noscale x) const { return DstChannelV(x + 0.5f); }
153 };
154 
155 template <typename SrcChannelV>
156 struct channel_converter<SrcChannelV, bits32f_noscale>
157  : public std::unary_function<SrcChannelV, bits32f_noscale> {
158  bits32f_noscale operator()(SrcChannelV x) const { return bits32f_noscale(x); }
159 };
160 
161 template <typename DstChannelV>
162 struct channel_converter<bits64f_noscale, DstChannelV>
163  : public std::unary_function<bits64f_noscale, DstChannelV> {
164  DstChannelV operator()(bits64f_noscale x) const { return DstChannelV(x + 0.5f); }
165 };
166 
167 template <typename SrcChannelV>
168 struct channel_converter<SrcChannelV, bits64f_noscale>
169  : public std::unary_function<SrcChannelV, bits64f_noscale> {
170  bits64f_noscale operator()(SrcChannelV x) const { return bits64f_noscale(x); }
171 };
172 
173 //
174 // Totally specialised templates to resolve ambiguities
175 //
176 #define LSST_CONVERT_NOOP(T1, T2) \
177  template <> \
178  struct channel_converter<T1, T2> : public std::unary_function<T1, T2> { \
179  T2 operator()(T1 x) const { return static_cast<T2>(x); } \
180  }; \
181  \
182  template <> \
183  struct channel_converter<T2, T1> : public std::unary_function<T2, T1> { \
184  T1 operator()(T2 x) const { return static_cast<T1>(x); } \
185  }
186 
187 LSST_CONVERT_NOOP(bits32f_noscale, bits64f_noscale);
188 
189 LSST_CONVERT_NOOP(unsigned char, short);
190 LSST_CONVERT_NOOP(unsigned char, unsigned short);
191 LSST_CONVERT_NOOP(unsigned char, int);
192 LSST_CONVERT_NOOP(unsigned short, short);
193 LSST_CONVERT_NOOP(unsigned short, int);
194 LSST_CONVERT_NOOP(short, int);
195 
196 #undef LSST_CONVERT_NOOP
197 
199 //
200 // These are in the boost::gil namespace in order to permit Koenig lookup
201 //
202 #define LSST_BOOST_GIL_OP_EQUALS(TYPE, OP) \
203  template <typename T2> \
204  TYPE##_pixel_t& operator OP##=(TYPE##_pixel_t& lhs, T2 rhs) { \
205  return (lhs = lhs OP rhs); \
206  }
207 
208 #define LSST_BOOST_GIL_OP_EQUALS_ALL(PIXTYPE) \
209  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, +) \
210  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, -) \
211  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, *) \
212  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, /) \
213  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, &) \
214  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, |)
215 
216 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8)
217 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8s)
218 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16)
219 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16s)
220 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32)
221 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32s)
222 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32f_noscale)
223 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64)
224 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64s)
225 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64f_noscale)
226 
227 #undef LSST_BOOST_GIL_OP_EQUALS
228 #undef LSST_BOOST_GIL_OP_EQUALS_ALL
229 } // namespace gil
230 } // namespace boost
231 
232 namespace lsst {
233 namespace afw {
234 namespace image {
235 namespace detail {
236 //
237 // Map typenames to gil's types
238 //
239 #if defined(__ICC)
240 #pragma warning(push)
241 #pragma warning(disable : 304)
242 #endif
243 
244 template <typename T, bool rescale = false>
245 struct types_traits {
246  BOOST_MPL_ASSERT_MSG(boost::mpl::bool_<false>::value, I_DO_NOT_KNOW_HOW_TO_MAP_THIS_TYPE_TO_A_GIL_TYPE,
247  ());
248 };
249 #if defined(__ICC)
250 #pragma warning(pop)
251 #endif
252 
253 template <>
254 struct types_traits<unsigned char, false> {
255  typedef boost::gil::gray8_image_t image_t;
256  typedef boost::gil::gray8_view_t view_t;
257  typedef boost::gil::gray8c_view_t const_view_t;
258  typedef boost::gil::channel_traits<char>::reference reference;
259  typedef boost::gil::channel_traits<char>::const_reference const_reference;
260 };
261 
262 template <>
263 struct types_traits<short, false> {
264  typedef boost::gil::gray16s_image_t image_t;
265  typedef boost::gil::gray16s_view_t view_t;
266  typedef boost::gil::gray16sc_view_t const_view_t;
267  typedef boost::gil::channel_traits<short>::reference reference;
268  typedef boost::gil::channel_traits<short>::const_reference const_reference;
269 };
270 
271 template <>
272 struct types_traits<unsigned short, false> {
273  typedef boost::gil::gray16_image_t image_t;
274  typedef boost::gil::gray16_view_t view_t;
275  typedef boost::gil::gray16c_view_t const_view_t;
276  typedef boost::gil::channel_traits<unsigned short>::reference reference;
277  typedef boost::gil::channel_traits<unsigned short>::const_reference const_reference;
278 };
279 
280 template <>
281 struct types_traits<int, false> {
282  typedef boost::gil::gray32s_image_t image_t;
283  typedef boost::gil::gray32s_view_t view_t;
284  typedef boost::gil::gray32sc_view_t const_view_t;
285  typedef boost::gil::channel_traits<int>::reference reference;
286  typedef boost::gil::channel_traits<int>::const_reference const_reference;
287 };
288 
289 template <>
290 struct types_traits<unsigned int, false> {
291  typedef boost::gil::gray32_image_t image_t;
292  typedef boost::gil::gray32_view_t view_t;
293  typedef boost::gil::gray32c_view_t const_view_t;
294  typedef boost::gil::channel_traits<int>::reference reference;
295  typedef boost::gil::channel_traits<int>::const_reference const_reference;
296 };
297 
298 template <>
299 struct types_traits<float, false> {
300  typedef boost::gil::gray32f_noscale_image_t image_t;
301  typedef boost::gil::gray32f_noscale_view_t view_t;
302  typedef boost::gil::gray32f_noscalec_view_t const_view_t;
303  typedef boost::gil::channel_traits<float>::reference reference;
304  typedef boost::gil::channel_traits<float>::const_reference const_reference;
305 };
306 
307 template <>
308 struct types_traits<long, false> {
309  typedef boost::gil::gray64s_image_t image_t;
310  typedef boost::gil::gray64s_view_t view_t;
311  typedef boost::gil::gray64sc_view_t const_view_t;
312  typedef boost::gil::channel_traits<long>::reference reference;
313  typedef boost::gil::channel_traits<long>::const_reference const_reference;
314 };
315 
316 template <>
317 struct types_traits<unsigned long, false> {
318  typedef boost::gil::gray64_image_t image_t;
319  typedef boost::gil::gray64_view_t view_t;
320  typedef boost::gil::gray64c_view_t const_view_t;
321  typedef boost::gil::channel_traits<long>::reference reference;
322  typedef boost::gil::channel_traits<long>::const_reference const_reference;
323 };
324 
325 namespace {
326 struct unknown {}; // two unused and unimplemented types
327 struct unknown_u {};
328 /*
329  * Return long long type (as type) if it's a synonym for std::int64_t
330  * We also need unsigned long long (as type_u), because "unsigned unknown" won't compile
331  */
332 struct CheckBoost64 {
333  typedef boost::mpl::if_<std::is_same<long long, std::int64_t>, long long, struct unknown>::type type;
334  typedef boost::mpl::if_<std::is_same<long long, std::int64_t>, unsigned long long, struct unknown_u>::type
335  type_u;
336 };
337 } // namespace
338 
339 template <>
340 struct types_traits<CheckBoost64::type, false> {
341  typedef boost::gil::gray64s_image_t image_t;
342  typedef boost::gil::gray64s_view_t view_t;
343  typedef boost::gil::gray64sc_view_t const_view_t;
344  typedef boost::gil::channel_traits<long>::reference reference;
345  typedef boost::gil::channel_traits<long>::const_reference const_reference;
346 };
347 
348 template <>
349 struct types_traits<CheckBoost64::type_u, false> {
350  typedef boost::gil::gray64_image_t image_t;
351  typedef boost::gil::gray64_view_t view_t;
352  typedef boost::gil::gray64c_view_t const_view_t;
353  typedef boost::gil::channel_traits<long>::reference reference;
354  typedef boost::gil::channel_traits<long>::const_reference const_reference;
355 };
356 
357 template <>
358 struct types_traits<double, false> {
359  typedef boost::gil::gray64f_noscale_image_t image_t;
360  typedef boost::gil::gray64f_noscale_view_t view_t;
361  typedef boost::gil::gray64f_noscalec_view_t const_view_t;
362  typedef boost::gil::channel_traits<double>::reference reference;
363  typedef boost::gil::channel_traits<double>::const_reference const_reference;
364 };
365 
366 template <typename T>
367 struct const_iterator_type {
369 };
370 
371 template <typename T>
372 struct const_locator_type { // should assert that T is a locator
373  typedef typename T::const_t type;
374 };
375 
376 typedef boost::gil::point2<std::ptrdiff_t> difference_type; // type used to advance locators
377 }
378 } // namespace image
379 } // namespace afw
380 } // namespace lsst
381 
382 namespace boost {
383 namespace gil {
384 
386 template <typename View1, typename View2, typename View3, typename ViewDest, typename F>
387 BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3,
388  const ViewDest& dst, F fun) {
389  for (std::ptrdiff_t y = 0; y < dst.height(); ++y) {
390  typename View1::x_iterator srcIt1 = src1.row_begin(y);
391  typename View2::x_iterator srcIt2 = src2.row_begin(y);
392  typename View3::x_iterator srcIt3 = src3.row_begin(y);
393  typename ViewDest::x_iterator dstIt = dst.row_begin(y);
394  for (std::ptrdiff_t x = 0; x < dst.width(); ++x) dstIt[x] = fun(srcIt1[x], srcIt2[x], srcIt3[x]);
395  }
396  return fun;
397 }
398 
400 template <typename View1, typename View2, typename View3, typename View4, typename ViewDest, typename F>
401 BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3, const View4& src4,
402  const ViewDest& dst, F fun) {
403  for (std::ptrdiff_t y = 0; y < dst.height(); ++y) {
404  typename View1::x_iterator srcIt1 = src1.row_begin(y);
405  typename View2::x_iterator srcIt2 = src2.row_begin(y);
406  typename View3::x_iterator srcIt3 = src3.row_begin(y);
407  typename View4::x_iterator srcIt4 = src4.row_begin(y);
408  typename ViewDest::x_iterator dstIt = dst.row_begin(y);
409  for (std::ptrdiff_t x = 0; x < dst.width(); ++x)
410  dstIt[x] = fun(srcIt1[x], srcIt2[x], srcIt3[x], srcIt4[x]);
411  }
412  return fun;
413 }
414 } // namespace gil
415 } // namespace boost
416 #endif
417 
Definition: Polygon.cc:25
Image< LhsPixelT > & operator+=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Add lhs to Image rhs (i.e. pixel-by-pixel addition) where types are different.
Definition: Image.cc:680
table::Key< int > b
int y
Definition: SpanSet.cc:49
table::Key< int > a
STL namespace.
A base class for image defects.
table::Key< int > type
Definition: Detector.cc:164
solver_t * s
double x
Image< LhsPixelT > & operator-=(Image< LhsPixelT > &lhs, Image< RhsPixelT > const &rhs)
Subtract lhs from Image rhs (i.e. pixel-by-pixel subtraction) where types are different.
Definition: Image.cc:686