/* 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 #include 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 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 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 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 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