tiff_io.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. Copyright 2005-2007 Adobe Systems Incorporated
  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. See http://opensource.adobe.com/gil for most recent version including documentation.
  7. */
  8. /*************************************************************************************************/
  9. #ifndef GIL_TIFF_IO_H
  10. #define GIL_TIFF_IO_H
  11. /// \file
  12. /// \brief Support for reading and writing TIFF files
  13. /// Requires libtiff!
  14. /// \author Hailin Jin and Lubomir Bourdev \n
  15. /// Adobe Systems Incorporated
  16. /// \date 2005-2007 \n Last updated September 24, 2006
  17. #include <vector>
  18. #include <string>
  19. #include <algorithm>
  20. #include <boost/static_assert.hpp>
  21. #include <tiffio.h>
  22. #include "../../gil_all.hpp"
  23. #include "io_error.hpp"
  24. namespace boost { namespace gil {
  25. namespace detail {
  26. template <typename Channel,typename ColorSpace>
  27. struct tiff_read_support_private {
  28. BOOST_STATIC_CONSTANT(bool,is_supported=false);
  29. BOOST_STATIC_CONSTANT(int,bit_depth=0);
  30. BOOST_STATIC_CONSTANT(int,color_type=0);
  31. };
  32. template <>
  33. struct tiff_read_support_private<bits8,gray_t> {
  34. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  35. BOOST_STATIC_CONSTANT(int,bit_depth=8);
  36. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  37. };
  38. template <>
  39. struct tiff_read_support_private<bits8,rgb_t> {
  40. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  41. BOOST_STATIC_CONSTANT(int,bit_depth=8);
  42. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  43. };
  44. template <>
  45. struct tiff_read_support_private<bits16,gray_t> {
  46. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  47. BOOST_STATIC_CONSTANT(int,bit_depth=16);
  48. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  49. };
  50. template <>
  51. struct tiff_read_support_private<bits16,rgb_t> {
  52. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  53. BOOST_STATIC_CONSTANT(int,bit_depth=16);
  54. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  55. };
  56. template <>
  57. struct tiff_read_support_private<bits32f,gray_t> {
  58. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  59. BOOST_STATIC_CONSTANT(int,bit_depth=32);
  60. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  61. };
  62. template <>
  63. struct tiff_read_support_private<bits32f,rgb_t> {
  64. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  65. BOOST_STATIC_CONSTANT(int,bit_depth=32);
  66. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  67. };
  68. template <typename Channel,typename ColorSpace>
  69. struct tiff_write_support_private {
  70. BOOST_STATIC_CONSTANT(bool,is_supported=false);
  71. BOOST_STATIC_CONSTANT(int,bit_depth=0);
  72. BOOST_STATIC_CONSTANT(int,color_type=0);
  73. };
  74. template <>
  75. struct tiff_write_support_private<bits8,gray_t> {
  76. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  77. BOOST_STATIC_CONSTANT(int,bit_depth=8);
  78. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  79. };
  80. template <>
  81. struct tiff_write_support_private<bits8,rgb_t> {
  82. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  83. BOOST_STATIC_CONSTANT(int,bit_depth=8);
  84. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  85. };
  86. template <>
  87. struct tiff_write_support_private<bits16,gray_t> {
  88. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  89. BOOST_STATIC_CONSTANT(int,bit_depth=16);
  90. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  91. };
  92. template <>
  93. struct tiff_write_support_private<bits16,rgb_t> {
  94. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  95. BOOST_STATIC_CONSTANT(int,bit_depth=16);
  96. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  97. };
  98. template <>
  99. struct tiff_write_support_private<bits32f,gray_t> {
  100. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  101. BOOST_STATIC_CONSTANT(int,bit_depth=32);
  102. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
  103. };
  104. template <>
  105. struct tiff_write_support_private<bits32f,rgb_t> {
  106. BOOST_STATIC_CONSTANT(bool,is_supported=true);
  107. BOOST_STATIC_CONSTANT(int,bit_depth=32);
  108. BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
  109. };
  110. class tiff_reader {
  111. protected:
  112. TIFF *_tp;
  113. public:
  114. tiff_reader(const char* filename,tdir_t dirnum=0) {
  115. io_error_if((_tp=TIFFOpen(filename,"r"))==NULL,
  116. "tiff_reader: fail to open file");
  117. if(dirnum>0) {
  118. io_error_if(TIFFSetDirectory(_tp,dirnum)!=1,
  119. "tiff_reader: fail to set directory");
  120. }
  121. }
  122. ~tiff_reader() { TIFFClose(_tp); }
  123. template <typename View>
  124. void apply(const View& view) {
  125. unsigned short bps,photometric;
  126. point2<std::ptrdiff_t> dims=get_dimensions();
  127. io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
  128. io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
  129. io_error_if(dims!=view.dimensions(),
  130. "tiff_read_view: input view size does not match TIFF file size");
  131. io_error_if(tiff_read_support_private<typename channel_type<View>::type,
  132. typename color_space_type<View>::type>::bit_depth!=bps ||
  133. tiff_read_support_private<typename channel_type<View>::type,
  134. typename color_space_type<View>::type>::color_type!=photometric,
  135. "tiff_read_view: input view type is incompatible with the image type");
  136. std::size_t element_size=sizeof(pixel<typename channel_type<View>::type,
  137. layout<typename color_space_type<View>::type> >);
  138. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  139. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  140. std::vector<pixel<typename channel_type<View>::type,
  141. layout<typename color_space_type<View>::type> > > row(size_to_allocate);
  142. for (int y=0;y<view.height();++y) {
  143. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  144. std::copy(row.begin(),row.begin()+view.width(),view.row_begin(y));
  145. }
  146. }
  147. point2<std::ptrdiff_t> get_dimensions() {
  148. int w,h;
  149. io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH, &w)!=1);
  150. io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&h)!=1);
  151. return point2<std::ptrdiff_t>(w,h);
  152. }
  153. template <typename Image>
  154. void read_image(Image& im) {
  155. im.recreate(get_dimensions());
  156. apply(view(im));
  157. }
  158. };
  159. // This code will be simplified...
  160. template <typename CC>
  161. class tiff_reader_color_convert : public tiff_reader {
  162. private:
  163. CC _cc;
  164. public:
  165. tiff_reader_color_convert(const char* filename,tdir_t dirnum=0) :
  166. tiff_reader(filename,dirnum) {}
  167. tiff_reader_color_convert(const char* filename,CC cc_in,tdir_t dirnum=0) :
  168. tiff_reader(filename,dirnum),_cc(cc_in) {}
  169. template <typename View>
  170. void apply(const View& view) {
  171. point2<std::ptrdiff_t> dims=get_dimensions();
  172. unsigned short bps,photometric;
  173. io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
  174. io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
  175. io_error_if(dims!=view.dimensions(),
  176. "tiff_reader_color_convert::apply(): input view size does not match TIFF file size");
  177. switch (photometric) {
  178. case PHOTOMETRIC_MINISBLACK: {
  179. switch (bps) {
  180. case 8: {
  181. std::size_t element_size=sizeof(gray8_pixel_t);
  182. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  183. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  184. std::vector<gray8_pixel_t> row(size_to_allocate);
  185. for (int y=0;y<view.height();++y) {
  186. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  187. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  188. color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
  189. }
  190. break;
  191. }
  192. case 16: {
  193. std::size_t element_size=sizeof(gray16_pixel_t);
  194. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  195. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  196. std::vector<gray16_pixel_t> row(size_to_allocate);
  197. for (int y=0;y<view.height();++y) {
  198. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  199. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  200. color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
  201. }
  202. break;
  203. }
  204. case 32: {
  205. std::size_t element_size=sizeof(gray32f_pixel_t);
  206. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  207. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  208. std::vector<gray32f_pixel_t> row(size_to_allocate);
  209. for (int y=0;y<view.height();++y) {
  210. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  211. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  212. color_convert_deref_fn<gray32f_ref_t,typename View::value_type,CC>(_cc));
  213. }
  214. break;
  215. }
  216. default:
  217. io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
  218. }
  219. break;
  220. }
  221. case PHOTOMETRIC_RGB: {
  222. switch (bps) {
  223. case 8: {
  224. std::size_t element_size=sizeof(rgb8_pixel_t);
  225. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  226. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  227. std::vector<rgb8_pixel_t> row(size_to_allocate);
  228. for (int y=0;y<view.height();++y) {
  229. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  230. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  231. color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
  232. }
  233. break;
  234. }
  235. case 16: {
  236. std::size_t element_size=sizeof(rgb16_pixel_t);
  237. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  238. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  239. std::vector<rgb16_pixel_t> row(size_to_allocate);
  240. for (int y=0;y<view.height();++y) {
  241. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  242. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  243. color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
  244. }
  245. break;
  246. }
  247. case 32: {
  248. std::size_t element_size=sizeof(rgb32f_pixel_t);
  249. std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
  250. (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
  251. std::vector<rgb32f_pixel_t> row(size_to_allocate);
  252. for (int y=0;y<view.height();++y) {
  253. io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
  254. std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
  255. color_convert_deref_fn<rgb32f_ref_t,typename View::value_type,CC>(_cc));
  256. }
  257. break;
  258. }
  259. default:
  260. io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
  261. }
  262. break;
  263. }
  264. default: {
  265. // reads an image in incompatible format via TIFFReadRGBAImage
  266. rgba8_image_t rgbaImg(dims);
  267. io_error_if(!TIFFReadRGBAImage(_tp, dims.x, dims.y, (uint32*)&gil::view(rgbaImg)(0,0), 0),
  268. "tiff_reader_color_convert::unsupported image format");
  269. copy_and_convert_pixels(flipped_up_down_view(const_view(rgbaImg)), view, _cc);
  270. }
  271. }
  272. }
  273. template <typename Image>
  274. void read_image(Image& im) {
  275. im.recreate(get_dimensions());
  276. apply(view(im));
  277. }
  278. };
  279. class tiff_writer {
  280. protected:
  281. TIFF* _tp;
  282. public:
  283. tiff_writer(const char *filename) {
  284. io_error_if((_tp=TIFFOpen(filename,"w"))==NULL,
  285. "tiff_writer: fail to open file");
  286. }
  287. ~tiff_writer() {TIFFClose(_tp);}
  288. template <typename View>
  289. void apply(const View& view) {
  290. io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGELENGTH, view.height())!=1);
  291. io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGEWIDTH, view.width())!=1);
  292. io_error_if(TIFFSetField(_tp,TIFFTAG_PHOTOMETRIC, tiff_write_support_private<typename channel_type<View>::type,
  293. typename color_space_type<View>::type>::color_type)!=1);
  294. io_error_if(TIFFSetField(_tp,TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE)!=1);
  295. io_error_if(TIFFSetField(_tp,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)!=1);
  296. io_error_if(TIFFSetField(_tp,TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)!=1);
  297. io_error_if(TIFFSetField(_tp,TIFFTAG_SAMPLESPERPIXEL,num_channels<View>::value)!=1);
  298. io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private<typename channel_type<View>::type,
  299. typename color_space_type<View>::type>::bit_depth)!=1);
  300. io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1);
  301. std::vector<pixel<typename channel_type<View>::type,
  302. layout<typename color_space_type<View>::type> > > row(view.width());
  303. for (int y=0;y<view.height();++y) {
  304. std::copy(view.row_begin(y),view.row_end(y),row.begin());
  305. io_error_if(TIFFWriteScanline(_tp,&row.front(),y,0)!=1,
  306. "tiff_write_view: fail to write file");
  307. }
  308. }
  309. };
  310. } // namespace detail
  311. /// \ingroup TIFF_IO
  312. /// \brief Determines whether the given view type is supported for reading
  313. template <typename View>
  314. struct tiff_read_support {
  315. BOOST_STATIC_CONSTANT(bool,is_supported=
  316. (detail::tiff_read_support_private<typename channel_type<View>::type,
  317. typename color_space_type<View>::type>::is_supported));
  318. BOOST_STATIC_CONSTANT(int,bit_depth=
  319. (detail::tiff_read_support_private<typename channel_type<View>::type,
  320. typename color_space_type<View>::type>::bit_depth));
  321. BOOST_STATIC_CONSTANT(int,color_type=
  322. (detail::tiff_read_support_private<typename channel_type<View>::type,
  323. typename color_space_type<View>::type>::color_type));
  324. };
  325. /// \ingroup TIFF_IO
  326. /// \brief Returns the number of directories in the TIFF file
  327. inline int tiff_get_directory_count(const char* filename) {
  328. TIFF *tif;
  329. io_error_if((tif=TIFFOpen(filename,"r"))==NULL,
  330. "tiff_get_count: fail to open file");
  331. int dircount = 0;
  332. do {
  333. dircount++;
  334. } while (TIFFReadDirectory(tif));
  335. TIFFClose(tif);
  336. return dircount;
  337. }
  338. /// \ingroup TIFF_IO
  339. /// \brief Returns the width and height of the TIFF file at the specified location.
  340. /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
  341. inline point2<std::ptrdiff_t> tiff_read_dimensions(const char* filename,tdir_t dirnum=0) {
  342. detail::tiff_reader m(filename,dirnum);
  343. return m.get_dimensions();
  344. }
  345. /// \ingroup TIFF_IO
  346. /// \brief Returns the width and height of the TIFF file at the specified location.
  347. /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
  348. inline point2<std::ptrdiff_t> tiff_read_dimensions(const std::string& filename,tdir_t dirnum=0) {
  349. return tiff_read_dimensions(filename.c_str(),dirnum);
  350. }
  351. /// \ingroup TIFF_IO
  352. /// \brief Loads the image specified by the given tiff image file name into the given view.
  353. /// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
  354. /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
  355. /// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
  356. template <typename View>
  357. inline void tiff_read_view(const char* filename,const View& view,tdir_t dirnum=0) {
  358. BOOST_STATIC_ASSERT(tiff_read_support<View>::is_supported);
  359. detail::tiff_reader m(filename,dirnum);
  360. m.apply(view);
  361. }
  362. /// \ingroup TIFF_IO
  363. /// \brief Loads the image specified by the given tiff image file name into the given view.
  364. template <typename View>
  365. inline void tiff_read_view(const std::string& filename,const View& view,tdir_t dirnum=0) {
  366. tiff_read_view(filename.c_str(),view,dirnum);
  367. }
  368. /// \ingroup TIFF_IO
  369. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
  370. /// Triggers a compile assert if the image color space or channel depth are not supported by the TIFF library or by the I/O extension.
  371. /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
  372. /// compatible with the ones specified by Image
  373. template <typename Image>
  374. void tiff_read_image(const char* filename,Image& im,tdir_t dirnum=0) {
  375. BOOST_STATIC_ASSERT(tiff_read_support<typename Image::view_t>::is_supported);
  376. detail::tiff_reader m(filename,dirnum);
  377. m.read_image(im);
  378. }
  379. /// \ingroup TIFF_IO
  380. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
  381. template <typename Image>
  382. inline void tiff_read_image(const std::string& filename,Image& im,tdir_t dirnum=0) {
  383. tiff_read_image(filename.c_str(),im,dirnum);
  384. }
  385. /// \ingroup TIFF_IO
  386. /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
  387. /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
  388. template <typename View,typename CC>
  389. inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc,tdir_t dirnum=0) {
  390. detail::tiff_reader_color_convert<CC> m(filename,cc,dirnum);
  391. m.apply(view);
  392. }
  393. /// \ingroup TIFF_IO
  394. /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
  395. /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
  396. template <typename View>
  397. inline void tiff_read_and_convert_view(const char* filename,const View& view,tdir_t dirnum=0) {
  398. detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter(),dirnum);
  399. m.apply(view);
  400. }
  401. /// \ingroup TIFF_IO
  402. /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
  403. template <typename View,typename CC>
  404. inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc,tdir_t dirnum=0) {
  405. tiff_read_and_convert_view(filename.c_str(),view,cc,dirnum);
  406. }
  407. /// \ingroup TIFF_IO
  408. /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
  409. template <typename View>
  410. inline void tiff_read_and_convert_view(const std::string& filename,const View& view,tdir_t dirnum=0) {
  411. tiff_read_and_convert_view(filename.c_str(),view,dirnum);
  412. }
  413. /// \ingroup TIFF_IO
  414. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
  415. /// Throws std::ios_base::failure if the file is not a valid TIFF file
  416. template <typename Image,typename CC>
  417. void tiff_read_and_convert_image(const char* filename,Image& im,CC cc,tdir_t dirnum=0) {
  418. detail::tiff_reader_color_convert<CC> m(filename,cc,dirnum);
  419. m.read_image(im);
  420. }
  421. /// \ingroup TIFF_IO
  422. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
  423. /// Throws std::ios_base::failure if the file is not a valid TIFF file
  424. template <typename Image>
  425. void tiff_read_and_convert_image(const char* filename,Image& im,tdir_t dirnum=0) {
  426. detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter(),dirnum);
  427. m.read_image(im);
  428. }
  429. /// \ingroup TIFF_IO
  430. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
  431. template <typename Image,typename CC>
  432. inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc,tdir_t dirnum=0) {
  433. tiff_read_and_convert_image(filename.c_str(),im,cc,dirnum);
  434. }
  435. /// \ingroup TIFF_IO
  436. /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
  437. template <typename Image>
  438. inline void tiff_read_and_convert_image(const std::string& filename,Image& im,tdir_t dirnum=0) {
  439. tiff_read_and_convert_image(filename.c_str(),im,dirnum);
  440. }
  441. /// \ingroup TIFF_IO
  442. /// \brief Determines whether the given view type is supported for writing
  443. template <typename View>
  444. struct tiff_write_support {
  445. BOOST_STATIC_CONSTANT(bool,is_supported=
  446. (detail::tiff_write_support_private<typename channel_type<View>::type,
  447. typename color_space_type<View>::type>::is_supported));
  448. BOOST_STATIC_CONSTANT(int,bit_depth=
  449. (detail::tiff_write_support_private<typename channel_type<View>::type,
  450. typename color_space_type<View>::type>::bit_depth));
  451. BOOST_STATIC_CONSTANT(int,color_type=
  452. (detail::tiff_write_support_private<typename channel_type<View>::type,
  453. typename color_space_type<View>::type>::color_type));
  454. BOOST_STATIC_CONSTANT(bool, value=is_supported);
  455. };
  456. /// \ingroup TIFF_IO
  457. /// \brief Saves the view to a tiff file specified by the given tiff image file name.
  458. /// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
  459. /// Throws std::ios_base::failure if it fails to create the file.
  460. template <typename View>
  461. inline void tiff_write_view(const char* filename,const View& view) {
  462. BOOST_STATIC_ASSERT(tiff_write_support<View>::is_supported);
  463. detail::tiff_writer m(filename);
  464. m.apply(view);
  465. }
  466. /// \ingroup TIFF_IO
  467. /// \brief Saves the view to a tiff file specified by the given tiff image file name.
  468. template <typename View>
  469. inline void tiff_write_view(const std::string& filename,const View& view) {
  470. tiff_write_view(filename.c_str(),view);
  471. }
  472. } } // namespace boost::gil
  473. #endif