Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64081 - sandbox/gil/boost/gil/extension/io2
From: dsaritz_at_[hidden]
Date: 2010-07-17 05:27:22


Author: psiha
Date: 2010-07-17 05:27:20 EDT (Sat, 17 Jul 2010)
New Revision: 64081
URL: http://svn.boost.org/trac/boost/changeset/64081

Log:
Moved the offset classes to the public namespace.
Moved a few more utility functions to the formatted_image_base class.
Added the formatted_image<>::image_id_finder functor and used it to implement the new formatted_image<>::image_format_id() member function.
Added planar image support to the formatted_image<>::in_place_converter_t functor.

Minor other refactoring and stylistic changes.
Text files modified:
   sandbox/gil/boost/gil/extension/io2/formatted_image.hpp | 340 ++++++++++++++++++++++++++++-----------
   1 files changed, 239 insertions(+), 101 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-07-17 05:27:20 EDT (Sat, 17 Jul 2010)
@@ -26,6 +26,7 @@
 
 #include <boost/gil/extension/dynamic_image/any_image.hpp>
 
+#include <boost/compressed_pair.hpp>
 #ifdef _DEBUG
 #include <boost/detail/endian.hpp>
 #endif // _DEBUG
@@ -101,7 +102,7 @@
         typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
         typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
 
- if ( is_unsigned<SrcChannelV>::value )
+ if ( std::tr1::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 );
@@ -135,13 +136,107 @@
 #endif
 
 
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class offset_view_t
+/// \todo document properly...
+///
+////////////////////////////////////////////////////////////////////////////////
+
+template <class View, typename Offset>
+class offset_view_t
+{
+public:
+ typedef View view_t ;
+ typedef Offset offset_t;
+
+public:
+ offset_view_t( View const & view, Offset const & offset ) : view_( view ), offset_( offset ) {}
+
+ typename View::point_t dimensions() const
+ {
+ return offset_dimensions( original_view().dimensions(), offset() );
+ }
+
+ View const & original_view() const { return view_ ; }
+ Offset const & offset () const { return offset_; }
+
+private:
+ static typename View::point_t offset_dimensions
+ (
+ typename View::point_t view_dimensions,
+ typename View::point_t::value_type const offset
+ )
+ {
+ //return typename View::point_t( view_dimensions.x, view_dimensions.y + offset );
+ view_dimensions.y += offset;
+ return view_dimensions;
+ }
+
+ static typename View::point_t offset_dimensions
+ (
+ typename View::point_t view_dimensions,
+ typename View::point_t const & offset
+ )
+ {
+ return view_dimensions += offset;
+ }
+
+private:
+ View const & view_ ;
+ typename call_traits<Offset>::param_type offset_;
+};
+
+
+template <class View, typename Offset>
+offset_view_t<View, Offset> offset_view( View const & view, Offset const & offset ) { return offset_view_t<View, Offset>( view, offset ); }
+
+
 namespace detail
 {
 //------------------------------------------------------------------------------
 
+#ifndef _UNICODE
+ typedef char TCHAR;
+#else
+ typedef wchar_t TCHAR;
+#endif
 typedef iterator_range<TCHAR const *> string_chunk_t;
 
 
+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; }
+
+
+template <typename View>
+struct get_original_view_t;
+
+template <typename Locator>
+struct get_original_view_t<image_view<Locator> > { typedef image_view<Locator> type; };
+
+template <typename View, typename Offset>
+struct get_original_view_t<offset_view_t<View, Offset> > { typedef View type; };
+
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \class formatted_image_base
@@ -165,6 +260,13 @@
         return dimensions_mismatch( mine, view.dimensions() );
     }
 
+ template <class View, typename Offset>
+ static bool dimensions_mismatch( dimensions_t const & mine, offset_view_t<View, Offset> const & offset_view )
+ {
+ dimensions_t const other( offset_view.dimensions() );
+ return !( ( mine.x >= other.x ) && ( mine.y >= other.y ) );
+ }
+
     static void do_ensure_dimensions_match( dimensions_t const & mine, dimensions_t const & other )
     {
         io_error_if( dimensions_mismatch( mine, other ), "input view size does not match source image size" );
@@ -176,6 +278,12 @@
         do_ensure_dimensions_match( mine, view.dimensions() );
     }
 
+ template <class View, typename Offset>
+ static void do_ensure_dimensions_match( dimensions_t const & mine, offset_view_t<View, Offset> const & offset_view )
+ {
+ io_error_if( dimensions_mismatch( mine, offset_view ), "input view size does not match source image size" );
+ }
+
     static void do_ensure_formats_match( bool const formats_mismatch )
     {
         io_error_if( formats_mismatch, "input view format does not match source image format" );
@@ -266,66 +374,6 @@
 };
 
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \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; }
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -410,6 +458,28 @@
 
     typedef mpl::range_c<std::size_t, 0, mpl::size<supported_pixel_formats>::value> valid_type_id_range_t;
 
+ struct image_id_finder
+ {
+ image_id_finder( format_t const format ) : format_( format ), image_id_( static_cast<unsigned int>( -1 ) ) {}
+
+ template <typename ImageIndex>
+ void operator()( ImageIndex )
+ {
+ format_t const image_format
+ (
+ formatted_image_traits<Impl>::view_to_native_format::apply<typename mpl::at<supported_pixel_formats, ImageIndex>::type::view_t>::value
+ );
+ if ( image_format == this->format_ )
+ {
+ BOOST_ASSERT( image_id_ == -1 );
+ image_id_ = ImageIndex::value;
+ }
+ }
+
+ format_t /*const*/ format_;
+ unsigned int image_id_;
+ };
+
 private:
     Impl & impl() { return static_cast<Impl &>( *this ); }
     Impl const & impl() const { return static_cast<Impl const &>( *this ); }
@@ -418,7 +488,7 @@
     template <typename View>
     bool dimensions_mismatch( View const & view ) const
     {
- return dimensions_mismatch( view.dimensions() );
+ return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
     }
 
     bool dimensions_mismatch( dimensions_t const & other_dimensions ) const
@@ -429,7 +499,7 @@
     template <class View>
     void do_ensure_dimensions_match( View const & view ) const
     {
- formatted_image_base::do_ensure_dimensions_match( impl().dimensions(), view.dimensions() );
+ formatted_image_base::do_ensure_dimensions_match( impl().dimensions(), view );
     }
 
     template <typename View>
@@ -455,17 +525,29 @@
     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 ) );
+ return ( Impl::format_size( my_format ) == memunit_step( get_original_view_t<View>::type::x_iterator() )/*sizeof( typename get_original_view_t<View>::type::value_type )*/ );
+ }
+
+ // A generic implementation...impl classes are encouraged to provide more
+ // efficient overrides...
+ static image_type_id image_format_id( format_t const closest_gil_supported_format )
+ {
+ // This (linear search) will be transformed to a switch...
+ image_id_finder finder( closest_gil_supported_format );
+ mpl::for_each<valid_type_id_range_t>( ref( finder ) );
+ BOOST_ASSERT( finder.image_id_ != -1 );
+ return finder.image_id_;
     }
 
 public: // Views...
     template <typename View>
- void copy_to( View & view, assert_dimensions_match, assert_formats_match ) const
+ void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
     {
+ BOOST_STATIC_ASSERT( View::value_type::is_mutable );
         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().raw_copy_to_prepared_view
         (
             formatted_image_traits<Impl>::view_data_t
             (
@@ -476,57 +558,55 @@
     }
 
     template <typename View>
- void copy_to( View & view, assert_dimensions_match, ensure_formats_match ) const
+ void copy_to( View const & view, assert_dimensions_match, ensure_formats_match ) const
     {
         impl().do_ensure_formats_match<View>();
         impl().copy_to( view, assert_dimensions_match(), assert_formats_match() );
     }
 
     template <typename View>
- void copy_to( View & view, ensure_dimensions_match, assert_formats_match ) const
+ void copy_to( View const & view, ensure_dimensions_match, assert_formats_match ) const
     {
         impl().do_ensure_dimensions_match( view );
         impl().copy_to( view, assert_dimensions_match(), assert_formats_match() );
     }
 
     template <typename View>
- void copy_to( View & view, ensure_dimensions_match, ensure_formats_match ) const
+ void copy_to( View const & view, ensure_dimensions_match, ensure_formats_match ) const
     {
- 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, ensure_dimensions_match, synchronize_formats ) const
+ void copy_to( View const & view, ensure_dimensions_match, synchronize_formats ) const
     {
         impl().do_ensure_dimensions_match( view );
         impl().copy_to( view, assert_dimensions_match(), synchronize_formats() );
     }
 
     template <typename View>
- void copy_to( View & view, assert_dimensions_match, synchronize_formats ) const
+ void copy_to( View const & view, assert_dimensions_match, synchronize_formats ) const
     {
         BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- impl().raw_convert_to_prepared_view
+ bool const can_use_raw
         (
- formatted_image_traits<Impl>::view_data_t
- (
- original_view ( view ),
- get_offset<offset_t>( view )
- )
+ formatted_image_traits<Impl>::is_supported<View>::value &&
+ formatted_image_traits<Impl>::builtin_conversion
         );
+ default_convert_to_worker( view, mpl::bool_<can_use_raw>() );
     }
 
+
     template <typename FormatConverter, typename View>
- void copy_to( View & view, ensure_dimensions_match, FormatConverter const & format_converter ) const
+ void copy_to( View const & 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
+ void copy_to( View const & view, assert_dimensions_match, FormatConverter const & format_converter ) const
     {
         BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
         impl().convert_to_prepared_view( view, format_converter );
@@ -580,63 +660,102 @@
 
 private:
     template <class View, typename CC>
- struct in_place_converter_t
+ class in_place_converter_t
     {
+ public:
         typedef void result_type;
 
- in_place_converter_t( CC const & cc, View const & view ) : cc_( cc ), view_( view ) {}
+ in_place_converter_t( CC const & cc, View const & view ) : members_( cc, view ) {}
 
         template <std::size_t index>
- void operator()( mpl::integral_c<std::size_t, index> const & ) const
+ void operator()( mpl::integral_c<std::size_t, index> ) 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 );
+ BOOST_ASSERT( is_planar<View>::value == is_planar<view_t>::value ); //zzz...make this a static assert...
+ if ( is_planar<View>::value )
+ {
+ for ( unsigned int plane( 0 ); plane < num_channels<View>::value; ++plane )
+ {
+ BOOST_ASSERT( sizeof( view_t ) == sizeof( View ) ); //zzz...make this a static assert...
+ for_each_pixel( nth_channel_view( *gil_reinterpret_cast_c<view_t const *>( &view() ), plane ), *this );
+ }
+ }
+ else
+ {
+ BOOST_ASSERT( sizeof( view_t ) == sizeof( View ) ); //zzz...make this a static assert...
+ 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 ) );
+ convert_aux( srcP, is_planar<View>() );
         }
 
         void operator=( in_place_converter_t const & other )
         {
- BOOST_ASSERT( this->view_ == other.view_ );
- this->cc_ = other.cc_;
+ BOOST_ASSERT( this->view() == other.view() );
+ this->cc() = other.cc();
+ }
+
+ private:
+ CC & cc () { return members_.first (); }
+ CC const & cc () const { return members_.first (); }
+ View const & view() const { return members_.second(); }
+
+ template <typename SrcP>
+ void convert_aux( SrcP & srcP, mpl::true_ /*is planar*/ )
+ {
+ typedef typename nth_channel_view_type<View>::type::value_type DstP;
+ BOOST_ASSERT( sizeof( SrcP ) == sizeof( DstP ) ); //zzz...make this a static assert...
+ cc()( srcP, *const_cast<DstP *>( gil_reinterpret_cast_c<DstP const *>( &srcP ) ) );
+ }
+
+ template <typename SrcP>
+ void convert_aux( SrcP & srcP, mpl::false_ /*is not planar*/ )
+ {
+ typedef typename View::value_type DstP;
+ BOOST_ASSERT( sizeof( SrcP ) == sizeof( DstP ) ); //zzz...make this a static assert...
+ cc()( srcP, *const_cast<DstP *>( gil_reinterpret_cast_c<DstP const *>( &srcP ) ) );
         }
 
- CC cc_;
- View const & view_;
+ private:
+ compressed_pair<CC, View const &> members_;
     };
 
     template <class View, typename CC>
- struct generic_converter_t
+ class generic_converter_t
     {
+ public:
         typedef void result_type;
 
         generic_converter_t( Impl const & impl, CC const & cc, View const & view )
- : impl_( impl ), cc_( cc ), view_( view ) {}
+ : impl_( impl ), cc_view_( cc, 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_ );
+ 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_;
+ this->cc() = other.cc();
         }
 
- Impl const & impl_;
- CC cc_ ;
- View const & view_;
+ private:
+ CC & cc () { return cc_view_.first (); }
+ CC const & cc () const { return cc_view_.first (); }
+ View const & view() const { return cc_view_.second(); }
+
+ private:
+ Impl const & impl_ ;
+ compressed_pair<CC, View const &> cc_view_;
     };
 
     template <class TargetView, class CC>
@@ -671,7 +790,7 @@
             converter,
             mpl::bool_
             <
- is_plain_in_memory_view<View>::value &&
+ is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
                 formatted_image_traits<Impl>::is_supported<View>::value
>()
         );
@@ -684,9 +803,9 @@
         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 ) );
+ typename formatted_image_traits<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 );
+ impl().raw_copy_to_prepared_view( view_data );
             in_place_transform( current_image_format_id, original_view( view ), converter );
         }
         else
@@ -700,6 +819,25 @@
     {
         generic_transform( Impl::image_format_id( impl().closest_gil_supported_format() ), view, converter );
     }
+
+ template <typename View>
+ void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
+ {
+ impl().raw_convert_to_prepared_view
+ (
+ formatted_image_traits<Impl>::view_data_t
+ (
+ original_view ( view ),
+ get_offset<offset_t>( view )
+ )
+ );
+ }
+
+ template <typename View>
+ void default_convert_to_worker( View const & view, mpl::false_ /*cannot use raw*/ ) const
+ {
+ impl().convert_to_prepared_view( view, default_color_converter() );
+ }
 };
 
 


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