LSST Applications 27.0.0,g0265f82a02+469cd937ee,g02d81e74bb+21ad69e7e1,g1470d8bcf6+cbe83ee85a,g2079a07aa2+e67c6346a6,g212a7c68fe+04a9158687,g2305ad1205+94392ce272,g295015adf3+81dd352a9d,g2bbee38e9b+469cd937ee,g337abbeb29+469cd937ee,g3939d97d7f+72a9f7b576,g487adcacf7+71499e7cba,g50ff169b8f+5929b3527e,g52b1c1532d+a6fc98d2e7,g591dd9f2cf+df404f777f,g5a732f18d5+be83d3ecdb,g64a986408d+21ad69e7e1,g858d7b2824+21ad69e7e1,g8a8a8dda67+a6fc98d2e7,g99cad8db69+f62e5b0af5,g9ddcbc5298+d4bad12328,ga1e77700b3+9c366c4306,ga8c6da7877+71e4819109,gb0e22166c9+25ba2f69a1,gb6a65358fc+469cd937ee,gbb8dafda3b+69d3c0e320,gc07e1c2157+a98bf949bb,gc120e1dc64+615ec43309,gc28159a63d+469cd937ee,gcf0d15dbbd+72a9f7b576,gdaeeff99f8+a38ce5ea23,ge6526c86ff+3a7c1ac5f1,ge79ae78c31+469cd937ee,gee10cc3b42+a6fc98d2e7,gf1cff7945b+21ad69e7e1,gfbcc870c63+9a11dc8c8f
LSST Data Management Base Package
Loading...
Searching...
No Matches
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
44#include "boost/gil.hpp"
45
46#ifndef BOOST_GIL_DEFINE_BASE_TYPEDEFS
47// Boost >=1.72 redefines GIL_ -> BOOST_GIL
48// Add these for compatibility
49#define BOOST_GIL_DEFINE_BASE_TYPEDEFS GIL_DEFINE_BASE_TYPEDEFS
50#define BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL GIL_DEFINE_ALL_TYPEDEFS_INTERNAL
51#endif
52
53
54namespace lsst {
55namespace afw {
56namespace image {
57
59//
60/* We want to be able to call operator+= in the global namespace, but define it in lsst::afw::image.
61 * To make this possible, at least one of its arguments must be in lsst::afw::image, so we define
62 * this type to make the argument lookup ("Koenig Lookup") work smoothly
63 */
64struct pair2I : public std::pair<int, int> {
65 explicit pair2I(int first, int second) : std::pair<int, int>(first, second) {}
66 pair2I(std::pair<int, int> pair) : std::pair<int, int>(pair) {}
67};
68
75template <typename T>
76boost::gil::memory_based_2d_locator<T>& operator+=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
77 return (loc += boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
78}
83template <typename T>
84boost::gil::memory_based_2d_locator<T>& operator-=(boost::gil::memory_based_2d_locator<T>& loc, pair2I off) {
85 return (loc -= boost::gil::point2<std::ptrdiff_t>(off.first, off.second));
86}
87} // namespace image
88} // namespace afw
89} // namespace lsst
90
91namespace boost {
92namespace gil {
97template <typename T>
98memory_based_2d_locator<T>& operator+=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
99 return (loc += point2<std::ptrdiff_t>(off.first, off.second));
100}
105template <typename T>
106memory_based_2d_locator<T>& operator-=(memory_based_2d_locator<T>& loc, std::pair<int, int> off) {
107 return (loc -= point2<std::ptrdiff_t>(off.first, off.second));
108}
109
110/*
111 * Define types that are pure (un)signed long, without scaling into [0, 1]
112 */
113using bits64 = uint64_t;
114using bits64s = int64_t;
115
116BOOST_GIL_DEFINE_BASE_TYPEDEFS(64, bits64, gray)
117BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64, bits64, dev2n, devicen_t<2>, devicen_layout_t<2>)
118BOOST_GIL_DEFINE_BASE_TYPEDEFS(64s, bits64s, gray)
119BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64s, bits64s, dev2n, devicen_t<2>, devicen_layout_t<2>)
120
121/*
122 * Define a type that's a pure float, without scaling into [0, 1]
123 */
124using bits32f_noscale = float;
125
126BOOST_GIL_DEFINE_BASE_TYPEDEFS(32f_noscale, bits32f_noscale, gray)
127BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f_noscale, bits32f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
128
129template <>
130struct channel_multiplier<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 */
137using bits64f_noscale = double;
138
139BOOST_GIL_DEFINE_BASE_TYPEDEFS(64f_noscale, bits64f_noscale, gray)
140BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(64f_noscale, bits64f_noscale, dev2n, devicen_t<2>, devicen_layout_t<2>)
141
142//
143// Conversions that don't scale
144//
145template <typename DstChannelV>
146struct channel_converter<bits32f_noscale, DstChannelV> {
147 DstChannelV operator()(bits32f_noscale x) const { return DstChannelV(x + 0.5f); }
148};
149
150template <typename SrcChannelV>
151struct channel_converter<SrcChannelV, bits32f_noscale> {
152 bits32f_noscale operator()(SrcChannelV x) const { return bits32f_noscale(x); }
153};
154
155template <typename DstChannelV>
156struct channel_converter<bits64f_noscale, DstChannelV> {
157 DstChannelV operator()(bits64f_noscale x) const { return DstChannelV(x + 0.5f); }
158};
159
160template <typename SrcChannelV>
161struct channel_converter<SrcChannelV, bits64f_noscale> {
162 bits64f_noscale operator()(SrcChannelV x) const { return bits64f_noscale(x); }
163};
164
165//
166// Totally specialised templates to resolve ambiguities
167//
168#define LSST_CONVERT_NOOP(T1, T2) \
169 template <> \
170 struct channel_converter<T1, T2> { \
171 T2 operator()(T1 x) const { return static_cast<T2>(x); } \
172 }; \
173 \
174 template <> \
175 struct channel_converter<T2, T1> { \
176 T1 operator()(T2 x) const { return static_cast<T1>(x); } \
177 }
178
179LSST_CONVERT_NOOP(bits32f_noscale, bits64f_noscale);
180
181LSST_CONVERT_NOOP(unsigned char, short);
182LSST_CONVERT_NOOP(unsigned char, unsigned short);
183LSST_CONVERT_NOOP(unsigned char, int);
184LSST_CONVERT_NOOP(unsigned short, short);
185LSST_CONVERT_NOOP(unsigned short, int);
186LSST_CONVERT_NOOP(short, int);
187
188#undef LSST_CONVERT_NOOP
189
191//
192// These are in the boost::gil namespace in order to permit Koenig lookup
193//
194#define LSST_BOOST_GIL_OP_EQUALS(TYPE, OP) \
195 template <typename T2> \
196 TYPE##_pixel_t& operator OP##=(TYPE##_pixel_t& lhs, T2 rhs) { \
197 return (lhs = lhs OP rhs); \
198 }
199
200#define LSST_BOOST_GIL_OP_EQUALS_ALL(PIXTYPE) \
201 LSST_BOOST_GIL_OP_EQUALS(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
208LSST_BOOST_GIL_OP_EQUALS_ALL(gray8)
209LSST_BOOST_GIL_OP_EQUALS_ALL(gray8s)
210LSST_BOOST_GIL_OP_EQUALS_ALL(gray16)
211LSST_BOOST_GIL_OP_EQUALS_ALL(gray16s)
212LSST_BOOST_GIL_OP_EQUALS_ALL(gray32)
213LSST_BOOST_GIL_OP_EQUALS_ALL(gray32s)
214LSST_BOOST_GIL_OP_EQUALS_ALL(gray32f_noscale)
215LSST_BOOST_GIL_OP_EQUALS_ALL(gray64)
216LSST_BOOST_GIL_OP_EQUALS_ALL(gray64s)
217LSST_BOOST_GIL_OP_EQUALS_ALL(gray64f_noscale)
218
219#undef LSST_BOOST_GIL_OP_EQUALS
220#undef LSST_BOOST_GIL_OP_EQUALS_ALL
221} // namespace gil
222} // namespace boost
223
224namespace lsst {
225namespace afw {
226namespace image {
227namespace detail {
228//
229// Map typenames to gil's types
230//
231
232template <typename T, bool rescale = false>
233struct types_traits {
234 BOOST_MPL_ASSERT_MSG(boost::mpl::bool_<false>::value, I_DO_NOT_KNOW_HOW_TO_MAP_THIS_TYPE_TO_A_GIL_TYPE,
235 ());
236};
237
238template <>
239struct types_traits<unsigned char, false> {
240 using image_t = boost::gil::gray8_image_t;
241 using view_t = boost::gil::gray8_view_t;
242 using const_view_t = boost::gil::gray8c_view_t;
243 using reference = boost::gil::channel_traits<char>::reference;
244 using const_reference = boost::gil::channel_traits<char>::const_reference;
245};
246
247template <>
248struct types_traits<short, false> {
249 using image_t = boost::gil::gray16s_image_t;
250 using view_t = boost::gil::gray16s_view_t;
251 using const_view_t = boost::gil::gray16sc_view_t;
252 using reference = boost::gil::channel_traits<short>::reference;
253 using const_reference = boost::gil::channel_traits<short>::const_reference;
254};
255
256template <>
257struct types_traits<unsigned short, false> {
258 using image_t = boost::gil::gray16_image_t;
259 using view_t = boost::gil::gray16_view_t;
260 using const_view_t = boost::gil::gray16c_view_t;
261 using reference = boost::gil::channel_traits<unsigned short>::reference;
262 using const_reference = boost::gil::channel_traits<unsigned short>::const_reference;
263};
264
265template <>
266struct types_traits<int, false> {
267 using image_t = boost::gil::gray32s_image_t;
268 using view_t = boost::gil::gray32s_view_t;
269 using const_view_t = boost::gil::gray32sc_view_t;
270 using reference = boost::gil::channel_traits<int>::reference;
271 using const_reference = boost::gil::channel_traits<int>::const_reference;
272};
273
274template <>
275struct types_traits<unsigned int, false> {
276 using image_t = boost::gil::gray32_image_t;
277 using view_t = boost::gil::gray32_view_t;
278 using const_view_t = boost::gil::gray32c_view_t;
279 using reference = boost::gil::channel_traits<int>::reference;
280 using const_reference = boost::gil::channel_traits<int>::const_reference;
281};
282
283template <>
284struct types_traits<float, false> {
285 using image_t = boost::gil::gray32f_noscale_image_t;
286 using view_t = boost::gil::gray32f_noscale_view_t;
287 using const_view_t = boost::gil::gray32f_noscalec_view_t;
288 using reference = boost::gil::channel_traits<float>::reference;
289 using const_reference = boost::gil::channel_traits<float>::const_reference;
290};
291
292template <>
293struct types_traits<long, false> {
294 using image_t = boost::gil::gray64s_image_t;
295 using view_t = boost::gil::gray64s_view_t;
296 using const_view_t = boost::gil::gray64sc_view_t;
297 using reference = boost::gil::channel_traits<long>::reference;
298 using const_reference = boost::gil::channel_traits<long>::const_reference;
299};
300
301template <>
302struct types_traits<unsigned long, false> {
303 using image_t = boost::gil::gray64_image_t;
304 using view_t = boost::gil::gray64_view_t;
305 using const_view_t = boost::gil::gray64c_view_t;
306 using reference = boost::gil::channel_traits<long>::reference;
307 using const_reference = boost::gil::channel_traits<long>::const_reference;
308};
309
310namespace {
311struct unknown {}; // two unused and unimplemented types
312struct unknown_u {};
313/*
314 * Return long long type (as type) if it's a synonym for std::int64_t
315 * We also need unsigned long long (as type_u), because "unsigned unknown" won't compile
316 */
317struct CheckBoost64 {
318 using type = boost::mpl::if_<std::is_same<long long, std::int64_t>, long long, struct unknown>::type;
319 using type_u = boost::mpl::if_<std::is_same<long long, std::int64_t>, unsigned long long, struct unknown_u>::type;
320};
321} // namespace
322
323template <>
324struct types_traits<CheckBoost64::type, false> {
325 using image_t = boost::gil::gray64s_image_t;
326 using view_t = boost::gil::gray64s_view_t;
327 using const_view_t = boost::gil::gray64sc_view_t;
328 using reference = boost::gil::channel_traits<long>::reference;
329 using const_reference = boost::gil::channel_traits<long>::const_reference;
330};
331
332template <>
333struct types_traits<CheckBoost64::type_u, false> {
334 using image_t = boost::gil::gray64_image_t;
335 using view_t = boost::gil::gray64_view_t;
336 using const_view_t = boost::gil::gray64c_view_t;
337 using reference = boost::gil::channel_traits<long>::reference;
338 using const_reference = boost::gil::channel_traits<long>::const_reference;
339};
340
341template <>
342struct types_traits<double, false> {
343 using image_t = boost::gil::gray64f_noscale_image_t;
344 using view_t = boost::gil::gray64f_noscale_view_t;
345 using const_view_t = boost::gil::gray64f_noscalec_view_t;
346 using reference = boost::gil::channel_traits<double>::reference;
347 using const_reference = boost::gil::channel_traits<double>::const_reference;
348};
349
350template <typename T>
351struct const_iterator_type {
352 using type = typename boost::gil::const_iterator_type<T>::type;
353};
354
355template <typename T>
356struct const_locator_type { // should assert that T is a locator
357 using type = typename T::const_t;
358};
359
360using difference_type = boost::gil::point2<std::ptrdiff_t>; // type used to advance locators
361}
362} // namespace image
363} // namespace afw
364} // namespace lsst
365
366namespace boost {
367namespace gil {
368
370template <typename View1, typename View2, typename View3, typename ViewDest, typename F>
371BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3,
372 const ViewDest& dst, F fun) {
373 for (std::ptrdiff_t y = 0; y < dst.height(); ++y) {
374 typename View1::x_iterator srcIt1 = src1.row_begin(y);
375 typename View2::x_iterator srcIt2 = src2.row_begin(y);
376 typename View3::x_iterator srcIt3 = src3.row_begin(y);
377 typename ViewDest::x_iterator dstIt = dst.row_begin(y);
378 for (std::ptrdiff_t x = 0; x < dst.width(); ++x) dstIt[x] = fun(srcIt1[x], srcIt2[x], srcIt3[x]);
379 }
380 return fun;
381}
382
384template <typename View1, typename View2, typename View3, typename View4, typename ViewDest, typename F>
385BOOST_FORCEINLINE F transform_pixels(const View1& src1, const View2& src2, const View3& src3, const View4& src4,
386 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 gil
399} // namespace boost
400#endif
int y
Definition SpanSet.cc:48
table::Key< int > b
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:658
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:664
STL namespace.