File indexing completed on 2025-01-18 09:36:59
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_IS_ALLOWED_HPP
0009 #define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_IS_ALLOWED_HPP
0010
0011 #include <boost/gil/extension/io/tiff/tags.hpp>
0012 #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
0013 #include <boost/gil/detail/mp11.hpp>
0014 #include <boost/gil/io/base.hpp>
0015
0016 #include <type_traits>
0017
0018 namespace boost { namespace gil { namespace detail {
0019
0020 using channel_sizes_t = std::vector<tiff_bits_per_sample::type>;
0021
0022 template <typename View, typename Channel, typename Enable = void>
0023 struct Format_Type {};
0024
0025
0026 template <typename View, typename Channel>
0027 struct Format_Type
0028 <
0029 View,
0030 Channel,
0031 typename std::enable_if
0032 <
0033 is_bit_aligned
0034 <
0035 typename get_pixel_type<View>::type
0036 >::value
0037 >::type
0038 >
0039 {
0040 static const int value = SAMPLEFORMAT_UINT;
0041 };
0042
0043
0044 template <typename View, typename Channel>
0045 struct Format_Type
0046 <
0047 View,
0048 Channel,
0049 typename std::enable_if
0050 <
0051 mp11::mp_and
0052 <
0053 mp11::mp_not
0054 <
0055 typename is_bit_aligned<typename get_pixel_type<View>::type>::type
0056 >,
0057 std::is_unsigned<Channel>
0058 >::value
0059 >::type
0060 >
0061 {
0062 static const int value = SAMPLEFORMAT_UINT;
0063 };
0064
0065
0066 template <typename View, typename Channel>
0067 struct Format_Type
0068 <
0069 View,
0070 Channel,
0071 typename std::enable_if
0072 <
0073 mp11::mp_and
0074 <
0075 mp11::mp_not
0076 <
0077 typename is_bit_aligned<typename get_pixel_type<View>::type>::type
0078 >,
0079 std::is_signed<Channel>
0080 >::value
0081 >::type
0082 >
0083 {
0084 static const int value = SAMPLEFORMAT_INT;
0085 };
0086
0087
0088 template <typename View, typename Channel>
0089 struct Format_Type
0090 <
0091 View,
0092 Channel,
0093 typename std::enable_if
0094 <
0095 mp11::mp_and
0096 <
0097 mp11::mp_not
0098 <
0099 typename is_bit_aligned<typename get_pixel_type<View>::type>::type
0100 >,
0101 is_floating_point<Channel>
0102 >::value
0103 >::type
0104 >
0105 {
0106 static const int value = SAMPLEFORMAT_IEEEFP;
0107 };
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 template< typename View >
0139 bool compare_channel_sizes( const channel_sizes_t& channel_sizes
0140 , std::false_type
0141 , std::true_type
0142 )
0143 {
0144 using pixel_t = typename View::value_type;
0145 using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
0146
0147 unsigned int s = detail::unsigned_integral_num_bits< channel_t >::value;
0148
0149 return ( s == channel_sizes[0] );
0150 }
0151
0152
0153 template< typename View >
0154 bool compare_channel_sizes( const channel_sizes_t& channel_sizes
0155 , std::true_type
0156 , std::true_type
0157 )
0158 {
0159 using ref_t = typename View::reference;
0160 using channel_t = typename channel_traits<typename element_type<ref_t>::type>::value_type;
0161
0162 unsigned int s = detail::unsigned_integral_num_bits< channel_t >::value;
0163 return ( s == channel_sizes[0] );
0164 }
0165
0166 struct compare_channel_sizes_fn
0167 {
0168 compare_channel_sizes_fn( uint16_t* a )
0169 : _a( a )
0170 , _b( true )
0171 {}
0172
0173 template< typename ChannelSize >
0174 void operator()( ChannelSize x)
0175 {
0176 if( x != *_a++ )
0177 {
0178 _b = false;
0179 }
0180 }
0181
0182 uint16_t* _a;
0183 bool _b;
0184 };
0185
0186 template< typename T >
0187 struct channel_sizes_type {};
0188
0189 template< typename B, typename C, typename L, bool M >
0190 struct channel_sizes_type< bit_aligned_pixel_reference< B, C, L, M > > { using type = C; };
0191
0192 template< typename B, typename C, typename L, bool M >
0193 struct channel_sizes_type< const bit_aligned_pixel_reference< B, C, L, M > > { using type = C; };
0194
0195 template< typename View >
0196 bool compare_channel_sizes( channel_sizes_t& channel_sizes
0197 , std::true_type
0198 , std::false_type
0199 )
0200 {
0201
0202
0203 using ref_t = typename View::reference;
0204 using cs_t = typename channel_sizes_type<ref_t>::type;
0205
0206 compare_channel_sizes_fn fn( &channel_sizes.front() );
0207 mp11::mp_for_each<cs_t>(fn);
0208
0209 return fn._b;
0210 }
0211
0212 template< typename View >
0213 bool is_allowed( const image_read_info< tiff_tag >& info
0214 , std::true_type
0215 )
0216 {
0217 channel_sizes_t channel_sizes( info._samples_per_pixel
0218 , info._bits_per_sample
0219 );
0220
0221 using pixel_t = typename get_pixel_type<View>::type;
0222 using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
0223
0224 using num_channel_t = typename num_channels<pixel_t>::value_type;
0225
0226 const num_channel_t dst_samples_per_pixel = num_channels< pixel_t >::value;
0227
0228
0229 const num_channel_t dst_sample_format = Format_Type<View, channel_t>::value;
0230
0231
0232 return ( dst_samples_per_pixel == info._samples_per_pixel
0233 && compare_channel_sizes< View >( channel_sizes
0234 , typename is_bit_aligned< pixel_t >::type()
0235 , typename is_homogeneous< pixel_t >::type()
0236 )
0237 && dst_sample_format == info._sample_format
0238 );
0239 }
0240
0241 template< typename View >
0242 bool is_allowed( const image_read_info< tiff_tag >&
0243 , std::false_type
0244 )
0245 {
0246 return true;
0247 }
0248
0249 }
0250 }
0251 }
0252
0253 #endif