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_READER_BACKEND_HPP
9 #define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_READER_BACKEND_HPP
10 
11 #include <boost/gil/extension/io/tiff/tags.hpp>
12 
13 namespace boost { namespace gil {
14 
15 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
16 #pragma warning(push)
17 #pragma warning(disable:4512) //assignment operator could not be generated
18 #endif
19 
20 ///
21 /// TIFF Backend
22 ///
23 template< typename Device >
24 struct reader_backend< Device
25                      , tiff_tag
26                      >
27 {
28 public:
29 
30     using format_tag_t = tiff_tag;
31 
32 public:
33 
reader_backendboost::gil::reader_backend34     reader_backend( const Device&                          io_dev
35                   , const image_read_settings< tiff_tag >& settings
36                   )
37     : _io_dev  ( io_dev   )
38     , _settings( settings )
39     , _info()
40 
41     , _scanline_length( 0 )
42 
43     , _red  ( nullptr )
44     , _green( nullptr )
45     , _blue ( nullptr )
46     {
47         init_multipage_read( settings );
48 
49         read_header();
50 
51         if( _settings._dim.x == 0 )
52         {
53             _settings._dim.x = _info._width;
54         }
55 
56         if( _settings._dim.y == 0 )
57         {
58             _settings._dim.y = _info._height;
59         }
60     }
61 
read_headerboost::gil::reader_backend62     void read_header()
63     {
64         io_error_if( _io_dev.template get_property<tiff_image_width>               ( _info._width ) == false
65                     , "cannot read tiff tag." );
66         io_error_if( _io_dev.template get_property<tiff_image_height>              ( _info._height ) == false
67                     , "cannot read tiff tag." );
68         io_error_if( _io_dev.template get_property<tiff_compression>               ( _info._compression ) == false
69                     , "cannot read tiff tag." );
70         io_error_if( _io_dev.template get_property<tiff_samples_per_pixel>         ( _info._samples_per_pixel ) == false
71                     , "cannot read tiff tag." );
72         io_error_if( _io_dev.template get_property<tiff_bits_per_sample>           ( _info._bits_per_sample ) == false
73                     , "cannot read tiff tag." );
74         io_error_if( _io_dev.template get_property<tiff_sample_format>             ( _info._sample_format ) == false
75                     , "cannot read tiff tag." );
76         io_error_if( _io_dev.template get_property<tiff_planar_configuration>      ( _info._planar_configuration ) == false
77                     , "cannot read tiff tag." );
78         io_error_if( _io_dev.template get_property<tiff_photometric_interpretation>( _info._photometric_interpretation  ) == false
79                     , "cannot read tiff tag." );
80 
81         _info._is_tiled = false;
82 
83         // Tile tags
84         if( _io_dev.is_tiled() )
85         {
86             _info._is_tiled = true;
87 
88             io_error_if( !_io_dev.template get_property< tiff_tile_width  >( _info._tile_width )
89                         , "cannot read tiff_tile_width tag." );
90             io_error_if( !_io_dev.template get_property< tiff_tile_length >( _info._tile_length )
91                         , "cannot read tiff_tile_length tag." );
92         }
93 
94         io_error_if( _io_dev.template get_property<tiff_resolution_unit>( _info._resolution_unit) == false
95           , "cannot read tiff tag");
96         io_error_if( _io_dev. template get_property<tiff_x_resolution>( _info._x_resolution ) == false
97           , "cannot read tiff tag" );
98         io_error_if( _io_dev. template get_property<tiff_y_resolution>( _info._y_resolution ) == false
99           , "cannot read tiff tag" );
100 
101         /// optional and non-baseline properties below here
102         _io_dev. template get_property <tiff_icc_profile> ( _info._icc_profile );
103     }
104 
105     /// Check if image is large enough.
check_image_sizeboost::gil::reader_backend106     void check_image_size( const point_t& img_dim )
107     {
108         if( _settings._dim.x > 0 )
109         {
110             if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
111         }
112         else
113         {
114             if( (tiff_image_width::type) img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
115         }
116 
117 
118         if( _settings._dim.y > 0 )
119         {
120             if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
121         }
122         else
123         {
124             if( (tiff_image_height::type) img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
125         }
126     }
127 
128 private:
129 
init_multipage_readboost::gil::reader_backend130     void init_multipage_read( const image_read_settings< tiff_tag >& settings )
131     {
132         if( settings._directory > 0 )
133         {
134             _io_dev.set_directory( settings._directory );
135         }
136     }
137 
138 public:
139 
140     Device _io_dev;
141 
142     image_read_settings< tiff_tag > _settings;
143     image_read_info< tiff_tag >     _info;
144 
145     std::size_t _scanline_length;
146 
147     // palette
148     tiff_color_map::red_t   _red;
149     tiff_color_map::green_t _green;
150     tiff_color_map::blue_t  _blue;
151 
152     rgb16_planar_view_t _palette;
153 };
154 
155 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
156 #pragma warning(pop)
157 #endif
158 
159 } // namespace gil
160 } // namespace boost
161 
162 #endif
163