Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r60877 - in sandbox/gil: boost boost/gil boost/gil/extension boost/gil/extension/io2 libs libs/gil libs/gil/doc libs/gil/doc/io2
From: dsaritz_at_[hidden]
Date: 2010-03-27 12:12:06


Author: psiha
Date: 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
New Revision: 60877
URL: http://svn.boost.org/trac/boost/changeset/60877

Log:
First commit: adding a first version of a Windows GDI+ based PNG implementation along with other original implementations from the boost 1.42 release.
Added:
   sandbox/gil/boost/
   sandbox/gil/boost/gil/
   sandbox/gil/boost/gil/extension/
   sandbox/gil/boost/gil/extension/io2/
   sandbox/gil/boost/gil/extension/io2/dynamic_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/extern_lib.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/extern_lib_guard.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/gp_private_png_io.ipp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/io_error.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/jpeg_dynamic_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/jpeg_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/jpeg_io_private.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/png_dynamic_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/png_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/png_io_libpng.ipp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/png_io_private.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/tiff_dynamic_io.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/tiff_io.hpp (contents, props changed)
   sandbox/gil/libs/
   sandbox/gil/libs/gil/
   sandbox/gil/libs/gil/doc/
   sandbox/gil/libs/gil/doc/io2/
   sandbox/gil/libs/gil/doc/io2/readme.txt (contents, props changed)

Added: sandbox/gil/boost/gil/extension/io2/dynamic_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/dynamic_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,80 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+/*************************************************************************************************/
+
+#ifndef GIL_DYNAMIC_IO_H
+#define GIL_DYNAMIC_IO_H
+
+/// \file
+/// \brief Generic io functions for dealing with dynamic images
+//
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated May 30, 2006
+
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/size.hpp>
+#include "../../gil_config.hpp"
+#include "io_error.hpp"
+#include "../dynamic_image/any_image.hpp"
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+template <long N>
+struct construct_matched_t {
+ template <typename Images,typename Pred>
+ static bool apply(any_image<Images>& im,Pred pred) {
+ if (pred.template apply<typename mpl::at_c<Images,N-1>::type>()) {
+ typename mpl::at_c<Images,N-1>::type x;
+ im.move_in(x);
+ return true;
+ } else return construct_matched_t<N-1>::apply(im,pred);
+ }
+};
+template <>
+struct construct_matched_t<0> {
+ template <typename Images,typename Pred>
+ static bool apply(any_image<Images>&,Pred) {return false;}
+};
+
+// A function object that can be passed to apply_operation.
+// Given a predicate IsSupported taking a view type and returning an MPL boolean,
+// calls the apply method of OpClass with the view if the given view IsSupported, or throws an exception otherwise
+template <typename IsSupported, typename OpClass>
+class dynamic_io_fnobj {
+ OpClass* _op;
+
+ template <typename View>
+ void apply(const View& view,mpl::true_ ) {_op->apply(view);}
+ template <typename View>
+ void apply(const View& view,mpl::false_) {io_error("dynamic_io: unsupported view type for the given file format");}
+public:
+ dynamic_io_fnobj(OpClass* op) : _op(op) {}
+
+ typedef void result_type;
+
+ template <typename View>
+ void operator()(const View& view) {apply(view,typename IsSupported::template apply<View>::type());}
+};
+
+} // namespace detail
+
+/// \brief Within the any_image, constructs an image with the given dimensions
+/// and a type that satisfies the given predicate
+template <typename Images,typename Pred>
+inline bool construct_matched(any_image<Images>& im,Pred pred) {
+ return detail::construct_matched_t<mpl::size<Images>::value>::apply(im,pred);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/extern_lib.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/extern_lib.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,388 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file extern_lib.hpp
+/// --------------------
+///
+/// BOOST_DELAYED_EXTERN_LIB_GUARD helper macro for reducing boilerplate code
+/// related to dynamic/run-time linking.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef extern_lib_hpp__EAE6695D_91B6_4E14_A3B9_9931BA3FB3B3
+#define extern_lib_hpp__EAE6695D_91B6_4E14_A3B9_9931BA3FB3B3
+//------------------------------------------------------------------------------
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/optional.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/control/expr_if.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/facilities/expand.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/utility/in_place_factory.hpp>
+
+#ifdef _WIN32
+ #include "windows.h"
+#else // _WIN32
+ ...do implement...
+#endif // platform switch
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Configuration macros
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#define BOOST_LIB_LINK_LOADTIME_OR_STATIC 1
+#define BOOST_LIB_LINK_RUNTIME_ASSUME_LOADED 2
+#define BOOST_LIB_LINK_RUNTIME_AUTO_LOAD 3
+
+#define BOOST_LIB_LOADING_STATIC 1
+#define BOOST_LIB_LOADING_SINGLE 2
+#define BOOST_LIB_LOADING_RELOADABLE 3
+
+#define BOOST_LIB_INIT_ASSUME 1
+#define BOOST_LIB_INIT_AUTO 2
+
+// Usage example:
+// #define BOOST_GIL_EXTERNAL_LIB ( BOOST_LIB_LINK_RUNTIME_ASSUME_LOADED, BOOST_LIB_LOADING_RELOADABLE, BOOST_LIB_INIT_AUTO )
+
+
+//...or maybe provide the above options merged...something like this:
+//#define StaticallyLinkAssumeInitialized 0
+//#define StaticallyLinkAutoInitialized 1
+//#define DynamicLinkAssumeLoadedAndInitialized 2
+//#define DynamicLinkAssumeLoadedAutoInitialize 3
+//#define DynamicLinkAutoLoadAutoInitialize 4
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Base guard classes
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class win32_lib_handle : noncopyable
+{
+public:
+ HMODULE lib_handle() const { return lib_handle_; }
+
+ static HMODULE loaded_lib_handle( char const * const lib_name ) { return ::GetModuleHandleA( lib_name ); }
+ static HMODULE loaded_lib_handle( wchar_t const * const lib_name ) { return ::GetModuleHandleW( lib_name ); }
+
+ template <typename T>
+ static T checked_proc_address( HMODULE const lib_handle, char const * const function_name )
+ {
+ BOOST_ASSERT( lib_handle );
+ FARPROC const funcion_address( ::GetProcAddress( lib_handle, function_name ) );
+ BOOST_ASSERT( funcion_address && "Requested function not exported by the library." );
+ return reinterpret_cast<T>( *funcion_address );
+ }
+
+ template <typename T>
+ T checked_proc_address( char const * const function_name ) const
+ {
+ return checked_proc_address<T>( lib_handle(), function_name );
+ }
+
+protected:
+ win32_lib_handle( HMODULE const lib_handle ) : lib_handle_( lib_handle ) {}
+ ~win32_lib_handle() {}
+
+ void ensure() const; //...implement later as desired...
+ void verify() const { BOOST_ASSERT( lib_handle() && "Library not loaded." ); }
+
+private:
+ HMODULE const lib_handle_;
+};
+
+
+class win32_preloaded_reloadable_lib : public win32_lib_handle
+{
+public:
+ win32_preloaded_reloadable_lib( char const * const lib_name ) : win32_lib_handle( loaded_lib_handle( lib_name ) ) { verify(); }
+ win32_preloaded_reloadable_lib( wchar_t const * const lib_name ) : win32_lib_handle( loaded_lib_handle( lib_name ) ) { verify(); }
+};
+
+
+class win32_preloaded_delayloaded_lib
+{
+public:
+ win32_preloaded_delayloaded_lib( char const * const lib_name )
+ {
+ if ( !delayed_lib_.is_initialized() )
+ delayed_lib_ = in_place( lib_name );
+ else
+ BOOST_ASSERT
+ (
+ ( delayed_lib_->lib_handle() == win32_preloaded_reloadable_lib( lib_name ).lib_handle() ) &&
+ "Library reloaded/relocated!"
+ );
+ }
+
+ win32_preloaded_delayloaded_lib( wchar_t const * const lib_name )
+ {
+ if ( !delayed_lib_.is_initialized() )
+ delayed_lib_ = in_place( lib_name );
+ else
+ BOOST_ASSERT
+ (
+ ( delayed_lib_->lib_handle() == win32_preloaded_reloadable_lib( lib_name ).lib_handle() ) &&
+ "Library reloaded/relocated!"
+ );
+ }
+
+ static HMODULE lib_handle() { return delayed_lib_->lib_handle(); }
+
+ static HMODULE loaded_lib_handle( char const * const lib_name )
+ {
+ BOOST_ASSERT( win32_lib_handle::loaded_lib_handle( lib_name ) == lib_handle() );
+ ignore_unused_variable_warning( lib_name );
+ return lib_handle();
+ }
+ static HMODULE loaded_lib_handle( wchar_t const * const lib_name )
+ {
+ BOOST_ASSERT( win32_lib_handle::loaded_lib_handle( lib_name ) == lib_handle() );
+ ignore_unused_variable_warning( lib_name );
+ return lib_handle();
+ }
+
+private:
+ static optional<win32_preloaded_reloadable_lib> delayed_lib_;
+};
+
+__declspec( selectany )
+optional<win32_preloaded_reloadable_lib> win32_preloaded_delayloaded_lib::delayed_lib_;
+
+
+class win32_reloadable_lib_guard : public win32_lib_handle
+{
+public:
+ win32_reloadable_lib_guard( char const * const lib_name ) : win32_lib_handle( ::LoadLibraryA( lib_name ) ) { ensure(); }
+ win32_reloadable_lib_guard( wchar_t const * const lib_name ) : win32_lib_handle( ::LoadLibraryW( lib_name ) ) { ensure(); }
+
+ ~win32_reloadable_lib_guard() { BOOST_VERIFY( ::FreeLibrary( lib_handle() ) ); }
+};
+
+
+class win32_delayloaded_lib_guard
+{
+public:
+ win32_delayloaded_lib_guard( char const * const lib_name )
+ {
+ if ( !delayed_lib_.is_initialized() )
+ delayed_lib_ = in_place( lib_name );
+ else
+ BOOST_ASSERT
+ (
+ ( delayed_lib_->lib_handle() == win32_reloadable_lib_guard( lib_name ).lib_handle() ) &&
+ "Library reloaded/relocated!"
+ );
+ }
+
+ win32_delayloaded_lib_guard( wchar_t const * const lib_name )
+ {
+ if ( !delayed_lib_.is_initialized() )
+ delayed_lib_ = in_place( lib_name );
+ else
+ BOOST_ASSERT
+ (
+ ( delayed_lib_->lib_handle() == win32_reloadable_lib_guard( lib_name ).lib_handle() ) &&
+ "Library reloaded/relocated!"
+ );
+ }
+
+ static HMODULE lib_handle() { return delayed_lib_->lib_handle(); }
+
+ static HMODULE loaded_lib_handle( char const * const lib_name )
+ {
+ BOOST_ASSERT( win32_lib_handle::loaded_lib_handle( lib_name ) == lib_handle() );
+ ignore_unused_variable_warning( lib_name );
+ return lib_handle();
+ }
+ static HMODULE loaded_lib_handle( wchar_t const * const lib_name )
+ {
+ BOOST_ASSERT( win32_lib_handle::loaded_lib_handle( lib_name ) == lib_handle() );
+ ignore_unused_variable_warning( lib_name );
+ return lib_handle();
+ }
+
+private:
+ static optional<win32_reloadable_lib_guard> delayed_lib_;
+};
+
+__declspec( selectany )
+optional<win32_reloadable_lib_guard> win32_delayloaded_lib_guard::delayed_lib_;
+
+
+class dummy_lib_guard
+{
+public:
+ dummy_lib_guard( char const * /*lib_name*/ ) {}
+ dummy_lib_guard( wchar_t const * /*lib_name*/ ) {}
+
+ static HMODULE loaded_lib_handle( char const * const lib_name ) { return win32_lib_handle::loaded_lib_handle( lib_name ); }
+ static HMODULE loaded_lib_handle( wchar_t const * const lib_name ) { return win32_lib_handle::loaded_lib_handle( lib_name ); }
+};
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor section
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#define BOOST_LIB_LINK( option ) BOOST_PP_TUPLE_ELEM( 3, 0, option )
+#define BOOST_LIB_LOADING( option ) BOOST_PP_TUPLE_ELEM( 3, 1, option )
+#define BOOST_LIB_INIT( option ) BOOST_PP_TUPLE_ELEM( 3, 2, option )
+
+#define BOOST_LIB_GUARD_FOR_LINK_TYPE( type ) \
+ BOOST_PP_EXPR_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_LINK( type ), BOOST_LIB_LINK_LOADTIME_OR_STATIC ), \
+ no need for a lib guard with load time or static linking \
+ ) \
+ BOOST_PP_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_INIT( type ), BOOST_LIB_INIT_ASSUME ), \
+ dummy_lib_guard, \
+ BOOST_PP_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_LINK( type ), BOOST_LIB_LINK_RUNTIME_ASSUME_LOADED ), \
+ BOOST_PP_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_LOADING( type ), BOOST_LIB_LOADING_SINGLE ), \
+ win32_preloaded_delayloaded_lib, \
+ win32_preloaded_reloadable_lib \
+ ), \
+ BOOST_PP_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_LOADING( type ), BOOST_LIB_LOADING_SINGLE ), \
+ win32_delayloaded_lib_guard, \
+ win32_reloadable_lib_guard \
+ ) \
+ ) \
+ )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_TYPEDEF_AND_POINTER_WORKER( condition, return_type, call_convention, function_name, parameter_sequence ) \
+ BOOST_PP_EXPR_IF \
+ ( \
+ condition, \
+ typedef return_type ( call_convention & BOOST_PP_CAT( P, function_name ) ) ( BOOST_PP_SEQ_ENUM( parameter_sequence ) ) throw(); \
+ return_type ( call_convention & BOOST_PP_CAT( p, function_name ) ) ( BOOST_PP_SEQ_ENUM( parameter_sequence ) ) throw(); \
+ )
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_TYPEDEF_AND_POINTER( r, dummy, element ) \
+ BOOST_DELAYED_EXTERN_LIB_FUNCTION_TYPEDEF_AND_POINTER_WORKER( BOOST_PP_TUPLE_ELEM( 5, 0, element ), BOOST_PP_TUPLE_ELEM( 5, 1, element ), BOOST_PP_TUPLE_ELEM( 5, 2, element ), BOOST_PP_TUPLE_ELEM( 5, 3, element ), BOOST_PP_TUPLE_ELEM( 5, 4, element ) )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_PARAMETERS( r, data, index, parameter ) \
+ BOOST_PP_COMMA_IF( index ) \
+ parameter BOOST_PP_CAT( prm, index )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_ARGUMENTS( r, data, index, parameter ) \
+ BOOST_PP_COMMA_IF( index ) \
+ BOOST_PP_CAT( prm, index )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_IMPLEMENTATION_WORKER( condition, guard_class_name, return_type, call_convention, function_name, parameter_sequence ) \
+ BOOST_PP_EXPR_IF \
+ ( \
+ condition, \
+ inline __declspec( nothrow ) return_type call_convention function_name( BOOST_PP_SEQ_FOR_EACH_I( BOOST_DELAYED_EXTERN_LIB_FUNCTION_PARAMETERS, 0, parameter_sequence ) ) { \
+ return guard_class_name::lib_functions().BOOST_PP_CAT( p, function_name )( BOOST_PP_SEQ_FOR_EACH_I( BOOST_DELAYED_EXTERN_LIB_FUNCTION_ARGUMENTS, 0, parameter_sequence ) ); } \
+ )
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_IMPLEMENTATION( r, guard_class_name, element ) \
+ BOOST_DELAYED_EXTERN_LIB_FUNCTION_IMPLEMENTATION_WORKER( BOOST_PP_TUPLE_ELEM( 5, 0, element ), guard_class_name, BOOST_PP_TUPLE_ELEM( 5, 1, element ), BOOST_PP_TUPLE_ELEM( 5, 2, element ), BOOST_PP_TUPLE_ELEM( 5, 3, element ), BOOST_PP_TUPLE_ELEM( 5, 4, element ) )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_LOAD_WORKER( function_name ) \
+ BOOST_PP_CAT( p, function_name )( boost::win32_lib_handle::checked_proc_address<BOOST_PP_CAT( P, function_name )>( lib_handle, BOOST_PP_STRINGIZE( function_name ) ) )
+
+#define BOOST_DELAYED_EXTERN_LIB_FUNCTION_LOAD( r, data, index, function_tuple ) \
+ BOOST_PP_EXPR_IF \
+ ( \
+ BOOST_PP_TUPLE_ELEM( 5, 0, function_tuple ), \
+ BOOST_PP_COMMA_IF( index ) \
+ BOOST_DELAYED_EXTERN_LIB_FUNCTION_LOAD_WORKER \
+ ( \
+ BOOST_PP_TUPLE_ELEM( 5, 3, function_tuple ) \
+ ) \
+ )
+
+
+#define BOOST_DELAYED_EXTERN_LIB_GUARD( lib_name, guard_class_name, guard_option, functionSequence ) \
+ class guard_class_name : public boost:: BOOST_LIB_GUARD_FOR_LINK_TYPE( guard_option ) \
+ { \
+ private: \
+ struct functions : ::boost::noncopyable \
+ { \
+ BOOST_PP_SEQ_FOR_EACH( BOOST_DELAYED_EXTERN_LIB_FUNCTION_TYPEDEF_AND_POINTER, 0 , functionSequence ); \
+ \
+ functions( HMODULE const lib_handle ) \
+ : \
+ BOOST_PP_SEQ_FOR_EACH_I( BOOST_DELAYED_EXTERN_LIB_FUNCTION_LOAD, 0 , functionSequence ) \
+ {} \
+ }; \
+ template <int dummy = 0> \
+ struct functions_singleton : ::boost::noncopyable \
+ { \
+ static void create( HMODULE const lib_handle ) \
+ { \
+ if ( !functions_.is_initialized() ) \
+ functions_ = boost::in_place( lib_handle ); \
+ } \
+ static functions const & lib_functions() { return *functions_; } \
+ private: \
+ static boost::optional<functions> functions_; \
+ }; \
+ public: \
+ guard_class_name() : boost:: BOOST_LIB_GUARD_FOR_LINK_TYPE( guard_option ) ( L#lib_name ) \
+ { \
+ BOOST_PP_EXPR_IF \
+ ( \
+ BOOST_PP_EQUAL( BOOST_LIB_INIT( guard_option ), BOOST_LIB_INIT_AUTO ), \
+ functions_singleton<>::create( lib_handle() ); \
+ ) \
+ } \
+ static void init_functions( HMODULE const lib_handle ) { functions_singleton<>::create( lib_handle ); } \
+ static void init_functions() { functions_singleton<>::create( loaded_lib_handle( L#lib_name ) ); } \
+ static functions const & lib_functions() { return functions_singleton<>::lib_functions(); } \
+ }; \
+ \
+template <int dummy> \
+__declspec( selectany ) \
+boost::optional<guard_class_name::functions> guard_class_name::functions_singleton<dummy>::functions_; \
+ \
+BOOST_PP_SEQ_FOR_EACH( BOOST_DELAYED_EXTERN_LIB_FUNCTION_IMPLEMENTATION, guard_class_name, functionSequence ); \
+/**/
+
+
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // extern_lib_hpp

Added: sandbox/gil/boost/gil/extension/io2/extern_lib_guard.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/extern_lib_guard.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,216 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file extern_lib_guard.hpp
+/// --------------------------
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
+#define extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
+//------------------------------------------------------------------------------
+#include "extern_lib.hpp"
+#include "io_error.hpp"
+
+#include <boost/preprocessor/comparison/greater.hpp>
+
+#include "objbase.h"
+#ifdef NOMINMAX
+ // ...yuck... hacks needed because of GDIPlus...
+ #define max(a, b) (((a) > (b)) ? (a) : (b))
+ #define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif // NOMINMAX
+#include "gdiplus.h"
+#ifdef NOMINMAX
+ #undef max
+ #undef min
+#endif // NOMINMAX
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+
+#ifndef BOOST_GIL_USE_NATIVE_IO
+
+ struct gil_io_lib_guard {};
+
+#else // BOOST_GIL_USE_NATIVE_IO
+
+ #ifndef BOOST_GIL_EXTERNAL_LIB
+ //#define BOOST_GIL_EXTERNAL_LIB DynamicLinkAutoLoadAutoInitialize
+ #define BOOST_GIL_EXTERNAL_LIB ( BOOST_LIB_LINK_RUNTIME_AUTO_LOAD, BOOST_LIB_LOADING_RELOADABLE, BOOST_LIB_INIT_AUTO )
+ #endif // BOOST_GIL_EXTERNAL_LIB
+
+
+ #if BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_LINK_LOADTIME_OR_STATIC
+
+ #pragma comment( lib, "gdiplus.lib" )
+ //...consider adding specific version support via embedded manifests like this:
+ //#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.GdiPlus' version='1.1.6001.22170' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"" )
+
+ struct gp_guard_base {};
+
+ namespace detail
+ {
+ typedef dummy_lib_guard gil_io_lib_guard_base;
+ }
+
+ #else // BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_LINK_LOADTIME_OR_STATIC
+
+ } // namespace gil
+
+ inline void win32_lib_handle::ensure() const
+ {
+ gil::io_error_if( !lib_handle(), "Boost.GIL failed to load external library." );
+ }
+
+ } // namespace boost
+
+ namespace Gdiplus
+ {
+ namespace DllExports
+ {
+
+ #define ALWAYS 1
+
+ #if GDIPVER >= 0x0110
+ #define GP1_1 1
+ #else
+ #define GP1_1 0
+ #endif
+
+ #define GP_FUNCTION( function_name ) Gdiplus::GpStatus, WINGDIPAPI, function_name
+
+ BOOST_DELAYED_EXTERN_LIB_GUARD
+ (
+ gdiplus.dll,
+ gp_guard_base,
+ BOOST_GIL_EXTERNAL_LIB,
+ (( ALWAYS, Gdiplus::Status, WINAPI, GdiplusStartup , ( ULONG_PTR * )( const Gdiplus::GdiplusStartupInput * )( Gdiplus::GdiplusStartupOutput * ) ))
+ (( ALWAYS, VOID , WINAPI, GdiplusShutdown , ( ULONG_PTR ) ))
+ (( ALWAYS, GP_FUNCTION( GdipCreateBitmapFromStreamICM ), ( IStream * )( Gdiplus::GpBitmap ** ) ))
+ (( ALWAYS, GP_FUNCTION( GdipCreateBitmapFromFileICM ), ( GDIPCONST WCHAR* )( Gdiplus::GpBitmap ** ) ))
+ (( ALWAYS, GP_FUNCTION( GdipDisposeImage ), ( Gdiplus::GpImage * ) ))
+ (( ALWAYS, GP_FUNCTION( GdipGetImageDimension ), ( Gdiplus::GpImage * )( Gdiplus::REAL * )( Gdiplus::REAL * ) ))
+ (( ALWAYS, GP_FUNCTION( GdipGetImagePixelFormat ), ( Gdiplus::GpImage * )( Gdiplus::PixelFormat * ) ))
+ (( ALWAYS, GP_FUNCTION( GdipBitmapLockBits ), ( Gdiplus::GpBitmap* )( GDIPCONST Gdiplus::GpRect* )( UINT )( Gdiplus::PixelFormat )( Gdiplus::BitmapData* ) ))
+ (( ALWAYS, GP_FUNCTION( GdipBitmapUnlockBits ), ( Gdiplus::GpBitmap* )( Gdiplus::BitmapData* ) ))
+ (( ALWAYS, GP_FUNCTION( GdipSaveImageToFile ), ( Gdiplus::GpImage * )( GDIPCONST WCHAR* )( GDIPCONST CLSID* )( GDIPCONST Gdiplus::EncoderParameters* ) ))
+ (( ALWAYS, GP_FUNCTION( GdipCreateBitmapFromScan0 ), ( INT )( INT )( INT )( Gdiplus::PixelFormat )( BYTE * )( Gdiplus::GpBitmap** ) ))
+ (( GP1_1 , GP_FUNCTION( GdipInitializePalette ), ( OUT Gdiplus::ColorPalette * )( Gdiplus::PaletteType )( INT )( BOOL )( Gdiplus::GpBitmap * ) ))
+ (( GP1_1 , GP_FUNCTION( GdipBitmapConvertFormat ), ( IN Gdiplus::GpBitmap * )( Gdiplus::PixelFormat )( Gdiplus::DitherType )( Gdiplus::PaletteType )( Gdiplus::ColorPalette * )( Gdiplus::REAL ) ))
+ );
+
+ #undef ALWAYS
+ #undef GP1_1
+ #undef GP_FUNCTION
+
+ }
+
+ // ...argh...GDI+ puts all functions in the DllExports namespace (hides the
+ // 'flat API') except the following two. The BOOST_DELAYED_EXTERN_LIB_GUARD
+ // macro does not support that level of customization so we must trivially
+ // reimplement these two here...
+ extern "C" Status WINAPI GdiplusStartup
+ (
+ OUT ULONG_PTR * const token,
+ const GdiplusStartupInput * const input,
+ OUT GdiplusStartupOutput * const output
+ )
+ {
+ return DllExports::GdiplusStartup( token, input, output );
+ }
+
+ extern "C" VOID WINAPI GdiplusShutdown( ULONG_PTR const token )
+ {
+ return DllExports::GdiplusShutdown( token );
+ }
+
+ }
+
+ namespace boost
+ {
+ namespace gil
+ {
+ namespace detail
+ {
+ typedef Gdiplus::DllExports::gp_guard_base gp_guard_base;
+
+ #if BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_LINK_RUNTIME_ASSUME_LOADED
+ // The user/gil_io_lib_guard loads the lib.
+ typedef
+ BOOST_PP_IF
+ (
+ BOOST_PP_GREATER( BOOST_LIB_LOADING( BOOST_GIL_EXTERNAL_LIB ), BOOST_LIB_LOADING_SINGLE ),
+ win32_reloadable_lib_guard,
+ win32_delayloaded_lib_guard
+ ) gil_io_lib_guard_base_helper;
+
+ class gil_io_lib_guard_base : gil_io_lib_guard_base_helper
+ {
+ public:
+ template <typename Char>
+ gil_io_lib_guard_base( Char const * const lib_name )
+ : gil_io_lib_guard_base_helper( lib_name )
+ {
+ #if BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_ASSUME
+ // The user/gil_io_lib_guard inits the lib so it also has to
+ // init the function pointers (required for initialization).
+ gp_guard_base::init_functions( lib_handle() );
+ #endif // BOOST_LIB_INIT_ASSUME
+ }
+ };
+
+ #else // BOOST_LIB_LINK_RUNTIME_AUTO_LOAD
+ // GIL loads the lib automatically every time.
+ typedef dummy_lib_guard gil_io_lib_guard_base;
+
+ #endif // BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB )
+
+ } // namespace detail
+
+ #endif // BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) != BOOST_LIB_LINK_LOADTIME_OR_STATIC
+
+ namespace detail
+ {
+ class gp_initialize_guard : noncopyable
+ {
+ public:
+ gp_initialize_guard();
+ ~gp_initialize_guard();
+ private:
+ ULONG_PTR gp_token_;
+ };
+ } // namespace detail
+
+ class gil_io_lib_guard
+ :
+ detail::gil_io_lib_guard_base
+ #if BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_ASSUME
+ ,detail::gp_initialize_guard
+ #endif // BOOST_LIB_INIT_ASSUME
+ {
+ public:
+ gil_io_lib_guard() : detail::gil_io_lib_guard_base( L"gdiplus.dll" ) {}
+ };
+
+ #undef BOOST_GIL_GUARD_HELPER
+
+#endif // BOOST_GIL_USE_NATIVE_IO
+
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // extern_lib_guard_hpp

Added: sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,785 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file gp_private_base.hpp
+/// -------------------------
+///
+/// Base IO interface GDI+ implementation.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef gp_private_base_hpp__3B1ED5BC_42C6_4EC6_B700_01C1B8646431
+#define gp_private_base_hpp__3B1ED5BC_42C6_4EC6_B700_01C1B8646431
+//------------------------------------------------------------------------------
+#include "../../gil_all.hpp"
+#include "extern_lib_guard.hpp"
+#include "io_error.hpp"
+#include "gp_private_istreams.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
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+
+template <Gdiplus::PixelFormat gp_format> struct is_canonical : mpl::bool_ <(gp_format & PixelFormatCanonical) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct is_extended : mpl::bool_ <(gp_format & PixelFormatExtended ) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct is_indexed : mpl::bool_ <(gp_format & PixelFormatIndexed ) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct is_supported : mpl::bool_ <(gp_format & PixelFormatGDI ) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct has_alpha : mpl::bool_ <(gp_format & PixelFormatAlpha ) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct has_premultiplied_alpha : mpl::bool_ <(gp_format & PixelFormatPAlpha ) != 0> {};
+template <Gdiplus::PixelFormat gp_format> struct pixel_size : mpl::size_t<( gp_format >> 8 ) & 0xff > {};
+
+
+template <typename Channel, typename ColorSpace>
+struct gil_to_gp_format : mpl::integral_c<Gdiplus::PixelFormat, PixelFormatUndefined> {};
+
+template <> struct gil_to_gp_format<bits8 ,rgb_t > : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat24bppRGB > {};
+template <> struct gil_to_gp_format<bits8 ,rgba_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat32bppARGB > {};
+template <> struct gil_to_gp_format<bits16,gray_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppGrayScale> {};
+template <> struct gil_to_gp_format<bits16,rgb_t > : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat48bppRGB > {};
+template <> struct gil_to_gp_format<bits16,rgba_t> : mpl::integral_c<Gdiplus::PixelFormat, PixelFormat64bppARGB > {};
+
+/// @see GdiplusPixelFormats.h: ARGB -> little endian BGRA
+typedef bgra_layout_t gp_alpha_layout_t;
+typedef bgr_layout_t gp_layout_t;
+
+// An attempt to support packed pixel formats...still does not work/compile...:
+typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, gp_layout_t>::type gp_rgb565_pixel_t;
+
+struct unpacked_view_gp_format
+{
+ template <class View>
+ struct apply
+ {
+ typedef gil_to_gp_format
+ <
+ typename channel_type <View>::type,
+ typename color_space_type<View>::type
+ > type;
+ };
+};
+
+struct packed_view_gp_format
+{
+ template <class View>
+ struct apply
+ {
+ typedef typename mpl::if_
+ <
+ is_same<typename View::value_type, gp_rgb565_pixel_t>,
+ mpl::integral_c<Gdiplus::PixelFormat, PixelFormat16bppRGB565>,
+ mpl::integral_c<Gdiplus::PixelFormat, PixelFormatUndefined>
+ >::type type;
+ };
+};
+
+template <class View>
+struct view_gp_format
+ :
+ mpl::eval_if
+ <
+ is_reference<typename View::reference>,
+ mpl::identity<unpacked_view_gp_format>,
+ mpl::identity< packed_view_gp_format>
+ >::type::apply<View>::type
+{};
+
+
+typedef iterator_range<TCHAR const *> string_chunk_t;
+
+
+string_chunk_t error_string( Gdiplus::GpStatus const status )
+{
+ using namespace Gdiplus;
+ switch ( status )
+ {
+ case GenericError : return "Generic GDI+ error";
+ case OutOfMemory : return "Out of memory";
+ case ObjectBusy : return "Object busy";
+ case InsufficientBuffer : return "Insufficient buffer";
+ case NotImplemented : return "Not implemented";
+ case Win32Error : return "Win32 subsystem failure";
+ case Aborted : return "Aborted";
+ case FileNotFound : return "File not found";
+ case ValueOverflow : return "Numeric overflow";
+ case AccessDenied : return "Access denied";
+ case UnknownImageFormat : return "Unknown image format";
+ case FontFamilyNotFound : return "Font family not found";
+ case FontStyleNotFound : return "Font style not found";
+ case NotTrueTypeFont : return "A non TrueType font specified";
+ case UnsupportedGdiplusVersion : return "Unsupported GDI+ version";
+ case PropertyNotFound : return "Specified property does not exist in the image";
+ case PropertyNotSupported : return "Specified property not supported by the format of the image";
+ #if (GDIPVER >= 0x0110)
+ case ProfileNotFound : return "Profile required to save an image in CMYK format not found";
+ #endif //(GDIPVER >= 0x0110)
+ }
+
+ // Programmer errors:
+ switch ( status )
+ {
+ case Ok : assert( !"Should not be called for no error" ); __assume( false );
+ case InvalidParameter : assert( !"Invalid parameter" ); __assume( false );
+ case WrongState : assert( !"Object in wrong state" ); __assume( false );
+ case GdiplusNotInitialized : assert( !"GDI+ not initialized" ); __assume( false );
+
+ default: assert( !"Unknown GDI+ status code." ); __assume( false );
+ }
+}
+
+inline void ensure_result( Gdiplus::GpStatus const result )
+{
+ if ( result != Gdiplus::Ok )
+ io_error( error_string( result ).begin() );
+}
+
+inline void verify_result( Gdiplus::GpStatus const result )
+{
+ BOOST_VERIFY( result == Gdiplus::Ok );
+}
+
+
+inline gp_initialize_guard::gp_initialize_guard()
+{
+ using namespace Gdiplus;
+
+ #if (GDIPVER >= 0x0110)
+ GdiplusStartupInputEx const gp_startup_input( GdiplusStartupNoSetRound, 0, true, true );
+ #else
+ GdiplusStartupInput const gp_startup_input( 0, true, true );
+ #endif //(GDIPVER >= 0x0110)
+ GdiplusStartupOutput gp_startup_output;
+ ensure_result
+ (
+ GdiplusStartup
+ (
+ &gp_token_,
+ &gp_startup_input,
+ &gp_startup_output
+ )
+ );
+}
+
+inline gp_initialize_guard::~gp_initialize_guard()
+{
+ Gdiplus::GdiplusShutdown( gp_token_ );
+}
+
+
+class gp_guard
+ :
+ gp_guard_base
+#if BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_AUTO
+ ,gp_initialize_guard
+#endif
+{
+};
+
+
+#if defined(BOOST_MSVC)
+# pragma warning( push )
+# pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif
+
+class gp_bitmap : gp_guard//, noncopyable
+{
+private:
+ // - GP wants wide-char paths
+ // - we received a narrow-char path
+ // - we are using GP that means we are also using Windows
+ // - on Windows a narrow-char path can only be up to MAX_PATH in length:
+ // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
+ // - it is therefor safe to use a fixed sized/stack buffer...
+ class wide_path
+ {
+ public:
+ explicit wide_path( char const * const pFilename )
+ {
+ BOOST_ASSERT( pFilename );
+ BOOST_ASSERT( std::strlen( pFilename ) < wideFileName_.size() );
+ char const * pSource ( pFilename );
+ WCHAR * pDestination( wideFileName_.begin() );
+ do
+ {
+ *pDestination++ = *pSource;
+ } while ( *pSource++ );
+ BOOST_ASSERT( pDestination < wideFileName_.end() );
+ }
+
+ operator wchar_t const * () const { return wideFileName_.begin(); }
+
+ private:
+ boost::array<wchar_t, MAX_PATH> wideFileName_;
+ };
+
+protected:
+ // This one is intended only for derived classes because GP uses lazy
+ // evaluation of the stream so the stream object must preexist and also
+ // outlive the GpBitmap object.
+ explicit gp_bitmap( IStream & stream )
+ {
+ ensure_result( Gdiplus::DllExports::GdipCreateBitmapFromStreamICM( &stream, &pBitmap_ ) );
+ BOOST_ASSERT( pBitmap_ );
+ }
+
+public:
+ explicit gp_bitmap( wchar_t const * const filename )
+ {
+ ensure_result( Gdiplus::DllExports::GdipCreateBitmapFromFileICM( filename, &pBitmap_ ) );
+ BOOST_ASSERT( pBitmap_ );
+ }
+
+ explicit gp_bitmap( char const * const filename )
+ {
+ ensure_result( Gdiplus::DllExports::GdipCreateBitmapFromFileICM( wide_path( filename ), &pBitmap_ ) );
+ BOOST_ASSERT( pBitmap_ );
+ }
+
+ template <class View>
+ explicit gp_bitmap( View & view )
+ {
+ BOOST_STATIC_ASSERT( is_supported<view_gp_format<View>::value>::value );
+ // http://msdn.microsoft.com/en-us/library/ms536315(VS.85).aspx
+ // stride has to be a multiple of 4 bytes
+ BOOST_ASSERT( !( view.pixels().row_size() % sizeof( Gdiplus::ARGB ) ) );
+
+ ensure_result
+ (
+ Gdiplus::DllExports::GdipCreateBitmapFromScan0
+ (
+ view.width(),
+ view.height(),
+ view.pixels().row_size(),
+ view_gp_format<View>::value,
+ interleaved_view_get_raw_data( view ),
+ &pBitmap_
+ )
+ );
+ BOOST_ASSERT( pBitmap_ );
+ }
+
+ ~gp_bitmap()
+ {
+ verify_result( Gdiplus::DllExports::GdipDisposeImage( pBitmap_ ) );
+ }
+
+public:
+ point2<std::ptrdiff_t> get_dimensions() const
+ {
+ using namespace Gdiplus;
+ REAL width, height;
+ verify_result( Gdiplus::DllExports::GdipGetImageDimension( const_cast<Gdiplus::GpBitmap *>( pBitmap_ ), &width, &height ) );
+ return point2<std::ptrdiff_t>( static_cast<std::ptrdiff_t>( width ), static_cast<std::ptrdiff_t>( height ) );
+ }
+
+ Gdiplus::PixelFormat get_format() const
+ {
+ using namespace Gdiplus;
+ PixelFormat format;
+ verify_result( DllExports::GdipGetImagePixelFormat( pBitmap_, &format ) );
+ return format;
+ }
+
+
+ template <typename View>
+ void convert_to_prepared_view( View const & view ) const
+ {
+ BOOST_STATIC_ASSERT( is_supported<view_gp_format<View>::value>::value );
+
+ BOOST_ASSERT( !dimensions_mismatch( view ) );
+
+ using namespace Gdiplus;
+
+ if ( is_supported<view_gp_format<View>::value>::value )
+ {
+ PixelFormat const desired_format( view_gp_format<View>::value );
+ pre_palettized_conversion<desired_format>( is_indexed<desired_format>::type() );
+ copy_to_target( get_bitmap_data_for_view( view ) );
+ }
+ else
+ {
+ convert_to_prepared_view( view, default_color_converter() );
+ }
+ }
+
+ template <typename View>
+ void convert_to_view( View const & view ) const
+ {
+ ensure_dimensions_match();
+ convert_to_prepared_view( view )
+ }
+
+ template <typename View, typename CC>
+ void convert_to_prepared_view( View const & view, CC const & converter ) const
+ {
+ BOOST_STATIC_ASSERT( is_supported<view_gp_format<View>::value>::value );
+
+ BOOST_ASSERT( !dimensions_mismatch( view ) );
+
+ using namespace Gdiplus;
+
+ PixelFormat const my_format ( get_format() );
+ BitmapData bitmapData( get_bitmap_data_for_view( view ) );
+
+ if ( my_format == view_gp_format<View>::value )
+ {
+ copy_to_target( bitmapData );
+ }
+ else
+ {
+ bool const can_do_in_place( can_do_inplace_transform<typename View::value_type>() );
+ if ( can_do_in_place )
+ {
+ bitmapData.PixelFormat = my_format;
+ copy_to_target( bitmapData );
+ transform( my_format, view, view, converter );
+ }
+ else
+ {
+ BOOST_ASSERT( bitmapData.Scan0 );
+ typedef typename View::value_type pixel_t;
+ pixel_t * const p_raw_view( static_cast<pixel_t *>( bitmapData.Scan0 ) );
+ bitmapData.Scan0 = 0;
+
+ Rect const rect( 0, 0, bitmapData.Width, bitmapData.Height );
+ ensure_result
+ (
+ DllExports::GdipBitmapLockBits
+ (
+ pBitmap_,
+ &rect,
+ ImageLockModeRead,
+ bitmapData.PixelFormat,
+ &bitmapData
+ )
+ );
+ transform
+ (
+ bitmapData.PixelFormat,
+ interleaved_view( bitmapData.Width, bitmapData.Height, p_raw_view, bitmapData.Stride ),
+ view,
+ converter
+ );
+ verify_result( DllExports::GdipBitmapUnlockBits( pBitmap_, &bitmapData ) );
+ }
+ }
+ }
+
+ template <typename View, typename CC>
+ void convert_to_view( View const & view, CC const & converter ) const
+ {
+ ensure_dimensions_match( view );
+ convert_to_prepared_view( view, converter );
+ }
+
+ template <typename View>
+ void copy_to_view( View const & view ) const
+ {
+ ensure_dimensions_match( view );
+ copy_to_prepared_view( view );
+ }
+
+ template <typename View>
+ void copy_to_prepared_view( View const & view ) const
+ {
+ ensure_formats_match<View>();
+ convert_to_prepared_view( view );
+ }
+
+ void save_to_png( char const * const pFilename ) const { save_to( pFilename, png_encoder() ); }
+ void save_to_png( wchar_t const * const pFilename ) const { save_to( pFilename, png_encoder() ); }
+
+private:
+ static CLSID const & png_encoder()
+ {
+ static CLSID const PNG_CLSID = { 0x557cf406, 0x1a04, 0x11d3, 0x9A, 0x73, 0x00, 0x00, 0xF8, 0x1E, 0xF3, 0x2E };
+ return PNG_CLSID;
+ }
+
+ template <typename View>
+ Gdiplus::BitmapData get_bitmap_data_for_view( View const & view ) const
+ {
+ using namespace Gdiplus;
+
+ BitmapData const bitmapData =
+ {
+ view.width(),
+ view.height(),
+ view.pixels().row_size(),
+ view_gp_format<View>::value,
+ interleaved_view_get_raw_data( view ),
+ 0
+ };
+ return bitmapData;
+ }
+
+ void convert_to_target( Gdiplus::BitmapData const & bitmapData ) const
+ {
+ BOOST_ASSERT( bitmapData.Scan0 );
+
+ using namespace Gdiplus;
+
+ BitmapData * const pMutableBitmapData( const_cast<BitmapData *>( &bitmapData ) );
+ // It actually performs faster if only ImageLockModeUserInputBuf is
+ // specified, without ImageLockModeRead. Probably does no locking at all
+ // even though this option is not clearly documented.
+ GpStatus const load_result
+ (
+ DllExports::GdipBitmapLockBits
+ (
+ pBitmap_,
+ 0,
+ ImageLockModeUserInputBuf /* | ImageLockModeRead */,
+ bitmapData.PixelFormat,
+ pMutableBitmapData
+ )
+ );
+ GpStatus const unlock_result( DllExports::GdipBitmapUnlockBits( pBitmap_, pMutableBitmapData ) );
+ ensure_result( load_result );
+ verify_result( unlock_result );
+ }
+
+
+ void copy_to_target( Gdiplus::BitmapData const & bitmapData ) const
+ {
+ BOOST_ASSERT( bitmapData.Width == static_cast<UINT>( get_dimensions().x ) );
+ BOOST_ASSERT( bitmapData.Height == static_cast<UINT>( get_dimensions().y ) );
+ //...this need not hold as it can be used to perform GDI+ default
+ //internal colour conversion...maybe i'll provide another worker
+ //function...
+ //BOOST_ASSERT( bitmapData.PixelFormat == get_format () );
+ convert_to_target( bitmapData );
+ }
+
+ template <Gdiplus::PixelFormat desired_format>
+ void pre_palettized_conversion( mpl::true_ /*is_indexed*/ )
+ {
+ #if (GDIPVER >= 0x0110)
+ // A GDI+ 1.1 (a non-distributable version, distributed with MS Office
+ // 2003 and MS Windows Vista and MS Windows 7) 'enhanced'/'tuned'
+ // version of the conversion routine for indexed/palettized image
+ // formats. Unless/until proven usefull, pretty much still a GDI+ 1.1
+ // tester...
+
+ BOOST_ASSERT( !has_alpha<desired_format>::value && "Is this possible for indexed formats?" );
+ std::size_t const number_of_pixel_bits ( pixel_size<desired_format>::value );
+ std::size_t const number_of_palette_colours( static_cast<std::size_t>( ( 2 << ( number_of_pixel_bits - 1 ) ) - 1 ) );
+ std::size_t const palette_size ( sizeof( ColorPalette ) + number_of_palette_colours * sizeof( ARGB ) );
+ aligned_storage
+ <
+ palette_size,
+ alignment_of<ColorPalette>::value
+ >::type palette_storage;
+ ColorPalette & palette( *static_cast<ColorPalette *>( palette_storage.address() ) );
+ palette.Flags = ( PaletteFlagsHasAlpha * has_alpha<desired_format>::value ) |
+ ( PaletteFlagsGrayScale * is_same<typename color_space_type<View>::type, gray_t>::value );
+ palette.Count = number_of_palette_colours;
+
+ verify_result
+ (
+ DllExports::GdipInitializePalette
+ (
+ &palette,
+ PaletteTypeOptimal,
+ number_of_palette_colours,
+ has_alpha<desired_format>::value,
+ pBitmap_
+ )
+ );
+
+ ensure_result
+ (
+ DllExports::GdipBitmapConvertFormat
+ (
+ pBitmap_,
+ desired_format,
+ DitherTypeErrorDiffusion,
+ PaletteTypeOptimal,
+ &palette,
+ 50
+ )
+ );
+ #endif // (GDIPVER >= 0x0110)
+ }
+
+ template <Gdiplus::PixelFormat desired_format>
+ void pre_palettized_conversion( mpl::false_ /*not is_indexed*/ ) const {}
+
+
+ template <class SourceView, class DestinationView, class CC>
+ static void transform( Gdiplus::PixelFormat const sourceFormat, SourceView const & src, DestinationView const & dst, CC const & converter )
+ {
+ // Reinterpret cast/type punning ugliness is required for dynamic
+ // in-place detection/optimization...to be cleaned up...
+ typedef typename DestinationView::value_type target_pixel_t;
+ switch ( sourceFormat )
+ {
+ case PixelFormat48bppRGB :
+ case PixelFormat24bppRGB :
+ typedef pixel<bits8, gp_layout_t> gp_rgb24_pixel_t;
+ typedef view_type_from_pixel<gp_rgb24_pixel_t, false>::type gp_rgb24_view_t ;
+ transform_pixels
+ (
+ *gil_reinterpret_cast_c<gp_rgb24_view_t const *>( &src ),
+ dst,
+ color_convert_deref_fn
+ <
+ gp_rgb24_pixel_t const &,
+ target_pixel_t,
+ CC
+ >( converter )
+ );
+ break;
+
+ case PixelFormat64bppARGB :
+ case PixelFormat32bppARGB :
+ typedef pixel<bits8, gp_alpha_layout_t> gp_argb32_pixel_t;
+ typedef view_type_from_pixel<gp_argb32_pixel_t, false>::type gp_argb32_view_t ;
+ transform_pixels
+ (
+ *gil_reinterpret_cast_c<gp_argb32_view_t const *>( &src ),
+ dst,
+ color_convert_deref_fn
+ <
+ gp_argb32_pixel_t const &,
+ target_pixel_t,
+ CC
+ >( converter )
+ );
+ break;
+
+ case PixelFormat16bppGrayScale:
+ typedef view_type_from_pixel<gray16_pixel_t, false>::type gp_gray16_view_t ;
+ transform_pixels
+ (
+ *gil_reinterpret_cast_c<gp_gray16_view_t const *>( &src ),
+ dst,
+ color_convert_deref_fn
+ <
+ gray16_ref_t,
+ target_pixel_t,
+ CC
+ >( converter )
+ );
+ break;
+
+ case PixelFormat16bppRGB555 :
+ BOOST_ASSERT( !"What about unused bits?" );
+ typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,5,5>, gp_layout_t>::type gp555_pixel_t ;
+ typedef view_type_from_pixel<gp555_pixel_t, false>::type gp_rgb16_555_view_t;
+ //...this...does not compile...how to specify a layout with an
+ //unused bit?
+ //transform_pixels
+ //(
+ // *gil_reinterpret_cast_c<gp_rgb16_555_view_t const *>( &src ),
+ // dst,
+ // color_convert_deref_fn
+ // <
+ // gp555_pixel_t const &,
+ // target_pixel_t,
+ // CC
+ // >( converter )
+ //);
+ break;
+
+ case PixelFormat16bppRGB565 :
+ BOOST_ASSERT( !"Why does this fail to compile?" );
+ typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, gp_layout_t>::type gp565_pixel_t ;
+ typedef view_type_from_pixel<gp565_pixel_t, false>::type gp_rgb16_565_view_t;
+ //transform_pixels
+ //(
+ // *gil_reinterpret_cast_c<gp_rgb16_565_view_t const *>( &src ),
+ // dst,
+ // color_convert_deref_fn
+ // <
+ // //gp565_pixel_t const &,
+ // //gp_rgb16_565_view_t::reference,
+ // gp565_pixel_t::const_reference,
+ // target_pixel_t,
+ // CC
+ // >( converter )
+ //);
+ break;
+
+ case PixelFormat32bppCMYK :
+ BOOST_ASSERT( !"What about byte order/endianess here?" );
+ typedef view_type_from_pixel<cmyk_t, false>::type gp_cmyk_view_t;
+ //...this...does not compile...
+ //transform_pixels
+ //(
+ // *gil_reinterpret_cast_c<gp_cmyk_view_t const *>( &src ),
+ // dst,
+ // color_convert_deref_fn
+ // <
+ // cmyk_t const &,
+ // target_pixel_t,
+ // CC
+ // >( converter )
+ //);
+ break;
+
+ case PixelFormat64bppPARGB :
+ case PixelFormat32bppPARGB :
+ BOOST_ASSERT( !"What about premultiplied alpha?" );
+ break;
+
+ case PixelFormat16bppARGB1555 :
+ BOOST_ASSERT( !"What about 'high colour with 1 bit alpha?" );
+ break;
+
+ case PixelFormat32bppRGB :
+ BOOST_ASSERT( !"What about 4 byte pixels without alpha?" );
+ break;
+
+ case PixelFormat1bppIndexed :
+ case PixelFormat4bppIndexed :
+ case PixelFormat8bppIndexed :
+ BOOST_ASSERT( !"What about indexed colour?" );
+ break;
+
+ default: BOOST_ASSERT( !"Should not get reached." ); __assume( false );
+ }
+ }
+
+
+ void save_to( char const * const pFilename, CLSID const & encoderID ) const { save_to( wide_path( pFilename ), encoderID ); }
+ void save_to( wchar_t const * const pFilename, CLSID const & encoderID ) const
+ {
+ ensure_result( Gdiplus::DllExports::GdipSaveImageToFile( pBitmap_, pFilename, &encoderID, NULL ) );
+ }
+
+
+ template <typename Pixel>
+ bool can_do_inplace_transform() const
+ {
+ return can_do_inplace_transform<Pixel>( get_format() );
+ }
+
+ template <typename Pixel>
+ bool can_do_inplace_transform( Gdiplus::PixelFormat const my_format ) const
+ {
+ return ( Gdiplus::GetPixelFormatSize( my_format ) == sizeof( Pixel ) );
+ }
+
+
+ template <typename View>
+ bool dimensions_mismatch( View const & view ) const
+ {
+ return dimensions_mismatch( view.dimensions() );
+ }
+
+ bool dimensions_mismatch( point2<std::ptrdiff_t> const & other_dimensions ) const
+ {
+ return other_dimensions != get_dimensions();
+ }
+
+
+ template <typename View>
+ bool formats_mismatch() const
+ {
+ return formats_mismatch( view_gp_format<View>::value );
+ }
+
+ bool formats_mismatch( Gdiplus::PixelFormat const other_format ) const
+ {
+ return other_format != get_format();
+ }
+
+
+ template <typename View>
+ void ensure_dimensions_match( View const & view ) const
+ {
+ ensure_dimensions_match( view.get_dimensions() );
+ }
+
+ void ensure_dimensions_match( point2<std::ptrdiff_t> const & other_dimensions ) const
+ {
+ io_error_if( dimensions_mismatch( other_dimensions ), "input view size does not match source image size" );
+ }
+
+
+ template <typename View>
+ void ensure_formats_match() const
+ {
+ ensure_formats_match( view_gp_format<View>::value );
+ }
+
+ void ensure_formats_match( Gdiplus::PixelFormat const other_format ) const
+ {
+ io_error_if( formats_mismatch( other_format ), "input view type is incompatible with the image type" );
+ }
+
+private:
+ Gdiplus::GpBitmap * /*const*/ pBitmap_;
+};
+
+#if defined(BOOST_MSVC)
+# pragma warning( pop )
+#endif
+
+
+#pragma warning( push )
+#pragma warning( disable : 4355 ) // 'this' used in base member initializer list.
+
+class __declspec( novtable ) gp_memory_bitmap sealed
+ :
+ private MemoryReadStream,
+ public gp_bitmap
+{
+public:
+ gp_memory_bitmap( memory_chunk_t const & in_memory_image )
+ :
+ MemoryReadStream( in_memory_image ),
+ gp_bitmap ( static_cast<IStream &>( *this ) )
+ {
+ }
+};
+
+class __declspec( novtable ) gp_FILE_bitmap sealed
+ :
+ private FileReadStream,
+ public gp_bitmap
+{
+public:
+ explicit gp_FILE_bitmap( FILE * const pFile )
+ :
+ FileReadStream( *pFile ),
+ gp_bitmap ( static_cast<IStream &>( *this ) )
+ {
+ }
+};
+
+#pragma warning( pop )
+
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // gp_private_base_hpp

Added: sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,151 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file gp_private_io.hpp
+/// -----------------------
+///
+/// Base IO interface GDI+ implementation.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef gp_private_io_hpp__7BCE38D9_64FA_4C63_8BAE_FE220717DBB9
+#define gp_private_io_hpp__7BCE38D9_64FA_4C63_8BAE_FE220717DBB9
+//------------------------------------------------------------------------------
+#include "gp_private_base.hpp"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+inline point2<std::ptrdiff_t> read_dimensions( detail::gp_bitmap const & image ) {
+ return image.get_dimensions();
+}
+
+inline point2<std::ptrdiff_t> read_dimensions( char const * const filename ) {
+ return read_dimensions( gp_bitmap( filename ) );
+}
+
+
+template <typename View>
+inline void read_view( gp_bitmap const & image, View const & view ) {
+ image.copy_to_view( view );
+}
+
+template <typename View>
+inline void read_view( char const * const filename, View const & view ) {
+ read_view( gp_bitmap( filename ), view );
+}
+
+
+template <typename Image>
+inline void read_image( gp_bitmap const & gp_image, Image & gil_image ) {
+ gil_image.recreate( gp_image.get_dimensions(), sizeof( Gdiplus::ARGB ) );
+ gp_image.copy_to_prepared_view( view( gil_image ) );
+}
+
+template <typename Image>
+inline void read_image(const char* filename,Image& im) {
+ read_image( gp_bitmap( filename ), im );
+}
+
+template <typename Image>
+inline void read_image( wchar_t const * const filename, Image & im ) {
+ read_image( gp_bitmap( filename ), im );
+}
+
+
+template <typename View,typename CC>
+inline void read_and_convert_view( gp_bitmap const & image, View const & view, CC cc ) {
+ image.convert_to_view( view, cc );
+}
+
+template <typename View,typename CC>
+inline void read_and_convert_view( char const * const filename, View const & view, CC cc ) {
+ read_and_convert_view( gp_bitmap( filename ), view, cc );
+}
+
+
+template <typename View>
+inline void read_and_convert_view( gp_bitmap const & image, View const & view ) {
+ image.convert_to_view( view );
+}
+
+template <typename View>
+inline void read_and_convert_view( const char* filename, const View& view ) {
+ read_and_convert_view( gp_bitmap( filename ), view );
+}
+
+
+template <typename Image,typename CC>
+inline void read_and_convert_image( gp_bitmap const & gp_image, Image & gil_image, CC cc ) {
+ gil_image.recreate( gp_image.get_dimensions(), sizeof( Gdiplus::ARGB ) );
+ gp_image.convert_to_prepared_view( view( gil_image ), cc );
+}
+
+template <typename Image,typename CC>
+inline void read_and_convert_image(const char* filename,Image& im,CC cc) {
+ read_and_convert_image( gp_bitmap( filename ), im, cc );
+}
+
+template <typename Image,typename CC>
+inline void read_and_convert_image( wchar_t const * const filename, Image & im, CC const & cc ) {
+ read_and_convert_image( gp_bitmap( filename ), im, cc );
+}
+
+
+template <typename Image>
+inline void read_and_convert_image( gp_bitmap const & gp_image, Image & gil_image ) {
+ gil_image.recreate( gp_image.get_dimensions(), sizeof( Gdiplus::ARGB ) );
+ gp_image.convert_to_prepared_view( view( gil_image ) );
+}
+
+template <typename Image>
+inline void read_and_convert_image(const char* filename,Image& im) {
+ read_and_convert_image( gp_bitmap( filename ), im );
+}
+
+template <typename Image>
+inline void read_and_convert_image( wchar_t const * const filename, Image & im ) {
+ read_and_convert_image( gp_bitmap( filename ), im );
+}
+
+template <typename Image>
+inline void read_and_convert_image( FILE * pFile, Image & im ) {
+ read_and_convert_image( gp_FILE_bitmap( pFile ), im );
+}
+
+template <typename Image>
+inline void read_and_convert_image( memory_chunk_t const & in_memory_image, Image & im ) {
+ read_and_convert_image( gp_memory_bitmap( in_memory_image ), im );
+}
+
+
+template <typename View>
+inline void png_write_view(const char* filename,const View& view) {
+ detail::gp_bitmap const m( view );
+ m.save_to_png( filename );
+}
+
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // gp_private_io_hpp

Added: sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,380 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file gp_private_istreams.hpp
+/// -----------------------------
+///
+/// Helper IStream implementations for in-memory and FILE base IO.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef gp_private_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
+#define gp_private_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
+//------------------------------------------------------------------------------
+#include <boost/range/iterator_range.hpp>
+
+#include "objbase.h"
+#include "objidl.h"
+#include "unknwn.h"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+#pragma warning( push )
+#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
+/// -----------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class __declspec( novtable ) StreamBase : public IStream, noncopyable
+{
+#ifndef NDEBUG
+protected:
+ StreamBase() : ref_cnt_( 1 ) {}
+ ~StreamBase() { assert( ref_cnt_ == 1 ); }
+#endif // NDEBUG
+
+protected:
+ static HRESULT not_implemented()
+ {
+ assert( !"Should not get called!" );
+ return E_NOTIMPL;
+ }
+
+private: // Not implemented/not required methods.
+ HRESULT STDMETHODCALLTYPE SetSize ( ULARGE_INTEGER /*libNewSize*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE CopyTo ( IStream * /*pstm*/, ULARGE_INTEGER /*cb*/, ULARGE_INTEGER * /*pcbRead*/, ULARGE_INTEGER * /*pcbWritten*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE Commit ( DWORD /*grfCommitFlags*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE Revert ( ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE LockRegion ( ULARGE_INTEGER /*libOffset*/, ULARGE_INTEGER /*cb*/, DWORD /*dwLockType*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE UnlockRegion ( ULARGE_INTEGER /*libOffset*/, ULARGE_INTEGER /*cb*/, DWORD /*dwLockType*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE Clone ( IStream ** /*ppstm*/ ) override { return not_implemented(); }
+ //HRESULT STDMETHODCALLTYPE QueryInterface( REFIID /*iid*/, void ** /*ppvObject*/ ) override { return not_implemented(); }
+
+private: // Not implemented or 'possibly' implemented by derived classes.
+ HRESULT STDMETHODCALLTYPE Read ( void * /*pv*/, ULONG /*cb*/, ULONG * /*pcbRead*/ ) override { return not_implemented(); }
+ HRESULT STDMETHODCALLTYPE Write ( void const * /*pv*/, ULONG /*cb*/, ULONG * /*pcbWritten*/ ) override { return not_implemented(); }
+
+private:
+ HRESULT STDMETHODCALLTYPE Stat( STATSTG * const pstatstg, DWORD const grfStatFlag ) override
+ {
+ assert( pstatstg );
+
+ assert( grfStatFlag & STATFLAG_NONAME );
+
+ std::memset( pstatstg, 0, sizeof( *pstatstg ) );
+
+ if ( !( grfStatFlag & STATFLAG_NONAME ) )
+ {
+ static OLECHAR const name[] = OLESTR( "Boost.GIL" );
+ pstatstg->pwcsName = static_cast<OLECHAR *>( ::CoTaskMemAlloc( sizeof( name ) ) );
+ if ( !pstatstg->pwcsName )
+ return STG_E_INSUFFICIENTMEMORY;
+ std::memcpy( pstatstg->pwcsName, name, sizeof( name ) );
+ }
+
+ pstatstg->type = STGTY_STREAM;
+
+ {
+ 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 );
+ }
+
+ //pstatstg->grfMode : http://msdn.microsoft.com/en-us/library/ms891273.aspx
+
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface( REFIID iid, void ** ppvObject ) override
+ {
+ BOOST_ASSERT( ppvObject );
+ BOOST_ASSERT( iid != __uuidof( IUnknown ) );
+ BOOST_ASSERT( iid != __uuidof( IStream ) );
+ BOOST_ASSERT( iid != __uuidof( ISequentialStream ) );
+
+ ignore_unused_variable_warning( iid );
+ ignore_unused_variable_warning( ppvObject );
+
+ return E_NOINTERFACE;
+ }
+
+
+private: // Dummy reference counting for stack based objects.
+ ULONG STDMETHODCALLTYPE AddRef () override
+ {
+ #ifdef NDEBUG
+ return 0;
+ #else
+ BOOST_ASSERT( ref_cnt_ > 0 );
+ return ++ref_cnt_;
+ #endif // NDEBUG
+ }
+
+ ULONG STDMETHODCALLTYPE Release() override
+ {
+ #ifdef NDEBUG
+ return 0;
+ #else
+ BOOST_ASSERT( ref_cnt_ > 1 );
+ return --ref_cnt_;
+ #endif // NDEBUG
+ }
+
+ void * operator new ( size_t );
+ void operator delete( void * );
+
+#ifndef NDEBUG
+ int ref_cnt_;
+#endif // NDEBUG
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class FileStreamBase
+/// ---------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class __declspec( novtable ) FileStreamBase : public StreamBase
+{
+protected:
+ FileStreamBase( FILE & file ) : file_( file ) {}
+
+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( 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 ) );
+
+ 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_ );
+
+ bool const success( result == 0 );
+ return success ? S_OK : S_FALSE;
+ }
+
+protected:
+ FILE & file_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class FileReadStream
+/// ---------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class FileReadStream : public FileStreamBase
+{
+public:
+ FileReadStream( FILE & file ) : FileStreamBase( 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_ ) );
+ if ( pcbRead )
+ *pcbRead = size_read;
+ return ( size_read == cb ) ? S_OK : S_FALSE;
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class FileWriteStream
+/// ----------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class FileWriteStream : public FileStreamBase
+{
+public:
+ FileWriteStream( FILE & file ) : FileStreamBase( file ) {}
+
+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_ ) );
+ if ( pcbWritten )
+ *pcbWritten = size_written;
+ return ( size_written == cb ) ? S_OK : S_FALSE;
+ }
+};
+
+
+typedef iterator_range<unsigned char const *> memory_chunk_t;
+typedef iterator_range<unsigned char *> writable_memory_chunk_t;
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class MemoryStreamBase
+/// -----------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+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: assert( false ); __assume( false );
+ }
+ }
+
+protected:
+ unsigned char * pCurrentPosition_;
+ writable_memory_chunk_t const memory_chunk_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class MemoryReadStream
+/// -----------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class MemoryReadStream : public MemoryStreamBase
+{
+public:
+ MemoryReadStream( memory_chunk_t const & in_memory_image )
+ :
+ 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
+ {
+ 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;
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class MemoryWriteStream
+/// ------------------------
+///
+////////////////////////////////////////////////////////////////////////////////
+
+class MemoryWriteStream : public MemoryStreamBase
+{
+public:
+ MemoryWriteStream( writable_memory_chunk_t const & in_memory_image )
+ :
+ MemoryStreamBase( in_memory_image ) {}
+
+private:
+ HRESULT STDMETHODCALLTYPE Write( void const * const pv, ULONG const cb, ULONG * const pcbWritten ) override
+ {
+ 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;
+ }
+};
+
+
+#pragma warning( pop )
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // gp_private_istreams_hpp

Added: sandbox/gil/boost/gil/extension/io2/gp_private_png_io.ipp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_png_io.ipp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,66 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file gp_private_png_io.ipp
+/// ---------------------------
+///
+/// Base PNG IO interface GDI+ implementation.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#include "gp_private_io.hpp"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+
+template <typename Source>
+inline point2<std::ptrdiff_t> png_read_dimensions( Source const & source ) {
+ return detail::read_dimensions( source );
+}
+
+
+template <typename View, typename Source>
+inline void png_read_view( Source const & source, View const & view ) {
+ detail::read_view( source, view );
+}
+
+
+template <typename Image, typename Source>
+inline void png_read_image( Source const & source, Image & gil_image ) {
+ detail::read_image( source, gil_image );
+}
+
+
+template <typename View,typename CC, typename Source>
+inline void png_read_and_convert_view( Source const & source, View const & view, CC cc ) {
+ detail::read_and_convert_view( source, view, cc );
+}
+
+
+template <typename Image,typename CC, typename Source>
+inline void png_read_and_convert_image( Source const & source, Image & gil_image, CC cc ) {
+ detail::read_and_convert_image( source, gil_image, cc );
+}
+
+template <typename Image, typename Source>
+inline void png_read_and_convert_image( Source const & source, Image & gil_image ) {
+ detail::read_and_convert_image( source, gil_image );
+}
+
+
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------

Added: sandbox/gil/boost/gil/extension/io2/io_error.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/io_error.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,51 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+/*************************************************************************************************/
+
+#ifndef GIL_IO_ERROR_H
+#define GIL_IO_ERROR_H
+
+/// \file
+/// \brief Handle input-output errors
+/// \author Lubomir Bourdev and Hailin Jin \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated on May 30, 2006
+
+#include <ios>
+#include "../../gil_config.hpp"
+#include <boost/shared_ptr.hpp>
+
+namespace boost { namespace gil {
+
+inline void io_error(const char* descr) { throw std::ios_base::failure(descr); }
+inline void io_error_if(bool expr, const char* descr="") { if (expr) io_error(descr); }
+
+namespace detail {
+ class file_mgr {
+ protected:
+ shared_ptr<FILE> _fp;
+
+ struct null_deleter { void operator()(void const*) const {} };
+ file_mgr(FILE* file) : _fp(file, null_deleter()) {}
+
+ file_mgr(const char* filename, const char* flags) {
+ FILE* fp;
+ io_error_if((fp=fopen(filename,flags))==NULL, "file_mgr: failed to open file");
+ _fp=shared_ptr<FILE>(fp,fclose);
+ }
+
+ public:
+ FILE* get() { return _fp.get(); }
+ };
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/jpeg_dynamic_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/jpeg_dynamic_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,130 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_JPEG_DYNAMIC_IO_H
+#define GIL_JPEG_DYNAMIC_IO_H
+
+/// \file
+/// \brief Support for reading and writing JPEG files
+/// Requires libjpeg
+///
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated June 10, 2006
+
+#include <stdio.h>
+#include <string>
+#include <boost/mpl/bool.hpp>
+#include <boost/shared_ptr.hpp>
+#include "../dynamic_image/dynamic_image_all.hpp"
+#include "io_error.hpp"
+
+#include "jpeg_io.hpp"
+#include "jpeg_io_private.hpp"
+#include "dynamic_io.hpp"
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+struct jpeg_write_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<jpeg_write_support<View>::is_supported> {};
+};
+
+class jpeg_writer_dynamic : public jpeg_writer {
+ int _quality;
+public:
+ jpeg_writer_dynamic(FILE* file, int quality=100) : jpeg_writer(file) , _quality(quality) {}
+ jpeg_writer_dynamic(const char* filename, int quality=100) : jpeg_writer(filename), _quality(quality) {}
+
+ template <typename Views>
+ void write_view(const any_image_view<Views>& runtime_view) {
+ dynamic_io_fnobj<jpeg_write_is_supported, jpeg_writer> op(this);
+ apply_operation(runtime_view,op);
+ }
+};
+
+class jpeg_type_format_checker {
+ J_COLOR_SPACE _color_type;
+public:
+ jpeg_type_format_checker(J_COLOR_SPACE color_type_in) :
+ _color_type(color_type_in) {}
+ template <typename Image>
+ bool apply() {
+ return jpeg_read_support<typename Image::view_t>::color_type==_color_type;
+ }
+};
+
+struct jpeg_read_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<jpeg_read_support<View>::is_supported> {};
+};
+
+class jpeg_reader_dynamic : public jpeg_reader {
+public:
+ jpeg_reader_dynamic(FILE* file) : jpeg_reader(file) {}
+ jpeg_reader_dynamic(const char* filename) : jpeg_reader(filename){}
+
+ template <typename Images>
+ void read_image(any_image<Images>& im) {
+ if (!construct_matched(im,detail::jpeg_type_format_checker(_cinfo.out_color_space))) {
+ io_error("jpeg_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
+ } else {
+ im.recreate(get_dimensions());
+ dynamic_io_fnobj<jpeg_read_is_supported, jpeg_reader> op(this);
+ apply_operation(view(im),op);
+ }
+ }
+};
+
+} // namespace detail
+
+
+/// \ingroup JPEG_IO
+/// \brief reads a JPEG image into a run-time instantiated image
+/// Opens the given JPEG file name, selects the first type in Images whose color space and channel are compatible to those of the image file
+/// and creates a new image of that type with the dimensions specified by the image file.
+/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
+template <typename Images>
+inline void jpeg_read_image(const char* filename,any_image<Images>& im) {
+ detail::jpeg_reader_dynamic m(filename);
+ m.read_image(im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief reads a JPEG image into a run-time instantiated image
+template <typename Images>
+inline void jpeg_read_image(const std::string& filename,any_image<Images>& im) {
+ jpeg_read_image(filename.c_str(),im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name.
+/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
+/// or if it fails to create the file.
+template <typename Views>
+inline void jpeg_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
+ detail::jpeg_writer_dynamic m(filename);
+ m.write_view(runtime_view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name.
+template <typename Views>
+inline void jpeg_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
+ jpeg_write_view(filename.c_str(),runtime_view);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/jpeg_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/jpeg_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,202 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_JPEG_IO_H
+#define GIL_JPEG_IO_H
+
+/// \file
+/// \brief Support for reading and writing JPEG files
+/// Requires libjpeg
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated September 24, 2006
+
+#include <cstdio>
+#include <algorithm>
+#include <string>
+#include <boost/static_assert.hpp>
+#include <boost/shared_ptr.hpp>
+extern "C" {
+#include <jpeglib.h>
+}
+#include "io_error.hpp"
+#include "jpeg_io_private.hpp"
+
+namespace boost { namespace gil {
+
+/// \ingroup JPEG_IO
+/// \brief Determines whether the given view type is supported for reading
+template <typename View>
+struct jpeg_read_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::jpeg_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=
+ (detail::jpeg_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+ BOOST_STATIC_CONSTANT(bool, value=is_supported);
+};
+
+/// \ingroup JPEG_IO
+/// \brief Returns the width and height of the JPEG file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file
+inline point2<std::ptrdiff_t> jpeg_read_dimensions(const char* filename) {
+ detail::jpeg_reader m(filename);
+ return m.get_dimensions();
+}
+
+/// \ingroup JPEG_IO
+/// \brief Returns the width and height of the JPEG file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file
+inline point2<std::ptrdiff_t> jpeg_read_dimensions(const std::string& filename) {
+ return jpeg_read_dimensions(filename.c_str());
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads the image specified by the given jpeg image file name into the given view.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not
+/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
+template <typename View>
+inline void jpeg_read_view(const char* filename,const View& view) {
+ BOOST_STATIC_ASSERT(jpeg_read_support<View>::is_supported);
+
+ detail::jpeg_reader m(filename);
+ m.apply(view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads the image specified by the given jpeg image file name into the given view.
+template <typename View>
+inline void jpeg_read_view(const std::string& filename,const View& view) {
+ jpeg_read_view(filename.c_str(),view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it.
+/// Triggers a compile assert if the image color space or channel depth are not supported by the JPEG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not
+/// compatible with the ones specified by Image
+template <typename Image>
+inline void jpeg_read_image(const char* filename,Image& im) {
+ BOOST_STATIC_ASSERT(jpeg_read_support<typename Image::view_t>::is_supported);
+
+ detail::jpeg_reader m(filename);
+ m.read_image(im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it.
+template <typename Image>
+inline void jpeg_read_image(const std::string& filename,Image& im) {
+ jpeg_read_image(filename.c_str(),im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view.
+template <typename View,typename CC>
+inline void jpeg_read_and_convert_view(const char* filename,const View& view,CC cc) {
+ detail::jpeg_reader_color_convert<CC> m(filename,cc);
+ m.apply(view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view.
+template <typename View>
+inline void jpeg_read_and_convert_view(const char* filename,const View& view) {
+ detail::jpeg_reader_color_convert<default_color_converter> m(filename,default_color_converter());
+ m.apply(view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
+template <typename View,typename CC>
+inline void jpeg_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
+ jpeg_read_and_convert_view(filename.c_str(),view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
+template <typename View>
+inline void jpeg_read_and_convert_view(const std::string& filename,const View& view) {
+ jpeg_read_and_convert_view(filename.c_str(),view);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file
+template <typename Image,typename CC>
+inline void jpeg_read_and_convert_image(const char* filename,Image& im,CC cc) {
+ detail::jpeg_reader_color_convert<CC> m(filename,cc);
+ m.read_image(im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid JPEG file
+template <typename Image>
+inline void jpeg_read_and_convert_image(const char* filename,Image& im) {
+ detail::jpeg_reader_color_convert<default_color_converter> m(filename,default_color_converter());
+ m.read_image(im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
+template <typename Image,typename CC>
+inline void jpeg_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
+ jpeg_read_and_convert_image(filename.c_str(),im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
+template <typename Image>
+inline void jpeg_read_and_convert_image(const std::string& filename,Image& im) {
+ jpeg_read_and_convert_image(filename.c_str(),im);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Determines whether the given view type is supported for writing
+template <typename View>
+struct jpeg_write_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::jpeg_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=
+ (detail::jpeg_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+ BOOST_STATIC_CONSTANT(bool, value=is_supported);
+};
+
+/// \ingroup JPEG_IO
+/// \brief Saves the view to a jpeg file specified by the given jpeg image file name.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension.
+/// Throws std::ios_base::failure if it fails to create the file.
+template <typename View>
+inline void jpeg_write_view(const char* filename,const View& view,int quality=100) {
+ BOOST_STATIC_ASSERT(jpeg_write_support<View>::is_supported);
+
+ detail::jpeg_writer m(filename);
+ m.apply(view,quality);
+}
+
+/// \ingroup JPEG_IO
+/// \brief Saves the view to a jpeg file specified by the given jpeg image file name.
+template <typename View>
+inline void jpeg_write_view(const std::string& filename,const View& view,int quality=100) {
+ jpeg_write_view(filename.c_str(),view,quality);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/jpeg_io_private.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/jpeg_io_private.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,226 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_JPEG_IO_PRIVATE_H
+#define GIL_JPEG_IO_PRIVATE_H
+
+/// \file
+/// \brief Internal support for reading and writing JPEG files
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated September 24, 2006
+
+#include <stdio.h>
+#include <boost/static_assert.hpp>
+#include <vector>
+#include "../../gil_all.hpp"
+#include "io_error.hpp"
+#include <jpeglib.h>
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+// lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated?
+
+template <typename Channel,typename ColorSpace>
+struct jpeg_read_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
+};
+template <>
+struct jpeg_read_support_private<bits8,gray_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
+};
+template <>
+struct jpeg_read_support_private<bits8,rgb_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
+};
+template <>
+struct jpeg_read_support_private<bits8,cmyk_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
+};
+template <typename Channel,typename ColorSpace>
+struct jpeg_write_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
+};
+template <>
+struct jpeg_write_support_private<bits8,gray_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
+};
+template <>
+struct jpeg_write_support_private<bits8,rgb_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
+};
+template <>
+struct jpeg_write_support_private<bits8,cmyk_t> {
+ BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
+};
+
+
+class jpeg_reader : public file_mgr {
+protected:
+ jpeg_decompress_struct _cinfo;
+ jpeg_error_mgr _jerr;
+
+ void init() {
+ _cinfo.err=jpeg_std_error(&_jerr);
+ jpeg_create_decompress(&_cinfo);
+ jpeg_stdio_src(&_cinfo,_fp.get());
+ jpeg_read_header(&_cinfo,TRUE);
+ }
+public:
+ jpeg_reader(FILE* file) : file_mgr(file) { init(); }
+ jpeg_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
+
+ ~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); }
+
+ template <typename View>
+ void apply(const View& view) {
+ jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
+ io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
+ io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type,
+ "jpeg_reader::apply(): input view type does not match the image file");
+ io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
+ std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
+ JSAMPLE* row_address=(JSAMPLE*)&row.front();
+ for(int y=0;y<view.height();++y) {
+ io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
+ "jpeg_reader::apply(): fail to read JPEG file");
+ std::copy(row.begin(),row.end(),view.row_begin(y));
+ }
+ jpeg_finish_decompress(&_cinfo);
+ }
+
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+
+ point2<std::ptrdiff_t> get_dimensions() const {
+ return point2<std::ptrdiff_t>(_cinfo.image_width,_cinfo.image_height);
+ }
+};
+
+// This code will be simplified...
+template <typename CC>
+class jpeg_reader_color_convert : public jpeg_reader {
+private:
+ CC _cc;
+public:
+ jpeg_reader_color_convert(FILE* file,CC cc_in) : jpeg_reader(file),_cc(cc_in) {}
+ jpeg_reader_color_convert(FILE* file) : jpeg_reader(file) {}
+ jpeg_reader_color_convert(const char* filename,CC cc_in) : jpeg_reader(filename),_cc(cc_in) {}
+ jpeg_reader_color_convert(const char* filename) : jpeg_reader(filename) {}
+ template <typename View>
+ void apply(const View& view) {
+ jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
+ io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
+ io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
+ switch (_cinfo.out_color_space) {
+ case JCS_GRAYSCALE: {
+ std::vector<gray8_pixel_t> row(view.width());
+ JSAMPLE* row_address=(JSAMPLE*)&row.front();
+ for(int y=0;y<view.height();++y) {
+ io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
+ "jpeg_reader_color_covert::apply(): fail to read JPEG file");
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t, typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case JCS_RGB: {
+ std::vector<rgb8_pixel_t> row(view.width());
+ JSAMPLE* row_address=(JSAMPLE*)&row.front();
+ for(int y=0;y<view.height();++y) {
+ io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
+ "jpeg_reader_color_covert::apply(): fail to read JPEG file");
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t, typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case JCS_CMYK: {
+ std::vector<cmyk8_pixel_t> row(view.width());
+ JSAMPLE* row_address=(JSAMPLE*)&row.front();
+ for(int y=0;y<view.height();++y) {
+ io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
+ "jpeg_reader_color_covert::apply(): fail to read JPEG file");
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<cmyk8_ref_t, typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default:
+ io_error("jpeg_reader_color_covert::apply(): unknown color type");
+ }
+ jpeg_finish_decompress(&_cinfo);
+ }
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+};
+
+class jpeg_writer : public file_mgr {
+ jpeg_compress_struct _cinfo;
+ jpeg_error_mgr _jerr;
+
+ void init() {
+ _cinfo.err=jpeg_std_error(&_jerr);
+ jpeg_create_compress(&_cinfo);
+ jpeg_stdio_dest(&_cinfo,_fp.get());
+ }
+public:
+ jpeg_writer(FILE* file) : file_mgr(file) { init(); }
+ jpeg_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
+ ~jpeg_writer() { jpeg_destroy_compress(&_cinfo); }
+
+ template <typename View>
+ void apply(const View& view,int quality=100) {
+ _cinfo.image_width = (JDIMENSION)view.width();
+ _cinfo.image_height = (JDIMENSION)view.height();
+ _cinfo.input_components=num_channels<View>::value;
+ _cinfo.in_color_space = jpeg_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type;
+ jpeg_set_defaults(&_cinfo);
+ jpeg_set_quality(&_cinfo, quality, TRUE);
+ jpeg_start_compress(&_cinfo, TRUE);
+ std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
+ JSAMPLE* row_address=(JSAMPLE*)&row.front();
+ for (int y=0;y<view.height(); ++y) {
+ std::copy(view.row_begin(y),view.row_end(y),row.begin());
+ io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
+ "jpeg_writer::apply(): fail to write file");
+ }
+ jpeg_finish_compress(&_cinfo);
+ }
+};
+
+} // namespace detail
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/png_dynamic_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/png_dynamic_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,141 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_PNG_DYNAMIC_IO_H
+#define GIL_PNG_DYNAMIC_IO_H
+
+/// \file
+/// \brief Support for reading and writing PNG files
+/// Requires libpng and zlib!
+///
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated June 10, 2006
+//
+// We are currently providing the following functions:
+// template <typename Images> void png_read_image(const char*,any_image<Images>&)
+// template <typename Images> void png_read_image(FILE*,any_image<Images>&,std::size_t)
+// template <typename Views> void png_write_view(const char*,const any_image_view<View>&)
+// template <typename Views> void png_write_view(FILE*,const any_image_view<View>&)
+
+
+#include <string>
+#include <stdio.h>
+#include <boost/mpl/bool.hpp>
+#include <boost/shared_ptr.hpp>
+#include "../dynamic_image/dynamic_image_all.hpp"
+#include "io_error.hpp"
+#include "png_io.hpp"
+#include "png_io_private.hpp"
+#include "dynamic_io.hpp"
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+struct png_write_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<png_write_support<View>::is_supported> {};
+};
+
+class png_writer_dynamic : public png_writer {
+public:
+ png_writer_dynamic(FILE* file ) : png_writer(file) {}
+ png_writer_dynamic(const char* filename) : png_writer(filename){}
+
+ template <typename Views>
+ void write_view(const any_image_view<Views>& runtime_view) {
+ dynamic_io_fnobj<png_write_is_supported, png_writer> op(this);
+ apply_operation(runtime_view,op);
+ }
+};
+
+class png_type_format_checker {
+ int _bit_depth;
+ int _color_type;
+public:
+ png_type_format_checker(int bit_depth_in,int color_type_in) :
+ _bit_depth(bit_depth_in),_color_type(color_type_in) {}
+ template <typename Image>
+ bool apply() {
+ return png_read_support<typename Image::view_t>::bit_depth==_bit_depth &&
+ png_read_support<typename Image::view_t>::color_type==_color_type;
+ }
+};
+
+struct png_read_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<png_read_support<View>::is_supported> {};
+};
+
+class png_reader_dynamic : public png_reader {
+public:
+ png_reader_dynamic(FILE* file) : png_reader(file) {}
+ png_reader_dynamic(const char* filename) : png_reader(filename){}
+
+ template <typename Images>
+ void read_image(any_image<Images>& im) {
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+ png_get_IHDR(_png_ptr, _info_ptr,
+ &width, &height,&bit_depth,&color_type,&interlace_type,
+ int_p_NULL, int_p_NULL);
+ if (!construct_matched(im,png_type_format_checker(bit_depth,color_type))) {
+ io_error("png_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
+ } else {
+ im.recreate(width,height);
+ dynamic_io_fnobj<png_read_is_supported, png_reader> op(this);
+ apply_operation(view(im),op);
+ }
+ }
+};
+
+} // namespace detail
+
+/// \ingroup PNG_IO
+/// \brief reads a PNG image into a run-time instantiated image
+/// Opens the given png file name, selects the first type in Images whose color space and channel are compatible to those of the image file
+/// and creates a new image of that type with the dimensions specified by the image file.
+/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
+template <typename Images>
+inline void png_read_image(const char* filename,any_image<Images>& im) {
+ detail::png_reader_dynamic m(filename);
+ m.read_image(im);
+}
+
+/// \ingroup PNG_IO
+/// \brief reads a PNG image into a run-time instantiated image
+template <typename Images>
+inline void png_read_image(const std::string& filename,any_image<Images>& im) {
+ png_read_image(filename.c_str(),im);
+}
+
+/// \ingroup PNG_IO
+/// \brief Saves the currently instantiated view to a png file specified by the given png image file name.
+/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
+/// or if it fails to create the file.
+template <typename Views>
+inline void png_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
+ detail::png_writer_dynamic m(filename);
+ m.write_view(runtime_view);
+}
+
+/// \ingroup PNG_IO
+/// \brief Saves the currently instantiated view to a png file specified by the given png image file name.
+template <typename Views>
+inline void png_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
+ png_write_view(filename.c_str(),runtime_view);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/png_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/png_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,169 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_PNG_IO_H
+#define GIL_PNG_IO_H
+
+/// \file
+/// \brief Support for reading and writing PNG files
+/// Requires libpng and zlib! (or GDI+)
+//
+// We are currently providing the following functions:
+// point2<std::ptrdiff_t> png_read_dimensions(const char*)
+// template <typename View> void png_read_view(const char*,const View&)
+// template <typename View> void png_read_image(const char*,image<View>&)
+// template <typename View> void png_write_view(const char*,const View&)
+// template <typename View> struct png_read_support;
+// template <typename View> struct png_write_support;
+//
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated September 24, 2006
+
+#include <cstddef>
+#include <string>
+
+#include "../../gil_config.hpp"
+#include "../../utilities.hpp"
+
+namespace boost { namespace gil {
+
+/// \ingroup PNG_IO
+/// \brief Returns the width and height of the PNG file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file
+template <typename Source>
+point2<std::ptrdiff_t> png_read_dimensions( Source const & );
+
+/// \ingroup PNG_IO
+/// \brief Returns the width and height of the PNG file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file
+inline point2<std::ptrdiff_t> png_read_dimensions(const std::string& filename) {
+ return png_read_dimensions(filename.c_str());
+}
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name into the given view.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
+/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
+template <typename View, typename Source>
+void png_read_view( Source const &, View const & );
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name into the given view.
+template <typename View>
+inline void png_read_view(const std::string& filename,const View& view) {
+ png_read_view(filename.c_str(),view);
+}
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it.
+/// Triggers a compile assert if the image color space or channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
+/// compatible with the ones specified by Image
+template <typename Image, typename Source>
+void png_read_image( Source const &, Image & );
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it.
+template <typename Image>
+inline void png_read_image(const std::string& filename,Image& im) {
+ png_read_image(filename.c_str(),im);
+}
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
+template <typename View, typename CC, typename Source>
+void png_read_and_convert_view( Source const &, View const &, CC );
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
+template <typename View, typename Source>
+void png_read_and_convert_view( Source const &, View const & );
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+template <typename View,typename CC>
+inline void png_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
+ png_read_and_convert_view(filename.c_str(),view,cc);
+}
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+template <typename View>
+inline void png_read_and_convert_view(const std::string& filename,const View& view) {
+ png_read_and_convert_view(filename.c_str(),view);
+}
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid PNG file
+template <typename Image,typename CC, typename Source>
+void png_read_and_convert_image( Source const &, Image &, CC );
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid PNG file
+template <typename Image, typename Source>
+void png_read_and_convert_image( Source const &, Image & );
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+template <typename Image,typename CC>
+inline void png_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
+ png_read_and_convert_image(filename.c_str(),im,cc);
+}
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+template <typename Image>
+inline void png_read_and_convert_image(const std::string& filename,Image& im) {
+ png_read_and_convert_image(filename.c_str(),im);
+}
+
+/// \ingroup PNG_IO
+/// \brief Saves the view to a png file specified by the given png image file name.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if it fails to create the file.
+template <typename View, typename Source>
+void png_write_view( Source const &, View const & );
+
+/// \ingroup PNG_IO
+/// \brief Saves the view to a png file specified by the given png image file name.
+template <typename View>
+inline void png_write_view(const std::string& filename,const View& view) {
+ png_write_view(filename.c_str(),view);
+}
+
+} } // namespace boost::gil
+
+
+#if !defined( _WIN32 )
+ #undef BOOST_GIL_USE_NATIVE_IO
+#endif // (un)supported platforms for native IO
+
+
+#ifdef BOOST_GIL_USE_NATIVE_IO
+
+ #ifdef _WIN32
+ #include "gp_private_png_io.inl"
+ #endif
+
+#else // BOOST_GIL_USE_NATIVE_IO
+
+ #include "png_io_libpng.inl"
+
+#endif // BOOST_GIL_USE_NATIVE_IO
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/png_io_libpng.ipp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/png_io_libpng.ipp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,145 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#include <cstdio>
+#include <string>
+extern "C" {
+#include "png.h"
+}
+#include <boost/static_assert.hpp>
+#include "../../gil_config.hpp"
+#include "../../utilities.hpp"
+#include "io_error.hpp"
+#include "png_io_private.hpp"
+
+namespace boost { namespace gil {
+
+
+/// \ingroup PNG_IO
+/// \brief Returns the width and height of the PNG file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file
+template <typename Source>
+point2<std::ptrdiff_t> png_read_dimensions( Source const & source ) {
+ detail::png_reader m(source);
+ return m.get_dimensions();
+}
+
+/// \ingroup PNG_IO
+/// \brief Determines whether the given view type is supported for reading
+template <typename View>
+struct png_read_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::png_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(int,bit_depth=
+ (detail::png_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth));
+ BOOST_STATIC_CONSTANT(int,color_type=
+ (detail::png_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+ BOOST_STATIC_CONSTANT(bool, value=is_supported);
+};
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name into the given view.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
+/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
+template <typename View, typename Source>
+void png_read_view( Source const & source, View const & view ) {
+ BOOST_STATIC_ASSERT(png_read_support<View>::is_supported);
+ detail::png_reader m(source);
+ m.apply(view);
+}
+
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it.
+/// Triggers a compile assert if the image color space or channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
+/// compatible with the ones specified by Image
+template <typename Image, typename Source>
+void png_read_image( Source const & source, Image & im ) {
+ BOOST_STATIC_ASSERT(png_read_support<typename Image::view_t>::is_supported);
+ detail::png_reader m(source);
+ m.read_image(im);
+}
+
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
+template <typename View, typename CC, typename Source>
+void png_read_and_convert_view( Source const & source, View const & view, CC cc ) {
+ detail::png_reader_color_convert<CC> m(source,cc);
+ m.apply(view);
+}
+
+/// \ingroup PNG_IO
+/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
+/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
+template <typename View, typename Source>
+void png_read_and_convert_view( Source const & source, View const & view ) {
+ detail::png_reader_color_convert<default_color_converter> m(source,default_color_converter());
+ m.apply(view);
+}
+
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid PNG file
+template <typename Image,typename CC, typename Source>
+void png_read_and_convert_image( Source const & source, Image & im, CC cc ) {
+ detail::png_reader_color_convert<CC> m(source,cc);
+ m.read_image(im);
+}
+
+
+/// \ingroup PNG_IO
+/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid PNG file
+template <typename Image, typename Source>
+void png_read_and_convert_image( Source const & source, Image & im ) {
+ detail::png_reader_color_convert<default_color_converter> m(source,default_color_converter());
+ m.read_image(im);
+}
+
+
+/// \ingroup PNG_IO
+/// \brief Determines whether the given view type is supported for writing
+template <typename View>
+struct png_write_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(int,bit_depth=
+ (detail::png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth));
+ BOOST_STATIC_CONSTANT(int,color_type=
+ (detail::png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+ BOOST_STATIC_CONSTANT(bool, value=is_supported);
+};
+
+/// \ingroup PNG_IO
+/// \brief Saves the view to a png file specified by the given png image file name.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
+/// Throws std::ios_base::failure if it fails to create the file.
+template <typename View, typename Source>
+void png_write_view( Source const & source, View const & view ) {
+ BOOST_STATIC_ASSERT(png_write_support<View>::is_supported);
+ detail::png_writer m(source);
+ m.apply(view);
+}
+
+
+} } // namespace boost::gil

Added: sandbox/gil/boost/gil/extension/io2/png_io_private.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/png_io_private.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,360 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://stlab.adobe.com/gil for most recent version including documentation.
+*/
+/*************************************************************************************************/
+
+#ifndef GIL_PNG_IO_PRIVATE_H
+#define GIL_PNG_IO_PRIVATE_H
+
+/// \file
+/// \brief Internal support for reading and writing PNG files
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated August 14, 2007
+
+#include <algorithm>
+#include <vector>
+#include <boost/static_assert.hpp>
+#include "../../gil_all.hpp"
+#include "io_error.hpp"
+#include <png.h>
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+static const std::size_t PNG_BYTES_TO_CHECK = 4;
+
+// lbourdev: These can be greatly simplified, for example:
+template <typename Cs> struct png_color_type {BOOST_STATIC_CONSTANT(int,color_type=0);};
+template<> struct png_color_type<gray_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); };
+template<> struct png_color_type<rgb_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); };
+template<> struct png_color_type<rgba_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); };
+
+template <typename Channel,typename ColorSpace> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=false);};
+template <> struct png_is_supported<bits8,gray_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits8,rgb_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits8,rgba_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits16,gray_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits16,rgb_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits16,rgba_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+
+template <typename Channel> struct png_bit_depth {BOOST_STATIC_CONSTANT(int,bit_depth=sizeof(Channel)*8);};
+
+template <typename Channel,typename ColorSpace>
+struct png_read_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(int,bit_depth=0);
+ BOOST_STATIC_CONSTANT(int,color_type=0);
+};
+template <>
+struct png_read_support_private<bits8,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <>
+struct png_read_support_private<bits8,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
+};
+template <>
+struct png_read_support_private<bits8,rgba_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
+};
+template <>
+struct png_read_support_private<bits16,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <>
+struct png_read_support_private<bits16,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
+};
+template <>
+struct png_read_support_private<bits16,rgba_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
+};
+
+template <typename Channel,typename ColorSpace>
+struct png_write_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(int,bit_depth=0);
+ BOOST_STATIC_CONSTANT(int,color_type=0);
+};
+template <>
+struct png_write_support_private<bits8,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <>
+struct png_write_support_private<bits8,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
+};
+template <>
+struct png_write_support_private<bits8,rgba_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
+};
+template <>
+struct png_write_support_private<bits16,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <>
+struct png_write_support_private<bits16,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
+};
+template <>
+struct png_write_support_private<bits16,rgba_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
+};
+
+class png_reader : public file_mgr {
+protected:
+ png_structp _png_ptr;
+ png_infop _info_ptr;
+
+ void init() {
+ char buf[PNG_BYTES_TO_CHECK];
+ // read in some of the signature bytes
+ io_error_if(fread(buf, 1, PNG_BYTES_TO_CHECK, get()) != detail::PNG_BYTES_TO_CHECK,
+ "png_check_validity: fail to read file");
+ // compare the first PNG_BYTES_TO_CHECK bytes of the signature.
+ io_error_if(png_sig_cmp((png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK)!=0,
+ "png_check_validity: invalid png file");
+
+ _png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
+ io_error_if(_png_ptr==NULL,"png_get_file_size: fail to call png_create_write_struct()");
+ // allocate/initialize the image information data
+ _info_ptr = png_create_info_struct(_png_ptr);
+ if (_info_ptr == NULL) {
+ png_destroy_read_struct(&_png_ptr,png_infopp_NULL,png_infopp_NULL);
+ io_error("png_get_file_size: fail to call png_create_info_struct()");
+ }
+ if (setjmp(png_jmpbuf(_png_ptr))) {
+ //free all of the memory associated with the png_ptr and info_ptr
+ png_destroy_read_struct(&_png_ptr, &_info_ptr, png_infopp_NULL);
+ io_error("png_get_file_size: fail to call setjmp()");
+ }
+ png_init_io(_png_ptr, get());
+ png_set_sig_bytes(_png_ptr,PNG_BYTES_TO_CHECK);
+ png_read_info(_png_ptr, _info_ptr);
+ if (little_endian() && png_get_bit_depth(_png_ptr,_info_ptr)>8)
+ png_set_swap(_png_ptr);
+ }
+public:
+ png_reader(FILE* file ) : file_mgr(file) { init(); }
+ png_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
+
+ ~png_reader() {
+ png_destroy_read_struct(&_png_ptr,&_info_ptr,png_infopp_NULL);
+ }
+ point2<std::ptrdiff_t> get_dimensions() {
+ return point2<std::ptrdiff_t>(png_get_image_width(_png_ptr,_info_ptr),
+ png_get_image_height(_png_ptr,_info_ptr));
+ }
+ template <typename View>
+ void apply(const View& view) {
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+ png_get_IHDR(_png_ptr, _info_ptr,
+ &width, &height,&bit_depth,&color_type,&interlace_type,
+ int_p_NULL, int_p_NULL);
+ io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height),
+ "png_read_view: input view size does not match PNG file size");
+
+ if(png_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth!=bit_depth ||
+ png_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type!=color_type)
+ io_error("png_read_view: input view type is incompatible with the image type");
+
+ std::vector<pixel<typename channel_type<View>::type,
+ layout<typename color_space_type<View>::type> > > row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::copy(row.begin(),row.end(),view.row_begin(y));
+ }
+ png_read_end(_png_ptr,NULL);
+ }
+
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+};
+
+// This code will be simplified...
+template <typename CC>
+class png_reader_color_convert : public png_reader {
+private:
+ CC _cc;
+public:
+ png_reader_color_convert(FILE* file ,CC cc_in) : png_reader(file),_cc(cc_in) {}
+ png_reader_color_convert(FILE* file ) : png_reader(file) {}
+ png_reader_color_convert(const char* filename,CC cc_in) : png_reader(filename),_cc(cc_in) {}
+ png_reader_color_convert(const char* filename) : png_reader(filename) {}
+ template <typename View>
+ void apply(const View& view) {
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+ png_get_IHDR(_png_ptr, _info_ptr,
+ &width, &height,&bit_depth,&color_type,&interlace_type,
+ int_p_NULL, int_p_NULL);
+ io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height),
+ "png_reader_color_convert::apply(): input view size does not match PNG file size");
+ switch (color_type) {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth) {
+ case 8: {
+ std::vector<gray8_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 16: {
+ std::vector<gray16_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ switch (bit_depth) {
+ case 8: {
+ std::vector<rgb8_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 16: {
+ std::vector<rgb16_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
+ }
+ break;
+ case PNG_COLOR_TYPE_RGBA:
+ switch (bit_depth) {
+ case 8: {
+ std::vector<rgba8_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba8_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 16: {
+ std::vector<rgba16_pixel_t> row(width);
+ for(png_uint_32 y=0;y<height;++y) {
+ png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
+ std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba16_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
+ }
+ break;
+ default: io_error("png_reader_color_convert::apply(): unknown color type");
+ }
+ png_read_end(_png_ptr,NULL);
+ }
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+};
+
+
+class png_writer : public file_mgr {
+protected:
+ png_structp _png_ptr;
+ png_infop _info_ptr;
+
+ void init() {
+ _png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
+ io_error_if(!_png_ptr,"png_write_initialize: fail to call png_create_write_struct()");
+ _info_ptr = png_create_info_struct(_png_ptr);
+ if (!_info_ptr) {
+ png_destroy_write_struct(&_png_ptr,png_infopp_NULL);
+ io_error("png_write_initialize: fail to call png_create_info_struct()");
+ }
+ if (setjmp(png_jmpbuf(_png_ptr))) {
+ png_destroy_write_struct(&_png_ptr, &_info_ptr);
+ io_error("png_write_initialize: fail to call setjmp(png_jmpbuf())");
+ }
+ png_init_io(_png_ptr,get());
+ }
+public:
+ png_writer(FILE* file ) : file_mgr(file) { init(); }
+ png_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
+
+ ~png_writer() {
+ png_destroy_write_struct(&_png_ptr,&_info_ptr);
+ }
+ template <typename View>
+ void apply(const View& view) {
+ png_set_IHDR(_png_ptr, _info_ptr, view.width(), view.height(),
+ png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth,
+ png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
+ png_write_info(_png_ptr,_info_ptr);
+ if (little_endian() &&
+ png_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth>8)
+ png_set_swap(_png_ptr);
+ std::vector<pixel<typename channel_type<View>::type,
+ layout<typename color_space_type<View>::type> > > row(view.width());
+ for(int y=0;y<view.height();++y) {
+ std::copy(view.row_begin(y),view.row_end(y),row.begin());
+ png_write_row(_png_ptr,(png_bytep)&row.front());
+ }
+ png_write_end(_png_ptr,_info_ptr);
+ }
+};
+
+} // namespace detail
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/tiff_dynamic_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/tiff_dynamic_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,135 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_TIFF_DYNAMIC_IO_H
+#define GIL_TIFF_DYNAMIC_IO_H
+
+/// \file
+/// \brief Support for reading and writing TIFF files
+/// Requires libtiff!
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated June 10, 2006
+//
+// We are currently providing the following functions:
+// template <typename Images> void tiff_read_image(const char*,any_image<Images>)
+// template <typename Views> void tiff_write_view(const char*,any_image_view<Views>)
+//
+
+#include <string>
+#include <boost/mpl/bool.hpp>
+#include "../dynamic_image/dynamic_image_all.hpp"
+#include "io_error.hpp"
+#include "tiff_io.hpp"
+#include "dynamic_io.hpp"
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+struct tiff_write_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<tiff_write_support<View>::is_supported> {};
+};
+
+class tiff_writer_dynamic : public tiff_writer {
+public:
+ typedef void result_type;
+ tiff_writer_dynamic(const char* filename) : tiff_writer(filename) {}
+
+ template <typename Views>
+ void write_view(const any_image_view<Views>& runtime_view) {
+ dynamic_io_fnobj<tiff_write_is_supported, tiff_writer> op(this);
+ apply_operation(runtime_view,op);
+ }
+};
+
+class tiff_type_format_checker {
+ int _bit_depth;
+ int _color_type;
+public:
+ tiff_type_format_checker(int bit_depth_in,int color_type_in) :
+ _bit_depth(bit_depth_in),_color_type(color_type_in) {}
+ template <typename Image>
+ bool apply() {
+ return tiff_read_support<typename Image::view_t>::bit_depth==_bit_depth &&
+ tiff_read_support<typename Image::view_t>::color_type==_color_type;
+ }
+};
+
+struct tiff_read_is_supported {
+ template<typename View> struct apply
+ : public mpl::bool_<tiff_read_support<View>::is_supported> {};
+};
+
+class tiff_reader_dynamic : public tiff_reader {
+public:
+ tiff_reader_dynamic(const char* filename) : tiff_reader(filename) {}
+
+ template <typename Images>
+ void read_image(any_image<Images>& im) {
+ int width,height;
+ unsigned short bps,photometric;
+ TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH,&width);
+ TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&height);
+ TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps);
+ TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric);
+ if (!construct_matched(im,tiff_type_format_checker(bps,photometric))) {
+ io_error("tiff_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
+ } else {
+ im.recreate(width,height);
+ dynamic_io_fnobj<tiff_read_is_supported, tiff_reader> op(this);
+ apply_operation(view(im),op);
+ }
+ }
+};
+
+} // namespace detail
+
+/// \ingroup TIFF_IO
+/// \brief reads a TIFF image into a run-time instantiated image
+/// Opens the given tiff file name, selects the first type in Images whose color space and channel are compatible to those of the image file
+/// and creates a new image of that type with the dimensions specified by the image file.
+/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
+template <typename Images>
+inline void tiff_read_image(const char* filename,any_image<Images>& im) {
+ detail::tiff_reader_dynamic m(filename);
+ m.read_image(im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief reads a TIFF image into a run-time instantiated image
+template <typename Images>
+inline void tiff_read_image(const std::string& filename,any_image<Images>& im) {
+ tiff_read_image(filename.c_str(),im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name.
+/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
+/// or if it fails to create the file.
+template <typename Views>
+inline void tiff_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
+ detail::tiff_writer_dynamic m(filename);
+ m.write_view(runtime_view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name.
+template <typename Views>
+inline void tiff_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
+ tiff_write_view(filename.c_str(),runtime_view);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/boost/gil/extension/io2/tiff_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/tiff_io.hpp 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,491 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_TIFF_IO_H
+#define GIL_TIFF_IO_H
+
+/// \file
+/// \brief Support for reading and writing TIFF files
+/// Requires libtiff!
+/// \author Hailin Jin and Lubomir Bourdev \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated September 24, 2006
+
+#include <vector>
+#include <string>
+#include <algorithm>
+#include <boost/static_assert.hpp>
+#include <tiffio.h>
+#include "../../gil_all.hpp"
+#include "io_error.hpp"
+
+namespace boost { namespace gil {
+
+namespace detail {
+
+template <typename Channel,typename ColorSpace>
+struct tiff_read_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(int,bit_depth=0);
+ BOOST_STATIC_CONSTANT(int,color_type=0);
+};
+template <>
+struct tiff_read_support_private<bits8,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_read_support_private<bits8,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+template <>
+struct tiff_read_support_private<bits16,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_read_support_private<bits16,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+template <>
+struct tiff_read_support_private<bits32f,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=32);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_read_support_private<bits32f,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=32);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+
+template <typename Channel,typename ColorSpace>
+struct tiff_write_support_private {
+ BOOST_STATIC_CONSTANT(bool,is_supported=false);
+ BOOST_STATIC_CONSTANT(int,bit_depth=0);
+ BOOST_STATIC_CONSTANT(int,color_type=0);
+};
+template <>
+struct tiff_write_support_private<bits8,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_write_support_private<bits8,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=8);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+template <>
+struct tiff_write_support_private<bits16,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_write_support_private<bits16,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=16);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+template <>
+struct tiff_write_support_private<bits32f,gray_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=32);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
+};
+template <>
+struct tiff_write_support_private<bits32f,rgb_t> {
+ BOOST_STATIC_CONSTANT(bool,is_supported=true);
+ BOOST_STATIC_CONSTANT(int,bit_depth=32);
+ BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
+};
+
+class tiff_reader {
+protected:
+ TIFF *_tp;
+public:
+ tiff_reader(const char* filename) {
+ io_error_if((_tp=TIFFOpen(filename,"r"))==NULL,
+ "tiff_reader: fail to open file");
+ }
+ ~tiff_reader() { TIFFClose(_tp); }
+ template <typename View>
+ void apply(const View& view) {
+ unsigned short bps,photometric;
+ point2<std::ptrdiff_t> dims=get_dimensions();
+ io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
+ io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
+ io_error_if(dims!=view.dimensions(),
+ "tiff_read_view: input view size does not match TIFF file size");
+ io_error_if(tiff_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth!=bps ||
+ tiff_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type!=photometric,
+ "tiff_read_view: input view type is incompatible with the image type");
+ std::size_t element_size=sizeof(pixel<typename channel_type<View>::type,
+ layout<typename color_space_type<View>::type> >);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<pixel<typename channel_type<View>::type,
+ layout<typename color_space_type<View>::type> > > row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::copy(row.begin(),row.begin()+view.width(),view.row_begin(y));
+ }
+ }
+ point2<std::ptrdiff_t> get_dimensions() {
+ int w,h;
+ io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH, &w)!=1);
+ io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&h)!=1);
+ return point2<std::ptrdiff_t>(w,h);
+ }
+
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+};
+
+// This code will be simplified...
+template <typename CC>
+class tiff_reader_color_convert : public tiff_reader {
+private:
+ CC _cc;
+public:
+ tiff_reader_color_convert(const char* filename) :
+ tiff_reader(filename) {}
+ tiff_reader_color_convert(const char* filename,CC cc_in) :
+ tiff_reader(filename),_cc(cc_in) {}
+ template <typename View>
+ void apply(const View& view) {
+ point2<std::ptrdiff_t> dims=get_dimensions();
+ unsigned short bps,photometric;
+ io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
+ io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
+ io_error_if(dims!=view.dimensions(),
+ "tiff_reader_color_convert::apply(): input view size does not match TIFF file size");
+ switch (photometric) {
+ case PHOTOMETRIC_MINISBLACK: {
+ switch (bps) {
+ case 8: {
+ std::size_t element_size=sizeof(gray8_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<gray8_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 16: {
+ std::size_t element_size=sizeof(gray16_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<gray16_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 32: {
+ std::size_t element_size=sizeof(gray32f_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<gray32f_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<gray32f_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default:
+ io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
+ }
+ break;
+ }
+ case PHOTOMETRIC_RGB: {
+ switch (bps) {
+ case 8: {
+ std::size_t element_size=sizeof(rgb8_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<rgb8_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 16: {
+ std::size_t element_size=sizeof(rgb16_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<rgb16_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ case 32: {
+ std::size_t element_size=sizeof(rgb32f_pixel_t);
+ std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
+ (std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
+ std::vector<rgb32f_pixel_t> row(size_to_allocate);
+ for (int y=0;y<view.height();++y) {
+ io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
+ std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
+ color_convert_deref_fn<rgb32f_ref_t,typename View::value_type,CC>(_cc));
+ }
+ break;
+ }
+ default:
+ io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
+ }
+ break;
+ }
+ default: {
+ // reads an image in incompatible format via TIFFReadRGBAImage
+ rgba8_image_t rgbaImg(dims);
+ io_error_if(!TIFFReadRGBAImage(_tp, dims.x, dims.y, (uint32*)&gil::view(rgbaImg)(0,0), 0),
+ "tiff_reader_color_convert::unsupported image format");
+ copy_and_convert_pixels(flipped_up_down_view(const_view(rgbaImg)), view, _cc);
+ }
+ }
+ }
+ template <typename Image>
+ void read_image(Image& im) {
+ im.recreate(get_dimensions());
+ apply(view(im));
+ }
+};
+
+class tiff_writer {
+protected:
+ TIFF* _tp;
+public:
+ tiff_writer(const char *filename) {
+ io_error_if((_tp=TIFFOpen(filename,"w"))==NULL,
+ "tiff_writer: fail to open file");
+ }
+ ~tiff_writer() {TIFFClose(_tp);}
+ template <typename View>
+ void apply(const View& view) {
+ io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGELENGTH, view.height())!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGEWIDTH, view.width())!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_PHOTOMETRIC, tiff_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_SAMPLESPERPIXEL,num_channels<View>::value)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth)!=1);
+ io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1);
+ std::vector<pixel<typename channel_type<View>::type,
+ layout<typename color_space_type<View>::type> > > row(view.width());
+ for (int y=0;y<view.height();++y) {
+ std::copy(view.row_begin(y),view.row_end(y),row.begin());
+ io_error_if(TIFFWriteScanline(_tp,&row.front(),y,0)!=1,
+ "tiff_write_view: fail to write file");
+ }
+ }
+};
+
+} // namespace detail
+
+/// \ingroup TIFF_IO
+/// \brief Determines whether the given view type is supported for reading
+template <typename View>
+struct tiff_read_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::tiff_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(int,bit_depth=
+ (detail::tiff_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth));
+ BOOST_STATIC_CONSTANT(int,color_type=
+ (detail::tiff_read_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+};
+
+/// \ingroup TIFF_IO
+/// \brief Returns the width and height of the TIFF file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
+inline point2<std::ptrdiff_t> tiff_read_dimensions(const char* filename) {
+ detail::tiff_reader m(filename);
+ return m.get_dimensions();
+}
+
+/// \ingroup TIFF_IO
+/// \brief Returns the width and height of the TIFF file at the specified location.
+/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
+inline point2<std::ptrdiff_t> tiff_read_dimensions(const std::string& filename) {
+ return tiff_read_dimensions(filename.c_str());
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads the image specified by the given tiff image file name into the given view.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
+/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
+template <typename View>
+inline void tiff_read_view(const char* filename,const View& view) {
+ BOOST_STATIC_ASSERT(tiff_read_support<View>::is_supported);
+ detail::tiff_reader m(filename);
+ m.apply(view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads the image specified by the given tiff image file name into the given view.
+template <typename View>
+inline void tiff_read_view(const std::string& filename,const View& view) {
+ tiff_read_view(filename.c_str(),view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
+/// Triggers a compile assert if the image color space or channel depth are not supported by the TIFF library or by the I/O extension.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
+/// compatible with the ones specified by Image
+template <typename Image>
+void tiff_read_image(const char* filename,Image& im) {
+ BOOST_STATIC_ASSERT(tiff_read_support<typename Image::view_t>::is_supported);
+ detail::tiff_reader m(filename);
+ m.read_image(im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
+template <typename Image>
+inline void tiff_read_image(const std::string& filename,Image& im) {
+ tiff_read_image(filename.c_str(),im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
+template <typename View,typename CC>
+inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc) {
+ detail::tiff_reader_color_convert<CC> m(filename,cc);
+ m.apply(view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
+template <typename View>
+inline void tiff_read_and_convert_view(const char* filename,const View& view) {
+ detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
+ m.apply(view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
+template <typename View,typename CC>
+inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
+ tiff_read_and_convert_view(filename.c_str(),view,cc);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
+template <typename View>
+inline void tiff_read_and_convert_view(const std::string& filename,const View& view) {
+ tiff_read_and_convert_view(filename.c_str(),view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file
+template <typename Image,typename CC>
+void tiff_read_and_convert_image(const char* filename,Image& im,CC cc) {
+ detail::tiff_reader_color_convert<CC> m(filename,cc);
+ m.read_image(im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
+/// Throws std::ios_base::failure if the file is not a valid TIFF file
+template <typename Image>
+void tiff_read_and_convert_image(const char* filename,Image& im) {
+ detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
+ m.read_image(im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
+template <typename Image,typename CC>
+inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
+ tiff_read_and_convert_image(filename.c_str(),im,cc);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
+template <typename Image>
+inline void tiff_read_and_convert_image(const std::string& filename,Image& im) {
+ tiff_read_and_convert_image(filename.c_str(),im);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Determines whether the given view type is supported for writing
+template <typename View>
+struct tiff_write_support {
+ BOOST_STATIC_CONSTANT(bool,is_supported=
+ (detail::tiff_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::is_supported));
+ BOOST_STATIC_CONSTANT(int,bit_depth=
+ (detail::tiff_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::bit_depth));
+ BOOST_STATIC_CONSTANT(int,color_type=
+ (detail::tiff_write_support_private<typename channel_type<View>::type,
+ typename color_space_type<View>::type>::color_type));
+ BOOST_STATIC_CONSTANT(bool, value=is_supported);
+};
+
+/// \ingroup TIFF_IO
+/// \brief Saves the view to a tiff file specified by the given tiff image file name.
+/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
+/// Throws std::ios_base::failure if it fails to create the file.
+template <typename View>
+inline void tiff_write_view(const char* filename,const View& view) {
+ BOOST_STATIC_ASSERT(tiff_write_support<View>::is_supported);
+ detail::tiff_writer m(filename);
+ m.apply(view);
+}
+
+/// \ingroup TIFF_IO
+/// \brief Saves the view to a tiff file specified by the given tiff image file name.
+template <typename View>
+inline void tiff_write_view(const std::string& filename,const View& view) {
+ tiff_write_view(filename.c_str(),view);
+}
+
+} } // namespace boost::gil
+
+#endif

Added: sandbox/gil/libs/gil/doc/io2/readme.txt
==============================================================================
--- (empty file)
+++ sandbox/gil/libs/gil/doc/io2/readme.txt 2010-03-27 12:12:04 EDT (Sat, 27 Mar 2010)
@@ -0,0 +1,14 @@
+This is an attempt at an alternate GIL.IO implementation that
+- provides native backends/implementations
+- provides a more powerfull and low(er) level interface to underlying formats
+- allows more source types for reading 'formatted' images (as opposed to only char const * specified filenames)
+- uses a public class approach (as opposed to current global function wrappers around private implementation classes) with classes that directly provide atleast some sort of a GIL Image/View concept
+- provides adaptors for image/bitmap classes from popular GUI frameworks that turn them into GIL Image/View concepts
+- has other generic improvements in the fields of space/time efficiency and code bloat reduction.
+
+Currently this (alternate) code is based on original code from the
+Boost.GIL.IO official 1.42 release.
+
+Development is currently being done with MSVC++ 9.0 SP1 so no jamfiles are provided yet.
+
+You can contact me/"the author" at dsaritz at gmail.com.
\ No newline at end of file


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