row_buffer_helper.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. Copyright 2007-2008 Christian Henning
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. /*************************************************************************************************/
  8. #ifndef BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
  9. #define BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
  10. ////////////////////////////////////////////////////////////////////////////////////////
  11. /// \file
  12. /// \brief Helper for having one read implementation used for
  13. /// bit_aligned and byte images.
  14. /// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n
  15. ///
  16. /// \date 2007-2008 \n
  17. ///
  18. ////////////////////////////////////////////////////////////////////////////////////////
  19. #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
  20. #include <boost/gil/io/typedefs.hpp>
  21. namespace boost { namespace gil { namespace detail {
  22. template< typename Pixel
  23. , typename DummyT = void
  24. >
  25. struct row_buffer_helper
  26. {
  27. typedef Pixel element_t;
  28. typedef std::vector< element_t > buffer_t;
  29. typedef typename buffer_t::iterator iterator_t;
  30. row_buffer_helper( std::size_t width
  31. , bool
  32. )
  33. : _row_buffer( width )
  34. {}
  35. element_t* data() { return &_row_buffer[0]; }
  36. iterator_t begin() { return _row_buffer.begin(); }
  37. iterator_t end() { return _row_buffer.end(); }
  38. buffer_t& buffer() { return _row_buffer; }
  39. private:
  40. buffer_t _row_buffer;
  41. };
  42. template<typename Pixel >
  43. struct row_buffer_helper< Pixel
  44. , typename enable_if< typename is_bit_aligned< Pixel >::type >::type
  45. >
  46. {
  47. typedef byte_t element_t;
  48. typedef std::vector< element_t > buffer_t;
  49. typedef Pixel pixel_type;
  50. typedef bit_aligned_pixel_iterator<pixel_type> iterator_t;
  51. row_buffer_helper( std::size_t width
  52. , bool in_bytes
  53. )
  54. : _c( ( width
  55. * pixel_bit_size< pixel_type >::value
  56. )
  57. >> 3
  58. )
  59. , _r( width
  60. * pixel_bit_size< pixel_type >::value
  61. - ( _c << 3 )
  62. )
  63. {
  64. if( in_bytes )
  65. {
  66. _row_buffer.resize( width );
  67. }
  68. else
  69. {
  70. // add one byte if there are remaining bits
  71. _row_buffer.resize( _c + ( _r!=0 ));
  72. }
  73. }
  74. element_t* data() { return &_row_buffer[0]; }
  75. iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
  76. iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
  77. : iterator_t( &_row_buffer.back() , (int) _r );
  78. }
  79. buffer_t& buffer() { return _row_buffer; }
  80. private:
  81. // For instance 25 pixels of rgb2 type would be:
  82. // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
  83. // c = 18 bytes
  84. // r = 6 bits
  85. std::size_t _c; // number of full bytes
  86. std::size_t _r; // number of remaining bits
  87. buffer_t _row_buffer;
  88. };
  89. template<typename Pixel >
  90. struct row_buffer_helper< Pixel
  91. , typename boost::enable_if< typename mpl::and_< typename is_bit_aligned< Pixel >::type
  92. , typename is_homogeneous< Pixel >::type
  93. >::type
  94. >
  95. >
  96. {
  97. typedef byte_t element_t;
  98. typedef std::vector< element_t > buffer_t;
  99. typedef Pixel pixel_type;
  100. typedef bit_aligned_pixel_iterator<pixel_type> iterator_t;
  101. row_buffer_helper( std::size_t width
  102. , bool in_bytes
  103. )
  104. : _c( ( width
  105. * num_channels< pixel_type >::type::value
  106. * channel_type< pixel_type >::type::num_bits
  107. )
  108. >> 3
  109. )
  110. , _r( width
  111. * num_channels< pixel_type >::type::value
  112. * channel_type< pixel_type >::type::num_bits
  113. - ( _c << 3 )
  114. )
  115. {
  116. if( in_bytes )
  117. {
  118. _row_buffer.resize( width );
  119. }
  120. else
  121. {
  122. // add one byte if there are remaining bits
  123. _row_buffer.resize( _c + ( _r!=0 ));
  124. }
  125. }
  126. element_t* data() { return &_row_buffer[0]; }
  127. iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
  128. iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
  129. : iterator_t( &_row_buffer.back() , (int) _r );
  130. }
  131. buffer_t& buffer() { return _row_buffer; }
  132. private:
  133. // For instance 25 pixels of rgb2 type would be:
  134. // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
  135. // c = 18 bytes
  136. // r = 6 bits
  137. std::size_t _c; // number of full bytes
  138. std::size_t _r; // number of remaining bits
  139. buffer_t _row_buffer;
  140. };
  141. template< typename View
  142. , typename D = void
  143. >
  144. struct row_buffer_helper_view : row_buffer_helper< typename View::value_type >
  145. {
  146. row_buffer_helper_view( std::size_t width
  147. , bool in_bytes
  148. )
  149. : row_buffer_helper< typename View::value_type >( width
  150. , in_bytes
  151. )
  152. {}
  153. };
  154. template< typename View >
  155. struct row_buffer_helper_view< View
  156. , typename enable_if< typename is_bit_aligned< typename View::value_type
  157. >::type
  158. >::type
  159. > : row_buffer_helper< typename View::reference >
  160. {
  161. row_buffer_helper_view( std::size_t width
  162. , bool in_bytes
  163. )
  164. : row_buffer_helper< typename View::reference >( width
  165. , in_bytes
  166. )
  167. {}
  168. };
  169. } // namespace detail
  170. } // namespace gil
  171. } // namespace boost
  172. #endif