File indexing completed on 2024-11-15 09:12:41
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_PACKED_PIXEL_HPP
0009 #define BOOST_GIL_PACKED_PIXEL_HPP
0010
0011 #include <boost/gil/pixel.hpp>
0012 #include <boost/gil/detail/mp11.hpp>
0013
0014 #include <functional>
0015 #include <type_traits>
0016
0017 namespace boost { namespace gil {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 template <typename BitField, typename ChannelRefs, typename Layout>
0049 struct packed_pixel
0050 {
0051 BitField _bitfield{0};
0052
0053 using layout_t = Layout;
0054 using value_type = packed_pixel<BitField, ChannelRefs, Layout>;
0055 using reference = value_type&;
0056 using const_reference = value_type const&;
0057
0058 static constexpr bool is_mutable =
0059 channel_traits<mp11::mp_front<ChannelRefs>>::is_mutable;
0060
0061 packed_pixel() = default;
0062 explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {}
0063
0064 template <typename Pixel>
0065 packed_pixel(Pixel const& p,
0066 typename std::enable_if<is_pixel<Pixel>::value>::type* = nullptr)
0067 {
0068 check_compatible<Pixel>();
0069 static_copy(p, *this);
0070 }
0071
0072 packed_pixel(int chan0, int chan1)
0073 : _bitfield(0)
0074 {
0075 static_assert(num_channels<packed_pixel>::value == 2, "");
0076 gil::at_c<0>(*this) = chan0;
0077 gil::at_c<1>(*this) = chan1;
0078 }
0079
0080 packed_pixel(int chan0, int chan1, int chan2)
0081 : _bitfield(0)
0082 {
0083 static_assert(num_channels<packed_pixel>::value == 3, "");
0084 gil::at_c<0>(*this) = chan0;
0085 gil::at_c<1>(*this) = chan1;
0086 gil::at_c<2>(*this) = chan2;
0087 }
0088
0089 packed_pixel(int chan0, int chan1, int chan2, int chan3)
0090 : _bitfield(0)
0091 {
0092 static_assert(num_channels<packed_pixel>::value == 4, "");
0093 gil::at_c<0>(*this) = chan0;
0094 gil::at_c<1>(*this) = chan1;
0095 gil::at_c<2>(*this) = chan2;
0096 gil::at_c<3>(*this) = chan3;
0097 }
0098
0099 packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4)
0100 : _bitfield(0)
0101 {
0102 static_assert(num_channels<packed_pixel>::value == 5, "");
0103 gil::at_c<0>(*this) = chan0;
0104 gil::at_c<1>(*this) = chan1;
0105 gil::at_c<2>(*this) = chan2;
0106 gil::at_c<3>(*this) = chan3;
0107 gil::at_c<4>(*this) = chan4;
0108 }
0109
0110 template <typename Pixel>
0111 auto operator=(Pixel const& p) -> packed_pixel&
0112 {
0113 assign(p, is_pixel<Pixel>());
0114 return *this;
0115 }
0116
0117 template <typename Pixel>
0118 bool operator==(Pixel const& p) const
0119 {
0120 return equal(p, is_pixel<Pixel>());
0121 }
0122
0123 template <typename Pixel>
0124 bool operator!=(Pixel const& p) const { return !(*this==p); }
0125
0126 private:
0127 template <typename Pixel>
0128 static void check_compatible()
0129 {
0130 gil_function_requires<PixelsCompatibleConcept<Pixel, packed_pixel>>();
0131 }
0132
0133 template <typename Pixel>
0134 void assign(Pixel const& p, std::true_type)
0135 {
0136 check_compatible<Pixel>();
0137 static_copy(p, *this);
0138 }
0139
0140 template <typename Pixel>
0141 bool equal(Pixel const& p, std::true_type) const
0142 {
0143 check_compatible<Pixel>();
0144 return static_equal(*this, p);
0145 }
0146
0147
0148 static void check_gray()
0149 {
0150 static_assert(std::is_same<typename Layout::color_space_t, gray_t>::value, "");
0151 }
0152
0153 template <typename Channel>
0154 void assign(Channel const& channel, std::false_type)
0155 {
0156 check_gray();
0157 gil::at_c<0>(*this) = channel;
0158 }
0159
0160 template <typename Channel>
0161 bool equal (Channel const& channel, std::false_type) const
0162 {
0163 check_gray();
0164 return gil::at_c<0>(*this) == channel;
0165 }
0166
0167 public:
0168 auto operator=(int channel) -> packed_pixel&
0169 {
0170 check_gray();
0171 gil::at_c<0>(*this) = channel;
0172 return *this;
0173 }
0174
0175 bool operator==(int channel) const
0176 {
0177 check_gray();
0178 return gil::at_c<0>(*this) == channel;
0179 }
0180 };
0181
0182
0183
0184
0185
0186 template <typename BitField, typename ChannelRefs, typename Layout, int K>
0187 struct kth_element_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
0188 {
0189 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::value_type;
0190 };
0191
0192 template <typename BitField, typename ChannelRefs, typename Layout, int K>
0193 struct kth_element_reference_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
0194 {
0195 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::reference;
0196 };
0197
0198 template <typename BitField, typename ChannelRefs, typename Layout, int K>
0199 struct kth_element_const_reference_type<packed_pixel<BitField, ChannelRefs, Layout>, K>
0200 {
0201 using type = typename channel_traits<mp11::mp_at_c<ChannelRefs, K>>::const_reference;
0202 };
0203
0204 template <int K, typename P, typename C, typename L>
0205 inline
0206 auto at_c(packed_pixel<P, C, L>& p)
0207 -> typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type
0208 {
0209 return typename kth_element_reference_type
0210 <
0211 packed_pixel<P, C, L>,
0212 K
0213 >::type{&p._bitfield};
0214 }
0215
0216 template <int K, typename P, typename C, typename L>
0217 inline
0218 auto at_c(const packed_pixel<P, C, L>& p)
0219 -> typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type
0220 {
0221 return typename kth_element_const_reference_type
0222 <
0223 packed_pixel<P, C, L>,
0224 K>::type{&p._bitfield};
0225 }
0226
0227
0228
0229
0230
0231
0232
0233 template <typename BitField, typename ChannelRefs, typename Layout>
0234 struct is_pixel<packed_pixel<BitField, ChannelRefs, Layout>> : std::true_type {};
0235
0236
0237
0238
0239
0240 template <typename P, typename C, typename Layout>
0241 struct color_space_type<packed_pixel<P, C, Layout>>
0242 {
0243 using type = typename Layout::color_space_t;
0244 };
0245
0246 template <typename P, typename C, typename Layout>
0247 struct channel_mapping_type<packed_pixel<P, C, Layout>>
0248 {
0249 using type = typename Layout::channel_mapping_t;
0250 };
0251
0252 template <typename P, typename C, typename Layout>
0253 struct is_planar<packed_pixel<P, C, Layout>> : std::false_type {};
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 template <typename P, typename C, typename L>
0267 struct iterator_is_mutable<packed_pixel<P, C, L>*>
0268 : std::integral_constant<bool, packed_pixel<P, C, L>::is_mutable>
0269 {};
0270
0271 template <typename P, typename C, typename L>
0272 struct iterator_is_mutable<const packed_pixel<P, C, L>*> : std::false_type {};
0273
0274 }}
0275
0276 #endif