scanline_read.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. //
  2. // Copyright 2007-2012 Christian Henning, Lubomir Bourdev
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SCANLINE_READ_HPP
  9. #define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SCANLINE_READ_HPP
  10. #include <boost/gil/extension/io/tiff/detail/device.hpp>
  11. #include <boost/gil/extension/io/tiff/detail/is_allowed.hpp>
  12. #include <boost/gil/extension/io/tiff/detail/reader_backend.hpp>
  13. #include <boost/gil/io/base.hpp>
  14. #include <boost/gil/io/bit_operations.hpp>
  15. #include <boost/gil/io/conversion_policies.hpp>
  16. #include <boost/gil/io/device.hpp>
  17. #include <boost/gil/io/reader_base.hpp>
  18. #include <boost/gil/io/row_buffer_helper.hpp>
  19. #include <boost/gil/io/scanline_read_iterator.hpp>
  20. #include <algorithm>
  21. #include <functional>
  22. #include <string>
  23. #include <type_traits>
  24. #include <vector>
  25. // taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
  26. #ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
  27. extern "C" {
  28. #endif
  29. #include <tiff.h>
  30. #include <tiffio.h>
  31. #ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
  32. }
  33. #endif
  34. namespace boost { namespace gil {
  35. ///
  36. /// TIFF scanline reader
  37. ///
  38. template< typename Device >
  39. class scanline_reader< Device
  40. , tiff_tag
  41. >
  42. : public reader_backend< Device
  43. , tiff_tag
  44. >
  45. {
  46. public:
  47. using tag_t = tiff_tag;
  48. using backend_t = reader_backend<Device, tag_t>;
  49. using this_t = scanline_reader<Device, tag_t>;
  50. using iterator_t = scanline_read_iterator<this_t>;
  51. scanline_reader( Device& device
  52. , const image_read_settings< tiff_tag >& settings
  53. )
  54. : backend_t( device
  55. , settings
  56. )
  57. {
  58. initialize();
  59. }
  60. /// Read part of image defined by View and return the data.
  61. void read( byte_t* dst, int pos )
  62. {
  63. _read_function( this, dst, pos );
  64. }
  65. /// Skip over a scanline.
  66. void skip( byte_t* dst, int pos )
  67. {
  68. this->_read_function( this, dst, pos );
  69. }
  70. iterator_t begin() { return iterator_t( *this ); }
  71. iterator_t end() { return iterator_t( *this, this->_info._height ); }
  72. private:
  73. void initialize()
  74. {
  75. io_error_if( this->_info._is_tiled
  76. , "scanline_reader doesn't support tiled tiff images."
  77. );
  78. if( this->_info._photometric_interpretation == PHOTOMETRIC_PALETTE )
  79. {
  80. this->_scanline_length = this->_info._width
  81. * num_channels< rgb16_view_t >::value
  82. * sizeof( channel_type<rgb16_view_t>::type );
  83. this->_io_dev.get_field_defaulted( this->_red
  84. , this->_green
  85. , this->_blue
  86. );
  87. _buffer = std::vector< byte_t >( this->_io_dev.get_scanline_size() );
  88. switch( this->_info._bits_per_sample )
  89. {
  90. case 1:
  91. {
  92. using channel_t = channel_type<get_pixel_type<gray1_image_t::view_t>::type>::type;
  93. int num_colors = channel_traits< channel_t >::max_value() + 1;
  94. this->_palette = planar_rgb_view( num_colors
  95. , 1
  96. , this->_red
  97. , this->_green
  98. , this->_blue
  99. , sizeof(uint16_t) * num_colors
  100. );
  101. _read_function = std::mem_fn(&this_t::read_1_bit_index_image);
  102. break;
  103. }
  104. case 2:
  105. {
  106. using channel_t = channel_type<get_pixel_type<gray2_image_t::view_t>::type>::type;
  107. int num_colors = channel_traits< channel_t >::max_value() + 1;
  108. this->_palette = planar_rgb_view( num_colors
  109. , 1
  110. , this->_red
  111. , this->_green
  112. , this->_blue
  113. , sizeof(uint16_t) * num_colors
  114. );
  115. _read_function = std::mem_fn(&this_t::read_2_bits_index_image);
  116. break;
  117. }
  118. case 4:
  119. {
  120. using channel_t = channel_type<get_pixel_type<gray4_image_t::view_t>::type>::type;
  121. int num_colors = channel_traits< channel_t >::max_value() + 1;
  122. this->_palette = planar_rgb_view( num_colors
  123. , 1
  124. , this->_red
  125. , this->_green
  126. , this->_blue
  127. , sizeof(uint16_t) * num_colors
  128. );
  129. _read_function = std::mem_fn(&this_t::read_4_bits_index_image);
  130. break;
  131. }
  132. case 8:
  133. {
  134. using channel_t = channel_type<get_pixel_type<gray8_image_t::view_t>::type>::type;
  135. int num_colors = channel_traits< channel_t >::max_value() + 1;
  136. this->_palette = planar_rgb_view( num_colors
  137. , 1
  138. , this->_red
  139. , this->_green
  140. , this->_blue
  141. , sizeof(uint16_t) * num_colors
  142. );
  143. _read_function = std::mem_fn(&this_t::read_8_bits_index_image);
  144. break;
  145. }
  146. case 16:
  147. {
  148. using channel_t = channel_type<get_pixel_type<gray16_image_t::view_t>::type>::type;
  149. int num_colors = channel_traits< channel_t >::max_value() + 1;
  150. this->_palette = planar_rgb_view( num_colors
  151. , 1
  152. , this->_red
  153. , this->_green
  154. , this->_blue
  155. , sizeof(uint16_t) * num_colors
  156. );
  157. _read_function = std::mem_fn(&this_t::read_16_bits_index_image);
  158. break;
  159. }
  160. case 24:
  161. {
  162. using channel_t = channel_type<get_pixel_type<gray24_image_t::view_t>::type>::type;
  163. int num_colors = channel_traits< channel_t >::max_value() + 1;
  164. this->_palette = planar_rgb_view( num_colors
  165. , 1
  166. , this->_red
  167. , this->_green
  168. , this->_blue
  169. , sizeof(uint16_t) * num_colors
  170. );
  171. _read_function = std::mem_fn(&this_t::read_24_bits_index_image);
  172. break;
  173. }
  174. case 32:
  175. {
  176. using channel_t = channel_type<get_pixel_type<gray32_image_t::view_t>::type>::type;
  177. int num_colors = channel_traits< channel_t >::max_value() + 1;
  178. this->_palette = planar_rgb_view( num_colors
  179. , 1
  180. , this->_red
  181. , this->_green
  182. , this->_blue
  183. , sizeof(uint16_t) * num_colors
  184. );
  185. _read_function = std::mem_fn(&this_t::read_32_bits_index_image);
  186. break;
  187. }
  188. default: { io_error( "Not supported palette " ); }
  189. }
  190. }
  191. else
  192. {
  193. this->_scanline_length = this->_io_dev.get_scanline_size();
  194. if( this->_info._planar_configuration == PLANARCONFIG_SEPARATE )
  195. {
  196. io_error( "scanline_reader doesn't support planar tiff images." );
  197. }
  198. else if( this->_info._planar_configuration == PLANARCONFIG_CONTIG )
  199. {
  200. // the read_data function needs to know what gil type the source image is
  201. // to have the default color converter function correctly
  202. switch( this->_info._photometric_interpretation )
  203. {
  204. case PHOTOMETRIC_MINISWHITE:
  205. case PHOTOMETRIC_MINISBLACK:
  206. {
  207. switch( this->_info._bits_per_sample )
  208. {
  209. case 1:
  210. case 2:
  211. case 4:
  212. case 6:
  213. case 8:
  214. case 10:
  215. case 12:
  216. case 14:
  217. case 16:
  218. case 24:
  219. case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
  220. default: { io_error( "Image type is not supported." ); }
  221. }
  222. break;
  223. }
  224. case PHOTOMETRIC_RGB:
  225. {
  226. switch( this->_info._samples_per_pixel )
  227. {
  228. case 3:
  229. {
  230. switch( this->_info._bits_per_sample )
  231. {
  232. case 2:
  233. case 4:
  234. case 8:
  235. case 10:
  236. case 12:
  237. case 14:
  238. case 16:
  239. case 24:
  240. case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
  241. default: { io_error( "Image type is not supported." ); }
  242. }
  243. break;
  244. }
  245. case 4:
  246. {
  247. switch( this->_info._bits_per_sample )
  248. {
  249. case 2:
  250. case 4:
  251. case 8:
  252. case 10:
  253. case 12:
  254. case 14:
  255. case 16:
  256. case 24:
  257. case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
  258. default: { io_error( "Image type is not supported." ); }
  259. }
  260. break;
  261. }
  262. default: { io_error( "Image type is not supported." ); }
  263. }
  264. break;
  265. }
  266. case PHOTOMETRIC_SEPARATED: // CYMK
  267. {
  268. switch( this->_info._bits_per_sample )
  269. {
  270. case 2:
  271. case 4:
  272. case 8:
  273. case 10:
  274. case 12:
  275. case 14:
  276. case 16:
  277. case 24:
  278. case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
  279. default: { io_error( "Image type is not supported." ); }
  280. }
  281. break;
  282. }
  283. default: { io_error( "Image type is not supported." ); }
  284. }
  285. }
  286. else
  287. {
  288. io_error( "Wrong planar configuration setting." );
  289. }
  290. }
  291. }
  292. template< typename Src_View >
  293. void read_n_bits_row( byte_t* dst, int pos )
  294. {
  295. using dst_view_t = rgb16_view_t;
  296. this->_io_dev.read_scanline( _buffer
  297. , pos
  298. , 0
  299. );
  300. Src_View src_view = interleaved_view( this->_info._width
  301. , 1
  302. , (typename Src_View::x_iterator) &_buffer.front()
  303. , this->_scanline_length
  304. );
  305. dst_view_t dst_view = interleaved_view( this->_info._width
  306. , 1
  307. , (typename dst_view_t::value_type*) dst
  308. , num_channels< dst_view_t >::value * 2 * this->_info._width
  309. );
  310. typename Src_View::x_iterator src_it = src_view.row_begin( 0 );
  311. typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
  312. for( dst_view_t::x_coord_t i = 0
  313. ; i < this->_info._width
  314. ; ++i, src_it++, dst_it++
  315. )
  316. {
  317. auto const c = static_cast<std::uint16_t>(get_color(*src_it, gray_color_t()));
  318. *dst_it = this->_palette[c];
  319. }
  320. }
  321. void read_1_bit_index_image( byte_t* dst, int pos )
  322. {
  323. read_n_bits_row< gray1_image_t::view_t >( dst, pos );
  324. }
  325. void read_2_bits_index_image( byte_t* dst, int pos )
  326. {
  327. read_n_bits_row< gray2_image_t::view_t >( dst, pos );
  328. }
  329. void read_4_bits_index_image( byte_t* dst, int pos )
  330. {
  331. read_n_bits_row< gray4_image_t::view_t >( dst, pos );
  332. }
  333. void read_8_bits_index_image( byte_t* dst, int pos )
  334. {
  335. read_n_bits_row< gray8_image_t::view_t >( dst, pos );
  336. }
  337. void read_16_bits_index_image( byte_t* dst, int pos )
  338. {
  339. read_n_bits_row< gray16_image_t::view_t >( dst, pos );
  340. }
  341. void read_24_bits_index_image( byte_t* dst, int pos )
  342. {
  343. read_n_bits_row< gray24_image_t::view_t >( dst, pos );
  344. }
  345. void read_32_bits_index_image( byte_t* dst, int pos )
  346. {
  347. read_n_bits_row< gray32_image_t::view_t >( dst, pos );
  348. }
  349. void read_row(byte_t* dst, int pos )
  350. {
  351. this->_io_dev.read_scanline( dst
  352. , pos
  353. , 0
  354. );
  355. }
  356. private:
  357. std::vector< byte_t> _buffer;
  358. detail::mirror_bits<std::vector<byte_t>, std::true_type> _mirror_bites;
  359. std::function<void(this_t*, byte_t*, int)> _read_function;
  360. };
  361. } // namespace gil
  362. } // namespace boost
  363. #endif