9 #ifndef BOOST_GIL_METAFUNCTIONS_HPP
10 #define BOOST_GIL_METAFUNCTIONS_HPP
12 #include <boost/gil/channel.hpp>
13 #include <boost/gil/dynamic_step.hpp>
14 #include <boost/gil/concepts.hpp>
15 #include <boost/gil/concepts/detail/type_traits.hpp>
16 #include <boost/gil/detail/mp11.hpp>
19 #include <type_traits>
21 namespace boost {
namespace gil {
24 template <
typename T,
typename L>
struct pixel;
25 template <
typename BitField,
typename ChannelRefs,
typename Layout>
struct packed_pixel;
31 template <
typename Pixel,
bool IsPlanar = false,
typename Alloc=std::allocator<
unsigned char> >
class image;
33 template <
typename T>
struct color_space_type;
34 template <
typename T>
struct channel_mapping_type;
37 template <
typename BitField,
typename ChannelBitSizes,
typename Layout,
bool IsMutable>
struct bit_aligned_pixel_reference;
57 template <
typename PixelRef>
60 template <
typename T,
typename L>
63 template <
typename T,
typename L>
64 struct pixel_reference_is_basic<const pixel<T, L>&> : std::true_type {};
66 template <
typename TR,
typename CS>
67 struct pixel_reference_is_basic<planar_pixel_reference<TR, CS>> : std::true_type {};
69 template <
typename TR,
typename CS>
70 struct pixel_reference_is_basic<const planar_pixel_reference<TR, CS>> : std::true_type {};
75 template <
typename Iterator>
79 template <
typename T,
typename L>
83 template <
typename T,
typename L>
87 template <
typename T,
typename CS>
91 template <
typename T,
typename CS>
95 template <
typename T,
typename L>
99 template <
typename T,
typename L>
103 template <
typename T,
typename CS>
109 template <
typename T,
typename CS>
117 template <
typename Loc>
120 template <
typename Iterator>
129 template <
typename View>
132 template <
typename Loc>
137 template <
typename Img>
140 template <
typename Pixel,
bool IsPlanar,
typename Alloc>
148 template <
typename I>
153 template <
typename It,
bool IsBase,
bool EqualsStepType>
154 struct iterator_is_step_impl;
157 template <
typename It,
bool IsBase>
158 struct iterator_is_step_impl<It, IsBase, true> : std::true_type {};
161 template <
typename It>
162 struct iterator_is_step_impl<It, true, false> : std::false_type {};
165 template <
typename It>
166 struct iterator_is_step_impl<It, false, false>
167 :
public iterator_is_step<typename iterator_adaptor_get_base<It>::type> {};
173 template <
typename I>
174 struct iterator_is_step
175 : detail::iterator_is_step_impl
178 !is_iterator_adaptor<I>::value,
179 std::is_same<I, typename dynamic_x_step_type<I>::type
202 template <
typename PixelReference>
208 typename detail::remove_const_and_reference<PixelReference>::type,
209 typename detail::remove_const_and_reference<PixelReference>::type::value_type
216 template <
typename Pixel>
218 : mp11::mp_or<is_reference<Pixel>, pixel_reference_is_proxy<Pixel>> {};
228 template <
typename R>
230 : std::integral_constant<bool, std::remove_reference<R>::type::is_mutable>
233 template <
typename R>
269 template <
typename T,
typename L>
struct pixel_reference_type<T,L,false,false> {
using type = pixel<T,L>
const&; };
270 template <
typename T,
typename L>
struct pixel_reference_type<T,L,true,true> {
using type = planar_pixel_reference<typename channel_traits<T>::reference,
typename color_space_type<L>::type>
const; };
271 template <
typename T,
typename L>
struct pixel_reference_type<T,L,true,false> {
using type = planar_pixel_reference<typename channel_traits<T>::const_reference,
typename color_space_type<L>::type>
const; };
277 template <
typename Pixel>
struct iterator_type_from_pixel<Pixel,false,false,false> {
using type =
const Pixel *; };
278 template <
typename Pixel>
struct iterator_type_from_pixel<Pixel,true,false,true> {
279 using type = planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::pointer,
typename color_space_type<Pixel>::type>;
281 template <
typename Pixel>
struct iterator_type_from_pixel<Pixel,true,false,false> {
282 using type = planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::const_pointer,
typename color_space_type<Pixel>::type>;
284 template <
typename Pixel,
bool IsPlanar,
bool IsMutable>
struct iterator_type_from_pixel<Pixel,IsPlanar,true,IsMutable> {
285 using type = memory_based_step_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,false,IsMutable>::type>;
290 template <
typename T,
typename L,
bool IsPlanar=false,
bool IsStep=false,
bool IsMutable=true>
struct iterator_type{};
292 template <
typename T,
typename L>
struct iterator_type<T,L,false,false,false> {
using type = pixel<T,L>
const*; };
293 template <
typename T,
typename L>
struct iterator_type<T,L,true,false,true> {
using type = planar_pixel_iterator<T*,typename L::color_space_t>; };
294 template <
typename T,
typename L>
struct iterator_type<T,L,true,false,false> {
using type = planar_pixel_iterator<const T*,typename L::color_space_t>; };
295 template <
typename T,
typename L,
bool IsPlanar,
bool IsMutable>
struct iterator_type<T,L,IsPlanar,true,IsMutable> {
296 using type = memory_based_step_iterator<typename iterator_type<T,L,IsPlanar,false,IsMutable>::type>;
301 template <
typename XIterator>
311 template <
typename BitField,
typename FirstBit,
typename NumBits>
312 struct packed_channel_reference_type
314 using type = packed_channel_reference
316 BitField, FirstBit::value, NumBits::value,
true
320 template <
typename BitField,
typename ChannelBitSizes>
321 class packed_channel_references_vector_type
323 template <
typename FirstBit,
typename NumBits>
324 using reference_type =
typename packed_channel_reference_type<BitField, FirstBit, NumBits>::type;
328 using first_bit_list = mp11::mp_fold_q
331 mp11::mp_list<std::integral_constant<int, 0>>,
339 mp11::mp_bind<mp_back, mp11::_1>,
345 static_assert(mp11::mp_at_c<first_bit_list, 0>::value == 0,
"packed channel first bit must be 0");
348 using type = mp11::mp_transform
351 mp_pop_back<first_bit_list>,
366 template <
typename BitField,
typename ChannelBitSizes,
typename Layout>
372 typename detail::packed_channel_references_vector_type
391 template <
typename BitField,
typename ChannelBitSizes,
typename Layout,
typename Alloc=std::allocator<
unsigned char>>
399 template <
typename BitField,
unsigned Size1,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
406 template <
typename BitField,
unsigned Size1,
unsigned Size2,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
408 :
packed_image_type<BitField, mp11::mp_list_c<unsigned, Size1, Size2>, Layout, Alloc>
413 template <
typename BitField,
unsigned Size1,
unsigned Size2,
unsigned Size3,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
415 :
packed_image_type<BitField, mp11::mp_list_c<unsigned, Size1, Size2, Size3>, Layout, Alloc>
420 template <
typename BitField,
unsigned Size1,
unsigned Size2,
unsigned Size3,
unsigned Size4,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
422 :
packed_image_type<BitField, mp11::mp_list_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc>
427 template <
typename BitField,
unsigned Size1,
unsigned Size2,
unsigned Size3,
unsigned Size4,
unsigned Size5,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
429 :
packed_image_type<BitField, mp11::mp_list_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
440 typename ChannelBitSizes,
442 typename Alloc = std::allocator<unsigned char>
448 static constexpr
int bit_size =
452 std::integral_constant<int, 0>,
456 using bitfield_t =
typename detail::min_fast_uint<bit_size + 7>::type;
457 using bit_alignedref_t = bit_aligned_pixel_reference<bitfield_t, ChannelBitSizes, Layout, true>
const;
465 template <
unsigned Size1,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
470 template <
unsigned Size1,
unsigned Size2,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
475 template <
unsigned Size1,
unsigned Size2,
unsigned Size3,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
480 template <
unsigned Size1,
unsigned Size2,
unsigned Size3,
unsigned Size4,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
485 template <
unsigned Size1,
unsigned Size2,
unsigned Size3,
unsigned Size4,
unsigned Size5,
typename Layout,
typename Alloc = std::allocator<
unsigned char>>
491 template <
typename Channel,
typename Layout>
499 template <
typename BitField,
int NumBits,
bool IsMutable,
typename Layout>
500 struct pixel_value_type<packed_dynamic_channel_reference<BitField, NumBits, IsMutable>, Layout>
504 template <
typename BitField,
int NumBits,
bool IsMutable,
typename Layout>
505 struct pixel_value_type<packed_dynamic_channel_reference<BitField, NumBits, IsMutable> const, Layout>
506 : packed_pixel_type<BitField, mp11::mp_list_c<unsigned, NumBits>, Layout>
509 template <
typename BitField,
int FirstBit,
int NumBits,
bool IsMutable,
typename Layout>
510 struct pixel_value_type<packed_channel_reference<BitField, FirstBit, NumBits, IsMutable>, Layout>
511 : packed_pixel_type<BitField, mp11::mp_list_c<unsigned, NumBits>, Layout>
514 template <
typename BitField,
int FirstBit,
int NumBits,
bool IsMutable,
typename Layout>
515 struct pixel_value_type<packed_channel_reference<BitField, FirstBit, NumBits, IsMutable> const, Layout>
516 : packed_pixel_type<BitField, mp11::mp_list_c<unsigned, NumBits>, Layout>
519 template <
int NumBits,
typename Layout>
520 struct pixel_value_type<packed_channel_value<NumBits>, Layout>
521 : packed_pixel_type<typename detail::min_fast_uint<NumBits>::type, mp11::mp_list_c<unsigned, NumBits>, Layout>
526 template <
typename T,
typename L,
bool IsPlanar = false,
bool IsStepX = false,
bool IsMutable = true>
537 template <
typename T,
typename L,
bool IsPlanar = false,
bool IsStepX = false,
bool IsMutable = true>
548 template <
typename T,
typename L,
bool IsPlanar = false,
typename Alloc = std::allocator<
unsigned char>>
556 template <
typename Pixel,
bool IsPlanar=false,
bool IsStepX=false,
bool IsMutable=true>
568 typename T = use_default,
569 typename L = use_default,
570 typename IsPlanar = use_default,
571 typename IsMutable = use_default>
574 using pixel_t =
typename std::remove_reference<Ref>::type;
576 using channel_t =
typename mp11::mp_if
578 std::is_same<T, use_default>,
583 using layout_t =
typename mp11::mp_if
585 std::is_same<L, use_default>,
588 typename color_space_type<pixel_t>::type,
589 typename channel_mapping_type<pixel_t>::type
594 static bool const mut = mp11::mp_if
596 std::is_same<IsMutable, use_default>,
601 static bool const planar = mp11::mp_if
603 std::is_same<IsPlanar, use_default>,
618 typename T = use_default,
619 typename L = use_default,
620 typename IsPlanar = use_default,
621 typename IsStep = use_default,
622 typename IsMutable = use_default
626 using channel_t =
typename mp11::mp_if
628 std::is_same<T, use_default>,
633 using layout_t =
typename mp11::mp_if
635 std::is_same<L, use_default>,
638 typename color_space_type<Iterator>::type,
639 typename channel_mapping_type<Iterator>::type
644 static const bool mut = mp11::mp_if
646 std::is_same<IsMutable, use_default>,
651 static bool const planar = mp11::mp_if
653 std::is_same<IsPlanar, use_default>,
658 static bool const step = mp11::mp_if
660 std::is_same<IsStep, use_default>,
672 template <
typename View,
typename T = use_default,
typename L = use_default,
typename IsPlanar = use_default,
typename StepX = use_default,
typename IsMutable = use_default>
675 using channel_t =
typename mp11::mp_if
677 std::is_same<T, use_default>,
682 using layout_t =
typename mp11::mp_if
684 std::is_same<L, use_default>,
687 typename color_space_type<View>::type,
688 typename channel_mapping_type<View>::type
693 static bool const mut = mp11::mp_if
695 std::is_same<IsMutable, use_default>,
700 static bool const planar = mp11::mp_if
702 std::is_same<IsPlanar, use_default>,
707 static bool const step = mp11::mp_if
709 std::is_same<StepX, use_default>,
715 using type =
typename view_type<channel_t, layout_t, planar, step, mut>::type;
721 template <
typename Image,
typename T = use_default,
typename L = use_default,
typename IsPlanar = use_default>
724 using channel_t =
typename mp11::mp_if
726 std::is_same<T, use_default>,
731 using layout_t =
typename mp11::mp_if
733 std::is_same<L, use_default>,
736 typename color_space_type<Image>::type,
737 typename channel_mapping_type<Image>::type>,
741 static bool const planar = mp11::mp_if
743 std::is_same<IsPlanar, use_default>,