Chris@16: /* Chris@16: Copyright 2005-2007 Adobe Systems Incorporated Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: See http://opensource.adobe.com/gil for most recent version including documentation. Chris@16: */ Chris@16: Chris@16: /*************************************************************************************************/ Chris@16: Chris@16: #ifndef GIL_TIFF_IO_H Chris@16: #define GIL_TIFF_IO_H Chris@16: Chris@16: /// \file Chris@16: /// \brief Support for reading and writing TIFF files Chris@16: /// Requires libtiff! Chris@16: /// \author Hailin Jin and Lubomir Bourdev \n Chris@16: /// Adobe Systems Incorporated Chris@16: /// \date 2005-2007 \n Last updated September 24, 2006 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include "../../gil_all.hpp" Chris@16: #include "io_error.hpp" Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=false); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=0); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=0); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=8); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=8); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=16); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=16); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=32); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_read_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=32); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=false); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=0); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=0); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=8); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=8); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=16); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=16); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=32); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK); Chris@16: }; Chris@16: template <> Chris@16: struct tiff_write_support_private { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported=true); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth=32); Chris@16: BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB); Chris@16: }; Chris@16: Chris@16: class tiff_reader { Chris@16: protected: Chris@16: TIFF *_tp; Chris@16: public: Chris@16: tiff_reader(const char* filename,tdir_t dirnum=0) { Chris@16: io_error_if((_tp=TIFFOpen(filename,"r"))==NULL, Chris@16: "tiff_reader: fail to open file"); Chris@16: if(dirnum>0) { Chris@16: io_error_if(TIFFSetDirectory(_tp,dirnum)!=1, Chris@16: "tiff_reader: fail to set directory"); Chris@16: } Chris@16: } Chris@16: ~tiff_reader() { TIFFClose(_tp); } Chris@16: template Chris@16: void apply(const View& view) { Chris@16: unsigned short bps,photometric; Chris@16: point2 dims=get_dimensions(); Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1); Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1); Chris@16: io_error_if(dims!=view.dimensions(), Chris@16: "tiff_read_view: input view size does not match TIFF file size"); Chris@16: io_error_if(tiff_read_support_private::type, Chris@16: typename color_space_type::type>::bit_depth!=bps || Chris@16: tiff_read_support_private::type, Chris@16: typename color_space_type::type>::color_type!=photometric, Chris@16: "tiff_read_view: input view type is incompatible with the image type"); Chris@16: std::size_t element_size=sizeof(pixel::type, Chris@16: layout::type> >); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector::type, Chris@16: layout::type> > > row(size_to_allocate); Chris@16: for (int y=0;y get_dimensions() { Chris@16: int w,h; Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH, &w)!=1); Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&h)!=1); Chris@16: return point2(w,h); Chris@16: } Chris@16: Chris@16: template Chris@16: void read_image(Image& im) { Chris@16: im.recreate(get_dimensions()); Chris@16: apply(view(im)); Chris@16: } Chris@16: }; Chris@16: Chris@16: // This code will be simplified... Chris@16: template Chris@16: class tiff_reader_color_convert : public tiff_reader { Chris@16: private: Chris@16: CC _cc; Chris@16: public: Chris@16: tiff_reader_color_convert(const char* filename,tdir_t dirnum=0) : Chris@16: tiff_reader(filename,dirnum) {} Chris@16: tiff_reader_color_convert(const char* filename,CC cc_in,tdir_t dirnum=0) : Chris@16: tiff_reader(filename,dirnum),_cc(cc_in) {} Chris@16: template Chris@16: void apply(const View& view) { Chris@16: point2 dims=get_dimensions(); Chris@16: unsigned short bps,photometric; Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1); Chris@16: io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1); Chris@16: io_error_if(dims!=view.dimensions(), Chris@16: "tiff_reader_color_convert::apply(): input view size does not match TIFF file size"); Chris@16: switch (photometric) { Chris@16: case PHOTOMETRIC_MINISBLACK: { Chris@16: switch (bps) { Chris@16: case 8: { Chris@16: std::size_t element_size=sizeof(gray8_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: case 16: { Chris@16: std::size_t element_size=sizeof(gray16_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: case 32: { Chris@16: std::size_t element_size=sizeof(gray32f_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: default: Chris@16: io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth"); Chris@16: } Chris@16: break; Chris@16: } Chris@16: case PHOTOMETRIC_RGB: { Chris@16: switch (bps) { Chris@16: case 8: { Chris@16: std::size_t element_size=sizeof(rgb8_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: case 16: { Chris@16: std::size_t element_size=sizeof(rgb16_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: case 32: { Chris@16: std::size_t element_size=sizeof(rgb32f_pixel_t); Chris@16: std::size_t size_to_allocate = (std::max)((std::size_t)view.width(), Chris@16: (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size); Chris@16: std::vector row(size_to_allocate); Chris@16: for (int y=0;y(_cc)); Chris@16: } Chris@16: break; Chris@16: } Chris@16: default: Chris@16: io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth"); Chris@16: } Chris@16: break; Chris@16: } Chris@16: default: { Chris@16: // reads an image in incompatible format via TIFFReadRGBAImage Chris@16: rgba8_image_t rgbaImg(dims); Chris@16: io_error_if(!TIFFReadRGBAImage(_tp, dims.x, dims.y, (uint32*)&gil::view(rgbaImg)(0,0), 0), Chris@16: "tiff_reader_color_convert::unsupported image format"); Chris@16: copy_and_convert_pixels(flipped_up_down_view(const_view(rgbaImg)), view, _cc); Chris@16: } Chris@16: } Chris@16: } Chris@16: template Chris@16: void read_image(Image& im) { Chris@16: im.recreate(get_dimensions()); Chris@16: apply(view(im)); Chris@16: } Chris@16: }; Chris@16: Chris@16: class tiff_writer { Chris@16: protected: Chris@16: TIFF* _tp; Chris@16: public: Chris@16: tiff_writer(const char *filename) { Chris@16: io_error_if((_tp=TIFFOpen(filename,"w"))==NULL, Chris@16: "tiff_writer: fail to open file"); Chris@16: } Chris@16: ~tiff_writer() {TIFFClose(_tp);} Chris@16: template Chris@16: void apply(const View& view) { Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGELENGTH, view.height())!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGEWIDTH, view.width())!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_PHOTOMETRIC, tiff_write_support_private::type, Chris@16: typename color_space_type::type>::color_type)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_SAMPLESPERPIXEL,num_channels::value)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private::type, Chris@16: typename color_space_type::type>::bit_depth)!=1); Chris@16: io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1); Chris@16: std::vector::type, Chris@16: layout::type> > > row(view.width()); Chris@16: for (int y=0;y Chris@16: struct tiff_read_support { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported= Chris@16: (detail::tiff_read_support_private::type, Chris@16: typename color_space_type::type>::is_supported)); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth= Chris@16: (detail::tiff_read_support_private::type, Chris@16: typename color_space_type::type>::bit_depth)); Chris@16: BOOST_STATIC_CONSTANT(int,color_type= Chris@16: (detail::tiff_read_support_private::type, Chris@16: typename color_space_type::type>::color_type)); Chris@16: }; Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Returns the number of directories in the TIFF file Chris@16: inline int tiff_get_directory_count(const char* filename) { Chris@16: TIFF *tif; Chris@16: io_error_if((tif=TIFFOpen(filename,"r"))==NULL, Chris@16: "tiff_get_count: fail to open file"); Chris@16: Chris@16: int dircount = 0; Chris@16: do { Chris@16: dircount++; Chris@16: } while (TIFFReadDirectory(tif)); Chris@16: Chris@16: TIFFClose(tif); Chris@16: return dircount; Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Returns the width and height of the TIFF file at the specified location. Chris@16: /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file Chris@16: inline point2 tiff_read_dimensions(const char* filename,tdir_t dirnum=0) { Chris@16: detail::tiff_reader m(filename,dirnum); Chris@16: return m.get_dimensions(); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Returns the width and height of the TIFF file at the specified location. Chris@16: /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file Chris@16: inline point2 tiff_read_dimensions(const std::string& filename,tdir_t dirnum=0) { Chris@16: return tiff_read_dimensions(filename.c_str(),dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads the image specified by the given tiff image file name into the given view. Chris@16: /// 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: /// 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: /// compatible with the ones specified by View, or if its dimensions don't match the ones of the view. Chris@16: template Chris@16: inline void tiff_read_view(const char* filename,const View& view,tdir_t dirnum=0) { Chris@16: BOOST_STATIC_ASSERT(tiff_read_support::is_supported); Chris@16: detail::tiff_reader m(filename,dirnum); Chris@16: m.apply(view); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads the image specified by the given tiff image file name into the given view. Chris@16: template Chris@16: inline void tiff_read_view(const std::string& filename,const View& view,tdir_t dirnum=0) { Chris@16: tiff_read_view(filename.c_str(),view,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it. Chris@16: /// 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: /// 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: /// compatible with the ones specified by Image Chris@16: template Chris@16: void tiff_read_image(const char* filename,Image& im,tdir_t dirnum=0) { Chris@16: BOOST_STATIC_ASSERT(tiff_read_support::is_supported); Chris@16: detail::tiff_reader m(filename,dirnum); Chris@16: m.read_image(im); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it. Chris@16: template Chris@16: inline void tiff_read_image(const std::string& filename,Image& im,tdir_t dirnum=0) { Chris@16: tiff_read_image(filename.c_str(),im,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. Chris@16: /// 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: template Chris@16: inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc,tdir_t dirnum=0) { Chris@16: detail::tiff_reader_color_convert m(filename,cc,dirnum); Chris@16: m.apply(view); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. Chris@16: /// 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: template Chris@16: inline void tiff_read_and_convert_view(const char* filename,const View& view,tdir_t dirnum=0) { Chris@16: detail::tiff_reader_color_convert m(filename,default_color_converter(),dirnum); Chris@16: m.apply(view); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. Chris@16: template Chris@16: inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc,tdir_t dirnum=0) { Chris@16: tiff_read_and_convert_view(filename.c_str(),view,cc,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view. Chris@16: template Chris@16: inline void tiff_read_and_convert_view(const std::string& filename,const View& view,tdir_t dirnum=0) { Chris@16: tiff_read_and_convert_view(filename.c_str(),view,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \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: /// Throws std::ios_base::failure if the file is not a valid TIFF file Chris@16: template Chris@16: void tiff_read_and_convert_image(const char* filename,Image& im,CC cc,tdir_t dirnum=0) { Chris@16: detail::tiff_reader_color_convert m(filename,cc,dirnum); Chris@16: m.read_image(im); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \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: /// Throws std::ios_base::failure if the file is not a valid TIFF file Chris@16: template Chris@16: void tiff_read_and_convert_image(const char* filename,Image& im,tdir_t dirnum=0) { Chris@16: detail::tiff_reader_color_convert m(filename,default_color_converter(),dirnum); Chris@16: m.read_image(im); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \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: template Chris@16: inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc,tdir_t dirnum=0) { Chris@16: tiff_read_and_convert_image(filename.c_str(),im,cc,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \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: template Chris@16: inline void tiff_read_and_convert_image(const std::string& filename,Image& im,tdir_t dirnum=0) { Chris@16: tiff_read_and_convert_image(filename.c_str(),im,dirnum); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Determines whether the given view type is supported for writing Chris@16: template Chris@16: struct tiff_write_support { Chris@16: BOOST_STATIC_CONSTANT(bool,is_supported= Chris@16: (detail::tiff_write_support_private::type, Chris@16: typename color_space_type::type>::is_supported)); Chris@16: BOOST_STATIC_CONSTANT(int,bit_depth= Chris@16: (detail::tiff_write_support_private::type, Chris@16: typename color_space_type::type>::bit_depth)); Chris@16: BOOST_STATIC_CONSTANT(int,color_type= Chris@16: (detail::tiff_write_support_private::type, Chris@16: typename color_space_type::type>::color_type)); Chris@16: BOOST_STATIC_CONSTANT(bool, value=is_supported); Chris@16: }; Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Saves the view to a tiff file specified by the given tiff image file name. Chris@16: /// 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: /// Throws std::ios_base::failure if it fails to create the file. Chris@16: template Chris@16: inline void tiff_write_view(const char* filename,const View& view) { Chris@16: BOOST_STATIC_ASSERT(tiff_write_support::is_supported); Chris@16: detail::tiff_writer m(filename); Chris@16: m.apply(view); Chris@16: } Chris@16: Chris@16: /// \ingroup TIFF_IO Chris@16: /// \brief Saves the view to a tiff file specified by the given tiff image file name. Chris@16: template Chris@16: inline void tiff_write_view(const std::string& filename,const View& view) { Chris@16: tiff_write_view(filename.c_str(),view); Chris@16: } Chris@16: Chris@16: } } // namespace boost::gil Chris@16: Chris@16: #endif