Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61386 - sandbox/gil/boost/gil/extension/io2
From: dsaritz_at_[hidden]
Date: 2010-04-18 17:10:02


Author: psiha
Date: 2010-04-18 17:10:01 EDT (Sun, 18 Apr 2010)
New Revision: 61386
URL: http://svn.boost.org/trac/boost/changeset/61386

Log:
Added a faster/integer version/overload for a special default_color_converter code path.
Replaced the pixel_format_type<> logic/machinery/typedefs with simpler gil::image<> typedefs.
Moved more shared logic from the gp_image class to the formatted_image(_base) class (dimensions_mismatch(), get_raw_data() ...).
Simplified the formatted_image_base::check_type_match<> functor.
Added ROI/offset view support.
Replaced the multiple template parameter formatted_image design with a single template parameter and a traits class (formatted_image_traits<>).
Added proper and/or missing formatted_image<> copy_to() and copy_to_image() member function overloads.
Moved the core 'generic' and 'in-place' transform logic into the base formatted_image<> class.

Updated the GDI+ implementation with the above changes.
Fixed the GDI+ implementation to include CMYK support only for GDI+ 1.1 builds.

Minor other refactoring and stylistic changes.
Text files modified:
   sandbox/gil/boost/gil/extension/io2/formatted_image.hpp | 579 +++++++++++++++++++++++++++++--------
   sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp | 614 +++++++++++++--------------------------
   sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp | 13
   3 files changed, 653 insertions(+), 553 deletions(-)

Modified: sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/formatted_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/formatted_image.hpp 2010-04-18 17:10:01 EDT (Sun, 18 Apr 2010)
@@ -26,8 +26,15 @@
 
 #include <boost/gil/extension/dynamic_image/any_image.hpp>
 
+#ifdef _DEBUG
+#include <boost/detail/endian.hpp>
+#endif // _DEBUG
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/integral_c.hpp>
+#ifdef _DEBUG
+#include <boost/numeric/conversion/converter.hpp>
+#include <boost/numeric/conversion/converter_policies.hpp>
+#endif // _DEBUG
 #include <boost/range/iterator_range.hpp>
 #include <boost/static_assert.hpp>
 //------------------------------------------------------------------------------
@@ -47,71 +54,92 @@
 struct synchronize_formats {};
 
 
-namespace detail
+//...zzz...test unrolled 24bit-16bit conversion
+//template <typename ChannelValue, typename Layout, typename BitField, typename ChannelRefVec>
+//void color_convert
+//(
+// pixel <ChannelValue, Layout> const & src,
+// packed_pixel<BitField, ChannelRefVec, Layout> & dst
+//)
+//{
+// struct bfield_t
+// {
+// BitField r : 5;
+// BitField g : 6;
+// BitField b : 5;
+// };
+// //BitField & fast_dst( reinterpret_cast<BitField &>( dst ) );
+// bfield_t & fast_dst( reinterpret_cast<bfield_t &>( dst._bitfield ) );
+//
+// unsigned char const source_max ( detail::unsigned_integral_max_value<ChannelValue>::value );
+// //unsigned char const rb_max( (1<<5)-1 );
+// //unsigned char const g_max( (1<<6)-1 );
+// unsigned int const rtmp( ( static_cast<unsigned short>( src[ 0 ] ) << 5 ) - src[ 0 ] );
+// unsigned int const btmp( ( static_cast<unsigned short>( src[ 2 ] ) << 5 ) - src[ 2 ] );
+// unsigned int const gtmp( ( static_cast<unsigned short>( src[ 1 ] ) << 6 ) - src[ 1 ] );
+//
+// fast_dst.r = ( rtmp / source_max ) + ( ( rtmp % source_max ) > ( source_max / 2 ) );
+// fast_dst.b = ( btmp / source_max ) + ( ( btmp % source_max ) > ( source_max / 2 ) );
+// fast_dst.g = ( gtmp / source_max ) + ( ( gtmp % source_max ) > ( source_max / 2 ) );
+//}
+
+
+#if defined(BOOST_MSVC)
+# pragma warning( push )
+# pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif
+
+// An integer version of the unsigned channel downsampling/quantizing 'overload'...
+template <typename SrcChannelV, int DestPackedNumBits>
+struct channel_converter<SrcChannelV, packed_channel_value<DestPackedNumBits> >
+ : public std::unary_function<SrcChannelV, packed_channel_value<DestPackedNumBits> >
 {
-//------------------------------------------------------------------------------
-
-
-typedef iterator_range<TCHAR const *> string_chunk_t;
-
-
-template <typename Pixel, bool planar>
-struct pixel_format_type : mpl::pair<Pixel, mpl::bool_<planar>> {};
-
-
-struct get_planar_pixel_iterator
-{
- template <typename PixelFormatType>
- struct apply
+ packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
     {
- typedef planar_pixel_iterator
- <
- typename channel_type <typename PixelFormatType::first>::type,
- typename color_space_type<typename PixelFormatType::first>::type
- > type;
- };
-};
+ typedef packed_channel_value<DestPackedNumBits> DstChannelV;
 
-struct get_plain_pixel_iterator
-{
- template <typename PixelFormatType>
- struct apply
- {
- typedef typename PixelFormatType::first * type;
- };
-};
-
-
-template <typename PixelFormat>
-struct view_for_pixel_format
-{
- typedef typename type_from_x_iterator
- <
- typename mpl::if_
- <
- typename PixelFormat::second,
- get_planar_pixel_iterator,
- get_plain_pixel_iterator
+ typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
+ typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
 
- >::type::apply<PixelFormat>::type
- >::view_t type;
+ if ( is_unsigned<SrcChannelV>::value )
+ {
+ SrcChannelV const source_max( detail::unsigned_integral_max_value<SrcChannelV>::value );
+ unsigned int const tmp ( ( static_cast<unsigned short>( src ) << DestPackedNumBits ) - src );
+ typename DstChannelV::integer_t const result
+ (
+ static_cast<typename DstChannelV::integer_t>( tmp / source_max ) + ( ( tmp % source_max ) > ( source_max / 2 ) )
+ );
+ #ifdef _DEBUG
+ unsigned char const destination_max( detail::unsigned_integral_max_value<DstChannelV>::value );
+ DstChannelV const debug_result
+ (
+ numeric::converter<unsigned, double, numeric::conversion_traits<unsigned, double>, numeric::def_overflow_handler, numeric::RoundEven<double> >::convert
+ (
+ src * double( destination_max ) / double( source_max )
+ )
+ );
+ BOOST_ASSERT( result == debug_result );
+ #endif // _DEBUG
+ return *gil_reinterpret_cast_c<DstChannelV const *>( &result );
+ }
+ else
+ {
+ typedef channel_converter_unsigned<typename to_unsigned::result_type, typename from_unsigned::argument_type> converter_unsigned;
+ return from_unsigned()(converter_unsigned()(to_unsigned()(src)));
+ }
+ }
 };
 
-template <typename PixelFormats>
-struct views_for_pixel_formats
- : public mpl::transform<PixelFormats, view_for_pixel_format<mpl::_1> > {};
+#if defined(BOOST_MSVC)
+# pragma warning( pop )
+#endif
 
 
-template <typename PixelFormat>
-struct const_view_for_pixel_format
- :
- public view_for_pixel_format<pixel_format_type<typename PixelFormat::first const, PixelFormat::second::value> >
-{};
-
-template <typename PixelFormats>
-struct const_views_for_pixel_formats
- : public mpl::transform<PixelFormats, const_view_for_pixel_format<mpl::_1> > {};
+namespace detail
+{
+//------------------------------------------------------------------------------
 
+typedef iterator_range<TCHAR const *> string_chunk_t;
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -126,36 +154,61 @@
     typedef point2<std::ptrdiff_t> dimensions_t;
 
     typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = -1;
+ static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
 
 protected:
- static bool dimensions_match( dimensions_t const & mine, dimensions_t const & other ) { return mine == other; }
+ static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
+
     template <class View>
- static bool dimensions_match( dimensions_t const & mine, View const & view ) { return dimensions_match( mine, view.dimensions(); ) }
+ static bool dimensions_mismatch( dimensions_t const & mine, View const & view )
+ {
+ return dimensions_mismatch( mine, view.dimensions() );
+ }
 
     static void do_ensure_dimensions_match( dimensions_t const & mine, dimensions_t const & other )
     {
- io_error_if( !dimensions_match( mine, other ), "input view size does not match source image size" );
+ io_error_if( dimensions_mismatch( mine, other ), "input view size does not match source image size" );
     }
+
     template <class View>
     static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
     {
         do_ensure_dimensions_match( mine, view.dimensions() );
     }
 
- static void do_ensure_formats_match( bool const formats_match )
+ static void do_ensure_formats_match( bool const formats_mismatch )
     {
- io_error_if( !formats_match, "input view format does not match source image format" );
+ io_error_if( formats_mismatch, "input view format does not match source image format" );
     }
 
-protected:
     template <typename Image>
- void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
+ static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
     {
         image.recreate( my_dimensions, alignment );
     }
 
+public: //...zzz...
+ template <typename View>
+ static unsigned char * get_raw_data( View const & view )
+ {
+ // A private implementation of interleaved_view_get_raw_data() that
+ // works with packed pixel views.
+ BOOST_STATIC_ASSERT(( !is_planar<View>::value /*&& view_is_basic<View>::value*/ ));
+ BOOST_STATIC_ASSERT(( is_pointer<typename View::x_iterator>::value ));
+
+ return gil_reinterpret_cast<unsigned char *>( &gil::at_c<0>( view( 0, 0 ) ) );
+ }
+
 protected:
+ template <typename View>
+ struct is_plain_in_memory_view
+ :
+ mpl::bool_
+ <
+ is_pointer<typename View::x_iterator>::value ||
+ ( is_planar<View>::value && view_is_basic<View>::value )
+ > {};
+
     struct assert_type_mismatch
     {
         typedef bool result_type;
@@ -166,7 +219,7 @@
     struct throw_type_mismatch
     {
         typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( false ); }
+ result_type operator()() const { do_ensure_formats_match( true ); }
     };
 
     template <typename Type, typename SupportedPixelFormats>
@@ -176,18 +229,20 @@
         template <typename SupportedFormatIndex>
         result_type operator()( SupportedFormatIndex const & ) const
         {
- return worker<SupportedFormatIndex>( mpl::less<SupportedFormatIndex, mpl::size<SupportedPixelFormats> >() );
+ return is_same<Type, typename mpl::at<SupportedPixelFormats, SupportedFormatIndex>::type>::value;
         }
+ };
 
+ template <typename ResultType>
+ struct assert_default_case_not_reached
+ {
+ typedef ResultType result_type;
         template <typename Index>
- bool worker( mpl::true_ /*in-range*/ ) const
- {
- return is_same<Type, typename mpl::at<SupportedPixelFormats, Index>::type>::value;
- }
- template <typename Index>
- bool worker( mpl::false_ /*not-in-range*/ ) const
+ result_type operator()( Index const & ) const
         {
- return false;
+ BOOST_ASSERT( !"Default case must not have been reached!" );
+ __assume( false );
+ return result_type();
         }
     };
 
@@ -213,20 +268,94 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \class offset_view_t
+/// \todo document properly...
+///
+////////////////////////////////////////////////////////////////////////////////
+
+template <class View, typename Offset>
+class offset_view_t
+{
+public:
+ offset_view_t( View const & view, Offset const & offset ) : view_( view ), offset_( offset ) {}
+
+ typename View::point_t dimensions() const
+ {
+ return offset_dimensions( offset_ );
+ }
+
+ View const & original_view() const { return view_ ; }
+ Offset const & offset () const { return offset_; }
+
+private:
+ typename View::point_t offset_dimensions( typename View::point_t::value_type const offset ) const
+ {
+ typename View::point_t view_dimensions( view_.dimensions() );
+ return view_dimensions += typename View::point_t( 0, offset );
+ }
+
+ typename View::point_t offset_dimensions( typename View::point_t const & offset ) const
+ {
+ typename View::point_t view_dimensions( view_.dimensions() );
+ return view_dimensions += offset;
+ }
+
+private:
+ View const & view_ ;
+ typename call_traits<Offset>::param_type offset_;
+};
+
+template <class View, typename Offset>
+View const & original_view( offset_view_t<View, Offset> const & offset_view ) { return offset_view.original_view(); }
+
+template <class View>
+View const & original_view( View const & view ) { return view; }
+
+template <typename Offset, class View>
+Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
+
+template <typename Offset, class View>
+Offset get_offset( View const & ) { return Offset(); }
+
+
+template <class NewView, class View, typename Offset>
+offset_view_t<NewView, Offset> offset_new_view( NewView const & new_view, offset_view_t<View, Offset> const & offset_view )
+{
+ return offset_view_t<NewView, Offset>( new_view, offset_view.offset_ );
+}
+
+template <class NewView, class View>
+NewView const & offset_new_view( NewView const & new_view, View const & ) { return new_view; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class formatted_image_traits
+/// ( forward declaration )
+////////////////////////////////////////////////////////////////////////////////
+
+template <class Impl>
+struct formatted_image_traits;
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \class formatted_image
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-template <class Impl, class SupportedPixelFormats, class ROI>
+template <class Impl>
 class formatted_image : public formatted_image_base
 {
 public:
- //typedef typename any_image<typename Impl::supported_pixel_formats> any_image_t;
- typedef SupportedPixelFormats supported_pixel_formats;
- typedef ROI roi;
+ typedef typename formatted_image_traits<Impl>::format_t format_t;
 
- typedef any_image_view<typename const_views_for_pixel_formats<typename supported_pixel_formats>::type> const_view_t;
- typedef any_image_view<typename views_for_pixel_formats <typename supported_pixel_formats>::type> view_t;
+ typedef typename formatted_image_traits<Impl>::supported_pixel_formats_t supported_pixel_formats;
+ typedef typename formatted_image_traits<Impl>::roi_t roi;
+ typedef typename roi::offset_t offset_t;
+
+ typedef any_image<supported_pixel_formats> dynamic_image_t;
+ typedef typename dynamic_image_t::const_view_t const_view_t;
+ typedef typename dynamic_image_t:: view_t view_t;
 
     BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<roi::offset_t, roi::point_t>::value) );
 
@@ -249,16 +378,10 @@
             {}
 
         template <class Image>
- void apply()
- {
- impl_.copy_to( base::apply<Image>(), dimensions_policy(), formats_policy() );
- }
+ void apply() { impl_.copy_to( base::apply<Image>(), dimensions_policy(), formats_policy() ); }
 
         template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & )
- {
- apply<typename mpl::at<SupportedFormatIndex>::type>();
- }
+ void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
 
     private:
         Impl & impl_;
@@ -273,10 +396,7 @@
         write_dynamic_view( Impl & impl ) : impl_( impl ) {}
 
         template <class View>
- void apply( View const & view )
- {
- impl_.copy_from( view, dimensions_policy(), formats_policy() );
- }
+ void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
 
     private:
         Impl & impl_;
@@ -291,71 +411,156 @@
     typedef mpl::range_c<std::size_t, 0, mpl::size<supported_pixel_formats>::value> valid_type_id_range_t;
 
 private:
+ Impl & impl() { return static_cast<Impl &>( *this ); }
+ Impl const & impl() const { return static_cast<Impl const &>( *this ); }
+
+protected:
     template <typename View>
- bool formats_match()
+ bool dimensions_mismatch( View const & view ) const
     {
- Gdiplus::PixelFormat tzt = view_gp_format<View>::value;
- return switch_<valid_type_id_range_t>
+ return dimensions_mismatch( view.dimensions() );
+ }
+
+ bool dimensions_mismatch( dimensions_t const & other_dimensions ) const
+ {
+ return formatted_image_base::dimensions_mismatch( impl().dimensions(), other_dimensions );
+ }
+
+ template <class View>
+ void do_ensure_dimensions_match( View const & view ) const
+ {
+ formatted_image_base::do_ensure_dimensions_match( impl().dimensions(), view.dimensions() );
+ }
+
+ template <typename View>
+ bool formats_mismatch() const
+ {
+ return formats_mismatch( formatted_image_traits<Impl>::view_to_native_format::apply<View>::value );
+ }
+
+ bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
+ {
+ return other_format != impl().closest_gil_supported_format();
+ }
+
+ template <class View>
+ void do_ensure_formats_match() const { formatted_image_base::do_ensure_formats_match( formats_mismatch<View>() ); }
+
+ template <typename View>
+ bool can_do_inplace_transform() const
+ {
+ return can_do_inplace_transform<View>( format() );
+ }
+
+ template <typename View>
+ bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
+ {
+ return ( Impl::format_size( my_format ) == sizeof( typename View::value_type ) );
+ }
+
+public: // Views...
+ template <typename View>
+ void copy_to( View & view, assert_dimensions_match, assert_formats_match ) const
+ {
+ BOOST_STATIC_ASSERT( formatted_image_traits<Impl>::is_supported<View>::value );
+ BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
+ BOOST_ASSERT( !impl().formats_mismatch<View>() );
+ impl().raw_convert_to_prepared_view
         (
- impl().current_image_type_id(),
- check_type_match
- <
- pixel_format_type
- <
- typename View::value_type,
- is_planar<typename View>::value
- >,
- supported_pixel_formats
- >(),
- assert_type_mismatch()
+ formatted_image_traits<Impl>::view_data_t
+ (
+ original_view ( view ),
+ get_offset<offset_t>( view )
+ )
         );
     }
 
- Impl & impl() { return static_cast<Impl &>( *this ); }
-
-public:
- template <typename Image, typename DimensionsPolicy, typename FormatsPolicy>
- void copy_to_image( Image & image, DimensionsPolicy const dimensions_policy, FormatsPolicy const formats_policy )
+ template <typename View>
+ void copy_to( View & view, assert_dimensions_match, ensure_formats_match ) const
     {
- impl().copy_to( view( image ), dimensions_policy, formats_policy );
+ impl().do_ensure_formats_match<View>();
+ impl().copy_to( view, assert_dimensions_match(), assert_formats_match() );
     }
 
- template <typename Image, typename FormatsPolicy>
- void copy_to_image( Image & image, synchronize_dimensions, FormatsPolicy const formats_policy )
+ template <typename View>
+ void copy_to( View & view, ensure_dimensions_match, assert_formats_match ) const
     {
- do_synchronize_dimensions( image, impl().dimensions(), Impl::desired_alignment );
- impl().copy_to( view( image ), assert_dimensions_match(), formats_policy );
+ impl().do_ensure_dimensions_match( view );
+ impl().copy_to( view, assert_dimensions_match(), assert_formats_match() );
     }
 
     template <typename View>
- void copy_to( View & view, assert_dimensions_match, assert_formats_match )
+ void copy_to( View & view, ensure_dimensions_match, ensure_formats_match ) const
     {
- BOOST_ASSERT( dimensions_match( view.dimensions(), impl().dimensions() ) );
- BOOST_ASSERT( formats_match<View>() );
- impl().copy_to_prepared_view( view );
+ impl().do_ensure_formats_match<View>();
+ impl().do_ensure_dimensions_match( view );
+ impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
     }
 
     template <typename View>
- void copy_to( View & view, assert_dimensions_match, ensure_formats_match )
+ void copy_to( View & view, ensure_dimensions_match, synchronize_formats ) const
     {
- do_ensure_formats_match( formats_match<View>() );
- copy_to( view, assert_dimensions_match(), assert_formats_match() );
+ impl().do_ensure_dimensions_match( view );
+ impl().copy_to( view, assert_dimensions_match(), synchronize_formats() );
     }
 
     template <typename View>
- void copy_to( View & view, ensure_dimensions_match, assert_formats_match )
+ void copy_to( View & view, assert_dimensions_match, synchronize_formats ) const
+ {
+ BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
+ impl().raw_convert_to_prepared_view
+ (
+ formatted_image_traits<Impl>::view_data_t
+ (
+ original_view ( view ),
+ get_offset<offset_t>( view )
+ )
+ );
+ }
+
+ template <typename FormatConverter, typename View>
+ void copy_to( View & view, ensure_dimensions_match, FormatConverter const & format_converter ) const
+ {
+ impl().do_ensure_dimensions_match( view );
+ impl().copy_to( view, assert_dimensions_match(), format_converter );
+ }
+
+ template <typename FormatConverter, typename View>
+ void copy_to( View & view, assert_dimensions_match, FormatConverter const & format_converter ) const
+ {
+ BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
+ impl().convert_to_prepared_view( view, format_converter );
+ }
+
+public: // Images...
+ template <typename Image, typename FormatsPolicy>
+ Image copy_to_image( FormatsPolicy const formats_policy ) const
+ {
+ Image image( impl().dimensions(), formatted_image_traits<Impl>::desired_alignment );
+ impl().copy_to( view( image ), assert_dimensions_match(), formats_policy );
+ return image;
+ }
+
+ template <typename Image, typename DimensionsPolicy, typename FormatsPolicy>
+ void copy_to_image( Image & image, DimensionsPolicy const dimensions_policy, FormatsPolicy const formats_policy ) const
+ {
+ impl().copy_to( view( image ), dimensions_policy, formats_policy );
+ }
+
+ template <typename Image, typename FormatsPolicy>
+ void copy_to_image( Image & image, synchronize_dimensions, FormatsPolicy const formats_policy ) const
     {
- do_ensure_dimensions_match( formats_match<View>() );
- copy_to( view, assert_dimensions_match, assert_formats_match );
+ impl().do_synchronize_dimensions( image, impl().dimensions(), formatted_image_traits<Impl>::desired_alignment );
+ impl().copy_to( view( image ), assert_dimensions_match(), formats_policy );
     }
 
     template <typename Images, typename dimensions_policy, typename formats_policy>
- void copy_to( any_image<Images> & im )
+ void copy_to_image( any_image<Images> & im ) const
     {
         typedef mpl::range_c<std::size_t, 0, typename Impl::supported_pixel_formats> valid_range_t;
         switch_<valid_range_t>
         (
- Impl::current_image_type_id(),
+ impl().current_image_format_id(),
             read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
             throw_type_mismatch()
         );
@@ -373,16 +578,128 @@
         );
     }
 
- void save_to( std::string const & path )
+private:
+ template <class View, typename CC>
+ struct in_place_converter_t
+ {
+ typedef void result_type;
+
+ in_place_converter_t( CC const & cc, View const & view ) : cc_( cc ), view_( view ) {}
+
+ template <std::size_t index>
+ void operator()( mpl::integral_c<std::size_t, index> const & ) const
+ {
+ typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
+ BOOST_STATIC_ASSERT( sizeof( view_t ) == sizeof( View ) );
+ for_each_pixel( *gil_reinterpret_cast_c<view_t const *>( &view_ ), *this );
+ }
+
+ template <typename SrcP>
+ typename enable_if<is_pixel<SrcP>>::type
+ operator()( SrcP & srcP )
+ {
+ BOOST_ASSERT( sizeof( SrcP ) == sizeof( typename View::value_type ) );
+ cc_( srcP, *gil_reinterpret_cast<typename View::value_type *>( &srcP ) );
+ }
+
+ void operator=( in_place_converter_t const & other )
+ {
+ BOOST_ASSERT( this->view_ == other.view_ );
+ this->cc_ = other.cc_;
+ }
+
+ CC cc_;
+ View const & view_;
+ };
+
+ template <class View, typename CC>
+ struct generic_converter_t
+ {
+ typedef void result_type;
+
+ generic_converter_t( Impl const & impl, CC const & cc, View const & view )
+ : impl_( impl ), cc_( cc ), view_( view ) {}
+
+ template <std::size_t index>
+ void operator()( mpl::integral_c<std::size_t, index> const & ) const
+ {
+ typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t my_view_t;
+ impl_.generic_convert_to_prepared_view<my_view_t>( view_, cc_ );
+ }
+
+ void operator=( generic_converter_t const & other )
+ {
+ BOOST_ASSERT( this->impl_ == other.impl_ );
+ BOOST_ASSERT( this->view_ == other.view_ );
+ this->cc_ = other.cc_;
+ }
+
+ Impl const & impl_;
+ CC cc_ ;
+ View const & view_;
+ };
+
+ template <class TargetView, class CC>
+ static void in_place_transform( unsigned int const source_view_type_id, TargetView const & view, CC const & cc )
+ {
+ return switch_<valid_type_id_range_t>
+ (
+ source_view_type_id,
+ in_place_converter_t<TargetView, CC>( cc, view ),
+ assert_default_case_not_reached<void>()
+ );
+ }
+
+ template <class TargetView, class CC>
+ void generic_transform( unsigned int const source_view_type_id, TargetView const & view, CC const & cc ) const
     {
- impl().save_to( path.c_str() );
+ return switch_<valid_type_id_range_t>
+ (
+ source_view_type_id,
+ generic_converter_t<TargetView, CC>( impl(), cc, view ),
+ assert_default_case_not_reached<void>()
+ );
     }
 
- void save_to( std::wstring const & path )
+ template <typename View, typename CC>
+ void convert_to_prepared_view( View const & view, CC const & converter ) const
     {
- impl().save_to( path.c_str() );
+ BOOST_ASSERT( !dimensions_mismatch( view ) );
+ convert_to_prepared_view_worker
+ (
+ view,
+ converter,
+ mpl::bool_
+ <
+ is_plain_in_memory_view<View>::value &&
+ formatted_image_traits<Impl>::is_supported<View>::value
+ >()
+ );
+ }
+
+ template <typename View, typename CC>
+ void convert_to_prepared_view_worker( View const & view, CC const & converter, mpl::true_ /*can use raw*/ ) const
+ {
+ format_t const my_format ( impl().closest_gil_supported_format() );
+ unsigned int const current_image_format_id( impl().image_format_id( my_format ) );
+ if ( can_do_inplace_transform<View>( my_format ) )
+ {
+ Impl::view_data_t view_data( original_view( view ), get_offset<offset_t>( view ) );
+ view_data.set_format( my_format );
+ impl().copy_to_prepared_view( view_data );
+ in_place_transform( current_image_format_id, original_view( view ), converter );
+ }
+ else
+ {
+ generic_transform( current_image_format_id, view, converter );
+ }
     }
 
+ template <typename View, typename CC>
+ void convert_to_prepared_view_worker( View const & view, CC const & converter, mpl::false_ /*must use generic*/ ) const
+ {
+ generic_transform( Impl::image_format_id( impl().closest_gil_supported_format() ), view, converter );
+ }
 };
 
 

Modified: sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp 2010-04-18 17:10:01 EDT (Sun, 18 Apr 2010)
@@ -44,6 +44,13 @@
 {
 //------------------------------------------------------------------------------
 
+#if (GDIPVER >= 0x0110)
+Gdiplus::PixelFormat const cmyk_format( PixelFormat32bppCMYK | PixelFormatGDI );
+#undef PixelFormat32bppCMYK
+#define PixelFormat32bppCMYK cmyk_format
+#else
+#undef PixelFormat32bppCMYK
+#endif // (GDIPVER >= 0x0110)
 
 template <Gdiplus::PixelFormat gp_format> struct is_canonical : mpl::bool_ <(gp_format & PixelFormatCanonical) != 0> {};
 template <Gdiplus::PixelFormat gp_format> struct is_extended : mpl::bool_ <(gp_format & PixelFormatExtended ) != 0> {};
@@ -54,70 +61,49 @@
 template <Gdiplus::PixelFormat gp_format> struct pixel_size : mpl::size_t<( gp_format >> 8 ) & 0xff > {};
 
 
-template <typename Channel, typename ColorSpace>
-struct gil_to_gp_format : mpl::integral_c<Gdiplus::PixelFormat, PixelFormatUndefined> {};
-
-template <> struct gil_to_gp_format<bits8 ,rgb_t > : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat24bppRGB > {};
-template <> struct gil_to_gp_format<bits8 ,rgba_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat32bppARGB > {};
-template <> struct gil_to_gp_format<bits16,gray_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppGrayScale> {};
-template <> struct gil_to_gp_format<bits16,rgb_t > : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat48bppRGB > {};
-template <> struct gil_to_gp_format<bits16,rgba_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat64bppARGB > {};
-
-/// @see GdiplusPixelFormats.h: ARGB -> little endian BGRA
+/// @see GdiplusPixelFormats.h: ARGB -> little endian BGRA
 typedef bgra_layout_t gp_alpha_layout_t;
 typedef bgr_layout_t gp_layout_t;
 
-typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, gp_layout_t>::type gp_rgb565_pixel_t;
 
-struct unpacked_view_gp_format
-{
- template <class View>
- struct apply
- {
- typedef gil_to_gp_format
- <
- typename channel_type <View>::type,
- typename color_space_type<View>::type
- > type;
- };
-};
+typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, gp_layout_t>::type gp_bgr565_pixel_t;
 
-struct packed_view_gp_format
-{
- template <class View>
- struct apply
- {
- typedef typename mpl::if_
- <
- is_same<typename View::value_type, gp_rgb565_pixel_t>,
- mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppRGB565>,
- mpl::integral_c<Gdiplus::PixelFormat, PixelFormatUndefined>
- >::type type;
- };
-};
 
+template <typename Pixel, bool IsPlanar>
+struct gil_to_gp_format : mpl::integral_c<Gdiplus::PixelFormat, PixelFormatUndefined> {};
 
-typedef mpl::vector5
+template <> struct gil_to_gp_format<gp_bgr565_pixel_t, false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppRGB565 > {};
+template <> struct gil_to_gp_format<bgr8_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat24bppRGB > {};
+template <> struct gil_to_gp_format<bgra8_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat32bppARGB > {};
+template <> struct gil_to_gp_format<gray16_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppGrayScale> {};
+template <> struct gil_to_gp_format<bgr16_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat48bppRGB > {};
+template <> struct gil_to_gp_format<bgra16_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat64bppARGB > {};
+#if (GDIPVER >= 0x0110)
+template <> struct gil_to_gp_format<cmyk8_pixel_t , false> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat32bppCMYK > {};
+#endif // (GDIPVER >= 0x0110)
+
+
+typedef mpl::
+#if (GDIPVER >= 0x0110)
+ vector4
+#else
+ vector3
+#endif
 <
- pixel_format_type<pixel<bits8 , gp_layout_t >, false>,
- pixel_format_type<pixel<bits8 , gp_alpha_layout_t>, false>,
- pixel_format_type<pixel<bits16, gray_layout_t >, false>,
- pixel_format_type<gp_rgb565_pixel_t , false>,
- pixel_format_type<cmyk_t , false>
+ image<bgr8_pixel_t , false>,
+ image<bgra8_pixel_t , false>,
+ image<gp_bgr565_pixel_t, false>
+ #if (GDIPVER >= 0x0110)
+ ,image<cmyk8_pixel_t , false>
+ #endif
> gp_supported_pixel_formats;
 
 
-template <class View>
 struct view_gp_format
- :
- mpl::eval_if_c
- <
- // Err, an 'official' way to detect this?
- ( mpl::size<typename View::value_type::layout_t::channel_mapping_t>::value <= sizeof( typename View::value_type ) ),
- mpl::identity<unpacked_view_gp_format>,
- mpl::identity< packed_view_gp_format>
- >::type::apply<View>::type
-{};
+{
+ template <class View>
+ struct apply : gil_to_gp_format<typename View::value_type, is_planar<View>::value> {};
+};
 
 
 typedef iterator_range<TCHAR const *> string_chunk_t;
@@ -230,6 +216,59 @@
         : Gdiplus::Rect( Gdiplus::Point( top_left.x, top_left.y ), Gdiplus::Size( bottom_right.x - top_left.x, bottom_right.y - top_left.y ) ) {}
 };
 
+class gp_image;
+
+template <>
+struct formatted_image_traits<gp_image>
+{
+ typedef Gdiplus::PixelFormat format_t;
+
+ typedef gp_supported_pixel_formats supported_pixel_formats_t;
+
+ typedef gp_roi roi_t;
+
+ typedef view_gp_format view_to_native_format;
+
+ template <class View>
+ struct is_supported : detail::is_supported<view_gp_format::apply<View>::value> {};
+
+ struct view_data_t : public Gdiplus::BitmapData
+ {
+ template <typename View>
+ view_data_t( View const & view ) : p_roi_( 0 ) { set_bitmapdata_for_view( view ); }
+
+ template <typename View>
+ view_data_t( View const & view, gp_roi::offset_t const & offset )
+ :
+ p_roi_( static_cast<gp_roi const *>( optional_roi_.address() ) )
+ {
+ set_bitmapdata_for_view( view );
+ new ( optional_roi_.address() ) gp_roi( offset, Width, Height );
+ }
+
+ Gdiplus::Rect const * const p_roi_;
+
+ private:
+ template <typename View>
+ void set_bitmapdata_for_view( View const & view )
+ {
+ Width = view.width();
+ Height = view.height();
+ Stride = view.pixels().row_size();
+ PixelFormat = view_gp_format::apply<View>::value;
+ Scan0 = formatted_image_base::get_raw_data( view );
+ Reserved = 0;
+ }
+
+ void operator=( view_data_t const & );
+
+ private:
+ aligned_storage<sizeof( gp_roi ), alignment_of<gp_roi>::value>::type optional_roi_;
+ };
+
+ BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( Gdiplus::ARGB ) );
+};
+
 
 #if defined(BOOST_MSVC)
 # pragma warning( push )
@@ -239,14 +278,14 @@
 class gp_image
     :
     private gp_guard,
- public detail::formatted_image<gp_image, gp_supported_pixel_formats, gp_roi>
+ public detail::formatted_image<gp_image>
 {
 public:
- template <class View>
- struct is_supported : detail::is_supported<view_gp_format<View>::value> {};
+ static std::size_t format_size( format_t const format )
+ {
+ return Gdiplus::GetPixelFormatSize( format );
+ }
 
- BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( Gdiplus::ARGB ) );
-
 private:
     // - GP wants wide-char paths
     // - we received a narrow-char path
@@ -314,7 +353,7 @@
                 view.width(),
                 view.height(),
                 view.pixels().row_size(),
- view_gp_format<View>::value,
+ view_gp_format::apply<View>::value,
                 get_raw_data( view ),
                 &pBitmap_
             )
@@ -332,7 +371,7 @@
     {
         using namespace Gdiplus;
         REAL width, height;
- verify_result( Gdiplus::DllExports::GdipGetImageDimension( const_cast<Gdiplus::GpBitmap *>( pBitmap_ ), &width, &height ) );
+ verify_result( DllExports::GdipGetImageDimension( const_cast<GpBitmap *>( pBitmap_ ), &width, &height ) );
         return point2<std::ptrdiff_t>( static_cast<std::ptrdiff_t>( width ), static_cast<std::ptrdiff_t>( height ) );
     }
 
@@ -345,138 +384,147 @@
 private: // Private formatted_image_base interface.
     friend base_t;
 
- Gdiplus::PixelFormat get_format() const
+ format_t format() const
     {
- using namespace Gdiplus;
- PixelFormat format;
- verify_result( DllExports::GdipGetImagePixelFormat( pBitmap_, &format ) );
- return format;
+ format_t pixel_format;
+ verify_result( Gdiplus::DllExports::GdipGetImagePixelFormat( pBitmap_, &pixel_format ) );
+ return pixel_format;
     }
 
- image_type_id current_image_type_id() const
+ format_t closest_gil_supported_format() const
     {
- switch ( get_format() )
+ //http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.gdi/2008-01/msg00044.html
+ switch ( format() )
         {
+ case PixelFormat16bppGrayScale:
             case PixelFormat48bppRGB :
+ case PixelFormat32bppRGB :
             case PixelFormat24bppRGB :
- return 0;
+ return
+ PixelFormat24bppRGB;
 
+ case PixelFormat64bppPARGB :
+ case PixelFormat32bppPARGB :
             case PixelFormat64bppARGB :
             case PixelFormat32bppARGB :
- return 1;
-
- case PixelFormat16bppGrayScale:
- return 2;
+ case PixelFormat16bppARGB1555 :
+ return
+ PixelFormat32bppARGB;
 
             case PixelFormat16bppRGB565 :
- return 3;
+ case PixelFormat16bppRGB555 :
+ case PixelFormat8bppIndexed :
+ case PixelFormat4bppIndexed :
+ case PixelFormat1bppIndexed :
+ return
+ PixelFormat16bppRGB565;
 
+ #if (GDIPVER >= 0x0110)
             case PixelFormat32bppCMYK :
- return 4;
+ return
+ PixelFormat32bppCMYK;
+ #endif // (GDIPVER >= 0x0110)
 
             default:
                 BOOST_ASSERT( !"Should not get reached." ); __assume( false );
+ return PixelFormatUndefined;
+ }
 
- case PixelFormat16bppRGB555 :
-
- case PixelFormat64bppPARGB :
- case PixelFormat32bppPARGB :
+ }
 
- case PixelFormat16bppARGB1555 :
+ image_type_id current_image_format_id() const
+ {
+ return image_format_id( closest_gil_supported_format() );
+ }
 
- case PixelFormat32bppRGB :
+ static image_type_id image_format_id( format_t const closest_gil_supported_format )
+ {
+ switch ( closest_gil_supported_format )
+ {
+ case PixelFormat24bppRGB : return 0;
+ case PixelFormat32bppARGB : return 1;
+ case PixelFormat16bppGrayScale: return 2;
+ case PixelFormat16bppRGB565 : return 3;
+ #if (GDIPVER >= 0x0110)
+ case PixelFormat32bppCMYK : return 4;
+ #endif
 
- case PixelFormat1bppIndexed :
- case PixelFormat4bppIndexed :
- case PixelFormat8bppIndexed :
+ default:
+ BOOST_ASSERT( !"Should not get reached." ); __assume( false );
                 return unsupported_format;
         }
     }
 
 public:
     template <typename View>
- void convert_to_prepared_view( View const & view ) const
+ void generic_convert_to_prepared_view( View const & view ) const
     {
- BOOST_STATIC_ASSERT( detail::is_supported<view_gp_format<View>::value>::value );
-
         BOOST_ASSERT( !dimensions_mismatch( view ) );
+ //BOOST_ASSERT( !formats_mismatch ( view ) );
 
- using namespace Gdiplus;
-
- if ( detail::is_supported<view_gp_format<View>::value>::value )
- {
- PixelFormat const desired_format( view_gp_format<View>::value );
- pre_palettized_conversion<desired_format>( is_indexed<desired_format>::type() );
- copy_to_target( get_bitmap_data_for_view( view ) );
- }
- else
- {
- convert_to_prepared_view( view, default_color_converter() );
- }
+ BitmapData bitmapData;
+ Rect const rect( 0, 0, bitmapData.Width, bitmapData.Height );
+ ensure_result
+ (
+ DllExports::GdipBitmapLockBits
+ (
+ pBitmap_,
+ &rect,
+ ImageLockModeRead,
+ view_gp_format::apply<View>::value,
+ &bitmapData
+ )
+ );
+ copy_pixels // This must not throw!
+ (
+ interleaved_view
+ (
+ bitmapData.Width ,
+ bitmapData.Height,
+ gil_reinterpret_cast_c<typename View::value_type const *>( bitmapData.Scan0 ),
+ bitmapData.Stride
+ ),
+ view
+ );
+ verify_result( DllExports::GdipBitmapUnlockBits( pBitmap_, &bitmapData ) );
     }
 
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
+ void raw_convert_to_prepared_view( formatted_image_traits<gp_image>::view_data_t const & view_data ) const
     {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
+ BOOST_ASSERT( view_data.Scan0 );
 
         using namespace Gdiplus;
 
- PixelFormat const my_format ( get_format() );
- BitmapData bitmapData( get_bitmap_data_for_view( view ) );
-
- if ( my_format == view_gp_format<View>::value )
- {
- copy_to_target( bitmapData );
- }
- else
- {
- bool const can_do_in_place( can_do_inplace_transform<typename View::value_type>( my_format ) );
- if ( can_do_in_place )
- {
- bitmapData.PixelFormat = my_format;
- copy_to_target( bitmapData );
- transform( my_format, view, view, converter );
- }
- else
- {
- BOOST_ASSERT( bitmapData.Scan0 );
- typedef typename View::value_type pixel_t;
- pixel_t * const p_raw_view( static_cast<pixel_t *>( bitmapData.Scan0 ) );
- bitmapData.Scan0 = 0;
-
- Rect const rect( 0, 0, bitmapData.Width, bitmapData.Height );
- ensure_result
- (
- DllExports::GdipBitmapLockBits
- (
- pBitmap_,
- &rect,
- ImageLockModeRead,
- bitmapData.PixelFormat,
- &bitmapData
- )
- );
- transform
- (
- bitmapData.PixelFormat,
- interleaved_view( bitmapData.Width, bitmapData.Height, p_raw_view, bitmapData.Stride ),
- view,
- converter
- );
- verify_result( DllExports::GdipBitmapUnlockBits( pBitmap_, &bitmapData ) );
- }
- }
+ BitmapData * const pMutableBitmapData( const_cast<BitmapData *>( static_cast<BitmapData const *>( &view_data ) ) );
+ GpStatus const load_result
+ (
+ DllExports::GdipBitmapLockBits
+ (
+ pBitmap_,
+ view_data.p_roi_,
+ ImageLockModeRead | ImageLockModeUserInputBuf,
+ view_data.PixelFormat,
+ pMutableBitmapData
+ )
+ );
+ GpStatus const unlock_result( DllExports::GdipBitmapUnlockBits( pBitmap_, pMutableBitmapData ) );
+ ensure_result( load_result );
+ verify_result( unlock_result );
     }
 
- template <typename View>
- void copy_to_prepared_view( View const & view ) const
+
+ void copy_to_target( formatted_image_traits<gp_image>::view_data_t const & view_data ) const
     {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- BOOST_ASSERT( !formats_mismatch<View>() );
- convert_to_prepared_view( view );
+ BOOST_ASSERT( view_data.Width == static_cast<UINT>( dimensions().x ) );
+ BOOST_ASSERT( view_data.Height == static_cast<UINT>( dimensions().y ) );
+ //...this need not hold as it can be used to perform GDI+ default
+ //internal colour conversion...maybe i'll provide another worker
+ //function...
+ //BOOST_ASSERT( view_data.PixelFormat == format () );
+ raw_convert_to_prepared_view( view_data );
     }
 
+
 private:
     static CLSID const & png_codec()
     {
@@ -504,70 +552,6 @@
         return clsid;
     }
 
- template <typename View>
- static BYTE * get_raw_data( View const & view )
- {
- // A private implementation of interleaved_view_get_raw_data() that
- // works with packed pixel views.
- BOOST_STATIC_ASSERT((!is_planar<View>::value /*&& view_is_basic<View>::value*/));
- BOOST_STATIC_ASSERT((boost::is_pointer<typename View::x_iterator>::value));
-
- BOOST_STATIC_ASSERT( detail::is_supported<view_gp_format<View>::value>::value );
-
- return static_cast<BYTE *>( &gil::at_c<0>( view( 0, 0 ) ) );
- }
-
- template <typename View>
- Gdiplus::BitmapData get_bitmap_data_for_view( View const & view ) const
- {
- using namespace Gdiplus;
-
- BitmapData const bitmapData =
- {
- view.width(),
- view.height(),
- view.pixels().row_size(),
- view_gp_format<View>::value,
- get_raw_data( view ),
- 0
- };
- return bitmapData;
- }
-
- void convert_to_target( Gdiplus::BitmapData const & bitmapData ) const
- {
- BOOST_ASSERT( bitmapData.Scan0 );
-
- using namespace Gdiplus;
-
- BitmapData * const pMutableBitmapData( const_cast<BitmapData *>( &bitmapData ) );
- GpStatus const load_result
- (
- DllExports::GdipBitmapLockBits
- (
- pBitmap_,
- 0,
- ImageLockModeRead | ImageLockModeUserInputBuf,
- bitmapData.PixelFormat,
- pMutableBitmapData
- )
- );
- GpStatus const unlock_result( DllExports::GdipBitmapUnlockBits( pBitmap_, pMutableBitmapData ) );
- ensure_result( load_result );
- verify_result( unlock_result );
- }
-
-
- void copy_to_target( Gdiplus::BitmapData const & bitmapData ) const
- {
- BOOST_ASSERT( bitmapData.Width == static_cast<UINT>( dimensions().x ) );
- BOOST_ASSERT( bitmapData.Height == static_cast<UINT>( dimensions().y ) );
- //...this need not hold as it can be used to perform GDI+ default
- //internal colour conversion...maybe i'll provide another worker
- //function...
- //BOOST_ASSERT( bitmapData.PixelFormat == get_format () );
- convert_to_target( bitmapData );
- }
 
     template <Gdiplus::PixelFormat desired_format>
     void pre_palettized_conversion( mpl::true_ /*is_indexed*/ )
@@ -576,7 +560,7 @@
         // A GDI+ 1.1 (a non-distributable version, distributed with MS Office
         // 2003 and MS Windows Vista and MS Windows 7) 'enhanced'/'tuned'
         // version of the conversion routine for indexed/palettized image
- // formats. Unless/until proven usefull, pretty much still a GDI+ 1.1
+ // formats. Unless/until proven useful, pretty much still a GDI+ 1.1
         // tester...
     
         BOOST_ASSERT( !has_alpha<desired_format>::value && "Is this possible for indexed formats?" );
@@ -623,210 +607,12 @@
     template <Gdiplus::PixelFormat desired_format>
     void pre_palettized_conversion( mpl::false_ /*not is_indexed*/ ) const {}
 
-
- template <class SourceView, class DestinationView, class CC>
- static void transform( Gdiplus::PixelFormat const sourceFormat, SourceView const & src, DestinationView const & dst, CC const & converter )
- {
- // Reinterpret cast/type punning ugliness is required for dynamic
- // in-place detection/optimization...to be cleaned up...
- typedef typename DestinationView::value_type target_pixel_t;
- switch ( sourceFormat )
- {
- case PixelFormat48bppRGB :
- case PixelFormat24bppRGB :
- typedef pixel<bits8, gp_layout_t> gp_rgb24_pixel_t;
- typedef view_type_from_pixel<gp_rgb24_pixel_t, false>::type gp_rgb24_view_t ;
- transform_pixels
- (
- *gil_reinterpret_cast_c<gp_rgb24_view_t const *>( &src ),
- dst,
- color_convert_deref_fn
- <
- gp_rgb24_pixel_t const &,
- target_pixel_t,
- CC
- >( converter )
- );
- break;
-
- case PixelFormat64bppARGB :
- case PixelFormat32bppARGB :
- typedef pixel<bits8, gp_alpha_layout_t> gp_argb32_pixel_t;
- typedef view_type_from_pixel<gp_argb32_pixel_t, false>::type gp_argb32_view_t ;
- transform_pixels
- (
- *gil_reinterpret_cast_c<gp_argb32_view_t const *>( &src ),
- dst,
- color_convert_deref_fn
- <
- gp_argb32_pixel_t const &,
- target_pixel_t,
- CC
- >( converter )
- );
- break;
-
- case PixelFormat16bppGrayScale:
- typedef view_type_from_pixel<gray16_pixel_t, false>::type gp_gray16_view_t ;
- transform_pixels
- (
- *gil_reinterpret_cast_c<gp_gray16_view_t const *>( &src ),
- dst,
- color_convert_deref_fn
- <
- gray16_ref_t,
- target_pixel_t,
- CC
- >( converter )
- );
- break;
-
- case PixelFormat16bppRGB555 :
- BOOST_ASSERT( !"What about unused bits?" );
- typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,5,5>, gp_layout_t>::type gp555_pixel_t ;
- typedef view_type_from_pixel<gp555_pixel_t, false>::type gp_rgb16_555_view_t;
- //...this...does not compile...how to specify a layout with an
- //unused bit?
- //transform_pixels
- //(
- // *gil_reinterpret_cast_c<gp_rgb16_555_view_t const *>( &src ),
- // dst,
- // color_convert_deref_fn
- // <
- // gp555_pixel_t const &,
- // target_pixel_t,
- // CC
- // >( converter )
- //);
- break;
-
- case PixelFormat16bppRGB565 :
- BOOST_ASSERT( !"Why does this fail to compile?" );
- typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, gp_layout_t>::type gp565_pixel_t ;
- typedef view_type_from_pixel<gp565_pixel_t, false>::type gp_rgb16_565_view_t;
- //transform_pixels
- //(
- // *gil_reinterpret_cast_c<gp_rgb16_565_view_t const *>( &src ),
- // dst,
- // color_convert_deref_fn
- // <
- // //gp565_pixel_t const &,
- // //gp_rgb16_565_view_t::reference,
- // gp565_pixel_t::const_reference,
- // target_pixel_t,
- // CC
- // >( converter )
- //);
- break;
-
- case PixelFormat32bppCMYK :
- BOOST_ASSERT( !"What about byte order/endianess here?" );
- typedef view_type_from_pixel<cmyk_t, false>::type gp_cmyk_view_t;
- //...this...does not compile...
- //transform_pixels
- //(
- // *gil_reinterpret_cast_c<gp_cmyk_view_t const *>( &src ),
- // dst,
- // color_convert_deref_fn
- // <
- // cmyk_t const &,
- // target_pixel_t,
- // CC
- // >( converter )
- //);
- break;
-
- case PixelFormat64bppPARGB :
- case PixelFormat32bppPARGB :
- BOOST_ASSERT( !"What about premultiplied alpha?" );
- break;
-
- case PixelFormat16bppARGB1555 :
- BOOST_ASSERT( !"What about 'high colour with 1 bit alpha?" );
- break;
-
- case PixelFormat32bppRGB :
- BOOST_ASSERT( !"What about 4 byte pixels without alpha?" );
- break;
-
- case PixelFormat1bppIndexed :
- case PixelFormat4bppIndexed :
- case PixelFormat8bppIndexed :
- BOOST_ASSERT( !"What about indexed colour?" );
- break;
-
- default: BOOST_ASSERT( !"Should not get reached." ); __assume( false );
- }
- }
-
-
     void save_to( char const * const pFilename, CLSID const & encoderID ) const { save_to( wide_path( pFilename ), encoderID ); }
     void save_to( wchar_t const * const pFilename, CLSID const & encoderID ) const
     {
         ensure_result( Gdiplus::DllExports::GdipSaveImageToFile( pBitmap_, pFilename, &encoderID, NULL ) );
     }
 
-
- template <typename Pixel>
- bool can_do_inplace_transform() const
- {
- return can_do_inplace_transform<Pixel>( get_format() );
- }
-
- template <typename Pixel>
- bool can_do_inplace_transform( Gdiplus::PixelFormat const my_format ) const
- {
- return ( Gdiplus::GetPixelFormatSize( my_format ) == sizeof( Pixel ) );
- }
-
-
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return dimensions_mismatch( view.dimensions() );
- }
-
- bool dimensions_mismatch( point2<std::ptrdiff_t> const & other_dimensions ) const
- {
- return other_dimensions != dimensions();
- }
-
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( view_gp_format<View>::value );
- }
-
- bool formats_mismatch( Gdiplus::PixelFormat const other_format ) const
- {
- return other_format != get_format();
- }
-
-
- template <typename View>
- void ensure_dimensions_match( View const & view ) const
- {
- ensure_dimensions_match( view.dimensions() );
- }
-
- void ensure_dimensions_match( point2<std::ptrdiff_t> const & other_dimensions ) const
- {
- io_error_if( dimensions_mismatch( other_dimensions ), "input view size does not match source image size" );
- }
-
-
- template <typename View>
- void ensure_formats_match() const
- {
- ensure_formats_match( view_gp_format<View>::value );
- }
-
- void ensure_formats_match( Gdiplus::PixelFormat const other_format ) const
- {
- io_error_if( formats_mismatch( other_format ), "input view type is incompatible with the image type" );
- }
-
 private:
     friend class gp_view_base;
 
@@ -867,7 +653,7 @@
                 &bitmap_,
                 p_roi,
                 lock_mode,
- bitmap.get_format(),
+ bitmap.format(),
                 &bitmapData_
             )
         );

Modified: sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp 2010-04-18 17:10:01 EDT (Sun, 18 Apr 2010)
@@ -42,7 +42,7 @@
 
 template <typename View>
 inline void read_view( gp_image const & image, View const & view ) {
- image.copy_to_view( view );
+ image.copy_to( view, ensure_dimensions_match(), ensure_formats_match() );
 }
 
 template <typename View>
@@ -53,8 +53,7 @@
 
 template <typename Image>
 inline void read_image( gp_image const & gp_image, Image & gil_image ) {
- gil_image.recreate( gp_image.get_dimensions(), sizeof( Gdiplus::ARGB ) );
- gp_image.copy_to_prepared_view( view( gil_image ) );
+ gp_image.copy_to_image( gil_image, synchronize_dimensions(), ensure_formats_match() );
 }
 
 template <typename Image>
@@ -91,9 +90,8 @@
 
 
 template <typename Image,typename CC>
-inline void read_and_convert_image( gp_image const & gp_image, Image & gil_image, CC cc ) {
- gil_image.recreate( gp_image.get_dimensions(), sizeof( Gdiplus::ARGB ) );
- gp_image.convert_to_prepared_view( view( gil_image ), cc );
+inline void read_and_convert_image( gp_image const & gp_image, Image & gil_image, CC const cc ) {
+ gp_image.copy_to_image( gil_image, synchronize_dimensions() , cc );
 }
 
 template <typename Image,typename CC>
@@ -109,8 +107,7 @@
 
 template <typename Image>
 inline void read_and_convert_image( gp_image const & gp_image, Image & gil_image ) {
- gil_image.recreate( gp_image.dimensions(), sizeof( Gdiplus::ARGB ) );
- gp_image.convert_to_prepared_view( view( gil_image ) );
+ gp_image.copy_to_image( gil_image, synchronize_dimensions() , synchronize_formats() );
 }
 
 template <typename Image>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk