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