Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64370 - in sandbox/gil/boost/gil/extension/io2: . detail
From: dsaritz_at_[hidden]
Date: 2010-07-26 13:20:11


Author: psiha
Date: 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
New Revision: 64370
URL: http://svn.boost.org/trac/boost/changeset/64370

Log:
Added the WIC backend implementation.
Extracted shared Windows functionality into the new detail/windows_shared.hpp file.
Renamed and moved the gp_private_istreams.hpp header to detail/windows_shared_istreams.hpp.

Reorganized and cleaned up the extern_lib.hpp and gp_extern_lib_guard.hpp headers to better reflect the idea that each backend should have its own guard class/header (if needed).
Added:
   sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp (contents, props changed)
   sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp
      - copied, changed from r64224, /sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp
   sandbox/gil/boost/gil/extension/io2/wic_image.hpp (contents, props changed)
Removed:
   sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp
Text files modified:
   sandbox/gil/boost/gil/extension/io2/detail/extern_lib.hpp | 6 ++
   sandbox/gil/boost/gil/extension/io2/detail/gp_extern_lib_guard.hpp | 82 +++++++++++++++++++++++++------------
   sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp | 11 ++--
   sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp | 88 ++++++---------------------------------
   4 files changed, 82 insertions(+), 105 deletions(-)

Modified: sandbox/gil/boost/gil/extension/io2/detail/extern_lib.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/extern_lib.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/extern_lib.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -382,6 +382,12 @@
 /**/
 
 
+#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
+
+
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------

Modified: sandbox/gil/boost/gil/extension/io2/detail/gp_extern_lib_guard.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/gp_extern_lib_guard.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/gp_extern_lib_guard.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file extern_lib_guard.hpp
-/// --------------------------
+/// \file gp_extern_lib_guard.hpp
+/// -----------------------------
 ///
 /// Copyright (c) Domagoj Saric 2010.
 ///
@@ -13,8 +13,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
 #pragma once
-#ifndef extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
-#define extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
+#ifndef gp_extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
+#define gp_extern_lib_guard_hpp__5C845C6C_F8AE_422B_A041_BA78815FCDD3
 //------------------------------------------------------------------------------
 #include "extern_lib.hpp"
 #include "io_error.hpp"
@@ -40,29 +40,25 @@
 {
 //------------------------------------------------------------------------------
 
-#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
     {
+ struct gp_guard_base {};
+
         typedef dummy_lib_guard gil_io_lib_guard_base;
     }
 
-#else // BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_LINK_LOADTIME_OR_STATIC
+#else // BOOST_LIB_LINK( BOOST_GIL_EXTERNAL_LIB ) != BOOST_LIB_LINK_LOADTIME_OR_STATIC
 
 } // namespace gil
 
+/// \todo This 'configurability' needs to be handled better.
+/// (23.07.2010.) (Domagoj Saric)
 inline void win32_lib_handle::ensure() const
 {
     gil::io_error_if( !lib_handle(), "Boost.GIL failed to load external library." );
@@ -94,12 +90,12 @@
     (( 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( 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 ) ))
@@ -111,15 +107,18 @@
 
 }
 
-// ...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...
+// Implementation note:
+// 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...
+// (23.07.2010.) (Domagoj Saric)
+
 extern "C" Status WINAPI GdiplusStartup
 (
- OUT ULONG_PTR * const token,
- const GdiplusStartupInput * const input,
- OUT GdiplusStartupOutput * const output
+ OUT ULONG_PTR * const token,
+ IN GdiplusStartupInput const * const input,
+ OUT GdiplusStartupOutput * const output
 )
 {
     return DllExports::GdiplusStartup( token, input, output );
@@ -185,6 +184,35 @@
     private:
         ULONG_PTR gp_token_;
     };
+
+ void ensure_result( Gdiplus::GpStatus );
+
+ 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_ );
+ }
+
 } // namespace detail
 
 class gil_io_lib_guard
@@ -204,4 +232,4 @@
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // extern_lib_guard_hpp
+#endif // gp_extern_lib_guard_hpp

Added: sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/detail/wic_extern_lib_guard.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -0,0 +1,98 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file wic_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 wic_extern_lib_guard_hpp__A28436C0_3FEA_4850_9287_656BAAAD6259
+#define wic_extern_lib_guard_hpp__A28436C0_3FEA_4850_9287_656BAAAD6259
+//------------------------------------------------------------------------------
+#include "extern_lib.hpp"
+#include "io_error.hpp"
+
+#include <boost/preprocessor/comparison/greater.hpp>
+
+#define ATLENSURE ATLVERIFY
+#include "atlcomcli.h"
+#include "wincodec.h"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+template <int dummy = 0>
+class wic_factory
+{
+public:
+ static IWICImagingFactory & singleton()
+ {
+ BOOST_ASSERT( p_imaging_factory_ && "WIC not initialized!" );
+ return *p_imaging_factory_;
+ }
+
+ class creator : noncopyable
+ {
+ public:
+ creator()
+ {
+ HRESULT hr( ::CoInitializeEx( 0, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY ) );
+ if
+ (
+ ( ( hr != S_OK ) && ( hr != S_FALSE ) ) ||
+ ( ( hr = wic_factory<>::p_imaging_factory_.CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER ) ) != S_OK )
+ )
+ io_error( "Boost.GIL failed to load external library." ); //...zzz...duplicated...
+ BOOST_ASSERT( wic_factory<>::p_imaging_factory_ );
+ }
+ ~creator()
+ {
+ wic_factory<>::p_imaging_factory_.Release();
+ ::CoUninitialize();
+ }
+ };
+
+private:
+ static CComPtr<IWICImagingFactory> p_imaging_factory_;
+};
+
+template<>
+CComPtr<IWICImagingFactory> wic_factory<>::p_imaging_factory_;
+
+
+#if BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_ASSUME
+
+ typedef wic_factory<>::creator wic_user_guard;
+
+ struct wic_base_guard {};
+
+#else // BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_AUTO
+
+ struct wic_user_guard {};
+
+ typedef wic_factory<>::creator wic_base_guard;
+
+#endif // BOOST_LIB_INIT( BOOST_GIL_EXTERNAL_LIB ) == BOOST_LIB_INIT_AUTO
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // wic_extern_lib_guard_hpp

Added: sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/detail/windows_shared.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -0,0 +1,81 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file windows_shared.hpp
+/// ----------------------------
+///
+/// Common functionality for MS Windows based backends.
+///
+/// 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 windows_shared_hpp__9337A434_D2F6_43F2_93C8_4CE66C07B74D
+#define windows_shared_hpp__9337A434_D2F6_43F2_93C8_4CE66C07B74D
+//------------------------------------------------------------------------------
+#include "boost/array.hpp"
+#include "boost/assert.hpp"
+
+#include <cstring>
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \class wide_path
+///
+////////////////////////////////////////////////////////////////////////////////
+// Implementation note:
+// - GP and WIC want wide-char paths
+// - we received a narrow-char path
+// - we are using GP or WIC which 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 therefore safe to use a fixed sized/stack buffer....
+// (24.07.2010.) (Domagoj Saric)
+////////////////////////////////////////////////////////////////////////////////
+
+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_t * 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_;
+};
+
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // windows_shared_hpp

Copied: sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp (from r64224, /sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp)
==============================================================================
--- /sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/windows_shared_istreams.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \file gp_private_istreams.hpp
-/// -----------------------------
+/// \file windows_shared_istreams.hpp
+/// ---------------------------------
 ///
 /// Helper IStream implementations for in-memory and FILE base IO.
 ///
@@ -16,8 +16,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
 #pragma once
-#ifndef gp_private_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
-#define gp_private_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
+#ifndef windows_shared_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
+#define windows_shared_istreams_hpp__A8D022F0_BBFA_4496_8252_8FD1F6A28DF7
 //------------------------------------------------------------------------------
 #include <boost/range/iterator_range.hpp>
 
@@ -249,6 +249,7 @@
 typedef iterator_range<unsigned char const *> memory_chunk_t;
 typedef iterator_range<unsigned char *> writable_memory_chunk_t;
 
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \class MemoryStreamBase
@@ -377,4 +378,4 @@
 //------------------------------------------------------------------------------
 } // namespace boost
 //------------------------------------------------------------------------------
-#endif // gp_private_istreams_hpp
+#endif // windows_shared_istreams_hpp

Modified: sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/gp_private_base.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -21,8 +21,9 @@
 //------------------------------------------------------------------------------
 #include "../../gil_all.hpp"
 #include "detail/gp_extern_lib_guard.hpp"
+#include "detail/windows_shared.hpp"
+#include "detail/windows_shared_istreams.hpp"
 #include "formatted_image.hpp"
-#include "gp_private_istreams.hpp"
 #include "io_error.hpp"
 
 #include <boost/array.hpp>
@@ -101,7 +102,7 @@
 typedef iterator_range<TCHAR const *> string_chunk_t;
 
 
-string_chunk_t error_string( Gdiplus::GpStatus const status )
+/*string_chunk_t*/char const * error_string( Gdiplus::GpStatus const status )
 {
     using namespace Gdiplus;
     switch ( status )
@@ -131,19 +132,19 @@
     // 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 );
+ case Ok : BOOST_ASSERT( !"Should not be called for no error" ); __assume( false ); break;
+ case InvalidParameter : BOOST_ASSERT( !"Invalid parameter" ); __assume( false ); break;
+ case WrongState : BOOST_ASSERT( !"Object in wrong state" ); __assume( false ); break;
+ case GdiplusNotInitialized : BOOST_ASSERT( !"GDI+ not initialized" ); __assume( false ); break;
 
- default: assert( !"Unknown GDI+ status code." ); __assume( false );
+ default: BOOST_ASSERT( !"Unknown GDI+ status code." ); __assume( false ); break;
     }
 }
 
 inline void ensure_result( Gdiplus::GpStatus const result )
 {
     if ( result != Gdiplus::Ok )
- io_error( error_string( result ).begin() );
+ io_error( error_string( result )/*.begin()*/ );
 }
 
 inline void verify_result( Gdiplus::GpStatus const result )
@@ -152,32 +153,6 @@
 }
 
 
-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
     :
@@ -275,41 +250,6 @@
     private gp_guard,
     public detail::formatted_image<gp_image>
 {
-public:
- static std::size_t format_size( format_t const format )
- {
- return Gdiplus::GetPixelFormatSize( format );
- }
-
-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 therefore 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_t * 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_;
- };
-
 public: /// \ingroup Construction
     explicit gp_image( wchar_t const * const filename )
     {
@@ -369,6 +309,10 @@
         return point2<std::ptrdiff_t>( static_cast<std::ptrdiff_t>( width ), static_cast<std::ptrdiff_t>( height ) );
     }
 
+ static std::size_t format_size( format_t const format )
+ {
+ return Gdiplus::GetPixelFormatSize( format );
+ }
 
     void save_to_png( char const * const pFilename ) const { save_to( pFilename, png_codec() ); }
     void save_to_png( wchar_t const * const pFilename ) const { save_to( pFilename, png_codec() ); }
@@ -426,7 +370,6 @@
                 BOOST_ASSERT( !"Should not get reached." ); __assume( false );
                 return PixelFormatUndefined;
         }
-
     }
 
     image_type_id current_image_format_id() const
@@ -451,7 +394,7 @@
         }
     }
 
-public:
+private:
     template <class MyView, class TargetView, class Converter>
     void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
     {
@@ -524,7 +467,6 @@
         raw_convert_to_prepared_view( view_data );
     }
 
-
 private:
     static CLSID const & png_codec()
     {
@@ -636,7 +578,7 @@
 public:
     ~gp_view_base()
     {
- verify_result( Gdiplus::DllExports::GdipBitmapUnlockBits( &bitmap_, &bitmapData_ ) );
+ detail::verify_result( Gdiplus::DllExports::GdipBitmapUnlockBits( &bitmap_, &bitmapData_ ) );
     }
 
 protected:

Deleted: sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/gp_private_istreams.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
+++ (empty file)
@@ -1,380 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \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/wic_image.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/wic_image.hpp 2010-07-26 13:20:10 EDT (Mon, 26 Jul 2010)
@@ -0,0 +1,445 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file wic_image.hpp
+/// -------------------
+///
+/// Base IO interface WIC 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 wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
+#define wic_image_hpp__78D710F7_11C8_4023_985A_22B180C9A476
+//------------------------------------------------------------------------------
+#include "../../gil_all.hpp"
+#include "detail/wic_extern_lib_guard.hpp"
+#include "detail/windows_shared.hpp"
+#include "detail/windows_shared_istreams.hpp"
+#include "io_error.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 "wincodec.h"
+
+#include <algorithm>
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+
+class wic_image;
+
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+template <GUID const & guid>
+struct format_guid
+{
+ typedef format_guid type;
+
+ static GUID const & value;
+};
+
+template <GUID const & guid>
+GUID const & format_guid<guid>::value( guid );
+
+template <typename Pixel, bool IsPlanar>
+struct gil_to_wic_format : format_guid<GUID_WICPixelFormatUndefined> {};
+
+typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, bgr_layout_t>::type wic_bgr565_pixel_t;
+
+template <> struct gil_to_wic_format<wic_bgr565_pixel_t, false> : format_guid<GUID_WICPixelFormat16bppBGR555> {};
+template <> struct gil_to_wic_format<bgr8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppBGR > {};
+template <> struct gil_to_wic_format<rgb8_pixel_t , false> : format_guid<GUID_WICPixelFormat24bppRGB > {};
+template <> struct gil_to_wic_format<bgra8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppBGRA > {};
+template <> struct gil_to_wic_format<gray16_pixel_t , false> : format_guid<GUID_WICPixelFormat16bppGray > {};
+template <> struct gil_to_wic_format<bgr16_pixel_t , false> : format_guid<GUID_WICPixelFormat48bppRGB > {};
+template <> struct gil_to_wic_format<bgra16_pixel_t , false> : format_guid<GUID_WICPixelFormat64bppBGRA > {};
+template <> struct gil_to_wic_format<cmyk8_pixel_t , false> : format_guid<GUID_WICPixelFormat32bppCMYK > {};
+
+template <GUID const & wic_format>
+struct is_supported_format
+ : is_same
+ <
+ format_guid<wic_format >,
+ format_guid<GUID_WICPixelFormatUndefined>
+ >
+{};
+
+
+typedef mpl::vector8
+<
+ image<wic_bgr565_pixel_t, false>,
+ image<bgr8_pixel_t , false>,
+ image<rgb8_pixel_t , false>,
+ image<bgra8_pixel_t , false>,
+ image<gray16_pixel_t , false>,
+ image<bgr16_pixel_t , false>,
+ image<bgra16_pixel_t , false>,
+ image<cmyk8_pixel_t , false>
+> wic_supported_pixel_formats;
+
+
+struct view_wic_format
+{
+ template <class View>
+ struct apply : gil_to_wic_format<typename View::value_type, is_planar<View>::value> {};
+};
+
+
+class wic_roi : public WICRect
+{
+public:
+ typedef INT value_type;
+ typedef point2<value_type> point_t ;
+
+ typedef point_t offset_t ;
+
+public:
+ wic_roi( value_type const x, value_type const y, value_type const width, value_type const height )
+ {
+ X = x; Y = y; Width = width; Height = height;
+ }
+
+ wic_roi( offset_t const offset, value_type const width, value_type const height )
+ {
+ X = offset.x; Y = offset.y; Width = width; Height = height;
+ }
+
+ wic_roi( offset_t const top_left, offset_t const bottom_right )
+ {
+ X = top_left.x; Y = top_left.y;
+ Width = bottom_right.x - top_left.x;
+ Height = bottom_right.y - top_left.y;
+ }
+};
+
+
+template <>
+struct formatted_image_traits<wic_image>
+{
+ typedef WICPixelFormatGUID const & format_t;
+
+ typedef wic_supported_pixel_formats supported_pixel_formats_t;
+
+ typedef wic_roi roi_t;
+
+ typedef view_wic_format view_to_native_format;
+
+ template <class View>
+ struct is_supported
+ :
+ mpl::not_
+ <
+ is_same
+ <
+ typename view_wic_format::apply<View>::type,
+ //format_guid<wic_format >,
+ format_guid<GUID_WICPixelFormatUndefined>
+ >
+ > {};
+
+ struct view_data_t
+ {
+ template <typename View>
+ view_data_t( View const & view )
+ :
+ p_roi_ ( 0 ),
+ format_( view_wic_format::apply<View>::value )
+ {
+ set_bitmapdata_for_view( view );
+ }
+
+ template <typename View>
+ view_data_t( View const & view, wic_roi::offset_t const & offset )
+ :
+ p_roi_ ( static_cast<wic_roi const *>( optional_roi_.address() ) ),
+ format_( view_wic_format::apply<View>::value )
+ {
+ set_bitmapdata_for_view( view );
+ new ( optional_roi_.address() ) wic_roi( offset, width_, height_ );
+ }
+
+ WICRect const * const p_roi_ ;
+ unsigned int /*const*/ width_ ;
+ unsigned int /*const*/ height_;
+ unsigned int /*const*/ stride_;
+ unsigned int /*const*/ pixel_size_;
+ BYTE * /*const*/ p_buffer_;
+ format_t format_;
+
+ private:
+ template <typename View>
+ void set_bitmapdata_for_view( View const & view )
+ {
+ width_ = view.width();
+ height_ = view.height();
+ stride_ = view.pixels().row_size();
+ pixel_size_ = memunit_step( typename View::x_iterator() );
+ //format_ = view_wic_format::apply<View>::value;
+ p_buffer_ = formatted_image_base::get_raw_data( view );
+ }
+
+ void operator=( view_data_t const & );
+
+ private:
+ aligned_storage<sizeof( wic_roi ), alignment_of<wic_roi>::value>::type optional_roi_;
+ };
+
+ BOOST_STATIC_CONSTANT( unsigned int, desired_alignment = sizeof( void * ) );
+ BOOST_STATIC_CONSTANT( bool , builtin_conversion = true );
+};
+
+
+inline void ensure_result( HRESULT const result )
+{
+ io_error_if( result != S_OK, "WIC failure"/*error_string( result )*/ );
+}
+
+inline void verify_result( HRESULT const result )
+{
+ BOOST_VERIFY( result == S_OK );
+}
+
+//------------------------------------------------------------------------------
+} // namespace detail
+
+
+class wic_image
+ :
+ private detail::wic_base_guard,
+ public detail::formatted_image<wic_image>
+{
+public:
+ // Implementation note:
+ // The IWICBitmapDecoder instance is not otherwise necessary once an
+ // IWICBitmapDecoder is created but we keep it here and make it accessible
+ // to the user to enable the use of multi frame/page/picture formats like
+ // GIF and TIFF.
+ // (26.07.2010.) (Domagoj Saric)
+ typedef std::pair
+ <
+ CComPtr<IWICBitmapFrameDecode>,
+ CComPtr<IWICBitmapDecoder >
+ > lib_object_t;
+
+ typedef detail::wic_user_guard guard_t;
+
+public:
+ explicit wic_image( wchar_t const * const filename )
+ {
+ create_decoder_from_filename( filename );
+ }
+
+ explicit wic_image( char const * const filename )
+ {
+ create_decoder_from_filename( detail::wide_path( filename ) );
+ }
+
+ // The passed IStream object must outlive the wic_image object (to support
+ // lazy evaluation).
+ explicit wic_image( IStream & stream )
+ {
+ using namespace detail;
+ ensure_result( wic_factory<>::singleton().CreateDecoderFromStream( &stream, NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
+ create_first_frame_decoder();
+ }
+
+ explicit wic_image( HANDLE const file_handle )
+ {
+ using namespace detail;
+ ensure_result( wic_factory<>::singleton().CreateDecoderFromFileHandle( reinterpret_cast<ULONG_PTR>( file_handle ), NULL, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
+ create_first_frame_decoder();
+ }
+
+ // The passed View object must outlive the wic_image object (to support
+ // lazy evaluation).
+ //...zzz...the same approach as with GDI+ cannot be used with WIC so an IStream approach will be required...
+ //template <class View>
+ //explicit wic_image( View & view )
+ //{
+ // ensure_result
+ // (
+ // wic_factory<>::singleton().CreateBitmapFromMemory
+ // (
+ // view.width(),
+ // view.height(),
+ // view.pixels().row_size(),
+ // view_wic_format::apply<View>::value,
+ // get_raw_data( view ),
+ // &pBitmap_
+ // )
+ // );
+ // create_first_frame_decoder();
+ //}
+
+ lib_object_t & lib_object() { return lib_object_; }
+
+public:
+ point2<std::ptrdiff_t> dimensions() const
+ {
+ using namespace detail;
+ aligned_storage<sizeof( wic_roi ), alignment_of<wic_roi>::value>::type placeholder;
+ point2<std::ptrdiff_t> & result( *gil_reinterpret_cast<point2<std::ptrdiff_t> *>( placeholder.address() ) );
+ verify_result( frame_decoder().GetSize( gil_reinterpret_cast<UINT *>( &result.x ), gil_reinterpret_cast<UINT *>( &result.y ) ) );
+ return result;
+ }
+
+ static std::size_t format_size( format_t /*const*/ format )
+ {
+ using namespace detail;
+ CComQIPtr<IWICComponentInfo> p_component_info;
+ ensure_result( wic_factory<>::singleton().CreateComponentInfo( format, &p_component_info ) );
+ //CComQIPtr<IWICPixelFormatInfo> p_pixel_format_info;
+ //p_component_info->QueryInterface( );(IID_IWICPixelFormatInfo
+ CComQIPtr<IWICPixelFormatInfo> const p_pixel_format_info( p_component_info );
+ io_error_if( !p_pixel_format_info, "WIC failure" );
+ unsigned int bits_per_pixel;
+ verify_result( p_pixel_format_info->GetBitsPerPixel( &bits_per_pixel ) );
+ return bits_per_pixel;
+ }
+
+private: // Private formatted_image_base interface.
+ friend base_t;
+
+ //...zzz...cleanup...
+ /*format_t*/WICPixelFormatGUID format() const
+ {
+ WICPixelFormatGUID pixel_format;
+ detail::verify_result( frame_decoder().GetPixelFormat( &pixel_format ) );
+ //...zzz...check that it is a supported format...
+ return pixel_format;
+ }
+
+ /*format_t*/WICPixelFormatGUID closest_gil_supported_format() const { return format(); }
+
+ image_type_id current_image_format_id() const
+ {
+ return image_format_id( closest_gil_supported_format() );
+ }
+
+
+ template <class MyView, class TargetView, class Converter>
+ void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
+ {
+ BOOST_ASSERT( !dimensions_mismatch( view ) );
+ //BOOST_ASSERT( !formats_mismatch ( view ) );
+
+ using namespace detail;
+
+ //...non template related code yet to be extracted...
+ point2<std::ptrdiff_t> const & targetDimensions( original_view( view ).dimensions() );
+ wic_roi const roi( get_offset<wic_roi::offset_t>( view ), targetDimensions.x, targetDimensions.y );
+ CComQIPtr<IWICBitmap> p_bitmap;
+ ensure_result( wic_factory<>::singleton().CreateBitmapFromSourceRect( &frame_decoder(), roi.X, roi.Y, roi.Width, roi.Height, &p_bitmap ) );
+ CComQIPtr<IWICBitmapLock> p_bitmap_lock;
+ ensure_result( p_bitmap->Lock( &roi, WICBitmapLockRead, &p_bitmap_lock ) );
+ unsigned int buffer_size;
+ BYTE * p_buffer;
+ verify_result( p_bitmap_lock->GetDataPointer( &buffer_size, &p_buffer ) );
+ unsigned int stride;
+ verify_result( p_bitmap_lock->GetStride( &stride ) );
+ #ifndef NDEBUG
+ WICPixelFormatGUID locked_format;
+ verify_result( p_bitmap_lock->GetPixelFormat( &locked_format ) );
+ BOOST_ASSERT( locked_format == view_wic_format::apply<MyView>::value );
+ #endif
+ copy_and_convert_pixels
+ (
+ interleaved_view
+ (
+ roi.Width ,
+ roi.Height,
+ gil_reinterpret_cast_c<typename MyView::value_type const *>( p_buffer ),
+ stride
+ ),
+ view,
+ converter
+ );
+ }
+
+
+ void raw_convert_to_prepared_view( detail::formatted_image_traits<wic_image>::view_data_t const & view_data ) const
+ {
+ BOOST_ASSERT( view_data.format_ != GUID_WICPixelFormatUndefined ); //...zzz...
+ using namespace detail;
+ CComQIPtr<IWICFormatConverter> p_converter;
+ ensure_result( wic_factory<>::singleton().CreateFormatConverter( &p_converter ) );
+ ensure_result( p_converter->Initialize( &frame_decoder(), view_data.format_, WICBitmapDitherTypeNone, NULL, 0, WICBitmapPaletteTypeCustom ) );
+ ensure_result
+ (
+ p_converter->CopyPixels
+ (
+ view_data.p_roi_,
+ view_data.stride_,
+ view_data.height_ * view_data.stride_ * view_data.pixel_size_,
+ view_data.p_buffer_
+ )
+ );
+ }
+
+
+ void copy_to_target( detail::formatted_image_traits<wic_image>::view_data_t const & view_data ) const
+ {
+ detail::ensure_result
+ (
+ frame_decoder().CopyPixels
+ (
+ view_data.p_roi_,
+ view_data.stride_,
+ view_data.height_ * view_data.stride_ * view_data.pixel_size_,
+ view_data.p_buffer_
+ )
+ );
+ }
+
+private:
+ IWICBitmapFrameDecode & frame_decoder() const { return *lib_object_.first ; }
+ IWICBitmapDecoder & wic_decoder () const { return *lib_object_.second; }
+
+ void create_decoder_from_filename( wchar_t const * const filename )
+ {
+ using namespace detail;
+ ensure_result( wic_factory<>::singleton().CreateDecoderFromFilename( filename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &lib_object().second ) );
+ create_first_frame_decoder();
+ }
+
+ void create_first_frame_decoder()
+ {
+ using namespace detail;
+ #ifndef NDEBUG
+ unsigned int frame_count;
+ verify_result( wic_decoder().GetFrameCount( &frame_count ) );
+ BOOST_ASSERT( frame_count >= 1 );
+ #endif // NDEBUG
+ ensure_result( wic_decoder().GetFrame( 0, &lib_object().first ) );
+ }
+
+private:
+ lib_object_t lib_object_;
+};
+
+
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // wic_image_hpp


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