WIP. Scale cover art option. Seems to work
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
Copyright 2008 Christian Henning
|
||||
Use, modification and distribution are subject to 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_IO_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_IO_WRITE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \brief
|
||||
/// \author Christian Henning \n
|
||||
///
|
||||
/// \date 2008 \n
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/gil/extension/io_new/detail/base.hpp>
|
||||
#include <boost/gil/extension/io_new/detail/io_device.hpp>
|
||||
|
||||
#include <boost/gil/extension/io_new/bmp_tags.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template < int N > struct get_bgr_cs {};
|
||||
template <> struct get_bgr_cs< 1 > { typedef gray8_view_t type; };
|
||||
template <> struct get_bgr_cs< 3 > { typedef bgr8_view_t type; };
|
||||
template <> struct get_bgr_cs< 4 > { typedef bgra8_view_t type; };
|
||||
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
writer( Device& file )
|
||||
: _out( file )
|
||||
{
|
||||
}
|
||||
|
||||
~writer()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
write( view );
|
||||
}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view
|
||||
, const image_write_info< bmp_tag >& /* info */
|
||||
)
|
||||
{
|
||||
// Add code here, once image_write_info< bmp_tag > isn't empty anymore.
|
||||
|
||||
write( view );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename View >
|
||||
void write( const View& view )
|
||||
{
|
||||
typedef typename channel_type<
|
||||
typename get_pixel_type< View >::type >::type channel_t;
|
||||
|
||||
typedef typename color_space_type< View >::type color_space_t;
|
||||
|
||||
// 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 = 1 << 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
|
||||
_out.write_int16( bmp_signature );
|
||||
_out.write_int32( (uint32_t) siz );
|
||||
_out.write_int16( 0 );
|
||||
_out.write_int16( 0 );
|
||||
_out.write_int32( (uint32_t) ofs );
|
||||
|
||||
// writes Windows information header
|
||||
_out.write_int32( bmp_header_size::_win32_info_size );
|
||||
_out.write_int32( static_cast< uint32_t >( view.width() ));
|
||||
_out.write_int32( static_cast< uint32_t >( view.height() ));
|
||||
_out.write_int16( 1 );
|
||||
_out.write_int16( static_cast< uint16_t >( bpp ));
|
||||
_out.write_int32( bmp_compression::_rgb );
|
||||
_out.write_int32( 0 );
|
||||
_out.write_int32( 0 );
|
||||
_out.write_int32( 0 );
|
||||
_out.write_int32( entries );
|
||||
_out.write_int32( 0 );
|
||||
|
||||
write_image< View
|
||||
, typename 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
|
||||
);
|
||||
|
||||
_out.write( &buffer.front(), spn );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Device& _out;
|
||||
};
|
||||
|
||||
|
||||
struct bmp_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, bmp_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
typedef writer< Device
|
||||
, bmp_tag
|
||||
> parent_t;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( Device& file )
|
||||
: parent_t( file )
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
dynamic_io_fnobj< bmp_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views, op );
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_GIL_EXTENSION_IO_BMP_IO_WRITE_HPP
|
||||
Reference in New Issue
Block a user