mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-18 05:08:11 +00:00
Added thirdparty: boost library
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< pnm_tag >& info
|
||||
, std::true_type // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
pnm_image_type::type asc_type = is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>::_asc_type;
|
||||
|
||||
pnm_image_type::type bin_type = is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>::_bin_type;
|
||||
if( info._type == pnm_image_type::mono_asc_t::value )
|
||||
{
|
||||
// ascii mono images are read gray8_image_t
|
||||
return ( asc_type == pnm_image_type::gray_asc_t::value );
|
||||
}
|
||||
|
||||
|
||||
return ( asc_type == info._type
|
||||
|| bin_type == info._type
|
||||
);
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< pnm_tag >& /* info */
|
||||
, std::false_type // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+454
@@ -0,0 +1,454 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/reader_backend.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/is_allowed.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#include <boost/gil/io/detail/dynamic.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/typedefs.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNM Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, pnm_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
, public reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, pnm_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend<Device, pnm_tag>;
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>()
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const cc_t& cc
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
using is_read_and_convert_t = typename std::is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_and_convert_t()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
switch( this->_info._type )
|
||||
{
|
||||
// reading mono text is reading grayscale but with only two values
|
||||
case pnm_image_type::mono_asc_t::value:
|
||||
case pnm_image_type::gray_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
read_text_data< gray8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
read_text_data< rgb8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::mono_bin_t::value:
|
||||
{
|
||||
//gray1_image_t
|
||||
this->_scanline_length = ( this->_info._width + 7 ) >> 3;
|
||||
|
||||
read_bin_data< gray1_image_t::view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::gray_bin_t::value:
|
||||
{
|
||||
// gray8_image_t
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
read_bin_data< gray8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_bin_t::value:
|
||||
{
|
||||
// rgb8_image_t
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
read_bin_data< rgb8_view_t >( view );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_text_data( const View_Dst& dst )
|
||||
{
|
||||
using y_t = typename View_Dst::y_coord_t;
|
||||
|
||||
byte_vector_t row( this->_scanline_length );
|
||||
|
||||
//Skip scanlines if necessary.
|
||||
for( int y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
read_text_row< View_Src >( dst, row, y, false );
|
||||
}
|
||||
|
||||
for( y_t y = 0; y < dst.height(); ++y )
|
||||
{
|
||||
read_text_row< View_Src >( dst, row, y, true );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_text_row( const View_Dst& dst
|
||||
, byte_vector_t& row
|
||||
, typename View_Dst::y_coord_t y
|
||||
, bool process
|
||||
)
|
||||
{
|
||||
View_Src src = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename View_Src::value_type*) &row.front()
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
for( uint32_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
buf[ k++ ] = static_cast< char >( ch );
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
buf[ k ] = 0;
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( process )
|
||||
{
|
||||
int value = atoi( buf );
|
||||
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
using channel_t = typename channel_type<typename get_pixel_type<View_Dst>::type>::type;
|
||||
|
||||
// for pnm format 0 is white
|
||||
row[x] = ( value != 0 )
|
||||
? typename channel_traits< channel_t >::value_type( 0 )
|
||||
: channel_traits< channel_t >::max_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
row[x] = static_cast< byte_t >( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( process )
|
||||
{
|
||||
// We are reading a gray1_image like a gray8_image but the two pixel_t
|
||||
// aren't compatible. Though, read_and_no_convert::read(...) wont work.
|
||||
copy_data< View_Dst
|
||||
, View_Src >( dst
|
||||
, src
|
||||
, y
|
||||
, typename std::is_same< View_Dst
|
||||
, gray1_image_t::view_t
|
||||
>::type()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst
|
||||
, typename View_Src
|
||||
>
|
||||
void copy_data( const View_Dst& dst
|
||||
, const View_Src& src
|
||||
, typename View_Dst::y_coord_t y
|
||||
, std::true_type // is gray1_view
|
||||
)
|
||||
{
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
typename View_Dst::x_iterator it = dst.row_begin( y );
|
||||
|
||||
for( typename View_Dst::x_coord_t x = 0
|
||||
; x < dst.width()
|
||||
; ++x
|
||||
)
|
||||
{
|
||||
it[x] = src[x];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_data(dst, src, y, std::false_type{});
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst
|
||||
, typename View_Src
|
||||
>
|
||||
void copy_data( const View_Dst& view
|
||||
, const View_Src& src
|
||||
, typename View_Dst::y_coord_t y
|
||||
, std::false_type // is gray1_view
|
||||
)
|
||||
{
|
||||
typename View_Src::x_iterator beg = src.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
typename View_Src::x_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_bin_data( const View_Dst& view )
|
||||
{
|
||||
using y_t = typename View_Dst::y_coord_t;
|
||||
using is_bit_aligned_t = typename is_bit_aligned<typename View_Src::value_type>::type;
|
||||
|
||||
using rh_t = detail::row_buffer_helper_view<View_Src>;
|
||||
rh_t rh( this->_scanline_length, true );
|
||||
|
||||
typename rh_t::iterator_t beg = rh.begin() + this->_settings._top_left.x;
|
||||
typename rh_t::iterator_t end = beg + this->_settings._dim.x;
|
||||
|
||||
// For bit_aligned images we need to negate all bytes in the row_buffer
|
||||
// to make sure that 0 is black and 255 is white.
|
||||
detail::negate_bits
|
||||
<
|
||||
typename rh_t::buffer_t,
|
||||
std::integral_constant<bool, is_bit_aligned_t::value> // TODO: Simplify after MPL removal
|
||||
> neg;
|
||||
|
||||
detail::swap_half_bytes
|
||||
<
|
||||
typename rh_t::buffer_t,
|
||||
std::integral_constant<bool, is_bit_aligned_t::value> // TODO: Simplify after MPL removal
|
||||
> swhb;
|
||||
|
||||
//Skip scanlines if necessary.
|
||||
for( y_t y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, this->_scanline_length
|
||||
);
|
||||
}
|
||||
|
||||
for( y_t y = 0; y < view.height(); ++y )
|
||||
{
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
neg( rh.buffer() );
|
||||
swhb( rh.buffer() );
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char buf[16];
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct pnm_type_format_checker
|
||||
{
|
||||
pnm_type_format_checker( pnm_image_type::type type )
|
||||
: _type( type )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
using is_supported_t = is_read_supported
|
||||
<
|
||||
typename get_pixel_type<typename Image::view_t>::type,
|
||||
pnm_tag
|
||||
>;
|
||||
|
||||
return is_supported_t::_asc_type == _type
|
||||
|| is_supported_t::_bin_type == _type;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pnm_image_type::type _type;
|
||||
};
|
||||
|
||||
struct pnm_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// PNM Dynamic Image Reader
|
||||
///
|
||||
template< typename Device
|
||||
>
|
||||
class dynamic_image_reader< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, pnm_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader
|
||||
<
|
||||
Device,
|
||||
pnm_tag,
|
||||
detail::read_and_no_convert
|
||||
>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename ...Images >
|
||||
void apply( any_image< Images... >& images )
|
||||
{
|
||||
detail::pnm_type_format_checker format_checker( this->_info._type );
|
||||
|
||||
if( !detail::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::pnm_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
variant2::visit( op
|
||||
,view( images )
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/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
|
||||
|
||||
///
|
||||
/// PNM Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = pnm_tag;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: _io_dev ( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
|
||||
, _scanline_length( 0 )
|
||||
{
|
||||
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()
|
||||
{
|
||||
// read signature
|
||||
io_error_if( read_char() != 'P', "Invalid PNM signature" );
|
||||
|
||||
_info._type = read_char() - '0';
|
||||
|
||||
io_error_if( _info._type < pnm_image_type::mono_asc_t::value || _info._type > pnm_image_type::color_bin_t::value
|
||||
, "Invalid PNM file (supports P1 to P6)"
|
||||
);
|
||||
|
||||
_info._width = read_int();
|
||||
_info._height = read_int();
|
||||
|
||||
if( _info._type == pnm_image_type::mono_asc_t::value || _info._type == pnm_image_type::mono_bin_t::value )
|
||||
{
|
||||
_info._max_value = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_info._max_value = read_int();
|
||||
|
||||
io_error_if( _info._max_value > 255
|
||||
, "Unsupported PNM format (supports maximum value 255)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( 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( img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Read a character and skip a comment if necessary.
|
||||
char read_char()
|
||||
{
|
||||
char ch;
|
||||
|
||||
if(( ch = _io_dev.getc() ) == '#' )
|
||||
{
|
||||
// skip comment to EOL
|
||||
do
|
||||
{
|
||||
ch = _io_dev.getc();
|
||||
}
|
||||
while (ch != '\n' && ch != '\r');
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
unsigned int read_int()
|
||||
{
|
||||
char ch;
|
||||
|
||||
// skip whitespaces, tabs, and new lines
|
||||
do
|
||||
{
|
||||
ch = read_char();
|
||||
}
|
||||
while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
|
||||
|
||||
if( ch < '0' || ch > '9' )
|
||||
{
|
||||
io_error( "Unexpected characters reading decimal digits" );
|
||||
}
|
||||
|
||||
unsigned val = 0;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned dig = ch - '0';
|
||||
|
||||
if( val > INT_MAX / 10 - dig )
|
||||
{
|
||||
io_error( "Integer too large" );
|
||||
}
|
||||
|
||||
val = val * 10 + dig;
|
||||
|
||||
ch = read_char();
|
||||
}
|
||||
while( '0' <= ch && ch <= '9' );
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< pnm_tag > _settings;
|
||||
image_read_info< pnm_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#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 <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// PNM Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = pnm_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>;
|
||||
|
||||
public:
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: backend_t( device
|
||||
, settings
|
||||
)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
/// Read part of image defined by View and return the data.
|
||||
void read( byte_t* dst
|
||||
, int
|
||||
)
|
||||
{
|
||||
_read_function( this, dst );
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t*, int )
|
||||
{
|
||||
_skip_function( this );
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
switch( this->_info._type )
|
||||
{
|
||||
// reading mono text is reading grayscale but with only two values
|
||||
case pnm_image_type::mono_asc_t::value:
|
||||
case pnm_image_type::gray_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_text_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_text_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_text_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_text_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case pnm_image_type::mono_bin_t::value:
|
||||
{
|
||||
//gray1_image_t
|
||||
this->_scanline_length = ( this->_info._width + 7 ) >> 3;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_bit_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::gray_bin_t::value:
|
||||
{
|
||||
// gray8_image_t
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_byte_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_bin_t::value:
|
||||
{
|
||||
// rgb8_image_t
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_byte_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Unsupported pnm file." ); break; }
|
||||
}
|
||||
}
|
||||
|
||||
void read_text_row( byte_t* dst )
|
||||
{
|
||||
for( std::size_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
_text_buffer[ k++ ] = static_cast< char >( ch );
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
_text_buffer[ k ] = 0;
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int value = atoi( _text_buffer );
|
||||
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
// for pnm format 0 is white
|
||||
dst[x] = ( value != 0 )
|
||||
? 0
|
||||
: 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[x] = static_cast< byte_t >( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void skip_text_row()
|
||||
{
|
||||
for( std::size_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
k++;
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void read_binary_bit_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
_negate_bits ( dst, this->_scanline_length );
|
||||
_swap_half_bytes( dst, this->_scanline_length );
|
||||
|
||||
}
|
||||
|
||||
void read_binary_byte_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst
|
||||
, this->_scanline_length
|
||||
);
|
||||
}
|
||||
|
||||
void skip_binary_row()
|
||||
{
|
||||
this->_io_dev.seek( static_cast<long>( this->_scanline_length ), SEEK_CUR );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char _text_buffer[16];
|
||||
|
||||
// For bit_aligned images we need to negate all bytes in the row_buffer
|
||||
// to make sure that 0 is black and 255 is white.
|
||||
detail::negate_bits<std::vector<byte_t>, std::true_type> _negate_bits;
|
||||
detail::swap_half_bytes<std::vector<byte_t>, std::true_type> _swap_half_bytes;
|
||||
|
||||
std::function<void(this_t*, byte_t*)> _read_function;
|
||||
std::function<void(this_t*)> _skip_function;
|
||||
};
|
||||
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// Copyright 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_PNM_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
// Read Support
|
||||
|
||||
template< pnm_image_type::type ASCII_Type
|
||||
, pnm_image_type::type Binary_Type
|
||||
>
|
||||
struct pnm_rw_support_base
|
||||
{
|
||||
static const pnm_image_type::type _asc_type = ASCII_Type;
|
||||
static const pnm_image_type::type _bin_type = Binary_Type;
|
||||
};
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct pnm_read_support : read_support_false
|
||||
, pnm_rw_support_base< 0
|
||||
, 0
|
||||
> {};
|
||||
|
||||
template< typename BitField, bool Mutable >
|
||||
struct pnm_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::mono_asc_t::value
|
||||
, pnm_image_type::mono_bin_t::value
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct pnm_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::gray_asc_t::value
|
||||
, pnm_image_type::gray_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::color_asc_t::value
|
||||
, pnm_image_type::color_bin_t::value
|
||||
> {};
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct pnm_write_support : write_support_false
|
||||
{};
|
||||
|
||||
template< typename BitField, bool Mutable >
|
||||
struct pnm_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::mono_asc_t::value
|
||||
, pnm_image_type::mono_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_write_support<uint8_t
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::gray_asc_t::value
|
||||
, pnm_image_type::gray_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::color_asc_t::value
|
||||
, pnm_image_type::color_bin_t::value
|
||||
> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename Pixel>
|
||||
struct is_read_supported<Pixel, pnm_tag>
|
||||
: std::integral_constant
|
||||
<
|
||||
bool,
|
||||
detail::pnm_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::pnm_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const pnm_image_type::type _asc_type = parent_t::_asc_type;
|
||||
static const pnm_image_type::type _bin_type = parent_t::_bin_type;
|
||||
};
|
||||
|
||||
template<typename Pixel>
|
||||
struct is_write_supported<Pixel, pnm_tag>
|
||||
: std::integral_constant
|
||||
<
|
||||
bool,
|
||||
detail::pnm_write_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>::is_supported
|
||||
>
|
||||
{};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/detail/dynamic.hpp>
|
||||
#include <boost/gil/detail/mp11.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
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 {
|
||||
|
||||
struct pnm_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// PNM Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
using backend_t = writer_backend<Device, pnm_tag>;
|
||||
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename View >
|
||||
void apply( const View& view )
|
||||
{
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
|
||||
std::size_t width = view.width();
|
||||
std::size_t height = view.height();
|
||||
|
||||
std::size_t chn = num_channels< View >::value;
|
||||
std::size_t pitch = chn * width;
|
||||
|
||||
unsigned int type = get_type< num_channels< View >::value >( is_bit_aligned< pixel_t >() );
|
||||
|
||||
// write header
|
||||
|
||||
// Add a white space at each string so read_int() can decide when a numbers ends.
|
||||
|
||||
std::string str( "P" );
|
||||
str += std::to_string( type ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
str.clear();
|
||||
str += std::to_string( width ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
str.clear();
|
||||
str += std::to_string( height ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
if( type != pnm_image_type::mono_bin_t::value )
|
||||
{
|
||||
this->_io_dev.print_line( "255 ");
|
||||
}
|
||||
|
||||
// write data
|
||||
write_data( view
|
||||
, pitch
|
||||
, typename is_bit_aligned< pixel_t >::type()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< int Channels >
|
||||
unsigned int get_type( std::true_type /* is_bit_aligned */ )
|
||||
{
|
||||
return mp11::mp_if_c
|
||||
<
|
||||
Channels == 1,
|
||||
pnm_image_type::mono_bin_t,
|
||||
pnm_image_type::color_bin_t
|
||||
>::value;
|
||||
}
|
||||
|
||||
template< int Channels >
|
||||
unsigned int get_type( std::false_type /* is_bit_aligned */ )
|
||||
{
|
||||
return mp11::mp_if_c
|
||||
<
|
||||
Channels == 1,
|
||||
pnm_image_type::gray_bin_t,
|
||||
pnm_image_type::color_bin_t
|
||||
>::value;
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& src
|
||||
, std::size_t pitch
|
||||
, const std::true_type& // bit_aligned
|
||||
)
|
||||
{
|
||||
static_assert(std::is_same<View, typename gray1_image_t::view_t>::value, "");
|
||||
|
||||
byte_vector_t row( pitch / 8 );
|
||||
|
||||
using x_it_t = typename View::x_iterator;
|
||||
x_it_t row_it = x_it_t( &( *row.begin() ));
|
||||
|
||||
detail::negate_bits<byte_vector_t, std::true_type> negate;
|
||||
detail::mirror_bits<byte_vector_t, std::true_type> mirror;
|
||||
for (typename View::y_coord_t y = 0; y < src.height(); ++y)
|
||||
{
|
||||
std::copy(src.row_begin(y), src.row_end(y), row_it);
|
||||
|
||||
mirror(row);
|
||||
negate(row);
|
||||
|
||||
this->_io_dev.write(&row.front(), pitch / 8);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& src
|
||||
, std::size_t pitch
|
||||
, const std::false_type& // bit_aligned
|
||||
)
|
||||
{
|
||||
std::vector< pixel< typename channel_type< View >::type
|
||||
, layout<typename color_space_type< View >::type >
|
||||
>
|
||||
> buf( src.width() );
|
||||
|
||||
// using pixel_t = typename View::value_type;
|
||||
// using view_t = typename view_type_from_pixel< pixel_t >::type;
|
||||
|
||||
//view_t row = interleaved_view( src.width()
|
||||
// , 1
|
||||
// , reinterpret_cast< pixel_t* >( &buf.front() )
|
||||
// , pitch
|
||||
// );
|
||||
|
||||
byte_t* row_addr = reinterpret_cast< byte_t* >( &buf.front() );
|
||||
|
||||
for( typename View::y_coord_t y = 0
|
||||
; y < src.height()
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
//copy_pixels( subimage_view( src
|
||||
// , 0
|
||||
// , (int) y
|
||||
// , (int) src.width()
|
||||
// , 1
|
||||
// )
|
||||
// , row
|
||||
// );
|
||||
|
||||
std::copy( src.row_begin( y )
|
||||
, src.row_end ( y )
|
||||
, buf.begin()
|
||||
);
|
||||
|
||||
this->_io_dev.write( row_addr, pitch );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// PNM Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, pnm_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename ...Views >
|
||||
void apply( const any_image_view< Views... >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::pnm_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
variant2::visit( op, views );
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// 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_PNM_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/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
|
||||
|
||||
///
|
||||
/// PNM Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = pnm_tag;
|
||||
|
||||
public:
|
||||
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info( info )
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< pnm_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Copyright 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_PNM_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Returns the width and height of the PNM file at the specified location.
|
||||
/// Throws std::ios_base::failure if the location does not correspond to a valid PNM file
|
||||
template<typename String>
|
||||
inline point_t pnm_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, pnm_tag>::type;
|
||||
backend_t backend = read_image_info(filename, pnm_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads the image specified by the given pnm image file name into the given view.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNM library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM 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 pnm_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm 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 PNM library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM 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 pnm_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads and color-converts the image specified by the given pnm image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads and color-converts the image specified by the given pnm image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file
|
||||
template< typename String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Saves the view to a pnm file specified by the given pnm image file name.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNM 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 pnm_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 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_PNM_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/scanline_read.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
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright 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_PNM_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_TAGS_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines pnm tag.
|
||||
struct pnm_tag : format_tag {};
|
||||
|
||||
/// see http://en.wikipedia.org/wiki/Portable_Bitmap_File_Format for reference
|
||||
|
||||
/// Defines type for image type property.
|
||||
struct pnm_image_type : property_base< uint32_t >
|
||||
{
|
||||
using mono_asc_t = std::integral_constant<type, 1>;
|
||||
using gray_asc_t = std::integral_constant<type, 2>;
|
||||
using color_asc_t = std::integral_constant<type, 3>;
|
||||
|
||||
using mono_bin_t = std::integral_constant<type, 4>;
|
||||
using gray_bin_t = std::integral_constant<type, 5>;
|
||||
using color_bin_t = std::integral_constant<type, 6>;
|
||||
};
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct pnm_image_width : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct pnm_image_height : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for image max value property.
|
||||
struct pnm_image_max_value : property_base< uint32_t > {};
|
||||
|
||||
/// Read information for pnm images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< pnm_tag >
|
||||
{
|
||||
/// The image type.
|
||||
pnm_image_type::type _type;
|
||||
/// The image width.
|
||||
pnm_image_width::type _width;
|
||||
/// The image height.
|
||||
pnm_image_height::type _height;
|
||||
/// The image max value.
|
||||
pnm_image_max_value::type _max_value;
|
||||
};
|
||||
|
||||
/// Read settings for pnm images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< pnm_tag > : public image_read_settings_base
|
||||
{
|
||||
/// Default constructor
|
||||
image_read_settings()
|
||||
: image_read_settings_base()
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
image_read_settings( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
/// Write information for pnm images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< pnm_tag >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 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_PNM_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/pnm/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