add boost on mac
This commit is contained in:
479
macx64/include/boost/gil/extension/io/tiff/detail/device.hpp
Normal file
479
macx64/include/boost/gil/extension/io/tiff/detail/device.hpp
Normal file
@@ -0,0 +1,479 @@
|
||||
//
|
||||
// Copyright 2007-2008 Andreas Pokorny, Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_DEVICE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_DEVICE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/log.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
// taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <tiffio.hxx>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template <int n_args>
|
||||
struct get_property_f {
|
||||
template <typename Property>
|
||||
bool call_me(typename Property:: type& value, std::shared_ptr<TIFF>& file);
|
||||
};
|
||||
|
||||
template <int n_args>
|
||||
struct set_property_f {
|
||||
template <typename Property>
|
||||
bool call_me(const typename Property:: type& value, std::shared_ptr<TIFF>& file) const;
|
||||
};
|
||||
|
||||
template <> struct get_property_f <1>
|
||||
{
|
||||
// For single-valued properties
|
||||
template <typename Property>
|
||||
bool call_me(typename Property::type & value, std::shared_ptr<TIFF>& file) const
|
||||
{
|
||||
// @todo: defaulted, really?
|
||||
return (1 == TIFFGetFieldDefaulted( file.get()
|
||||
, Property:: tag
|
||||
, & value));
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct get_property_f <2>
|
||||
{
|
||||
// Specialisation for multi-valued properties. @todo: add one of
|
||||
// these for the three-parameter fields too.
|
||||
template <typename Property>
|
||||
bool call_me(typename Property:: type & vs, std::shared_ptr<TIFF>& file) const
|
||||
{
|
||||
typename mpl:: at <typename Property:: arg_types, mpl::int_<0> >:: type length;
|
||||
typename mpl:: at <typename Property:: arg_types, mpl::int_<1> >:: type pointer;
|
||||
if (1 == TIFFGetFieldDefaulted( file.get()
|
||||
, Property:: tag
|
||||
, & length
|
||||
, & pointer)) {
|
||||
std:: copy_n (static_cast <typename Property:: type:: const_pointer> (pointer), length, std:: back_inserter (vs));
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct set_property_f <1>
|
||||
{
|
||||
// For single-valued properties
|
||||
template <typename Property>
|
||||
inline
|
||||
bool call_me(typename Property:: type const & value, std::shared_ptr<TIFF>& file) const
|
||||
{
|
||||
return (1 == TIFFSetField( file.get()
|
||||
, Property:: tag
|
||||
, value));
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct set_property_f <2>
|
||||
{
|
||||
// Specialisation for multi-valued properties. @todo: add one
|
||||
// of these for the three-parameter fields too. Actually we
|
||||
// will need further templation / specialisation for the
|
||||
// two-element fields which aren't a length and a data buffer
|
||||
// (e.g. http://www.awaresystems.be/imaging/tiff/tifftags/dotrange.html
|
||||
// )
|
||||
template <typename Property>
|
||||
inline
|
||||
bool call_me(typename Property:: type const & values, std::shared_ptr<TIFF>& file) const
|
||||
{
|
||||
typename mpl:: at <typename Property:: arg_types, mpl::int_<0> >:: type const length = values. size ();
|
||||
typename mpl:: at <typename Property:: arg_types, mpl::int_<1> >:: type const pointer = & (values. front ());
|
||||
return (1 == TIFFSetField( file.get()
|
||||
, Property:: tag
|
||||
, length
|
||||
, pointer));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Log >
|
||||
class tiff_device_base
|
||||
{
|
||||
public:
|
||||
using tiff_file_t = std::shared_ptr<TIFF>;
|
||||
|
||||
tiff_device_base()
|
||||
{}
|
||||
|
||||
tiff_device_base( TIFF* tiff_file )
|
||||
: _tiff_file( tiff_file
|
||||
, TIFFClose )
|
||||
{}
|
||||
|
||||
template <typename Property>
|
||||
bool get_property( typename Property::type& value )
|
||||
{
|
||||
return get_property_f <mpl:: size <typename Property:: arg_types>::value > ().template call_me<Property>(value, _tiff_file);
|
||||
}
|
||||
|
||||
template <typename Property>
|
||||
inline
|
||||
bool set_property( const typename Property::type& value )
|
||||
{
|
||||
// http://www.remotesensing.org/libtiff/man/TIFFSetField.3tiff.html
|
||||
return set_property_f <mpl:: size <typename Property:: arg_types>::value > ().template call_me<Property> (value, _tiff_file);
|
||||
}
|
||||
|
||||
// TIFFIsByteSwapped returns a non-zero value if the image data was in a different
|
||||
// byte-order than the host machine. Zero is returned if the TIFF file and local
|
||||
// host byte-orders are the same. Note that TIFFReadTile(), TIFFReadStrip() and TIFFReadScanline()
|
||||
// functions already normally perform byte swapping to local host order if needed.
|
||||
bool are_bytes_swapped()
|
||||
{
|
||||
return ( TIFFIsByteSwapped( _tiff_file.get() )) ? true : false;
|
||||
}
|
||||
|
||||
bool is_tiled() const
|
||||
{
|
||||
return ( TIFFIsTiled( _tiff_file.get() )) ? true : false;
|
||||
}
|
||||
|
||||
unsigned int get_default_strip_size()
|
||||
{
|
||||
return TIFFDefaultStripSize( _tiff_file.get()
|
||||
, 0 );
|
||||
}
|
||||
|
||||
std::size_t get_scanline_size()
|
||||
{
|
||||
return TIFFScanlineSize( _tiff_file.get() );
|
||||
}
|
||||
|
||||
std::size_t get_tile_size()
|
||||
{
|
||||
return TIFFTileSize( _tiff_file.get() );
|
||||
}
|
||||
|
||||
|
||||
int get_field_defaulted( uint16_t*& red
|
||||
, uint16_t*& green
|
||||
, uint16_t*& blue
|
||||
)
|
||||
{
|
||||
return TIFFGetFieldDefaulted( _tiff_file.get()
|
||||
, TIFFTAG_COLORMAP
|
||||
, &red
|
||||
, &green
|
||||
, &blue
|
||||
);
|
||||
}
|
||||
|
||||
template< typename Buffer >
|
||||
void read_scanline( Buffer& buffer
|
||||
, std::ptrdiff_t row
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
io_error_if( TIFFReadScanline( _tiff_file.get()
|
||||
, reinterpret_cast< tdata_t >( &buffer.front() )
|
||||
, (uint32) row
|
||||
, plane ) == -1
|
||||
, "Read error."
|
||||
);
|
||||
}
|
||||
|
||||
void read_scanline( byte_t* buffer
|
||||
, std::ptrdiff_t row
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
io_error_if( TIFFReadScanline( _tiff_file.get()
|
||||
, reinterpret_cast< tdata_t >( buffer )
|
||||
, (uint32) row
|
||||
, plane ) == -1
|
||||
, "Read error."
|
||||
);
|
||||
}
|
||||
|
||||
template< typename Buffer >
|
||||
void read_tile( Buffer& buffer
|
||||
, std::ptrdiff_t x
|
||||
, std::ptrdiff_t y
|
||||
, std::ptrdiff_t z
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
if( TIFFReadTile( _tiff_file.get()
|
||||
, reinterpret_cast< tdata_t >( &buffer.front() )
|
||||
, (uint32) x
|
||||
, (uint32) y
|
||||
, (uint32) z
|
||||
, plane
|
||||
) == -1 )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Read tile error (" << x << "," << y << "," << z << "," << plane << ").";
|
||||
io_error(oss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Buffer >
|
||||
void write_scaline( Buffer& buffer
|
||||
, uint32 row
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
io_error_if( TIFFWriteScanline( _tiff_file.get()
|
||||
, &buffer.front()
|
||||
, row
|
||||
, plane
|
||||
) == -1
|
||||
, "Write error"
|
||||
);
|
||||
}
|
||||
|
||||
void write_scaline( byte_t* buffer
|
||||
, uint32 row
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
io_error_if( TIFFWriteScanline( _tiff_file.get()
|
||||
, buffer
|
||||
, row
|
||||
, plane
|
||||
) == -1
|
||||
, "Write error"
|
||||
);
|
||||
}
|
||||
|
||||
template< typename Buffer >
|
||||
void write_tile( Buffer& buffer
|
||||
, uint32 x
|
||||
, uint32 y
|
||||
, uint32 z
|
||||
, tsample_t plane
|
||||
)
|
||||
{
|
||||
if( TIFFWriteTile( _tiff_file.get()
|
||||
, &buffer.front()
|
||||
, x
|
||||
, y
|
||||
, z
|
||||
, plane
|
||||
) == -1 )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Write tile error (" << x << "," << y << "," << z << "," << plane << ").";
|
||||
io_error(oss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void set_directory( tdir_t directory )
|
||||
{
|
||||
io_error_if( TIFFSetDirectory( _tiff_file.get()
|
||||
, directory
|
||||
) != 1
|
||||
, "Failing to set directory"
|
||||
);
|
||||
}
|
||||
|
||||
// return false if the given tile width or height is not TIFF compliant (multiple of 16) or larger than image size, true otherwise
|
||||
bool check_tile_size( tiff_tile_width::type& width
|
||||
, tiff_tile_length::type& height
|
||||
|
||||
)
|
||||
{
|
||||
bool result = true;
|
||||
uint32 tw = static_cast< uint32 >( width );
|
||||
uint32 th = static_cast< uint32 >( height );
|
||||
|
||||
TIFFDefaultTileSize( _tiff_file.get()
|
||||
, &tw
|
||||
, &th
|
||||
);
|
||||
|
||||
if(width==0 || width%16!=0)
|
||||
{
|
||||
width = tw;
|
||||
result = false;
|
||||
}
|
||||
if(height==0 || height%16!=0)
|
||||
{
|
||||
height = th;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
tiff_file_t _tiff_file;
|
||||
|
||||
Log _log;
|
||||
};
|
||||
|
||||
/*!
|
||||
*
|
||||
* file_stream_device specialization for tiff images, which are based on TIFF*.
|
||||
*/
|
||||
template<>
|
||||
class file_stream_device< tiff_tag > : public tiff_device_base< tiff_no_log >
|
||||
{
|
||||
public:
|
||||
|
||||
struct read_tag {};
|
||||
struct write_tag {};
|
||||
|
||||
file_stream_device( std::string const& file_name, read_tag )
|
||||
{
|
||||
TIFF* tiff;
|
||||
|
||||
io_error_if( ( tiff = TIFFOpen( file_name.c_str(), "r" )) == nullptr
|
||||
, "file_stream_device: failed to open file" );
|
||||
|
||||
_tiff_file = tiff_file_t( tiff, TIFFClose );
|
||||
}
|
||||
|
||||
file_stream_device( std::string const& file_name, write_tag )
|
||||
{
|
||||
TIFF* tiff;
|
||||
|
||||
io_error_if( ( tiff = TIFFOpen( file_name.c_str(), "w" )) == nullptr
|
||||
, "file_stream_device: failed to open file" );
|
||||
|
||||
_tiff_file = tiff_file_t( tiff, TIFFClose );
|
||||
}
|
||||
|
||||
file_stream_device( TIFF* tiff_file )
|
||||
: tiff_device_base( tiff_file )
|
||||
{}
|
||||
};
|
||||
|
||||
/*!
|
||||
*
|
||||
* ostream_device specialization for tiff images.
|
||||
*/
|
||||
template<>
|
||||
class ostream_device< tiff_tag > : public tiff_device_base< tiff_no_log >
|
||||
{
|
||||
public:
|
||||
ostream_device( std::ostream & out )
|
||||
: _out( out )
|
||||
{
|
||||
TIFF* tiff;
|
||||
|
||||
io_error_if( ( tiff = TIFFStreamOpen( ""
|
||||
, &_out
|
||||
)
|
||||
) == nullptr
|
||||
, "ostream_device: failed to stream"
|
||||
);
|
||||
|
||||
_tiff_file = tiff_file_t( tiff, TIFFClose );
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_device& operator=( const ostream_device& ) { return *this; }
|
||||
|
||||
private:
|
||||
|
||||
std::ostream& _out;
|
||||
};
|
||||
|
||||
/*!
|
||||
*
|
||||
* ostream_device specialization for tiff images.
|
||||
*/
|
||||
template<>
|
||||
class istream_device< tiff_tag > : public tiff_device_base< tiff_no_log >
|
||||
{
|
||||
public:
|
||||
istream_device( std::istream & in )
|
||||
: _in( in )
|
||||
{
|
||||
TIFF* tiff;
|
||||
|
||||
io_error_if( ( tiff = TIFFStreamOpen( ""
|
||||
, &_in
|
||||
)
|
||||
) == nullptr
|
||||
, "istream_device: failed to stream"
|
||||
);
|
||||
|
||||
_tiff_file = tiff_file_t( tiff, TIFFClose );
|
||||
}
|
||||
|
||||
private:
|
||||
istream_device& operator=( const istream_device& ) { return *this; }
|
||||
|
||||
private:
|
||||
|
||||
std::istream& _in;
|
||||
};
|
||||
|
||||
/*
|
||||
template< typename T, typename D >
|
||||
struct is_adaptable_input_device< tiff_tag, T, D > : mpl::false_{};
|
||||
*/
|
||||
|
||||
template< typename FormatTag >
|
||||
struct is_adaptable_input_device< FormatTag
|
||||
, TIFF*
|
||||
, void
|
||||
>
|
||||
: mpl::true_
|
||||
{
|
||||
using device_type = file_stream_device<FormatTag>;
|
||||
};
|
||||
|
||||
template< typename FormatTag >
|
||||
struct is_adaptable_output_device< FormatTag
|
||||
, TIFF*
|
||||
, void
|
||||
>
|
||||
: mpl::true_
|
||||
{
|
||||
using device_type = file_stream_device<FormatTag>;
|
||||
};
|
||||
|
||||
|
||||
template < typename Channel > struct sample_format : public mpl::int_<SAMPLEFORMAT_UINT> {};
|
||||
template<> struct sample_format<uint8_t> : public mpl::int_<SAMPLEFORMAT_UINT> {};
|
||||
template<> struct sample_format<uint16_t> : public mpl::int_<SAMPLEFORMAT_UINT> {};
|
||||
template<> struct sample_format<uint32_t> : public mpl::int_<SAMPLEFORMAT_UINT> {};
|
||||
template<> struct sample_format<float32_t> : public mpl::int_<SAMPLEFORMAT_IEEEFP> {};
|
||||
template<> struct sample_format<double> : public mpl::int_<SAMPLEFORMAT_IEEEFP> {};
|
||||
template<> struct sample_format<int8_t> : public mpl::int_<SAMPLEFORMAT_INT> {};
|
||||
template<> struct sample_format<int16_t> : public mpl::int_<SAMPLEFORMAT_INT> {};
|
||||
template<> struct sample_format<int32_t> : public mpl::int_<SAMPLEFORMAT_INT> {};
|
||||
|
||||
template <typename Channel> struct photometric_interpretation {};
|
||||
template<> struct photometric_interpretation< gray_t > : public mpl::int_< PHOTOMETRIC_MINISBLACK > {};
|
||||
template<> struct photometric_interpretation< rgb_t > : public mpl::int_< PHOTOMETRIC_RGB > {};
|
||||
template<> struct photometric_interpretation< rgba_t > : public mpl::int_< PHOTOMETRIC_RGB > {};
|
||||
template<> struct photometric_interpretation< cmyk_t > : public mpl::int_< PHOTOMETRIC_SEPARATED > {};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
256
macx64/include/boost/gil/extension/io/tiff/detail/is_allowed.hpp
Normal file
256
macx64/include/boost/gil/extension/io/tiff/detail/is_allowed.hpp
Normal file
@@ -0,0 +1,256 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
using channel_sizes_t = std::vector<tiff_bits_per_sample::type>;
|
||||
|
||||
template <typename View, typename Channel, typename Enable = void>
|
||||
struct Format_Type {};
|
||||
|
||||
// is_bit_aligned< View >
|
||||
template <typename View, typename Channel>
|
||||
struct Format_Type
|
||||
<
|
||||
View,
|
||||
Channel,
|
||||
typename std::enable_if
|
||||
<
|
||||
is_bit_aligned
|
||||
<
|
||||
typename get_pixel_type<View>::type
|
||||
>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static const int value = SAMPLEFORMAT_UINT;
|
||||
};
|
||||
|
||||
// is_not_bit_aligned< View > && is_unsigned< Channel >
|
||||
template <typename View, typename Channel>
|
||||
struct Format_Type
|
||||
<
|
||||
View,
|
||||
Channel,
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
mpl::not_
|
||||
<
|
||||
typename is_bit_aligned<typename get_pixel_type<View>::type>::type
|
||||
>,
|
||||
is_unsigned<Channel>
|
||||
>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static const int value = SAMPLEFORMAT_UINT;
|
||||
};
|
||||
|
||||
// is_not_bit_aligned< View > && is_signed< Channel >
|
||||
template <typename View, typename Channel>
|
||||
struct Format_Type
|
||||
<
|
||||
View,
|
||||
Channel,
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
mpl::not_
|
||||
<
|
||||
typename is_bit_aligned<typename get_pixel_type<View>::type>::type
|
||||
>,
|
||||
is_signed<Channel>
|
||||
>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static const int value = SAMPLEFORMAT_INT;
|
||||
};
|
||||
|
||||
// is_not_bit_aligned< View > && is_floating_point< Channel >
|
||||
template <typename View, typename Channel>
|
||||
struct Format_Type
|
||||
<
|
||||
View,
|
||||
Channel,
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
mpl::not_
|
||||
<
|
||||
typename is_bit_aligned<typename get_pixel_type<View>::type>::type
|
||||
>,
|
||||
is_floating_point<Channel>
|
||||
>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
static const int value = SAMPLEFORMAT_IEEEFP;
|
||||
};
|
||||
|
||||
//template< typename Channel >
|
||||
//int format_value( mpl::true_ ) // is_bit_aligned
|
||||
//{
|
||||
// return SAMPLEFORMAT_UINT;
|
||||
//}
|
||||
//
|
||||
//template< typename Channel >
|
||||
//int format_value( mpl::false_ ) // is_bit_aligned
|
||||
//{
|
||||
// if( is_unsigned< Channel >::value )
|
||||
// {
|
||||
// return SAMPLEFORMAT_UINT;
|
||||
// }
|
||||
//
|
||||
// if( is_signed< Channel >::value )
|
||||
// {
|
||||
// return SAMPLEFORMAT_INT;
|
||||
// }
|
||||
//
|
||||
// else if( is_floating_point< Channel >::value )
|
||||
// {
|
||||
// return SAMPLEFORMAT_IEEEFP;
|
||||
// }
|
||||
//
|
||||
// io_error( "Unkown channel format." );
|
||||
//}
|
||||
|
||||
// The following two functions look the same but are different since one is using
|
||||
// a pixel_t as template parameter whereas the other is using reference_t.
|
||||
template< typename View >
|
||||
bool compare_channel_sizes( const channel_sizes_t& channel_sizes // in bits
|
||||
, mpl::false_ // is_bit_aligned
|
||||
, mpl::true_ // is_homogeneous
|
||||
)
|
||||
{
|
||||
using pixel_t = typename View::value_type;
|
||||
using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
|
||||
|
||||
unsigned int s = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
|
||||
return ( s == channel_sizes[0] );
|
||||
}
|
||||
|
||||
|
||||
template< typename View >
|
||||
bool compare_channel_sizes( const channel_sizes_t& channel_sizes // in bits
|
||||
, mpl::true_ // is_bit_aligned
|
||||
, mpl::true_ // is_homogeneous
|
||||
)
|
||||
{
|
||||
using ref_t = typename View::reference;
|
||||
|
||||
using channel_t = typename channel_traits<typename element_type<ref_t>::type>::value_type;
|
||||
channel_t c;
|
||||
|
||||
unsigned int s = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
|
||||
return ( s == channel_sizes[0] );
|
||||
}
|
||||
|
||||
struct compare_channel_sizes_fn
|
||||
{
|
||||
compare_channel_sizes_fn( uint16_t* a )
|
||||
: _a( a )
|
||||
, _b( true )
|
||||
{}
|
||||
|
||||
template< typename ChannelSize >
|
||||
void operator()( ChannelSize x)
|
||||
{
|
||||
if( x != *_a++ )
|
||||
{
|
||||
_b = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t* _a;
|
||||
bool _b;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct channel_sizes_type {};
|
||||
|
||||
template< typename B, typename C, typename L, bool M >
|
||||
struct channel_sizes_type< bit_aligned_pixel_reference< B, C, L, M > > { using type = C; };
|
||||
|
||||
template< typename B, typename C, typename L, bool M >
|
||||
struct channel_sizes_type< const bit_aligned_pixel_reference< B, C, L, M > > { using type = C; };
|
||||
|
||||
template< typename View >
|
||||
bool compare_channel_sizes( channel_sizes_t& channel_sizes // in bits
|
||||
, mpl::true_ // is_bit_aligned
|
||||
, mpl::false_ // is_homogeneous
|
||||
)
|
||||
{
|
||||
// loop through all channels and compare
|
||||
|
||||
using ref_t = typename View::reference;
|
||||
using cs_t = typename channel_sizes_type<ref_t>::type;
|
||||
|
||||
compare_channel_sizes_fn fn( &channel_sizes.front() );
|
||||
mpl::for_each< cs_t >( fn );
|
||||
|
||||
return fn._b;
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< tiff_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
channel_sizes_t channel_sizes( info._samples_per_pixel
|
||||
, info._bits_per_sample
|
||||
);
|
||||
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
|
||||
|
||||
using num_channel_t = typename num_channels<pixel_t>::value_type;
|
||||
|
||||
const num_channel_t dst_samples_per_pixel = num_channels< pixel_t >::value;
|
||||
|
||||
//const num_channel_t dst_sample_format = format_value< channel_t >( typename is_bit_aligned< pixel_t >::type() );
|
||||
const num_channel_t dst_sample_format = Format_Type<View, channel_t>::value;
|
||||
|
||||
|
||||
return ( dst_samples_per_pixel == info._samples_per_pixel
|
||||
&& compare_channel_sizes< View >( channel_sizes
|
||||
, typename is_bit_aligned< pixel_t >::type()
|
||||
, typename is_homogeneous< pixel_t >::type()
|
||||
)
|
||||
&& dst_sample_format == info._sample_format
|
||||
);
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< tiff_tag >& /* info */
|
||||
, mpl::false_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
66
macx64/include/boost/gil/extension/io/tiff/detail/log.hpp
Normal file
66
macx64/include/boost/gil/extension/io/tiff/detail/log.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright 2009 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_LOG_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_LOG_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" {
|
||||
#include "tiffio.h"
|
||||
}
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
class tiff_no_log
|
||||
{
|
||||
public:
|
||||
|
||||
tiff_no_log()
|
||||
{
|
||||
TIFFSetErrorHandler ( nullptr );
|
||||
TIFFSetWarningHandler( nullptr );
|
||||
}
|
||||
};
|
||||
|
||||
class console_log
|
||||
{
|
||||
public:
|
||||
|
||||
console_log()
|
||||
{
|
||||
TIFFSetErrorHandler ( console_log::error );
|
||||
TIFFSetWarningHandler( console_log::warning );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void error( const char* /* module */
|
||||
, const char* fmt
|
||||
, va_list ap
|
||||
)
|
||||
{
|
||||
char buf[1000];
|
||||
sprintf(buf, fmt, ap);
|
||||
std::cout << "error: " << buf << std::endl;
|
||||
}
|
||||
|
||||
static void warning( char const* /* module */
|
||||
, char const* fmt
|
||||
, va_list ap
|
||||
)
|
||||
{
|
||||
char buf[1000];
|
||||
sprintf(buf, fmt, ap);
|
||||
std::cout << "warning: " << fmt << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
780
macx64/include/boost/gil/extension/io/tiff/detail/read.hpp
Normal file
780
macx64/include/boost/gil/extension/io/tiff/detail/read.hpp
Normal file
@@ -0,0 +1,780 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_READER_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_READER_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/detail/device.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template < int K >
|
||||
struct plane_recursion
|
||||
{
|
||||
template< typename View
|
||||
, typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
static
|
||||
void read_plane( const View& dst_view
|
||||
, reader< Device
|
||||
, tiff_tag
|
||||
, ConversionPolicy >* p
|
||||
)
|
||||
{
|
||||
using plane_t = typename kth_channel_view_type<K, View>::type;
|
||||
plane_t plane = kth_channel_view<K>( dst_view );
|
||||
|
||||
p->template read_data< detail::row_buffer_helper_view< plane_t > >( plane, K );
|
||||
|
||||
plane_recursion< K - 1 >::read_plane( dst_view, p );
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct plane_recursion< -1 >
|
||||
{
|
||||
template< typename View
|
||||
, typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
static
|
||||
void read_plane( const View& /* dst_view */
|
||||
, reader< Device
|
||||
, tiff_tag
|
||||
, ConversionPolicy
|
||||
>* /* p */
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
///
|
||||
/// Tiff Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, tiff_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< tiff_tag
|
||||
, ConversionPolicy >
|
||||
|
||||
, public reader_backend< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, tiff_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend<Device, tiff_tag>;
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< tiff_tag >& settings
|
||||
)
|
||||
: reader_base< tiff_tag
|
||||
, ConversionPolicy
|
||||
>()
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const typename ConversionPolicy::color_converter_type& cc
|
||||
, const image_read_settings< tiff_tag >& settings
|
||||
)
|
||||
: reader_base< tiff_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
// only works for homogeneous image types
|
||||
template< typename View >
|
||||
void apply( View& dst_view )
|
||||
{
|
||||
if( this->_info._photometric_interpretation == PHOTOMETRIC_PALETTE )
|
||||
{
|
||||
this->_scanline_length = this->_info._width
|
||||
* num_channels< rgb16_view_t >::value
|
||||
* sizeof( channel_type<rgb16_view_t>::type );
|
||||
|
||||
// Steps:
|
||||
// 1. Read indices. It's an array of grayX_pixel_t.
|
||||
// 2. Read palette. It's an array of rgb16_pixel_t.
|
||||
// 3. ??? Create virtual image or transform the two arrays
|
||||
// into a rgb16_image_t object. The latter might
|
||||
// be a good first solution.
|
||||
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 1: { read_palette_image< gray1_image_t >( dst_view ); break; }
|
||||
case 2: { read_palette_image< gray2_image_t >( dst_view ); break; }
|
||||
case 4: { read_palette_image< gray4_image_t >( dst_view ); break; }
|
||||
case 8: { read_palette_image< gray8_image_t >( dst_view ); break; }
|
||||
case 16: { read_palette_image< gray16_image_t >( dst_view ); break; }
|
||||
|
||||
default: { io_error( "Not supported palette " ); }
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_scanline_length = this->_io_dev.get_scanline_size();
|
||||
|
||||
// In case we only read the image the user's type and
|
||||
// the tiff type need to compatible. Which means:
|
||||
// color_spaces_are_compatible && channels_are_pairwise_compatible
|
||||
|
||||
using is_read_only = typename is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_only()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
if( this->_info._planar_configuration == PLANARCONFIG_SEPARATE )
|
||||
{
|
||||
plane_recursion< num_channels< View >::value - 1 >::read_plane( dst_view
|
||||
, this
|
||||
);
|
||||
}
|
||||
else if( this->_info._planar_configuration == PLANARCONFIG_CONTIG )
|
||||
{
|
||||
read( dst_view
|
||||
, typename is_read_only::type()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Wrong planar configuration setting." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename View >
|
||||
void read( View v
|
||||
, mpl::true_ // is_read_only
|
||||
)
|
||||
{
|
||||
read_data< detail::row_buffer_helper_view< View > >( v, 0 );
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void read( View v
|
||||
, mpl::false_ // is_read_only
|
||||
)
|
||||
{
|
||||
// the read_data function needs to know what gil type the source image is
|
||||
// to have the default color converter function correctly
|
||||
|
||||
switch( this->_info._photometric_interpretation )
|
||||
{
|
||||
case PHOTOMETRIC_MINISWHITE:
|
||||
case PHOTOMETRIC_MINISBLACK:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 1: { read_data< detail::row_buffer_helper_view< gray1_image_t::view_t > >( v, 0 ); break; }
|
||||
case 2: { read_data< detail::row_buffer_helper_view< gray2_image_t::view_t > >( v, 0 ); break; }
|
||||
case 4: { read_data< detail::row_buffer_helper_view< gray4_image_t::view_t > >( v, 0 ); break; }
|
||||
case 8: { read_data< detail::row_buffer_helper_view< gray8_view_t > >( v, 0 ); break; }
|
||||
case 16: { read_data< detail::row_buffer_helper_view< gray16_view_t > >( v, 0 ); break; }
|
||||
case 32: { read_data< detail::row_buffer_helper_view< gray32_view_t > >( v, 0 ); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PHOTOMETRIC_RGB:
|
||||
{
|
||||
switch( this->_info._samples_per_pixel )
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 8: { read_data< detail::row_buffer_helper_view< rgb8_view_t > >( v, 0 ); break; }
|
||||
case 16: { read_data< detail::row_buffer_helper_view< rgb16_view_t > >( v, 0 ); break; }
|
||||
case 32: { read_data< detail::row_buffer_helper_view< rgb32_view_t > >( v, 0 ); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 8: { read_data< detail::row_buffer_helper_view< rgba8_view_t > >( v, 0 ); break; }
|
||||
case 16: { read_data< detail::row_buffer_helper_view< rgba16_view_t > >( v, 0 ); break; }
|
||||
case 32: { read_data< detail::row_buffer_helper_view< rgba32_view_t > >( v, 0 ); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PHOTOMETRIC_SEPARATED: // CYMK
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 8: { read_data< detail::row_buffer_helper_view< cmyk8_view_t > >( v, 0 ); break; }
|
||||
case 16: { read_data< detail::row_buffer_helper_view< cmyk16_view_t > >( v, 0 ); break; }
|
||||
case 32: { read_data< detail::row_buffer_helper_view< cmyk32_view_t > >( v, 0 ); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
}
|
||||
|
||||
template< typename PaletteImage
|
||||
, typename View
|
||||
>
|
||||
void read_palette_image( const View& dst_view )
|
||||
{
|
||||
PaletteImage indices( this->_info._width - this->_settings._top_left.x
|
||||
, this->_info._height - this->_settings._top_left.y );
|
||||
|
||||
// read the palette first
|
||||
read_data< detail::row_buffer_helper_view< typename PaletteImage::view_t > >( view( indices ), 0 );
|
||||
|
||||
read_palette_image( dst_view
|
||||
, view( indices )
|
||||
, typename is_same< View, rgb16_view_t >::type() );
|
||||
}
|
||||
|
||||
template< typename View
|
||||
, typename Indices_View
|
||||
>
|
||||
void read_palette_image( const View& dst_view
|
||||
, const Indices_View& indices_view
|
||||
, mpl::true_ // is View rgb16_view_t
|
||||
)
|
||||
{
|
||||
tiff_color_map::red_t red = nullptr;
|
||||
tiff_color_map::green_t green = nullptr;
|
||||
tiff_color_map::blue_t blue = nullptr;
|
||||
|
||||
this->_io_dev.get_field_defaulted( red, green, blue );
|
||||
|
||||
using channel_t = typename channel_traits<typename element_type<typename Indices_View::value_type>::type>::value_type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value();
|
||||
|
||||
rgb16_planar_view_t palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, red
|
||||
, green
|
||||
, blue
|
||||
, sizeof(uint16_t) * num_colors );
|
||||
|
||||
for( typename rgb16_view_t::y_coord_t y = 0; y < dst_view.height(); ++y )
|
||||
{
|
||||
typename rgb16_view_t::x_iterator it = dst_view.row_begin( y );
|
||||
typename rgb16_view_t::x_iterator end = dst_view.row_end( y );
|
||||
|
||||
typename Indices_View::x_iterator indices_it = indices_view.row_begin( y );
|
||||
|
||||
for( ; it != end; ++it, ++indices_it )
|
||||
{
|
||||
uint16_t i = gil::at_c<0>( *indices_it );
|
||||
|
||||
*it = palette[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View
|
||||
, typename Indices_View
|
||||
>
|
||||
inline
|
||||
void read_palette_image( const View& /* dst_view */
|
||||
, const Indices_View& /* indices_view */
|
||||
, mpl::false_ // is View rgb16_view_t
|
||||
)
|
||||
{
|
||||
io_error( "User supplied image type must be rgb16_image_t." );
|
||||
}
|
||||
|
||||
template< typename Buffer >
|
||||
void skip_over_rows( Buffer& buffer
|
||||
, int plane
|
||||
)
|
||||
{
|
||||
if( this->_info._compression != COMPRESSION_NONE )
|
||||
{
|
||||
// Skipping over rows is not possible for compressed images( no random access ). See man
|
||||
// page ( diagnostics section ) for more information.
|
||||
for( std::ptrdiff_t row = 0; row < this->_settings._top_left.y; ++row )
|
||||
{
|
||||
this->_io_dev.read_scanline( buffer
|
||||
, row
|
||||
, static_cast< tsample_t >( plane ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void read_data( const View& dst_view
|
||||
, int /* plane */ )
|
||||
{
|
||||
if( this->_io_dev.is_tiled() )
|
||||
{
|
||||
read_tiled_data< Buffer >( dst_view, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
read_stripped_data< Buffer >( dst_view, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void read_tiled_data( const View& dst_view
|
||||
, int plane
|
||||
)
|
||||
{
|
||||
if( dst_view.width() != this->_info._width
|
||||
|| dst_view.height() != this->_info._height
|
||||
)
|
||||
{
|
||||
// read a subimage
|
||||
read_tiled_data_subimage< Buffer >( dst_view, plane );
|
||||
}
|
||||
else
|
||||
{
|
||||
// read full image
|
||||
read_tiled_data_full< Buffer >( dst_view, plane );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void read_tiled_data_subimage( const View& dst_view
|
||||
, int plane
|
||||
)
|
||||
{
|
||||
///@todo: why is
|
||||
/// using row_buffer_helper_t = Buffer;
|
||||
/// not working? I get compiler error with MSVC10.
|
||||
/// read_stripped_data IS working.
|
||||
using row_buffer_helper_t = detail::row_buffer_helper_view<View>;
|
||||
|
||||
using it_t = typename row_buffer_helper_t::iterator_t;
|
||||
|
||||
tiff_image_width::type image_width = this->_info._width;
|
||||
tiff_image_height::type image_height = this->_info._height;
|
||||
|
||||
tiff_tile_width::type tile_width = this->_info._tile_width;
|
||||
tiff_tile_length::type tile_height = this->_info._tile_length;
|
||||
|
||||
std::ptrdiff_t subimage_x = this->_settings._top_left.x;
|
||||
std::ptrdiff_t subimage_y = this->_settings._top_left.y;
|
||||
|
||||
std::ptrdiff_t subimage_width = this->_settings._dim.x;
|
||||
std::ptrdiff_t subimage_height = this->_settings._dim.y;
|
||||
|
||||
row_buffer_helper_t row_buffer_helper(this->_io_dev.get_tile_size(), true );
|
||||
|
||||
for( unsigned int y = 0; y < image_height; y += tile_height )
|
||||
{
|
||||
for( unsigned int x = 0; x < image_width; x += tile_width )
|
||||
{
|
||||
uint32_t current_tile_width = ( x + tile_width < image_width ) ? tile_width : image_width - x;
|
||||
uint32_t current_tile_length = ( y + tile_height < image_height ) ? tile_height : image_height - y;
|
||||
|
||||
this->_io_dev.read_tile( row_buffer_helper.buffer()
|
||||
, x
|
||||
, y
|
||||
, 0
|
||||
, static_cast< tsample_t >( plane )
|
||||
);
|
||||
|
||||
// these are all whole image coordinates
|
||||
point_t tile_top_left ( x, y );
|
||||
point_t tile_lower_right( x + current_tile_width - 1, y + current_tile_length - 1 );
|
||||
|
||||
point_t view_top_left ( subimage_x, subimage_y );
|
||||
point_t view_lower_right( subimage_x + subimage_width - 1
|
||||
, subimage_y + subimage_height - 1 );
|
||||
|
||||
if( tile_top_left.x > view_lower_right.x
|
||||
|| tile_top_left.y > view_lower_right.y
|
||||
|| tile_lower_right.x < view_top_left.x
|
||||
|| tile_lower_right.y < view_top_left.y
|
||||
)
|
||||
{
|
||||
// current tile and dst_view do not overlap
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// dst_view is overlapping the current tile
|
||||
|
||||
// next is to define the portion in the tile that needs to be copied
|
||||
|
||||
// get the whole image coordinates
|
||||
std::ptrdiff_t img_x0 = ( tile_top_left.x >= view_top_left.x ) ? tile_top_left.x : view_top_left.x;
|
||||
std::ptrdiff_t img_y0 = ( tile_top_left.y >= view_top_left.y ) ? tile_top_left.y : view_top_left.y;
|
||||
|
||||
std::ptrdiff_t img_x1 = ( tile_lower_right.x <= view_lower_right.x ) ? tile_lower_right.x : view_lower_right.x;
|
||||
std::ptrdiff_t img_y1 = ( tile_lower_right.y <= view_lower_right.y ) ? tile_lower_right.y : view_lower_right.y;
|
||||
|
||||
// convert to tile coordinates
|
||||
std::ptrdiff_t tile_x0 = img_x0 - x;
|
||||
std::ptrdiff_t tile_y0 = img_y0 - y;
|
||||
std::ptrdiff_t tile_x1 = img_x1 - x;
|
||||
std::ptrdiff_t tile_y1 = img_y1 - y;
|
||||
|
||||
BOOST_ASSERT(tile_x0 >= 0 && tile_y0 >= 0 && tile_x1 >= 0 && tile_y1 >= 0);
|
||||
BOOST_ASSERT(tile_x0 <= img_x1 && tile_y0 <= img_y1);
|
||||
BOOST_ASSERT(tile_x0 < tile_width && tile_y0 < tile_height && tile_x1 < tile_width && tile_y1 < tile_height);
|
||||
|
||||
std::ptrdiff_t tile_subimage_view_width = tile_x1 - tile_x0 + 1;
|
||||
std::ptrdiff_t tile_subimage_view_height = tile_y1 - tile_y0 + 1;
|
||||
|
||||
// convert to dst_view coordinates
|
||||
std::ptrdiff_t dst_x0 = img_x0 - subimage_x;
|
||||
std::ptrdiff_t dst_y0 = img_y0 - subimage_y;
|
||||
BOOST_ASSERT(dst_x0 >= 0 && dst_y0 >= 0);
|
||||
|
||||
View dst_subimage_view = subimage_view( dst_view
|
||||
, (int) dst_x0
|
||||
, (int) dst_y0
|
||||
, (int) tile_subimage_view_width
|
||||
, (int) tile_subimage_view_height
|
||||
);
|
||||
|
||||
// the row_buffer is a 1D array which represents a 2D image. We cannot
|
||||
// use interleaved_view here, since row_buffer could be bit_aligned.
|
||||
// Interleaved_view's fourth parameter "rowsize_in_bytes" doesn't work
|
||||
// for bit_aligned pixels.
|
||||
|
||||
for( std::ptrdiff_t dst_row = 0; dst_row < dst_subimage_view.height(); ++dst_row )
|
||||
{
|
||||
std::ptrdiff_t tile_row = dst_row + tile_y0;
|
||||
|
||||
// jump to the beginning of the current tile row
|
||||
it_t begin = row_buffer_helper.begin() + tile_row * tile_width;
|
||||
|
||||
begin += tile_x0;
|
||||
it_t end = begin + dst_subimage_view.width();
|
||||
|
||||
this->_cc_policy.read( begin
|
||||
, end
|
||||
, dst_subimage_view.row_begin( dst_row )
|
||||
);
|
||||
} //for
|
||||
}
|
||||
} // for
|
||||
} // for
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void read_tiled_data_full( const View& dst_view
|
||||
, int plane
|
||||
)
|
||||
{
|
||||
///@todo: why is
|
||||
/// using row_buffer_helper_t = Buffer;
|
||||
/// not working? I get compiler error with MSVC10.
|
||||
/// read_stripped_data IS working.
|
||||
using row_buffer_helper_t = detail::row_buffer_helper_view<View>;
|
||||
|
||||
using it_t = typename row_buffer_helper_t::iterator_t;
|
||||
|
||||
tiff_image_width::type image_width = this->_info._width;
|
||||
tiff_image_height::type image_height = this->_info._height;
|
||||
|
||||
tiff_tile_width::type tile_width = this->_info._tile_width;
|
||||
tiff_tile_length::type tile_height = this->_info._tile_length;
|
||||
|
||||
row_buffer_helper_t row_buffer_helper(this->_io_dev.get_tile_size(), true );
|
||||
|
||||
for( unsigned int y = 0; y < image_height; y += tile_height )
|
||||
{
|
||||
for( unsigned int x = 0; x < image_width; x += tile_width )
|
||||
{
|
||||
uint32_t current_tile_width = ( x + tile_width < image_width ) ? tile_width : image_width - x;
|
||||
uint32_t current_tile_length = ( y + tile_height < image_height ) ? tile_height : image_height - y;
|
||||
|
||||
this->_io_dev.read_tile( row_buffer_helper.buffer()
|
||||
, x
|
||||
, y
|
||||
, 0
|
||||
, static_cast< tsample_t >( plane )
|
||||
);
|
||||
|
||||
View dst_subimage_view = subimage_view( dst_view
|
||||
, x
|
||||
, y
|
||||
, current_tile_width
|
||||
, current_tile_length
|
||||
);
|
||||
|
||||
// the row_buffer is a 1D array which represents a 2D image. We cannot
|
||||
// use interleaved_view here, since row_buffer could be bit_aligned.
|
||||
// Interleaved_view's fourth parameter "rowsize_in_bytes" doesn't work
|
||||
// for bit_aligned pixels.
|
||||
|
||||
for( int row = 0; row < dst_subimage_view.height(); ++row )
|
||||
{
|
||||
it_t begin = row_buffer_helper.begin() + row * tile_width;
|
||||
it_t end = begin + dst_subimage_view.width();
|
||||
|
||||
this->_cc_policy.read( begin
|
||||
, end
|
||||
, dst_subimage_view.row_begin( row )
|
||||
);
|
||||
} //for
|
||||
} // for
|
||||
} // for
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void read_stripped_data( const View& dst_view
|
||||
, int plane )
|
||||
{
|
||||
using is_view_bit_aligned_t = typename is_bit_aligned<typename View::value_type>::type;
|
||||
|
||||
//using row_buffer_helper_t =detail::row_buffer_helper_view<View>;
|
||||
using row_buffer_helper_t = Buffer;
|
||||
using it_t = typename row_buffer_helper_t::iterator_t;
|
||||
|
||||
std::size_t size_to_allocate = buffer_size< typename View::value_type >( dst_view.width()
|
||||
, is_view_bit_aligned_t() );
|
||||
row_buffer_helper_t row_buffer_helper( size_to_allocate, true );
|
||||
|
||||
it_t begin = row_buffer_helper.begin();
|
||||
|
||||
it_t first = begin + this->_settings._top_left.x;
|
||||
it_t last = first + this->_settings._dim.x; // one after last element
|
||||
|
||||
// I don't think tiff allows for random access of row, that's why we need
|
||||
// to read and discard rows when reading subimages.
|
||||
skip_over_rows( row_buffer_helper.buffer()
|
||||
, plane
|
||||
);
|
||||
|
||||
std::ptrdiff_t row = this->_settings._top_left.y;
|
||||
std::ptrdiff_t row_end = row + this->_settings._dim.y;
|
||||
std::ptrdiff_t dst_row = 0;
|
||||
|
||||
for(
|
||||
; row < row_end
|
||||
; ++row, ++dst_row
|
||||
)
|
||||
{
|
||||
this->_io_dev.read_scanline( row_buffer_helper.buffer()
|
||||
, row
|
||||
, static_cast< tsample_t >( plane )
|
||||
);
|
||||
|
||||
this->_cc_policy.read( first
|
||||
, last
|
||||
, dst_view.row_begin( dst_row ));
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Pixel >
|
||||
std::size_t buffer_size( std::size_t width
|
||||
, mpl::false_ // is_bit_aligned
|
||||
)
|
||||
{
|
||||
std::size_t scanline_size_in_bytes = this->_io_dev.get_scanline_size();
|
||||
|
||||
std::size_t element_size = sizeof( Pixel );
|
||||
|
||||
std::size_t ret = std::max( width
|
||||
, (( scanline_size_in_bytes + element_size - 1 ) / element_size )
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template< typename Pixel >
|
||||
std::size_t buffer_size( std::size_t /* width */
|
||||
, mpl::true_ // is_bit_aligned
|
||||
)
|
||||
{
|
||||
return this->_io_dev.get_scanline_size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template < int K > friend struct plane_recursion;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct tiff_type_format_checker
|
||||
{
|
||||
tiff_type_format_checker( const image_read_info< tiff_tag >& info )
|
||||
: _info( info )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
using view_t = typename Image::view_t;
|
||||
|
||||
return is_allowed< view_t >( _info
|
||||
, mpl::true_()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
tiff_type_format_checker& operator=( const tiff_type_format_checker& ) { return *this; }
|
||||
|
||||
private:
|
||||
|
||||
const image_read_info< tiff_tag > _info;
|
||||
};
|
||||
|
||||
struct tiff_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, tiff_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
///
|
||||
/// Tiff Dynamic Image Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_reader< Device
|
||||
, tiff_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, tiff_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader<Device, tiff_tag, detail::read_and_no_convert>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< tiff_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::tiff_type_format_checker format_checker( this->_info );
|
||||
|
||||
if( !construct_matched( images
|
||||
, format_checker
|
||||
))
|
||||
{
|
||||
io_error( "No matching image type between those of the given any_image and that of the file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->init_image( images
|
||||
, this->_settings
|
||||
);
|
||||
|
||||
detail::dynamic_io_fnobj< detail::tiff_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// TIFF Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = tiff_tag;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< tiff_tag >& settings
|
||||
)
|
||||
: _io_dev ( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
|
||||
, _scanline_length( 0 )
|
||||
|
||||
, _red ( nullptr )
|
||||
, _green( nullptr )
|
||||
, _blue ( nullptr )
|
||||
{
|
||||
init_multipage_read( settings );
|
||||
|
||||
read_header();
|
||||
|
||||
if( _settings._dim.x == 0 )
|
||||
{
|
||||
_settings._dim.x = _info._width;
|
||||
}
|
||||
|
||||
if( _settings._dim.y == 0 )
|
||||
{
|
||||
_settings._dim.y = _info._height;
|
||||
}
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
io_error_if( _io_dev.template get_property<tiff_image_width> ( _info._width ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_image_height> ( _info._height ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_compression> ( _info._compression ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_samples_per_pixel> ( _info._samples_per_pixel ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_bits_per_sample> ( _info._bits_per_sample ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_sample_format> ( _info._sample_format ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_planar_configuration> ( _info._planar_configuration ) == false
|
||||
, "cannot read tiff tag." );
|
||||
io_error_if( _io_dev.template get_property<tiff_photometric_interpretation>( _info._photometric_interpretation ) == false
|
||||
, "cannot read tiff tag." );
|
||||
|
||||
_info._is_tiled = false;
|
||||
|
||||
// Tile tags
|
||||
if( _io_dev.is_tiled() )
|
||||
{
|
||||
_info._is_tiled = true;
|
||||
|
||||
io_error_if( !_io_dev.template get_property< tiff_tile_width >( _info._tile_width )
|
||||
, "cannot read tiff_tile_width tag." );
|
||||
io_error_if( !_io_dev.template get_property< tiff_tile_length >( _info._tile_length )
|
||||
, "cannot read tiff_tile_length tag." );
|
||||
}
|
||||
|
||||
io_error_if( _io_dev.template get_property<tiff_resolution_unit>( _info._resolution_unit) == false
|
||||
, "cannot read tiff tag");
|
||||
io_error_if( _io_dev. template get_property<tiff_x_resolution>( _info._x_resolution ) == false
|
||||
, "cannot read tiff tag" );
|
||||
io_error_if( _io_dev. template get_property<tiff_y_resolution>( _info._y_resolution ) == false
|
||||
, "cannot read tiff tag" );
|
||||
|
||||
/// optional and non-baseline properties below here
|
||||
_io_dev. template get_property <tiff_icc_profile> ( _info._icc_profile );
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (tiff_image_width::type) img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
|
||||
|
||||
if( _settings._dim.y > 0 )
|
||||
{
|
||||
if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (tiff_image_height::type) img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_multipage_read( const image_read_settings< tiff_tag >& settings )
|
||||
{
|
||||
if( settings._directory > 0 )
|
||||
{
|
||||
_io_dev.set_directory( settings._directory );
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< tiff_tag > _settings;
|
||||
image_read_info< tiff_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
|
||||
// palette
|
||||
tiff_color_map::red_t _red;
|
||||
tiff_color_map::green_t _green;
|
||||
tiff_color_map::blue_t _blue;
|
||||
|
||||
rgb16_planar_view_t _palette;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,447 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/detail/device.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
// taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// TIFF scanline reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, tiff_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = tiff_tag;
|
||||
using backend_t = reader_backend<Device, tag_t>;
|
||||
using this_t = scanline_reader<Device, tag_t>;
|
||||
using iterator_t = scanline_read_iterator<this_t>;
|
||||
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< tiff_tag >& settings
|
||||
)
|
||||
: backend_t( device
|
||||
, settings
|
||||
)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
/// Read part of image defined by View and return the data.
|
||||
void read( byte_t* dst, int pos )
|
||||
{
|
||||
_read_function( this, dst, pos );
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t* dst, int pos )
|
||||
{
|
||||
this->_read_function( this, dst, pos );
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
io_error_if( this->_info._is_tiled
|
||||
, "scanline_reader doesn't support tiled tiff images."
|
||||
);
|
||||
|
||||
if( this->_info._photometric_interpretation == PHOTOMETRIC_PALETTE )
|
||||
{
|
||||
|
||||
this->_scanline_length = this->_info._width
|
||||
* num_channels< rgb16_view_t >::value
|
||||
* sizeof( channel_type<rgb16_view_t>::type );
|
||||
|
||||
this->_io_dev.get_field_defaulted( this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
);
|
||||
|
||||
_buffer = std::vector< byte_t >( this->_io_dev.get_scanline_size() );
|
||||
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray1_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_1_bit_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray2_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_2_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray4_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_4_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray8_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_8_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray16_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_16_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray24_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_24_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
using channel_t = channel_type<get_pixel_type<gray32_image_t::view_t>::type>::type;
|
||||
|
||||
int num_colors = channel_traits< channel_t >::max_value() + 1;
|
||||
|
||||
this->_palette = planar_rgb_view( num_colors
|
||||
, 1
|
||||
, this->_red
|
||||
, this->_green
|
||||
, this->_blue
|
||||
, sizeof(uint16_t) * num_colors
|
||||
);
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_32_bits_index_image);
|
||||
|
||||
break;
|
||||
}
|
||||
default: { io_error( "Not supported palette " ); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_scanline_length = this->_io_dev.get_scanline_size();
|
||||
|
||||
if( this->_info._planar_configuration == PLANARCONFIG_SEPARATE )
|
||||
{
|
||||
io_error( "scanline_reader doesn't support planar tiff images." );
|
||||
}
|
||||
else if( this->_info._planar_configuration == PLANARCONFIG_CONTIG )
|
||||
{
|
||||
|
||||
// the read_data function needs to know what gil type the source image is
|
||||
// to have the default color converter function correctly
|
||||
|
||||
switch( this->_info._photometric_interpretation )
|
||||
{
|
||||
case PHOTOMETRIC_MINISWHITE:
|
||||
case PHOTOMETRIC_MINISBLACK:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PHOTOMETRIC_RGB:
|
||||
{
|
||||
switch( this->_info._samples_per_pixel )
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PHOTOMETRIC_SEPARATED: // CYMK
|
||||
{
|
||||
switch( this->_info._bits_per_sample )
|
||||
{
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Image type is not supported." ); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Wrong planar configuration setting." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Src_View >
|
||||
void read_n_bits_row( byte_t* dst, int pos )
|
||||
{
|
||||
using dst_view_t = rgb16_view_t;
|
||||
|
||||
this->_io_dev.read_scanline( _buffer
|
||||
, pos
|
||||
, 0
|
||||
);
|
||||
|
||||
Src_View src_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename Src_View::x_iterator) &_buffer.front()
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
dst_view_t dst_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename dst_view_t::value_type*) dst
|
||||
, num_channels< dst_view_t >::value * 2 * this->_info._width
|
||||
);
|
||||
|
||||
|
||||
typename Src_View::x_iterator src_it = src_view.row_begin( 0 );
|
||||
typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
|
||||
|
||||
for( dst_view_t::x_coord_t i = 0
|
||||
; i < this->_info._width
|
||||
; ++i, src_it++, dst_it++
|
||||
)
|
||||
{
|
||||
auto const c = static_cast<std::uint16_t>(get_color(*src_it, gray_color_t()));
|
||||
*dst_it = this->_palette[c];
|
||||
}
|
||||
}
|
||||
|
||||
void read_1_bit_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray1_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_2_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray2_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_4_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray4_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_8_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray8_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_16_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray16_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_24_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray24_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_32_bits_index_image( byte_t* dst, int pos )
|
||||
{
|
||||
read_n_bits_row< gray32_image_t::view_t >( dst, pos );
|
||||
}
|
||||
|
||||
void read_row(byte_t* dst, int pos )
|
||||
{
|
||||
this->_io_dev.read_scanline( dst
|
||||
, pos
|
||||
, 0
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector< byte_t> _buffer;
|
||||
detail::mirror_bits<std::vector<byte_t>, std::true_type> _mirror_bites;
|
||||
std::function<void(this_t*, byte_t*, int)> _read_function;
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost{ namespace gil {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Read support
|
||||
|
||||
// TIFF virtually supports everything
|
||||
struct tiff_read_support : read_support_true
|
||||
{};
|
||||
|
||||
|
||||
// Write support
|
||||
|
||||
struct tiff_write_support : write_support_true
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, tiff_tag
|
||||
>
|
||||
: mpl::bool_< detail::tiff_read_support::is_supported > {};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, tiff_tag
|
||||
>
|
||||
: mpl::bool_< detail::tiff_write_support::is_supported >
|
||||
{};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
449
macx64/include/boost/gil/extension/io/tiff/detail/write.hpp
Normal file
449
macx64/include/boost/gil/extension/io/tiff/detail/write.hpp
Normal file
@@ -0,0 +1,449 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/writer_backend.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/device.hpp>
|
||||
|
||||
#include <boost/gil/premultiply.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include "tiff.h"
|
||||
#include "tiffio.h"
|
||||
}
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename PixelReference>
|
||||
struct my_interleaved_pixel_iterator_type_from_pixel_reference
|
||||
{
|
||||
private:
|
||||
using pixel_t = typename remove_reference<PixelReference>::type::value_type;
|
||||
public:
|
||||
using type = typename iterator_type_from_pixel
|
||||
<
|
||||
pixel_t,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
>::type;
|
||||
};
|
||||
|
||||
|
||||
template< typename Channel
|
||||
, typename Layout
|
||||
, bool Mutable
|
||||
>
|
||||
struct my_interleaved_pixel_iterator_type_from_pixel_reference< const bit_aligned_pixel_reference< byte_t
|
||||
, Channel
|
||||
, Layout
|
||||
, Mutable
|
||||
>
|
||||
>
|
||||
: public iterator_type_from_pixel< const bit_aligned_pixel_reference< uint8_t
|
||||
, Channel
|
||||
, Layout
|
||||
, Mutable
|
||||
>
|
||||
,false
|
||||
,false
|
||||
,true
|
||||
> {};
|
||||
|
||||
struct tiff_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, tiff_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// TIFF Writer
|
||||
///
|
||||
template < typename Device, typename Log >
|
||||
class writer< Device
|
||||
, tiff_tag
|
||||
, Log
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
using backend_t = writer_backend<Device, tiff_tag>;
|
||||
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< tiff_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
write_view( view );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename View >
|
||||
void write_view( const View& view )
|
||||
{
|
||||
using pixel_t = typename View::value_type;
|
||||
// get the type of the first channel (heterogeneous pixels might be broken for now!)
|
||||
using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
|
||||
tiff_bits_per_sample::type bits_per_sample = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
|
||||
tiff_samples_per_pixel::type samples_per_pixel = num_channels< pixel_t >::value;
|
||||
|
||||
this->write_header( view );
|
||||
|
||||
if( this->_info._is_tiled == false )
|
||||
{
|
||||
write_data( view
|
||||
, (view.width() * samples_per_pixel * bits_per_sample + 7) / 8
|
||||
, typename is_bit_aligned< pixel_t >::type()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
tiff_tile_width::type tw = this->_info._tile_width;
|
||||
tiff_tile_length::type th = this->_info._tile_length;
|
||||
|
||||
if(!this->_io_dev.check_tile_size( tw, th ))
|
||||
{
|
||||
io_error( "Tile sizes need to be multiples of 16." );
|
||||
}
|
||||
|
||||
// tile related tags
|
||||
this->_io_dev.template set_property<tiff_tile_width> ( tw );
|
||||
this->_io_dev.template set_property<tiff_tile_length>( th );
|
||||
|
||||
write_tiled_data( view
|
||||
, tw
|
||||
, th
|
||||
, typename is_bit_aligned< pixel_t >::type()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
template<typename View>
|
||||
void write_bit_aligned_view_to_dev( const View& view
|
||||
, const std::size_t row_size_in_bytes
|
||||
, const mpl::true_& // has_alpha
|
||||
)
|
||||
{
|
||||
byte_vector_t row( row_size_in_bytes );
|
||||
|
||||
using x_it_t = typename View::x_iterator;
|
||||
x_it_t row_it = x_it_t( &(*row.begin()));
|
||||
|
||||
auto pm_view = premultiply_view <typename View:: value_type> (view);
|
||||
|
||||
for( typename View::y_coord_t y = 0; y < pm_view.height(); ++y )
|
||||
{
|
||||
std::copy( pm_view.row_begin( y )
|
||||
, pm_view.row_end( y )
|
||||
, row_it
|
||||
);
|
||||
|
||||
|
||||
this->_io_dev.write_scaline( row
|
||||
, (uint32) y
|
||||
, 0
|
||||
);
|
||||
|
||||
// @todo: do optional bit swapping here if you need to...
|
||||
}
|
||||
}
|
||||
|
||||
template<typename View>
|
||||
void write_bit_aligned_view_to_dev( const View& view
|
||||
, const std::size_t row_size_in_bytes
|
||||
, const mpl::false_& // has_alpha
|
||||
)
|
||||
{
|
||||
byte_vector_t row( row_size_in_bytes );
|
||||
|
||||
using x_it_t = typename View::x_iterator;
|
||||
x_it_t row_it = x_it_t( &(*row.begin()));
|
||||
|
||||
for( typename View::y_coord_t y = 0; y < view.height(); ++y )
|
||||
{
|
||||
std::copy( view.row_begin( y )
|
||||
, view.row_end( y )
|
||||
, row_it
|
||||
);
|
||||
|
||||
|
||||
this->_io_dev.write_scaline( row
|
||||
, (uint32) y
|
||||
, 0
|
||||
);
|
||||
|
||||
// @todo: do optional bit swapping here if you need to...
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& view
|
||||
, std::size_t row_size_in_bytes
|
||||
, const mpl::true_& // bit_aligned
|
||||
)
|
||||
{
|
||||
using colour_space_t = typename color_space_type<typename View::value_type>::type;
|
||||
using has_alpha_t = mpl::bool_<mpl::contains<colour_space_t, alpha_t>::value>;
|
||||
|
||||
write_bit_aligned_view_to_dev(view, row_size_in_bytes, has_alpha_t());
|
||||
}
|
||||
|
||||
template< typename View>
|
||||
void write_tiled_data( const View& view
|
||||
, tiff_tile_width::type tw
|
||||
, tiff_tile_length::type th
|
||||
, const mpl::true_& // bit_aligned
|
||||
)
|
||||
{
|
||||
byte_vector_t row( this->_io_dev.get_tile_size() );
|
||||
|
||||
using x_it_t = typename View::x_iterator;
|
||||
x_it_t row_it = x_it_t( &(*row.begin()));
|
||||
|
||||
internal_write_tiled_data(view, tw, th, row, row_it);
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& view
|
||||
, std::size_t
|
||||
, const mpl::false_& // bit_aligned
|
||||
)
|
||||
{
|
||||
std::vector< pixel< typename channel_type< View >::type
|
||||
, layout<typename color_space_type< View >::type >
|
||||
>
|
||||
> row( view.size() );
|
||||
|
||||
byte_t* row_addr = reinterpret_cast< byte_t* >( &row.front() );
|
||||
|
||||
// @todo: is there an overhead to doing this when there's no
|
||||
// alpha to premultiply by? I'd hope it's optimised out.
|
||||
auto pm_view = premultiply_view <typename View:: value_type> (view);
|
||||
|
||||
for( typename View::y_coord_t y = 0; y < pm_view.height(); ++y )
|
||||
{
|
||||
std::copy( pm_view.row_begin( y )
|
||||
, pm_view.row_end( y )
|
||||
, row.begin()
|
||||
);
|
||||
|
||||
this->_io_dev.write_scaline( row_addr
|
||||
, (uint32) y
|
||||
, 0
|
||||
);
|
||||
|
||||
// @todo: do optional bit swapping here if you need to...
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_tiled_data( const View& view
|
||||
, tiff_tile_width::type tw
|
||||
, tiff_tile_length::type th
|
||||
, const mpl::false_& // bit_aligned
|
||||
)
|
||||
{
|
||||
byte_vector_t row( this->_io_dev.get_tile_size() );
|
||||
|
||||
using x_iterator = typename detail::my_interleaved_pixel_iterator_type_from_pixel_reference<typename View::reference>::type;
|
||||
x_iterator row_it = x_iterator( &(*row.begin()));
|
||||
|
||||
internal_write_tiled_data(view, tw, th, row, row_it);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
template< typename View
|
||||
, typename IteratorType
|
||||
>
|
||||
void write_tiled_view_to_dev( const View& view
|
||||
, IteratorType it
|
||||
, const mpl::true_& // has_alpha
|
||||
)
|
||||
{
|
||||
auto pm_view = premultiply_view <typename View:: value_type>( view );
|
||||
|
||||
std::copy( pm_view.begin()
|
||||
, pm_view.end()
|
||||
, it
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template< typename View
|
||||
, typename IteratorType
|
||||
>
|
||||
void write_tiled_view_to_dev( const View& view
|
||||
, IteratorType it
|
||||
, const mpl::false_& // has_alpha
|
||||
)
|
||||
{
|
||||
std::copy( view.begin()
|
||||
, view.end()
|
||||
, it
|
||||
);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
|
||||
template< typename View,
|
||||
typename IteratorType
|
||||
>
|
||||
void internal_write_tiled_data( const View& view
|
||||
, tiff_tile_width::type tw
|
||||
, tiff_tile_length::type th
|
||||
, byte_vector_t& row
|
||||
, IteratorType it
|
||||
)
|
||||
{
|
||||
std::ptrdiff_t i = 0, j = 0;
|
||||
View tile_subimage_view;
|
||||
while( i < view.height() )
|
||||
{
|
||||
while( j < view.width() )
|
||||
{
|
||||
if( j + tw < view.width() && i + th < view.height() )
|
||||
{
|
||||
// a tile is fully included in the image: just copy values
|
||||
tile_subimage_view = subimage_view( view
|
||||
, static_cast< int >( j )
|
||||
, static_cast< int >( i )
|
||||
, static_cast< int >( tw )
|
||||
, static_cast< int >( th )
|
||||
);
|
||||
|
||||
using colour_space_t = typename color_space_type<typename View::value_type>::type;
|
||||
using has_alpha_t = mpl::bool_<mpl::contains<colour_space_t, alpha_t>::value>;
|
||||
|
||||
write_tiled_view_to_dev(tile_subimage_view, it, has_alpha_t());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ptrdiff_t width = view.width();
|
||||
std::ptrdiff_t height = view.height();
|
||||
|
||||
std::ptrdiff_t current_tile_width = ( j + tw < width ) ? tw : width - j;
|
||||
std::ptrdiff_t current_tile_length = ( i + th < height) ? th : height - i;
|
||||
|
||||
tile_subimage_view = subimage_view( view
|
||||
, static_cast< int >( j )
|
||||
, static_cast< int >( i )
|
||||
, static_cast< int >( current_tile_width )
|
||||
, static_cast< int >( current_tile_length )
|
||||
);
|
||||
|
||||
for( typename View::y_coord_t y = 0; y < tile_subimage_view.height(); ++y )
|
||||
{
|
||||
std::copy( tile_subimage_view.row_begin( y )
|
||||
, tile_subimage_view.row_end( y )
|
||||
, it
|
||||
);
|
||||
std::advance(it, tw);
|
||||
}
|
||||
|
||||
it = IteratorType( &(*row.begin()));
|
||||
}
|
||||
|
||||
this->_io_dev.write_tile( row
|
||||
, static_cast< uint32 >( j )
|
||||
, static_cast< uint32 >( i )
|
||||
, 0
|
||||
, 0
|
||||
);
|
||||
j += tw;
|
||||
}
|
||||
j = 0;
|
||||
i += th;
|
||||
}
|
||||
// @todo: do optional bit swapping here if you need to...
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// TIFF Dynamic Image Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, tiff_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, tiff_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< tiff_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::tiff_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views, op );
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/device.hpp>
|
||||
|
||||
#include <boost/mpl/contains.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// TIFF Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, tiff_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = tiff_tag;
|
||||
|
||||
public:
|
||||
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< tiff_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info( info )
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
||||
template< typename View >
|
||||
void write_header( const View& view )
|
||||
{
|
||||
using pixel_t = typename View::value_type;
|
||||
|
||||
// get the type of the first channel (heterogeneous pixels might be broken for now!)
|
||||
using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
|
||||
using color_space_t = typename color_space_type<View>::type;
|
||||
|
||||
if(! this->_info._photometric_interpretation_user_defined )
|
||||
{
|
||||
// write photometric interpretion - Warning: This value is rather
|
||||
// subjective. The user should better set this value itself. There
|
||||
// is no way to decide if a image is PHOTOMETRIC_MINISWHITE or
|
||||
// PHOTOMETRIC_MINISBLACK. If the user has not manually set it, then
|
||||
// this writer will assume PHOTOMETRIC_MINISBLACK for gray_t images,
|
||||
// PHOTOMETRIC_RGB for rgb_t images, and PHOTOMETRIC_SEPARATED (as
|
||||
// is conventional) for cmyk_t images.
|
||||
this->_info._photometric_interpretation = detail::photometric_interpretation< color_space_t >::value;
|
||||
}
|
||||
|
||||
// write dimensions
|
||||
tiff_image_width::type width = (tiff_image_width::type) view.width();
|
||||
tiff_image_height::type height = (tiff_image_height::type) view.height();
|
||||
|
||||
this->_io_dev.template set_property< tiff_image_width >( width );
|
||||
this->_io_dev.template set_property< tiff_image_height >( height );
|
||||
|
||||
// write planar configuration
|
||||
this->_io_dev.template set_property<tiff_planar_configuration>( this->_info._planar_configuration );
|
||||
|
||||
// write samples per pixel
|
||||
tiff_samples_per_pixel::type samples_per_pixel = num_channels< pixel_t >::value;
|
||||
this->_io_dev.template set_property<tiff_samples_per_pixel>( samples_per_pixel );
|
||||
|
||||
if (mpl:: contains <color_space_t, alpha_t>:: value) {
|
||||
std:: vector <uint16_t> extra_samples {EXTRASAMPLE_ASSOCALPHA};
|
||||
this->_io_dev.template set_property<tiff_extra_samples>( extra_samples );
|
||||
}
|
||||
// write bits per sample
|
||||
// @todo: Settings this value usually requires to write for each sample the bit
|
||||
// value seperately in case they are different, like rgb556.
|
||||
tiff_bits_per_sample::type bits_per_sample = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
this->_io_dev.template set_property<tiff_bits_per_sample>( bits_per_sample );
|
||||
|
||||
// write sample format
|
||||
tiff_sample_format::type sampl_format = detail::sample_format< channel_t >::value;
|
||||
this->_io_dev.template set_property<tiff_sample_format>( sampl_format );
|
||||
|
||||
// write photometric format
|
||||
this->_io_dev.template set_property<tiff_photometric_interpretation>( this->_info._photometric_interpretation );
|
||||
|
||||
// write compression
|
||||
this->_io_dev.template set_property<tiff_compression>( this->_info._compression );
|
||||
|
||||
// write orientation
|
||||
this->_io_dev.template set_property<tiff_orientation>( this->_info._orientation );
|
||||
|
||||
// write rows per strip
|
||||
this->_io_dev.template set_property<tiff_rows_per_strip>( this->_io_dev.get_default_strip_size() );
|
||||
|
||||
// write x, y resolution and units
|
||||
this->_io_dev.template set_property<tiff_resolution_unit>( this->_info._resolution_unit );
|
||||
this->_io_dev.template set_property<tiff_x_resolution>( this->_info._x_resolution );
|
||||
this->_io_dev.template set_property<tiff_y_resolution>( this->_info._y_resolution );
|
||||
|
||||
/// Optional and / or non-baseline tags below here
|
||||
|
||||
// write ICC colour profile, if it's there
|
||||
// http://www.color.org/icc_specs2.xalter
|
||||
if ( 0 != this->_info._icc_profile.size())
|
||||
this->_io_dev.template set_property<tiff_icc_profile>( this->_info._icc_profile );
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< tiff_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
160
macx64/include/boost/gil/extension/io/tiff/old.hpp
Normal file
160
macx64/include/boost/gil/extension/io/tiff/old.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \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
|
||||
template<typename String>
|
||||
inline point_t tiff_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, tiff_tag>::type;
|
||||
backend_t backend = read_image_info(filename, tiff_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \ingroup TIFF_IO
|
||||
/// \brief Loads the image specified by the given tiff image file name into the given view.
|
||||
/// 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.
|
||||
/// 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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void tiff_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup TIFF_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
|
||||
/// 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.
|
||||
/// 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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void tiff_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void tiff_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void tiff_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void tiff_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void tiff_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup TIFF_IO
|
||||
/// \brief Saves the view to a tiff file specified by the given tiff image file name.
|
||||
/// 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.
|
||||
/// Throws std::ios_base::failure if it fails to create the file.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void tiff_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, tiff_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
30
macx64/include/boost/gil/extension/io/tiff/read.hpp
Normal file
30
macx64/include/boost/gil/extension/io/tiff/read.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_READ_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/scanline_read.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/supported_types.hpp>
|
||||
|
||||
#include <boost/gil/io/get_reader.hpp>
|
||||
#include <boost/gil/io/make_backend.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_reader.hpp>
|
||||
#include <boost/gil/io/make_reader.hpp>
|
||||
#include <boost/gil/io/make_scanline_reader.hpp>
|
||||
#include <boost/gil/io/read_and_convert_image.hpp>
|
||||
#include <boost/gil/io/read_and_convert_view.hpp>
|
||||
#include <boost/gil/io/read_image.hpp>
|
||||
#include <boost/gil/io/read_image_info.hpp>
|
||||
#include <boost/gil/io/read_view.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#endif
|
||||
351
macx64/include/boost/gil/extension/io/tiff/tags.hpp
Normal file
351
macx64/include/boost/gil/extension/io/tiff/tags.hpp
Normal file
@@ -0,0 +1,351 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_TAGS_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/detail/log.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
// taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <tiff.h>
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines tiff tag.
|
||||
struct tiff_tag : format_tag {};
|
||||
|
||||
/// http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
|
||||
/// http://www.remotesensing.org/libtiff/
|
||||
|
||||
/// TIFF property base class
|
||||
template< typename T, int Value >
|
||||
struct tiff_property_base : property_base< T >
|
||||
{
|
||||
/// Tag, needed when reading or writing image properties.
|
||||
static const ttag_t tag = Value;
|
||||
/// The list of argument types used in the interface of LibTIFF
|
||||
/// for
|
||||
/// this property:
|
||||
/// http://www.remotesensing.org/libtiff/man/TIFFGetField.3tiff.html
|
||||
/// http://www.remotesensing.org/libtiff/man/TIFFSetField.3tiff.html
|
||||
using arg_types = mpl::vector<typename property_base<unsigned short>::type>;
|
||||
};
|
||||
|
||||
/// baseline tags
|
||||
|
||||
/// Defines type for new subfile property.
|
||||
struct tiff_new_subfile_type : tiff_property_base< uint32_t, TIFFTAG_SUBFILETYPE > {};
|
||||
|
||||
/// Defines type for subfile property.
|
||||
struct tiff_subfile_type : tiff_property_base< uint16_t, TIFFTAG_OSUBFILETYPE > {};
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct tiff_image_width : tiff_property_base< uint32_t, TIFFTAG_IMAGEWIDTH > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct tiff_image_height : tiff_property_base< uint32_t, TIFFTAG_IMAGELENGTH > {};
|
||||
|
||||
/// Defines type for bits per sample property.
|
||||
struct tiff_bits_per_sample : tiff_property_base< uint16_t, TIFFTAG_BITSPERSAMPLE > {};
|
||||
|
||||
/// Defines type for compression property.
|
||||
struct tiff_compression : tiff_property_base< uint16_t, TIFFTAG_COMPRESSION > {};
|
||||
|
||||
/// Defines type for photometric interpretation property.
|
||||
struct tiff_photometric_interpretation : tiff_property_base< uint16_t, TIFFTAG_PHOTOMETRIC > {};
|
||||
|
||||
/// Defines type for threshold property.
|
||||
struct tiff_thresholding : tiff_property_base< uint16_t, TIFFTAG_THRESHHOLDING > {};
|
||||
|
||||
/// Defines type for cell width property.
|
||||
struct tiff_cell_width : tiff_property_base< uint16_t, TIFFTAG_CELLWIDTH > {};
|
||||
|
||||
/// Defines type for cell length property.
|
||||
struct tiff_cell_length : tiff_property_base< uint16_t, TIFFTAG_CELLLENGTH > {};
|
||||
|
||||
/// Defines type for fill order property.
|
||||
struct tiff_fill_order : tiff_property_base< std::string, TIFFTAG_FILLORDER > {};
|
||||
|
||||
/// Defines type for image description.
|
||||
struct tiff_image_description : tiff_property_base< std::string, TIFFTAG_IMAGEDESCRIPTION > {};
|
||||
|
||||
/// Defines type for make property.
|
||||
struct tiff_make : tiff_property_base< std::string, TIFFTAG_MAKE > {};
|
||||
|
||||
/// Defines type for model property.
|
||||
struct tiff_model : tiff_property_base< std::string, TIFFTAG_MODEL > {};
|
||||
|
||||
/// Defines type for image orientation.
|
||||
struct tiff_orientation : tiff_property_base< uint16_t, TIFFTAG_ORIENTATION > {};
|
||||
|
||||
/// Defines type for samples per pixel property.
|
||||
struct tiff_samples_per_pixel : tiff_property_base< uint16_t, TIFFTAG_SAMPLESPERPIXEL > {};
|
||||
|
||||
/// Defines type for rows per strip property.
|
||||
struct tiff_rows_per_strip : tiff_property_base< uint32_t, TIFFTAG_ROWSPERSTRIP > {};
|
||||
|
||||
/// Defines type for min sample property.
|
||||
struct tiff_min_sample_value : tiff_property_base< uint16_t, TIFFTAG_MINSAMPLEVALUE > {};
|
||||
|
||||
/// Defines type for max sample property.
|
||||
struct tiff_max_sample_value : tiff_property_base< uint16_t, TIFFTAG_MAXSAMPLEVALUE > {};
|
||||
|
||||
/// Defines type for x resolution property.
|
||||
struct tiff_x_resolution : tiff_property_base< float, TIFFTAG_XRESOLUTION > {};
|
||||
|
||||
/// Defines type for y resolution property.
|
||||
struct tiff_y_resolution : tiff_property_base< float, TIFFTAG_YRESOLUTION > {};
|
||||
|
||||
/// Defines type for resolution unit property.
|
||||
enum class tiff_resolution_unit_value: std:: uint16_t {
|
||||
NONE = RESUNIT_NONE,
|
||||
INCH = RESUNIT_INCH,
|
||||
CENTIMETER = RESUNIT_CENTIMETER
|
||||
};
|
||||
|
||||
struct tiff_resolution_unit : tiff_property_base< tiff_resolution_unit_value, TIFFTAG_RESOLUTIONUNIT > {};
|
||||
|
||||
/// Defines type for planar configuration property.
|
||||
struct tiff_planar_configuration : tiff_property_base< uint16_t, TIFFTAG_PLANARCONFIG > {};
|
||||
|
||||
/// Defines type for gray response unit property.
|
||||
struct tiff_gray_response_unit : tiff_property_base< uint16_t, TIFFTAG_GRAYRESPONSEUNIT > {};
|
||||
|
||||
/// Defines type for gray response curve property.
|
||||
struct tiff_gray_response_curve : tiff_property_base< uint16_t*, TIFFTAG_GRAYRESPONSECURVE > {};
|
||||
|
||||
/// Defines type for software vendor property.
|
||||
struct tiff_software : tiff_property_base< std::string, TIFFTAG_SOFTWARE > {};
|
||||
|
||||
/// Defines type for date time property.
|
||||
struct tiff_date_time : tiff_property_base< std::string, TIFFTAG_DATETIME > {};
|
||||
|
||||
/// Defines type for artist information property.
|
||||
struct tiff_artist : tiff_property_base< std::string, TIFFTAG_ARTIST > {};
|
||||
|
||||
/// Defines type for host computer property.
|
||||
struct tiff_host_computer : tiff_property_base< std::string, TIFFTAG_HOSTCOMPUTER > {};
|
||||
|
||||
/// Helper structure for reading a color mapper.
|
||||
struct tiff_color_map
|
||||
{
|
||||
using red_t = uint16_t *;
|
||||
using green_t = uint16_t *;
|
||||
using blue_t = uint16_t *;
|
||||
|
||||
static const unsigned int tag = TIFFTAG_COLORMAP;
|
||||
};
|
||||
|
||||
/// Defines type for extra samples property.
|
||||
struct tiff_extra_samples : tiff_property_base<std:: vector <uint16_t>, TIFFTAG_EXTRASAMPLES>
|
||||
{
|
||||
using arg_types = mpl::vector<uint16_t, uint16_t const *>;
|
||||
};
|
||||
|
||||
/// Defines type for copyright property.
|
||||
struct tiff_copyright : tiff_property_base< std::string, TIFFTAG_COPYRIGHT > {};
|
||||
|
||||
/// non-baseline tags
|
||||
|
||||
/// Defines type for sample format property.
|
||||
struct tiff_sample_format : tiff_property_base< uint16_t, TIFFTAG_SAMPLEFORMAT > {};
|
||||
|
||||
/// Defines type for indexed property.
|
||||
/// Not supported yet
|
||||
//struct tiff_indexed : tiff_property_base< bool, TIFFTAG_INDEXED > {};
|
||||
|
||||
/// Tile related tags
|
||||
|
||||
/// Defines type for a (not) tiled tiff image
|
||||
struct tiff_is_tiled : tiff_property_base< bool, false > {};
|
||||
|
||||
/// Defines type for tile width
|
||||
struct tiff_tile_width : tiff_property_base< long, TIFFTAG_TILEWIDTH > {};
|
||||
|
||||
/// Defines type for tile length
|
||||
struct tiff_tile_length : tiff_property_base< long, TIFFTAG_TILELENGTH > {};
|
||||
|
||||
/// Defines the page to read in a multipage tiff file.
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
struct tiff_directory : property_base< tdir_t >
|
||||
{
|
||||
using default_value = boost::mpl::integral_c<type, 0>;
|
||||
};
|
||||
|
||||
/// Non-baseline tags
|
||||
|
||||
/// Defines type for icc profile property.
|
||||
struct tiff_icc_profile : tiff_property_base<std::vector<uint8_t>, TIFFTAG_ICCPROFILE>
|
||||
{
|
||||
using arg_types = mpl::vector<uint32_t, void const *>;
|
||||
};
|
||||
|
||||
/// Read information for tiff images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< tiff_tag >
|
||||
{
|
||||
image_read_info()
|
||||
: _width( 0 )
|
||||
, _height( 0 )
|
||||
|
||||
, _compression( COMPRESSION_NONE )
|
||||
|
||||
, _bits_per_sample( 0 )
|
||||
, _samples_per_pixel( 0 )
|
||||
, _sample_format( SAMPLEFORMAT_UINT )
|
||||
|
||||
, _planar_configuration( PLANARCONFIG_CONTIG )
|
||||
|
||||
, _photometric_interpretation( PHOTOMETRIC_MINISWHITE )
|
||||
|
||||
, _is_tiled( false )
|
||||
|
||||
, _tile_width ( 0 )
|
||||
, _tile_length( 0 )
|
||||
|
||||
, _x_resolution( 1 )
|
||||
, _y_resolution( 1 )
|
||||
, _resolution_unit( tiff_resolution_unit_value:: NONE )
|
||||
|
||||
, _icc_profile( )
|
||||
{}
|
||||
|
||||
/// The number of rows of pixels in the image.
|
||||
tiff_image_width::type _width;
|
||||
/// The number of columns in the image, i.e., the number of pixels per row.
|
||||
tiff_image_height::type _height;
|
||||
|
||||
/// Compression scheme used on the image data.
|
||||
tiff_compression::type _compression;
|
||||
|
||||
/// Number of bits per component.
|
||||
tiff_bits_per_sample::type _bits_per_sample;
|
||||
/// The number of components per pixel.
|
||||
tiff_samples_per_pixel::type _samples_per_pixel;
|
||||
/// Specifies how to interpret each data sample in a pixel.
|
||||
tiff_sample_format::type _sample_format;
|
||||
|
||||
/// How the components of each pixel are stored.
|
||||
tiff_planar_configuration::type _planar_configuration;
|
||||
|
||||
/// The color space of the image data.
|
||||
tiff_photometric_interpretation::type _photometric_interpretation;
|
||||
|
||||
/// Is tiled?
|
||||
tiff_is_tiled::type _is_tiled;
|
||||
/// Tile width
|
||||
tiff_tile_width::type _tile_width;
|
||||
/// Tile length
|
||||
tiff_tile_length::type _tile_length;
|
||||
|
||||
tiff_x_resolution::type _x_resolution;
|
||||
tiff_y_resolution::type _y_resolution;
|
||||
tiff_resolution_unit::type _resolution_unit;
|
||||
|
||||
tiff_icc_profile:: type _icc_profile;
|
||||
};
|
||||
|
||||
/// Read settings for tiff images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< tiff_tag > : public image_read_settings_base
|
||||
{
|
||||
/// Default constructor
|
||||
image_read_settings< tiff_tag >()
|
||||
: image_read_settings_base()
|
||||
, _directory( tiff_directory::default_value::value )
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
/// \param directory Defines the page to read in a multipage tiff file.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
, const tiff_directory::type& directory = tiff_directory::default_value::value
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
, _directory( directory )
|
||||
{}
|
||||
|
||||
/// Defines the page to read in a multipage tiff file.
|
||||
tiff_directory::type _directory;
|
||||
};
|
||||
|
||||
/// Write settings for tiff images.
|
||||
///
|
||||
/// The structure can be used for all write_xxx functions, except write_image_info.
|
||||
template< typename Log >
|
||||
struct image_write_info< tiff_tag, Log >
|
||||
{
|
||||
/// Default constructor
|
||||
image_write_info()
|
||||
: _photometric_interpretation ( PHOTOMETRIC_MINISBLACK )
|
||||
, _photometric_interpretation_user_defined( false )
|
||||
|
||||
, _compression ( COMPRESSION_NONE )
|
||||
, _orientation ( ORIENTATION_TOPLEFT )
|
||||
, _planar_configuration ( PLANARCONFIG_CONTIG )
|
||||
, _is_tiled ( false )
|
||||
, _tile_width ( 0 )
|
||||
, _tile_length ( 0 )
|
||||
, _x_resolution ( 1 )
|
||||
, _y_resolution ( 1 )
|
||||
, _resolution_unit ( tiff_resolution_unit_value::NONE )
|
||||
, _icc_profile ( )
|
||||
{}
|
||||
|
||||
/// The color space of the image data.
|
||||
tiff_photometric_interpretation::type _photometric_interpretation;
|
||||
bool _photometric_interpretation_user_defined;
|
||||
|
||||
/// Compression scheme used on the image data.
|
||||
tiff_compression::type _compression;
|
||||
/// The orientation of the image with respect to the rows and columns.
|
||||
tiff_orientation::type _orientation;
|
||||
/// How the components of each pixel are stored.
|
||||
tiff_planar_configuration::type _planar_configuration;
|
||||
|
||||
/// Is the image tiled?
|
||||
tiff_is_tiled::type _is_tiled;
|
||||
/// Tiles width
|
||||
tiff_tile_width::type _tile_width;
|
||||
/// Tiles length
|
||||
tiff_tile_length::type _tile_length;
|
||||
|
||||
/// x, y resolution
|
||||
tiff_x_resolution::type _x_resolution;
|
||||
tiff_y_resolution::type _y_resolution;
|
||||
tiff_resolution_unit::type _resolution_unit;
|
||||
|
||||
tiff_icc_profile:: type _icc_profile;
|
||||
|
||||
/// A log to transcript error and warning messages issued by libtiff.
|
||||
Log _log;
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
macx64/include/boost/gil/extension/io/tiff/write.hpp
Normal file
19
macx64/include/boost/gil/extension/io/tiff/write.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_TIFF_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_TIFF_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/tiff/tags.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/tiff/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user