LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
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/version.hpp"
52 #if BOOST_VERSION < 106900
53 #include "boost/gil/gil_all.hpp"
54 #else
55 #include "boost/gil.hpp"
56 #endif
57 
58 #ifndef BOOST_GIL_DEFINE_BASE_TYPEDEFS
59 // Boost >=1.72 redefines GIL_ -> BOOST_GIL
60 // Add these for compatibility
61 #define BOOST_GIL_DEFINE_BASE_TYPEDEFS GIL_DEFINE_BASE_TYPEDEFS
62 #define BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL GIL_DEFINE_ALL_TYPEDEFS_INTERNAL
63 #endif
64 
65 #if defined(__ICC)
66 #pragma warning(pop)
67 #endif
68 
69 namespace lsst {
70 namespace afw {
71 namespace image {
72 
74 //
75 /* We want to be able to call operator+= in the global namespace, but define it in lsst::afw::image.
76  * To make this possible, at least one of its arguments must be in lsst::afw::image, so we define
77  * this type to make the argument lookup ("Koenig Lookup") work smoothly
78  */
79 struct pair2I : public std::pair<int, int> {
80  explicit pair2I(int first, int second) : std::pair<int, int>(first, second) {}
81  pair2I(std::pair<int, int> pair) : std::pair<int, int>(pair) {}
82 };
83 
90 template <typename T>
91 boost::gil::memory_based_2d_locator<T>& operator+=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
92  return (loc += boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
93 }
98 template <typename T>
99 boost::gil::memory_based_2d_locator<T>& operator-=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
100  return (loc -= boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
101 }
102 } // namespace image
103 } // namespace afw
104 } // namespace lsst
105 
106 namespace boost {
107 namespace gil {
112 template <typename T>
113 memory_based_2d_locator<T>& operator+=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
114  return (loc += point2<std::ptrdiff_t>(off.first, off.second));
115 }
120 template <typename T>
121 memory_based_2d_locator<T>& operator-=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
122  return (loc -= point2<std::ptrdiff_t>(off.first, off.second));
123 }
124 
125 /*
126  * Define types that are pure (un)signed long, without scaling into [0, 1]
127  */
128 typedef uint64_t bits64;
129 typedef int64_t bits64s;
130 
131 BOOST_GIL_DEFINE_BASE_TYPEDEFS(64, bits64, gray)
132 BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64, bits64, dev2n, devicen_t<2>, devicen_layout_t<2>)
133 BOOST_GIL_DEFINE_BASE_TYPEDEFS(64s, bits64s, gray)
134 BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64s, bits64s, dev2n, devicen_t<2>, devicen_layout_t<2>)
135 
136 /*
137  * Define a type that's a pure float, without scaling into [0, 1]
138  */
139 typedef float bits32f_noscale;
140 
141 BOOST_GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, bits32f_noscale, gray)
142 BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, bits32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
143 
144 template <>
145 struct channel_multiplier<bits32f_noscale>
146  : public std::binary_function<bits32f_noscale, bits32f_noscale, bits32f_noscale> {
147  bits32f_noscale operator()(bits32f_noscale a, bits32f_noscale b) const { return a * b; }
148 };
149 
150 /*
151  * Define a type that's a pure double, without scaling into [0, 1]
152  */
153 typedef double bits64f_noscale;
154 
155 BOOST_GIL_DEFINE_BASE_TYPEDEFS(64f_noscale, bits64f_noscale, gray)
156 BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64f_noscale, bits64f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
157 
158 //
159 // Conversions that don't scale
160 //
161 template <typename DstChannelV>
162 struct channel_converter<bits32f_noscale, DstChannelV>
163  : public std::unary_function<bits32f_noscale, DstChannelV> {
164  DstChannelV operator()(bits32f_noscale x) const { return DstChannelV(x + 0.5f); }
165 };
166 
167 template <typename SrcChannelV>
168 struct channel_converter<SrcChannelV, bits32f_noscale>
169  : public std::unary_function<SrcChannelV, bits32f_noscale> {
170  bits32f_noscale operator()(SrcChannelV x) const { return bits32f_noscale(x); }
171 };
172 
173 template <typename DstChannelV>
174 struct channel_converter<bits64f_noscale, DstChannelV>
175  : public std::unary_function<bits64f_noscale, DstChannelV> {
176  DstChannelV operator()(bits64f_noscale x) const { return DstChannelV(x + 0.5f); }
177 };
178 
179 template <typename SrcChannelV>
180 struct channel_converter<SrcChannelV, bits64f_noscale>
181  : public std::unary_function<SrcChannelV, bits64f_noscale> {
182  bits64f_noscale operator()(SrcChannelV x) const { return bits64f_noscale(x); }
183 };
184 
185 //
186 // Totally specialised templates to resolve ambiguities
187 //
188 #define LSST_CONVERT_NOOP(T1, T2) \
189  template <> \
190  struct channel_converter<T1, T2> : public std::unary_function<T1, T2> { \
191  T2 operator()(T1 x) const { return static_cast<T2>(x); } \
192  }; \
193  \
194  template <> \
195  struct channel_converter<T2, T1> : public std::unary_function<T2, T1> { \
196  T1 operator()(T2 x) const { return static_cast<T1>(x); } \
197  }
198 
199 LSST_CONVERT_NOOP(bits32f_noscale, bits64f_noscale);
200 
201 LSST_CONVERT_NOOP(unsigned char, short);
202 LSST_CONVERT_NOOP(unsigned char, unsigned short);
203 LSST_CONVERT_NOOP(unsigned char, int);
204 LSST_CONVERT_NOOP(unsigned short, short);
205 LSST_CONVERT_NOOP(unsigned short, int);
206 LSST_CONVERT_NOOP(short, int);
207 
208 #undef LSST_CONVERT_NOOP
209 
211 //
212 // These are in the boost::gil namespace in order to permit Koenig lookup
213 //
214 #define LSST_BOOST_GIL_OP_EQUALS(TYPE, OP) \
215  template <typename T2> \
216  TYPE##_pixel_t& operator OP##=(TYPE##_pixel_t& lhs, T2 rhs) { \
217  return (lhs = lhs OP rhs); \
218  }
219 
220 #define LSST_BOOST_GIL_OP_EQUALS_ALL(PIXTYPE) \
221  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, +) \
222  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, -) \
223  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, *) \
224  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, /) \
225  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, &) \
226  LSST_BOOST_GIL_OP_EQUALS(PIXTYPE, |)
227 
228 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8)
229 LSST_BOOST_GIL_OP_EQUALS_ALL(gray8s)
230 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16)
231 LSST_BOOST_GIL_OP_EQUALS_ALL(gray16s)
232 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32)
233 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32s)
234 LSST_BOOST_GIL_OP_EQUALS_ALL(gray32f_noscale)
235 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64)
236 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64s)
237 LSST_BOOST_GIL_OP_EQUALS_ALL(gray64f_noscale)
238 
239 #undef LSST_BOOST_GIL_OP_EQUALS
240 #undef LSST_BOOST_GIL_OP_EQUALS_ALL
241 } // namespace gil
242 } // namespace boost
243 
244 namespace lsst {
245 namespace afw {
246 namespace image {
247 namespace detail {
248 //
249 // Map typenames to gil's types
250 //
251 #if defined(__ICC)
252 #pragma warning(push)
253 #pragma warning(disable : 304)
254 #endif
255 
256 template <typename T, bool rescale = false>
257 struct types_traits {
258  BOOST_MPL_ASSERT_MSG(boost::mpl::bool_<false>::value, I_DO_NOT_KNOW_HOW_TO_MAP_THIS_TYPE_TO_A_GIL_TYPE,
259  ());
260 };
261 #if defined(__ICC)
262 #pragma warning(pop)
263 #endif
264 
265 template <>
266 struct types_traits<unsigned char, false> {
267  typedef boost::gil::gray8_image_t image_t;
268  typedef boost::gil::gray8_view_t view_t;
269  typedef boost::gil::gray8c_view_t const_view_t;
270  typedef boost::gil::channel_traits<char>::reference reference;
271  typedef boost::gil::channel_traits<char>::const_reference const_reference;
272 };
273 
274 template <>
275 struct types_traits<short, false> {
276  typedef boost::gil::gray16s_image_t image_t;
277  typedef boost::gil::gray16s_view_t view_t;
278  typedef boost::gil::gray16sc_view_t const_view_t;
279  typedef boost::gil::channel_traits<short>::reference reference;
280  typedef boost::gil::channel_traits<short>::const_reference const_reference;
281 };
282 
283 template <>
284 struct types_traits<unsigned short, false> {
285  typedef boost::gil::gray16_image_t image_t;
286  typedef boost::gil::gray16_view_t view_t;
287  typedef boost::gil::gray16c_view_t const_view_t;
288  typedef boost::gil::channel_traits<unsigned short>::reference reference;
289  typedef boost::gil::channel_traits<unsigned short>::const_reference const_reference;
290 };
291 
292 template <>
293 struct types_traits<int, false> {
294  typedef boost::gil::gray32s_image_t image_t;
295  typedef boost::gil::gray32s_view_t view_t;
296  typedef boost::gil::gray32sc_view_t const_view_t;
297  typedef boost::gil::channel_traits<int>::reference reference;
298  typedef boost::gil::channel_traits<int>::const_reference const_reference;
299 };
300 
301 template <>
302 struct types_traits<unsigned int, false> {
303  typedef boost::gil::gray32_image_t image_t;
304  typedef boost::gil::gray32_view_t view_t;
305  typedef boost::gil::gray32c_view_t const_view_t;
306  typedef boost::gil::channel_traits<int>::reference reference;
307  typedef boost::gil::channel_traits<int>::const_reference const_reference;
308 };
309 
310 template <>
311 struct types_traits<float, false> {
312  typedef boost::gil::gray32f_noscale_image_t image_t;
313  typedef boost::gil::gray32f_noscale_view_t view_t;
314  typedef boost::gil::gray32f_noscalec_view_t const_view_t;
315  typedef boost::gil::channel_traits<float>::reference reference;
316  typedef boost::gil::channel_traits<float>::const_reference const_reference;
317 };
318 
319 template <>
320 struct types_traits<long, false> {
321  typedef boost::gil::gray64s_image_t image_t;
322  typedef boost::gil::gray64s_view_t view_t;
323  typedef boost::gil::gray64sc_view_t const_view_t;
324  typedef boost::gil::channel_traits<long>::reference reference;
325  typedef boost::gil::channel_traits<long>::const_reference const_reference;
326 };
327 
328 template <>
329 struct types_traits<unsigned long, false> {
330  typedef boost::gil::gray64_image_t image_t;
331  typedef boost::gil::gray64_view_t view_t;
332  typedef boost::gil::gray64c_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 namespace {
338 struct unknown {}; // two unused and unimplemented types
339 struct unknown_u {};
340 /*
341  * Return long long type (as type) if it's a synonym for std::int64_t
342  * We also need unsigned long long (as type_u), because "unsigned unknown" won't compile
343  */
344 struct CheckBoost64 {
345  typedef boost::mpl::if_<std::is_same<long long, std::int64_t>, long long, struct unknown>::type type;
346  typedef boost::mpl::if_<std::is_same<long long, std::int64_t>, unsigned long long, struct unknown_u>::type
347  type_u;
348 };
349 } // namespace
350 
351 template <>
352 struct types_traits<CheckBoost64::type, false> {
353  typedef boost::gil::gray64s_image_t image_t;
354  typedef boost::gil::gray64s_view_t view_t;
355  typedef boost::gil::gray64sc_view_t const_view_t;
356  typedef boost::gil::channel_traits<long>::reference reference;
357  typedef boost::gil::channel_traits<long>::const_reference const_reference;
358 };
359 
360 template <>
361 struct types_traits<CheckBoost64::type_u, false> {
362  typedef boost::gil::gray64_image_t image_t;
363  typedef boost::gil::gray64_view_t view_t;
364  typedef boost::gil::gray64c_view_t const_view_t;
365  typedef boost::gil::channel_traits<long>::reference reference;
366  typedef boost::gil::channel_traits<long>::const_reference const_reference;
367 };
368 
369 template <>
370 struct types_traits<double, false> {
371  typedef boost::gil::gray64f_noscale_image_t image_t;
372  typedef boost::gil::gray64f_noscale_view_t view_t;
373  typedef boost::gil::gray64f_noscalec_view_t const_view_t;
374  typedef boost::gil::channel_traits<double>::reference reference;
375  typedef boost::gil::channel_traits<double>::const_reference const_reference;
376 };
377 
378 template <typename T>
379 struct const_iterator_type {
381 };
382 
383 template <typename T>
384 struct const_locator_type { // should assert that T is a locator
385  typedef typename T::const_t type;
386 };
387 
388 typedef boost::gil::point2<std::ptrdiff_t> difference_type; // type used to advance locators
389 }
390 } // namespace image
391 } // namespace afw
392 } // namespace lsst
393 
394 namespace boost {
395 namespace gil {
396 
398 template <typename View1, typename View2, typename View3, typename ViewDest, typename F>
399 BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3,
400  const ViewDest& dst, F fun) {
401  for (std::ptrdiff_t y = 0; y < dst.height(); ++y) {
402  typename View1::x_iterator srcIt1 = src1.row_begin(y);
403  typename View2::x_iterator srcIt2 = src2.row_begin(y);
404  typename View3::x_iterator srcIt3 = src3.row_begin(y);
405  typename ViewDest::x_iterator dstIt = dst.row_begin(y);
406  for (std::ptrdiff_t x = 0; x < dst.width(); ++x) dstIt[x] = fun(srcIt1[x], srcIt2[x], srcIt3[x]);
407  }
408  return fun;
409 }
410 
412 template <typename View1, typename View2, typename View3, typename View4, typename ViewDest, typename F>
413 BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3, const View4& src4,
414  const ViewDest& dst, F fun) {
415  for (std::ptrdiff_t y = 0; y < dst.height(); ++y) {
416  typename View1::x_iterator srcIt1 = src1.row_begin(y);
417  typename View2::x_iterator srcIt2 = src2.row_begin(y);
418  typename View3::x_iterator srcIt3 = src3.row_begin(y);
419  typename View4::x_iterator srcIt4 = src4.row_begin(y);
420  typename ViewDest::x_iterator dstIt = dst.row_begin(y);
421  for (std::ptrdiff_t x = 0; x < dst.width(); ++x)
422  dstIt[x] = fun(srcIt1[x], srcIt2[x], srcIt3[x], srcIt4[x]);
423  }
424  return fun;
425 }
426 } // namespace gil
427 } // namespace boost
428 #endif
double x
table::Key< int > type
Definition: Detector.cc:163
int y
Definition: SpanSet.cc:49
table::Key< int > b
table::Key< int > a
Definition: Polygon.cc:25
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
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:671
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:677
A base class for image defects.
STL namespace.