Boost logo

Boost :

Subject: Re: [boost] [GIL] [patch] read multipage TIFF files
From: Christian Henning (chhenning_at_[hidden])
Date: 2010-07-16 10:23:22


Hi Robert, thanks for your submission. I gladly will update the code
after some testing, of course. Could you send me your tiff_io.hpp. I
have no idea how to apply a patch file on Windows. Unless someone can
explain that to me.

Do you have some sort of test suite with multi-page tiff files?

I think I could even use this code in my gil::io rewrite. I have to
check but of the top of my head multi-page cannot be read right now.

Thanks again,
Christian

On Fri, Jul 16, 2010 at 4:12 AM, Robert Pollak <robert.pollak_at_[hidden]> wrote:
> Hello,
>
> the following patch (against the current trunk) allows to read any page
> of a multipage TIFF file, by optionally specifying the zero-based
> directory number.  (The correct term for a TIFF page is "directory".)
>
>
> It adds a "dirnum" to the relevant functions, and uses the
> corresponding libtiff functionality.  The "dirnum" default value is 0
> for compatibility with present callers.
>
> Additionally, it defines the function tiff_get_directory_count to get
> the number of directories in the TIFF file.
>
>
> Please give me some feedback or consider applying the patch.
>
>
> This patch would close the corresponding feature request
> https://svn.boost.org/trac/boost/ticket/2373 .
>
> Credits go to Roland Richter, whose code the patch is based on.
>
> Best Regards,
> Robert Pollak
>
>
>
> Index: boost/gil/extension/io/tiff_io.hpp
> ===================================================================
> --- boost/gil/extension/io/tiff_io.hpp  (revision 64065)
> +++ boost/gil/extension/io/tiff_io.hpp  (working copy)
> @@ -122,9 +122,13 @@
>  protected:
>     TIFF *_tp;
>  public:
> -    tiff_reader(const char* filename) {
> +    tiff_reader(const char* filename,tdir_t dirnum=0) {
>         io_error_if((_tp=TIFFOpen(filename,"r"))==NULL,
>                     "tiff_reader: fail to open file");
> +        if(dirnum>0) {
> +            io_error_if(TIFFSetDirectory(_tp,dirnum)!=1,
> +                        "tiff_reader: fail to set directory");
> +        }
>     }
>     ~tiff_reader() { TIFFClose(_tp); }
>     template <typename View>
> @@ -171,10 +175,10 @@
>  private:
>     CC _cc;
>  public:
> -    tiff_reader_color_convert(const char* filename) :
> -        tiff_reader(filename) {}
> -    tiff_reader_color_convert(const char* filename,CC cc_in) :
> -        tiff_reader(filename),_cc(cc_in) {}
> +    tiff_reader_color_convert(const char* filename,tdir_t dirnum=0) :
> +        tiff_reader(filename,dirnum) {}
> +    tiff_reader_color_convert(const char* filename,CC cc_in,tdir_t dirnum=0) :
> +        tiff_reader(filename,dirnum),_cc(cc_in) {}
>     template <typename View>
>     void apply(const View& view) {
>         point2<std::ptrdiff_t> dims=get_dimensions();
> @@ -336,18 +340,34 @@
>  };
>
>  /// \ingroup TIFF_IO
> +/// \brief Returns the number of directories in the TIFF file
> +inline int tiff_get_directory_count(const char* filename) {
> +    TIFF *tif;
> +    io_error_if((tif=TIFFOpen(filename,"r"))==NULL,
> +                    "tiff_get_count: fail to open file");
> +
> +    int dircount = 0;
> +    do {
> +        dircount++;
> +    } while (TIFFReadDirectory(tif));
> +
> +    TIFFClose(tif);
> +    return dircount;
> +}
> +
> +/// \ingroup TIFF_IO
>  /// \brief Returns the width and height of the TIFF file at the specified location.
>  /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
> -inline point2<std::ptrdiff_t> tiff_read_dimensions(const char* filename) {
> -    detail::tiff_reader m(filename);
> +inline point2<std::ptrdiff_t> tiff_read_dimensions(const char* filename,tdir_t dirnum=0) {
> +    detail::tiff_reader m(filename,dirnum);
>     return m.get_dimensions();
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Returns the width and height of the TIFF file at the specified location.
>  /// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
> -inline point2<std::ptrdiff_t> tiff_read_dimensions(const std::string& filename) {
> -    return tiff_read_dimensions(filename.c_str());
> +inline point2<std::ptrdiff_t> tiff_read_dimensions(const std::string& filename,tdir_t dirnum=0) {
> +    return tiff_read_dimensions(filename.c_str(),dirnum);
>  }
>
>  /// \ingroup TIFF_IO
> @@ -356,17 +376,17 @@
>  /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
>  /// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
>  template <typename View>
> -inline void tiff_read_view(const char* filename,const View& view) {
> +inline void tiff_read_view(const char* filename,const View& view,tdir_t dirnum=0) {
>     BOOST_STATIC_ASSERT(tiff_read_support<View>::is_supported);
> -    detail::tiff_reader m(filename);
> +    detail::tiff_reader m(filename,dirnum);
>     m.apply(view);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Loads the image specified by the given tiff image file name into the given view.
>  template <typename View>
> -inline void tiff_read_view(const std::string& filename,const View& view) {
> -    tiff_read_view(filename.c_str(),view);
> +inline void tiff_read_view(const std::string& filename,const View& view,tdir_t dirnum=0) {
> +    tiff_read_view(filename.c_str(),view,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
> @@ -375,25 +395,25 @@
>  /// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
>  /// compatible with the ones specified by Image
>  template <typename Image>
> -void tiff_read_image(const char* filename,Image& im) {
> +void tiff_read_image(const char* filename,Image& im,tdir_t dirnum=0) {
>     BOOST_STATIC_ASSERT(tiff_read_support<typename Image::view_t>::is_supported);
> -    detail::tiff_reader m(filename);
> +    detail::tiff_reader m(filename,dirnum);
>     m.read_image(im);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
>  template <typename Image>
> -inline void tiff_read_image(const std::string& filename,Image& im) {
> -    tiff_read_image(filename.c_str(),im);
> +inline void tiff_read_image(const std::string& filename,Image& im,tdir_t dirnum=0) {
> +    tiff_read_image(filename.c_str(),im,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
>  /// 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.
>  template <typename View,typename CC>
> -inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc) {
> -    detail::tiff_reader_color_convert<CC> m(filename,cc);
> +inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc,tdir_t dirnum=0) {
> +    detail::tiff_reader_color_convert<CC> m(filename,cc,dirnum);
>     m.apply(view);
>  }
>
> @@ -401,31 +421,31 @@
>  /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
>  /// 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.
>  template <typename View>
> -inline void tiff_read_and_convert_view(const char* filename,const View& view) {
> -    detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
> +inline void tiff_read_and_convert_view(const char* filename,const View& view,tdir_t dirnum=0) {
> +    detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter(),dirnum);
>     m.apply(view);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
>  template <typename View,typename CC>
> -inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
> -    tiff_read_and_convert_view(filename.c_str(),view,cc);
> +inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc,tdir_t dirnum=0) {
> +    tiff_read_and_convert_view(filename.c_str(),view,cc,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
>  template <typename View>
> -inline void tiff_read_and_convert_view(const std::string& filename,const View& view) {
> -    tiff_read_and_convert_view(filename.c_str(),view);
> +inline void tiff_read_and_convert_view(const std::string& filename,const View& view,tdir_t dirnum=0) {
> +    tiff_read_and_convert_view(filename.c_str(),view,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
>  /// Throws std::ios_base::failure if the file is not a valid TIFF file
>  template <typename Image,typename CC>
> -void tiff_read_and_convert_image(const char* filename,Image& im,CC cc) {
> -    detail::tiff_reader_color_convert<CC> m(filename,cc);
> +void tiff_read_and_convert_image(const char* filename,Image& im,CC cc,tdir_t dirnum=0) {
> +    detail::tiff_reader_color_convert<CC> m(filename,cc,dirnum);
>     m.read_image(im);
>  }
>
> @@ -433,23 +453,23 @@
>  /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
>  /// Throws std::ios_base::failure if the file is not a valid TIFF file
>  template <typename Image>
> -void tiff_read_and_convert_image(const char* filename,Image& im) {
> -    detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
> +void tiff_read_and_convert_image(const char* filename,Image& im,tdir_t dirnum=0) {
> +    detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter(),dirnum);
>     m.read_image(im);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
>  template <typename Image,typename CC>
> -inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
> -    tiff_read_and_convert_image(filename.c_str(),im,cc);
> +inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc,tdir_t dirnum=0) {
> +    tiff_read_and_convert_image(filename.c_str(),im,cc,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
>  /// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
>  template <typename Image>
> -inline void tiff_read_and_convert_image(const std::string& filename,Image& im) {
> -    tiff_read_and_convert_image(filename.c_str(),im);
> +inline void tiff_read_and_convert_image(const std::string& filename,Image& im,tdir_t dirnum=0) {
> +    tiff_read_and_convert_image(filename.c_str(),im,dirnum);
>  }
>
>  /// \ingroup TIFF_IO
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk