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