| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /*
- Copyright 2007-2008 Christian Henning
- Use, modification and distribution are subject to the Boost Software License,
- Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt).
- */
- /*************************************************************************************************/
- #ifndef BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
- #define BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
- ////////////////////////////////////////////////////////////////////////////////////////
- /// \file
- /// \brief Helper for having one read implementation used for
- /// bit_aligned and byte images.
- /// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n
- ///
- /// \date 2007-2008 \n
- ///
- ////////////////////////////////////////////////////////////////////////////////////////
- #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
- #include <boost/gil/io/typedefs.hpp>
- namespace boost { namespace gil { namespace detail {
- template< typename Pixel
- , typename DummyT = void
- >
- struct row_buffer_helper
- {
- typedef Pixel element_t;
- typedef std::vector< element_t > buffer_t;
- typedef typename buffer_t::iterator iterator_t;
- row_buffer_helper( std::size_t width
- , bool
- )
- : _row_buffer( width )
- {}
- element_t* data() { return &_row_buffer[0]; }
- iterator_t begin() { return _row_buffer.begin(); }
- iterator_t end() { return _row_buffer.end(); }
- buffer_t& buffer() { return _row_buffer; }
- private:
- buffer_t _row_buffer;
- };
- template<typename Pixel >
- struct row_buffer_helper< Pixel
- , typename enable_if< typename is_bit_aligned< Pixel >::type >::type
- >
- {
- typedef byte_t element_t;
- typedef std::vector< element_t > buffer_t;
- typedef Pixel pixel_type;
- typedef bit_aligned_pixel_iterator<pixel_type> iterator_t;
- row_buffer_helper( std::size_t width
- , bool in_bytes
- )
- : _c( ( width
- * pixel_bit_size< pixel_type >::value
- )
- >> 3
- )
- , _r( width
- * pixel_bit_size< pixel_type >::value
- - ( _c << 3 )
- )
- {
- if( in_bytes )
- {
- _row_buffer.resize( width );
- }
- else
- {
- // add one byte if there are remaining bits
- _row_buffer.resize( _c + ( _r!=0 ));
- }
- }
- element_t* data() { return &_row_buffer[0]; }
- iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
- iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
- : iterator_t( &_row_buffer.back() , (int) _r );
- }
- buffer_t& buffer() { return _row_buffer; }
- private:
- // For instance 25 pixels of rgb2 type would be:
- // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
- // c = 18 bytes
- // r = 6 bits
- std::size_t _c; // number of full bytes
- std::size_t _r; // number of remaining bits
- buffer_t _row_buffer;
- };
- template<typename Pixel >
- struct row_buffer_helper< Pixel
- , typename boost::enable_if< typename mpl::and_< typename is_bit_aligned< Pixel >::type
- , typename is_homogeneous< Pixel >::type
- >::type
- >
- >
- {
- typedef byte_t element_t;
- typedef std::vector< element_t > buffer_t;
- typedef Pixel pixel_type;
- typedef bit_aligned_pixel_iterator<pixel_type> iterator_t;
- row_buffer_helper( std::size_t width
- , bool in_bytes
- )
- : _c( ( width
- * num_channels< pixel_type >::type::value
- * channel_type< pixel_type >::type::num_bits
- )
- >> 3
- )
- , _r( width
- * num_channels< pixel_type >::type::value
- * channel_type< pixel_type >::type::num_bits
- - ( _c << 3 )
- )
- {
- if( in_bytes )
- {
- _row_buffer.resize( width );
- }
- else
- {
- // add one byte if there are remaining bits
- _row_buffer.resize( _c + ( _r!=0 ));
- }
- }
- element_t* data() { return &_row_buffer[0]; }
- iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
- iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
- : iterator_t( &_row_buffer.back() , (int) _r );
- }
- buffer_t& buffer() { return _row_buffer; }
- private:
- // For instance 25 pixels of rgb2 type would be:
- // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
- // c = 18 bytes
- // r = 6 bits
- std::size_t _c; // number of full bytes
- std::size_t _r; // number of remaining bits
- buffer_t _row_buffer;
- };
- template< typename View
- , typename D = void
- >
- struct row_buffer_helper_view : row_buffer_helper< typename View::value_type >
- {
- row_buffer_helper_view( std::size_t width
- , bool in_bytes
- )
- : row_buffer_helper< typename View::value_type >( width
- , in_bytes
- )
- {}
- };
- template< typename View >
- struct row_buffer_helper_view< View
- , typename enable_if< typename is_bit_aligned< typename View::value_type
- >::type
- >::type
- > : row_buffer_helper< typename View::reference >
- {
- row_buffer_helper_view( std::size_t width
- , bool in_bytes
- )
- : row_buffer_helper< typename View::reference >( width
- , in_bytes
- )
- {}
- };
- } // namespace detail
- } // namespace gil
- } // namespace boost
- #endif
|