add boost on mac
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// 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_BMP_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/channel.hpp>
|
||||
|
||||
#include <boost/mpl/bool_fwd.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< bmp_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
bmp_bits_per_pixel::type src_bits_per_pixel = 0;
|
||||
|
||||
switch( info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
{
|
||||
if( info._header_size == bmp_header_size::_win32_info_size
|
||||
&& info._compression != bmp_compression::_rle8
|
||||
&& info._compression != bmp_compression::_rle4
|
||||
)
|
||||
{
|
||||
src_bits_per_pixel = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_bits_per_pixel = 24;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
src_bits_per_pixel = 24;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
src_bits_per_pixel = info._bits_per_pixel;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
io_error( "Pixel size not supported." );
|
||||
}
|
||||
}
|
||||
|
||||
using channel_t = typename channel_traits<typename element_type<typename View::value_type>::type>::value_type;
|
||||
bmp_bits_per_pixel::type dst_bits_per_pixel = detail::unsigned_integral_num_bits< channel_t >::value
|
||||
* num_channels< View >::value;
|
||||
|
||||
return ( dst_bits_per_pixel == src_bits_per_pixel );
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< bmp_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
743
macx64/include/boost/gil/extension/io/bmp/detail/read.hpp
Normal file
743
macx64/include/boost/gil/extension/io/bmp/detail/read.hpp
Normal file
@@ -0,0 +1,743 @@
|
||||
//
|
||||
// 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_BMP_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/bmp/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/gil/io/typedefs.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/is_same.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
|
||||
|
||||
///
|
||||
/// BMP Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, bmp_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< bmp_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
, public reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, bmp_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend< Device, bmp_tag>;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
, _pitch( 0 )
|
||||
{}
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const ConversionPolicy& cc
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: reader_base< bmp_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
, _pitch( 0 )
|
||||
{}
|
||||
|
||||
|
||||
/// Read image.
|
||||
template< typename View >
|
||||
void apply( const View& dst_view )
|
||||
{
|
||||
if( this->_info._valid == false )
|
||||
{
|
||||
io_error( "Image header was not read." );
|
||||
}
|
||||
|
||||
using is_read_and_convert_t = typename 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."
|
||||
);
|
||||
|
||||
// the row pitch must be multiple 4 bytes
|
||||
if( this->_info._bits_per_pixel < 8 )
|
||||
{
|
||||
_pitch = static_cast<long>((( this->_info._width * this->_info._bits_per_pixel ) + 7 ) >> 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
_pitch = static_cast<long>( this->_info._width * (( this->_info._bits_per_pixel + 7 ) >> 3 ));
|
||||
}
|
||||
|
||||
_pitch = (_pitch + 3) & ~3;
|
||||
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image
|
||||
<
|
||||
gray1_image_t::view_t,
|
||||
detail::mirror_bits<byte_vector_t, std::true_type>
|
||||
>(dst_view);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch ( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle4:
|
||||
{
|
||||
///@todo How can we determine that?
|
||||
this->_scanline_length = 0;
|
||||
|
||||
read_palette_image_rle( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image
|
||||
<
|
||||
gray4_image_t::view_t,
|
||||
detail::swap_half_bytes<byte_vector_t, std::true_type>
|
||||
>(dst_view);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
switch ( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle8:
|
||||
{
|
||||
///@todo How can we determine that?
|
||||
this->_scanline_length = 0;
|
||||
|
||||
read_palette_image_rle( dst_view );
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image< gray8_image_t::view_t
|
||||
, detail::do_nothing< std::vector< gray8_pixel_t > >
|
||||
> ( dst_view );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15: case 16:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data_15( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data< bgr8_view_t >( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data< bgra8_view_t >( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
long get_offset( std::ptrdiff_t pos )
|
||||
{
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
// the image is upside down
|
||||
return static_cast<long>( ( this->_info._offset
|
||||
+ ( this->_info._height - 1 - pos ) * _pitch
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<long>( ( this->_info._offset
|
||||
+ pos * _pitch
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Src
|
||||
, typename Byte_Manipulator
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_palette_image( const View_Dst& view )
|
||||
{
|
||||
this->read_palette();
|
||||
|
||||
using rh_t = detail::row_buffer_helper_view<View_Src>;
|
||||
using it_t = typename rh_t::iterator_t;
|
||||
|
||||
rh_t rh( _pitch, true );
|
||||
|
||||
// we have to swap bits
|
||||
Byte_Manipulator byte_manipulator;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, _pitch
|
||||
);
|
||||
|
||||
byte_manipulator( rh.buffer() );
|
||||
|
||||
typename View_Dst::x_iterator dst_it = view.row_begin( y );
|
||||
|
||||
it_t it = rh.begin() + this->_settings._top_left.x;
|
||||
it_t end = it + this->_settings._dim.x;
|
||||
|
||||
for( ; it != end; ++it, ++dst_it )
|
||||
{
|
||||
unsigned char c = get_color( *it, gray_color_t() );
|
||||
*dst_it = this->_palette[ c ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void read_data_15( const View& view )
|
||||
{
|
||||
byte_vector_t row( _pitch );
|
||||
|
||||
// read the color masks
|
||||
if( this->_info._compression == bmp_compression::_bitfield )
|
||||
{
|
||||
this->_mask.red.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.green.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.blue.mask = this->_io_dev.read_uint32();
|
||||
|
||||
this->_mask.red.width = detail::count_ones( this->_mask.red.mask );
|
||||
this->_mask.green.width = detail::count_ones( this->_mask.green.mask );
|
||||
this->_mask.blue.width = detail::count_ones( this->_mask.blue.mask );
|
||||
|
||||
this->_mask.red.shift = detail::trailing_zeros( this->_mask.red.mask );
|
||||
this->_mask.green.shift = detail::trailing_zeros( this->_mask.green.mask );
|
||||
this->_mask.blue.shift = detail::trailing_zeros( this->_mask.blue.mask );
|
||||
}
|
||||
else if( this->_info._compression == bmp_compression::_rgb )
|
||||
{
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_mask.red.mask = 0x007C00; this->_mask.red.width = 5; this->_mask.red.shift = 10;
|
||||
this->_mask.green.mask = 0x0003E0; this->_mask.green.width = 5; this->_mask.green.shift = 5;
|
||||
this->_mask.blue.mask = 0x00001F; this->_mask.blue.width = 5; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
this->_mask.red.mask = 0xFF0000; this->_mask.red.width = 8; this->_mask.red.shift = 16;
|
||||
this->_mask.green.mask = 0x00FF00; this->_mask.green.width = 8; this->_mask.green.shift = 8;
|
||||
this->_mask.blue.mask = 0x0000FF; this->_mask.blue.width = 8; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "bmp_reader::apply(): unsupported BMP compression" );
|
||||
}
|
||||
|
||||
using image_t = rgb8_image_t;
|
||||
using it_t = typename image_t::view_t::x_iterator;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( &row.front()
|
||||
, row.size()
|
||||
);
|
||||
|
||||
image_t img_row( this->_info._width, 1 );
|
||||
image_t::view_t v = gil::view( img_row );
|
||||
it_t it = v.row_begin( 0 );
|
||||
|
||||
it_t beg = v.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
it_t end = beg + this->_settings._dim.x;
|
||||
|
||||
byte_t* src = &row.front();
|
||||
for( int32_t i = 0 ; i < this->_info._width; ++i, src += 2 )
|
||||
{
|
||||
int p = ( src[1] << 8 ) | src[0];
|
||||
|
||||
int r = ((p & this->_mask.red.mask) >> this->_mask.red.shift) << (8 - this->_mask.red.width);
|
||||
int g = ((p & this->_mask.green.mask) >> this->_mask.green.shift) << (8 - this->_mask.green.width);
|
||||
int b = ((p & this->_mask.blue.mask) >> this->_mask.blue.shift) << (8 - this->_mask.blue.width);
|
||||
|
||||
get_color( it[i], red_t() ) = static_cast< byte_t >( r );
|
||||
get_color( it[i], green_t() ) = static_cast< byte_t >( g );
|
||||
get_color( it[i], blue_t() ) = static_cast< byte_t >( b );
|
||||
}
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 8-8-8 BGR
|
||||
// 8-8-8-8 BGRA
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_data( const View_Dst& view )
|
||||
{
|
||||
byte_vector_t row( _pitch );
|
||||
|
||||
View_Src v = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename View_Src::value_type*) &row.front()
|
||||
, this->_info._width * num_channels< View_Src >::value
|
||||
);
|
||||
|
||||
typename View_Src::x_iterator beg = v.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
typename View_Src::x_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( &row.front()
|
||||
, row.size()
|
||||
);
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void copy_row_if_needed( const Buffer& buf
|
||||
, const View& view
|
||||
, std::ptrdiff_t y
|
||||
)
|
||||
{
|
||||
if( y >= this->_settings._top_left.y
|
||||
&& y < this->_settings._dim.y
|
||||
)
|
||||
{
|
||||
typename Buffer::const_iterator beg = buf.begin() + this->_settings._top_left.x;
|
||||
typename Buffer::const_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
std::copy( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst >
|
||||
void read_palette_image_rle( const View_Dst& view )
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
this->_info._compression == bmp_compression::_rle4 ||
|
||||
this->_info._compression == bmp_compression::_rle8);
|
||||
|
||||
this->read_palette();
|
||||
|
||||
// jump to start of rle4 data
|
||||
this->_io_dev.seek( this->_info._offset );
|
||||
|
||||
// we need to know the stream position for padding purposes
|
||||
std::size_t stream_pos = this->_info._offset;
|
||||
|
||||
using Buf_type = std::vector<rgba8_pixel_t>;
|
||||
Buf_type buf( this->_settings._dim.x );
|
||||
Buf_type::iterator dst_it = buf.begin();
|
||||
Buf_type::iterator dst_end = buf.end();
|
||||
|
||||
// If height is positive, the bitmap is a bottom-up DIB.
|
||||
// If height is negative, the bitmap is a top-down DIB.
|
||||
// The origin of a bottom-up DIB is the bottom left corner of the bitmap image,
|
||||
// which is the first pixel of the first row of bitmap data.
|
||||
// The origin of a top-down DIB is also the bottom left corner of the bitmap image,
|
||||
// but in this case the bottom left corner is the first pixel of the last row of bitmap data.
|
||||
// - "Programming Windows", 5th Ed. by Charles Petzold explains Windows docs ambiguities.
|
||||
std::ptrdiff_t ybeg = 0;
|
||||
std::ptrdiff_t yend = this->_settings._dim.y;
|
||||
std::ptrdiff_t yinc = 1;
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
ybeg = this->_settings._dim.y - 1;
|
||||
yend = -1;
|
||||
yinc = -1;
|
||||
}
|
||||
|
||||
std::ptrdiff_t y = ybeg;
|
||||
bool finished = false;
|
||||
|
||||
while ( !finished )
|
||||
{
|
||||
std::ptrdiff_t count = this->_io_dev.read_uint8();
|
||||
std::ptrdiff_t second = this->_io_dev.read_uint8();
|
||||
stream_pos += 2;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
// encoded mode
|
||||
|
||||
// clamp to boundary
|
||||
if( count > dst_end - dst_it )
|
||||
{
|
||||
count = dst_end - dst_it;
|
||||
}
|
||||
|
||||
if( this->_info._compression == bmp_compression::_rle4 )
|
||||
{
|
||||
std::ptrdiff_t cs[2] = { second >> 4, second & 0x0f };
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
*dst_it++ = this->_palette[ cs[i & 1] ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
*dst_it++ = this->_palette[ second ];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( second )
|
||||
{
|
||||
case 0: // end of row
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
|
||||
y += yinc;
|
||||
if( y == yend )
|
||||
{
|
||||
finished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_it = buf.begin();
|
||||
dst_end = buf.end();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // end of bitmap
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
finished = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // offset coordinates
|
||||
{
|
||||
std::ptrdiff_t dx = this->_io_dev.read_uint8();
|
||||
std::ptrdiff_t dy = this->_io_dev.read_uint8() * yinc;
|
||||
stream_pos += 2;
|
||||
|
||||
if( dy )
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
}
|
||||
|
||||
std::ptrdiff_t x = dst_it - buf.begin();
|
||||
x += dx;
|
||||
|
||||
if( x > this->_info._width )
|
||||
{
|
||||
io_error( "Mangled BMP file." );
|
||||
}
|
||||
|
||||
y += dy;
|
||||
if( yinc > 0 ? y > yend : y < yend )
|
||||
{
|
||||
io_error( "Mangled BMP file." );
|
||||
}
|
||||
|
||||
dst_it = buf.begin() + x;
|
||||
dst_end = buf.end();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: // absolute mode
|
||||
{
|
||||
count = second;
|
||||
|
||||
// clamp to boundary
|
||||
if( count > dst_end - dst_it )
|
||||
{
|
||||
count = dst_end - dst_it;
|
||||
}
|
||||
|
||||
if ( this->_info._compression == bmp_compression::_rle4 )
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
uint8_t packed_indices = this->_io_dev.read_uint8();
|
||||
++stream_pos;
|
||||
|
||||
*dst_it++ = this->_palette[ packed_indices >> 4 ];
|
||||
if( ++i == second )
|
||||
break;
|
||||
|
||||
*dst_it++ = this->_palette[ packed_indices & 0x0f ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
uint8_t c = this->_io_dev.read_uint8();
|
||||
++stream_pos;
|
||||
*dst_it++ = this->_palette[ c ];
|
||||
}
|
||||
}
|
||||
|
||||
// pad to word boundary
|
||||
if( ( stream_pos - get_offset( 0 )) & 1 )
|
||||
{
|
||||
this->_io_dev.seek( 1, SEEK_CUR );
|
||||
++stream_pos;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::size_t _pitch;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
class bmp_type_format_checker
|
||||
{
|
||||
public:
|
||||
|
||||
bmp_type_format_checker( const bmp_bits_per_pixel::type& bpp )
|
||||
: _bpp( bpp )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
if( _bpp < 32 )
|
||||
{
|
||||
return pixels_are_compatible< typename Image::value_type, rgb8_pixel_t >::value
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pixels_are_compatible< typename Image::value_type, rgba8_pixel_t >::value
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// to avoid C4512
|
||||
bmp_type_format_checker& operator=( const bmp_type_format_checker& ) { return *this; }
|
||||
|
||||
private:
|
||||
|
||||
const bmp_bits_per_pixel::type _bpp;
|
||||
};
|
||||
|
||||
struct bmp_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, bmp_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// BMP Dynamic Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_reader< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, bmp_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader<Device, bmp_tag, detail::read_and_no_convert>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::bmp_type_format_checker format_checker( this->_info._bits_per_pixel );
|
||||
|
||||
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::bmp_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -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_BMP_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/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
|
||||
|
||||
/// Color channel mask
|
||||
struct bit_field
|
||||
{
|
||||
unsigned int mask; // Bit mask at corresponding position
|
||||
unsigned int width; // Bit width of the mask
|
||||
unsigned int shift; // Bit position from right to left
|
||||
};
|
||||
|
||||
/// BMP color masks
|
||||
struct color_mask
|
||||
{
|
||||
bit_field red; // Red bits
|
||||
bit_field green; // Green bits
|
||||
bit_field blue; // Blue bits
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// BMP Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = bmp_tag;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: _io_dev ( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
, _scanline_length( 0 )
|
||||
, _palette()
|
||||
{
|
||||
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()
|
||||
{
|
||||
// the magic number used to identify the BMP file:
|
||||
// 0x42 0x4D (ASCII code points for B and M)
|
||||
if( _io_dev.read_uint16() == 0x424D )
|
||||
{
|
||||
io_error( "Wrong magic number for bmp file." );
|
||||
}
|
||||
|
||||
// the size of the BMP file in bytes
|
||||
_io_dev.read_uint32();
|
||||
|
||||
// reserved; actual value depends on the application that creates the image
|
||||
_io_dev.read_uint16();
|
||||
// reserved; actual value depends on the application that creates the image
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._offset = _io_dev.read_uint32();
|
||||
|
||||
|
||||
// bitmap information
|
||||
|
||||
// the size of this header ( 40 bytes )
|
||||
_info._header_size = _io_dev.read_uint32();
|
||||
|
||||
if( _info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
_info._width = _io_dev.read_uint32();
|
||||
_info._height = _io_dev.read_uint32();
|
||||
|
||||
if (_info._height < 0)
|
||||
{
|
||||
_info._height = -_info._height;
|
||||
_info._top_down = true;
|
||||
}
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = _io_dev.read_uint32();
|
||||
|
||||
_info._image_size = _io_dev.read_uint32();
|
||||
|
||||
_info._horizontal_resolution = _io_dev.read_uint32();
|
||||
_info._vertical_resolution = _io_dev.read_uint32();
|
||||
|
||||
_info._num_colors = _io_dev.read_uint32();
|
||||
_info._num_important_colors = _io_dev.read_uint32();
|
||||
|
||||
}
|
||||
else if( _info._header_size == bmp_header_size::_os2_info_size )
|
||||
{
|
||||
_info._width = static_cast< bmp_image_width::type >( _io_dev.read_uint16() );
|
||||
_info._height = static_cast< bmp_image_height::type >( _io_dev.read_uint16() );
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = bmp_compression::_rgb;
|
||||
|
||||
// not used
|
||||
_info._image_size = 0;
|
||||
_info._horizontal_resolution = 0;
|
||||
_info._vertical_resolution = 0;
|
||||
_info._num_colors = 0;
|
||||
_info._num_important_colors = 0;
|
||||
}
|
||||
else if (_info._header_size > bmp_header_size::_win32_info_size)
|
||||
{
|
||||
// could be v4 or v5
|
||||
// see MSDN: Bitmap Header Types ( BITMAPV4HEADER or BITMAPV5HEADER )
|
||||
|
||||
_info._width = _io_dev.read_uint32();
|
||||
_info._height = _io_dev.read_uint32();
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = _io_dev.read_uint32();
|
||||
|
||||
_info._image_size = _io_dev.read_uint32();
|
||||
|
||||
_info._horizontal_resolution = _io_dev.read_uint32();
|
||||
_info._vertical_resolution = _io_dev.read_uint32();
|
||||
|
||||
_info._num_colors = _io_dev.read_uint32();
|
||||
_info._num_important_colors = _io_dev.read_uint32();
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Invalid BMP info header." );
|
||||
}
|
||||
|
||||
_info._valid = true;
|
||||
}
|
||||
|
||||
void read_palette()
|
||||
{
|
||||
int entries = this->_info._num_colors;
|
||||
|
||||
if( entries == 0 )
|
||||
{
|
||||
entries = 1u << this->_info._bits_per_pixel;
|
||||
}
|
||||
|
||||
_palette.resize( entries, rgba8_pixel_t(0, 0, 0, 0));
|
||||
|
||||
for( int i = 0; i < entries; ++i )
|
||||
{
|
||||
get_color( _palette[i], blue_t() ) = _io_dev.read_uint8();
|
||||
get_color( _palette[i], green_t() ) = _io_dev.read_uint8();
|
||||
get_color( _palette[i], red_t() ) = _io_dev.read_uint8();
|
||||
|
||||
// there are 4 entries when windows header
|
||||
// but 3 for os2 header
|
||||
if( _info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
_io_dev.read_uint8();
|
||||
}
|
||||
|
||||
} // for
|
||||
}
|
||||
|
||||
/// 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( 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" ); }
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< bmp_tag > _settings;
|
||||
image_read_info< bmp_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
|
||||
///@todo make it an image.
|
||||
std::vector< rgba8_pixel_t > _palette;
|
||||
|
||||
color_mask _mask;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,414 @@
|
||||
//
|
||||
// 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_BMP_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/bmp/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 <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// BMP Scanline Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = bmp_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:
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: backend_t( device
|
||||
, settings
|
||||
)
|
||||
|
||||
, _pitch( 0 )
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
/// Read part of image defined by View and return the data.
|
||||
void read( byte_t* dst, int pos )
|
||||
{
|
||||
// jump to scanline
|
||||
long offset = 0;
|
||||
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
// the image is upside down
|
||||
offset = this->_info._offset
|
||||
+ ( this->_info._height - 1 - pos ) * this->_pitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = this->_info._offset
|
||||
+ pos * _pitch;
|
||||
}
|
||||
|
||||
this->_io_dev.seek( offset );
|
||||
|
||||
|
||||
// read data
|
||||
_read_function(this, dst);
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t*, int )
|
||||
{
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
if( this->_info._bits_per_pixel < 8 )
|
||||
{
|
||||
_pitch = (( this->_info._width * this->_info._bits_per_pixel ) + 7 ) >> 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pitch = this->_info._width * (( this->_info._bits_per_pixel + 7 ) >> 3);
|
||||
}
|
||||
|
||||
_pitch = (_pitch + 3) & ~3;
|
||||
|
||||
//
|
||||
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_1_bit_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle4:
|
||||
{
|
||||
io_error( "Cannot read run-length encoded images in iterator mode. Try to read as whole image." );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb :
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_4_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
switch( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle8:
|
||||
{
|
||||
io_error( "Cannot read run-length encoded images in iterator mode. Try to read as whole image." );
|
||||
|
||||
break;
|
||||
}
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_8_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Unsupported compression mode in BMP file." ); break; }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
if( this->_info._compression == bmp_compression::_bitfield )
|
||||
{
|
||||
this->_mask.red.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.green.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.blue.mask = this->_io_dev.read_uint32();
|
||||
|
||||
this->_mask.red.width = detail::count_ones( this->_mask.red.mask );
|
||||
this->_mask.green.width = detail::count_ones( this->_mask.green.mask );
|
||||
this->_mask.blue.width = detail::count_ones( this->_mask.blue.mask );
|
||||
|
||||
this->_mask.red.shift = detail::trailing_zeros( this->_mask.red.mask );
|
||||
this->_mask.green.shift = detail::trailing_zeros( this->_mask.green.mask );
|
||||
this->_mask.blue.shift = detail::trailing_zeros( this->_mask.blue.mask );
|
||||
}
|
||||
else if( this->_info._compression == bmp_compression::_rgb )
|
||||
{
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_mask.red.mask = 0x007C00; this->_mask.red.width = 5; this->_mask.red.shift = 10;
|
||||
this->_mask.green.mask = 0x0003E0; this->_mask.green.width = 5; this->_mask.green.shift = 5;
|
||||
this->_mask.blue.mask = 0x00001F; this->_mask.blue.width = 5; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
this->_mask.red.mask = 0xFF0000; this->_mask.red.width = 8; this->_mask.red.shift = 16;
|
||||
this->_mask.green.mask = 0x00FF00; this->_mask.green.width = 8; this->_mask.green.shift = 8;
|
||||
this->_mask.blue.mask = 0x0000FF; this->_mask.blue.width = 8; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Unsupported BMP compression." );
|
||||
}
|
||||
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_15_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
_read_function = std::mem_fn(&this_t::read_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
_read_function = std::mem_fn(&this_t::read_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported bits per pixel." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_palette()
|
||||
{
|
||||
if( this->_palette.size() > 0 )
|
||||
{
|
||||
// palette has been read already.
|
||||
return;
|
||||
}
|
||||
|
||||
int entries = this->_info._num_colors;
|
||||
|
||||
if( entries == 0 )
|
||||
{
|
||||
entries = 1u << this->_info._bits_per_pixel;
|
||||
}
|
||||
|
||||
this->_palette.resize( entries, rgba8_pixel_t(0,0,0,0) );
|
||||
|
||||
for( int i = 0; i < entries; ++i )
|
||||
{
|
||||
get_color( this->_palette[i], blue_t() ) = this->_io_dev.read_uint8();
|
||||
get_color( this->_palette[i], green_t() ) = this->_io_dev.read_uint8();
|
||||
get_color( this->_palette[i], red_t() ) = this->_io_dev.read_uint8();
|
||||
|
||||
// there are 4 entries when windows header
|
||||
// but 3 for os2 header
|
||||
if( this->_info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
this->_io_dev.read_uint8();
|
||||
}
|
||||
|
||||
} // for
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void read_bit_row( byte_t* dst )
|
||||
{
|
||||
using src_view_t = View;
|
||||
using dst_view_t = rgba8_image_t::view_t;
|
||||
|
||||
src_view_t src_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename src_view_t::x_iterator) &_buffer.front()
|
||||
, this->_pitch
|
||||
);
|
||||
|
||||
dst_view_t dst_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename dst_view_t::value_type*) dst
|
||||
, num_channels< dst_view_t >::value * this->_info._width
|
||||
);
|
||||
|
||||
|
||||
typename src_view_t::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++
|
||||
)
|
||||
{
|
||||
unsigned char c = get_color( *src_it, gray_color_t() );
|
||||
*dst_it = this->_palette[c];
|
||||
}
|
||||
}
|
||||
|
||||
// Read 1 bit image. The colors are encoded by an index.
|
||||
void read_1_bit_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
_mirror_bits( _buffer );
|
||||
|
||||
read_bit_row< gray1_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
// Read 4 bits image. The colors are encoded by an index.
|
||||
void read_4_bits_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
_swap_half_bytes( _buffer );
|
||||
|
||||
read_bit_row< gray4_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
/// Read 8 bits image. The colors are encoded by an index.
|
||||
void read_8_bits_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
|
||||
read_bit_row< gray8_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
/// Read 15 or 16 bits image.
|
||||
void read_15_bits_row( byte_t* dst )
|
||||
{
|
||||
using dst_view_t = rgb8_view_t;
|
||||
|
||||
dst_view_t dst_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename dst_view_t::value_type*) dst
|
||||
, this->_pitch
|
||||
);
|
||||
|
||||
typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
|
||||
|
||||
//
|
||||
byte_t* src = &_buffer.front();
|
||||
this->_io_dev.read( src, _pitch );
|
||||
|
||||
for( dst_view_t::x_coord_t i = 0
|
||||
; i < this->_info._width
|
||||
; ++i, src += 2
|
||||
)
|
||||
{
|
||||
int p = ( src[1] << 8 ) | src[0];
|
||||
|
||||
int r = ((p & this->_mask.red.mask) >> this->_mask.red.shift) << (8 - this->_mask.red.width);
|
||||
int g = ((p & this->_mask.green.mask) >> this->_mask.green.shift) << (8 - this->_mask.green.width);
|
||||
int b = ((p & this->_mask.blue.mask) >> this->_mask.blue.shift) << (8 - this->_mask.blue.width);
|
||||
|
||||
get_color( dst_it[i], red_t() ) = static_cast< byte_t >( r );
|
||||
get_color( dst_it[i], green_t() ) = static_cast< byte_t >( g );
|
||||
get_color( dst_it[i], blue_t() ) = static_cast< byte_t >( b );
|
||||
}
|
||||
}
|
||||
|
||||
void read_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst, _pitch );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// the row pitch must be multiple of 4 bytes
|
||||
int _pitch;
|
||||
|
||||
std::vector<byte_t> _buffer;
|
||||
detail::mirror_bits <std::vector<byte_t>, std::true_type> _mirror_bits;
|
||||
detail::swap_half_bytes<std::vector<byte_t>, std::true_type> _swap_half_bytes;
|
||||
|
||||
std::function<void(this_t*, byte_t*)> _read_function;
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// 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_BMP_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
|
||||
#include <boost/gil/bit_aligned_pixel_reference.hpp>
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
#include <boost/gil/packed_pixel.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
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct bmp_read_support : read_support_false
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 0;
|
||||
};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct bmp_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 1;
|
||||
};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct bmp_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 4
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 4;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 8;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 24;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, rgba_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 32;
|
||||
};
|
||||
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct bmp_write_support : write_support_false
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct bmp_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true {};
|
||||
|
||||
template<>
|
||||
struct bmp_write_support<uint8_t
|
||||
, rgba_t
|
||||
> : write_support_true {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, bmp_tag
|
||||
>
|
||||
: mpl::bool_< detail::bmp_read_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::bmp_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const typename bmp_bits_per_pixel::type bpp = parent_t::bpp;
|
||||
};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, bmp_tag
|
||||
>
|
||||
: mpl::bool_< detail::bmp_write_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
> {};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
217
macx64/include/boost/gil/extension/io/bmp/detail/write.hpp
Normal file
217
macx64/include/boost/gil/extension/io/bmp/detail/write.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// 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_BMP_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
|
||||
#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
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct bmp_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, bmp_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template < int N > struct get_bgr_cs {};
|
||||
template <> struct get_bgr_cs< 1 > { using type = gray8_view_t; };
|
||||
template <> struct get_bgr_cs< 3 > { using type = bgr8_view_t; };
|
||||
template <> struct get_bgr_cs< 4 > { using type = bgra8_view_t; };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// BMP Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
write( view );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using backend_t = writer_backend<Device, bmp_tag>;
|
||||
|
||||
template< typename View >
|
||||
void write( const View& view )
|
||||
{
|
||||
// using channel_t = typename channel_type<
|
||||
// typename get_pixel_type<View>::type>::type;
|
||||
|
||||
// using color_space_t = typename color_space_type<View>::type;
|
||||
|
||||
// check if supported
|
||||
/*
|
||||
/// todo
|
||||
if( bmp_read_write_support_private<channel_t, color_space_t>::channel != 8)
|
||||
{
|
||||
io_error("Input view type is incompatible with the image type");
|
||||
}
|
||||
*/
|
||||
|
||||
// compute the file size
|
||||
int bpp = num_channels< View >::value * 8;
|
||||
int entries = 0;
|
||||
|
||||
/*
|
||||
/// @todo: Not supported for now. bit_aligned_images refer to indexed images
|
||||
/// in this context.
|
||||
if( bpp <= 8 )
|
||||
{
|
||||
entries = 1u << bpp;
|
||||
}
|
||||
*/
|
||||
|
||||
std::size_t spn = ( view.width() * num_channels< View >::value + 3 ) & ~3;
|
||||
std::size_t ofs = bmp_header_size::_size
|
||||
+ bmp_header_size::_win32_info_size
|
||||
+ entries * 4;
|
||||
|
||||
std::size_t siz = ofs + spn * view.height();
|
||||
|
||||
// write the BMP file header
|
||||
this->_io_dev.write_uint16( bmp_signature );
|
||||
this->_io_dev.write_uint32( (uint32_t) siz );
|
||||
this->_io_dev.write_uint16( 0 );
|
||||
this->_io_dev.write_uint16( 0 );
|
||||
this->_io_dev.write_uint32( (uint32_t) ofs );
|
||||
|
||||
// writes Windows information header
|
||||
this->_io_dev.write_uint32( bmp_header_size::_win32_info_size );
|
||||
this->_io_dev.write_uint32( static_cast< uint32_t >( view.width() ));
|
||||
this->_io_dev.write_uint32( static_cast< uint32_t >( view.height() ));
|
||||
this->_io_dev.write_uint16( 1 );
|
||||
this->_io_dev.write_uint16( static_cast< uint16_t >( bpp ));
|
||||
this->_io_dev.write_uint32( bmp_compression::_rgb );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( entries );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
|
||||
write_image< View
|
||||
, typename detail::get_bgr_cs< num_channels< View >::value >::type
|
||||
>( view, spn );
|
||||
}
|
||||
|
||||
|
||||
template< typename View
|
||||
, typename BMP_View
|
||||
>
|
||||
void write_image( const View& view
|
||||
, const std::size_t spn
|
||||
)
|
||||
{
|
||||
byte_vector_t buffer( spn );
|
||||
std::fill( buffer.begin(), buffer.end(), 0 );
|
||||
|
||||
|
||||
BMP_View row = interleaved_view( view.width()
|
||||
, 1
|
||||
, (typename BMP_View::value_type*) &buffer.front()
|
||||
, spn
|
||||
);
|
||||
|
||||
for( typename View::y_coord_t y = view.height() - 1; y > -1; --y )
|
||||
{
|
||||
copy_pixels( subimage_view( view
|
||||
, 0
|
||||
, (int) y
|
||||
, (int) view.width()
|
||||
, 1
|
||||
)
|
||||
, row
|
||||
);
|
||||
|
||||
this->_io_dev.write( &buffer.front(), spn );
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// BMP Dynamic Image Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, bmp_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::bmp_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views
|
||||
, op
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -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_BMP_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/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
|
||||
|
||||
///
|
||||
/// BMP Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = bmp_tag;
|
||||
|
||||
public:
|
||||
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info ( info )
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< bmp_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
160
macx64/include/boost/gil/extension/io/bmp/old.hpp
Normal file
160
macx64/include/boost/gil/extension/io/bmp/old.hpp
Normal file
@@ -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_BMP_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Returns the width and height of the BMP file at the specified location.
|
||||
/// Throws std::ios_base::failure if the location does not correspond to a valid BMP file
|
||||
template<typename String>
|
||||
inline point_t bmp_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, bmp_tag>::type;
|
||||
backend_t backend = read_image_info(filename, bmp_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads the image specified by the given bmp image file name into the given view.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the BMP library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP 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 bmp_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp 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 BMP library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP 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 bmp_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads and color-converts the image specified by the given bmp image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads and color-converts the image specified by the given bmp image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file
|
||||
template< typename String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Saves the view to a bmp file specified by the given bmp image file name.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the BMP 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 bmp_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
30
macx64/include/boost/gil/extension/io/bmp/read.hpp
Normal file
30
macx64/include/boost/gil/extension/io/bmp/read.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 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_BMP_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_READ_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/scanline_read.hpp>
|
||||
#include <boost/gil/extension/io/bmp/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
|
||||
159
macx64/include/boost/gil/extension/io/bmp/tags.hpp
Normal file
159
macx64/include/boost/gil/extension/io/bmp/tags.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// 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_BMP_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_TAGS_HPP
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines bmp tag.
|
||||
struct bmp_tag : format_tag {};
|
||||
|
||||
/// See http://en.wikipedia.org/wiki/BMP_file_format#BMP_File_Header for reference.
|
||||
|
||||
/// Defines type for offset value.
|
||||
struct bmp_offset : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for header sizes.
|
||||
struct bmp_header_size : property_base< uint32_t >
|
||||
{
|
||||
static const type _size = 14; /// Constant size for bmp file header size.
|
||||
static const type _win32_info_size = 40; /// Constant size for win32 bmp info header size.
|
||||
static const type _os2_info_size = 12; /// Constant size for os2 bmp info header size.
|
||||
};
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct bmp_image_width : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct bmp_image_height : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for bits per pixels property.
|
||||
struct bmp_bits_per_pixel : property_base< uint16_t > {};
|
||||
|
||||
/// Defines type for compression property.
|
||||
struct bmp_compression : property_base< uint32_t >
|
||||
{
|
||||
static const type _rgb = 0; /// RGB without compression
|
||||
static const type _rle8 = 1; /// 8 bit index with RLE compression
|
||||
static const type _rle4 = 2; /// 4 bit index with RLE compression
|
||||
static const type _bitfield = 3; /// 16 or 32 bit fields without compression
|
||||
};
|
||||
|
||||
/// Defines type for image size property.
|
||||
struct bmp_image_size : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for horizontal resolution property.
|
||||
struct bmp_horizontal_resolution : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for vertical resolution property.
|
||||
struct bmp_vertical_resolution : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for number of colors property.
|
||||
struct bmp_num_colors : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for important number of colors property.
|
||||
struct bmp_num_important_colors : property_base< uint32_t > {};
|
||||
|
||||
/// if height is negative then image is stored top-down instead of bottom-up.
|
||||
struct bmp_top_down : property_base< bool > {};
|
||||
|
||||
static const uint32_t bmp_signature = 0x4D42; /// Constant signature for bmp file format.
|
||||
|
||||
/// Read information for bmp images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< bmp_tag >
|
||||
{
|
||||
/// Default contructor.
|
||||
image_read_info< bmp_tag >()
|
||||
: _top_down(false)
|
||||
, _valid( false )
|
||||
{}
|
||||
|
||||
/// The offset, i.e. starting address, of the byte where the bitmap data can be found.
|
||||
bmp_offset::type _offset;
|
||||
|
||||
/// The size of this header:
|
||||
/// - 40 bytes for Windows V3 header
|
||||
/// - 12 bytes for OS/2 V1 header
|
||||
bmp_header_size::type _header_size;
|
||||
|
||||
/// The bitmap width in pixels ( signed integer ).
|
||||
bmp_image_width::type _width;
|
||||
|
||||
/// The bitmap height in pixels ( signed integer ).
|
||||
bmp_image_height::type _height;
|
||||
|
||||
/// The number of bits per pixel, which is the color depth of the image.
|
||||
/// Typical values are 1, 4, 8, 16, 24 and 32.
|
||||
bmp_bits_per_pixel::type _bits_per_pixel;
|
||||
|
||||
/// The compression method being used. See above for a list of possible values.
|
||||
bmp_compression::type _compression;
|
||||
|
||||
/// The image size. This is the size of the raw bitmap data (see below),
|
||||
/// and should not be confused with the file size.
|
||||
bmp_image_size::type _image_size;
|
||||
|
||||
/// The horizontal resolution of the image. (pixel per meter, signed integer)
|
||||
bmp_horizontal_resolution::type _horizontal_resolution;
|
||||
|
||||
/// The vertical resolution of the image. (pixel per meter, signed integer)
|
||||
bmp_vertical_resolution::type _vertical_resolution;
|
||||
|
||||
/// The number of colors in the color palette, or 0 to default to 2^n - 1.
|
||||
bmp_num_colors::type _num_colors;
|
||||
|
||||
/// The number of important colors used, or 0 when every color is important;
|
||||
/// generally ignored.
|
||||
bmp_num_important_colors::type _num_important_colors;
|
||||
|
||||
bmp_top_down::type _top_down;
|
||||
|
||||
/// Used internaly to identify is the header has been read.
|
||||
bool _valid;
|
||||
};
|
||||
|
||||
/// Read settings for bmp images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< bmp_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( const point_t& top_left
|
||||
, const point_t& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
/// Write information for bmp images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< bmp_tag >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
macx64/include/boost/gil/extension/io/bmp/write.hpp
Normal file
19
macx64/include/boost/gil/extension/io/bmp/write.hpp
Normal file
@@ -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_BMP_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user