summaryrefslogtreecommitdiff
path: root/boost/gil/extension/dynamic_image/any_image.hpp
blob: 3c4445ff10f6dd175c12b8ec9ecd22a74ec90297 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
    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_DYNAMICIMAGE_ANY_IMAGE_HPP
#define GIL_DYNAMICIMAGE_ANY_IMAGE_HPP

////////////////////////////////////////////////////////////////////////////////////////
/// \file               
/// \brief Support for run-time instantiated images and image views
/// \author Lubomir Bourdev and Hailin Jin \n
///         Adobe Systems Incorporated
///
///
////////////////////////////////////////////////////////////////////////////////////////

#include "any_image_view.hpp"
#include "../../image.hpp"

//#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable : 4244)     // conversion from 'std::ptrdiff_t' to 'int', possible loss of data. even if we static-assert the two types are the same (on visual studio 8)
//#endif

#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 
#pragma warning(push) 
#pragma warning(disable:4512) //assignment operator could not be generated 
#endif

namespace boost { namespace gil {

namespace detail {
    template <typename T> struct get_view_t       { typedef typename T::view_t type; };
    template <typename Images> struct images_get_views_t : public mpl::transform<Images, get_view_t<mpl::_1> > {};

    template <typename T> struct get_const_view_t { typedef typename T::const_view_t type; };
    template <typename Images> struct images_get_const_views_t : public mpl::transform<Images, get_const_view_t<mpl::_1> > {};

    struct recreate_image_fnobj {
        typedef void result_type;
        const point2<std::ptrdiff_t>& _dimensions;
        unsigned _alignment;

        recreate_image_fnobj(const point2<std::ptrdiff_t>& dims, unsigned alignment) : _dimensions(dims), _alignment(alignment) {}
        template <typename Image> result_type operator()(Image& img) const { img.recreate(_dimensions,_alignment); }
    };

    template <typename AnyView>  // Models AnyViewConcept
    struct any_image_get_view {
        typedef AnyView result_type;
        template <typename Image> result_type operator()(      Image& img) const { return result_type(view(img)); }
    };

    template <typename AnyConstView>  // Models AnyConstViewConcept
    struct any_image_get_const_view {
        typedef AnyConstView result_type;
        template <typename Image> result_type operator()(const Image& img) const { return result_type(const_view(img)); }
    };
}

////////////////////////////////////////////////////////////////////////////////////////
/// \ingroup ImageModel
/// \brief Represents a run-time specified image. Note it does NOT model ImageConcept
///  
/// Represents an image whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
/// It is the runtime equivalent of \p image.
/// Some of the requirements of ImageConcept, such as the \p value_type typedef cannot be fulfilled, since the language does not allow runtime type specification.
/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image does not fully model ImageConcept.
/// In particular, its \p view and \p const_view methods return \p any_image_view, which does not fully model ImageViewConcept. See \p any_image_view for more.
////////////////////////////////////////////////////////////////////////////////////////
template <typename ImageTypes>
class any_image : public variant<ImageTypes> {
    typedef variant<ImageTypes> parent_t;
public:
    typedef any_image_view<typename detail::images_get_const_views_t<ImageTypes>::type> const_view_t;
    typedef any_image_view<typename detail::images_get_views_t<ImageTypes>::type>       view_t;
    typedef std::ptrdiff_t x_coord_t;
    typedef std::ptrdiff_t y_coord_t;
    typedef point2<std::ptrdiff_t> point_t;

    any_image()                                                          : parent_t() {}
    template <typename T> explicit any_image(const T& obj)               : parent_t(obj) {}
    template <typename T> explicit any_image(T& obj, bool do_swap)       : parent_t(obj,do_swap) {}
    any_image(const any_image& v)                                        : parent_t((const parent_t&)v)    {}
    template <typename Types> any_image(const any_image<Types>& v)       : parent_t((const variant<Types>&)v)    {}

    template <typename T> any_image& operator=(const T& obj)                  { parent_t::operator=(obj); return *this; }
    any_image&                       operator=(const any_image& v)            { parent_t::operator=((const parent_t&)v); return *this;}
    template <typename Types> any_image& operator=(const any_image<Types>& v) { parent_t::operator=((const variant<Types>&)v); return *this;}

    void recreate(const point_t& dims, unsigned alignment=1)               { apply_operation(*this,detail::recreate_image_fnobj(dims,alignment)); }
    void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1) { recreate(point2<std::ptrdiff_t>(width,height),alignment); }

    std::size_t num_channels()  const { return apply_operation(*this, detail::any_type_get_num_channels()); }
    point_t     dimensions()    const { return apply_operation(*this, detail::any_type_get_dimensions()); }
    x_coord_t   width()         const { return dimensions().x; }
    y_coord_t   height()        const { return dimensions().y; }
};

///@{
/// \name view, const_view
/// \brief Get an image view from a run-time instantiated image

/// \ingroup ImageModel

/// \brief Returns the non-constant-pixel view of any image. The returned view is any view.
template <typename Types>  BOOST_FORCEINLINE // Models ImageVectorConcept
typename any_image<Types>::view_t view(any_image<Types>& anyImage) { 
    return apply_operation(anyImage, detail::any_image_get_view<typename any_image<Types>::view_t>());
}

/// \brief Returns the constant-pixel view of any image. The returned view is any view.
template <typename Types> BOOST_FORCEINLINE // Models ImageVectorConcept
typename any_image<Types>::const_view_t const_view(const any_image<Types>& anyImage) { 
    return apply_operation(anyImage, detail::any_image_get_const_view<typename any_image<Types>::const_view_t>());
}
///@}

} }  // namespace boost::gil

#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 
#pragma warning(pop) 
#endif 

//#ifdef _MSC_VER
//#pragma warning(pop)
//#endif

#endif