Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73403 - in sandbox/gil/boost/gil/extension/io2: . detail devices
From: dsaritz_at_[hidden]
Date: 2011-07-27 17:06:53


Author: psiha
Date: 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
New Revision: 73403
URL: http://svn.boost.org/trac/boost/changeset/73403

Log:
Massive refactoring:
 - broken large modules and classes into smaller ones:
   - formatted_image into formatted_image, backend_reader, backend_writer, reader_for, writer_for and dynamic_image.hpp
   - individual backend classes into a base class and separate reader and writer classes
 - introduced the 'device' concept to remove IO code duplication between different backends
 - moved everything into the gil::io namespace
 - renamed sequential_*_access_state classes to sequential_*_read_state.
Refactoring done for the WIC and LibTIFF backends.

Minor other refactoring and stylistic changes.
Added:
   sandbox/gil/boost/gil/extension/io2/backend_reader.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
   sandbox/gil/boost/gil/extension/io2/backend_writer.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
   sandbox/gil/boost/gil/extension/io2/devices/ (props changed)
   sandbox/gil/boost/gil/extension/io2/devices/c_file.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/devices/c_file_descriptor.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/devices/c_file_name.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/devices/device.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/dynamic_image.hpp
      - copied, changed from r68172, /sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
   sandbox/gil/boost/gil/extension/io2/libtiff_reader.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp
   sandbox/gil/boost/gil/extension/io2/libtiff_writer.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp
   sandbox/gil/boost/gil/extension/io2/reader.hpp
      - copied, changed from r68172, /sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
   sandbox/gil/boost/gil/extension/io2/wic_reader.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/wic_image.hpp
   sandbox/gil/boost/gil/extension/io2/wic_writer.hpp
      - copied, changed from r73054, /sandbox/gil/boost/gil/extension/io2/wic_image.hpp
   sandbox/gil/boost/gil/extension/io2/writer.hpp
      - copied, changed from r68172, /sandbox/gil/boost/gil/extension/io2/formatted_image.hpp
Text files modified:
   sandbox/gil/boost/gil/extension/io2/backend_reader.hpp | 508 +---------------
   sandbox/gil/boost/gil/extension/io2/backend_writer.hpp | 1074 ----------------------------------
   sandbox/gil/boost/gil/extension/io2/detail/io_error.hpp | 5
   sandbox/gil/boost/gil/extension/io2/detail/shared.hpp | 9
   sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp | 25
   sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp | 171 -----
   sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp | 307 ++-------
   sandbox/gil/boost/gil/extension/io2/dynamic_image.hpp | 1012 --------------------------------
   sandbox/gil/boost/gil/extension/io2/formatted_image.hpp | 948 ------------------------------
   sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp | 1053 +++-------------------------------
   sandbox/gil/boost/gil/extension/io2/libtiff_reader.hpp | 625 ++------------------
   sandbox/gil/boost/gil/extension/io2/libtiff_writer.hpp | 1218 ---------------------------------------
   sandbox/gil/boost/gil/extension/io2/reader.hpp | 1123 +-----------------------------------
   sandbox/gil/boost/gil/extension/io2/wic_image.hpp | 377 -----------
   sandbox/gil/boost/gil/extension/io2/wic_reader.hpp | 347 ----------
   sandbox/gil/boost/gil/extension/io2/wic_writer.hpp | 527 +----------------
   sandbox/gil/boost/gil/extension/io2/writer.hpp | 1062 ++--------------------------------
   17 files changed, 598 insertions(+), 9793 deletions(-)

Copied: sandbox/gil/boost/gil/extension/io2/backend_reader.hpp (from r73054, /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/backend_reader.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -1,11 +1,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file formatted_image.hpp
-/// -------------------------
+/// \file backend_reader.hpp
+/// ------------------------
 ///
-/// Base CRTP class for all image implementation classes/backends.
+/// Base CRTP class for backend readers.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,39 +15,24 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef backend_reader_hpp__3E2ACB3B_F45F_404B_A603_0396518B183C
+#define backend_reader_hpp__3E2ACB3B_F45F_404B_A603_0396518B183C
 #pragma once
-#ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
-#define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 //------------------------------------------------------------------------------
 #include "format_tags.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/io_error.hpp"
 #include "detail/switch.hpp"
 
-#include "boost/gil/extension/dynamic_image/any_image.hpp"
-#include "boost/gil/extension/io/dynamic_io.hpp" //...zzz...
-#include "boost/gil/packed_pixel.hpp"
 #include "boost/gil/planar_pixel_iterator.hpp"
 #include "boost/gil/planar_pixel_reference.hpp"
 #include "boost/gil/typedefs.hpp"
 
 #include <boost/compressed_pair.hpp>
-#ifdef _DEBUG
-#include <boost/detail/endian.hpp>
-#endif // _DEBUG
-#include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/for_each.hpp>
-#include <boost/mpl/integral_c.hpp>
-#include <boost/mpl/map.hpp>
-#include <boost/mpl/vector_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/mpl/size_t_fwd.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/decay.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -55,6 +40,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 
 struct assert_dimensions_match {};
 struct ensure_dimensions_match {};
@@ -64,56 +52,6 @@
 struct ensure_formats_match {};
 struct synchronize_formats {};
 
-#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> >
-{
- packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
- {
- typedef packed_channel_value<DestPackedNumBits> DstChannelV;
-
- typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
- typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
-
- 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)));
- }
- }
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#endif
-
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
@@ -179,14 +117,6 @@
 {
 //------------------------------------------------------------------------------
 
-#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(); }
 
@@ -230,105 +160,7 @@
 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; };
 
-
-////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class configure_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to open the
-/// target/file and then be configured for the desired view.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct configure_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( target, specified_format ),
- view_data_( view )
- {}
-
- void write_default() { Writer::write_default( view_data_ ); }
- void write () { Writer::write ( view_data_ ); }
-
- private:
- ViewDataHolder const view_data_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- single_format_writer_wrapper( WriterTarget const & target, format_tag const specified_format = OnlyFormat )
- :
- Writer( target )
- {
- BOOST_VERIFY( specified_format == OnlyFormat );
- }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class open_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to be configured
-/// for/created from the desired view and then open the target/file.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct open_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( view ),
- target_ ( target ),
- specified_format_( specified_format )
- {}
-
- void write_default() { Writer::write_default( target_, specified_format_ ); }
- void write () { Writer::write ( target_, specified_format_ ); }
-
- private:
- typename call_traits<WriterTarget>::param_type const target_;
- format_tag const specified_format_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- template <typename View>
- single_format_writer_wrapper( View const & view ) : Writer( view ) {}
-
- void write_default( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write_default( target ); }
- void write ( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write ( target ); }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image_base
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class formatted_image_base : noncopyable
+class backend_reader_base
 {
 public:
     typedef point2<std::ptrdiff_t> dimensions_t;
@@ -336,18 +168,6 @@
     typedef unsigned int image_type_id;
     static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
 
-public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- static bool can_do_row_access () { return true ; }
- static bool can_do_strip_access() { return false; }
- static bool can_do_tile_access () { return false; }
-
- static bool can_do_roi_access () { return false; }
- static bool can_do_vertical_roi_access() { return true ; }
-
 protected:
     static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
     template <class View>
@@ -434,117 +254,19 @@
         
         return subimage_view( offset_view.original_view(), 0, 0, width, height );
     }
-
-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;
- template <typename Index>
- result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
- };
-
- struct throw_type_mismatch
- {
- typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( true ); }
- };
-
- template <typename Type, typename SupportedPixelFormats>
- struct check_type_match
- {
- typedef bool result_type;
- template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
- {
- 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>
- result_type operator()( Index const & ) const
- {
- BOOST_ASSERT( !"Default case must not have been reached!" );
- BF_UNREACHABLE_CODE
- return result_type();
- }
- };
-
- template <typename Images>
- class make_dynamic_image
- {
- public:
- make_dynamic_image( any_image<Images> & image ) : image_( image ) {}
-
- template <class Image>
- Image & apply()
- {
- image_.move_in( Image() );
- return image_. BOOST_NESTED_TEMPLATE _dynamic_cast<Image>();
- }
-
- protected:
- any_image<Images> & image_;
- };
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class formatted_image
+/// \class backend_reader
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-template <class Impl>
-class formatted_image : public formatted_image_base
+template <class Backend>
+class backend_reader : public backend_reader_base
 {
-public:
- typedef typename formatted_image_traits<Impl>::format_t format_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;
-
- template <typename PixelType, bool IsPlanar>
- struct native_format
- : formatted_image_traits<Impl>::gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<PixelType, IsPlanar>::type
- {};
-
- template <typename T> struct get_native_format;
-
- template <typename PixelType, typename IsPlanar>
- struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
-
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
-
- template <typename Locator>
- struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
-
+protected:
     template <class View>
     struct has_supported_format
     {
@@ -552,114 +274,20 @@
         typedef typename get_original_view_t<View>::type original_view_t;
 
     public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
+ typedef typename formatted_image_traits<Backend>:: BOOST_NESTED_TEMPLATE is_supported
         <
             typename original_view_t::value_type,
             is_planar<original_view_t>::value
> type;
         BOOST_STATIC_CONSTANT( bool, value = type::value );
     };
-
- typedef any_image<supported_pixel_formats> dynamic_image_t;
-
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
-
- BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
 
 protected:
- typedef formatted_image base_t;
-
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
+ typedef typename formatted_image_traits<Backend>::format_t format_t;
+ typedef typename formatted_image_traits<Backend>::view_data_t view_data_t;
 
 private:
- template <typename Images, typename dimensions_policy, typename formats_policy>
- class read_dynamic_image : make_dynamic_image<Images>
- {
- private:
- typedef make_dynamic_image<Images> base;
-
- public:
- typedef void result_type;
-
- read_dynamic_image( any_image<Images> & image, Impl & impl )
- :
- base ( image ),
- impl_( impl )
- {}
-
- template <class Image>
- void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
-
- template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
-
- private:
- Impl & impl_;
- };
-
- template <typename dimensions_policy, typename formats_policy>
- class write_dynamic_view
- {
- public:
- typedef void result_type;
-
- write_dynamic_view( Impl & impl ) : impl_( impl ) {}
-
- template <class View>
- void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
-
- private:
- Impl & impl_;
- };
-
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- typedef mpl::range_c<std::size_t, 0, mpl::size<supported_pixel_formats>::value> valid_type_id_range_t;
+ typedef mpl::range_c<std::size_t, 0, mpl::size<typename Backend::supported_pixel_formats>::value> valid_type_id_range_t;
 
     struct image_id_finder
     {
@@ -668,11 +296,11 @@
         template <typename ImageIndex>
         void operator()( ImageIndex )
         {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
+ typedef typename mpl::at<typename Backend::supported_pixel_formats, ImageIndex>::type pixel_format_t;
+ format_t const image_format( typename Backend:: template get_native_format<pixel_format_t>::value );
             if ( image_format == this->format_ )
             {
- BOOST_ASSERT( image_id_ == unsupported_format );
+ BOOST_ASSERT_MSG( image_id_ == unsupported_format, "Image ID already found." );
                 image_id_ = ImageIndex::value;
             }
         }
@@ -685,7 +313,8 @@
     };
 
 private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
+ // MSVC++ (8,9,10) generates code to check whether this == 0.
+ typedef typename Backend::native_reader Impl;
     Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
     Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
 
@@ -713,7 +342,7 @@
         return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
     }
 
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
+ bool formats_mismatch( format_t const other_format ) const
     {
         return ( other_format != impl().closest_gil_supported_format() ) != false;
     }
@@ -728,7 +357,7 @@
     }
 
     template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
+ bool can_do_inplace_transform( format_t const my_format ) const
     {
         return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
     }
@@ -749,7 +378,7 @@
     }
 
     template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
+ view_data_t get_view_data( offset_view_t<View, typename Backend::offset_t> const & offset_view ) const
     {
         return view_data_t
         (
@@ -759,6 +388,9 @@
     }
 
 public: // Low-level (row, strip, tile) access
+ // Generic implementations: impl classes are encouraged to provide more
+ // efficient overrides.
+
     std::size_t pixel_size() const
     {
         return impl().cached_format_size( impl().format() );
@@ -769,8 +401,6 @@
         return impl().pixel_size() * impl().dimensions().x;
     }
 
- // 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 into a switch...
@@ -825,8 +455,8 @@
         BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
         typedef mpl::bool_
         <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
+ has_supported_format <View >::value &&
+ formatted_image_traits<Backend>::builtin_conversion
> can_use_raw_t;
         default_convert_to_worker( view, can_use_raw_t() );
     }
@@ -849,7 +479,7 @@
     template <typename Image, typename FormatsPolicy>
     Image copy_to_image( FormatsPolicy const formats_policy ) const
     {
- Image image( impl().dimensions(), formatted_image_traits<Impl>::desired_alignment );
+ Image image( impl().dimensions(), formatted_image_traits<Backend>::desired_alignment );
         impl().copy_to( view( image ), assert_dimensions_match(), formats_policy );
         return image;
     }
@@ -863,38 +493,18 @@
     template <typename Image, typename FormatsPolicy>
     void copy_to_image( Image & image, synchronize_dimensions, FormatsPolicy const formats_policy ) const
     {
- impl().do_synchronize_dimensions( image, impl().dimensions(), formatted_image_traits<Impl>::desired_alignment );
+ impl().do_synchronize_dimensions( image, impl().dimensions(), formatted_image_traits<Backend>::desired_alignment );
         impl().copy_to( view( image ), assert_dimensions_match(), formats_policy );
     }
 
- template <typename Images, typename dimensions_policy, typename formats_policy>
- void copy_to_image( any_image<Images> & im ) const
- {
- switch_<valid_type_id_range_t>
- (
- impl().current_image_format_id(),
- read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
- );
- }
-
- template <typename Views, typename dimensions_policy, typename formats_policy>
- void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
- {
- typedef write_dynamic_view<dimensions_policy, formats_policy> op_t;
- op_t op( *this );
- apply_operation
- (
- runtime_view,
- dynamic_io_fnobj<write_is_supported, op_t>( &op )
- );
- }
-
 public: // Offset factory
     template <class View>
     static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
+ offset_view_t<View, typename Backend::offset_t>
+ offset_view( View const & view, typename Backend::offset_t const offset )
+ {
+ return offset_view_t<View, offset_t>( view, offset );
+ }
 
 public: // Utility 'quick-wrappers'...
     template <class Source, class Image>
@@ -918,36 +528,6 @@
         read( file_name.c_str(), view );
     }
 
- template <class Target, class View>
- static void write( Target & target, View const & view )
- {
- typedef typename writer_for<Target>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( target, view ).write_default();
- }
-
- template <class Target, class View>
- static void write( Target * p_target, View const & view )
- {
- typedef typename writer_for<Target const *>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( p_target, view ).write_default();
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> const & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
 private:
     template <class View, typename CC>
     class in_place_converter_t
@@ -958,7 +538,7 @@
         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
+ void operator()( mpl::size_t<index> ) const
         {
             typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
             BOOST_ASSERT( is_planar<View>::value == is_planar<view_t>::value ); //zzz...make this a static assert...
@@ -1025,7 +605,7 @@
             : impl_( impl ), cc_view_( cc, view ) {}
 
         template <std::size_t index>
- void operator()( mpl::integral_c<std::size_t, index> const & ) const
+ void operator()( mpl::size_t<index> ) const
         {
             typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t my_view_t;
             impl_. BOOST_NESTED_TEMPLATE generic_convert_to_prepared_view<my_view_t>( view(), cc() );
@@ -1104,7 +684,7 @@
         if ( can_do_inplace_transform<View>( current_format ) )
         {
             view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
+ if ( formatted_image_traits<Backend>::builtin_conversion )
                 view_data.set_format( current_format );
             else
                 BOOST_ASSERT( current_format == impl().format() );
@@ -1140,8 +720,10 @@
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // formatted_image_hpp
+#endif // backend_reader_hpp

Copied: sandbox/gil/boost/gil/extension/io2/backend_writer.hpp (from r73054, /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/backend_writer.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -1,11 +1,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file formatted_image.hpp
-/// -------------------------
+/// \file backend_writer.hpp
+/// ------------------------
 ///
-/// Base CRTP class for all image implementation classes/backends.
+/// Base CRTP class for backend writers.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,39 +15,18 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef backend_writer_hpp__D65DA8BE_0605_4A62_AC73_B557F7A94DA6
+#define backend_writer_hpp__D65DA8BE_0605_4A62_AC73_B557F7A94DA6
 #pragma once
-#ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
-#define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 //------------------------------------------------------------------------------
 #include "format_tags.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/io_error.hpp"
-#include "detail/switch.hpp"
 
-#include "boost/gil/extension/dynamic_image/any_image.hpp"
-#include "boost/gil/extension/io/dynamic_io.hpp" //...zzz...
-#include "boost/gil/packed_pixel.hpp"
-#include "boost/gil/planar_pixel_iterator.hpp"
-#include "boost/gil/planar_pixel_reference.hpp"
 #include "boost/gil/typedefs.hpp"
 
-#include <boost/compressed_pair.hpp>
-#ifdef _DEBUG
-#include <boost/detail/endian.hpp>
-#endif // _DEBUG
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/mpl/integral_c.hpp>
-#include <boost/mpl/map.hpp>
-#include <boost/mpl/vector_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>
-#include <boost/type_traits/decay.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
+#include "boost/static_assert.hpp"
+#include "boost/type_traits/is_same.hpp"
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -55,117 +34,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-
-struct assert_dimensions_match {};
-struct ensure_dimensions_match {};
-struct synchronize_dimensions {};
-
-struct assert_formats_match {};
-struct ensure_formats_match {};
-struct synchronize_formats {};
-
-#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> >
+namespace io
 {
- packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
- {
- typedef packed_channel_value<DestPackedNumBits> DstChannelV;
-
- typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
- typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
-
- 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)));
- }
- }
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#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_ ;
- Offset offset_;
-};
-
+//------------------------------------------------------------------------------
 
 ////////////////////////////////////////////////////////////////////////////////
 /// \class formatted_image_traits
@@ -175,749 +46,30 @@
 template <class Impl>
 struct formatted_image_traits;
 
+
 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 get_offset( View const & ) { return Offset(); }
-template <typename Offset, class View>
-Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
-
-template <typename Offset>
-Offset get_offset_x( Offset const & ) { return Offset(); }
-template <typename Offset>
-Offset const & get_offset_x( point2<Offset> const & offset ) { return offset.x; }
-
-template <typename Offset>
-Offset get_offset_y( Offset const & offset ) { return offset; }
-template <typename Offset>
-Offset const & get_offset_y( point2<Offset> const & offset ) { return offset.y; }
-
-
-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 <class View>
-struct is_offset_view : mpl::false_ {};
-
-template <class View, typename Offset>
-struct is_offset_view<offset_view_t<View, Offset> > : mpl::true_ {};
-
-
-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; };
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class configure_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to open the
-/// target/file and then be configured for the desired view.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct configure_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( target, specified_format ),
- view_data_( view )
- {}
-
- void write_default() { Writer::write_default( view_data_ ); }
- void write () { Writer::write ( view_data_ ); }
-
- private:
- ViewDataHolder const view_data_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- single_format_writer_wrapper( WriterTarget const & target, format_tag const specified_format = OnlyFormat )
- :
- Writer( target )
- {
- BOOST_VERIFY( specified_format == OnlyFormat );
- }
- };
-};
-
-
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class open_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to be configured
-/// for/created from the desired view and then open the target/file.
+/// \class backend_writer
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-struct open_on_write_writer
+template <class Backend>
+class backend_writer
 {
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( view ),
- target_ ( target ),
- specified_format_( specified_format )
- {}
-
- void write_default() { Writer::write_default( target_, specified_format_ ); }
- void write () { Writer::write ( target_, specified_format_ ); }
-
- private:
- typename call_traits<WriterTarget>::param_type const target_;
- format_tag const specified_format_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- template <typename View>
- single_format_writer_wrapper( View const & view ) : Writer( view ) {}
-
- void write_default( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write_default( target ); }
- void write ( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write ( target ); }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image_base
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class formatted_image_base : noncopyable
-{
-public:
- typedef point2<std::ptrdiff_t> dimensions_t;
-
- typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
-
-public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- static bool can_do_row_access () { return true ; }
- static bool can_do_strip_access() { return false; }
- static bool can_do_tile_access () { return false; }
-
- static bool can_do_roi_access () { return false; }
- static bool can_do_vertical_roi_access() { return true ; }
-
-protected:
- static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
- template <class View>
- static bool dimensions_mismatch( dimensions_t const & mine, View const & view ) { 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 )
- {
- // Implementation note:
- // For offset target views all dimensions are allowed as they are
- // intended to load an image in steps so they must be allowed to be
- // smaller. They are also allowed to be bigger to allow GIL users to use
- // fixed 'sub' view, while loading an image in steps, whose size is not
- // an exact divisor of the source image dimensions.
- // The exception is for backends that support only vertical 'ROIs'/
- // offsets, for those the horizontal dimensions must match.
- // (19.09.2010.) (Domagoj Saric)
- //dimensions_t const other( offset_view.dimensions() );
- //return ( other.x < mine.x ) || ( other.y < mine.y );
- return is_pod<Offset>::value ? ( mine.x != offset_view.dimensions().x ) : false;
- }
-
- 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" );
- }
-
- template <class View>
- static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
- {
- 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" );
- }
-
- template <typename Image>
- static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
- {
- image.recreate( my_dimensions, alignment );
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // subview_for_offset()
- // --------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \brief Locally adjusts a view with a ROI/offset to prevent it exceeding
- /// the image dimensions when 'merged' with its offset. Done here so that
- /// backend classes do not need to handle this.
- /// \internal
- /// \throws nothing
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- static View subview_for_offset( dimensions_t const & my_dimensions, offset_view_t<View, Offset> const & offset_view )
- {
- dimensions_t const & target_dimensions( offset_view.original_view().dimensions() );
-
- bool const zero_x_offset( is_pod<Offset>::value );
- if ( zero_x_offset )
- {
- BOOST_ASSERT( get_offset_x( offset_view.offset() ) == 0 );
- BOOST_ASSERT( my_dimensions.x == target_dimensions.x );
- }
-
- unsigned int const width ( zero_x_offset ? target_dimensions.x : (std::min)( my_dimensions.x - get_offset_x( offset_view.offset() ), target_dimensions.x ) );
- unsigned int const height( (std::min)( my_dimensions.y - get_offset_y( offset_view.offset() ), target_dimensions.y ) );
-
- return subimage_view( offset_view.original_view(), 0, 0, width, height );
- }
-
-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;
- template <typename Index>
- result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
- };
-
- struct throw_type_mismatch
- {
- typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( true ); }
- };
-
- template <typename Type, typename SupportedPixelFormats>
- struct check_type_match
- {
- typedef bool result_type;
- template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
- {
- 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>
- result_type operator()( Index const & ) const
- {
- BOOST_ASSERT( !"Default case must not have been reached!" );
- BF_UNREACHABLE_CODE
- return result_type();
- }
- };
-
- template <typename Images>
- class make_dynamic_image
- {
- public:
- make_dynamic_image( any_image<Images> & image ) : image_( image ) {}
-
- template <class Image>
- Image & apply()
- {
- image_.move_in( Image() );
- return image_. BOOST_NESTED_TEMPLATE _dynamic_cast<Image>();
- }
-
- protected:
- any_image<Images> & image_;
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-class formatted_image : public formatted_image_base
-{
-public:
- typedef typename formatted_image_traits<Impl>::format_t format_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;
-
- template <typename PixelType, bool IsPlanar>
- struct native_format
- : formatted_image_traits<Impl>::gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<PixelType, IsPlanar>::type
- {};
-
- template <typename T> struct get_native_format;
-
- template <typename PixelType, typename IsPlanar>
- struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
-
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
-
- template <typename Locator>
- struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
-
- template <class View>
- struct has_supported_format
- {
- private:
- typedef typename get_original_view_t<View>::type original_view_t;
-
- public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
- <
- typename original_view_t::value_type,
- is_planar<original_view_t>::value
- > type;
- BOOST_STATIC_CONSTANT( bool, value = type::value );
- };
-
- typedef any_image<supported_pixel_formats> dynamic_image_t;
-
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
-
- BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
-
-protected:
- typedef formatted_image base_t;
-
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
-
-private:
- template <typename Images, typename dimensions_policy, typename formats_policy>
- class read_dynamic_image : make_dynamic_image<Images>
- {
- private:
- typedef make_dynamic_image<Images> base;
-
- public:
- typedef void result_type;
-
- read_dynamic_image( any_image<Images> & image, Impl & impl )
- :
- base ( image ),
- impl_( impl )
- {}
-
- template <class Image>
- void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
-
- template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
-
- private:
- Impl & impl_;
- };
-
- template <typename dimensions_policy, typename formats_policy>
- class write_dynamic_view
- {
- public:
- typedef void result_type;
-
- write_dynamic_view( Impl & impl ) : impl_( impl ) {}
-
- template <class View>
- void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
-
- private:
- Impl & impl_;
- };
-
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- 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_( unsupported_format ) {}
-
- template <typename ImageIndex>
- void operator()( ImageIndex )
- {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
- if ( image_format == this->format_ )
- {
- BOOST_ASSERT( image_id_ == unsupported_format );
- image_id_ = ImageIndex::value;
- }
- }
-
- format_t const format_ ;
- unsigned int image_id_;
-
- private:
- void operator=( image_id_finder const & );
- };
+ typedef typename formatted_image_traits<Backend>::view_data_t view_data_t;
 
 private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
+ // MSVC++ (8,9,10) generates code to check whether this == 0.
+ typedef typename Backend::native_writer Impl;
     Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
     Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
 
-protected:
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
- }
-
- 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 );
- }
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
- }
-
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
- {
- return ( other_format != impl().closest_gil_supported_format() ) != false;
- }
-
- 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>( impl().format() );
- }
-
- template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
- {
- return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
- }
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- View subview_for_offset( offset_view_t<View, Offset> const & offset_view ) const
- {
- return formatted_image_base::subview_for_offset( impl().dimensions(), offset_view );
- }
-
- template <typename View>
- static view_data_t get_view_data( View const & view )
- {
- return view_data_t( view );
- }
-
- template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
- {
- return view_data_t
- (
- subview_for_offset( offset_view ),
- offset_view.offset()
- );
- }
-
-public: // Low-level (row, strip, tile) access
- std::size_t pixel_size() const
- {
- return impl().cached_format_size( impl().format() );
- }
-
- std::size_t row_size() const
- {
- return impl().pixel_size() * impl().dimensions().x;
- }
-
- // 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 into 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_ != unsupported_format );
- return finder.image_id_;
- }
-
-public: // Views...
- template <typename View>
- void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
- {
- BOOST_STATIC_ASSERT( get_original_view_t<View>::type::value_type::is_mutable );
- BOOST_STATIC_ASSERT( has_supported_format<View>::value );
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- BOOST_ASSERT( !impl().formats_mismatch<View>() );
- impl().raw_copy_to_prepared_view( get_view_data( view ) );
- }
-
- template <typename View>
- 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 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 const & view, ensure_dimensions_match, ensure_formats_match ) const
- {
- impl().do_ensure_dimensions_match( view );
- impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
- }
-
- template <typename View>
- 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 const & view, assert_dimensions_match, synchronize_formats ) const
- {
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- typedef mpl::bool_
- <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
- > can_use_raw_t;
- default_convert_to_worker( view, can_use_raw_t() );
- }
-
- template <typename FormatConverter, typename View>
- void copy_to( View const & view, ensure_dimensions_match, FormatConverter & 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 const & view, assert_dimensions_match, FormatConverter & 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
- {
- 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_image( any_image<Images> & im ) const
- {
- switch_<valid_type_id_range_t>
- (
- impl().current_image_format_id(),
- read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
- );
- }
-
- template <typename Views, typename dimensions_policy, typename formats_policy>
- void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
- {
- typedef write_dynamic_view<dimensions_policy, formats_policy> op_t;
- op_t op( *this );
- apply_operation
- (
- runtime_view,
- dynamic_io_fnobj<write_is_supported, op_t>( &op )
- );
- }
-
-public: // Offset factory
- template <class View>
- static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
-
 public: // Utility 'quick-wrappers'...
- template <class Source, class Image>
- static void read( Source const & target, Image & image )
- {
- typedef typename reader_for<typename decay<Source>::type>::type reader_t;
- // The backend does not know how to read from the specified source type.
- BOOST_STATIC_ASSERT(( !is_same<reader_t, mpl::void_>::value ));
- reader_t( target ).copy_to_image( image, synchronize_dimensions(), synchronize_formats() );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> const & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
     template <class Target, class View>
     static void write( Target & target, View const & view )
     {
@@ -947,201 +99,15 @@
     {
         write( file_name.c_str(), view );
     }
-
-private:
- template <class View, typename CC>
- class in_place_converter_t
- {
- public:
- typedef void result_type;
-
- 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
- {
- typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
- 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 )
- {
- convert_aux( srcP, is_planar<View>() );
- }
-
- void operator=( in_place_converter_t const & other )
- {
- 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 ) ) );
- }
-
- private:
- compressed_pair<CC, View const &> members_;
- };
-
- template <class View, typename CC>
- class generic_converter_t
- {
- public:
- typedef void result_type;
-
- generic_converter_t( Impl const & impl, CC const & cc, View const & 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_. BOOST_NESTED_TEMPLATE 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();
- }
-
- 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>
- 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
- {
- return switch_<valid_type_id_range_t>
- (
- source_view_type_id,
- generic_converter_t<TargetView, CC>
- (
- impl(),
- cc,
- offset_new_view
- (
- // See the note for formatted_image_base::subview_for_offset()...
- subview_for_offset( view ),
- view
- )
- ),
- assert_default_case_not_reached<void>()
- );
- }
-
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- convert_to_prepared_view_worker
- (
- view,
- converter,
- mpl::bool_
- <
- is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
- has_supported_format < 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 current_format ( impl().closest_gil_supported_format() );
- unsigned int const current_image_format_id( impl().image_format_id( current_format ) );
- if ( can_do_inplace_transform<View>( current_format ) )
- {
- view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
- view_data.set_format( current_format );
- else
- BOOST_ASSERT( current_format == impl().format() );
- impl().raw_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 );
- }
-
- template <typename View>
- void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
- {
- impl().raw_convert_to_prepared_view( get_view_data( 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() );
- }
 };
 
-
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // formatted_image_hpp
+#endif // backend_writer_hpp

Modified: sandbox/gil/boost/gil/extension/io2/detail/io_error.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/io_error.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/io_error.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -29,6 +29,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -76,6 +79,8 @@
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Modified: sandbox/gil/boost/gil/extension/io2/detail/shared.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/shared.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/shared.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Common functionality for all GIL::IO backends.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2001.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,9 +15,9 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#pragma once
 #ifndef shared_hpp__DA4F9174_EBAA_43E8_BEDD_A273BBA88CE7
 #define shared_hpp__DA4F9174_EBAA_43E8_BEDD_A273BBA88CE7
+#pragma once
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 namespace boost
@@ -26,6 +26,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -101,6 +104,8 @@
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Modified: sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -26,7 +26,9 @@
 #if defined( _STDINT ) && !defined( _INTSAFE_H_INCLUDED_ )
     #define _INTSAFE_H_INCLUDED_
 #endif
-#define COM_NO_WINDOWS_H
+#ifndef COM_NO_WINDOWS_H
+ #define COM_NO_WINDOWS_H
+#endif // COM_NO_WINDOWS_H
 #include "objbase.h"
 #include "wincodec.h"
 //------------------------------------------------------------------------------
@@ -36,6 +38,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -60,7 +65,7 @@
 
 public:
     com_scoped_ptr() : baseCOMPtr_( NULL ) {}
- com_scoped_ptr( COMInterface const * const baseCOMPtr ) : baseCOMPtr_( baseCOMPtr ) { if ( baseCOMPtr ) baseCOMPtr->AddRef(); }
+ com_scoped_ptr( COMInterface const * const baseCOMPtr ) : baseCOMPtr_( baseCOMPtr ) { if ( baseCOMPtr ) baseCOMPtr ->AddRef(); }
     com_scoped_ptr( com_scoped_ptr const & source ) : baseCOMPtr_( source.baseCOMPtr_ ) { if ( baseCOMPtr_ ) baseCOMPtr_->AddRef(); }
     com_scoped_ptr( IUnknown & source )
     {
@@ -123,7 +128,7 @@
 public:
     static IWICImagingFactory & singleton()
     {
- BOOST_ASSERT( p_imaging_factory_ && "WIC not initialized!" );
+ BOOST_ASSERT_MSG( p_imaging_factory_, "WIC not initialized!" );
         return *p_imaging_factory_;
     }
 
@@ -133,14 +138,16 @@
         creator()
         {
             HRESULT hr( ::CoInitializeEx( 0, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY ) );
- if
- (
- ( ( hr != S_OK ) && ( hr != S_FALSE ) ) ||
- ( ( hr = wic_factory::p_imaging_factory_.create_instance( CLSID_WICImagingFactory ) ) != S_OK )
- )
+ if ( SUCCEEDED( hr ) )
+ hr = wic_factory::p_imaging_factory_.create_instance( CLSID_WICImagingFactory );
+
+ if ( FAILED( hr ) )
                 io_error( "Boost.GIL failed to load external library." ); //...zzz...duplicated...
+
+ BOOST_ASSERT( hr == S_OK );
             BOOST_ASSERT( wic_factory::p_imaging_factory_ );
         }
+
         ~creator()
         {
             wic_factory::p_imaging_factory_.release();
@@ -178,6 +185,8 @@
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Modified: sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -31,6 +31,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -53,184 +56,36 @@
 class wide_path
 {
 public:
- explicit wide_path( char const * const pFilename )
+ explicit wide_path( char const * const p_file_name )
     {
- BOOST_ASSERT( pFilename );
- BOOST_ASSERT( std::strlen( pFilename ) < wideFileName_.size() );
- char const * pSource ( pFilename );
- wchar_t * pDestination( wideFileName_.begin() );
+ BOOST_ASSERT( p_file_name );
+ BOOST_ASSERT( std::strlen( p_file_name ) < wide_file_name_.size() );
+ char const * pSource ( p_file_name );
+ wchar_t * pDestination( wide_file_name_.begin() );
         do
         {
             *pDestination++ = *pSource;
         } while ( *pSource++ );
- BOOST_ASSERT( pDestination < wideFileName_.end() );
+ BOOST_ASSERT( pDestination < wide_file_name_.end() );
     }
 
- operator wchar_t const * () const { return wideFileName_.begin(); }
+ operator wchar_t const * () const { return wide_file_name_.begin(); }
 
 private:
- boost::array<wchar_t, MAX_PATH> wideFileName_;
+ boost::array<wchar_t, MAX_PATH> wide_file_name_;
 };
 
 
 #pragma warning( push )
 #pragma warning( disable : 4355 ) // 'this' used in base member initializer list.
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class input_FILE_for_IStream_extender
-/// \internal
-/// \brief Helper wrapper for classes that can construct from IStream objects.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class IStream_capable_class>
-class __declspec( novtable ) input_FILE_for_IStream_extender
- :
- private FileReadStream,
- public IStream_capable_class
-{
-public:
- input_FILE_for_IStream_extender( FILE & file )
- :
- FileReadStream ( file ),
- IStream_capable_class( static_cast<IStream &>( *this ) )
- {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class output_FILE_for_IStream_extender
-/// \internal
-/// \brief Helper wrapper for classes that can construct from IStream objects.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class IStream_capable_class>
-class __declspec( novtable ) output_FILE_for_IStream_extender
- :
- private FileWriteStream,
- public IStream_capable_class
-{
-public:
- output_FILE_for_IStream_extender( FILE & file )
- :
- FileWriteStream ( file ),
- IStream_capable_class( static_cast<IStream &>( *this ) )
- {}
-
- template <typename A2> //...zzz...
- output_FILE_for_IStream_extender( FILE & file, A2 const & a2 )
- :
- FileWriteStream ( file ),
- IStream_capable_class( static_cast<IStream &>( *this ), a2 )
- {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class output_file_name_for_IStream_extender
-/// \internal
-/// \brief Helper wrapper for classes that can construct from IStream objects.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class IStream_capable_class>
-class __declspec( novtable ) output_file_name_for_IStream_extender
- :
- private FileHandleWriteStream,
- public IStream_capable_class
-{
-public:
- output_file_name_for_IStream_extender( wchar_t const * const file_name )
- :
- FileHandleWriteStream( do_open( file_name ) ),
- IStream_capable_class( static_cast<IStream &>( *this ) )
- {}
-
- template <typename A2> //...zzz...
- output_file_name_for_IStream_extender( wchar_t const * const file_name, A2 const & a2 )
- :
- FileHandleWriteStream( do_open( file_name ) ),
- IStream_capable_class( static_cast<IStream &>( *this ), a2 )
- {}
-
- ~output_file_name_for_IStream_extender() { BOOST_VERIFY( ::CloseHandle( file_ ) ); }
-
-private:
- static HANDLE do_open( wchar_t const * const file_name )
- {
- HANDLE const handle
- (
- ::CreateFileW
- (
- file_name,
- GENERIC_WRITE,
- 0,
- 0,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL
- )
- );
- io_error_if_not( handle, "File open failure" );
- return handle;
- }
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class memory_chunk_for_IStream_extender
-/// \internal
-/// \brief Helper wrapper for classes that can construct from IStream objects.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class IStream_capable_class>
-class __declspec( novtable ) memory_chunk_for_IStream_extender
- :
- private MemoryReadStream,
- public IStream_capable_class
-{
-public:
- memory_chunk_for_IStream_extender( memory_chunk_t const & in_memory_image )
- :
- MemoryReadStream ( in_memory_image ),
- IStream_capable_class( static_cast<IStream &>( *this ) )
- {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class writable_memory_chunk_for_IStream_extender
-/// \internal
-/// \brief Helper wrapper for classes that can construct from IStream objects.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class IStream_capable_class>
-class __declspec( novtable ) writable_memory_chunk_for_IStream_extender
- :
- private MemoryWriteStream,
- public IStream_capable_class
-{
-public:
- writable_memory_chunk_for_IStream_extender( writable_memory_chunk_t const & in_memory_image )
- :
- MemoryWriteStream ( in_memory_image ),
- IStream_capable_class( static_cast<IStream &>( *this ) )
- {}
-};
-
 #pragma warning( pop )
 
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Modified: sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -3,9 +3,9 @@
 /// \file windows_shared_istreams.hpp
 /// ---------------------------------
 ///
-/// Helper IStream implementations for in-memory and FILE base IO.
+/// Windows IStream implementation(s) for the GIL.IO2 device concept.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,31 +15,33 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#pragma once
 #ifndef windows_shared_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
 #define windows_shared_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
+#pragma once
 //------------------------------------------------------------------------------
 #include "platform_specifics.hpp"
+#include "boost/gil/extension/io2/devices/device.hpp"
 
 #include "boost/gil/utilities.hpp"
 
 #include "boost/range/iterator_range.hpp"
 
+#ifndef COM_NO_WINDOWS_H
+ #define COM_NO_WINDOWS_H
+#endif // COM_NO_WINDOWS_H
 #include "objbase.h"
 #include "objidl.h"
 #include "unknwn.h"
 //------------------------------------------------------------------------------
 namespace boost
 {
-
-//...zzz...duplicated from memory_mapping.hpp...clean this up...
-typedef iterator_range<unsigned char const *> memory_chunk_t;
-typedef iterator_range<unsigned char *> writable_memory_chunk_t;
-
 //------------------------------------------------------------------------------
 namespace gil
 {
 //------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -48,7 +50,6 @@
 #pragma warning( disable: 4373 ) // previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
 #pragma warning( disable: 4481 ) // nonstandard extension used: override specifier 'override'
 
-
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \class StreamBase
@@ -58,16 +59,19 @@
 
 class __declspec( novtable ) StreamBase : public IStream, noncopyable
 {
+public:
+ static void * operator new( std::size_t, void * const p_placeholder ) { return p_placeholder; }
+
 #ifndef NDEBUG
 protected:
- StreamBase() : ref_cnt_( 1 ) {}
- ~StreamBase() { assert( ref_cnt_ == 1 ); }
+ StreamBase() : ref_cnt_( 1 ) {}
+ ~StreamBase() { BOOST_ASSERT( ref_cnt_ == 1 ); }
 #endif // NDEBUG
 
 protected:
     static HRESULT not_implemented()
     {
- assert( !"Should not get called!" );
+ BOOST_ASSERT( !"Should not get called!" );
         return E_NOTIMPL;
     }
 
@@ -88,9 +92,9 @@
 private:
     HRESULT STDMETHODCALLTYPE Stat( STATSTG * const pstatstg, DWORD const grfStatFlag ) override
     {
- assert( pstatstg );
+ BOOST_ASSERT( pstatstg );
 
- assert( grfStatFlag & STATFLAG_NONAME );
+ BOOST_ASSERT( grfStatFlag & STATFLAG_NONAME );
 
         std::memset( pstatstg, 0, sizeof( *pstatstg ) );
 
@@ -107,11 +111,11 @@
 
         {
             LARGE_INTEGER const seek_position = { 0, 0 };
- HRESULT hresult = Seek( seek_position, SEEK_END, &pstatstg->cbSize ); assert( hresult == S_OK );
- hresult = Seek( seek_position, SEEK_SET, 0 ); assert( hresult == S_OK );
- assert( pstatstg->cbSize.QuadPart );
+ HRESULT hresult = Seek( seek_position, SEEK_END, &pstatstg->cbSize ); BOOST_ASSERT( hresult == S_OK );
+ hresult = Seek( seek_position, SEEK_SET, 0 ); BOOST_ASSERT( hresult == S_OK );
+ BOOST_ASSERT( pstatstg->cbSize.QuadPart );
         }
-
+
         //pstatstg->grfMode : http://msdn.microsoft.com/en-us/library/ms891273.aspx
 
         return S_OK;
@@ -152,8 +156,8 @@
         #endif // NDEBUG
     }
 
- void * operator new ( size_t );
- void operator delete( void * );
+ static void * operator new ( std::size_t );
+ //...zzz...because of placement new...static void operator delete( void * );
 
 #ifndef NDEBUG
     int ref_cnt_;
@@ -163,67 +167,59 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class FileStreamBase
-/// ---------------------
+/// \class device_stream_base
+/// -------------------------
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-class __declspec( novtable ) FileStreamBase : public StreamBase
+template <class Device>
+class __declspec( novtable ) device_stream_base : public StreamBase
 {
 protected:
- FileStreamBase( FILE & file ) : file_( file ) {}
+ device_stream_base( typename Device::handle_t const handle ) : handle_( handle ) {}
 
 private:
     HRESULT STDMETHODCALLTYPE Seek( LARGE_INTEGER const dlibMove, DWORD const dwOrigin, ULARGE_INTEGER * const plibNewPosition ) override
     {
- bool const x64( sizeof( long ) == sizeof( dlibMove.QuadPart ) );
- assert( x64 || ( dlibMove.HighPart == 0 ) || ( dlibMove.HighPart == -1 ) );
- long const offset( x64 ? static_cast<long>( dlibMove.QuadPart ) : dlibMove.LowPart );
+ BOOST_STATIC_ASSERT( detail::device_base::beginning == STREAM_SEEK_SET );
+ BOOST_STATIC_ASSERT( detail::device_base::current_position == STREAM_SEEK_CUR );
+ BOOST_STATIC_ASSERT( detail::device_base::end == STREAM_SEEK_END );
 
- BOOST_STATIC_ASSERT( SEEK_SET == STREAM_SEEK_SET );
- BOOST_STATIC_ASSERT( SEEK_CUR == STREAM_SEEK_CUR );
- BOOST_STATIC_ASSERT( SEEK_END == STREAM_SEEK_END );
+ BOOST_ASSERT( ( dwOrigin >= STREAM_SEEK_SET ) && ( dwOrigin <= STREAM_SEEK_END ) );
 
- assert( ( dwOrigin >= SEEK_SET ) && ( dwOrigin <= SEEK_END ) );
+ intmax_t const offset( static_cast<intmax_t>( dlibMove.QuadPart ) );
+
+ bool const success( Device::seek_long( static_cast<detail::device_base::seek_origin>( dwOrigin ), offset, handle_ ) );
 
- int const result
- (
- x64
- ? /*std*/::_fseeki64( &file_, offset, dwOrigin )
- : /*std*/::fseek ( &file_, offset, dwOrigin )
- );
         if ( plibNewPosition )
- plibNewPosition->QuadPart =
- x64
- ? /*std*/::_ftelli64( &file_ )
- : /*std*/::ftell ( &file_ );
+ plibNewPosition->QuadPart = Device::position_long( handle_ );
 
- bool const success( result == 0 );
         return success ? S_OK : S_FALSE;
     }
 
 protected:
- FILE & file_;
+ typename Device::handle_t const handle_;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class FileReadStream
-/// ---------------------
+/// \class input_device_stream
+/// --------------------------
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-class FileReadStream : public FileStreamBase
+template <class DeviceHandle>
+class input_device_stream : public device_stream_base<input_device<DeviceHandle> >
 {
 public:
- FileReadStream( FILE & file ) : FileStreamBase( file ) {}
+ input_device_stream( DeviceHandle const handle ) : device_stream_base( file ) {}
 
 private:
     HRESULT STDMETHODCALLTYPE Read( void * const pv, ULONG const cb, ULONG * const pcbRead ) override
     {
- assert( pv );
- size_t const size_read( /*std*/::fread( pv, 1, cb, &file_ ) );
+ BOOST_ASSERT( pv );
+ std::size_t const size_read( input_device<DeviceHandle>::read( pv, cb, handle_ ) );
         if ( pcbRead )
             *pcbRead = size_read;
         return ( size_read == cb ) ? S_OK : S_FALSE;
@@ -233,224 +229,77 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class FileWriteStream
-/// ----------------------
+/// \class output_device_stream
+/// ---------------------------
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-class FileWriteStream : public FileStreamBase
+template <class DeviceHandle>
+class output_device_stream : public device_stream_base<output_device<DeviceHandle> >
 {
 public:
- FileWriteStream( FILE & file ) : FileStreamBase( file ) {}
+ output_device_stream( DeviceHandle const handle ) : device_stream_base( handle ) {}
 
 private:
     HRESULT STDMETHODCALLTYPE Write( void const * const pv, ULONG const cb, ULONG * const pcbWritten ) override
     {
- assert( pv );
- size_t const size_written( /*std*/::fwrite( pv, 1, cb, &file_ ) );
+ BOOST_ASSERT( pv );
+ std::size_t const size_written( output_device<DeviceHandle>::write( pv, cb, handle_ ) );
         if ( pcbWritten )
             *pcbWritten = size_written;
         return ( size_written == cb ) ? S_OK : S_FALSE;
     }
 };
 
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class FileHandleStreamBase
-/// ---------------------------
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class __declspec( novtable ) FileHandleStreamBase : public StreamBase
-{
-protected:
- FileHandleStreamBase( HANDLE const file ) : file_( file ) {}
-
-private:
- HRESULT STDMETHODCALLTYPE Seek( LARGE_INTEGER const dlibMove, DWORD const dwOrigin, ULARGE_INTEGER * const plibNewPosition ) override
- {
- BOOST_STATIC_ASSERT( SEEK_SET == STREAM_SEEK_SET );
- BOOST_STATIC_ASSERT( SEEK_CUR == STREAM_SEEK_CUR );
- BOOST_STATIC_ASSERT( SEEK_END == STREAM_SEEK_END );
-
- assert( ( dwOrigin >= SEEK_SET ) && ( dwOrigin <= SEEK_END ) );
-
- BOOL const success( ::SetFilePointerEx( file_, dlibMove, reinterpret_cast<PLARGE_INTEGER>( plibNewPosition ), dwOrigin ) );
- return success ? S_OK : S_FALSE;
- }
-
-protected:
- HANDLE const file_;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class FileHandleReadStream
-/// ---------------------------
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class FileHandleReadStream : public FileHandleStreamBase
-{
-public:
- FileHandleReadStream( HANDLE const file ) : FileHandleStreamBase( file ) {}
-
-private:
- HRESULT STDMETHODCALLTYPE Read( void * const pv, ULONG const cb, ULONG * const pcbRead ) override
- {
- BOOL const success( ::ReadFile( file_, pv, cb, pcbRead, NULL ) );
- return success ? S_OK : S_FALSE;
- }
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class FileWriteStream
-/// ----------------------
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class FileHandleWriteStream : public FileHandleStreamBase
-{
-public:
- FileHandleWriteStream( HANDLE const file ) : FileHandleStreamBase( file ) {}
-
-private:
- HRESULT STDMETHODCALLTYPE Write( void const * const pv, ULONG const cb, ULONG * const pcbWritten ) override
- {
- BOOL const success( ::WriteFile( file_, pv, cb, pcbWritten, NULL ) );
- return success ? S_OK : S_FALSE;
- }
-};
+#pragma warning( pop )
 
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class MemoryStreamBase
-/// -----------------------
+/// \class device_stream_wrapper
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-class __declspec( novtable ) MemoryStreamBase : public StreamBase
-{
-protected:
- MemoryStreamBase( writable_memory_chunk_t const & in_memory_image )
- :
- pCurrentPosition_( in_memory_image.begin() ),
- memory_chunk_ ( in_memory_image )
- {
- assert( in_memory_image );
- }
-
-#ifndef NDEBUG
- ~MemoryStreamBase() { assert( pCurrentPosition_ >= memory_chunk_.begin() && pCurrentPosition_ <= memory_chunk_.end() ); }
-#endif // NDEBUG
-
- std::size_t adjust_size_for_remaining_space( std::size_t const size ) const
- {
- return std::min<size_t>( size, memory_chunk_.end() - pCurrentPosition_ );
- }
-
-private:
- HRESULT STDMETHODCALLTYPE Seek( LARGE_INTEGER const dlibMove, DWORD const dwOrigin, ULARGE_INTEGER * const plibNewPosition ) override
- {
- bool const x64( sizeof( long ) == sizeof( dlibMove.QuadPart ) );
- assert( x64 || ( dlibMove.HighPart == 0 ) || ( dlibMove.HighPart == -1 ) );
- long const offset( x64 ? static_cast<long>( dlibMove.QuadPart ) : dlibMove.LowPart );
-
- unsigned char * const pOrigin( pointer_for_origin( dwOrigin ) );
- unsigned char * const pTarget( pOrigin + offset );
- bool const success( pTarget >= memory_chunk_.begin() && pTarget <= memory_chunk_.end() );
- if ( success )
- pCurrentPosition_ = pTarget;
-
- if ( plibNewPosition )
- plibNewPosition->QuadPart = pCurrentPosition_ - memory_chunk_.begin();
-
- return success ? S_OK : S_FALSE;
- }
-
- unsigned char * pointer_for_origin( DWORD const origin )
- {
- switch ( static_cast<STREAM_SEEK>( origin ) )
- {
- case STREAM_SEEK_SET: return memory_chunk_.begin();
- case STREAM_SEEK_CUR: return pCurrentPosition_ ;
- case STREAM_SEEK_END: return memory_chunk_.end ();
- default: BF_UNREACHABLE_CODE
- }
- }
-
-protected:
- unsigned char * pCurrentPosition_;
- writable_memory_chunk_t const memory_chunk_ ;
-};
+struct __declspec( novtable ) istream_placeholder_helper : private StreamBase { void * handle; };
+typedef aligned_storage<sizeof( istream_placeholder_helper ), sizeof( void *)> istream_placeholder;
 
+#ifdef NDEBUG
+ BOOST_STATIC_ASSERT( sizeof( istream_placeholder ) <= sizeof( void * ) * 2 /* vtable + handle */ );
+#endif
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class MemoryReadStream
-/// -----------------------
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class MemoryReadStream : public MemoryStreamBase
+template <template <typename Handle> class IODeviceStream, class BackendWriter>
+class device_stream_wrapper
+ :
+ private istream_placeholder,
+ public BackendWriter
 {
 public:
- MemoryReadStream( memory_chunk_t const & in_memory_image )
+ template <class DeviceHandle>
+ device_stream_wrapper( DeviceHandle const handle )
         :
- MemoryStreamBase( *gil_reinterpret_cast_c<writable_memory_chunk_t const *>( &in_memory_image ) ) {}
-
-private:
- HRESULT STDMETHODCALLTYPE Read( void * const pv, ULONG const cb, ULONG * const pcbRead ) override
+ BackendWriter( *( new ( istream_placeholder::address() ) IODeviceStream<DeviceHandle>( handle ) ) )
     {
- assert( pv );
- size_t const size_read( adjust_size_for_remaining_space( cb ) );
- std::memcpy( pv, pCurrentPosition_, size_read );
- pCurrentPosition_ += size_read;
- if ( pcbRead )
- *pcbRead = size_read;
- return ( size_read == cb ) ? S_OK : S_FALSE;
+ BOOST_STATIC_ASSERT( sizeof( IODeviceStream<DeviceHandle> ) <= sizeof( istream_placeholder ) );
     }
-};
 
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class MemoryWriteStream
-/// ------------------------
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class MemoryWriteStream : public MemoryStreamBase
-{
-public:
- MemoryWriteStream( writable_memory_chunk_t const & in_memory_image )
+ template <class DeviceHandle, typename SecondParameter>
+ device_stream_wrapper( DeviceHandle const handle, SecondParameter const & second_parameter )
         :
- MemoryStreamBase( in_memory_image ) {}
-
-private:
- HRESULT STDMETHODCALLTYPE Write( void const * const pv, ULONG const cb, ULONG * const pcbWritten ) override
+ BackendWriter
+ (
+ *( new ( istream_placeholder::address() ) IODeviceStream<DeviceHandle>( handle ) ),
+ second_parameter
+ )
     {
- assert( pv );
- size_t const size_written( adjust_size_for_remaining_space( cb ) );
- std::memcpy( pCurrentPosition_, pv, size_written );
- pCurrentPosition_ += size_written;
- if ( pcbWritten )
- *pcbWritten = size_written;
- return ( size_written == cb ) ? S_OK : S_FALSE;
+ BOOST_STATIC_ASSERT( sizeof( IODeviceStream<DeviceHandle> ) <= sizeof( istream_placeholder ) );
     }
 };
 
-
-#pragma warning( pop )
-
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Added: sandbox/gil/boost/gil/extension/io2/devices/c_file.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/devices/c_file.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -0,0 +1,131 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file c_file.hpp
+/// ----------------
+///
+/// Copyright (c) Domagoj Saric 2011.
+///
+/// Use, modification and distribution is 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)
+///
+/// For more information, see http://www.boost.org
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#ifndef c_file_hpp__BFE0FCB4_C999_4CBF_A897_7075F3CF0E27
+#define c_file_hpp__BFE0FCB4_C999_4CBF_A897_7075F3CF0E27
+#pragma once
+//------------------------------------------------------------------------------
+#include "device.hpp"
+
+#include "boost/assert.hpp"
+#include "boost/cstdint.hpp"
+
+#include <cstdio>
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
+
+namespace detail
+{
+ struct device_FILE_base
+ {
+ typedef FILE * handle_t;
+
+ static handle_t transform ( handle_t const handle ) { return handle; }
+ static bool is_valid ( handle_t const handle ) { return handle != 0; }
+ static void close ( handle_t const handle ) { BOOST_VERIFY( /*std*/::fclose( handle ) == 0 ); }
+ static std::size_t position ( handle_t const handle ) { return std::ftell( handle ); }
+ static uintmax_t position_long( handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_ftelli64( handle );
+ #else
+ return /*std*/::ftell64 ( handle );
+ #endif // BOOST_MSVC
+ }
+
+ static std::size_t size( handle_t const handle )
+ {
+ return device<c_file_descriptor_t>::size( /*std*/::_fileno( handle ) );
+ }
+
+ static uintmax_t size_long( handle_t const handle )
+ {
+ return device<c_file_descriptor_t>::size_long( /*std*/::_fileno( handle ) );
+ }
+
+ static bool seek( seek_origin const origin, off_t const offset, handle_t const handle )
+ {
+ return std::fseek( handle, offset, origin ) != 0;
+ }
+
+ static bool seek_long( seek_origin const origin, intmax_t const offset, handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_fseeki64( handle, offset, origin ) != 0;
+ #else
+ return /*std*/::fseeko ( handle, offset, origin ) != 0;
+ #endif
+ }
+ };
+} // namespace detail
+
+template <> struct input_device<FILE *>
+ :
+ detail::input_device_base,
+ detail::device_FILE_base
+{
+ input_device( handle_t /*handle*/ ) {}
+
+ static handle_t open( char const * const file_name )
+ {
+ return /*std*/::fopen( file_name, "rb" );
+ }
+
+ static std::size_t read( void * const p_data, std::size_t const size, handle_t const handle )
+ {
+ return std::fread( p_data, 1, size, handle );
+ }
+};
+
+
+template <> struct output_device<FILE *>
+ :
+ detail::output_device_base,
+ detail::device_FILE_base
+{
+ output_device( handle_t /*handle*/ ) {}
+
+ static handle_t open( char const * const file_name )
+ {
+ return /*std*/::fopen( file_name, "wb" );
+ }
+
+ static std::size_t write( void const * const p_data, std::size_t const size, handle_t const handle )
+ {
+ return std::fwrite( p_data, 1, size, handle );
+ }
+
+ static void flush( handle_t const handle )
+ {
+ BOOST_VERIFY( std::fflush( handle ) == 0 );
+ }
+};
+
+//------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // libx_shared_hpp

Added: sandbox/gil/boost/gil/extension/io2/devices/c_file_descriptor.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/devices/c_file_descriptor.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -0,0 +1,166 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file c_file_descriptor.hpp
+/// ---------------------------
+///
+/// Copyright (c) Domagoj Saric 2011.
+///
+/// Use, modification and distribution is 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)
+///
+/// For more information, see http://www.boost.org
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#ifndef c_file_descriptor_hpp__6569A70D_9A8D_41EB_8152_F8D87E85D1E3
+#define c_file_descriptor_hpp__6569A70D_9A8D_41EB_8152_F8D87E85D1E3
+#pragma once
+//------------------------------------------------------------------------------
+#include "device.hpp"
+
+#include "boost/assert.hpp"
+#include "boost/cstdint.hpp"
+
+#ifdef BOOST_HAS_UNISTD_H
+ #include "sys/stat.h"
+ #include "unistd.h"
+#else
+ #ifndef _POSIX_
+ #define _POSIX_
+ #endif
+ #include "io.h"
+#endif // BOOST_HAS_UNISTD_H
+#include "fcntl.h"
+#include "sys/stat.h"
+#include "sys/types.h"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
+
+typedef int c_file_descriptor_t;
+
+namespace detail
+{
+ struct device_c_file_descriptor_base
+ {
+ typedef c_file_descriptor_t handle_t;
+
+ static bool is_valid( handle_t const handle )
+ {
+ return handle >= 0;
+ }
+
+ static void close( handle_t const handle ) { BOOST_VERIFY( /*std*/::close( handle ) == 0 ); }
+
+ static std::size_t position( handle_t const handle )
+ {
+ return /*std*/::tell( handle );
+ }
+
+ static uintmax_t position_long( handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_telli64( handle );
+ #else
+ return /*std*/::tell64 ( handle );
+ #endif // BOOST_MSVC
+ }
+
+ static std::size_t size( handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_filelength( handle );
+ #else
+ struct stat file_status;
+ BOOST_VERIFY( ::fstat( handle, &file_status ) == 0 );
+ return file_status.st_size;
+ #endif // BOOST_MSVC
+ }
+
+ static uintmax_t size_long( handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_filelengthi64( handle );
+ #else
+ struct stat64 file_status;
+ BOOST_VERIFY( ::fstat64( handle, &file_status ) == 0 );
+ return file_status.st_size;
+ #endif // BOOST_MSVC
+ }
+
+ static bool seek( device_base::seek_origin const origin, off_t offset, handle_t const handle )
+ {
+ return /*std*/::lseek( handle, offset, origin ) != 0;
+ }
+
+ static bool seek_long( device_base::seek_origin const origin, intmax_t offset, handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ return /*std*/::_lseeki64( handle, offset, origin ) != 0;
+ #else
+ return /*std*/::lseeko ( handle, offset, origin ) != 0;
+ #endif
+ }
+ };
+} // namespace detail
+
+template <> struct input_device<c_file_descriptor_t>
+ :
+ detail::input_device_base,
+ detail::device_c_file_descriptor_base
+{
+ static handle_t open( char const * const p_file_name )
+ {
+ return /*std*/::open( p_file_name, BF_MSVC_SPECIFIC( O_BINARY | ) O_RDONLY, 0 );
+ }
+
+ static std::size_t read( void * p_data, std::size_t const size, handle_t const handle )
+ {
+ int const result( /*std*/::read( handle, p_data, size ) );
+ return ( result >= 0 ) ? result : 0;
+ }
+};
+
+
+template <> struct output_device<c_file_descriptor_t>
+ :
+ detail::output_device_base,
+ detail::device_c_file_descriptor_base
+{
+ static handle_t open( char const * const p_file_name )
+ {
+ return /*std*/::open( p_file_name, BF_MSVC_SPECIFIC( O_BINARY | ) O_CREAT | O_WRONLY, S_IREAD | S_IWRITE );
+ }
+
+ static std::size_t write( void const * p_data, std::size_t const size, handle_t const handle )
+ {
+ int const result( /*std*/::write( handle, p_data, size ) );
+ return ( result >= 0 ) ? result : 0;
+ }
+
+ static void flush( handle_t const handle )
+ {
+ #ifdef BOOST_MSVC
+ BOOST_VERIFY( /*std*/::_commit( handle ) == 0 );
+ #else
+ BOOST_VERIFY( /*std*/::fsync ( handle ) == 0 );
+ #endif
+ }
+};
+
+//------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // c_file_descriptor_hpp

Added: sandbox/gil/boost/gil/extension/io2/devices/c_file_name.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/devices/c_file_name.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -0,0 +1,77 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file c_file_name.hpp
+/// ---------------------
+///
+/// Copyright (c) Domagoj Saric 2011.
+///
+/// Use, modification and distribution is 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)
+///
+/// For more information, see http://www.boost.org
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#ifndef c_file_name_hpp__328689B4_EC2F_418B_99AC_5DFE988D87AE
+#define c_file_name_hpp__328689B4_EC2F_418B_99AC_5DFE988D87AE
+#pragma once
+//------------------------------------------------------------------------------
+#include "c_file_descriptor.hpp"
+#include "device.hpp"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
+
+template <> struct input_device<char const *>
+ :
+ input_device<c_file_descriptor_t>
+{
+ input_device( char const * const p_file_name )
+ :
+ file_descriptor_( input_device<c_file_descriptor_t>::open( p_file_name ) )
+ {
+ ensure( is_valid( file_descriptor_ ) );
+ }
+
+ ~input_device() { input_device<c_file_descriptor_t>::close( file_descriptor_ ); }
+
+ input_device<c_file_descriptor_t>::handle_t transform( char const * /*p_file_name*/ ) const { return file_descriptor_; }
+
+ input_device<c_file_descriptor_t>::handle_t const file_descriptor_;
+};
+
+
+template <> struct output_device<char const *>
+ :
+ output_device<c_file_descriptor_t>
+{
+ output_device( char const * const p_file_name )
+ :
+ file_descriptor_( output_device<c_file_descriptor_t>::open( p_file_name ) )
+ {
+ ensure( is_valid( file_descriptor_ ) );
+ }
+
+ ~output_device() { output_device<c_file_descriptor_t>::close( file_descriptor_ ); }
+
+ output_device<c_file_descriptor_t>::handle_t transform( char const * /*p_file_name*/ ) const { return file_descriptor_; }
+
+ output_device<c_file_descriptor_t>::handle_t const file_descriptor_;
+};
+
+//------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // c_file_name_hpp

Added: sandbox/gil/boost/gil/extension/io2/devices/device.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/devices/device.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -0,0 +1,79 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file device.hpp
+/// ----------------
+///
+/// Copyright (c) Domagoj Saric 2011.
+///
+/// Use, modification and distribution is 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)
+///
+/// For more information, see http://www.boost.org
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#ifndef device_hpp__0B0D753B_4DAB_4EAF_8F73_780FF1D1F4D6
+#define device_hpp__0B0D753B_4DAB_4EAF_8F73_780FF1D1F4D6
+#pragma once
+//------------------------------------------------------------------------------
+#include "detail/io_error.hpp"
+
+#include "boost/type_traits/is_convertible.hpp"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace io
+{
+//------------------------------------------------------------------------------
+
+template <typename Handle>
+struct input_device : mpl::false_ {};
+
+template <typename Handle>
+struct output_device : mpl::false_ {};
+
+template <typename Device>
+struct unknown_input_device : is_convertible<input_device<Device>, mpl::false_> {};
+
+template <typename Device>
+struct unknown_output_device : is_convertible<output_device<Device>, mpl::false_> {};
+
+
+namespace detail
+{
+ struct device_base
+ {
+ enum seek_origin { beginning = SEEK_SET, current_position = SEEK_CUR, end = SEEK_END };
+ };
+
+ struct input_device_base : device_base
+ {
+ void ensure( bool const condition )
+ {
+ io_error_if_not( condition, "Boost.GIL.IO failed to open input file." );
+ }
+ };
+
+ struct output_device_base : device_base
+ {
+ void ensure( bool const condition )
+ {
+ io_error_if_not( condition, "Boost.GIL.IO failed to open output file." );
+ }
+ };
+}
+
+
+//------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // device_hpp

Copied: sandbox/gil/boost/gil/extension/io2/dynamic_image.hpp (from r68172, /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/dynamic_image.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Base CRTP class for all image implementation classes/backends.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,9 +15,9 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef dynamic_image_hpp__85C4E125_7906_42D5_B25B_4D6D82DE13E0
+#define dynamic_image_hpp__85C4E125_7906_42D5_B25B_4D6D82DE13E0
 #pragma once
-#ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
-#define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 //------------------------------------------------------------------------------
 #include "format_tags.hpp"
 #include "detail/platform_specifics.hpp"
@@ -32,22 +32,11 @@
 #include "boost/gil/typedefs.hpp"
 
 #include <boost/compressed_pair.hpp>
-#ifdef _DEBUG
-#include <boost/detail/endian.hpp>
-#endif // _DEBUG
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/for_each.hpp>
 #include <boost/mpl/integral_c.hpp>
 #include <boost/mpl/map.hpp>
 #include <boost/mpl/vector_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>
-#include <boost/type_traits/decay.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -55,416 +44,20 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-
-struct assert_dimensions_match {};
-struct ensure_dimensions_match {};
-struct synchronize_dimensions {};
-
-struct assert_formats_match {};
-struct ensure_formats_match {};
-struct synchronize_formats {};
-
-#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> >
-{
- packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
- {
- typedef packed_channel_value<DestPackedNumBits> DstChannelV;
-
- typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
- typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
-
- 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)));
- }
- }
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#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_ ;
- Offset offset_;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class formatted_image_traits
-/// ( forward declaration )
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-struct formatted_image_traits;
-
-namespace detail
+namespace io
 {
 //------------------------------------------------------------------------------
 
-#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 get_offset( View const & ) { return Offset(); }
-template <typename Offset, class View>
-Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
-
-template <typename Offset>
-Offset get_offset_x( Offset const & ) { return Offset(); }
-template <typename Offset>
-Offset const & get_offset_x( point2<Offset> const & offset ) { return offset.x; }
-
-template <typename Offset>
-Offset get_offset_y( Offset const & offset ) { return offset; }
-template <typename Offset>
-Offset const & get_offset_y( point2<Offset> const & offset ) { return offset.y; }
-
-
-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 <class View>
-struct is_offset_view : mpl::false_ {};
-
-template <class View, typename Offset>
-struct is_offset_view<offset_view_t<View, Offset> > : mpl::true_ {};
-
-
-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; };
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class configure_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to open the
-/// target/file and then be configured for the desired view.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct configure_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( target, specified_format ),
- view_data_( view )
- {}
-
- void write_default() { Writer::write_default( view_data_ ); }
- void write () { Writer::write ( view_data_ ); }
-
- private:
- ViewDataHolder const view_data_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- single_format_writer_wrapper( WriterTarget const & target, format_tag const specified_format = OnlyFormat )
- :
- Writer( target )
- {
- BOOST_VERIFY( specified_format == OnlyFormat );
- }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class open_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to be configured
-/// for/created from the desired view and then open the target/file.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct open_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( view ),
- target_ ( target ),
- specified_format_( specified_format )
- {}
-
- void write_default() { Writer::write_default( target_, specified_format_ ); }
- void write () { Writer::write ( target_, specified_format_ ); }
-
- private:
- typename call_traits<WriterTarget>::param_type const target_;
- format_tag const specified_format_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- template <typename View>
- single_format_writer_wrapper( View const & view ) : Writer( view ) {}
-
- void write_default( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write_default( target ); }
- void write ( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write ( target ); }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image_base
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class formatted_image_base : noncopyable
+namespace detail
 {
-public:
- typedef point2<std::ptrdiff_t> dimensions_t;
-
- typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
-
-public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- static bool can_do_row_access () { return true ; }
- static bool can_do_strip_access() { return false; }
- static bool can_do_tile_access () { return false; }
-
- static bool can_do_roi_access () { return false; }
- static bool can_do_vertical_roi_access() { return true ; }
-
-protected:
- static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
- template <class View>
- static bool dimensions_mismatch( dimensions_t const & mine, View const & view ) { 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 )
- {
- // Implementation note:
- // For offset target views all dimensions are allowed as they are
- // intended to load an image in steps so they must be allowed to be
- // smaller. They are also allowed to be bigger to allow GIL users to use
- // fixed 'sub' view, while loading an image in steps, whose size is not
- // an exact divisor of the source image dimensions.
- // The exception is for backends that support only vertical 'ROIs'/
- // offsets, for those the horizontal dimensions must match.
- // (19.09.2010.) (Domagoj Saric)
- //dimensions_t const other( offset_view.dimensions() );
- //return ( other.x < mine.x ) || ( other.y < mine.y );
- return is_pod<Offset>::value ? ( mine.x != offset_view.dimensions().x ) : false;
- }
-
- 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" );
- }
-
- template <class View>
- static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
- {
- 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" );
- }
-
- template <typename Image>
- static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
- {
- image.recreate( my_dimensions, alignment );
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // subview_for_offset()
- // --------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \brief Locally adjusts a view with a ROI/offset to prevent it exceeding
- /// the image dimensions when 'merged' with its offset. Done here so that
- /// backend classes do not need to handle this.
- /// \internal
- /// \throws nothing
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- static View subview_for_offset( dimensions_t const & my_dimensions, offset_view_t<View, Offset> const & offset_view )
- {
- dimensions_t const & target_dimensions( offset_view.original_view().dimensions() );
-
- bool const zero_x_offset( is_pod<Offset>::value );
- if ( zero_x_offset )
- {
- BOOST_ASSERT( get_offset_x( offset_view.offset() ) == 0 );
- BOOST_ASSERT( my_dimensions.x == target_dimensions.x );
- }
-
- unsigned int const width ( zero_x_offset ? target_dimensions.x : (std::min)( my_dimensions.x - get_offset_x( offset_view.offset() ), target_dimensions.x ) );
- unsigned int const height( (std::min)( my_dimensions.y - get_offset_y( offset_view.offset() ), target_dimensions.y ) );
-
- return subimage_view( offset_view.original_view(), 0, 0, width, height );
- }
-
-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
+ struct assert_on_type_mismatch
     {
         typedef bool result_type;
         template <typename Index>
         result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
     };
 
- struct throw_type_mismatch
+ struct throw_on_type_mismatch
     {
         typedef void result_type;
         result_type operator()() const { do_ensure_formats_match( true ); }
@@ -475,25 +68,12 @@
     {
         typedef bool result_type;
         template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
+ result_type operator()( SupportedFormatIndex ) const
         {
             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>
- result_type operator()( Index const & ) const
- {
- BOOST_ASSERT( !"Default case must not have been reached!" );
- BF_UNREACHABLE_CODE
- return result_type();
- }
- };
-
     template <typename Images>
     class make_dynamic_image
     {
@@ -510,109 +90,10 @@
     protected:
         any_image<Images> & image_;
     };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-class formatted_image : public formatted_image_base
-{
-public:
- typedef typename formatted_image_traits<Impl>::format_t format_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;
 
- template <typename PixelType, bool IsPlanar>
- struct native_format
- : formatted_image_traits<Impl>::gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<PixelType, IsPlanar>::type
- {};
-
- template <typename T> struct get_native_format;
-
- template <typename PixelType, typename IsPlanar>
- struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
-
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
-
- template <typename Locator>
- struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
-
- template <class View>
- struct has_supported_format
- {
- private:
- typedef typename get_original_view_t<View>::type original_view_t;
-
- public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
- <
- typename original_view_t::value_type,
- is_planar<original_view_t>::value
- > type;
- BOOST_STATIC_CONSTANT( bool, value = type::value );
- };
-
     typedef any_image<supported_pixel_formats> dynamic_image_t;
 
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
-
- BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
-
-protected:
- typedef formatted_image base_t;
-
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
-
-private:
     template <typename Images, typename dimensions_policy, typename formats_policy>
     class read_dynamic_image : make_dynamic_image<Images>
     {
@@ -632,7 +113,7 @@
         void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
 
         template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
+ void operator()( SupportedFormatIndex ) { this->apply<typename mpl::at<SupportedFormatIndex>::type>(); }
 
     private:
         Impl & impl_;
@@ -653,220 +134,6 @@
         Impl & impl_;
     };
 
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- 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_( unsupported_format ) {}
-
- template <typename ImageIndex>
- void operator()( ImageIndex )
- {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
- if ( image_format == this->format_ )
- {
- BOOST_ASSERT( image_id_ == unsupported_format );
- image_id_ = ImageIndex::value;
- }
- }
-
- format_t const format_ ;
- unsigned int image_id_;
-
- private:
- void operator=( image_id_finder const & );
- };
-
-private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
- Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
- Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
-
-protected:
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
- }
-
- 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 );
- }
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
- }
-
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
- {
- return ( other_format != impl().closest_gil_supported_format() ) != false;
- }
-
- 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>( impl().format() );
- }
-
- template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
- {
- return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
- }
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- View subview_for_offset( offset_view_t<View, Offset> const & offset_view ) const
- {
- return formatted_image_base::subview_for_offset( impl().dimensions(), offset_view );
- }
-
- template <typename View>
- static view_data_t get_view_data( View const & view )
- {
- return view_data_t( view );
- }
-
- template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
- {
- return view_data_t
- (
- subview_for_offset( offset_view ),
- offset_view.offset()
- );
- }
-
-public: // Low-level (row, strip, tile) access
- std::size_t pixel_size() const
- {
- return impl().cached_format_size( impl().format() );
- }
-
- std::size_t row_size() const
- {
- return impl().pixel_size() * impl().dimensions().x;
- }
-
- // 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 into 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_ != unsupported_format );
- return finder.image_id_;
- }
-
-public: // Views...
- template <typename View>
- void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
- {
- BOOST_STATIC_ASSERT( get_original_view_t<View>::type::value_type::is_mutable );
- BOOST_STATIC_ASSERT( has_supported_format<View>::value );
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- BOOST_ASSERT( !impl().formats_mismatch<View>() );
- impl().raw_copy_to_prepared_view( get_view_data( view ) );
- }
-
- template <typename View>
- 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 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 const & view, ensure_dimensions_match, ensure_formats_match ) const
- {
- impl().do_ensure_dimensions_match( view );
- impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
- }
-
- template <typename View>
- 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 const & view, assert_dimensions_match, synchronize_formats ) const
- {
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- typedef mpl::bool_
- <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
- > can_use_raw_t;
- default_convert_to_worker( view, can_use_raw_t() );
- }
-
- template <typename FormatConverter, typename View>
- void copy_to( View const & view, ensure_dimensions_match, FormatConverter & 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 const & view, assert_dimensions_match, FormatConverter & 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
- {
- 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_image( any_image<Images> & im ) const
     {
@@ -874,10 +141,16 @@
         (
             impl().current_image_format_id(),
             read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
+ throw_on_type_mismatch()
         );
     }
 
+ struct write_is_supported
+ {
+ template <typename View>
+ struct apply : public has_supported_format<View> {};
+ };
+
     template <typename Views, typename dimensions_policy, typename formats_policy>
     void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
     {
@@ -889,259 +162,14 @@
             dynamic_io_fnobj<write_is_supported, op_t>( &op )
         );
     }
-
-public: // Offset factory
- template <class View>
- static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
-
-public: // Utility 'quick-wrappers'...
- template <class Source, class Image>
- static void read( Source const & target, Image & image )
- {
- typedef typename reader_for<typename decay<Source>::type>::type reader_t;
- // The backend does not know how to read from the specified source type.
- BOOST_STATIC_ASSERT(( !is_same<reader_t, mpl::void_>::value ));
- reader_t( target ).copy_to_image( image, synchronize_dimensions(), synchronize_formats() );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> const & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <class Target, class View>
- static void write( Target & target, View const & view )
- {
- typedef typename writer_for<Target>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( target, view ).write_default();
- }
-
- template <class Target, class View>
- static void write( Target * p_target, View const & view )
- {
- typedef typename writer_for<Target const *>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( p_target, view ).write_default();
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> const & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
-private:
- template <class View, typename CC>
- class in_place_converter_t
- {
- public:
- typedef void result_type;
-
- 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
- {
- typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
- 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 )
- {
- convert_aux( srcP, is_planar<View>() );
- }
-
- void operator=( in_place_converter_t const & other )
- {
- 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 ) ) );
- }
-
- private:
- compressed_pair<CC, View const &> members_;
- };
-
- template <class View, typename CC>
- class generic_converter_t
- {
- public:
- typedef void result_type;
-
- generic_converter_t( Impl const & impl, CC const & cc, View const & 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_. BOOST_NESTED_TEMPLATE 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();
- }
-
- 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>
- 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
- {
- return switch_<valid_type_id_range_t>
- (
- source_view_type_id,
- generic_converter_t<TargetView, CC>
- (
- impl(),
- cc,
- offset_new_view
- (
- // See the note for formatted_image_base::subview_for_offset()...
- subview_for_offset( view ),
- view
- )
- ),
- assert_default_case_not_reached<void>()
- );
- }
-
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- convert_to_prepared_view_worker
- (
- view,
- converter,
- mpl::bool_
- <
- is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
- has_supported_format < 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 current_format ( impl().closest_gil_supported_format() );
- unsigned int const current_image_format_id( impl().image_format_id( current_format ) );
- if ( can_do_inplace_transform<View>( current_format ) )
- {
- view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
- view_data.set_format( current_format );
- else
- BOOST_ASSERT( current_format == impl().format() );
- impl().raw_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 );
- }
-
- template <typename View>
- void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
- {
- impl().raw_convert_to_prepared_view( get_view_data( 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() );
- }
-};
-
+//------------------------------------------------------------------------------
+} // namespace detail
 
 //------------------------------------------------------------------------------
-} // namespace detail
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // formatted_image_hpp
+#endif // dynamic_image_hpp

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 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Base CRTP class for all image implementation classes/backends.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,17 +15,15 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#pragma once
 #ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 #define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
+#pragma once
 //------------------------------------------------------------------------------
 #include "format_tags.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/io_error.hpp"
 #include "detail/switch.hpp"
 
-#include "boost/gil/extension/dynamic_image/any_image.hpp"
-#include "boost/gil/extension/io/dynamic_io.hpp" //...zzz...
 #include "boost/gil/packed_pixel.hpp"
 #include "boost/gil/planar_pixel_iterator.hpp"
 #include "boost/gil/planar_pixel_reference.hpp"
@@ -56,19 +54,14 @@
 {
 //------------------------------------------------------------------------------
 
-struct assert_dimensions_match {};
-struct ensure_dimensions_match {};
-struct synchronize_dimensions {};
-
-struct assert_formats_match {};
-struct ensure_formats_match {};
-struct synchronize_formats {};
-
 #if defined(BOOST_MSVC)
 # pragma warning( push )
 # pragma warning( disable : 4127 ) // "conditional expression is constant"
 #endif
 
+template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
+struct channel_converter;
+
 // An integer version of the unsigned channel downsampling/quantizing 'overload'...
 template <typename SrcChannelV, int DestPackedNumBits>
 struct channel_converter<SrcChannelV, packed_channel_value<DestPackedNumBits> >
@@ -114,58 +107,9 @@
 # pragma warning( pop )
 #endif
 
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class offset_view_t
-/// \todo document properly...
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class View, typename Offset>
-class offset_view_t
+namespace io
 {
-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_ ;
- Offset offset_;
-};
-
+//------------------------------------------------------------------------------
 
 ////////////////////////////////////////////////////////////////////////////////
 /// \class formatted_image_traits
@@ -175,152 +119,15 @@
 template <class Impl>
 struct formatted_image_traits;
 
-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 get_offset( View const & ) { return Offset(); }
-template <typename Offset, class View>
-Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
-
-template <typename Offset>
-Offset get_offset_x( Offset const & ) { return Offset(); }
-template <typename Offset>
-Offset const & get_offset_x( point2<Offset> const & offset ) { return offset.x; }
-
-template <typename Offset>
-Offset get_offset_y( Offset const & offset ) { return offset; }
-template <typename Offset>
-Offset const & get_offset_y( point2<Offset> const & offset ) { return offset.y; }
-
-
-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 <class View>
-struct is_offset_view : mpl::false_ {};
+template <class Backend, typename Source>
+struct reader_for;
 
-template <class View, typename Offset>
-struct is_offset_view<offset_view_t<View, Offset> > : mpl::true_ {};
+template <class Backend, typename Target>
+struct writer_for;
 
-
-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; };
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class configure_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to open the
-/// target/file and then be configured for the desired view.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct configure_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( target, specified_format ),
- view_data_( view )
- {}
-
- void write_default() { Writer::write_default( view_data_ ); }
- void write () { Writer::write ( view_data_ ); }
-
- private:
- ViewDataHolder const view_data_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- single_format_writer_wrapper( WriterTarget const & target, format_tag const specified_format = OnlyFormat )
- :
- Writer( target )
- {
- BOOST_VERIFY( specified_format == OnlyFormat );
- }
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class open_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to be configured
-/// for/created from the desired view and then open the target/file.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct open_on_write_writer
+namespace detail
 {
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( view ),
- target_ ( target ),
- specified_format_( specified_format )
- {}
-
- void write_default() { Writer::write_default( target_, specified_format_ ); }
- void write () { Writer::write ( target_, specified_format_ ); }
-
- private:
- typename call_traits<WriterTarget>::param_type const target_;
- format_tag const specified_format_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- template <typename View>
- single_format_writer_wrapper( View const & view ) : Writer( view ) {}
-
- void write_default( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write_default( target ); }
- void write ( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write ( target ); }
- };
-};
-
+//------------------------------------------------------------------------------
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
@@ -330,16 +137,10 @@
 
 class formatted_image_base : noncopyable
 {
-public:
- typedef point2<std::ptrdiff_t> dimensions_t;
-
- typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
-
 public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
+ struct sequential_row_read_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
 
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
+ static sequential_row_read_state begin_sequential_row_read() { return sequential_row_read_state(); }
 
     static bool can_do_row_access () { return true ; }
     static bool can_do_strip_access() { return false; }
@@ -348,93 +149,6 @@
     static bool can_do_roi_access () { return false; }
     static bool can_do_vertical_roi_access() { return true ; }
 
-protected:
- static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
- template <class View>
- static bool dimensions_mismatch( dimensions_t const & mine, View const & view ) { 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 )
- {
- // Implementation note:
- // For offset target views all dimensions are allowed as they are
- // intended to load an image in steps so they must be allowed to be
- // smaller. They are also allowed to be bigger to allow GIL users to use
- // fixed 'sub' view, while loading an image in steps, whose size is not
- // an exact divisor of the source image dimensions.
- // The exception is for backends that support only vertical 'ROIs'/
- // offsets, for those the horizontal dimensions must match.
- // (19.09.2010.) (Domagoj Saric)
- //dimensions_t const other( offset_view.dimensions() );
- //return ( other.x < mine.x ) || ( other.y < mine.y );
- return is_pod<Offset>::value ? ( mine.x != offset_view.dimensions().x ) : false;
- }
-
- 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" );
- }
-
- template <class View>
- static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
- {
- 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" );
- }
-
- template <typename Image>
- static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
- {
- image.recreate( my_dimensions, alignment );
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // subview_for_offset()
- // --------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \brief Locally adjusts a view with a ROI/offset to prevent it exceeding
- /// the image dimensions when 'merged' with its offset. Done here so that
- /// backend classes do not need to handle this.
- /// \internal
- /// \throws nothing
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- static View subview_for_offset( dimensions_t const & my_dimensions, offset_view_t<View, Offset> const & offset_view )
- {
- dimensions_t const & target_dimensions( offset_view.original_view().dimensions() );
-
- bool const zero_x_offset( is_pod<Offset>::value );
- if ( zero_x_offset )
- {
- BOOST_ASSERT( get_offset_x( offset_view.offset() ) == 0 );
- BOOST_ASSERT( my_dimensions.x == target_dimensions.x );
- }
-
- unsigned int const width ( zero_x_offset ? target_dimensions.x : (std::min)( my_dimensions.x - get_offset_x( offset_view.offset() ), target_dimensions.x ) );
- unsigned int const height( (std::min)( my_dimensions.y - get_offset_y( offset_view.offset() ), target_dimensions.y ) );
-
- return subimage_view( offset_view.original_view(), 0, 0, width, height );
- }
-
 public: //...zzz...
     template <typename View>
     static unsigned char * get_raw_data( View const & view )
@@ -457,30 +171,6 @@
             ( is_planar<View>::value && view_is_basic<View>::value )
> {};
 
- struct assert_type_mismatch
- {
- typedef bool result_type;
- template <typename Index>
- result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
- };
-
- struct throw_type_mismatch
- {
- typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( true ); }
- };
-
- template <typename Type, typename SupportedPixelFormats>
- struct check_type_match
- {
- typedef bool result_type;
- template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
- {
- return is_same<Type, typename mpl::at<SupportedPixelFormats, SupportedFormatIndex>::type>::value;
- }
- };
-
     template <typename ResultType>
     struct assert_default_case_not_reached
     {
@@ -493,23 +183,6 @@
             return result_type();
         }
     };
-
- template <typename Images>
- class make_dynamic_image
- {
- public:
- make_dynamic_image( any_image<Images> & image ) : image_( image ) {}
-
- template <class Image>
- Image & apply()
- {
- image_.move_in( Image() );
- return image_. BOOST_NESTED_TEMPLATE _dynamic_cast<Image>();
- }
-
- protected:
- any_image<Images> & image_;
- };
 };
 
 
@@ -523,7 +196,7 @@
 class formatted_image : public formatted_image_base
 {
 public:
- typedef typename formatted_image_traits<Impl>::format_t format_t;
+ //typedef typename formatted_image_traits<Impl>::format_t format_t;
 
     typedef typename formatted_image_traits<Impl>::supported_pixel_formats_t supported_pixel_formats;
     typedef typename formatted_image_traits<Impl>::roi_t roi;
@@ -539,607 +212,34 @@
     template <typename PixelType, typename IsPlanar>
     struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
 
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
+ template <typename PixelType, bool IsPlanar, class Allocator>
+ struct get_native_format<image<PixelType, IsPlanar, Allocator> > : native_format<PixelType, IsPlanar> {};
 
     template <typename Locator>
     struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
 
- template <class View>
- struct has_supported_format
- {
- private:
- typedef typename get_original_view_t<View>::type original_view_t;
-
- public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
- <
- typename original_view_t::value_type,
- is_planar<original_view_t>::value
- > type;
- BOOST_STATIC_CONSTANT( bool, value = type::value );
- };
-
- typedef any_image<supported_pixel_formats> dynamic_image_t;
-
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
+ template <typename Source> struct reader_for : gil::io::reader_for<Impl, Source> {};
+ template <typename Target> struct writer_for : gil::io::writer_for<Impl, Target> {};
 
     BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
 
 protected:
     typedef formatted_image base_t;
 
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
+ //typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
 
 private:
- template <typename Images, typename dimensions_policy, typename formats_policy>
- class read_dynamic_image : make_dynamic_image<Images>
- {
- private:
- typedef make_dynamic_image<Images> base;
-
- public:
- typedef void result_type;
-
- read_dynamic_image( any_image<Images> & image, Impl & impl )
- :
- base ( image ),
- impl_( impl )
- {}
-
- template <class Image>
- void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
-
- template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
-
- private:
- Impl & impl_;
- };
-
- template <typename dimensions_policy, typename formats_policy>
- class write_dynamic_view
- {
- public:
- typedef void result_type;
-
- write_dynamic_view( Impl & impl ) : impl_( impl ) {}
-
- template <class View>
- void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
-
- private:
- Impl & impl_;
- };
-
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- 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_( unsupported_format ) {}
-
- template <typename ImageIndex>
- void operator()( ImageIndex )
- {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
- if ( image_format == this->format_ )
- {
- BOOST_ASSERT( image_id_ == unsupported_format );
- image_id_ = ImageIndex::value;
- }
- }
-
- format_t const format_ ;
- unsigned int image_id_;
-
- private:
- void operator=( image_id_finder const & );
- };
-
-private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
+ // MSVC++ 10 generates code to check whether this == 0.
     Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
     Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
-
-protected:
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
- }
-
- 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 );
- }
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
- }
-
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
- {
- return ( other_format != impl().closest_gil_supported_format() ) != false;
- }
-
- 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>( impl().format() );
- }
-
- template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
- {
- return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
- }
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- View subview_for_offset( offset_view_t<View, Offset> const & offset_view ) const
- {
- return formatted_image_base::subview_for_offset( impl().dimensions(), offset_view );
- }
-
- template <typename View>
- static view_data_t get_view_data( View const & view )
- {
- return view_data_t( view );
- }
-
- template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
- {
- return view_data_t
- (
- subview_for_offset( offset_view ),
- offset_view.offset()
- );
- }
-
-public: // Low-level (row, strip, tile) access
- std::size_t pixel_size() const
- {
- return impl().cached_format_size( impl().format() );
- }
-
- std::size_t row_size() const
- {
- return impl().pixel_size() * impl().dimensions().x;
- }
-
- // 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 into 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_ != unsupported_format );
- return finder.image_id_;
- }
-
-public: // Views...
- template <typename View>
- void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
- {
- BOOST_STATIC_ASSERT( get_original_view_t<View>::type::value_type::is_mutable );
- BOOST_STATIC_ASSERT( has_supported_format<View>::value );
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- BOOST_ASSERT( !impl().formats_mismatch<View>() );
- impl().raw_copy_to_prepared_view( get_view_data( view ) );
- }
-
- template <typename View>
- 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 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 const & view, ensure_dimensions_match, ensure_formats_match ) const
- {
- impl().do_ensure_dimensions_match( view );
- impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
- }
-
- template <typename View>
- 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 const & view, assert_dimensions_match, synchronize_formats ) const
- {
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- typedef mpl::bool_
- <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
- > can_use_raw_t;
- default_convert_to_worker( view, can_use_raw_t() );
- }
-
- template <typename FormatConverter, typename View>
- void copy_to( View const & view, ensure_dimensions_match, FormatConverter & 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 const & view, assert_dimensions_match, FormatConverter & 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
- {
- 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_image( any_image<Images> & im ) const
- {
- switch_<valid_type_id_range_t>
- (
- impl().current_image_format_id(),
- read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
- );
- }
-
- template <typename Views, typename dimensions_policy, typename formats_policy>
- void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
- {
- typedef write_dynamic_view<dimensions_policy, formats_policy> op_t;
- op_t op( *this );
- apply_operation
- (
- runtime_view,
- dynamic_io_fnobj<write_is_supported, op_t>( &op )
- );
- }
-
-public: // Offset factory
- template <class View>
- static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
-
-public: // Utility 'quick-wrappers'...
- template <class Source, class Image>
- static void read( Source const & target, Image & image )
- {
- typedef typename reader_for<typename decay<Source>::type>::type reader_t;
- // The backend does not know how to read from the specified source type.
- BOOST_STATIC_ASSERT(( !is_same<reader_t, mpl::void_>::value ));
- reader_t( target ).copy_to_image( image, synchronize_dimensions(), synchronize_formats() );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> const & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <class Target, class View>
- static void write( Target & target, View const & view )
- {
- typedef typename writer_for<Target>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( target, view ).write_default();
- }
-
- template <class Target, class View>
- static void write( Target * p_target, View const & view )
- {
- typedef typename writer_for<Target const *>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( p_target, view ).write_default();
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> const & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
-private:
- template <class View, typename CC>
- class in_place_converter_t
- {
- public:
- typedef void result_type;
-
- 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
- {
- typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
- 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 )
- {
- convert_aux( srcP, is_planar<View>() );
- }
-
- void operator=( in_place_converter_t const & other )
- {
- 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 ) ) );
- }
-
- private:
- compressed_pair<CC, View const &> members_;
- };
-
- template <class View, typename CC>
- class generic_converter_t
- {
- public:
- typedef void result_type;
-
- generic_converter_t( Impl const & impl, CC const & cc, View const & 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_. BOOST_NESTED_TEMPLATE 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();
- }
-
- 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>
- 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
- {
- return switch_<valid_type_id_range_t>
- (
- source_view_type_id,
- generic_converter_t<TargetView, CC>
- (
- impl(),
- cc,
- offset_new_view
- (
- // See the note for formatted_image_base::subview_for_offset()...
- subview_for_offset( view ),
- view
- )
- ),
- assert_default_case_not_reached<void>()
- );
- }
-
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- convert_to_prepared_view_worker
- (
- view,
- converter,
- mpl::bool_
- <
- is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
- has_supported_format < 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 current_format ( impl().closest_gil_supported_format() );
- unsigned int const current_image_format_id( impl().image_format_id( current_format ) );
- if ( can_do_inplace_transform<View>( current_format ) )
- {
- view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
- view_data.set_format( current_format );
- else
- BOOST_ASSERT( current_format == impl().format() );
- impl().raw_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 );
- }
-
- template <typename View>
- void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
- {
- impl().raw_convert_to_prepared_view( get_view_data( 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() );
- }
 };
 
 
 //------------------------------------------------------------------------------
 } // namespace detail
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost

Modified: sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -13,9 +13,9 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#pragma once
 #ifndef libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
 #define libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
+#pragma once
 //------------------------------------------------------------------------------
 #include "formatted_image.hpp"
 
@@ -29,6 +29,7 @@
 #endif
 
 #include <boost/array.hpp>
+#include <boost/mpl/set/set10.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/smart_ptr/scoped_array.hpp>
 
@@ -37,16 +38,6 @@
     #include "tiff.h"
     #include "tiffio.h"
 }
-
-#include <cstdio>
-#include <set>
-#ifdef _MSC_VER
- #include "io.h"
-#else
- #include "sys/types.h"
- #include "sys/stat.h"
- #include "unistd.h"
-#endif // _MSC_VER
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -54,6 +45,13 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+
+template <typename Pixel, bool IsPlanar, typename Alloc=std::allocator<unsigned char> >
+class image;
+
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -90,8 +88,8 @@
 
     typedef unsigned int format_id;
 
- format_bitfield bits ;
     format_id number;
+ format_bitfield bits ;
 };
 
 
@@ -165,49 +163,28 @@
> libtiff_supported_pixel_formats;
 
 
-inline tsize_t FILE_read_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
-{
- return static_cast<tsize_t>( std::fread( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
-}
-
-inline tsize_t FILE_write_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
-{
- return static_cast<tsize_t>( std::fwrite( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
-}
-
-inline toff_t FILE_seek_proc( thandle_t const handle, toff_t const off, int const whence )
-{
- return static_cast<tsize_t>( std::fseek( reinterpret_cast<FILE *>( handle ), off, whence ) );
-}
-
-inline int FILE_close_proc( thandle_t const handle )
+template <typename Handle>
+toff_t seek( thandle_t const handle, toff_t const off, int const whence )
 {
- return std::fclose( reinterpret_cast<FILE *>( handle ) );
+ return static_cast<tsize_t>( input_device<Handle>::seek( static_cast<device_base::seek_origin>( whence ), off, reinterpret_cast<Handle>( handle ) ) );
 }
 
-inline int FILE_close_proc_nop( thandle_t /*handle*/ )
+template <typename Handle>
+int close( thandle_t const handle )
 {
+ input_device<Handle>::close( reinterpret_cast<Handle>( handle ) );
     return 0;
 }
 
-inline toff_t FILE_size_proc( thandle_t const fd )
+inline int nop_close( thandle_t /*handle*/ )
 {
- #ifdef _MSC_VER
- return /*std*/::_filelength( /*std*/::_fileno( gil_reinterpret_cast<FILE *>( fd ) ) );
- #else
- struct stat file_status;
- BOOST_VERIFY( ::fstat( ::fileno( gil_reinterpret_cast<FILE *>( fd ) ), &file_status ) == 0 );
- return file_status.st_size;
- #endif // _MSC_VER
-}
-
-inline int FILE_map_proc( thandle_t /*handle*/, tdata_t * /*pbase*/, toff_t * /*psize*/ )
-{
- return false;
+ return 0;
 }
 
-inline void FILE_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
+template <typename Handle>
+toff_t size( thandle_t const fd )
 {
+ return static_cast<toff_t>( input_device<Handle>::size( reinterpret_cast<Handle>( handle ) ) );
 }
 
 
@@ -245,13 +222,10 @@
     BOOST_ASSERT( handle );
     BOOST_ASSERT( pbase );
     BOOST_ASSERT( psize );
- *pbase = static_cast<tdata_t>( const_cast<memory_chunk_t::value_type *>( gil_reinterpret_cast<memory_chunk_t *>( handle )->begin() ) );
- *psize = gil_reinterpret_cast<memory_chunk_t *>( handle )->size ();
- return true;
-}
-
-inline void memory_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
-{
+ //...zzz...
+ //*pbase = static_cast<tdata_t>( const_cast<memory_range_t::value_type *>( gil_reinterpret_cast<memory_range_t *>( handle )->begin() ) );
+ //*psize = gil_reinterpret_cast<memory_range_t *>( handle )->size ();
+ return false;
 }
 
 
@@ -314,172 +288,7 @@
     void operator=( tiff_view_data_t const & );
 };
 
-
-struct tiff_writer_view_data_t : public tiff_view_data_t
-{
- template <class View>
- tiff_writer_view_data_t( View const & view )
- :
- tiff_view_data_t( view, 0 )
- {
- format_.number = gil_to_libtiff_format<typename View::value_type, is_planar<View>::value>::value;
- }
-
- full_format_t format_;
-};
-
-
-class libtiff_base
-{
-public:
- TIFF & lib_object() const { BOOST_ASSERT( p_tiff_ ); return *p_tiff_; }
-
-protected:
- libtiff_base( char const * const file_name, char const * const access_mode )
- :
- p_tiff_( ::TIFFOpen( file_name, access_mode ) )
- {
- BOOST_ASSERT( file_name );
- construction_check();
- }
-
- explicit libtiff_base( FILE & file )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "",
- &file,
- &detail::FILE_read_proc,
- &detail::FILE_write_proc,
- &detail::FILE_seek_proc,
- &detail::FILE_close_proc_nop,
- &detail::FILE_size_proc,
- &detail::FILE_map_proc,
- &detail::FILE_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- explicit libtiff_base( memory_chunk_t & in_memory_image )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "M",
- &in_memory_image,
- &detail::memory_read_proc,
- &detail::memory_write_proc,
- &detail::memory_seek_proc,
- &detail::memory_close_proc,
- &detail::memory_size_proc,
- &detail::memory_map_proc,
- &detail::memory_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- BF_NOTHROW ~libtiff_base()
- {
- ::TIFFClose( &lib_object() );
- }
-
-protected:
- class cumulative_result : public detail::cumulative_result
- {
- public:
- void throw_if_error() const { detail::cumulative_result::throw_if_error( "Error reading TIFF file" ); }
- };
-
-private:
- void construction_check() const
- {
- io_error_if_not( p_tiff_, "Failed to open TIFF input file" );
- }
-
-private:
- TIFF * const p_tiff_;
-};
-
-
-class libtiff_writer
- :
- public libtiff_base,
- public configure_on_write_writer
-{
-public:
- explicit libtiff_writer( char const * const file_name ) : detail::libtiff_base( file_name, "w" ) {}
-
- explicit libtiff_writer( FILE & file ) : detail::libtiff_base( file ) {}
-
- void write_default( tiff_writer_view_data_t const & view )
- {
- full_format_t::format_bitfield const format_bits( view.format_.bits );
- //BOOST_ASSERT( ( format_bits.planar_configuration == PLANARCONFIG_CONTIG ) && "Add planar support..." );
-
- set_field( TIFFTAG_IMAGEWIDTH , view.dimensions_.x );
- set_field( TIFFTAG_IMAGELENGTH , view.dimensions_.y );
- set_field( TIFFTAG_BITSPERSAMPLE , format_bits.bits_per_sample );
- set_field( TIFFTAG_SAMPLESPERPIXEL, format_bits.samples_per_pixel );
- set_field( TIFFTAG_PLANARCONFIG , format_bits.planar_configuration );
- set_field( TIFFTAG_PHOTOMETRIC , format_bits.photometric );
- set_field( TIFFTAG_INKSET , format_bits.ink_set );
- set_field( TIFFTAG_SAMPLEFORMAT , format_bits.sample_format );
-
- set_field( TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
-
- if ( format_bits.samples_per_pixel == 4 && format_bits.photometric == PHOTOMETRIC_RGB )
- {
- uint16 const type( EXTRASAMPLE_UNASSALPHA );
- set_field( TIFFTAG_EXTRASAMPLES, 1, &type );
- }
-
- write( view );
- }
-
- void write( tiff_writer_view_data_t const & view )
- {
- cumulative_result result;
-
- for ( unsigned int plane( 0 ); plane < view.number_of_planes_; ++plane )
- {
- unsigned char * buf( view.plane_buffers_[ plane ] );
-
- unsigned int row ( 0 );
- unsigned int const target_row( view.dimensions_.y );
- while ( row < target_row )
- {
- result.accumulate_greater( ::TIFFWriteScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view.stride_;
- }
- }
-
- result.throw_if_error();
- }
-
-private:
- template <typename T>
- void set_field( ttag_t const tag, T value )
- {
- #ifdef _MSC_VER
- BOOST_VERIFY( ::TIFFVSetField( &lib_object(), tag, gil_reinterpret_cast<va_list>( &value ) ) );
- #else
- BOOST_VERIFY( ::TIFFSetField ( &lib_object(), tag, value ) );
- #endif // _MSC_VER
- }
-
- template <typename T1, typename T2>
- void set_field( ttag_t const tag, T1 const value1, T2 const value2 )
- {
- BOOST_VERIFY( ::TIFFSetField( &lib_object(), tag, value1, value2 ) );
- }
-};
+struct tiff_writer_view_data_t;
 
 //------------------------------------------------------------------------------
 } // namespace detail
@@ -506,17 +315,15 @@
     template <typename Pixel, bool IsPlanar>
     struct is_supported : mpl::true_ {}; //...zzz...
 
- typedef mpl::map2
+ typedef mpl::set1
     <
- mpl::pair<char const *, libtiff_image>,
- mpl::pair<FILE , libtiff_image>
- > readers;
+ char const *
+ > native_sources;
 
- typedef mpl::map2
+ typedef mpl::set1
     <
- mpl::pair<char const *, detail::libtiff_writer>,
- mpl::pair<FILE , detail::libtiff_writer>
- > writers;
+ char const *
+ > native_sinks;
 
     typedef mpl::vector1_c<format_tag, tiff> supported_image_formats;
 
@@ -529,108 +336,86 @@
 
 class libtiff_image
     :
- public detail::libtiff_base,
     public detail::formatted_image<libtiff_image>
 {
-private:
- typedef detail::full_format_t full_format_t;
-
 public:
     struct guard {};
+
+ class native_reader;
+ class native_writer;
 
-public: /// \ingroup Construction
- explicit libtiff_image( char const * const file_name )
- :
- detail::libtiff_base( file_name, "r" )
- {
- get_format();
- }
-
- explicit libtiff_image( FILE & file )
- :
- detail::libtiff_base( file )
- {
- get_format();
- }
+ typedef native_reader device_reader;
+ typedef native_writer device_writer;
 
 public:
- point2<std::ptrdiff_t> dimensions() const
- {
- return point2<std::ptrdiff_t>( get_field<uint32>( TIFFTAG_IMAGEWIDTH ), get_field<uint32>( TIFFTAG_IMAGELENGTH ) );
- }
-
- format_t const & format () const { return format_.number; }
- format_t const & closest_gil_supported_format() const { return format() ; }
+ TIFF & lib_object() const { BOOST_ASSERT( p_tiff_ ); return *p_tiff_; }
 
-public: // Low-level (row, strip, tile) access
- bool can_do_row_access () const { return !can_do_tile_access(); }
- bool can_do_strip_access() const { return /*...yet to implement...can_do_row_access();*/ false; }
- bool can_do_tile_access () const { return ::TIFFIsTiled( &lib_object() ) != 0; }
-
- std::size_t tile_size () const { return ::TIFFTileSize ( &lib_object() ); }
- std::size_t tile_row_size() const { return ::TIFFTileRowSize( &lib_object() ); }
- point2<std::ptrdiff_t> tile_dimensions() const
+protected:
+ libtiff_image( char const * const file_name, char const * const access_mode )
+ :
+ p_tiff_( ::TIFFOpen( file_name, access_mode ) )
     {
- BOOST_ASSERT( can_do_tile_access() );
- return point2<std::ptrdiff_t>
- (
- get_field<uint32>( TIFFTAG_TILEWIDTH ),
- get_field<uint32>( TIFFTAG_TILELENGTH )
- );
+ BOOST_ASSERT( file_name );
+ construction_check();
     }
 
- class sequential_row_access_state
+ template <typename DeviceHandle>
+ explicit libtiff_image
+ (
+ DeviceHandle const handle,
+ TIFFReadWriteProc const read_proc,
+ TIFFReadWriteProc const write_proc,
+ TIFFMapFileProc const map_proc,
+ TIFFUnmapFileProc const unmap_proc
+ )
         :
- private detail::libtiff_base::cumulative_result
+ p_tiff_
+ (
+ ::TIFFClientOpen
+ (
+ "", "", //"M"
+ reinterpret_cast<thandle_t>( handle ),
+ read_proc,
+ write_proc,
+ &detail::seek<DeviceHandle>,
+ &detail::nop_close, //&detail::close<<DeviceHandle>>
+ &detail::size<<DeviceHandle>,
+ map_proc,
+ unmap_proc
+ )
+ )
     {
- public:
- using detail::libtiff_base::cumulative_result::failed;
- using detail::libtiff_base::cumulative_result::throw_if_error;
-
- BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
-
- private: friend class libtiff_image;
- sequential_row_access_state() : position_( 0 ) {}
-
- unsigned int position_;
- };
-
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
+ construction_check();
+ }
 
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage, unsigned int const plane = 0 ) const
+ BF_NOTHROW ~libtiff_image()
     {
- state.accumulate_greater
- (
- ::TIFFReadScanline( &lib_object(), p_row_storage, state.position_++, static_cast<tsample_t>( plane ) ),
- 0
- );
+ ::TIFFClose( &lib_object() );
     }
 
+private:
+ typedef detail::full_format_t full_format_t;
 
- typedef sequential_row_access_state sequential_tile_access_state;
-
- static sequential_tile_access_state begin_sequential_tile_access() { return begin_sequential_row_access(); }
-
- void read_tile( sequential_row_access_state & state, unsigned char * const p_tile_storage ) const
+public:
+ point2<std::ptrdiff_t> dimensions() const
     {
- state.accumulate_greater
- (
- ::TIFFReadEncodedTile( &lib_object(), state.position_++, p_tile_storage, -1 ),
- 0
- );
+ return point2<std::ptrdiff_t>( get_field<uint32>( TIFFTAG_IMAGEWIDTH ), get_field<uint32>( TIFFTAG_IMAGELENGTH ) );
     }
 
-private:
+protected:
     template <typename T>
     T get_field( ttag_t const tag ) const
     {
+ // Implementation note:
+ // Vararg functions are a brickwall to most compilers so try and avoid
+ // them when possible.
+ // (20.07.2011.) (Domagoj Saric)
         T value;
         #ifdef _MSC_VER
             T * p_value( &value );
- BOOST_VERIFY( ::TIFFVGetFieldDefaulted( &lib_object(), tag, gil_reinterpret_cast<va_list>( &p_value ) ) );
+ BOOST_VERIFY( ::TIFFVGetFieldDefaulted( &lib_object(), tag, reinterpret_cast<va_list>( &p_value ) ) );
         #else
- BOOST_VERIFY( ::TIFFGetFieldDefaulted ( &lib_object(), tag, &value ) );
+ BOOST_VERIFY( ::TIFFGetFieldDefaulted ( &lib_object(), tag, &value ) );
         #endif // _MSC_VER
         return value;
     }
@@ -643,685 +428,35 @@
         return value;
     }
 
- void get_format()
- {
- int cumulative_result( true );
-
- unsigned const samples_per_pixel ( get_field<uint16>( TIFFTAG_SAMPLESPERPIXEL ) );
- unsigned const bits_per_sample ( get_field<uint16>( TIFFTAG_BITSPERSAMPLE ) );
- unsigned const sample_format ( get_field<uint16>( TIFFTAG_SAMPLEFORMAT ) );
- unsigned const planar_configuration( get_field<uint16>( TIFFTAG_PLANARCONFIG ) );
- unsigned const photometric ( get_field<uint16>( TIFFTAG_PHOTOMETRIC ) );
- unsigned const orientation ( get_field<uint16>( TIFFTAG_ORIENTATION ) );
-
- unsigned ink_set( 0 );
- bool unsupported_format( false );
- if ( samples_per_pixel == 4 )
- {
- switch ( photometric )
- {
- case PHOTOMETRIC_RGB:
- {
- std::pair<uint16, uint16 *> const extrasamples( get_field<uint16, uint16 *>( TIFFTAG_EXTRASAMPLES, cumulative_result ) );
- unsupported_format = ( extrasamples.first != 1 || *extrasamples.second != EXTRASAMPLE_UNASSALPHA );
- break;
- }
-
- case PHOTOMETRIC_SEPARATED:
- {
- ink_set = get_field<uint16>( TIFFTAG_INKSET );
- unsupported_format = ( ink_set != INKSET_CMYK );
- break;
- }
-
- default:
- unsupported_format = true;
- }
- }
-
- detail::io_error_if( !cumulative_result || unsupported_format || ( orientation != ORIENTATION_TOPLEFT ), "Unsupported TIFF format" );
-
- format_.number = LIBTIFF_FORMAT( samples_per_pixel, bits_per_sample, ( sample_format == SAMPLEFORMAT_VOID ) ? SAMPLEFORMAT_UINT : sample_format, planar_configuration, photometric, ink_set );
- }
-
-private:
- detail::full_format_t::format_bitfield const & format_bits() const { return format_.bits; }
-
- static unsigned int round_up_divide( unsigned int const dividend, unsigned int const divisor )
- {
- return ( dividend + divisor - 1 ) / divisor;
- }
-
-private: // Private formatted_image_base interface.
- // Implementation note:
- // MSVC 10 accepts friend base_t and friend class base_t, Clang 2.8
- // accepts friend class base_t, Apple Clang 1.6 and GCC (4.2 and 4.6) accept
- // neither.
- // (13.01.2011.) (Domagoj Saric)
- friend class detail::formatted_image<libtiff_image>;
-
- struct tile_setup_t
- #ifndef __GNUC__
- : boost::noncopyable
- #endif // __GNUC__
- {
- tile_setup_t( libtiff_image const & source, point2<std::ptrdiff_t> const & dimensions, offset_t const offset, bool const nptcc )
- :
- tile_height ( source.get_field<uint32>( TIFFTAG_TILELENGTH ) ),
- tile_width ( source.get_field<uint32>( TIFFTAG_TILEWIDTH ) ),
- row_tiles ( source.get_field<uint32>( TIFFTAG_IMAGEWIDTH ) / tile_width ),
- size_of_pixel ( ( source.format_bits().planar_configuration == PLANARCONFIG_CONTIG ? source.format_bits().samples_per_pixel : 1 ) * source.format_bits().bits_per_sample / 8 ),
- tile_width_bytes ( tile_width * size_of_pixel ),
- tile_size_bytes ( tile_width_bytes * tile_height ),
- p_tile_buffer ( new unsigned char[ tile_size_bytes * ( nptcc ? source.format_bits().samples_per_pixel : 1 ) ] ),
- last_row_tile_width ( modulo_unless_zero( dimensions.x, tile_width ) /*dimensions.x % tile_width*/ ),
- tiles_per_row ( ( dimensions.x / tile_width ) + /*( last_row_tile_width != 0 )*/ ( ( dimensions.x % tile_width ) != 0 ) ),
- last_row_tile_width_bytes ( last_row_tile_width * size_of_pixel ),
- last_row_tile_size_bytes ( last_row_tile_width_bytes * tile_height ),
- current_row_tiles_remaining( tiles_per_row ),
- starting_tile ( offset / tile_height * tiles_per_row ),
- rows_to_skip ( offset % tile_height ),
- number_of_tiles ( round_up_divide( dimensions.y, tile_height ) * tiles_per_row * ( source.format_bits().planar_configuration == PLANARCONFIG_SEPARATE ? source.format_bits().samples_per_pixel : 1 ) )
- {
- BOOST_ASSERT( static_cast<tsize_t>( tile_width_bytes ) == ::TIFFTileRowSize( &source.lib_object() ) );
- BOOST_ASSERT( static_cast<tsize_t>( tile_size_bytes ) == ::TIFFTileSize ( &source.lib_object() ) );
- BOOST_ASSERT( starting_tile + number_of_tiles <= ::TIFFNumberOfTiles( &source.lib_object() ) );
- if ( tile_height > static_cast<uint32>( dimensions.y ) )
- {
- rows_to_read_per_tile = end_rows_to_read = dimensions.y;
- }
- else
- {
- end_rows_to_read = modulo_unless_zero( dimensions.y - ( tile_height - rows_to_skip ), tile_height );
- bool const starting_at_last_row( ( number_of_tiles - starting_tile ) <= tiles_per_row );
- rows_to_read_per_tile = starting_at_last_row ? end_rows_to_read : tile_height;
- }
- }
-
- uint32 const tile_height;
- uint32 const tile_width ;
- uint32 const row_tiles ;
-
- unsigned int const size_of_pixel ;
- size_t const tile_width_bytes;
- tsize_t const tile_size_bytes ;
-
- scoped_array<unsigned char> p_tile_buffer;
-
- unsigned int const last_row_tile_width ;
- unsigned int const tiles_per_row ;
- unsigned int const last_row_tile_width_bytes ;
- unsigned int const last_row_tile_size_bytes ;
- unsigned int current_row_tiles_remaining;
- ttile_t const starting_tile ;
- unsigned int rows_to_skip ;
- ttile_t const number_of_tiles ;
- unsigned int /*const*/ end_rows_to_read ;
- unsigned int rows_to_read_per_tile ;
-
- private:
- static unsigned int modulo_unless_zero( unsigned int const dividend, unsigned int const divisor )
- {
- unsigned int const modulo( dividend % divisor );
- return ( modulo != 0 ) ? modulo : divisor;
- }
- };
-
- struct skip_row_results_t
- {
- unsigned int rows_per_strip;
- unsigned int rows_to_read_using_scanlines;
- unsigned int starting_strip;
- };
-
- void raw_copy_to_prepared_view( view_data_t const & view_data ) const
- {
- cumulative_result result;
-
- if ( can_do_tile_access() )
- {
- tile_setup_t setup( *this, view_data.dimensions_, view_data.offset_, false );
-
- ttile_t current_tile( 0 );
-
- for ( unsigned int plane( 0 ); plane < view_data.number_of_planes_; ++plane )
- {
- unsigned char * p_target( view_data.plane_buffers_[ plane ] );
- for ( current_tile += setup.starting_tile; current_tile < setup.number_of_tiles; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- unsigned int const this_tile_width_bytes( last_row_tile ? setup.last_row_tile_width_bytes : setup.tile_width_bytes );
-
- result.accumulate_equal( ::TIFFReadEncodedTile( &lib_object(), current_tile, setup.p_tile_buffer.get(), setup.tile_size_bytes ), setup.tile_size_bytes );
- unsigned char const * p_tile_buffer_location( setup.p_tile_buffer.get() + ( setup.rows_to_skip * this_tile_width_bytes ) );
- unsigned char * p_target_local ( p_target );
- for ( unsigned int row( setup.rows_to_skip ); row < setup.rows_to_read_per_tile; ++row )
- {
- std::memcpy( p_target_local, p_tile_buffer_location, this_tile_width_bytes );
- memunit_advance( p_tile_buffer_location, setup.tile_width_bytes );
- memunit_advance( p_target_local , view_data.stride_ );
- }
- memunit_advance( p_target, this_tile_width_bytes );
- if ( last_row_tile )
- {
- p_target += ( ( setup.rows_to_read_per_tile - 1 - setup.rows_to_skip ) * view_data.stride_ );
- setup.rows_to_skip = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( setup.number_of_tiles - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- setup.rows_to_read_per_tile = setup.end_rows_to_read;
- }
- //BOOST_ASSERT( p_tile_buffer_location == ( setup.p_tile_buffer.get() + this_tile_size_bytes ) || ( setup.rows_to_read_per_tile != setup.tile_height ) );
- BOOST_ASSERT( p_target <= view_data.plane_buffers_[ plane ] + ( view_data.stride_ * view_data.dimensions_.y ) );
- }
- BOOST_ASSERT( p_target == view_data.plane_buffers_[ plane ] + ( view_data.stride_ * view_data.dimensions_.y ) );
- }
- }
- else
- {
- BOOST_ASSERT( ::TIFFScanlineSize( &lib_object() ) <= static_cast<tsize_t>( view_data.stride_ ) );
- for ( unsigned int plane( 0 ); plane < view_data.number_of_planes_; ++plane )
- {
- unsigned char * buf( view_data.plane_buffers_[ plane ] );
- skip_row_results_t skip_result( skip_to_row( view_data.offset_, plane, buf, result ) );
- ttile_t const number_of_strips( ( view_data.dimensions_.y - skip_result.rows_to_read_using_scanlines + skip_result.rows_per_strip - 1 ) / skip_result.rows_per_strip );
- skip_result.rows_to_read_using_scanlines = std::min<unsigned int>( skip_result.rows_to_read_using_scanlines, view_data.dimensions_.y );
-
- unsigned int row( view_data.offset_ );
- while ( row != ( view_data.offset_ + skip_result.rows_to_read_using_scanlines ) )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view_data.stride_;
- }
-
- unsigned int const view_strip_increment( view_data.stride_ * skip_result.rows_per_strip );
- if ( view_strip_increment == static_cast<unsigned int>( ::TIFFStripSize( &lib_object() ) ) )
- {
- for ( unsigned int strip( skip_result.starting_strip ); strip < number_of_strips; ++strip )
- {
- result.accumulate_greater( ::TIFFReadEncodedStrip( &lib_object(), strip, buf, view_strip_increment ), 0 );
- buf += view_strip_increment;
- row += skip_result.rows_per_strip;
- }
- }
-
- unsigned int const target_row( view_data.offset_ + view_data.dimensions_.y );
- while ( row < target_row )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view_data.stride_;
- }
- }
- }
-
- result.throw_if_error();
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // generic_convert_to_prepared_view()
- // ----------------------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \todo Cleanup, document, split up and refactor this humongous beast
- /// (remove duplication, extract non-template and shared functionality...).
- /// (16.09.2010.) (Domagoj Saric)
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <class MyView, class TargetView, class Converter>
- void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
- {
- using namespace detail;
-
- typedef typename get_original_view_t<TargetView>::type original_target_view_t;
-
- typedef typename mpl::eval_if
- <
- is_planar<MyView>,
- nth_channel_view_type<original_target_view_t>,
- get_original_view_t<TargetView>
- >::type local_target_view_t;
- typedef typename get_original_view_t<local_target_view_t>::type::x_iterator target_x_iterator;
- typedef typename get_original_view_t<local_target_view_t>::type::y_iterator target_y_iterator;
-
- typedef typename mpl::eval_if
- <
- is_planar<MyView>,
- nth_channel_view_type<MyView>,
- mpl::identity<MyView>
- >::type::value_type my_pixel_t;
-
- typedef mpl::bool_
- <
- is_planar<MyView >::value &&
- !is_planar<original_target_view_t>::value &&
- (
- !is_same<typename color_space_type <MyView>::type, typename color_space_type <original_target_view_t>::type>::value ||
- !is_same<typename channel_mapping_type<MyView>::type, typename channel_mapping_type<original_target_view_t>::type>::value
- )
- > nondirect_planar_to_contig_conversion_t;
-
- cumulative_result result;
-
- typedef mpl::int_<is_planar<MyView>::value ? num_channels<MyView>::value : 1> number_of_planes_t;
-
- dimensions_t const & dimensions( original_view( view ).dimensions() );
-
- ////////////////////////////////////////////////////////////////////////
- // Tiled
- ////////////////////////////////////////////////////////////////////////
-
- if ( ::TIFFIsTiled( &lib_object() ) )
- {
- tile_setup_t setup
- (
- *this,
- dimensions,
- get_offset<offset_t>( view ),
- nondirect_planar_to_contig_conversion_t::value
- );
-
- unsigned int const tiles_per_plane( setup.number_of_tiles / number_of_planes_t::value );
- ttile_t current_tile ( 0 );
-
- if ( nondirect_planar_to_contig_conversion_t::value )
- {
- // For NPTCC there is no need for target view
- // planar<->non-planar adjustment because here we read whole
- // pixels before copying to the target view...
- typename original_target_view_t::y_iterator p_target( original_view( view ).y_at( 0, 0 ) );
-
- typename MyView::x_iterator const buffer_iterator
- (
- make_planar_buffer_iterator<typename MyView::x_iterator>
- (
- setup.p_tile_buffer.get(),
- setup.tile_size_bytes,
- number_of_planes_t()
- )
- );
-
- unsigned int horizontal_offset( 0 );
-
- for ( current_tile += setup.starting_tile; current_tile < tiles_per_plane; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- unsigned int const this_tile_width( last_row_tile ? setup.last_row_tile_width : setup.tile_width );
-
- for ( unsigned int channel_tile( 0 ); channel_tile < number_of_planes_t::value; ++channel_tile )
- {
- ttile_t const raw_tile_number( current_tile + ( channel_tile * tiles_per_plane ) );
- result.accumulate_equal
- (
- ::TIFFReadEncodedTile
- (
- &lib_object(),
- raw_tile_number,
- //buffer_iterator.at_c_dynamic( channel_tile ),
- &(*buffer_iterator)[ channel_tile ],
- setup.tile_size_bytes
- ),
- setup.tile_size_bytes
- );
- }
-
- typename MyView ::x_iterator p_source_pixel( buffer_iterator + ( setup.rows_to_skip * this_tile_width ) );
- typename original_target_view_t::x_iterator p_target_pixel( p_target.base() + horizontal_offset );
- for ( unsigned int row( setup.rows_to_skip ); row < setup.rows_to_read_per_tile; ++row )
- {
- typename MyView::x_iterator const local_end( p_source_pixel + this_tile_width );
- while ( p_source_pixel < local_end )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- BOOST_ASSERT( p_source_pixel == local_end );
- p_source_pixel += setup.tile_width - this_tile_width;
- memunit_advance( p_target_pixel, original_view( view ).pixels().row_size() );
- p_target_pixel -= this_tile_width;
- }
- if ( last_row_tile )
- {
- p_target += ( setup.rows_to_read_per_tile /*- 1*/ - setup.rows_to_skip );
- setup.rows_to_skip = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( tiles_per_plane - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- setup.rows_to_read_per_tile = setup.end_rows_to_read;
- }
- else
- horizontal_offset += setup.tile_width;
- //...make NPTCC version...BOOST_ASSERT( p_source_pixel == reinterpret_cast<my_pixel_t const *>( setup.p_tile_buffer.get() + this_tile_size_bytes ) || ( setup.rows_to_read_per_tile != setup.tile_height ) );
- BOOST_ASSERT( p_target <= original_view( view ).col_end( 0 ) );
- }
- BOOST_ASSERT( p_target == original_view( view ).col_end( 0 ) );
- }
- else // non NPTCC...
- {
- for
- (
- unsigned int plane( 0 ), current_plane_end_tile( tiles_per_plane );
- plane < number_of_planes_t::value;
- ++plane, current_plane_end_tile += tiles_per_plane
- )
- {
- local_target_view_t const & target_view( adjust_target_to_my_view( original_view( view ), plane, is_planar<MyView>() ) );
- target_y_iterator p_target( target_view.y_at( 0, 0 ) );
- BOOST_ASSERT( p_target.step() == original_view( view ).pixels().row_size() );
-
- unsigned int horizontal_offset ( 0 );
- unsigned int current_plane_rows_to_read_per_tile( setup.rows_to_read_per_tile );
- unsigned int current_plane_rows_to_skip ( setup.rows_to_skip );
-
- for ( current_tile += setup.starting_tile; current_tile < current_plane_end_tile; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- //unsigned int const this_tile_size_bytes ( last_row_tile ? setup.last_row_tile_size_bytes : setup.tile_size_bytes );
- unsigned int const this_tile_width_bytes( last_row_tile ? setup.last_row_tile_width_bytes : setup.tile_width_bytes );
-
- result.accumulate_equal( ::TIFFReadEncodedTile( &lib_object(), current_tile, setup.p_tile_buffer.get(), setup.tile_size_bytes ), setup.tile_size_bytes );
-
- my_pixel_t const * p_source_pixel( gil_reinterpret_cast_c<my_pixel_t const *>( setup.p_tile_buffer.get() + ( current_plane_rows_to_skip * this_tile_width_bytes ) ) );
- target_x_iterator p_target_pixel( p_target.base() + horizontal_offset );
- for ( unsigned int row( current_plane_rows_to_skip ); row < current_plane_rows_to_read_per_tile; ++row )
- {
- my_pixel_t const * const local_end( memunit_advanced( p_source_pixel, this_tile_width_bytes ) );
- while ( p_source_pixel < local_end )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- BOOST_ASSERT( p_source_pixel == local_end );
- memunit_advance( p_source_pixel, setup.tile_width_bytes - this_tile_width_bytes );
- memunit_advance( p_target_pixel, original_view( view ).pixels().row_size() - ( this_tile_width_bytes * memunit_step( p_target_pixel ) / memunit_step( p_source_pixel ) ) );
- }
- BOOST_ASSERT
- (
- ( p_source_pixel == reinterpret_cast<my_pixel_t const *>( setup.p_tile_buffer.get() + setup.tile_size_bytes ) ) ||
- ( current_plane_rows_to_read_per_tile != setup.tile_height )
- );
- if ( last_row_tile )
- {
- p_target += ( current_plane_rows_to_read_per_tile /*- 1*/ - current_plane_rows_to_skip );
- current_plane_rows_to_skip = 0;
- horizontal_offset = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( current_plane_end_tile - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- current_plane_rows_to_read_per_tile = setup.end_rows_to_read;
- }
- else
- {
- BOOST_ASSERT( this_tile_width_bytes == setup.tile_width_bytes );
- horizontal_offset += setup.tile_width;
- }
- BOOST_ASSERT( p_target.base() <= target_view.end().x() );
- }
- BOOST_ASSERT( p_target.base() == target_view.end().x() );
- }
- }
- }
- else
- ////////////////////////////////////////////////////////////////////////
- // Striped
- ////////////////////////////////////////////////////////////////////////
- {
- scanline_buffer_t<my_pixel_t> const scanline_buffer( *this, nondirect_planar_to_contig_conversion_t::value() );
-
- if ( nondirect_planar_to_contig_conversion_t::value )
- {
- typename original_target_view_t::y_iterator p_target( original_view( view ).y_at( 0, 0 ) );
- unsigned int row ( get_offset<offset_t>( view ) );
- unsigned int const target_row( row + dimensions.y );
-
- typename MyView::x_iterator const buffer_iterator
- (
- make_planar_buffer_iterator<typename MyView::x_iterator>
- (
- scanline_buffer.begin(),
- dimensions.x,
- number_of_planes_t()
- )
- );
-
- while ( row != target_row )
- {
- for ( unsigned int plane( 0 ); plane < number_of_planes_t::value; ++plane )
- {
- tdata_t const p_buffer( &(*buffer_iterator)[ plane ] );
- //...zzz...yup...not the most efficient thing in the universe...
- skip_to_row( get_offset<offset_t>( view ) + row, plane, p_buffer, result );
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), p_buffer, row, static_cast<tsample_t>( plane ) ), 0 );
- }
- typename MyView ::x_iterator p_source_pixel( buffer_iterator );
- typename original_target_view_t::x_iterator p_target_pixel( p_target.base() );
- while ( &(*p_source_pixel)[ 0 ] < &(*scanline_buffer.end())[ 0 ] )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- ++p_target;
- ++row;
- }
- }
- else
- {
- for ( unsigned int plane( 0 ); plane < number_of_planes_t::value; ++plane )
- {
- if ( is_offset_view<TargetView>::value )
- skip_to_row( get_offset<offset_t>( view ), plane, scanline_buffer.begin(), result );
-
- local_target_view_t const & target_view( adjust_target_to_my_view( original_view( view ), plane, is_planar<MyView>() ) );
- target_y_iterator p_target( target_view.y_at( 0, 0 ) );
- unsigned int row ( get_offset<offset_t>( view ) );
- unsigned int const target_row( row + dimensions.y );
- while ( row != target_row )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), scanline_buffer.begin(), row++, static_cast<tsample_t>( plane ) ), 0 );
- my_pixel_t const * p_source_pixel( scanline_buffer.begin() );
- target_x_iterator p_target_pixel( p_target.base() );
- while ( p_source_pixel != scanline_buffer.end() )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- ++p_target;
- }
- }
- }
- }
-
- result.throw_if_error();
- }
-
- static std::size_t cached_format_size( format_t const format )
+ static std::size_t cached_format_size( formatted_image_traits<libtiff_image>::format_t const format )
     {
         full_format_t::format_bitfield const & bits( reinterpret_cast<full_format_t const &>( format ).bits );
         return bits.bits_per_sample * ( ( bits.planar_configuration == PLANARCONFIG_CONTIG ) ? bits.samples_per_pixel : 1 ) / 8;
     }
 
-private:
- template <typename View>
- static typename nth_channel_view_type<View>::type
- adjust_target_to_my_view( View const & view, unsigned int const plane, mpl::true_ /*source is planar*/ )
- {
- return nth_channel_view( view, plane );
- }
-
- template <typename View>
- static View const &
- adjust_target_to_my_view( View const & view, unsigned int const plane, mpl::false_ /*source is not planar*/ )
- {
- BOOST_ASSERT( plane == 0 );
- ignore_unused_variable_warning( plane );
- return view;
- }
-
- template <typename PixelIterator>
- static PixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int /*row_width*/, mpl::int_<1> )
- {
- BOOST_ASSERT( !"Should not get called." );
- return static_cast<PixelIterator>( p_buffer );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<2> )
- {
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( first + stride );
- return PlanarPixelIterator( first, second );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<3> )
- {
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( first + stride );
- ptr_t const third ( second + stride );
- return PlanarPixelIterator( first, second, third );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<4> )
- {
- //...eradicate this triplication...
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( memunit_advanced( first , stride ) );
- ptr_t const third ( memunit_advanced( second, stride ) );
- ptr_t const fourth( memunit_advanced( third , stride ) );
- return PlanarPixelIterator( first, second, third, fourth );
- }
-
- // Implementation note:
- // Because of plain RVO incapable compilers (like Clang or not the latest
- // GCCs) a simple std::pair with a scoped_array cannot be used.
- // (11.01.2011.) (Domagoj Saric)
- //typedef std::pair
- //<
- // scoped_array<unsigned char> const,
- // unsigned char const * const
- //> generic_scanline_buffer_t;
-
- class scanline_buffer_base_t : boost::noncopyable
- {
- protected:
- explicit scanline_buffer_base_t( std::size_t const size )
- :
- p_begin_( new unsigned char[ size ] ),
- p_end_ ( p_begin_ + size )
- {}
-
- // This one makes the end pointer point to the end of the scanline/row
- // of the first plane not the end of the buffer itself...ugh...to be cleaned up...
- explicit scanline_buffer_base_t( std::pair<std::size_t, std::size_t> const size_to_allocate_size_to_report_pair )
- :
- p_begin_( new unsigned char[ size_to_allocate_size_to_report_pair.first ] ),
- p_end_ ( p_begin_ + size_to_allocate_size_to_report_pair.second )
- {}
-
- ~scanline_buffer_base_t() { delete[] p_begin_; }
-
- BF_NOTHROWNORESTRICTNOALIAS unsigned char * begin() const { return p_begin_; }
- BF_NOTHROWNORESTRICTNOALIAS unsigned char const * end () const { return p_end_ ; }
-
- static std::size_t scanline_buffer_construction( libtiff_image const & tiff )
- {
- return ( ::TIFFScanlineSize( &tiff.lib_object() ) );
- }
-
- static std::pair<std::size_t, std::size_t> planar_scanline_buffer_construction( libtiff_image const & tiff )
- {
- std::size_t const scanline_size ( tiff.format_bits().bits_per_sample * tiff.dimensions().x / 8 );
- std::size_t const allocation_size( scanline_size * tiff.format_bits().samples_per_pixel );
- return std::pair<std::size_t, std::size_t>( allocation_size, scanline_size );
- }
-
- private:
- unsigned char * const p_begin_;
- unsigned char const * const p_end_ ;
- };
-
- template <typename Pixel>
- class scanline_buffer_t : public scanline_buffer_base_t
- {
- public:
- scanline_buffer_t( libtiff_image const & tiff, mpl::true_ /* nptcc */ ) : scanline_buffer_base_t( planar_scanline_buffer_construction( tiff ) ) {}
- scanline_buffer_t( libtiff_image const & tiff, mpl::false_ /* not nptcc */ ) : scanline_buffer_base_t( scanline_buffer_construction ( tiff ) ) {}
-
- Pixel * begin() const { return gil_reinterpret_cast <Pixel *>( scanline_buffer_base_t::begin() ); }
- Pixel const * end () const { return gil_reinterpret_cast_c<Pixel const *>( scanline_buffer_base_t::end () ); }
- };
-
- template <typename Pixel>
- class planar_scanline_buffer_t : scanline_buffer_t<Pixel>
+protected:
+ class cumulative_result : public detail::cumulative_result
     {
     public:
- planar_scanline_buffer_t( libtiff_image const & image ) : scanline_buffer_t<Pixel>( tiff, mpl::true_() ) {}
+ void throw_if_error() const { detail::cumulative_result::throw_if_error( "Error reading TIFF file" ); }
     };
 
- skip_row_results_t BF_NOTHROWNOALIAS skip_to_row
- (
- unsigned int const row_to_skip_to,
- unsigned int const sample,
- tdata_t const buffer,
- cumulative_result & error_result
- ) const
+private:
+ void construction_check() const
     {
- BOOST_ASSERT( !::TIFFIsTiled( &lib_object() ) );
-
- skip_row_results_t result;
- result.rows_per_strip = get_field<uint32>( TIFFTAG_ROWSPERSTRIP );
- unsigned int const number_of_rows_to_skip_using_scanlines( row_to_skip_to % result.rows_per_strip );
- result.starting_strip = ( row_to_skip_to / result.rows_per_strip ) + ( number_of_rows_to_skip_using_scanlines != 0 ) + sample * get_field<uint32>( TIFFTAG_IMAGEWIDTH );
- result.rows_to_read_using_scanlines = row_to_skip_to ? ( result.rows_per_strip - number_of_rows_to_skip_using_scanlines - 1 ) : 0;
-
- bool const canSkipDirectly
- (
- ( result.rows_per_strip == 1 ) ||
- ( get_field<uint16>( TIFFTAG_COMPRESSION ) == COMPRESSION_NONE )
- );
- unsigned int row
- (
- canSkipDirectly
- ? row_to_skip_to
- : ( row_to_skip_to - number_of_rows_to_skip_using_scanlines )
- );
- while ( row < row_to_skip_to )
- {
- error_result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buffer, row++, static_cast<tsample_t>( sample ) ), 0 );
- }
-
- //BOOST_ASSERT( !row_to_skip_to || ( ::TIFFCurrentRow( &lib_object() ) == row_to_skip_to ) );
-
- return result;
+ detail::io_error_if_not( p_tiff_, "Failed to create a LibTIFF object." );
     }
 
 private:
- full_format_t format_;
+ TIFF * const p_tiff_;
 };
 
 #if defined(BOOST_MSVC)
 # pragma warning( pop )
 #endif
 
-
+//------------------------------------------------------------------------------
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------

Copied: sandbox/gil/boost/gil/extension/io2/libtiff_reader.hpp (from r73054, /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp)
==============================================================================
--- /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/libtiff_reader.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -1,9 +1,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file libtiff_image.hpp
-/// -----------------------
+/// \file libtiff_reader.hpp
+/// ------------------------
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,21 +13,18 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef libtiff_reader_hpp__24E9D122_DAC7_415B_8880_9BFA03916E9F
+#define libtiff_reader_hpp__24E9D122_DAC7_415B_8880_9BFA03916E9F
 #pragma once
-#ifndef libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
-#define libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
 //------------------------------------------------------------------------------
-#include "formatted_image.hpp"
+#include "backend_reader.hpp"
+#include "libtiff_image.hpp"
 
 #include "detail/io_error.hpp"
 #include "detail/libx_shared.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/shared.hpp"
 
-#if BOOST_MPL_LIMIT_VECTOR_SIZE < 35
- #error libtiff support requires mpl vectors of size 35 or greater...
-#endif
-
 #include <boost/array.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/smart_ptr/scoped_array.hpp>
@@ -37,16 +34,6 @@
     #include "tiff.h"
     #include "tiffio.h"
 }
-
-#include <cstdio>
-#include <set>
-#ifdef _MSC_VER
- #include "io.h"
-#else
- #include "sys/types.h"
- #include "sys/stat.h"
- #include "unistd.h"
-#endif // _MSC_VER
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -54,511 +41,61 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-namespace detail
+namespace io
 {
 //------------------------------------------------------------------------------
-
-#define LIBTIFF_SPP( param ) ( ( param ) << ( 0 ) )
-#define LIBTIFF_BPS( param ) ( ( param ) << ( 0 + 3 ) )
-#define LIBTIFF_FMT( param ) ( ( param ) << ( 0 + 3 + 5 ) )
-#define LIBTIFF_PLANAR( param ) ( ( param ) << ( 0 + 3 + 5 + 3 ) )
-#define LIBTIFF_PHOTOMETRIC( param ) ( ( param ) << ( 0 + 3 + 5 + 3 + 2 ) )
-#define LIBTIFF_INKSET( param ) ( ( param ) << ( 0 + 3 + 5 + 3 + 2 + 3 ) )
-
-#define LIBTIFF_FORMAT( spp, bps, sample_format, planar_config, photometric_interpretation, inkset ) \
-( \
- LIBTIFF_SPP( spp ) | \
- LIBTIFF_BPS( bps ) | \
- LIBTIFF_FMT( sample_format ) | \
- LIBTIFF_PLANAR( planar_config ) | \
- LIBTIFF_PHOTOMETRIC( photometric_interpretation ) | \
- LIBTIFF_INKSET( inkset ) \
-)
-
-
-union full_format_t
-{
- struct format_bitfield
- {
- unsigned int samples_per_pixel : 3;
- unsigned int bits_per_sample : 5;
- unsigned int sample_format : 3;
- unsigned int planar_configuration : 2;
- unsigned int photometric : 3;
- unsigned int ink_set : 2;
- };
-
- typedef unsigned int format_id;
-
- format_bitfield bits ;
- format_id number;
-};
-
-
-template <typename Pixel, bool isPlanar>
-struct gil_to_libtiff_format
- :
- mpl::int_
- <
- LIBTIFF_FORMAT
- (
- num_channels<Pixel>::value,
- sizeof( typename channel_type<Pixel>::type ) * 8,
- (
- ( is_unsigned <typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_UINT ) |
- ( is_signed <typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_INT ) |
- ( is_floating_point<typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_IEEEFP )
- ),
- isPlanar ? PLANARCONFIG_SEPARATE : PLANARCONFIG_CONTIG,
- (
- ( is_same<typename color_space_type<Pixel>::type, rgb_t >::value * PHOTOMETRIC_RGB ) |
- ( is_same<typename color_space_type<Pixel>::type, cmyk_t>::value * PHOTOMETRIC_SEPARATED ) |
- ( is_same<typename color_space_type<Pixel>::type, gray_t>::value * PHOTOMETRIC_MINISBLACK )
- ),
- ( is_same<typename color_space_type<Pixel>::type, cmyk_t>::value ? INKSET_CMYK : 0 )
- )
- >
-{};
-
-
-typedef mpl::vector35
-<
- image<rgb8_pixel_t , false>,
- image<rgb8_pixel_t , true >,
- image<rgba8_pixel_t, false>,
- image<rgba8_pixel_t, true >,
- image<cmyk8_pixel_t, false>,
- image<cmyk8_pixel_t, true >,
- image<gray8_pixel_t, false>,
-
- image<rgb16_pixel_t , false>,
- image<rgb16_pixel_t , true >,
- image<rgba16_pixel_t, false>,
- image<rgba16_pixel_t, true >,
- image<cmyk16_pixel_t, false>,
- image<cmyk16_pixel_t, true >,
- image<gray16_pixel_t, false>,
-
- image<rgb8s_pixel_t , false>,
- image<rgb8s_pixel_t , true >,
- image<rgba8s_pixel_t, false>,
- image<rgba8s_pixel_t, true >,
- image<cmyk8s_pixel_t, false>,
- image<cmyk8s_pixel_t, true >,
- image<gray8s_pixel_t, false>,
-
- image<rgb16s_pixel_t , false>,
- image<rgb16s_pixel_t , true >,
- image<rgba16s_pixel_t, false>,
- image<rgba16s_pixel_t, true >,
- image<cmyk16s_pixel_t, false>,
- image<cmyk16s_pixel_t, true >,
- image<gray16s_pixel_t, false>,
-
- image<rgb32f_pixel_t , false>,
- image<rgb32f_pixel_t , true >,
- image<rgba32f_pixel_t, false>,
- image<rgba32f_pixel_t, true >,
- image<cmyk32f_pixel_t, false>,
- image<cmyk32f_pixel_t, true >,
- image<gray32f_pixel_t, false>
-> libtiff_supported_pixel_formats;
-
-
-inline tsize_t FILE_read_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
-{
- return static_cast<tsize_t>( std::fread( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
-}
-
-inline tsize_t FILE_write_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
-{
- return static_cast<tsize_t>( std::fwrite( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
-}
-
-inline toff_t FILE_seek_proc( thandle_t const handle, toff_t const off, int const whence )
-{
- return static_cast<tsize_t>( std::fseek( reinterpret_cast<FILE *>( handle ), off, whence ) );
-}
-
-inline int FILE_close_proc( thandle_t const handle )
-{
- return std::fclose( reinterpret_cast<FILE *>( handle ) );
-}
-
-inline int FILE_close_proc_nop( thandle_t /*handle*/ )
+namespace detail
 {
- return 0;
-}
+//------------------------------------------------------------------------------
 
-inline toff_t FILE_size_proc( thandle_t const fd )
+template <typename Handle>
+tsize_t read( thandle_t const handle, tdata_t const buf, tsize_t const size )
 {
- #ifdef _MSC_VER
- return /*std*/::_filelength( /*std*/::_fileno( gil_reinterpret_cast<FILE *>( fd ) ) );
- #else
- struct stat file_status;
- BOOST_VERIFY( ::fstat( ::fileno( gil_reinterpret_cast<FILE *>( fd ) ), &file_status ) == 0 );
- return file_status.st_size;
- #endif // _MSC_VER
+ return static_cast<tsize_t>( input_device<Handle>::read( buf, size, reinterpret_cast<Handle>( handle ) ) );
 }
 
-inline int FILE_map_proc( thandle_t /*handle*/, tdata_t * /*pbase*/, toff_t * /*psize*/ )
+template <typename Handle>
+int map( thandle_t /*handle*/, tdata_t * /*pbase*/, toff_t * /*psize*/ )
 {
     return false;
 }
 
-inline void FILE_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
-{
-}
-
-
-inline tsize_t memory_read_proc( thandle_t /*handle*/, tdata_t /*buf*/, tsize_t /*size*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline tsize_t memory_write_proc( thandle_t /*handle*/, tdata_t /*buf*/, tsize_t /*size*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline toff_t memory_seek_proc( thandle_t /*handle*/, toff_t /*off*/, int /*whence*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline int memory_close_proc( thandle_t /*handle*/ )
-{
- return 0;
-}
-
-inline toff_t memory_size_proc( thandle_t /*handle*/ )
+template <typename Handle>
+void unmap( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
 {
- BF_UNREACHABLE_CODE
- return 0;
 }
 
-inline int memory_map_proc( thandle_t const handle, tdata_t * const pbase, toff_t * const psize )
-{
- BOOST_ASSERT( handle );
- BOOST_ASSERT( pbase );
- BOOST_ASSERT( psize );
- *pbase = static_cast<tdata_t>( const_cast<memory_chunk_t::value_type *>( gil_reinterpret_cast<memory_chunk_t *>( handle )->begin() ) );
- *psize = gil_reinterpret_cast<memory_chunk_t *>( handle )->size ();
- return true;
-}
-
-inline void memory_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
-{
-}
-
-
-#if defined(BOOST_MSVC)
-# pragma warning( push )
-# pragma warning( disable : 4127 ) // "conditional expression is constant"
-#endif
-
-struct tiff_view_data_t
-{
- template <class View>
- explicit tiff_view_data_t( View const & view, generic_vertical_roi::offset_t const offset = 0 )
- :
- dimensions_( view.dimensions() ),
- stride_ ( view.pixels().row_size() ),
- offset_ ( offset )
- #ifdef _DEBUG
- ,format_id_( gil_to_libtiff_format<typename View::value_type, is_planar<View>::value>::value )
- #endif
- {
- set_buffers( view, is_planar<View>() );
- }
-
- void set_format( full_format_t::format_id const format )
- {
- #ifdef _DEBUG
- BOOST_ASSERT( ( format_id_ == format ) && !"libtiff does not provide builtin conversion." );
- #endif // _DEBUG
- ignore_unused_variable_warning( format );
- }
-
- point2<std::ptrdiff_t> const & dimensions_ ;
- unsigned int stride_ ;
- unsigned int number_of_planes_;
- array<unsigned char *, 4> plane_buffers_ ;
- generic_vertical_roi::offset_t offset_ ;
-
- #ifdef _DEBUG
- unsigned int format_id_;
- #endif
-
-private: // this should probably go to the base formatted_image class...
- template <class View>
- void set_buffers( View const & view, mpl::true_ /*is planar*/ )
- {
- for ( number_of_planes_ = 0; number_of_planes_ < num_channels<View>::value; ++number_of_planes_ )
- {
- plane_buffers_[ number_of_planes_ ] = gil_reinterpret_cast<unsigned char *>( planar_view_get_raw_data( view, number_of_planes_ ) );
- }
- BOOST_ASSERT( number_of_planes_ == num_channels<View>::value );
- }
-
- template <class View>
- void set_buffers( View const & view, mpl::false_ /*is not planar*/ )
- {
- number_of_planes_ = 1;
- plane_buffers_[ 0 ] = formatted_image_base::get_raw_data( view );
- }
-
- void operator=( tiff_view_data_t const & );
-};
-
-
-struct tiff_writer_view_data_t : public tiff_view_data_t
-{
- template <class View>
- tiff_writer_view_data_t( View const & view )
- :
- tiff_view_data_t( view, 0 )
- {
- format_.number = gil_to_libtiff_format<typename View::value_type, is_planar<View>::value>::value;
- }
-
- full_format_t format_;
-};
-
-
-class libtiff_base
-{
-public:
- TIFF & lib_object() const { BOOST_ASSERT( p_tiff_ ); return *p_tiff_; }
-
-protected:
- libtiff_base( char const * const file_name, char const * const access_mode )
- :
- p_tiff_( ::TIFFOpen( file_name, access_mode ) )
- {
- BOOST_ASSERT( file_name );
- construction_check();
- }
-
- explicit libtiff_base( FILE & file )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "",
- &file,
- &detail::FILE_read_proc,
- &detail::FILE_write_proc,
- &detail::FILE_seek_proc,
- &detail::FILE_close_proc_nop,
- &detail::FILE_size_proc,
- &detail::FILE_map_proc,
- &detail::FILE_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- explicit libtiff_base( memory_chunk_t & in_memory_image )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "M",
- &in_memory_image,
- &detail::memory_read_proc,
- &detail::memory_write_proc,
- &detail::memory_seek_proc,
- &detail::memory_close_proc,
- &detail::memory_size_proc,
- &detail::memory_map_proc,
- &detail::memory_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- BF_NOTHROW ~libtiff_base()
- {
- ::TIFFClose( &lib_object() );
- }
-
-protected:
- class cumulative_result : public detail::cumulative_result
- {
- public:
- void throw_if_error() const { detail::cumulative_result::throw_if_error( "Error reading TIFF file" ); }
- };
-
-private:
- void construction_check() const
- {
- io_error_if_not( p_tiff_, "Failed to open TIFF input file" );
- }
-
-private:
- TIFF * const p_tiff_;
-};
-
-
-class libtiff_writer
- :
- public libtiff_base,
- public configure_on_write_writer
-{
-public:
- explicit libtiff_writer( char const * const file_name ) : detail::libtiff_base( file_name, "w" ) {}
-
- explicit libtiff_writer( FILE & file ) : detail::libtiff_base( file ) {}
-
- void write_default( tiff_writer_view_data_t const & view )
- {
- full_format_t::format_bitfield const format_bits( view.format_.bits );
- //BOOST_ASSERT( ( format_bits.planar_configuration == PLANARCONFIG_CONTIG ) && "Add planar support..." );
-
- set_field( TIFFTAG_IMAGEWIDTH , view.dimensions_.x );
- set_field( TIFFTAG_IMAGELENGTH , view.dimensions_.y );
- set_field( TIFFTAG_BITSPERSAMPLE , format_bits.bits_per_sample );
- set_field( TIFFTAG_SAMPLESPERPIXEL, format_bits.samples_per_pixel );
- set_field( TIFFTAG_PLANARCONFIG , format_bits.planar_configuration );
- set_field( TIFFTAG_PHOTOMETRIC , format_bits.photometric );
- set_field( TIFFTAG_INKSET , format_bits.ink_set );
- set_field( TIFFTAG_SAMPLEFORMAT , format_bits.sample_format );
-
- set_field( TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
-
- if ( format_bits.samples_per_pixel == 4 && format_bits.photometric == PHOTOMETRIC_RGB )
- {
- uint16 const type( EXTRASAMPLE_UNASSALPHA );
- set_field( TIFFTAG_EXTRASAMPLES, 1, &type );
- }
-
- write( view );
- }
-
- void write( tiff_writer_view_data_t const & view )
- {
- cumulative_result result;
-
- for ( unsigned int plane( 0 ); plane < view.number_of_planes_; ++plane )
- {
- unsigned char * buf( view.plane_buffers_[ plane ] );
-
- unsigned int row ( 0 );
- unsigned int const target_row( view.dimensions_.y );
- while ( row < target_row )
- {
- result.accumulate_greater( ::TIFFWriteScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view.stride_;
- }
- }
-
- result.throw_if_error();
- }
-
-private:
- template <typename T>
- void set_field( ttag_t const tag, T value )
- {
- #ifdef _MSC_VER
- BOOST_VERIFY( ::TIFFVSetField( &lib_object(), tag, gil_reinterpret_cast<va_list>( &value ) ) );
- #else
- BOOST_VERIFY( ::TIFFSetField ( &lib_object(), tag, value ) );
- #endif // _MSC_VER
- }
-
- template <typename T1, typename T2>
- void set_field( ttag_t const tag, T1 const value1, T2 const value2 )
- {
- BOOST_VERIFY( ::TIFFSetField( &lib_object(), tag, value1, value2 ) );
- }
-};
-
 //------------------------------------------------------------------------------
 } // namespace detail
 
-class libtiff_image;
 
-template <>
-struct formatted_image_traits<libtiff_image>
-{
- typedef detail::full_format_t::format_id format_t;
-
- typedef detail::libtiff_supported_pixel_formats supported_pixel_formats_t;
-
- typedef detail::generic_vertical_roi roi_t;
-
- typedef detail::tiff_view_data_t view_data_t;
-
- struct gil_to_native_format
- {
- template <typename Pixel, bool IsPlanar>
- struct apply : detail::gil_to_libtiff_format<Pixel, IsPlanar> {};
- };
-
- template <typename Pixel, bool IsPlanar>
- struct is_supported : mpl::true_ {}; //...zzz...
-
- typedef mpl::map2
- <
- mpl::pair<char const *, libtiff_image>,
- mpl::pair<FILE , libtiff_image>
- > readers;
-
- typedef mpl::map2
- <
- mpl::pair<char const *, detail::libtiff_writer>,
- mpl::pair<FILE , detail::libtiff_writer>
- > writers;
-
- typedef mpl::vector1_c<format_tag, tiff> supported_image_formats;
-
- typedef detail::tiff_writer_view_data_t writer_view_data_t;
-
- BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( void * ) );
- BOOST_STATIC_CONSTANT( bool , builtin_conversion = false );
-};
-
-
-class libtiff_image
+class libtiff_image::native_reader
     :
- public detail::libtiff_base,
- public detail::formatted_image<libtiff_image>
+ public libtiff_image,
+ public detail::backend_reader<libtiff_image>
 {
-private:
- typedef detail::full_format_t full_format_t;
-
-public:
- struct guard {};
-
 public: /// \ingroup Construction
- explicit libtiff_image( char const * const file_name )
+ explicit native_reader( char const * const file_name )
         :
- detail::libtiff_base( file_name, "r" )
- {
- get_format();
- }
+ libtiff_image( file_name, "r" ),
+ format_ ( get_format() )
+ {}
 
- explicit libtiff_image( FILE & file )
+ template <typename DeviceHandle>
+ explicit native_reader( DeviceHandle const handle )
         :
- detail::libtiff_base( file )
- {
- get_format();
- }
+ libtiff_image
+ (
+ handle,
+ &input_device<DeviceHandle>::read,
+ NULL,
+ NULL,
+ NULL
+ ),
+ format_( get_format() )
+ {}
 
 public:
- point2<std::ptrdiff_t> dimensions() const
- {
- return point2<std::ptrdiff_t>( get_field<uint32>( TIFFTAG_IMAGEWIDTH ), get_field<uint32>( TIFFTAG_IMAGELENGTH ) );
- }
-
     format_t const & format () const { return format_.number; }
     format_t const & closest_gil_supported_format() const { return format() ; }
 
@@ -579,26 +116,26 @@
         );
     }
 
- class sequential_row_access_state
+ class sequential_row_read_state
         :
- private detail::libtiff_base::cumulative_result
+ private libtiff_image::cumulative_result
     {
     public:
- using detail::libtiff_base::cumulative_result::failed;
- using detail::libtiff_base::cumulative_result::throw_if_error;
+ using libtiff_image::cumulative_result::failed;
+ using libtiff_image::cumulative_result::throw_if_error;
 
         BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
 
- private: friend class libtiff_image;
- sequential_row_access_state() : position_( 0 ) {}
+ private: friend class libtiff_image::native_reader;
+ sequential_row_read_state() : position_( 0 ) {}
 
         unsigned int position_;
     };
 
 
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
+ static sequential_row_read_state begin_sequential_row_read() { return sequential_row_read_state(); }
 
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage, unsigned int const plane = 0 ) const
+ void read_row( sequential_row_read_state & state, unsigned char * const p_row_storage, unsigned int const plane = 0 ) const
     {
         state.accumulate_greater
         (
@@ -608,11 +145,11 @@
     }
 
 
- typedef sequential_row_access_state sequential_tile_access_state;
+ typedef sequential_row_read_state sequential_tile_read_state;
 
- static sequential_tile_access_state begin_sequential_tile_access() { return begin_sequential_row_access(); }
+ static sequential_tile_read_state begin_sequential_tile_access() { return begin_sequential_row_read(); }
 
- void read_tile( sequential_row_access_state & state, unsigned char * const p_tile_storage ) const
+ void read_tile( sequential_row_read_state & state, unsigned char * const p_tile_storage ) const
     {
         state.accumulate_greater
         (
@@ -622,28 +159,7 @@
     }
 
 private:
- template <typename T>
- T get_field( ttag_t const tag ) const
- {
- T value;
- #ifdef _MSC_VER
- T * p_value( &value );
- BOOST_VERIFY( ::TIFFVGetFieldDefaulted( &lib_object(), tag, gil_reinterpret_cast<va_list>( &p_value ) ) );
- #else
- BOOST_VERIFY( ::TIFFGetFieldDefaulted ( &lib_object(), tag, &value ) );
- #endif // _MSC_VER
- return value;
- }
-
- template <typename T1, typename T2>
- std::pair<T1, T2> get_field( ttag_t const tag, int & cumulative_result ) const
- {
- std::pair<T1, T2> value;
- cumulative_result &= ::TIFFGetFieldDefaulted( &lib_object(), tag, &value.first, &value.second );
- return value;
- }
-
- void get_format()
+ full_format_t get_format()
     {
         int cumulative_result( true );
 
@@ -681,7 +197,11 @@
 
         detail::io_error_if( !cumulative_result || unsupported_format || ( orientation != ORIENTATION_TOPLEFT ), "Unsupported TIFF format" );
 
- format_.number = LIBTIFF_FORMAT( samples_per_pixel, bits_per_sample, ( sample_format == SAMPLEFORMAT_VOID ) ? SAMPLEFORMAT_UINT : sample_format, planar_configuration, photometric, ink_set );
+ full_format_t const result =
+ {
+ LIBTIFF_FORMAT( samples_per_pixel, bits_per_sample, ( sample_format == SAMPLEFORMAT_VOID ) ? SAMPLEFORMAT_UINT : sample_format, planar_configuration, photometric, ink_set )
+ };
+ return result;
     }
 
 private:
@@ -698,14 +218,14 @@
     // accepts friend class base_t, Apple Clang 1.6 and GCC (4.2 and 4.6) accept
     // neither.
     // (13.01.2011.) (Domagoj Saric)
- friend class detail::formatted_image<libtiff_image>;
+ friend class detail::formatted_image<libtiff_image::native_reader>;
 
     struct tile_setup_t
         #ifndef __GNUC__
             : boost::noncopyable
         #endif // __GNUC__
     {
- tile_setup_t( libtiff_image const & source, point2<std::ptrdiff_t> const & dimensions, offset_t const offset, bool const nptcc )
+ tile_setup_t( native_reader const & source, point2<std::ptrdiff_t> const & dimensions, offset_t const offset, bool const nptcc )
             :
             tile_height ( source.get_field<uint32>( TIFFTAG_TILELENGTH ) ),
             tile_width ( source.get_field<uint32>( TIFFTAG_TILEWIDTH ) ),
@@ -865,12 +385,17 @@
     //
     ////////////////////////////////////////////////////////////////////////////
     ///
- /// \todo Cleanup, document, split up and refactor this humongous beast
+ /// \todo Cleanup, document, split up and refactor this humongous monster
     /// (remove duplication, extract non-template and shared functionality...).
     /// (16.09.2010.) (Domagoj Saric)
     ///
     ////////////////////////////////////////////////////////////////////////////
 
+ #if defined(BOOST_MSVC)
+ # pragma warning( push )
+ # pragma warning( disable : 4127 ) // "conditional expression is constant"
+ #endif
+
     template <class MyView, class TargetView, class Converter>
     void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
     {
@@ -1141,11 +666,9 @@
         result.throw_if_error();
     }
 
- static std::size_t cached_format_size( format_t const format )
- {
- full_format_t::format_bitfield const & bits( reinterpret_cast<full_format_t const &>( format ).bits );
- return bits.bits_per_sample * ( ( bits.planar_configuration == PLANARCONFIG_CONTIG ) ? bits.samples_per_pixel : 1 ) / 8;
- }
+ #if defined(BOOST_MSVC)
+ # pragma warning( pop )
+ #endif
 
 private:
     template <typename View>
@@ -1210,7 +733,7 @@
     }
 
     // Implementation note:
- // Because of plain RVO incapable compilers (like Clang or not the latest
+ // Because of plain RVO incapable compilers (like Clang or even the latest
     // GCCs) a simple std::pair with a scoped_array cannot be used.
     // (11.01.2011.) (Domagoj Saric)
     //typedef std::pair
@@ -1246,10 +769,11 @@
             return ( ::TIFFScanlineSize( &tiff.lib_object() ) );
         }
 
- static std::pair<std::size_t, std::size_t> planar_scanline_buffer_construction( libtiff_image const & tiff )
+ static std::pair<std::size_t, std::size_t> planar_scanline_buffer_construction( native_reader const & tiff )
         {
- std::size_t const scanline_size ( tiff.format_bits().bits_per_sample * tiff.dimensions().x / 8 );
- std::size_t const allocation_size( scanline_size * tiff.format_bits().samples_per_pixel );
+ full_format_t::format_bitfield const format_bits( tiff.format_bits() );
+ std::size_t const scanline_size ( format_bits.bits_per_sample * tiff.dimensions().x / 8 );
+ std::size_t const allocation_size( scanline_size * format_bits.samples_per_pixel );
             return std::pair<std::size_t, std::size_t>( allocation_size, scanline_size );
         }
 
@@ -1314,17 +838,14 @@
     }
 
 private:
- full_format_t format_;
+ full_format_t const format_;
 };
 
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#endif
-
-
+//------------------------------------------------------------------------------
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // libtiff_image_hpp
+#endif // libtiff_reader_hpp

Copied: sandbox/gil/boost/gil/extension/io2/libtiff_writer.hpp (from r73054, /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp)
==============================================================================
--- /sandbox/gil/boost/gil/extension/io2/libtiff_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/libtiff_writer.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -1,9 +1,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file libtiff_image.hpp
-/// -----------------------
+/// \file libtiff_writer.hpp
+/// ------------------------
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,40 +13,19 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef libtiff_writer_hpp__FD402B04_E934_4E73_8839_001A8633B5D3
+#define libtiff_writer_hpp__FD402B04_E934_4E73_8839_001A8633B5D3
 #pragma once
-#ifndef libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
-#define libtiff_image_hpp__0808D24E_CED1_4921_A832_3C12DAE93Ef7
 //------------------------------------------------------------------------------
-#include "formatted_image.hpp"
+#include "libtiff_image.hpp"
+#include "backend_writer.hpp"
 
 #include "detail/io_error.hpp"
 #include "detail/libx_shared.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/shared.hpp"
 
-#if BOOST_MPL_LIMIT_VECTOR_SIZE < 35
- #error libtiff support requires mpl vectors of size 35 or greater...
-#endif
-
 #include <boost/array.hpp>
-#include <boost/mpl/vector.hpp>
-#include <boost/smart_ptr/scoped_array.hpp>
-
-extern "C"
-{
- #include "tiff.h"
- #include "tiffio.h"
-}
-
-#include <cstdio>
-#include <set>
-#ifdef _MSC_VER
- #include "io.h"
-#else
- #include "sys/types.h"
- #include "sys/stat.h"
- #include "unistd.h"
-#endif // _MSC_VER
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -58,263 +37,11 @@
 {
 //------------------------------------------------------------------------------
 
-#define LIBTIFF_SPP( param ) ( ( param ) << ( 0 ) )
-#define LIBTIFF_BPS( param ) ( ( param ) << ( 0 + 3 ) )
-#define LIBTIFF_FMT( param ) ( ( param ) << ( 0 + 3 + 5 ) )
-#define LIBTIFF_PLANAR( param ) ( ( param ) << ( 0 + 3 + 5 + 3 ) )
-#define LIBTIFF_PHOTOMETRIC( param ) ( ( param ) << ( 0 + 3 + 5 + 3 + 2 ) )
-#define LIBTIFF_INKSET( param ) ( ( param ) << ( 0 + 3 + 5 + 3 + 2 + 3 ) )
-
-#define LIBTIFF_FORMAT( spp, bps, sample_format, planar_config, photometric_interpretation, inkset ) \
-( \
- LIBTIFF_SPP( spp ) | \
- LIBTIFF_BPS( bps ) | \
- LIBTIFF_FMT( sample_format ) | \
- LIBTIFF_PLANAR( planar_config ) | \
- LIBTIFF_PHOTOMETRIC( photometric_interpretation ) | \
- LIBTIFF_INKSET( inkset ) \
-)
-
-
-union full_format_t
-{
- struct format_bitfield
- {
- unsigned int samples_per_pixel : 3;
- unsigned int bits_per_sample : 5;
- unsigned int sample_format : 3;
- unsigned int planar_configuration : 2;
- unsigned int photometric : 3;
- unsigned int ink_set : 2;
- };
-
- typedef unsigned int format_id;
-
- format_bitfield bits ;
- format_id number;
-};
-
-
-template <typename Pixel, bool isPlanar>
-struct gil_to_libtiff_format
- :
- mpl::int_
- <
- LIBTIFF_FORMAT
- (
- num_channels<Pixel>::value,
- sizeof( typename channel_type<Pixel>::type ) * 8,
- (
- ( is_unsigned <typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_UINT ) |
- ( is_signed <typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_INT ) |
- ( is_floating_point<typename channel_type<Pixel>::type>::value * SAMPLEFORMAT_IEEEFP )
- ),
- isPlanar ? PLANARCONFIG_SEPARATE : PLANARCONFIG_CONTIG,
- (
- ( is_same<typename color_space_type<Pixel>::type, rgb_t >::value * PHOTOMETRIC_RGB ) |
- ( is_same<typename color_space_type<Pixel>::type, cmyk_t>::value * PHOTOMETRIC_SEPARATED ) |
- ( is_same<typename color_space_type<Pixel>::type, gray_t>::value * PHOTOMETRIC_MINISBLACK )
- ),
- ( is_same<typename color_space_type<Pixel>::type, cmyk_t>::value ? INKSET_CMYK : 0 )
- )
- >
-{};
-
-
-typedef mpl::vector35
-<
- image<rgb8_pixel_t , false>,
- image<rgb8_pixel_t , true >,
- image<rgba8_pixel_t, false>,
- image<rgba8_pixel_t, true >,
- image<cmyk8_pixel_t, false>,
- image<cmyk8_pixel_t, true >,
- image<gray8_pixel_t, false>,
-
- image<rgb16_pixel_t , false>,
- image<rgb16_pixel_t , true >,
- image<rgba16_pixel_t, false>,
- image<rgba16_pixel_t, true >,
- image<cmyk16_pixel_t, false>,
- image<cmyk16_pixel_t, true >,
- image<gray16_pixel_t, false>,
-
- image<rgb8s_pixel_t , false>,
- image<rgb8s_pixel_t , true >,
- image<rgba8s_pixel_t, false>,
- image<rgba8s_pixel_t, true >,
- image<cmyk8s_pixel_t, false>,
- image<cmyk8s_pixel_t, true >,
- image<gray8s_pixel_t, false>,
-
- image<rgb16s_pixel_t , false>,
- image<rgb16s_pixel_t , true >,
- image<rgba16s_pixel_t, false>,
- image<rgba16s_pixel_t, true >,
- image<cmyk16s_pixel_t, false>,
- image<cmyk16s_pixel_t, true >,
- image<gray16s_pixel_t, false>,
-
- image<rgb32f_pixel_t , false>,
- image<rgb32f_pixel_t , true >,
- image<rgba32f_pixel_t, false>,
- image<rgba32f_pixel_t, true >,
- image<cmyk32f_pixel_t, false>,
- image<cmyk32f_pixel_t, true >,
- image<gray32f_pixel_t, false>
-> libtiff_supported_pixel_formats;
-
-
-inline tsize_t FILE_read_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
-{
- return static_cast<tsize_t>( std::fread( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
-}
-
 inline tsize_t FILE_write_proc( thandle_t const handle, tdata_t const buf, tsize_t const size )
 {
     return static_cast<tsize_t>( std::fwrite( buf, 1, size, reinterpret_cast<FILE *>( handle ) ) );
 }
 
-inline toff_t FILE_seek_proc( thandle_t const handle, toff_t const off, int const whence )
-{
- return static_cast<tsize_t>( std::fseek( reinterpret_cast<FILE *>( handle ), off, whence ) );
-}
-
-inline int FILE_close_proc( thandle_t const handle )
-{
- return std::fclose( reinterpret_cast<FILE *>( handle ) );
-}
-
-inline int FILE_close_proc_nop( thandle_t /*handle*/ )
-{
- return 0;
-}
-
-inline toff_t FILE_size_proc( thandle_t const fd )
-{
- #ifdef _MSC_VER
- return /*std*/::_filelength( /*std*/::_fileno( gil_reinterpret_cast<FILE *>( fd ) ) );
- #else
- struct stat file_status;
- BOOST_VERIFY( ::fstat( ::fileno( gil_reinterpret_cast<FILE *>( fd ) ), &file_status ) == 0 );
- return file_status.st_size;
- #endif // _MSC_VER
-}
-
-inline int FILE_map_proc( thandle_t /*handle*/, tdata_t * /*pbase*/, toff_t * /*psize*/ )
-{
- return false;
-}
-
-inline void FILE_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
-{
-}
-
-
-inline tsize_t memory_read_proc( thandle_t /*handle*/, tdata_t /*buf*/, tsize_t /*size*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline tsize_t memory_write_proc( thandle_t /*handle*/, tdata_t /*buf*/, tsize_t /*size*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline toff_t memory_seek_proc( thandle_t /*handle*/, toff_t /*off*/, int /*whence*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline int memory_close_proc( thandle_t /*handle*/ )
-{
- return 0;
-}
-
-inline toff_t memory_size_proc( thandle_t /*handle*/ )
-{
- BF_UNREACHABLE_CODE
- return 0;
-}
-
-inline int memory_map_proc( thandle_t const handle, tdata_t * const pbase, toff_t * const psize )
-{
- BOOST_ASSERT( handle );
- BOOST_ASSERT( pbase );
- BOOST_ASSERT( psize );
- *pbase = static_cast<tdata_t>( const_cast<memory_chunk_t::value_type *>( gil_reinterpret_cast<memory_chunk_t *>( handle )->begin() ) );
- *psize = gil_reinterpret_cast<memory_chunk_t *>( handle )->size ();
- return true;
-}
-
-inline void memory_unmap_proc( thandle_t /*handle*/, tdata_t /*base*/, toff_t /*size*/ )
-{
-}
-
-
-#if defined(BOOST_MSVC)
-# pragma warning( push )
-# pragma warning( disable : 4127 ) // "conditional expression is constant"
-#endif
-
-struct tiff_view_data_t
-{
- template <class View>
- explicit tiff_view_data_t( View const & view, generic_vertical_roi::offset_t const offset = 0 )
- :
- dimensions_( view.dimensions() ),
- stride_ ( view.pixels().row_size() ),
- offset_ ( offset )
- #ifdef _DEBUG
- ,format_id_( gil_to_libtiff_format<typename View::value_type, is_planar<View>::value>::value )
- #endif
- {
- set_buffers( view, is_planar<View>() );
- }
-
- void set_format( full_format_t::format_id const format )
- {
- #ifdef _DEBUG
- BOOST_ASSERT( ( format_id_ == format ) && !"libtiff does not provide builtin conversion." );
- #endif // _DEBUG
- ignore_unused_variable_warning( format );
- }
-
- point2<std::ptrdiff_t> const & dimensions_ ;
- unsigned int stride_ ;
- unsigned int number_of_planes_;
- array<unsigned char *, 4> plane_buffers_ ;
- generic_vertical_roi::offset_t offset_ ;
-
- #ifdef _DEBUG
- unsigned int format_id_;
- #endif
-
-private: // this should probably go to the base formatted_image class...
- template <class View>
- void set_buffers( View const & view, mpl::true_ /*is planar*/ )
- {
- for ( number_of_planes_ = 0; number_of_planes_ < num_channels<View>::value; ++number_of_planes_ )
- {
- plane_buffers_[ number_of_planes_ ] = gil_reinterpret_cast<unsigned char *>( planar_view_get_raw_data( view, number_of_planes_ ) );
- }
- BOOST_ASSERT( number_of_planes_ == num_channels<View>::value );
- }
-
- template <class View>
- void set_buffers( View const & view, mpl::false_ /*is not planar*/ )
- {
- number_of_planes_ = 1;
- plane_buffers_[ 0 ] = formatted_image_base::get_raw_data( view );
- }
-
- void operator=( tiff_view_data_t const & );
-};
-
-
 struct tiff_writer_view_data_t : public tiff_view_data_t
 {
     template <class View>
@@ -328,95 +55,19 @@
     full_format_t format_;
 };
 
-
-class libtiff_base
-{
-public:
- TIFF & lib_object() const { BOOST_ASSERT( p_tiff_ ); return *p_tiff_; }
-
-protected:
- libtiff_base( char const * const file_name, char const * const access_mode )
- :
- p_tiff_( ::TIFFOpen( file_name, access_mode ) )
- {
- BOOST_ASSERT( file_name );
- construction_check();
- }
-
- explicit libtiff_base( FILE & file )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "",
- &file,
- &detail::FILE_read_proc,
- &detail::FILE_write_proc,
- &detail::FILE_seek_proc,
- &detail::FILE_close_proc_nop,
- &detail::FILE_size_proc,
- &detail::FILE_map_proc,
- &detail::FILE_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- explicit libtiff_base( memory_chunk_t & in_memory_image )
- :
- p_tiff_
- (
- ::TIFFClientOpen
- (
- "", "M",
- &in_memory_image,
- &detail::memory_read_proc,
- &detail::memory_write_proc,
- &detail::memory_seek_proc,
- &detail::memory_close_proc,
- &detail::memory_size_proc,
- &detail::memory_map_proc,
- &detail::memory_unmap_proc
- )
- )
- {
- construction_check();
- }
-
- BF_NOTHROW ~libtiff_base()
- {
- ::TIFFClose( &lib_object() );
- }
-
-protected:
- class cumulative_result : public detail::cumulative_result
- {
- public:
- void throw_if_error() const { detail::cumulative_result::throw_if_error( "Error reading TIFF file" ); }
- };
-
-private:
- void construction_check() const
- {
- io_error_if_not( p_tiff_, "Failed to open TIFF input file" );
- }
-
-private:
- TIFF * const p_tiff_;
-};
-
+//------------------------------------------------------------------------------
+} // namespace detail
 
 class libtiff_writer
     :
- public libtiff_base,
+ public libtiff_image,
+ public detail::backend_writer<libtiff_image>,
     public configure_on_write_writer
 {
 public:
- explicit libtiff_writer( char const * const file_name ) : detail::libtiff_base( file_name, "w" ) {}
+ explicit libtiff_writer( char const * const file_name ) : libtiff_image( file_name, "w" ) {}
 
- explicit libtiff_writer( FILE & file ) : detail::libtiff_base( file ) {}
+ explicit libtiff_writer( FILE & file ) : libtiff_image( file ) {}
 
     void write_default( tiff_writer_view_data_t const & view )
     {
@@ -482,849 +133,8 @@
 };
 
 //------------------------------------------------------------------------------
-} // namespace detail
-
-class libtiff_image;
-
-template <>
-struct formatted_image_traits<libtiff_image>
-{
- typedef detail::full_format_t::format_id format_t;
-
- typedef detail::libtiff_supported_pixel_formats supported_pixel_formats_t;
-
- typedef detail::generic_vertical_roi roi_t;
-
- typedef detail::tiff_view_data_t view_data_t;
-
- struct gil_to_native_format
- {
- template <typename Pixel, bool IsPlanar>
- struct apply : detail::gil_to_libtiff_format<Pixel, IsPlanar> {};
- };
-
- template <typename Pixel, bool IsPlanar>
- struct is_supported : mpl::true_ {}; //...zzz...
-
- typedef mpl::map2
- <
- mpl::pair<char const *, libtiff_image>,
- mpl::pair<FILE , libtiff_image>
- > readers;
-
- typedef mpl::map2
- <
- mpl::pair<char const *, detail::libtiff_writer>,
- mpl::pair<FILE , detail::libtiff_writer>
- > writers;
-
- typedef mpl::vector1_c<format_tag, tiff> supported_image_formats;
-
- typedef detail::tiff_writer_view_data_t writer_view_data_t;
-
- BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( void * ) );
- BOOST_STATIC_CONSTANT( bool , builtin_conversion = false );
-};
-
-
-class libtiff_image
- :
- public detail::libtiff_base,
- public detail::formatted_image<libtiff_image>
-{
-private:
- typedef detail::full_format_t full_format_t;
-
-public:
- struct guard {};
-
-public: /// \ingroup Construction
- explicit libtiff_image( char const * const file_name )
- :
- detail::libtiff_base( file_name, "r" )
- {
- get_format();
- }
-
- explicit libtiff_image( FILE & file )
- :
- detail::libtiff_base( file )
- {
- get_format();
- }
-
-public:
- point2<std::ptrdiff_t> dimensions() const
- {
- return point2<std::ptrdiff_t>( get_field<uint32>( TIFFTAG_IMAGEWIDTH ), get_field<uint32>( TIFFTAG_IMAGELENGTH ) );
- }
-
- format_t const & format () const { return format_.number; }
- format_t const & closest_gil_supported_format() const { return format() ; }
-
-public: // Low-level (row, strip, tile) access
- bool can_do_row_access () const { return !can_do_tile_access(); }
- bool can_do_strip_access() const { return /*...yet to implement...can_do_row_access();*/ false; }
- bool can_do_tile_access () const { return ::TIFFIsTiled( &lib_object() ) != 0; }
-
- std::size_t tile_size () const { return ::TIFFTileSize ( &lib_object() ); }
- std::size_t tile_row_size() const { return ::TIFFTileRowSize( &lib_object() ); }
- point2<std::ptrdiff_t> tile_dimensions() const
- {
- BOOST_ASSERT( can_do_tile_access() );
- return point2<std::ptrdiff_t>
- (
- get_field<uint32>( TIFFTAG_TILEWIDTH ),
- get_field<uint32>( TIFFTAG_TILELENGTH )
- );
- }
-
- class sequential_row_access_state
- :
- private detail::libtiff_base::cumulative_result
- {
- public:
- using detail::libtiff_base::cumulative_result::failed;
- using detail::libtiff_base::cumulative_result::throw_if_error;
-
- BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
-
- private: friend class libtiff_image;
- sequential_row_access_state() : position_( 0 ) {}
-
- unsigned int position_;
- };
-
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage, unsigned int const plane = 0 ) const
- {
- state.accumulate_greater
- (
- ::TIFFReadScanline( &lib_object(), p_row_storage, state.position_++, static_cast<tsample_t>( plane ) ),
- 0
- );
- }
-
-
- typedef sequential_row_access_state sequential_tile_access_state;
-
- static sequential_tile_access_state begin_sequential_tile_access() { return begin_sequential_row_access(); }
-
- void read_tile( sequential_row_access_state & state, unsigned char * const p_tile_storage ) const
- {
- state.accumulate_greater
- (
- ::TIFFReadEncodedTile( &lib_object(), state.position_++, p_tile_storage, -1 ),
- 0
- );
- }
-
-private:
- template <typename T>
- T get_field( ttag_t const tag ) const
- {
- T value;
- #ifdef _MSC_VER
- T * p_value( &value );
- BOOST_VERIFY( ::TIFFVGetFieldDefaulted( &lib_object(), tag, gil_reinterpret_cast<va_list>( &p_value ) ) );
- #else
- BOOST_VERIFY( ::TIFFGetFieldDefaulted ( &lib_object(), tag, &value ) );
- #endif // _MSC_VER
- return value;
- }
-
- template <typename T1, typename T2>
- std::pair<T1, T2> get_field( ttag_t const tag, int & cumulative_result ) const
- {
- std::pair<T1, T2> value;
- cumulative_result &= ::TIFFGetFieldDefaulted( &lib_object(), tag, &value.first, &value.second );
- return value;
- }
-
- void get_format()
- {
- int cumulative_result( true );
-
- unsigned const samples_per_pixel ( get_field<uint16>( TIFFTAG_SAMPLESPERPIXEL ) );
- unsigned const bits_per_sample ( get_field<uint16>( TIFFTAG_BITSPERSAMPLE ) );
- unsigned const sample_format ( get_field<uint16>( TIFFTAG_SAMPLEFORMAT ) );
- unsigned const planar_configuration( get_field<uint16>( TIFFTAG_PLANARCONFIG ) );
- unsigned const photometric ( get_field<uint16>( TIFFTAG_PHOTOMETRIC ) );
- unsigned const orientation ( get_field<uint16>( TIFFTAG_ORIENTATION ) );
-
- unsigned ink_set( 0 );
- bool unsupported_format( false );
- if ( samples_per_pixel == 4 )
- {
- switch ( photometric )
- {
- case PHOTOMETRIC_RGB:
- {
- std::pair<uint16, uint16 *> const extrasamples( get_field<uint16, uint16 *>( TIFFTAG_EXTRASAMPLES, cumulative_result ) );
- unsupported_format = ( extrasamples.first != 1 || *extrasamples.second != EXTRASAMPLE_UNASSALPHA );
- break;
- }
-
- case PHOTOMETRIC_SEPARATED:
- {
- ink_set = get_field<uint16>( TIFFTAG_INKSET );
- unsupported_format = ( ink_set != INKSET_CMYK );
- break;
- }
-
- default:
- unsupported_format = true;
- }
- }
-
- detail::io_error_if( !cumulative_result || unsupported_format || ( orientation != ORIENTATION_TOPLEFT ), "Unsupported TIFF format" );
-
- format_.number = LIBTIFF_FORMAT( samples_per_pixel, bits_per_sample, ( sample_format == SAMPLEFORMAT_VOID ) ? SAMPLEFORMAT_UINT : sample_format, planar_configuration, photometric, ink_set );
- }
-
-private:
- detail::full_format_t::format_bitfield const & format_bits() const { return format_.bits; }
-
- static unsigned int round_up_divide( unsigned int const dividend, unsigned int const divisor )
- {
- return ( dividend + divisor - 1 ) / divisor;
- }
-
-private: // Private formatted_image_base interface.
- // Implementation note:
- // MSVC 10 accepts friend base_t and friend class base_t, Clang 2.8
- // accepts friend class base_t, Apple Clang 1.6 and GCC (4.2 and 4.6) accept
- // neither.
- // (13.01.2011.) (Domagoj Saric)
- friend class detail::formatted_image<libtiff_image>;
-
- struct tile_setup_t
- #ifndef __GNUC__
- : boost::noncopyable
- #endif // __GNUC__
- {
- tile_setup_t( libtiff_image const & source, point2<std::ptrdiff_t> const & dimensions, offset_t const offset, bool const nptcc )
- :
- tile_height ( source.get_field<uint32>( TIFFTAG_TILELENGTH ) ),
- tile_width ( source.get_field<uint32>( TIFFTAG_TILEWIDTH ) ),
- row_tiles ( source.get_field<uint32>( TIFFTAG_IMAGEWIDTH ) / tile_width ),
- size_of_pixel ( ( source.format_bits().planar_configuration == PLANARCONFIG_CONTIG ? source.format_bits().samples_per_pixel : 1 ) * source.format_bits().bits_per_sample / 8 ),
- tile_width_bytes ( tile_width * size_of_pixel ),
- tile_size_bytes ( tile_width_bytes * tile_height ),
- p_tile_buffer ( new unsigned char[ tile_size_bytes * ( nptcc ? source.format_bits().samples_per_pixel : 1 ) ] ),
- last_row_tile_width ( modulo_unless_zero( dimensions.x, tile_width ) /*dimensions.x % tile_width*/ ),
- tiles_per_row ( ( dimensions.x / tile_width ) + /*( last_row_tile_width != 0 )*/ ( ( dimensions.x % tile_width ) != 0 ) ),
- last_row_tile_width_bytes ( last_row_tile_width * size_of_pixel ),
- last_row_tile_size_bytes ( last_row_tile_width_bytes * tile_height ),
- current_row_tiles_remaining( tiles_per_row ),
- starting_tile ( offset / tile_height * tiles_per_row ),
- rows_to_skip ( offset % tile_height ),
- number_of_tiles ( round_up_divide( dimensions.y, tile_height ) * tiles_per_row * ( source.format_bits().planar_configuration == PLANARCONFIG_SEPARATE ? source.format_bits().samples_per_pixel : 1 ) )
- {
- BOOST_ASSERT( static_cast<tsize_t>( tile_width_bytes ) == ::TIFFTileRowSize( &source.lib_object() ) );
- BOOST_ASSERT( static_cast<tsize_t>( tile_size_bytes ) == ::TIFFTileSize ( &source.lib_object() ) );
- BOOST_ASSERT( starting_tile + number_of_tiles <= ::TIFFNumberOfTiles( &source.lib_object() ) );
- if ( tile_height > static_cast<uint32>( dimensions.y ) )
- {
- rows_to_read_per_tile = end_rows_to_read = dimensions.y;
- }
- else
- {
- end_rows_to_read = modulo_unless_zero( dimensions.y - ( tile_height - rows_to_skip ), tile_height );
- bool const starting_at_last_row( ( number_of_tiles - starting_tile ) <= tiles_per_row );
- rows_to_read_per_tile = starting_at_last_row ? end_rows_to_read : tile_height;
- }
- }
-
- uint32 const tile_height;
- uint32 const tile_width ;
- uint32 const row_tiles ;
-
- unsigned int const size_of_pixel ;
- size_t const tile_width_bytes;
- tsize_t const tile_size_bytes ;
-
- scoped_array<unsigned char> p_tile_buffer;
-
- unsigned int const last_row_tile_width ;
- unsigned int const tiles_per_row ;
- unsigned int const last_row_tile_width_bytes ;
- unsigned int const last_row_tile_size_bytes ;
- unsigned int current_row_tiles_remaining;
- ttile_t const starting_tile ;
- unsigned int rows_to_skip ;
- ttile_t const number_of_tiles ;
- unsigned int /*const*/ end_rows_to_read ;
- unsigned int rows_to_read_per_tile ;
-
- private:
- static unsigned int modulo_unless_zero( unsigned int const dividend, unsigned int const divisor )
- {
- unsigned int const modulo( dividend % divisor );
- return ( modulo != 0 ) ? modulo : divisor;
- }
- };
-
- struct skip_row_results_t
- {
- unsigned int rows_per_strip;
- unsigned int rows_to_read_using_scanlines;
- unsigned int starting_strip;
- };
-
- void raw_copy_to_prepared_view( view_data_t const & view_data ) const
- {
- cumulative_result result;
-
- if ( can_do_tile_access() )
- {
- tile_setup_t setup( *this, view_data.dimensions_, view_data.offset_, false );
-
- ttile_t current_tile( 0 );
-
- for ( unsigned int plane( 0 ); plane < view_data.number_of_planes_; ++plane )
- {
- unsigned char * p_target( view_data.plane_buffers_[ plane ] );
- for ( current_tile += setup.starting_tile; current_tile < setup.number_of_tiles; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- unsigned int const this_tile_width_bytes( last_row_tile ? setup.last_row_tile_width_bytes : setup.tile_width_bytes );
-
- result.accumulate_equal( ::TIFFReadEncodedTile( &lib_object(), current_tile, setup.p_tile_buffer.get(), setup.tile_size_bytes ), setup.tile_size_bytes );
- unsigned char const * p_tile_buffer_location( setup.p_tile_buffer.get() + ( setup.rows_to_skip * this_tile_width_bytes ) );
- unsigned char * p_target_local ( p_target );
- for ( unsigned int row( setup.rows_to_skip ); row < setup.rows_to_read_per_tile; ++row )
- {
- std::memcpy( p_target_local, p_tile_buffer_location, this_tile_width_bytes );
- memunit_advance( p_tile_buffer_location, setup.tile_width_bytes );
- memunit_advance( p_target_local , view_data.stride_ );
- }
- memunit_advance( p_target, this_tile_width_bytes );
- if ( last_row_tile )
- {
- p_target += ( ( setup.rows_to_read_per_tile - 1 - setup.rows_to_skip ) * view_data.stride_ );
- setup.rows_to_skip = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( setup.number_of_tiles - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- setup.rows_to_read_per_tile = setup.end_rows_to_read;
- }
- //BOOST_ASSERT( p_tile_buffer_location == ( setup.p_tile_buffer.get() + this_tile_size_bytes ) || ( setup.rows_to_read_per_tile != setup.tile_height ) );
- BOOST_ASSERT( p_target <= view_data.plane_buffers_[ plane ] + ( view_data.stride_ * view_data.dimensions_.y ) );
- }
- BOOST_ASSERT( p_target == view_data.plane_buffers_[ plane ] + ( view_data.stride_ * view_data.dimensions_.y ) );
- }
- }
- else
- {
- BOOST_ASSERT( ::TIFFScanlineSize( &lib_object() ) <= static_cast<tsize_t>( view_data.stride_ ) );
- for ( unsigned int plane( 0 ); plane < view_data.number_of_planes_; ++plane )
- {
- unsigned char * buf( view_data.plane_buffers_[ plane ] );
- skip_row_results_t skip_result( skip_to_row( view_data.offset_, plane, buf, result ) );
- ttile_t const number_of_strips( ( view_data.dimensions_.y - skip_result.rows_to_read_using_scanlines + skip_result.rows_per_strip - 1 ) / skip_result.rows_per_strip );
- skip_result.rows_to_read_using_scanlines = std::min<unsigned int>( skip_result.rows_to_read_using_scanlines, view_data.dimensions_.y );
-
- unsigned int row( view_data.offset_ );
- while ( row != ( view_data.offset_ + skip_result.rows_to_read_using_scanlines ) )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view_data.stride_;
- }
-
- unsigned int const view_strip_increment( view_data.stride_ * skip_result.rows_per_strip );
- if ( view_strip_increment == static_cast<unsigned int>( ::TIFFStripSize( &lib_object() ) ) )
- {
- for ( unsigned int strip( skip_result.starting_strip ); strip < number_of_strips; ++strip )
- {
- result.accumulate_greater( ::TIFFReadEncodedStrip( &lib_object(), strip, buf, view_strip_increment ), 0 );
- buf += view_strip_increment;
- row += skip_result.rows_per_strip;
- }
- }
-
- unsigned int const target_row( view_data.offset_ + view_data.dimensions_.y );
- while ( row < target_row )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buf, row++, static_cast<tsample_t>( plane ) ), 0 );
- buf += view_data.stride_;
- }
- }
- }
-
- result.throw_if_error();
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // generic_convert_to_prepared_view()
- // ----------------------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \todo Cleanup, document, split up and refactor this humongous beast
- /// (remove duplication, extract non-template and shared functionality...).
- /// (16.09.2010.) (Domagoj Saric)
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <class MyView, class TargetView, class Converter>
- void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
- {
- using namespace detail;
-
- typedef typename get_original_view_t<TargetView>::type original_target_view_t;
-
- typedef typename mpl::eval_if
- <
- is_planar<MyView>,
- nth_channel_view_type<original_target_view_t>,
- get_original_view_t<TargetView>
- >::type local_target_view_t;
- typedef typename get_original_view_t<local_target_view_t>::type::x_iterator target_x_iterator;
- typedef typename get_original_view_t<local_target_view_t>::type::y_iterator target_y_iterator;
-
- typedef typename mpl::eval_if
- <
- is_planar<MyView>,
- nth_channel_view_type<MyView>,
- mpl::identity<MyView>
- >::type::value_type my_pixel_t;
-
- typedef mpl::bool_
- <
- is_planar<MyView >::value &&
- !is_planar<original_target_view_t>::value &&
- (
- !is_same<typename color_space_type <MyView>::type, typename color_space_type <original_target_view_t>::type>::value ||
- !is_same<typename channel_mapping_type<MyView>::type, typename channel_mapping_type<original_target_view_t>::type>::value
- )
- > nondirect_planar_to_contig_conversion_t;
-
- cumulative_result result;
-
- typedef mpl::int_<is_planar<MyView>::value ? num_channels<MyView>::value : 1> number_of_planes_t;
-
- dimensions_t const & dimensions( original_view( view ).dimensions() );
-
- ////////////////////////////////////////////////////////////////////////
- // Tiled
- ////////////////////////////////////////////////////////////////////////
-
- if ( ::TIFFIsTiled( &lib_object() ) )
- {
- tile_setup_t setup
- (
- *this,
- dimensions,
- get_offset<offset_t>( view ),
- nondirect_planar_to_contig_conversion_t::value
- );
-
- unsigned int const tiles_per_plane( setup.number_of_tiles / number_of_planes_t::value );
- ttile_t current_tile ( 0 );
-
- if ( nondirect_planar_to_contig_conversion_t::value )
- {
- // For NPTCC there is no need for target view
- // planar<->non-planar adjustment because here we read whole
- // pixels before copying to the target view...
- typename original_target_view_t::y_iterator p_target( original_view( view ).y_at( 0, 0 ) );
-
- typename MyView::x_iterator const buffer_iterator
- (
- make_planar_buffer_iterator<typename MyView::x_iterator>
- (
- setup.p_tile_buffer.get(),
- setup.tile_size_bytes,
- number_of_planes_t()
- )
- );
-
- unsigned int horizontal_offset( 0 );
-
- for ( current_tile += setup.starting_tile; current_tile < tiles_per_plane; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- unsigned int const this_tile_width( last_row_tile ? setup.last_row_tile_width : setup.tile_width );
-
- for ( unsigned int channel_tile( 0 ); channel_tile < number_of_planes_t::value; ++channel_tile )
- {
- ttile_t const raw_tile_number( current_tile + ( channel_tile * tiles_per_plane ) );
- result.accumulate_equal
- (
- ::TIFFReadEncodedTile
- (
- &lib_object(),
- raw_tile_number,
- //buffer_iterator.at_c_dynamic( channel_tile ),
- &(*buffer_iterator)[ channel_tile ],
- setup.tile_size_bytes
- ),
- setup.tile_size_bytes
- );
- }
-
- typename MyView ::x_iterator p_source_pixel( buffer_iterator + ( setup.rows_to_skip * this_tile_width ) );
- typename original_target_view_t::x_iterator p_target_pixel( p_target.base() + horizontal_offset );
- for ( unsigned int row( setup.rows_to_skip ); row < setup.rows_to_read_per_tile; ++row )
- {
- typename MyView::x_iterator const local_end( p_source_pixel + this_tile_width );
- while ( p_source_pixel < local_end )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- BOOST_ASSERT( p_source_pixel == local_end );
- p_source_pixel += setup.tile_width - this_tile_width;
- memunit_advance( p_target_pixel, original_view( view ).pixels().row_size() );
- p_target_pixel -= this_tile_width;
- }
- if ( last_row_tile )
- {
- p_target += ( setup.rows_to_read_per_tile /*- 1*/ - setup.rows_to_skip );
- setup.rows_to_skip = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( tiles_per_plane - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- setup.rows_to_read_per_tile = setup.end_rows_to_read;
- }
- else
- horizontal_offset += setup.tile_width;
- //...make NPTCC version...BOOST_ASSERT( p_source_pixel == reinterpret_cast<my_pixel_t const *>( setup.p_tile_buffer.get() + this_tile_size_bytes ) || ( setup.rows_to_read_per_tile != setup.tile_height ) );
- BOOST_ASSERT( p_target <= original_view( view ).col_end( 0 ) );
- }
- BOOST_ASSERT( p_target == original_view( view ).col_end( 0 ) );
- }
- else // non NPTCC...
- {
- for
- (
- unsigned int plane( 0 ), current_plane_end_tile( tiles_per_plane );
- plane < number_of_planes_t::value;
- ++plane, current_plane_end_tile += tiles_per_plane
- )
- {
- local_target_view_t const & target_view( adjust_target_to_my_view( original_view( view ), plane, is_planar<MyView>() ) );
- target_y_iterator p_target( target_view.y_at( 0, 0 ) );
- BOOST_ASSERT( p_target.step() == original_view( view ).pixels().row_size() );
-
- unsigned int horizontal_offset ( 0 );
- unsigned int current_plane_rows_to_read_per_tile( setup.rows_to_read_per_tile );
- unsigned int current_plane_rows_to_skip ( setup.rows_to_skip );
-
- for ( current_tile += setup.starting_tile; current_tile < current_plane_end_tile; ++current_tile )
- {
- bool const last_row_tile ( !--setup.current_row_tiles_remaining );
- //unsigned int const this_tile_size_bytes ( last_row_tile ? setup.last_row_tile_size_bytes : setup.tile_size_bytes );
- unsigned int const this_tile_width_bytes( last_row_tile ? setup.last_row_tile_width_bytes : setup.tile_width_bytes );
-
- result.accumulate_equal( ::TIFFReadEncodedTile( &lib_object(), current_tile, setup.p_tile_buffer.get(), setup.tile_size_bytes ), setup.tile_size_bytes );
-
- my_pixel_t const * p_source_pixel( gil_reinterpret_cast_c<my_pixel_t const *>( setup.p_tile_buffer.get() + ( current_plane_rows_to_skip * this_tile_width_bytes ) ) );
- target_x_iterator p_target_pixel( p_target.base() + horizontal_offset );
- for ( unsigned int row( current_plane_rows_to_skip ); row < current_plane_rows_to_read_per_tile; ++row )
- {
- my_pixel_t const * const local_end( memunit_advanced( p_source_pixel, this_tile_width_bytes ) );
- while ( p_source_pixel < local_end )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- BOOST_ASSERT( p_source_pixel == local_end );
- memunit_advance( p_source_pixel, setup.tile_width_bytes - this_tile_width_bytes );
- memunit_advance( p_target_pixel, original_view( view ).pixels().row_size() - ( this_tile_width_bytes * memunit_step( p_target_pixel ) / memunit_step( p_source_pixel ) ) );
- }
- BOOST_ASSERT
- (
- ( p_source_pixel == reinterpret_cast<my_pixel_t const *>( setup.p_tile_buffer.get() + setup.tile_size_bytes ) ) ||
- ( current_plane_rows_to_read_per_tile != setup.tile_height )
- );
- if ( last_row_tile )
- {
- p_target += ( current_plane_rows_to_read_per_tile /*- 1*/ - current_plane_rows_to_skip );
- current_plane_rows_to_skip = 0;
- horizontal_offset = 0;
- setup.current_row_tiles_remaining = setup.tiles_per_row;
- bool const next_row_is_last_row( ( current_plane_end_tile - ( current_tile + 1 ) ) == setup.tiles_per_row );
- if ( next_row_is_last_row )
- current_plane_rows_to_read_per_tile = setup.end_rows_to_read;
- }
- else
- {
- BOOST_ASSERT( this_tile_width_bytes == setup.tile_width_bytes );
- horizontal_offset += setup.tile_width;
- }
- BOOST_ASSERT( p_target.base() <= target_view.end().x() );
- }
- BOOST_ASSERT( p_target.base() == target_view.end().x() );
- }
- }
- }
- else
- ////////////////////////////////////////////////////////////////////////
- // Striped
- ////////////////////////////////////////////////////////////////////////
- {
- scanline_buffer_t<my_pixel_t> const scanline_buffer( *this, nondirect_planar_to_contig_conversion_t::value() );
-
- if ( nondirect_planar_to_contig_conversion_t::value )
- {
- typename original_target_view_t::y_iterator p_target( original_view( view ).y_at( 0, 0 ) );
- unsigned int row ( get_offset<offset_t>( view ) );
- unsigned int const target_row( row + dimensions.y );
-
- typename MyView::x_iterator const buffer_iterator
- (
- make_planar_buffer_iterator<typename MyView::x_iterator>
- (
- scanline_buffer.begin(),
- dimensions.x,
- number_of_planes_t()
- )
- );
-
- while ( row != target_row )
- {
- for ( unsigned int plane( 0 ); plane < number_of_planes_t::value; ++plane )
- {
- tdata_t const p_buffer( &(*buffer_iterator)[ plane ] );
- //...zzz...yup...not the most efficient thing in the universe...
- skip_to_row( get_offset<offset_t>( view ) + row, plane, p_buffer, result );
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), p_buffer, row, static_cast<tsample_t>( plane ) ), 0 );
- }
- typename MyView ::x_iterator p_source_pixel( buffer_iterator );
- typename original_target_view_t::x_iterator p_target_pixel( p_target.base() );
- while ( &(*p_source_pixel)[ 0 ] < &(*scanline_buffer.end())[ 0 ] )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- ++p_target;
- ++row;
- }
- }
- else
- {
- for ( unsigned int plane( 0 ); plane < number_of_planes_t::value; ++plane )
- {
- if ( is_offset_view<TargetView>::value )
- skip_to_row( get_offset<offset_t>( view ), plane, scanline_buffer.begin(), result );
-
- local_target_view_t const & target_view( adjust_target_to_my_view( original_view( view ), plane, is_planar<MyView>() ) );
- target_y_iterator p_target( target_view.y_at( 0, 0 ) );
- unsigned int row ( get_offset<offset_t>( view ) );
- unsigned int const target_row( row + dimensions.y );
- while ( row != target_row )
- {
- result.accumulate_greater( ::TIFFReadScanline( &lib_object(), scanline_buffer.begin(), row++, static_cast<tsample_t>( plane ) ), 0 );
- my_pixel_t const * p_source_pixel( scanline_buffer.begin() );
- target_x_iterator p_target_pixel( p_target.base() );
- while ( p_source_pixel != scanline_buffer.end() )
- {
- converter( *p_source_pixel, *p_target_pixel );
- ++p_source_pixel;
- ++p_target_pixel;
- }
- ++p_target;
- }
- }
- }
- }
-
- result.throw_if_error();
- }
-
- static std::size_t cached_format_size( format_t const format )
- {
- full_format_t::format_bitfield const & bits( reinterpret_cast<full_format_t const &>( format ).bits );
- return bits.bits_per_sample * ( ( bits.planar_configuration == PLANARCONFIG_CONTIG ) ? bits.samples_per_pixel : 1 ) / 8;
- }
-
-private:
- template <typename View>
- static typename nth_channel_view_type<View>::type
- adjust_target_to_my_view( View const & view, unsigned int const plane, mpl::true_ /*source is planar*/ )
- {
- return nth_channel_view( view, plane );
- }
-
- template <typename View>
- static View const &
- adjust_target_to_my_view( View const & view, unsigned int const plane, mpl::false_ /*source is not planar*/ )
- {
- BOOST_ASSERT( plane == 0 );
- ignore_unused_variable_warning( plane );
- return view;
- }
-
- template <typename PixelIterator>
- static PixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int /*row_width*/, mpl::int_<1> )
- {
- BOOST_ASSERT( !"Should not get called." );
- return static_cast<PixelIterator>( p_buffer );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<2> )
- {
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( first + stride );
- return PlanarPixelIterator( first, second );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<3> )
- {
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( first + stride );
- ptr_t const third ( second + stride );
- return PlanarPixelIterator( first, second, third );
- }
-
- template <typename PlanarPixelIterator>
- static PlanarPixelIterator
- make_planar_buffer_iterator( void * const p_buffer, unsigned int const row_width, mpl::int_<4> )
- {
- //...eradicate this triplication...
- typedef typename channel_type<PlanarPixelIterator>::type * ptr_t;
- unsigned int const stride( row_width * memunit_step( ptr_t() ) );
- ptr_t const first ( static_cast<ptr_t>( p_buffer ) );
- ptr_t const second( memunit_advanced( first , stride ) );
- ptr_t const third ( memunit_advanced( second, stride ) );
- ptr_t const fourth( memunit_advanced( third , stride ) );
- return PlanarPixelIterator( first, second, third, fourth );
- }
-
- // Implementation note:
- // Because of plain RVO incapable compilers (like Clang or not the latest
- // GCCs) a simple std::pair with a scoped_array cannot be used.
- // (11.01.2011.) (Domagoj Saric)
- //typedef std::pair
- //<
- // scoped_array<unsigned char> const,
- // unsigned char const * const
- //> generic_scanline_buffer_t;
-
- class scanline_buffer_base_t : boost::noncopyable
- {
- protected:
- explicit scanline_buffer_base_t( std::size_t const size )
- :
- p_begin_( new unsigned char[ size ] ),
- p_end_ ( p_begin_ + size )
- {}
-
- // This one makes the end pointer point to the end of the scanline/row
- // of the first plane not the end of the buffer itself...ugh...to be cleaned up...
- explicit scanline_buffer_base_t( std::pair<std::size_t, std::size_t> const size_to_allocate_size_to_report_pair )
- :
- p_begin_( new unsigned char[ size_to_allocate_size_to_report_pair.first ] ),
- p_end_ ( p_begin_ + size_to_allocate_size_to_report_pair.second )
- {}
-
- ~scanline_buffer_base_t() { delete[] p_begin_; }
-
- BF_NOTHROWNORESTRICTNOALIAS unsigned char * begin() const { return p_begin_; }
- BF_NOTHROWNORESTRICTNOALIAS unsigned char const * end () const { return p_end_ ; }
-
- static std::size_t scanline_buffer_construction( libtiff_image const & tiff )
- {
- return ( ::TIFFScanlineSize( &tiff.lib_object() ) );
- }
-
- static std::pair<std::size_t, std::size_t> planar_scanline_buffer_construction( libtiff_image const & tiff )
- {
- std::size_t const scanline_size ( tiff.format_bits().bits_per_sample * tiff.dimensions().x / 8 );
- std::size_t const allocation_size( scanline_size * tiff.format_bits().samples_per_pixel );
- return std::pair<std::size_t, std::size_t>( allocation_size, scanline_size );
- }
-
- private:
- unsigned char * const p_begin_;
- unsigned char const * const p_end_ ;
- };
-
- template <typename Pixel>
- class scanline_buffer_t : public scanline_buffer_base_t
- {
- public:
- scanline_buffer_t( libtiff_image const & tiff, mpl::true_ /* nptcc */ ) : scanline_buffer_base_t( planar_scanline_buffer_construction( tiff ) ) {}
- scanline_buffer_t( libtiff_image const & tiff, mpl::false_ /* not nptcc */ ) : scanline_buffer_base_t( scanline_buffer_construction ( tiff ) ) {}
-
- Pixel * begin() const { return gil_reinterpret_cast <Pixel *>( scanline_buffer_base_t::begin() ); }
- Pixel const * end () const { return gil_reinterpret_cast_c<Pixel const *>( scanline_buffer_base_t::end () ); }
- };
-
- template <typename Pixel>
- class planar_scanline_buffer_t : scanline_buffer_t<Pixel>
- {
- public:
- planar_scanline_buffer_t( libtiff_image const & image ) : scanline_buffer_t<Pixel>( tiff, mpl::true_() ) {}
- };
-
- skip_row_results_t BF_NOTHROWNOALIAS skip_to_row
- (
- unsigned int const row_to_skip_to,
- unsigned int const sample,
- tdata_t const buffer,
- cumulative_result & error_result
- ) const
- {
- BOOST_ASSERT( !::TIFFIsTiled( &lib_object() ) );
-
- skip_row_results_t result;
- result.rows_per_strip = get_field<uint32>( TIFFTAG_ROWSPERSTRIP );
- unsigned int const number_of_rows_to_skip_using_scanlines( row_to_skip_to % result.rows_per_strip );
- result.starting_strip = ( row_to_skip_to / result.rows_per_strip ) + ( number_of_rows_to_skip_using_scanlines != 0 ) + sample * get_field<uint32>( TIFFTAG_IMAGEWIDTH );
- result.rows_to_read_using_scanlines = row_to_skip_to ? ( result.rows_per_strip - number_of_rows_to_skip_using_scanlines - 1 ) : 0;
-
- bool const canSkipDirectly
- (
- ( result.rows_per_strip == 1 ) ||
- ( get_field<uint16>( TIFFTAG_COMPRESSION ) == COMPRESSION_NONE )
- );
- unsigned int row
- (
- canSkipDirectly
- ? row_to_skip_to
- : ( row_to_skip_to - number_of_rows_to_skip_using_scanlines )
- );
- while ( row < row_to_skip_to )
- {
- error_result.accumulate_greater( ::TIFFReadScanline( &lib_object(), buffer, row++, static_cast<tsample_t>( sample ) ), 0 );
- }
-
- //BOOST_ASSERT( !row_to_skip_to || ( ::TIFFCurrentRow( &lib_object() ) == row_to_skip_to ) );
-
- return result;
- }
-
-private:
- full_format_t format_;
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#endif
-
-
-//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // libtiff_image_hpp
+#endif // libtiff_writer_hpp

Copied: sandbox/gil/boost/gil/extension/io2/reader.hpp (from r68172, /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/reader.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Base CRTP class for all image implementation classes/backends.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,39 +15,17 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef reader_hpp__1733426F_1D8C_4F4E_A966_BDB6426AA88C
+#define reader_hpp__1733426F_1D8C_4F4E_A966_BDB6426AA88C
 #pragma once
-#ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
-#define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 //------------------------------------------------------------------------------
 #include "format_tags.hpp"
 #include "detail/platform_specifics.hpp"
 #include "detail/io_error.hpp"
-#include "detail/switch.hpp"
 
-#include "boost/gil/extension/dynamic_image/any_image.hpp"
-#include "boost/gil/extension/io/dynamic_io.hpp" //...zzz...
-#include "boost/gil/packed_pixel.hpp"
-#include "boost/gil/planar_pixel_iterator.hpp"
-#include "boost/gil/planar_pixel_reference.hpp"
 #include "boost/gil/typedefs.hpp"
 
-#include <boost/compressed_pair.hpp>
-#ifdef _DEBUG
-#include <boost/detail/endian.hpp>
-#endif // _DEBUG
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/mpl/integral_c.hpp>
-#include <boost/mpl/map.hpp>
-#include <boost/mpl/vector_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>
-#include <boost/type_traits/decay.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -55,1093 +33,66 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-
-struct assert_dimensions_match {};
-struct ensure_dimensions_match {};
-struct synchronize_dimensions {};
-
-struct assert_formats_match {};
-struct ensure_formats_match {};
-struct synchronize_formats {};
-
-#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> >
-{
- packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
- {
- typedef packed_channel_value<DestPackedNumBits> DstChannelV;
-
- typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
- typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
-
- 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)));
- }
- }
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#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_ ;
- Offset offset_;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class formatted_image_traits
-/// ( forward declaration )
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-struct formatted_image_traits;
-
-namespace detail
+namespace io
 {
 //------------------------------------------------------------------------------
 
-#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 get_offset( View const & ) { return Offset(); }
-template <typename Offset, class View>
-Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
-
-template <typename Offset>
-Offset get_offset_x( Offset const & ) { return Offset(); }
-template <typename Offset>
-Offset const & get_offset_x( point2<Offset> const & offset ) { return offset.x; }
-
-template <typename Offset>
-Offset get_offset_y( Offset const & offset ) { return offset; }
-template <typename Offset>
-Offset const & get_offset_y( point2<Offset> const & offset ) { return offset.y; }
-
-
-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 <class View>
-struct is_offset_view : mpl::false_ {};
-
-template <class View, typename Offset>
-struct is_offset_view<offset_view_t<View, Offset> > : mpl::true_ {};
-
-
-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; };
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class configure_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to open the
-/// target/file and then be configured for the desired view.
-///
-////////////////////////////////////////////////////////////////////////////////
-
-struct configure_on_write_writer
+namespace detail
 {
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
+ template <class Reader, typename Source>
+ class reader_extender
+ :
+ public input_device<Source>,
+ public Reader
     {
     public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
+ reader_extender( Source const source )
             :
- Writer ( target, specified_format ),
- view_data_( view )
+ input_device<Source>( source ),
+ Reader ( input_device<Source>::transform( source ) )
         {}
-
- void write_default() { Writer::write_default( view_data_ ); }
- void write () { Writer::write ( view_data_ ); }
-
- private:
- ViewDataHolder const view_data_;
     };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- single_format_writer_wrapper( WriterTarget const & target, format_tag const specified_format = OnlyFormat )
- :
- Writer( target )
- {
- BOOST_VERIFY( specified_format == OnlyFormat );
- }
- };
-};
+} // namespace detail
 
 
 ////////////////////////////////////////////////////////////////////////////////
-///
-/// \class open_on_write_writer
-/// \internal
-/// \brief Helper wrapper for backends/writers that first need to be configured
-/// for/created from the desired view and then open the target/file.
-///
+/// \class formatted_image_traits
+/// ( forward declaration )
 ////////////////////////////////////////////////////////////////////////////////
 
-struct open_on_write_writer
-{
- template <typename Writer, typename WriterTarget, typename ViewDataHolder, format_tag DefaultFormat>
- class wrapper : public Writer
- {
- public:
- template <typename View>
- wrapper( WriterTarget const & target, View const & view, format_tag const specified_format = DefaultFormat )
- :
- Writer ( view ),
- target_ ( target ),
- specified_format_( specified_format )
- {}
-
- void write_default() { Writer::write_default( target_, specified_format_ ); }
- void write () { Writer::write ( target_, specified_format_ ); }
-
- private:
- typename call_traits<WriterTarget>::param_type const target_;
- format_tag const specified_format_;
- };
-
- template <typename Writer, typename WriterTarget, format_tag OnlyFormat>
- class single_format_writer_wrapper : public Writer
- {
- public:
- template <typename View>
- single_format_writer_wrapper( View const & view ) : Writer( view ) {}
-
- void write_default( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write_default( target ); }
- void write ( WriterTarget const & target, format_tag const specified_format = OnlyFormat ) { BOOST_VERIFY( specified_format == OnlyFormat ); Writer::write ( target ); }
- };
-};
+template <class Impl>
+struct formatted_image_traits;
 
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image_base
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class formatted_image_base : noncopyable
+template <class Backend, typename Source>
+struct reader_for
 {
-public:
- typedef point2<std::ptrdiff_t> dimensions_t;
-
- typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
-
-public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- static bool can_do_row_access () { return true ; }
- static bool can_do_strip_access() { return false; }
- static bool can_do_tile_access () { return false; }
-
- static bool can_do_roi_access () { return false; }
- static bool can_do_vertical_roi_access() { return true ; }
-
-protected:
- static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
- template <class View>
- static bool dimensions_mismatch( dimensions_t const & mine, View const & view ) { 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 )
- {
- // Implementation note:
- // For offset target views all dimensions are allowed as they are
- // intended to load an image in steps so they must be allowed to be
- // smaller. They are also allowed to be bigger to allow GIL users to use
- // fixed 'sub' view, while loading an image in steps, whose size is not
- // an exact divisor of the source image dimensions.
- // The exception is for backends that support only vertical 'ROIs'/
- // offsets, for those the horizontal dimensions must match.
- // (19.09.2010.) (Domagoj Saric)
- //dimensions_t const other( offset_view.dimensions() );
- //return ( other.x < mine.x ) || ( other.y < mine.y );
- return is_pod<Offset>::value ? ( mine.x != offset_view.dimensions().x ) : false;
- }
-
- 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" );
- }
-
- template <class View>
- static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
- {
- 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" );
- }
-
- template <typename Image>
- static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
- {
- image.recreate( my_dimensions, alignment );
- }
+ typedef typename mpl::has_key<typename formatted_image_traits<Backend>::native_sources, Source>::type supported_by_native_reader_t;
 
+ // The backend does not seem to provide a reader for the specified target...
+ BOOST_STATIC_ASSERT
+ ((
+ supported_by_native_reader_t::value ||
+ !unknown_input_device<Source>::value
+ ));
 
- ////////////////////////////////////////////////////////////////////////////
- //
- // subview_for_offset()
- // --------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \brief Locally adjusts a view with a ROI/offset to prevent it exceeding
- /// the image dimensions when 'merged' with its offset. Done here so that
- /// backend classes do not need to handle this.
- /// \internal
- /// \throws nothing
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- static View subview_for_offset( dimensions_t const & my_dimensions, offset_view_t<View, Offset> const & offset_view )
- {
- dimensions_t const & target_dimensions( offset_view.original_view().dimensions() );
-
- bool const zero_x_offset( is_pod<Offset>::value );
- if ( zero_x_offset )
- {
- BOOST_ASSERT( get_offset_x( offset_view.offset() ) == 0 );
- BOOST_ASSERT( my_dimensions.x == target_dimensions.x );
- }
-
- unsigned int const width ( zero_x_offset ? target_dimensions.x : (std::min)( my_dimensions.x - get_offset_x( offset_view.offset() ), target_dimensions.x ) );
- unsigned int const height( (std::min)( my_dimensions.y - get_offset_y( offset_view.offset() ), target_dimensions.y ) );
-
- return subimage_view( offset_view.original_view(), 0, 0, width, height );
- }
-
-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;
- template <typename Index>
- result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
- };
-
- struct throw_type_mismatch
- {
- typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( true ); }
- };
-
- template <typename Type, typename SupportedPixelFormats>
- struct check_type_match
- {
- typedef bool result_type;
- template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
- {
- 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>
- result_type operator()( Index const & ) const
- {
- BOOST_ASSERT( !"Default case must not have been reached!" );
- BF_UNREACHABLE_CODE
- return result_type();
- }
- };
-
- template <typename Images>
- class make_dynamic_image
- {
- public:
- make_dynamic_image( any_image<Images> & image ) : image_( image ) {}
-
- template <class Image>
- Image & apply()
- {
- image_.move_in( Image() );
- return image_. BOOST_NESTED_TEMPLATE _dynamic_cast<Image>();
- }
-
- protected:
- any_image<Images> & image_;
- };
+ typedef typename mpl::if_
+ <
+ supported_by_native_reader_t,
+ typename Backend::native_reader,
+ detail::reader_extender<typename Backend::device_reader, Source>
+ >::type type;
 };
 
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-class formatted_image : public formatted_image_base
-{
-public:
- typedef typename formatted_image_traits<Impl>::format_t format_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;
-
- template <typename PixelType, bool IsPlanar>
- struct native_format
- : formatted_image_traits<Impl>::gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<PixelType, IsPlanar>::type
- {};
-
- template <typename T> struct get_native_format;
-
- template <typename PixelType, typename IsPlanar>
- struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
-
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
-
- template <typename Locator>
- struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
-
- template <class View>
- struct has_supported_format
- {
- private:
- typedef typename get_original_view_t<View>::type original_view_t;
-
- public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
- <
- typename original_view_t::value_type,
- is_planar<original_view_t>::value
- > type;
- BOOST_STATIC_CONSTANT( bool, value = type::value );
- };
-
- typedef any_image<supported_pixel_formats> dynamic_image_t;
-
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
-
- BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
-
-protected:
- typedef formatted_image base_t;
-
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
-
-private:
- template <typename Images, typename dimensions_policy, typename formats_policy>
- class read_dynamic_image : make_dynamic_image<Images>
- {
- private:
- typedef make_dynamic_image<Images> base;
-
- public:
- typedef void result_type;
-
- read_dynamic_image( any_image<Images> & image, Impl & impl )
- :
- base ( image ),
- impl_( impl )
- {}
-
- template <class Image>
- void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
-
- template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
-
- private:
- Impl & impl_;
- };
-
- template <typename dimensions_policy, typename formats_policy>
- class write_dynamic_view
- {
- public:
- typedef void result_type;
-
- write_dynamic_view( Impl & impl ) : impl_( impl ) {}
-
- template <class View>
- void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
-
- private:
- Impl & impl_;
- };
-
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- 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_( unsupported_format ) {}
-
- template <typename ImageIndex>
- void operator()( ImageIndex )
- {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
- if ( image_format == this->format_ )
- {
- BOOST_ASSERT( image_id_ == unsupported_format );
- image_id_ = ImageIndex::value;
- }
- }
-
- format_t const format_ ;
- unsigned int image_id_;
-
- private:
- void operator=( image_id_finder const & );
- };
-
-private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
- Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
- Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
-
-protected:
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
- }
-
- 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 );
- }
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
- }
-
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
- {
- return ( other_format != impl().closest_gil_supported_format() ) != false;
- }
-
- 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>( impl().format() );
- }
-
- template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
- {
- return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
- }
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- View subview_for_offset( offset_view_t<View, Offset> const & offset_view ) const
- {
- return formatted_image_base::subview_for_offset( impl().dimensions(), offset_view );
- }
-
- template <typename View>
- static view_data_t get_view_data( View const & view )
- {
- return view_data_t( view );
- }
-
- template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
- {
- return view_data_t
- (
- subview_for_offset( offset_view ),
- offset_view.offset()
- );
- }
-
-public: // Low-level (row, strip, tile) access
- std::size_t pixel_size() const
- {
- return impl().cached_format_size( impl().format() );
- }
-
- std::size_t row_size() const
- {
- return impl().pixel_size() * impl().dimensions().x;
- }
-
- // 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 into 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_ != unsupported_format );
- return finder.image_id_;
- }
-
-public: // Views...
- template <typename View>
- void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
- {
- BOOST_STATIC_ASSERT( get_original_view_t<View>::type::value_type::is_mutable );
- BOOST_STATIC_ASSERT( has_supported_format<View>::value );
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- BOOST_ASSERT( !impl().formats_mismatch<View>() );
- impl().raw_copy_to_prepared_view( get_view_data( view ) );
- }
-
- template <typename View>
- 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 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 const & view, ensure_dimensions_match, ensure_formats_match ) const
- {
- impl().do_ensure_dimensions_match( view );
- impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
- }
-
- template <typename View>
- 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 const & view, assert_dimensions_match, synchronize_formats ) const
- {
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- typedef mpl::bool_
- <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
- > can_use_raw_t;
- default_convert_to_worker( view, can_use_raw_t() );
- }
-
- template <typename FormatConverter, typename View>
- void copy_to( View const & view, ensure_dimensions_match, FormatConverter & 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 const & view, assert_dimensions_match, FormatConverter & 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
- {
- 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_image( any_image<Images> & im ) const
- {
- switch_<valid_type_id_range_t>
- (
- impl().current_image_format_id(),
- read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
- );
- }
-
- template <typename Views, typename dimensions_policy, typename formats_policy>
- void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
- {
- typedef write_dynamic_view<dimensions_policy, formats_policy> op_t;
- op_t op( *this );
- apply_operation
- (
- runtime_view,
- dynamic_io_fnobj<write_is_supported, op_t>( &op )
- );
- }
-
-public: // Offset factory
- template <class View>
- static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
-
-public: // Utility 'quick-wrappers'...
- template <class Source, class Image>
- static void read( Source const & target, Image & image )
- {
- typedef typename reader_for<typename decay<Source>::type>::type reader_t;
- // The backend does not know how to read from the specified source type.
- BOOST_STATIC_ASSERT(( !is_same<reader_t, mpl::void_>::value ));
- reader_t( target ).copy_to_image( image, synchronize_dimensions(), synchronize_formats() );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> const & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <class Target, class View>
- static void write( Target & target, View const & view )
- {
- typedef typename writer_for<Target>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( target, view ).write_default();
- }
-
- template <class Target, class View>
- static void write( Target * p_target, View const & view )
- {
- typedef typename writer_for<Target const *>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( p_target, view ).write_default();
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> const & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
-private:
- template <class View, typename CC>
- class in_place_converter_t
- {
- public:
- typedef void result_type;
-
- 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
- {
- typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
- 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 )
- {
- convert_aux( srcP, is_planar<View>() );
- }
-
- void operator=( in_place_converter_t const & other )
- {
- 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 ) ) );
- }
-
- private:
- compressed_pair<CC, View const &> members_;
- };
-
- template <class View, typename CC>
- class generic_converter_t
- {
- public:
- typedef void result_type;
-
- generic_converter_t( Impl const & impl, CC const & cc, View const & 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_. BOOST_NESTED_TEMPLATE 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();
- }
-
- 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>
- 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
- {
- return switch_<valid_type_id_range_t>
- (
- source_view_type_id,
- generic_converter_t<TargetView, CC>
- (
- impl(),
- cc,
- offset_new_view
- (
- // See the note for formatted_image_base::subview_for_offset()...
- subview_for_offset( view ),
- view
- )
- ),
- assert_default_case_not_reached<void>()
- );
- }
-
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- convert_to_prepared_view_worker
- (
- view,
- converter,
- mpl::bool_
- <
- is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
- has_supported_format < 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 current_format ( impl().closest_gil_supported_format() );
- unsigned int const current_image_format_id( impl().image_format_id( current_format ) );
- if ( can_do_inplace_transform<View>( current_format ) )
- {
- view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
- view_data.set_format( current_format );
- else
- BOOST_ASSERT( current_format == impl().format() );
- impl().raw_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 );
- }
-
- template <typename View>
- void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
- {
- impl().raw_convert_to_prepared_view( get_view_data( 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() );
- }
-};
-
+template <class Backend>
+struct reader_for<Backend, char *> : reader_for<Backend, char const *> {};
 
 //------------------------------------------------------------------------------
-} // namespace detail
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // formatted_image_hpp
+#endif // reader_hpp

Modified: sandbox/gil/boost/gil/extension/io2/wic_image.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/wic_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/wic_image.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -15,12 +15,12 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#pragma once
 #ifndef wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
 #define wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
+#pragma once
 //------------------------------------------------------------------------------
 #include "detail/io_error.hpp"
-#include "detail/libx_shared.hpp" //...zzz...
+#include "detail/shared.hpp"
 #include "detail/wic_extern_lib_guard.hpp"
 #include "detail/windows_shared.hpp"
 #include "detail/windows_shared_istreams.hpp"
@@ -34,6 +34,7 @@
 #include <boost/array.hpp>
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/set/set10.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/type_traits/is_pod.hpp>
@@ -46,6 +47,13 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
+
+template <typename Pixel, bool IsPlanar, typename Alloc=std::allocator<unsigned char> >
+class image;
+
+namespace io
+{
+//------------------------------------------------------------------------------
 namespace detail
 {
 //------------------------------------------------------------------------------
@@ -57,12 +65,13 @@
 {
     typedef format_guid type;
 
- static wic_format_t & value;
+ static wic_format_t const value;
 };
 
 template <wic_format_t guid>
 wic_format_t format_guid<guid>::value( guid );
 
+
 template <typename Pixel, bool IsPlanar>
 struct gil_to_wic_format : format_guid<GUID_WICPixelFormatUndefined> {};
 
@@ -187,92 +196,8 @@
 };
 
 
-class wic_writer : public configure_on_write_writer
-{
-public:
- struct lib_object_t
- {
- detail::com_scoped_ptr<IWICBitmapFrameEncode> p_frame_ ;
- detail::com_scoped_ptr<IWICBitmapEncoder > p_encoder_ ;
- IPropertyBag2 * p_frame_parameters_;
- };
-
- lib_object_t & lib_object() { return lib_object_; }
-
-public:
- wic_writer( IStream & target, format_tag const format )
- {
- create_encoder( target, encoder_guid( format ) );
- }
-
- void write_default( wic_view_data_t const & view_data )
- {
- HRESULT hr( frame().Initialize( lib_object().p_frame_parameters_ ) );
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().SetSize( view_data.width_, view_data.height_ );
- }
-
- if ( SUCCEEDED( hr ) )
- {
- WICPixelFormatGUID formatGUID( view_data.format_ );
- hr = frame().SetPixelFormat( &formatGUID );
- if ( SUCCEEDED( hr ) )
- {
- hr = ( formatGUID == view_data.format_ ) ? S_OK : E_FAIL;
- }
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().WritePixels( view_data.height_, view_data.stride_, view_data.height_ * view_data.stride_, view_data.p_buffer_ );
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().Commit();
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = encoder().Commit();
- }
-
- ensure_result( hr );
- }
-
- void write( wic_view_data_t const & view_data ) { write_default( view_data ); }
-
-private:
- void create_encoder( IStream & target, GUID const & format )
- {
- ensure_result( wic_factory::singleton().CreateEncoder( format, NULL, &lib_object().p_encoder_ ) );
- ensure_result( lib_object().p_encoder_->Initialize( &target, WICBitmapEncoderNoCache ) );
- ensure_result( lib_object().p_encoder_->CreateNewFrame( &lib_object().p_frame_, &lib_object().p_frame_parameters_ ) );
- }
-
- static GUID const & encoder_guid( format_tag const format )
- {
- static GUID const * const guids[ number_of_known_formats ] =
- {
- &GUID_ContainerFormatBmp,
- &GUID_ContainerFormatGif,
- &GUID_ContainerFormatJpeg,
- &GUID_ContainerFormatPng,
- &GUID_ContainerFormatTiff,
- NULL // TGA
- };
- BOOST_ASSERT( guids[ format ] != NULL );
- return *guids[ format ];
- }
-
- IWICBitmapFrameEncode & frame () { return *lib_object().p_frame_ ; }
- IWICBitmapEncoder & encoder() { return *lib_object().p_encoder_; }
-
-private:
- lib_object_t lib_object_;
-};
+template <template <typename Handle> class IODeviceStream, class BackendWriter>
+class device_stream_wrapper;
 
 //------------------------------------------------------------------------------
 } // namespace detail
@@ -303,24 +228,20 @@
>
> {};
 
- typedef mpl::map6
+ typedef mpl::set4
     <
- mpl::pair<char const *, wic_image >,
- mpl::pair<wchar_t const *, wic_image >,
- mpl::pair<HANDLE , wic_image >,
- mpl::pair<IStream , wic_image >,
- mpl::pair<FILE , detail::input_FILE_for_IStream_extender <wic_image> >,
- mpl::pair<memory_chunk_t , detail::memory_chunk_for_IStream_extender<wic_image> >
- > readers;
+ char const *,
+ wchar_t const *,
+ HANDLE ,
+ IStream &
+ > native_sources;
 
- typedef mpl::map3
+ typedef mpl::set1
     <
- mpl::pair<wchar_t const *, detail::output_file_name_for_IStream_extender<detail::wic_writer> >,
- mpl::pair<IStream , detail::wic_writer >,
- mpl::pair<FILE , detail::output_FILE_for_IStream_extender <detail::wic_writer> >
- > writers;
+ IStream &
+ > native_sinks;
 
- typedef mpl::vector5_c<format_tag, bmp, gif, jpeg, png, tiff> supported_image_formats;
+ typedef mpl::vector5_c<format_tag, png, bmp, gif, jpeg, tiff> supported_image_formats;
 
     typedef detail::wic_view_data_t view_data_t ;
     typedef view_data_t writer_view_data_t;
@@ -344,258 +265,20 @@
     public detail::formatted_image<wic_image>
 {
 public:
- // Implementation note:
- // The IWICBitmapDecoder instance is not otherwise necessary once an
- // IWICBitmapFrameDecode instance is created but we keep it here and make it
- // accessible to the user to enable the use of multi frame/page/picture
- // formats like GIF and TIFF.
- // (26.07.2010.) (Domagoj Saric)
- typedef std::pair
- <
- detail::com_scoped_ptr<IWICBitmapFrameDecode>,
- detail::com_scoped_ptr<IWICBitmapDecoder >
- > lib_object_t;
-
     typedef detail::wic_user_guard guard;
 
-public:
- explicit wic_image( wchar_t const * const filename )
- {
- create_decoder_from_filename( filename );
- }
-
- explicit wic_image( char const * const filename )
- {
- create_decoder_from_filename( detail::wide_path( filename ) );
- }
-
- // The passed IStream object must outlive the wic_image object (to support
- // lazy evaluation).
- explicit wic_image( IStream & stream )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromStream( &stream, NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- explicit wic_image( HANDLE const file_handle )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromFileHandle( reinterpret_cast<ULONG_PTR>( file_handle ), NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- // The passed View object must outlive the wic_image object (to support
- // lazy evaluation).
- //...zzz...the same approach as with GDI+ cannot be used with WIC so an IStream approach will be required...
- //template <class View>
- //explicit wic_image( View & view )
- //{
- // ensure_result
- // (
- // wic_factory::singleton().CreateBitmapFromMemory
- // (
- // view.width(),
- // view.height(),
- // view.pixels().row_size(),
- // gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value,
- // get_raw_data( view ),
- // &pBitmap_
- // )
- // );
- // create_first_frame_decoder();
- //}
-
-public:
- point2<std::ptrdiff_t> dimensions() const
- {
- using namespace detail;
- typedef point2<std::ptrdiff_t> result_t;
- aligned_storage<sizeof( result_t ), alignment_of<result_t>::value>::type placeholder;
- result_t & result( *gil_reinterpret_cast<result_t *>( placeholder.address() ) );
- BOOST_STATIC_ASSERT( sizeof( result_t::value_type ) == sizeof( UINT ) );
- verify_result( frame_decoder().GetSize( gil_reinterpret_cast<UINT *>( &result.x ), gil_reinterpret_cast<UINT *>( &result.y ) ) );
- return result;
- }
-
- /*format_t*/WICPixelFormatGUID format() const
- {
- WICPixelFormatGUID pixel_format;
- detail::verify_result( frame_decoder().GetPixelFormat( &pixel_format ) );
- //...zzz...check that it is a supported format...
- return pixel_format;
- }
+ class native_reader;
+ typedef detail::device_stream_wrapper<detail::input_device_stream , native_reader> device_reader;
 
- /*format_t*/WICPixelFormatGUID closest_gil_supported_format() const { return format(); }
-
- image_type_id current_image_format_id() const
- {
- return image_format_id( closest_gil_supported_format() );
- }
+ class native_writer;
+ typedef detail::device_stream_wrapper<detail::output_device_stream, native_writer> device_writer;
 
 public: // Low-level (row, strip, tile) access
     static bool can_do_roi_access() { return true; }
-
- class sequential_row_access_state
- :
- private detail::cumulative_result
- {
- public:
- using detail::cumulative_result::failed;
- void throw_if_error() const { detail::cumulative_result::throw_if_error( "WIC failure" ); }
-
- BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
-
- private:
- sequential_row_access_state( wic_image const & source_image )
- :
- roi_ ( 0, 0, source_image.dimensions().x, 1 ),
- stride_( roi_.X * source_image.pixel_size() )
- {}
-
- private: friend wic_image;
- detail::wic_roi roi_ ;
- UINT const stride_;
- };
-
- sequential_row_access_state begin_sequential_row_access() const { return sequential_row_access_state( *this ); }
-
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage ) const
- {
- state.accumulate_equal
- (
- frame_decoder().CopyPixels
- (
- &state.roi_,
- state.stride_,
- state.stride_,
- p_row_storage
- ),
- S_OK
- );
- ++state.roi_.Y;
- }
-
- lib_object_t & lib_object() { return lib_object_; }
-
-private: // Private formatted_image_base interface.
- friend class base_t;
-
- template <class MyView, class TargetView, class Converter>
- void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
-
- using namespace detail;
-
- //...non template related code yet to be extracted...
- point2<std::ptrdiff_t> const & targetDimensions( original_view( view ).dimensions() );
- wic_roi const roi( get_offset<wic_roi::offset_t>( view ), targetDimensions.x, targetDimensions.y );
- com_scoped_ptr<IWICBitmap> p_bitmap;
- ensure_result( wic_factory::singleton().CreateBitmapFromSourceRect( &frame_decoder(), roi.X, roi.Y, roi.Width, roi.Height, &p_bitmap ) );
- com_scoped_ptr<IWICBitmapLock> p_bitmap_lock;
- ensure_result( p_bitmap->Lock( &roi, WICBitmapLockRead, &p_bitmap_lock ) );
- unsigned int buffer_size;
- BYTE * p_buffer;
- verify_result( p_bitmap_lock->GetDataPointer( &buffer_size, &p_buffer ) );
- unsigned int stride;
- verify_result( p_bitmap_lock->GetStride( &stride ) );
- #ifndef NDEBUG
- WICPixelFormatGUID locked_format;
- verify_result( p_bitmap_lock->GetPixelFormat( &locked_format ) );
- BOOST_ASSERT(( locked_format == gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value ));
- #endif
- copy_and_convert_pixels
- (
- interleaved_view
- (
- roi.Width ,
- roi.Height,
- gil_reinterpret_cast_c<typename MyView::value_type const *>( p_buffer ),
- stride
- ),
- view,
- converter
- );
- }
-
-
- void raw_convert_to_prepared_view( view_data_t const & view_data ) const
- {
- BOOST_ASSERT( view_data.format_ != GUID_WICPixelFormatUndefined ); //...zzz...
- using namespace detail;
- com_scoped_ptr<IWICFormatConverter> p_converter;
- ensure_result( wic_factory::singleton().CreateFormatConverter( &p_converter ) );
- ensure_result( p_converter->Initialize( &frame_decoder(), view_data.format_, WICBitmapDitherTypeNone, NULL, 0, WICBitmapPaletteTypeCustom ) );
- ensure_result
- (
- p_converter->CopyPixels
- (
- view_data.p_roi_,
- view_data.stride_,
- view_data.height_ * view_data.stride_ * view_data.pixel_size_,
- view_data.p_buffer_
- )
- );
- }
-
-
- void raw_copy_to_prepared_view( view_data_t const & view_data ) const
- {
- detail::ensure_result
- (
- frame_decoder().CopyPixels
- (
- view_data.p_roi_,
- view_data.stride_,
- view_data.height_ * view_data.stride_ * view_data.pixel_size_,
- view_data.p_buffer_
- )
- );
- }
-
-
- static std::size_t cached_format_size( format_t const format )
- {
- using namespace detail;
- com_scoped_ptr<IWICComponentInfo> p_component_info;
- ensure_result( wic_factory::singleton().CreateComponentInfo( format, &p_component_info ) );
- //com_scoped_ptr<IWICPixelFormatInfo> p_pixel_format_info;
- //p_component_info->QueryInterface( );IID_IWICPixelFormatInfo
- com_scoped_ptr<IWICPixelFormatInfo> const p_pixel_format_info( *p_component_info );
- io_error_if_not( p_pixel_format_info, "WIC failure" );
- unsigned int bits_per_pixel;
- verify_result( p_pixel_format_info->GetBitsPerPixel( &bits_per_pixel ) );
- return bits_per_pixel;
- }
-
-private:
- IWICBitmapFrameDecode & frame_decoder() const { return *lib_object_.first ; }
- IWICBitmapDecoder & wic_decoder () const { return *lib_object_.second; }
-
- void create_decoder_from_filename( wchar_t const * const filename )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromFilename( filename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- void create_first_frame_decoder()
- {
- using namespace detail;
- #ifndef NDEBUG
- unsigned int frame_count;
- verify_result( wic_decoder().GetFrameCount( &frame_count ) );
- BOOST_ASSERT( frame_count >= 1 );
- #endif // NDEBUG
- ensure_result( wic_decoder().GetFrame( 0, &lib_object().first ) );
- }
-
-private:
- lib_object_t lib_object_;
 };
 
-
+//------------------------------------------------------------------------------
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------

Copied: sandbox/gil/boost/gil/extension/io2/wic_reader.hpp (from r73054, /sandbox/gil/boost/gil/extension/io2/wic_image.hpp)
==============================================================================
--- /sandbox/gil/boost/gil/extension/io2/wic_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/wic_reader.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Base IO interface WIC implementation.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,16 +15,16 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef wic_reader_hpp__8C7EFA72_9E1A_4FD4_AF3F_B7921B320C1C
+#define wic_reader_hpp__8C7EFA72_9E1A_4FD4_AF3F_B7921B320C1C
 #pragma once
-#ifndef wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
-#define wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
 //------------------------------------------------------------------------------
+#include "backend_reader.hpp"
 #include "detail/io_error.hpp"
-#include "detail/libx_shared.hpp" //...zzz...
 #include "detail/wic_extern_lib_guard.hpp"
 #include "detail/windows_shared.hpp"
 #include "detail/windows_shared_istreams.hpp"
-#include "formatted_image.hpp"
+#include "wic_image.hpp"
 
 #include <boost/mpl/vector_c.hpp> //...missing from metafuncitons.hpp...
 #include "boost/gil/metafunctions.hpp"
@@ -46,302 +46,20 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-namespace detail
+namespace io
 {
 //------------------------------------------------------------------------------
 
-typedef WICPixelFormatGUID const & wic_format_t;
-
-template <wic_format_t guid>
-struct format_guid
-{
- typedef format_guid type;
-
- static wic_format_t & value;
-};
-
-template <wic_format_t guid>
-wic_format_t format_guid<guid>::value( guid );
-
-template <typename Pixel, bool IsPlanar>
-struct gil_to_wic_format : format_guid<GUID_WICPixelFormatUndefined> {};
-
-typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, bgr_layout_t>::type wic_bgr565_pixel_t;
-
-template <> struct gil_to_wic_format<wic_bgr565_pixel_t, false> : format_guid<GUID_WICPixelFormat16bppBGR555> {};
-template <> struct gil_to_wic_format<bgr8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppBGR > {};
-template <> struct gil_to_wic_format<rgb8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppRGB > {};
-template <> struct gil_to_wic_format<bgra8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppBGRA > {};
-template <> struct gil_to_wic_format<gray16_pixel_t , false> : format_guid<GUID_WICPixelFormat16bppGray > {};
-template <> struct gil_to_wic_format<bgr16_pixel_t , false> : format_guid<GUID_WICPixelFormat48bppRGB > {};
-template <> struct gil_to_wic_format<bgra16_pixel_t , false> : format_guid<GUID_WICPixelFormat64bppBGRA > {};
-template <> struct gil_to_wic_format<cmyk8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppCMYK > {};
-
-
-typedef mpl::vector8
-<
- image<wic_bgr565_pixel_t, false>,
- image<bgr8_pixel_t , false>,
- image<rgb8_pixel_t , false>,
- image<bgra8_pixel_t , false>,
- image<gray16_pixel_t , false>,
- image<bgr16_pixel_t , false>,
- image<bgra16_pixel_t , false>,
- image<cmyk8_pixel_t , false>
-> wic_supported_pixel_formats;
-
-
-struct view_wic_format
-{
- template <typename Pixel, bool IsPlanar>
- struct apply : gil_to_wic_format<Pixel, IsPlanar> {};
-};
-
-
-class wic_roi : public WICRect
-{
-public:
- typedef INT value_type;
- typedef point2<value_type> point_t ;
-
- typedef point_t offset_t ;
-
-public:
- wic_roi( value_type const x, value_type const y, value_type const width, value_type const height )
- {
- X = x; Y = y;
- Width = width; Height = height;
- }
-
- wic_roi( offset_t const top_left, value_type const width, value_type const height )
- {
- X = top_left.x; Y = top_left.y;
- Width = width; Height = height;
- }
-
- wic_roi( offset_t const top_left, offset_t const bottom_right )
- {
- X = top_left.x; Y = top_left.y;
- Width = bottom_right.x - top_left.x;
- Height = bottom_right.y - top_left.y;
- }
-};
-
-
-inline void ensure_result( HRESULT const result )
-{
- io_error_if( result != S_OK, "WIC failure"/*error_string( result )*/ );
-}
-
-inline void verify_result( HRESULT const result )
-{
- BOOST_VERIFY( result == S_OK );
-}
-
-
-struct wic_view_data_t
-{
- template <typename View>
- wic_view_data_t( View const & view )
- :
- p_roi_ ( 0 ),
- format_( gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value )
- {
- set_bitmapdata_for_view( view );
- }
-
- template <typename View>
- wic_view_data_t( View const & view, wic_roi::offset_t const & offset )
- :
- p_roi_ ( static_cast<wic_roi const *>( optional_roi_.address() ) ),
- format_( gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value )
- {
- set_bitmapdata_for_view( view );
- new ( optional_roi_.address() ) wic_roi( offset, width_, height_ );
- }
-
- WICRect const * const p_roi_ ;
- unsigned int /*const*/ width_ ;
- unsigned int /*const*/ height_;
- unsigned int /*const*/ stride_;
- unsigned int /*const*/ pixel_size_;
- BYTE * /*const*/ p_buffer_;
- wic_format_t const format_;
-
-private:
- template <typename View>
- void set_bitmapdata_for_view( View const & view )
- {
- width_ = view.width();
- height_ = view.height();
- stride_ = view.pixels().row_size();
- pixel_size_ = memunit_step( typename View::x_iterator() );
- //format_ = gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value;
- p_buffer_ = detail::formatted_image_base::get_raw_data( view );
- }
-
- void operator=( wic_view_data_t const & );
-
-private:
- aligned_storage<sizeof( wic_roi ), alignment_of<wic_roi>::value>::type optional_roi_;
-};
-
-
-class wic_writer : public configure_on_write_writer
-{
-public:
- struct lib_object_t
- {
- detail::com_scoped_ptr<IWICBitmapFrameEncode> p_frame_ ;
- detail::com_scoped_ptr<IWICBitmapEncoder > p_encoder_ ;
- IPropertyBag2 * p_frame_parameters_;
- };
-
- lib_object_t & lib_object() { return lib_object_; }
-
-public:
- wic_writer( IStream & target, format_tag const format )
- {
- create_encoder( target, encoder_guid( format ) );
- }
-
- void write_default( wic_view_data_t const & view_data )
- {
- HRESULT hr( frame().Initialize( lib_object().p_frame_parameters_ ) );
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().SetSize( view_data.width_, view_data.height_ );
- }
-
- if ( SUCCEEDED( hr ) )
- {
- WICPixelFormatGUID formatGUID( view_data.format_ );
- hr = frame().SetPixelFormat( &formatGUID );
- if ( SUCCEEDED( hr ) )
- {
- hr = ( formatGUID == view_data.format_ ) ? S_OK : E_FAIL;
- }
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().WritePixels( view_data.height_, view_data.stride_, view_data.height_ * view_data.stride_, view_data.p_buffer_ );
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = frame().Commit();
- }
-
- if ( SUCCEEDED( hr ) )
- {
- hr = encoder().Commit();
- }
-
- ensure_result( hr );
- }
-
- void write( wic_view_data_t const & view_data ) { write_default( view_data ); }
-
-private:
- void create_encoder( IStream & target, GUID const & format )
- {
- ensure_result( wic_factory::singleton().CreateEncoder( format, NULL, &lib_object().p_encoder_ ) );
- ensure_result( lib_object().p_encoder_->Initialize( &target, WICBitmapEncoderNoCache ) );
- ensure_result( lib_object().p_encoder_->CreateNewFrame( &lib_object().p_frame_, &lib_object().p_frame_parameters_ ) );
- }
-
- static GUID const & encoder_guid( format_tag const format )
- {
- static GUID const * const guids[ number_of_known_formats ] =
- {
- &GUID_ContainerFormatBmp,
- &GUID_ContainerFormatGif,
- &GUID_ContainerFormatJpeg,
- &GUID_ContainerFormatPng,
- &GUID_ContainerFormatTiff,
- NULL // TGA
- };
- BOOST_ASSERT( guids[ format ] != NULL );
- return *guids[ format ];
- }
-
- IWICBitmapFrameEncode & frame () { return *lib_object().p_frame_ ; }
- IWICBitmapEncoder & encoder() { return *lib_object().p_encoder_; }
-
-private:
- lib_object_t lib_object_;
-};
-
-//------------------------------------------------------------------------------
-} // namespace detail
-
-class wic_image;
-
-template <>
-struct formatted_image_traits<wic_image>
-{
- typedef detail::wic_format_t format_t;
-
- typedef detail::wic_supported_pixel_formats supported_pixel_formats_t;
-
- typedef detail::wic_roi roi_t;
-
- typedef detail::view_wic_format gil_to_native_format;
-
- template <typename Pixel, bool IsPlanar>
- struct is_supported
- :
- mpl::not_
- <
- is_same
- <
- typename gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<Pixel, IsPlanar>::type,
- //format_guid<wic_format >,
- detail::format_guid<GUID_WICPixelFormatUndefined>
- >
- > {};
-
- typedef mpl::map6
- <
- mpl::pair<char const *, wic_image >,
- mpl::pair<wchar_t const *, wic_image >,
- mpl::pair<HANDLE , wic_image >,
- mpl::pair<IStream , wic_image >,
- mpl::pair<FILE , detail::input_FILE_for_IStream_extender <wic_image> >,
- mpl::pair<memory_chunk_t , detail::memory_chunk_for_IStream_extender<wic_image> >
- > readers;
-
- typedef mpl::map3
- <
- mpl::pair<wchar_t const *, detail::output_file_name_for_IStream_extender<detail::wic_writer> >,
- mpl::pair<IStream , detail::wic_writer >,
- mpl::pair<FILE , detail::output_FILE_for_IStream_extender <detail::wic_writer> >
- > writers;
-
- typedef mpl::vector5_c<format_tag, bmp, gif, jpeg, png, tiff> supported_image_formats;
-
- typedef detail::wic_view_data_t view_data_t ;
- typedef view_data_t writer_view_data_t;
-
- BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( void * ) );
- BOOST_STATIC_CONSTANT( bool , builtin_conversion = true );
-};
-
-
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \class wic_image
+/// \class wic_image::native_reader
 ///
 ////////////////////////////////////////////////////////////////////////////////
-// http://msdn.microsoft.com/en-us/magazine/cc500647.aspx
-////////////////////////////////////////////////////////////////////////////////
 
-class wic_image
+class wic_image::native_reader
     :
- private detail::wic_base_guard,
- public detail::formatted_image<wic_image>
+ public wic_image,
+ public detail::backend_reader<wic_image>
 {
 public:
     // Implementation note:
@@ -359,53 +77,32 @@
     typedef detail::wic_user_guard guard;
 
 public:
- explicit wic_image( wchar_t const * const filename )
+ explicit native_reader( wchar_t const * const filename )
     {
         create_decoder_from_filename( filename );
     }
 
- explicit wic_image( char const * const filename )
+ explicit native_reader( char const * const filename )
     {
         create_decoder_from_filename( detail::wide_path( filename ) );
     }
 
     // The passed IStream object must outlive the wic_image object (to support
     // lazy evaluation).
- explicit wic_image( IStream & stream )
+ explicit native_reader( IStream & stream )
     {
         using namespace detail;
         ensure_result( wic_factory::singleton().CreateDecoderFromStream( &stream, NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
         create_first_frame_decoder();
     }
 
- explicit wic_image( HANDLE const file_handle )
+ explicit native_reader( HANDLE const file_handle )
     {
         using namespace detail;
         ensure_result( wic_factory::singleton().CreateDecoderFromFileHandle( reinterpret_cast<ULONG_PTR>( file_handle ), NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
         create_first_frame_decoder();
     }
 
- // The passed View object must outlive the wic_image object (to support
- // lazy evaluation).
- //...zzz...the same approach as with GDI+ cannot be used with WIC so an IStream approach will be required...
- //template <class View>
- //explicit wic_image( View & view )
- //{
- // ensure_result
- // (
- // wic_factory::singleton().CreateBitmapFromMemory
- // (
- // view.width(),
- // view.height(),
- // view.pixels().row_size(),
- // gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value,
- // get_raw_data( view ),
- // &pBitmap_
- // )
- // );
- // create_first_frame_decoder();
- //}
-
 public:
     point2<std::ptrdiff_t> dimensions() const
     {
@@ -434,9 +131,7 @@
     }
 
 public: // Low-level (row, strip, tile) access
- static bool can_do_roi_access() { return true; }
-
- class sequential_row_access_state
+ class sequential_row_read_state
         :
         private detail::cumulative_result
     {
@@ -447,7 +142,7 @@
         BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
 
     private:
- sequential_row_access_state( wic_image const & source_image )
+ sequential_row_read_state( wic_image::native_reader const & source_image )
             :
             roi_ ( 0, 0, source_image.dimensions().x, 1 ),
             stride_( roi_.X * source_image.pixel_size() )
@@ -458,9 +153,9 @@
         UINT const stride_;
     };
 
- sequential_row_access_state begin_sequential_row_access() const { return sequential_row_access_state( *this ); }
+ sequential_row_read_state begin_sequential_row_read() const { return sequential_row_read_state( *this ); }
 
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage ) const
+ void read_row( sequential_row_read_state & state, unsigned char * const p_row_storage ) const
     {
         state.accumulate_equal
         (
@@ -479,7 +174,7 @@
     lib_object_t & lib_object() { return lib_object_; }
 
 private: // Private formatted_image_base interface.
- friend class base_t;
+ friend class detail::backend_reader<wic_image>;
 
     template <class MyView, class TargetView, class Converter>
     void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
@@ -597,8 +292,10 @@
 
 
 //------------------------------------------------------------------------------
+} // namespace io
+//------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // wic_image_hpp
+#endif // wic_reader_hpp

Copied: sandbox/gil/boost/gil/extension/io2/wic_writer.hpp (from r73054, /sandbox/gil/boost/gil/extension/io2/wic_image.hpp)
==============================================================================
--- /sandbox/gil/boost/gil/extension/io2/wic_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/wic_writer.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -1,11 +1,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file wic_image.hpp
-/// -------------------
+/// \file wic_writer.hpp
+/// --------------------
 ///
 /// Base IO interface WIC implementation.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,30 +15,17 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef wic_writer_hpp__F8E533DB_13F3_495F_9F64_0C33F7C5AB95
+#define wic_writer_hpp__F8E533DB_13F3_495F_9F64_0C33F7C5AB95
 #pragma once
-#ifndef wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
-#define wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
 //------------------------------------------------------------------------------
+#include "wic_image.hpp"
+#include "backend_writer.hpp"
+#include "writer.hpp"
+
 #include "detail/io_error.hpp"
-#include "detail/libx_shared.hpp" //...zzz...
-#include "detail/wic_extern_lib_guard.hpp"
 #include "detail/windows_shared.hpp"
 #include "detail/windows_shared_istreams.hpp"
-#include "formatted_image.hpp"
-
-#include <boost/mpl/vector_c.hpp> //...missing from metafuncitons.hpp...
-#include "boost/gil/metafunctions.hpp"
-#include "boost/gil/rgb.hpp"
-#include "boost/gil/typedefs.hpp"
-
-#include <boost/array.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/integral_c.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_pod.hpp>
-
-#include <algorithm>
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -46,148 +33,15 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-namespace detail
+namespace io
 {
 //------------------------------------------------------------------------------
 
-typedef WICPixelFormatGUID const & wic_format_t;
-
-template <wic_format_t guid>
-struct format_guid
-{
- typedef format_guid type;
-
- static wic_format_t & value;
-};
-
-template <wic_format_t guid>
-wic_format_t format_guid<guid>::value( guid );
-
-template <typename Pixel, bool IsPlanar>
-struct gil_to_wic_format : format_guid<GUID_WICPixelFormatUndefined> {};
-
-typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, bgr_layout_t>::type wic_bgr565_pixel_t;
-
-template <> struct gil_to_wic_format<wic_bgr565_pixel_t, false> : format_guid<GUID_WICPixelFormat16bppBGR555> {};
-template <> struct gil_to_wic_format<bgr8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppBGR > {};
-template <> struct gil_to_wic_format<rgb8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppRGB > {};
-template <> struct gil_to_wic_format<bgra8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppBGRA > {};
-template <> struct gil_to_wic_format<gray16_pixel_t , false> : format_guid<GUID_WICPixelFormat16bppGray > {};
-template <> struct gil_to_wic_format<bgr16_pixel_t , false> : format_guid<GUID_WICPixelFormat48bppRGB > {};
-template <> struct gil_to_wic_format<bgra16_pixel_t , false> : format_guid<GUID_WICPixelFormat64bppBGRA > {};
-template <> struct gil_to_wic_format<cmyk8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppCMYK > {};
-
-
-typedef mpl::vector8
-<
- image<wic_bgr565_pixel_t, false>,
- image<bgr8_pixel_t , false>,
- image<rgb8_pixel_t , false>,
- image<bgra8_pixel_t , false>,
- image<gray16_pixel_t , false>,
- image<bgr16_pixel_t , false>,
- image<bgra16_pixel_t , false>,
- image<cmyk8_pixel_t , false>
-> wic_supported_pixel_formats;
-
-
-struct view_wic_format
-{
- template <typename Pixel, bool IsPlanar>
- struct apply : gil_to_wic_format<Pixel, IsPlanar> {};
-};
-
-
-class wic_roi : public WICRect
-{
-public:
- typedef INT value_type;
- typedef point2<value_type> point_t ;
-
- typedef point_t offset_t ;
-
-public:
- wic_roi( value_type const x, value_type const y, value_type const width, value_type const height )
- {
- X = x; Y = y;
- Width = width; Height = height;
- }
-
- wic_roi( offset_t const top_left, value_type const width, value_type const height )
- {
- X = top_left.x; Y = top_left.y;
- Width = width; Height = height;
- }
-
- wic_roi( offset_t const top_left, offset_t const bottom_right )
- {
- X = top_left.x; Y = top_left.y;
- Width = bottom_right.x - top_left.x;
- Height = bottom_right.y - top_left.y;
- }
-};
-
-
-inline void ensure_result( HRESULT const result )
-{
- io_error_if( result != S_OK, "WIC failure"/*error_string( result )*/ );
-}
-
-inline void verify_result( HRESULT const result )
-{
- BOOST_VERIFY( result == S_OK );
-}
-
-
-struct wic_view_data_t
-{
- template <typename View>
- wic_view_data_t( View const & view )
- :
- p_roi_ ( 0 ),
- format_( gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value )
- {
- set_bitmapdata_for_view( view );
- }
-
- template <typename View>
- wic_view_data_t( View const & view, wic_roi::offset_t const & offset )
- :
- p_roi_ ( static_cast<wic_roi const *>( optional_roi_.address() ) ),
- format_( gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value )
- {
- set_bitmapdata_for_view( view );
- new ( optional_roi_.address() ) wic_roi( offset, width_, height_ );
- }
-
- WICRect const * const p_roi_ ;
- unsigned int /*const*/ width_ ;
- unsigned int /*const*/ height_;
- unsigned int /*const*/ stride_;
- unsigned int /*const*/ pixel_size_;
- BYTE * /*const*/ p_buffer_;
- wic_format_t const format_;
-
-private:
- template <typename View>
- void set_bitmapdata_for_view( View const & view )
- {
- width_ = view.width();
- height_ = view.height();
- stride_ = view.pixels().row_size();
- pixel_size_ = memunit_step( typename View::x_iterator() );
- //format_ = gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value;
- p_buffer_ = detail::formatted_image_base::get_raw_data( view );
- }
-
- void operator=( wic_view_data_t const & );
-
-private:
- aligned_storage<sizeof( wic_roi ), alignment_of<wic_roi>::value>::type optional_roi_;
-};
-
-
-class wic_writer : public configure_on_write_writer
+class wic_image::native_writer
+ :
+ public wic_image,
+ public detail::backend_writer<wic_image>,
+ public detail::configure_on_write_writer
 {
 public:
     struct lib_object_t
@@ -200,12 +54,12 @@
     lib_object_t & lib_object() { return lib_object_; }
 
 public:
- wic_writer( IStream & target, format_tag const format )
+ native_writer( IStream & target, format_tag const format )
     {
         create_encoder( target, encoder_guid( format ) );
     }
 
- void write_default( wic_view_data_t const & view_data )
+ void write_default( detail::wic_view_data_t const & view_data )
     {
         HRESULT hr( frame().Initialize( lib_object().p_frame_parameters_ ) );
 
@@ -239,17 +93,28 @@
             hr = encoder().Commit();
         }
 
- ensure_result( hr );
+ detail::ensure_result( hr );
     }
 
- void write( wic_view_data_t const & view_data ) { write_default( view_data ); }
+ void write( detail::wic_view_data_t const & view_data ) { write_default( view_data ); }
 
 private:
     void create_encoder( IStream & target, GUID const & format )
     {
- ensure_result( wic_factory::singleton().CreateEncoder( format, NULL, &lib_object().p_encoder_ ) );
- ensure_result( lib_object().p_encoder_->Initialize( &target, WICBitmapEncoderNoCache ) );
- ensure_result( lib_object().p_encoder_->CreateNewFrame( &lib_object().p_frame_, &lib_object().p_frame_parameters_ ) );
+ using namespace detail;
+ HRESULT hr;
+ {
+ hr = wic_factory::singleton().CreateEncoder( format, NULL, &lib_object().p_encoder_ );
+ }
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = encoder().Initialize( &target, WICBitmapEncoderNoCache );
+ }
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = encoder().CreateNewFrame( &lib_object().p_frame_, &lib_object().p_frame_parameters_ );
+ }
+ ensure_result( hr );
     }
 
     static GUID const & encoder_guid( format_tag const format )
@@ -263,7 +128,7 @@
             &GUID_ContainerFormatTiff,
             NULL // TGA
         };
- BOOST_ASSERT( guids[ format ] != NULL );
+ BOOST_ASSERT_MSG( guids[ format ] != NULL, "File format not supported by WIC." );
         return *guids[ format ];
     }
 
@@ -275,330 +140,10 @@
 };
 
 //------------------------------------------------------------------------------
-} // namespace detail
-
-class wic_image;
-
-template <>
-struct formatted_image_traits<wic_image>
-{
- typedef detail::wic_format_t format_t;
-
- typedef detail::wic_supported_pixel_formats supported_pixel_formats_t;
-
- typedef detail::wic_roi roi_t;
-
- typedef detail::view_wic_format gil_to_native_format;
-
- template <typename Pixel, bool IsPlanar>
- struct is_supported
- :
- mpl::not_
- <
- is_same
- <
- typename gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<Pixel, IsPlanar>::type,
- //format_guid<wic_format >,
- detail::format_guid<GUID_WICPixelFormatUndefined>
- >
- > {};
-
- typedef mpl::map6
- <
- mpl::pair<char const *, wic_image >,
- mpl::pair<wchar_t const *, wic_image >,
- mpl::pair<HANDLE , wic_image >,
- mpl::pair<IStream , wic_image >,
- mpl::pair<FILE , detail::input_FILE_for_IStream_extender <wic_image> >,
- mpl::pair<memory_chunk_t , detail::memory_chunk_for_IStream_extender<wic_image> >
- > readers;
-
- typedef mpl::map3
- <
- mpl::pair<wchar_t const *, detail::output_file_name_for_IStream_extender<detail::wic_writer> >,
- mpl::pair<IStream , detail::wic_writer >,
- mpl::pair<FILE , detail::output_FILE_for_IStream_extender <detail::wic_writer> >
- > writers;
-
- typedef mpl::vector5_c<format_tag, bmp, gif, jpeg, png, tiff> supported_image_formats;
-
- typedef detail::wic_view_data_t view_data_t ;
- typedef view_data_t writer_view_data_t;
-
- BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( void * ) );
- BOOST_STATIC_CONSTANT( bool , builtin_conversion = true );
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class wic_image
-///
-////////////////////////////////////////////////////////////////////////////////
-// http://msdn.microsoft.com/en-us/magazine/cc500647.aspx
-////////////////////////////////////////////////////////////////////////////////
-
-class wic_image
- :
- private detail::wic_base_guard,
- public detail::formatted_image<wic_image>
-{
-public:
- // Implementation note:
- // The IWICBitmapDecoder instance is not otherwise necessary once an
- // IWICBitmapFrameDecode instance is created but we keep it here and make it
- // accessible to the user to enable the use of multi frame/page/picture
- // formats like GIF and TIFF.
- // (26.07.2010.) (Domagoj Saric)
- typedef std::pair
- <
- detail::com_scoped_ptr<IWICBitmapFrameDecode>,
- detail::com_scoped_ptr<IWICBitmapDecoder >
- > lib_object_t;
-
- typedef detail::wic_user_guard guard;
-
-public:
- explicit wic_image( wchar_t const * const filename )
- {
- create_decoder_from_filename( filename );
- }
-
- explicit wic_image( char const * const filename )
- {
- create_decoder_from_filename( detail::wide_path( filename ) );
- }
-
- // The passed IStream object must outlive the wic_image object (to support
- // lazy evaluation).
- explicit wic_image( IStream & stream )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromStream( &stream, NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- explicit wic_image( HANDLE const file_handle )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromFileHandle( reinterpret_cast<ULONG_PTR>( file_handle ), NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- // The passed View object must outlive the wic_image object (to support
- // lazy evaluation).
- //...zzz...the same approach as with GDI+ cannot be used with WIC so an IStream approach will be required...
- //template <class View>
- //explicit wic_image( View & view )
- //{
- // ensure_result
- // (
- // wic_factory::singleton().CreateBitmapFromMemory
- // (
- // view.width(),
- // view.height(),
- // view.pixels().row_size(),
- // gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value,
- // get_raw_data( view ),
- // &pBitmap_
- // )
- // );
- // create_first_frame_decoder();
- //}
-
-public:
- point2<std::ptrdiff_t> dimensions() const
- {
- using namespace detail;
- typedef point2<std::ptrdiff_t> result_t;
- aligned_storage<sizeof( result_t ), alignment_of<result_t>::value>::type placeholder;
- result_t & result( *gil_reinterpret_cast<result_t *>( placeholder.address() ) );
- BOOST_STATIC_ASSERT( sizeof( result_t::value_type ) == sizeof( UINT ) );
- verify_result( frame_decoder().GetSize( gil_reinterpret_cast<UINT *>( &result.x ), gil_reinterpret_cast<UINT *>( &result.y ) ) );
- return result;
- }
-
- /*format_t*/WICPixelFormatGUID format() const
- {
- WICPixelFormatGUID pixel_format;
- detail::verify_result( frame_decoder().GetPixelFormat( &pixel_format ) );
- //...zzz...check that it is a supported format...
- return pixel_format;
- }
-
- /*format_t*/WICPixelFormatGUID closest_gil_supported_format() const { return format(); }
-
- image_type_id current_image_format_id() const
- {
- return image_format_id( closest_gil_supported_format() );
- }
-
-public: // Low-level (row, strip, tile) access
- static bool can_do_roi_access() { return true; }
-
- class sequential_row_access_state
- :
- private detail::cumulative_result
- {
- public:
- using detail::cumulative_result::failed;
- void throw_if_error() const { detail::cumulative_result::throw_if_error( "WIC failure" ); }
-
- BOOST_STATIC_CONSTANT( bool, throws_on_error = false );
-
- private:
- sequential_row_access_state( wic_image const & source_image )
- :
- roi_ ( 0, 0, source_image.dimensions().x, 1 ),
- stride_( roi_.X * source_image.pixel_size() )
- {}
-
- private: friend wic_image;
- detail::wic_roi roi_ ;
- UINT const stride_;
- };
-
- sequential_row_access_state begin_sequential_row_access() const { return sequential_row_access_state( *this ); }
-
- void read_row( sequential_row_access_state & state, unsigned char * const p_row_storage ) const
- {
- state.accumulate_equal
- (
- frame_decoder().CopyPixels
- (
- &state.roi_,
- state.stride_,
- state.stride_,
- p_row_storage
- ),
- S_OK
- );
- ++state.roi_.Y;
- }
-
- lib_object_t & lib_object() { return lib_object_; }
-
-private: // Private formatted_image_base interface.
- friend class base_t;
-
- template <class MyView, class TargetView, class Converter>
- void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
-
- using namespace detail;
-
- //...non template related code yet to be extracted...
- point2<std::ptrdiff_t> const & targetDimensions( original_view( view ).dimensions() );
- wic_roi const roi( get_offset<wic_roi::offset_t>( view ), targetDimensions.x, targetDimensions.y );
- com_scoped_ptr<IWICBitmap> p_bitmap;
- ensure_result( wic_factory::singleton().CreateBitmapFromSourceRect( &frame_decoder(), roi.X, roi.Y, roi.Width, roi.Height, &p_bitmap ) );
- com_scoped_ptr<IWICBitmapLock> p_bitmap_lock;
- ensure_result( p_bitmap->Lock( &roi, WICBitmapLockRead, &p_bitmap_lock ) );
- unsigned int buffer_size;
- BYTE * p_buffer;
- verify_result( p_bitmap_lock->GetDataPointer( &buffer_size, &p_buffer ) );
- unsigned int stride;
- verify_result( p_bitmap_lock->GetStride( &stride ) );
- #ifndef NDEBUG
- WICPixelFormatGUID locked_format;
- verify_result( p_bitmap_lock->GetPixelFormat( &locked_format ) );
- BOOST_ASSERT(( locked_format == gil_to_wic_format<typename View::value_type, is_planar<View>::value>::value ));
- #endif
- copy_and_convert_pixels
- (
- interleaved_view
- (
- roi.Width ,
- roi.Height,
- gil_reinterpret_cast_c<typename MyView::value_type const *>( p_buffer ),
- stride
- ),
- view,
- converter
- );
- }
-
-
- void raw_convert_to_prepared_view( view_data_t const & view_data ) const
- {
- BOOST_ASSERT( view_data.format_ != GUID_WICPixelFormatUndefined ); //...zzz...
- using namespace detail;
- com_scoped_ptr<IWICFormatConverter> p_converter;
- ensure_result( wic_factory::singleton().CreateFormatConverter( &p_converter ) );
- ensure_result( p_converter->Initialize( &frame_decoder(), view_data.format_, WICBitmapDitherTypeNone, NULL, 0, WICBitmapPaletteTypeCustom ) );
- ensure_result
- (
- p_converter->CopyPixels
- (
- view_data.p_roi_,
- view_data.stride_,
- view_data.height_ * view_data.stride_ * view_data.pixel_size_,
- view_data.p_buffer_
- )
- );
- }
-
-
- void raw_copy_to_prepared_view( view_data_t const & view_data ) const
- {
- detail::ensure_result
- (
- frame_decoder().CopyPixels
- (
- view_data.p_roi_,
- view_data.stride_,
- view_data.height_ * view_data.stride_ * view_data.pixel_size_,
- view_data.p_buffer_
- )
- );
- }
-
-
- static std::size_t cached_format_size( format_t const format )
- {
- using namespace detail;
- com_scoped_ptr<IWICComponentInfo> p_component_info;
- ensure_result( wic_factory::singleton().CreateComponentInfo( format, &p_component_info ) );
- //com_scoped_ptr<IWICPixelFormatInfo> p_pixel_format_info;
- //p_component_info->QueryInterface( );IID_IWICPixelFormatInfo
- com_scoped_ptr<IWICPixelFormatInfo> const p_pixel_format_info( *p_component_info );
- io_error_if_not( p_pixel_format_info, "WIC failure" );
- unsigned int bits_per_pixel;
- verify_result( p_pixel_format_info->GetBitsPerPixel( &bits_per_pixel ) );
- return bits_per_pixel;
- }
-
-private:
- IWICBitmapFrameDecode & frame_decoder() const { return *lib_object_.first ; }
- IWICBitmapDecoder & wic_decoder () const { return *lib_object_.second; }
-
- void create_decoder_from_filename( wchar_t const * const filename )
- {
- using namespace detail;
- ensure_result( wic_factory::singleton().CreateDecoderFromFilename( filename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
- create_first_frame_decoder();
- }
-
- void create_first_frame_decoder()
- {
- using namespace detail;
- #ifndef NDEBUG
- unsigned int frame_count;
- verify_result( wic_decoder().GetFrameCount( &frame_count ) );
- BOOST_ASSERT( frame_count >= 1 );
- #endif // NDEBUG
- ensure_result( wic_decoder().GetFrame( 0, &lib_object().first ) );
- }
-
-private:
- lib_object_t lib_object_;
-};
-
-
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // wic_image_hpp
+#endif // wic_writer_hpp

Copied: sandbox/gil/boost/gil/extension/io2/writer.hpp (from r68172, /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/writer.hpp 2011-07-27 17:06:49 EDT (Wed, 27 Jul 2011)
@@ -5,7 +5,7 @@
 ///
 /// Base CRTP class for all image implementation classes/backends.
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,39 +15,11 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
+#ifndef writer_hpp__CBE52E51_7B06_4018_996A_63F9B7DF05AC
+#define writer_hpp__CBE52E51_7B06_4018_996A_63F9B7DF05AC
 #pragma once
-#ifndef formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
-#define formatted_image_hpp__C34C1FB0_A4F5_42F3_9318_5805B88CFE49
 //------------------------------------------------------------------------------
-#include "format_tags.hpp"
-#include "detail/platform_specifics.hpp"
-#include "detail/io_error.hpp"
-#include "detail/switch.hpp"
-
-#include "boost/gil/extension/dynamic_image/any_image.hpp"
-#include "boost/gil/extension/io/dynamic_io.hpp" //...zzz...
-#include "boost/gil/packed_pixel.hpp"
-#include "boost/gil/planar_pixel_iterator.hpp"
-#include "boost/gil/planar_pixel_reference.hpp"
-#include "boost/gil/typedefs.hpp"
-
-#include <boost/compressed_pair.hpp>
-#ifdef _DEBUG
-#include <boost/detail/endian.hpp>
-#endif // _DEBUG
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/mpl/integral_c.hpp>
-#include <boost/mpl/map.hpp>
-#include <boost/mpl/vector_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>
-#include <boost/type_traits/decay.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
+
 //------------------------------------------------------------------------------
 namespace boost
 {
@@ -55,116 +27,9 @@
 namespace gil
 {
 //------------------------------------------------------------------------------
-
-struct assert_dimensions_match {};
-struct ensure_dimensions_match {};
-struct synchronize_dimensions {};
-
-struct assert_formats_match {};
-struct ensure_formats_match {};
-struct synchronize_formats {};
-
-#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> >
-{
- packed_channel_value<DestPackedNumBits> operator()( SrcChannelV const src ) const
- {
- typedef packed_channel_value<DestPackedNumBits> DstChannelV;
-
- typedef detail::channel_convert_to_unsigned <SrcChannelV> to_unsigned;
- typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
-
- 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)));
- }
- }
-};
-
-#if defined(BOOST_MSVC)
-# pragma warning( pop )
-#endif
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class offset_view_t
-/// \todo document properly...
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class View, typename Offset>
-class offset_view_t
+namespace io
 {
-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_ ;
- Offset offset_;
-};
+//------------------------------------------------------------------------------
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -172,67 +37,37 @@
 /// ( forward declaration )
 ////////////////////////////////////////////////////////////////////////////////
 
-template <class Impl>
+template <class Backend>
 struct formatted_image_traits;
 
 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 get_offset( View const & ) { return Offset(); }
-template <typename Offset, class View>
-Offset const & get_offset( offset_view_t<View, Offset> const & offset_view ) { return offset_view.offset(); }
-
-template <typename Offset>
-Offset get_offset_x( Offset const & ) { return Offset(); }
-template <typename Offset>
-Offset const & get_offset_x( point2<Offset> const & offset ) { return offset.x; }
-
-template <typename Offset>
-Offset get_offset_y( Offset const & offset ) { return offset; }
-template <typename Offset>
-Offset const & get_offset_y( point2<Offset> const & offset ) { return offset.y; }
-
 
-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 )
+template <class Writer, typename Target>
+class writer_extender
+ :
+ public output_device<Target>,
+ public Writer
 {
- 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 <class View>
-struct is_offset_view : mpl::false_ {};
-
-template <class View, typename Offset>
-struct is_offset_view<offset_view_t<View, Offset> > : mpl::true_ {};
-
+public:
+ writer_extender( Target const target )
+ :
+ output_device<Target>( target ),
+ Writer ( output_device<Target>::transform( target ) )
+ {}
 
-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; };
+ writer_extender( Target const target, format_tag const file_format )
+ :
+ output_device<Target>( target ),
+ Writer ( output_device<Target>::transform( target ), file_format )
+ {}
+};
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// Wrappers that normalize wrapper interfaces.
+// Wrappers that normalize writer interfaces.
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -321,827 +156,56 @@
     };
 };
 
+//------------------------------------------------------------------------------
+} // namespace detail
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image_base
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class formatted_image_base : noncopyable
-{
-public:
- typedef point2<std::ptrdiff_t> dimensions_t;
-
- typedef unsigned int image_type_id;
- static image_type_id const unsupported_format = static_cast<image_type_id>( -1 );
-
-public: // Low-level (row, strip, tile) access
- struct sequential_row_access_state { BOOST_STATIC_CONSTANT( bool, throws_on_error = true ); };
-
- static sequential_row_access_state begin_sequential_row_access() { return sequential_row_access_state(); }
-
- static bool can_do_row_access () { return true ; }
- static bool can_do_strip_access() { return false; }
- static bool can_do_tile_access () { return false; }
-
- static bool can_do_roi_access () { return false; }
- static bool can_do_vertical_roi_access() { return true ; }
-
-protected:
- static bool dimensions_mismatch( dimensions_t const & mine, dimensions_t const & other ) { return mine != other; }
- template <class View>
- static bool dimensions_mismatch( dimensions_t const & mine, View const & view ) { 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 )
- {
- // Implementation note:
- // For offset target views all dimensions are allowed as they are
- // intended to load an image in steps so they must be allowed to be
- // smaller. They are also allowed to be bigger to allow GIL users to use
- // fixed 'sub' view, while loading an image in steps, whose size is not
- // an exact divisor of the source image dimensions.
- // The exception is for backends that support only vertical 'ROIs'/
- // offsets, for those the horizontal dimensions must match.
- // (19.09.2010.) (Domagoj Saric)
- //dimensions_t const other( offset_view.dimensions() );
- //return ( other.x < mine.x ) || ( other.y < mine.y );
- return is_pod<Offset>::value ? ( mine.x != offset_view.dimensions().x ) : false;
- }
-
- 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" );
- }
-
- template <class View>
- static void do_ensure_dimensions_match( dimensions_t const & mine, View const & view )
- {
- 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" );
- }
-
- template <typename Image>
- static void do_synchronize_dimensions( Image & image, dimensions_t const & my_dimensions, unsigned int const alignment = 0 )
- {
- image.recreate( my_dimensions, alignment );
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // subview_for_offset()
- // --------------------
- //
- ////////////////////////////////////////////////////////////////////////////
- ///
- /// \brief Locally adjusts a view with a ROI/offset to prevent it exceeding
- /// the image dimensions when 'merged' with its offset. Done here so that
- /// backend classes do not need to handle this.
- /// \internal
- /// \throws nothing
- ///
- ////////////////////////////////////////////////////////////////////////////
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- static View subview_for_offset( dimensions_t const & my_dimensions, offset_view_t<View, Offset> const & offset_view )
- {
- dimensions_t const & target_dimensions( offset_view.original_view().dimensions() );
-
- bool const zero_x_offset( is_pod<Offset>::value );
- if ( zero_x_offset )
- {
- BOOST_ASSERT( get_offset_x( offset_view.offset() ) == 0 );
- BOOST_ASSERT( my_dimensions.x == target_dimensions.x );
- }
-
- unsigned int const width ( zero_x_offset ? target_dimensions.x : (std::min)( my_dimensions.x - get_offset_x( offset_view.offset() ), target_dimensions.x ) );
- unsigned int const height( (std::min)( my_dimensions.y - get_offset_y( offset_view.offset() ), target_dimensions.y ) );
-
- return subimage_view( offset_view.original_view(), 0, 0, width, height );
- }
-
-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;
- template <typename Index>
- result_type operator()( Index const & ) const { BOOST_ASSERT( !"input view format does not match source image format" ); return false; }
- };
-
- struct throw_type_mismatch
- {
- typedef void result_type;
- result_type operator()() const { do_ensure_formats_match( true ); }
- };
-
- template <typename Type, typename SupportedPixelFormats>
- struct check_type_match
- {
- typedef bool result_type;
- template <typename SupportedFormatIndex>
- result_type operator()( SupportedFormatIndex const & ) const
- {
- 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>
- result_type operator()( Index const & ) const
- {
- BOOST_ASSERT( !"Default case must not have been reached!" );
- BF_UNREACHABLE_CODE
- return result_type();
- }
- };
-
- template <typename Images>
- class make_dynamic_image
- {
- public:
- make_dynamic_image( any_image<Images> & image ) : image_( image ) {}
-
- template <class Image>
- Image & apply()
- {
- image_.move_in( Image() );
- return image_. BOOST_NESTED_TEMPLATE _dynamic_cast<Image>();
- }
-
- protected:
- any_image<Images> & image_;
- };
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class formatted_image
-///
-////////////////////////////////////////////////////////////////////////////////
-
-template <class Impl>
-class formatted_image : public formatted_image_base
+template <class Backend, typename Target>
+struct writer_for
 {
-public:
- typedef typename formatted_image_traits<Impl>::format_t format_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;
-
- template <typename PixelType, bool IsPlanar>
- struct native_format
- : formatted_image_traits<Impl>::gil_to_native_format:: BOOST_NESTED_TEMPLATE apply<PixelType, IsPlanar>::type
- {};
-
- template <typename T> struct get_native_format;
-
- template <typename PixelType, typename IsPlanar>
- struct get_native_format<mpl::pair<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar::value> {};
-
- template <typename PixelType, bool IsPlanar>
- struct get_native_format<image<PixelType, IsPlanar> > : native_format<PixelType, IsPlanar > {};
-
- template <typename Locator>
- struct get_native_format<image_view<Locator> > : native_format<typename image_view<Locator>::value_type, is_planar<image_view<Locator> >::value> {};
-
- template <class View>
- struct has_supported_format
- {
- private:
- typedef typename get_original_view_t<View>::type original_view_t;
-
- public:
- typedef typename formatted_image_traits<Impl>:: BOOST_NESTED_TEMPLATE is_supported
- <
- typename original_view_t::value_type,
- is_planar<original_view_t>::value
- > type;
- BOOST_STATIC_CONSTANT( bool, value = type::value );
- };
-
- typedef any_image<supported_pixel_formats> dynamic_image_t;
-
- template <typename Source>
- struct reader_for
- : public mpl::at<typename formatted_image_traits<Impl>::readers, Source>
- {
- // The backend does not seem to provide a reader for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<typename reader_for<Source>::type, mpl::void_>::value ));
- };
-
- template <typename Target>
- struct writer_for
- {
- private:
- typedef typename formatted_image_traits<Impl>::supported_image_formats supported_image_formats;
-
- BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
- BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
-
- typedef typename mpl::at
- <
- typename formatted_image_traits<Impl>::writers,
- Target
- >::type base_writer_t;
-
- // The backend does not seem to provide a writer for the specified target...
- BOOST_STATIC_ASSERT(( !is_same<base_writer_t, mpl::void_>::value ));
-
- typedef typename mpl::if_c
- <
- single_format,
- typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
- base_writer_t
- >::type first_layer_wrapper;
-
- public:
- typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
- <
- first_layer_wrapper,
- Target,
- typename formatted_image_traits<Impl>::writer_view_data_t,
- default_format
- > type;
- };
-
- BOOST_STATIC_CONSTANT( bool, has_full_roi = (is_same<typename roi::offset_t, typename roi::point_t>::value) );
-
-protected:
- typedef formatted_image base_t;
-
- typedef typename formatted_image_traits<Impl>::view_data_t view_data_t;
-
 private:
- template <typename Images, typename dimensions_policy, typename formats_policy>
- class read_dynamic_image : make_dynamic_image<Images>
- {
- private:
- typedef make_dynamic_image<Images> base;
+ typedef typename formatted_image_traits<Backend>::supported_image_formats supported_image_formats;
 
- public:
- typedef void result_type;
+ BOOST_STATIC_CONSTANT( format_tag, default_format = mpl::front<supported_image_formats>::type::value );
+ BOOST_STATIC_CONSTANT( bool , single_format = mpl::size <supported_image_formats>::value == 1 );
 
- read_dynamic_image( any_image<Images> & image, Impl & impl )
- :
- base ( image ),
- impl_( impl )
- {}
-
- template <class Image>
- void apply() { impl_.copy_to( base:: BOOST_NESTED_TEMPLATE apply<Image>(), dimensions_policy(), formats_policy() ); }
+ typedef typename mpl::has_key<typename formatted_image_traits<Backend>::native_sinks, Target>::type supported_by_native_writer_t;
 
- template <typename SupportedFormatIndex>
- void operator()( SupportedFormatIndex const & ) { apply<typename mpl::at<SupportedFormatIndex>::type>(); }
+ // The backend does not seem to provide a writer for the specified target...
+ BOOST_STATIC_ASSERT
+ ((
+ supported_by_native_writer_t::value ||
+ !unknown_output_device<Target>::value
+ ));
+
+ typedef typename mpl::if_
+ <
+ supported_by_native_writer_t,
+ typename Backend::native_writer,
+ detail::writer_extender<typename Backend::device_writer, Target>
+ >::type base_writer_t;
+
+ typedef typename mpl::if_c
+ <
+ single_format,
+ typename base_writer_t:: BOOST_NESTED_TEMPLATE single_format_writer_wrapper<base_writer_t, Target, default_format>,
+ base_writer_t
+ >::type first_layer_wrapper;
 
- private:
- Impl & impl_;
- };
-
- template <typename dimensions_policy, typename formats_policy>
- class write_dynamic_view
- {
- public:
- typedef void result_type;
-
- write_dynamic_view( Impl & impl ) : impl_( impl ) {}
-
- template <class View>
- void apply( View const & view ) { impl_.copy_from( view, dimensions_policy(), formats_policy() ); }
-
- private:
- Impl & impl_;
- };
-
- struct write_is_supported
- {
- template <typename View>
- struct apply : public has_supported_format<View> {};
- };
-
- 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_( unsupported_format ) {}
-
- template <typename ImageIndex>
- void operator()( ImageIndex )
- {
- typedef typename mpl::at<supported_pixel_formats, ImageIndex>::type pixel_format_t;
- format_t const image_format( get_native_format<pixel_format_t>::value );
- if ( image_format == this->format_ )
- {
- BOOST_ASSERT( image_id_ == unsupported_format );
- image_id_ = ImageIndex::value;
- }
- }
-
- format_t const format_ ;
- unsigned int image_id_;
-
- private:
- void operator=( image_id_finder const & );
- };
-
-private:
- // ...zzz...MSVC++ 10 generates code to check whether this == 0...investigate...
- Impl & impl() { BF_ASSUME( this != 0 ); return static_cast<Impl &>( *this ); }
- Impl const & impl() const { BF_ASSUME( this != 0 ); return static_cast<Impl const &>( *this ); }
-
-protected:
- template <typename View>
- bool dimensions_mismatch( View const & view ) const
- {
- return formatted_image_base::dimensions_mismatch( impl().dimensions(), view );
- }
-
- 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 );
- }
-
- template <typename View>
- bool formats_mismatch() const
- {
- return formats_mismatch( get_native_format<typename get_original_view_t<View>::type>::value );
- }
-
- bool formats_mismatch( typename formatted_image_traits<Impl>::format_t const other_format ) const
- {
- return ( other_format != impl().closest_gil_supported_format() ) != false;
- }
-
- 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>( impl().format() );
- }
-
- template <typename View>
- bool can_do_inplace_transform( typename formatted_image_traits<Impl>::format_t const my_format ) const
- {
- return ( impl().cached_format_size( my_format ) == static_cast<std::size_t>( memunit_step( get_original_view_t<View>::type::x_iterator() ) ) );
- }
-
- template <typename View>
- static View const & subview_for_offset( View const & view ) { return view; }
-
- template <typename View, typename Offset>
- View subview_for_offset( offset_view_t<View, Offset> const & offset_view ) const
- {
- return formatted_image_base::subview_for_offset( impl().dimensions(), offset_view );
- }
-
- template <typename View>
- static view_data_t get_view_data( View const & view )
- {
- return view_data_t( view );
- }
-
- template <typename View>
- view_data_t get_view_data( offset_view_t<View, offset_t> const & offset_view ) const
- {
- return view_data_t
- (
- subview_for_offset( offset_view ),
- offset_view.offset()
- );
- }
-
-public: // Low-level (row, strip, tile) access
- std::size_t pixel_size() const
- {
- return impl().cached_format_size( impl().format() );
- }
-
- std::size_t row_size() const
- {
- return impl().pixel_size() * impl().dimensions().x;
- }
-
- // 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 into 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_ != unsupported_format );
- return finder.image_id_;
- }
-
-public: // Views...
- template <typename View>
- void copy_to( View const & view, assert_dimensions_match, assert_formats_match ) const
- {
- BOOST_STATIC_ASSERT( get_original_view_t<View>::type::value_type::is_mutable );
- BOOST_STATIC_ASSERT( has_supported_format<View>::value );
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- BOOST_ASSERT( !impl().formats_mismatch<View>() );
- impl().raw_copy_to_prepared_view( get_view_data( view ) );
- }
-
- template <typename View>
- 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 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 const & view, ensure_dimensions_match, ensure_formats_match ) const
- {
- impl().do_ensure_dimensions_match( view );
- impl().copy_to( view, assert_dimensions_match(), ensure_formats_match() );
- }
-
- template <typename View>
- 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 const & view, assert_dimensions_match, synchronize_formats ) const
- {
- BOOST_ASSERT( !impl().dimensions_mismatch( view ) );
- typedef mpl::bool_
- <
- has_supported_format <View>::value &&
- formatted_image_traits<Impl>::builtin_conversion
- > can_use_raw_t;
- default_convert_to_worker( view, can_use_raw_t() );
- }
-
- template <typename FormatConverter, typename View>
- void copy_to( View const & view, ensure_dimensions_match, FormatConverter & 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 const & view, assert_dimensions_match, FormatConverter & 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
- {
- 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_image( any_image<Images> & im ) const
- {
- switch_<valid_type_id_range_t>
- (
- impl().current_image_format_id(),
- read_dynamic_image<Images, dimensions_policy, formats_policy>( im, *this ),
- throw_type_mismatch()
- );
- }
-
- template <typename Views, typename dimensions_policy, typename formats_policy>
- void copy_from( any_image_view<Views> const & runtime_view, dimensions_policy, formats_policy )
- {
- typedef write_dynamic_view<dimensions_policy, formats_policy> op_t;
- op_t op( *this );
- apply_operation
- (
- runtime_view,
- dynamic_io_fnobj<write_is_supported, op_t>( &op )
- );
- }
-
-public: // Offset factory
- template <class View>
- static
- offset_view_t<View, offset_t>
- offset_view( View const & view, offset_t const offset ) { return offset_view_t<View, offset_t>( view, offset ); }
-
-public: // Utility 'quick-wrappers'...
- template <class Source, class Image>
- static void read( Source const & target, Image & image )
- {
- typedef typename reader_for<typename decay<Source>::type>::type reader_t;
- // The backend does not know how to read from the specified source type.
- BOOST_STATIC_ASSERT(( !is_same<reader_t, mpl::void_>::value ));
- reader_t( target ).copy_to_image( image, synchronize_dimensions(), synchronize_formats() );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> const & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void read( std::basic_string<char_type> & file_name, View const & view )
- {
- read( file_name.c_str(), view );
- }
-
- template <class Target, class View>
- static void write( Target & target, View const & view )
- {
- typedef typename writer_for<Target>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( target, view ).write_default();
- }
-
- template <class Target, class View>
- static void write( Target * p_target, View const & view )
- {
- typedef typename writer_for<Target const *>::type writer_t;
- // The backend does not know how to write to the specified target type.
- BOOST_STATIC_ASSERT(( !is_same<writer_t, mpl::void_>::value ));
- writer_t( p_target, view ).write_default();
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> const & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
- template <typename char_type, class View>
- static void write( std::basic_string<char_type> & file_name, View const & view )
- {
- write( file_name.c_str(), view );
- }
-
-private:
- template <class View, typename CC>
- class in_place_converter_t
- {
- public:
- typedef void result_type;
-
- 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
- {
- typedef typename mpl::at_c<supported_pixel_formats, index>::type::view_t view_t;
- 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 )
- {
- convert_aux( srcP, is_planar<View>() );
- }
-
- void operator=( in_place_converter_t const & other )
- {
- 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 ) ) );
- }
-
- private:
- compressed_pair<CC, View const &> members_;
- };
-
- template <class View, typename CC>
- class generic_converter_t
- {
- public:
- typedef void result_type;
-
- generic_converter_t( Impl const & impl, CC const & cc, View const & 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_. BOOST_NESTED_TEMPLATE 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();
- }
-
- 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>
- 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
- {
- return switch_<valid_type_id_range_t>
- (
- source_view_type_id,
- generic_converter_t<TargetView, CC>
- (
- impl(),
- cc,
- offset_new_view
- (
- // See the note for formatted_image_base::subview_for_offset()...
- subview_for_offset( view ),
- view
- )
- ),
- assert_default_case_not_reached<void>()
- );
- }
-
- template <typename View, typename CC>
- void convert_to_prepared_view( View const & view, CC const & converter ) const
- {
- BOOST_ASSERT( !dimensions_mismatch( view ) );
- convert_to_prepared_view_worker
- (
- view,
- converter,
- mpl::bool_
- <
- is_plain_in_memory_view<typename get_original_view_t<View>::type>::value &&
- has_supported_format < 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 current_format ( impl().closest_gil_supported_format() );
- unsigned int const current_image_format_id( impl().image_format_id( current_format ) );
- if ( can_do_inplace_transform<View>( current_format ) )
- {
- view_data_t view_data( get_view_data( view ) );
- if ( formatted_image_traits<Impl>::builtin_conversion )
- view_data.set_format( current_format );
- else
- BOOST_ASSERT( current_format == impl().format() );
- impl().raw_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 );
- }
-
- template <typename View>
- void default_convert_to_worker( View const & view, mpl::true_ /*can use raw*/ ) const
- {
- impl().raw_convert_to_prepared_view( get_view_data( 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() );
- }
+public:
+ typedef typename base_writer_t:: BOOST_NESTED_TEMPLATE wrapper
+ <
+ first_layer_wrapper,
+ Target,
+ typename formatted_image_traits<Backend>::writer_view_data_t,
+ default_format
+ > type;
 };
 
-
 //------------------------------------------------------------------------------
-} // namespace detail
+} // namespace io
 //------------------------------------------------------------------------------
 } // namespace gil
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // formatted_image_hpp
+#endif // writer_hpp


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