Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:15:13

0001 //
0002 // Copyright 2007-2008 Christian Henning
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_IO_ROW_BUFFER_HELPER_HPP
0009 #define BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
0010 
0011 // TODO: Shall we move toolbox to core?
0012 #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
0013 #include <boost/gil/extension/toolbox/metafunctions/is_homogeneous.hpp>
0014 #include <boost/gil/extension/toolbox/metafunctions/pixel_bit_size.hpp>
0015 
0016 #include <boost/gil/detail/mp11.hpp>
0017 #include <boost/gil/io/typedefs.hpp>
0018 
0019 #include <cstddef>
0020 #include <type_traits>
0021 #include <vector>
0022 
0023 namespace boost { namespace gil { namespace detail {
0024 
0025 template< typename Pixel
0026         , typename DummyT = void
0027         >
0028 struct row_buffer_helper
0029 {
0030     using element_t = Pixel;
0031     using buffer_t = std::vector<element_t>;
0032     using iterator_t = typename buffer_t::iterator;
0033 
0034     row_buffer_helper( std::size_t width
0035                      , bool
0036                      )
0037     : _row_buffer( width )
0038     {}
0039 
0040     element_t* data() { return &_row_buffer[0]; }
0041 
0042     iterator_t begin() { return _row_buffer.begin(); }
0043     iterator_t end()   { return _row_buffer.end();   }
0044 
0045     buffer_t& buffer() { return _row_buffer; }
0046 
0047 private:
0048 
0049     buffer_t _row_buffer;
0050 };
0051 
0052 template <typename Pixel>
0053 struct row_buffer_helper
0054 <
0055     Pixel,
0056     typename std::enable_if
0057     <
0058         is_bit_aligned<Pixel>::value
0059     >::type
0060 >
0061 {
0062     using element_t = byte_t;
0063     using buffer_t = std::vector<element_t>;
0064     using pixel_type = Pixel;
0065     using iterator_t = bit_aligned_pixel_iterator<pixel_type>;
0066 
0067     row_buffer_helper(std::size_t width, bool in_bytes)
0068         : _c{( width * pixel_bit_size< pixel_type >::value) >> 3}
0069         , _r{width * pixel_bit_size< pixel_type >::value - (_c << 3)}
0070     {
0071         if (in_bytes)
0072         {
0073             _row_buffer.resize(width);
0074         }
0075         else
0076         {
0077             // add one byte if there are remaining bits
0078             _row_buffer.resize(_c + (_r != 0));
0079         }
0080     }
0081 
0082     element_t* data() { return &_row_buffer[0]; }
0083 
0084     iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
0085     iterator_t end()   { return _r == 0 ? iterator_t( &_row_buffer.back() + 1,  0 )
0086                                         : iterator_t( &_row_buffer.back()    , (int) _r );
0087                        }
0088 
0089     buffer_t& buffer() { return _row_buffer; }
0090 
0091 private:
0092 
0093     // For instance 25 pixels of rgb2 type would be:
0094     // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
0095     // c = 18 bytes
0096     // r = 6 bits
0097 
0098     std::size_t _c; // number of full bytes
0099     std::size_t _r; // number of remaining bits
0100 
0101     buffer_t _row_buffer;
0102 };
0103 
0104 template<typename Pixel>
0105 struct row_buffer_helper
0106 <
0107     Pixel,
0108     typename std::enable_if
0109     <
0110         mp11::mp_and
0111         <
0112             typename is_bit_aligned<Pixel>::type,
0113             typename is_homogeneous<Pixel>::type
0114         >::value
0115     >
0116 >
0117 {
0118     using element_t = byte_t;
0119     using buffer_t = std::vector<element_t>;
0120     using pixel_type = Pixel;
0121     using iterator_t = bit_aligned_pixel_iterator<pixel_type>;
0122 
0123     row_buffer_helper( std::size_t width
0124                      , bool        in_bytes
0125                      )
0126     : _c( ( width
0127           * num_channels< pixel_type >::value
0128           * channel_type< pixel_type >::type::num_bits
0129           )
0130           >> 3
0131         )
0132 
0133     , _r( width
0134         * num_channels< pixel_type >::value
0135         * channel_type< pixel_type >::type::num_bits
0136         - ( _c << 3 )
0137        )
0138     {
0139         if( in_bytes )
0140         {
0141             _row_buffer.resize( width );
0142         }
0143         else
0144         {
0145             // add one byte if there are remaining bits
0146             _row_buffer.resize( _c + ( _r!=0 ));
0147         }
0148     }
0149 
0150     element_t* data() { return &_row_buffer[0]; }
0151 
0152     iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
0153     iterator_t end()   { return _r == 0 ? iterator_t( &_row_buffer.back() + 1,  0 )
0154                                         : iterator_t( &_row_buffer.back()    , (int) _r );
0155                        }
0156 
0157     buffer_t& buffer() { return _row_buffer; }
0158 
0159 private:
0160 
0161     // For instance 25 pixels of rgb2 type would be:
0162     // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
0163     // c = 18 bytes
0164     // r = 6 bits
0165 
0166     std::size_t _c; // number of full bytes
0167     std::size_t _r; // number of remaining bits
0168 
0169     buffer_t _row_buffer;
0170 };
0171 
0172 template <typename View, typename D = void>
0173 struct row_buffer_helper_view : row_buffer_helper<typename View::value_type>
0174 {
0175     row_buffer_helper_view(std::size_t width, bool in_bytes)
0176         : row_buffer_helper<typename View::value_type>(width, in_bytes)
0177     {}
0178 };
0179 
0180 template <typename View>
0181 struct row_buffer_helper_view
0182 <
0183     View,
0184     typename std::enable_if
0185     <
0186         is_bit_aligned<typename View::value_type>::value
0187     >::type
0188 > : row_buffer_helper<typename View::reference>
0189 {
0190     row_buffer_helper_view(std::size_t width, bool in_bytes)
0191         : row_buffer_helper<typename View::reference>(width, in_bytes)
0192     {}
0193 };
0194 
0195 } // namespace detail
0196 } // namespace gil
0197 } // namespace boost
0198 
0199 #endif