writer_backend.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // Copyright 2012 Christian Henning
  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_WRITER_BACKEND_HPP
  9. #define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_WRITER_BACKEND_HPP
  10. #include <boost/gil/extension/io/tiff/tags.hpp>
  11. #include <boost/gil/extension/io/tiff/detail/device.hpp>
  12. #include <boost/gil/detail/mp11.hpp>
  13. namespace boost { namespace gil {
  14. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  15. #pragma warning(push)
  16. #pragma warning(disable:4512) //assignment operator could not be generated
  17. #endif
  18. ///
  19. /// TIFF Writer Backend
  20. ///
  21. template< typename Device >
  22. struct writer_backend< Device
  23. , tiff_tag
  24. >
  25. {
  26. public:
  27. using format_tag_t = tiff_tag;
  28. public:
  29. writer_backend( const Device& io_dev
  30. , const image_write_info< tiff_tag >& info
  31. )
  32. : _io_dev( io_dev )
  33. , _info( info )
  34. {}
  35. protected:
  36. template< typename View >
  37. void write_header( const View& view )
  38. {
  39. using pixel_t = typename View::value_type;
  40. // get the type of the first channel (heterogeneous pixels might be broken for now!)
  41. using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
  42. using color_space_t = typename color_space_type<View>::type;
  43. if(! this->_info._photometric_interpretation_user_defined )
  44. {
  45. // write photometric interpretion - Warning: This value is rather
  46. // subjective. The user should better set this value itself. There
  47. // is no way to decide if a image is PHOTOMETRIC_MINISWHITE or
  48. // PHOTOMETRIC_MINISBLACK. If the user has not manually set it, then
  49. // this writer will assume PHOTOMETRIC_MINISBLACK for gray_t images,
  50. // PHOTOMETRIC_RGB for rgb_t images, and PHOTOMETRIC_SEPARATED (as
  51. // is conventional) for cmyk_t images.
  52. this->_info._photometric_interpretation = detail::photometric_interpretation< color_space_t >::value;
  53. }
  54. // write dimensions
  55. tiff_image_width::type width = (tiff_image_width::type) view.width();
  56. tiff_image_height::type height = (tiff_image_height::type) view.height();
  57. this->_io_dev.template set_property< tiff_image_width >( width );
  58. this->_io_dev.template set_property< tiff_image_height >( height );
  59. // write planar configuration
  60. this->_io_dev.template set_property<tiff_planar_configuration>( this->_info._planar_configuration );
  61. // write samples per pixel
  62. tiff_samples_per_pixel::type samples_per_pixel = num_channels< pixel_t >::value;
  63. this->_io_dev.template set_property<tiff_samples_per_pixel>( samples_per_pixel );
  64. if /*constexpr*/ (mp11::mp_contains<color_space_t, alpha_t>::value)
  65. {
  66. std:: vector <uint16_t> extra_samples {EXTRASAMPLE_ASSOCALPHA};
  67. this->_io_dev.template set_property<tiff_extra_samples>( extra_samples );
  68. }
  69. // write bits per sample
  70. // @todo: Settings this value usually requires to write for each sample the bit
  71. // value seperately in case they are different, like rgb556.
  72. tiff_bits_per_sample::type bits_per_sample = detail::unsigned_integral_num_bits< channel_t >::value;
  73. this->_io_dev.template set_property<tiff_bits_per_sample>( bits_per_sample );
  74. // write sample format
  75. tiff_sample_format::type sampl_format = detail::sample_format< channel_t >::value;
  76. this->_io_dev.template set_property<tiff_sample_format>( sampl_format );
  77. // write photometric format
  78. this->_io_dev.template set_property<tiff_photometric_interpretation>( this->_info._photometric_interpretation );
  79. // write compression
  80. this->_io_dev.template set_property<tiff_compression>( this->_info._compression );
  81. // write orientation
  82. this->_io_dev.template set_property<tiff_orientation>( this->_info._orientation );
  83. // write rows per strip
  84. this->_io_dev.template set_property<tiff_rows_per_strip>( this->_io_dev.get_default_strip_size() );
  85. // write x, y resolution and units
  86. this->_io_dev.template set_property<tiff_resolution_unit>( this->_info._resolution_unit );
  87. this->_io_dev.template set_property<tiff_x_resolution>( this->_info._x_resolution );
  88. this->_io_dev.template set_property<tiff_y_resolution>( this->_info._y_resolution );
  89. /// Optional and / or non-baseline tags below here
  90. // write ICC colour profile, if it's there
  91. // http://www.color.org/icc_specs2.xalter
  92. if ( 0 != this->_info._icc_profile.size())
  93. this->_io_dev.template set_property<tiff_icc_profile>( this->_info._icc_profile );
  94. }
  95. public:
  96. Device _io_dev;
  97. image_write_info< tiff_tag > _info;
  98. };
  99. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  100. #pragma warning(pop)
  101. #endif
  102. } // namespace gil
  103. } // namespace boost
  104. #endif