Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:59

0001 //
0002 // Copyright 2008 Christian Henning, Lubomir Bourdev
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
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 // is_bit_aligned< View >
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 // is_not_bit_aligned< View > && is_unsigned< Channel >
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 // is_not_bit_aligned< View > && is_signed< Channel >
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 // is_not_bit_aligned< View > && is_floating_point< Channel >
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 //template< typename Channel >
0110 //int format_value( std::true_type ) // is_bit_aligned
0111 //{
0112 //    return SAMPLEFORMAT_UINT;
0113 //}
0114 //
0115 //template< typename Channel >
0116 //int format_value( std::false_type ) // is_bit_aligned
0117 //{
0118 //    if( is_unsigned< Channel >::value )
0119 //    {
0120 //        return SAMPLEFORMAT_UINT;
0121 //    }
0122 //
0123 //    if( is_signed< Channel >::value )
0124 //    {
0125 //        return SAMPLEFORMAT_INT;
0126 //    }
0127 //
0128 //    else if( is_floating_point< Channel >::value )
0129 //    {
0130 //        return SAMPLEFORMAT_IEEEFP;
0131 //    }
0132 //
0133 //    io_error( "Unkown channel format." );
0134 //}
0135 
0136 // The following two functions look the same but are different since one is using
0137 // a pixel_t as template parameter whereas the other is using reference_t.
0138 template< typename View >
0139 bool compare_channel_sizes( const channel_sizes_t& channel_sizes // in bits
0140                           , std::false_type                      // is_bit_aligned
0141                           , std::true_type                       // is_homogeneous
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 // in bits
0155                           , std::true_type                       // is_bit_aligned
0156                           , std::true_type                       // is_homogeneous
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 // in bits
0197                           , std::true_type                 // is_bit_aligned
0198                           , std::false_type                // is_homogeneous
0199                           )
0200 {
0201     // loop through all channels and compare
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 // is read_and_no_convert
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     //const num_channel_t dst_sample_format     = format_value< channel_t >( typename is_bit_aligned< pixel_t >::type() );
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 >& /* info */
0243                , std::false_type // is read_and_no_convert
0244                )
0245 {
0246     return true;
0247 }
0248 
0249 } // namespace detail
0250 } // namespace gil
0251 } // namespace boost
0252 
0253 #endif