image_view_factory.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2006 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_IMAGE_VIEW_FACTORY_HPP
00010 #define GIL_IMAGE_VIEW_FACTORY_HPP
00011 
00021 
00023 #include <cassert>
00024 #include "gil_config.hpp"
00025 #include "image.hpp"
00026 #include "color_convert.hpp"
00027 
00028 ADOBE_GIL_NAMESPACE_BEGIN
00029 
00033 
00035 
00037 template <typename IT>
00038 inline typename type_from_x_iterator<IT>::view_t interleaved_view(ptrdiff_t width, ptrdiff_t height, IT pixels, ptrdiff_t rowsize_in_bytes) {
00039     return typename type_from_x_iterator<IT>::view_t(width, height, pixels, rowsize_in_bytes);
00040 }
00041 
00043 template <typename IC>
00044 inline typename type_from_x_iterator<planar_ptr<IC,rgb_t> >::view_t planar_rgb_view(int width, int height, IC r, IC g, IC b, ptrdiff_t rowsize_in_bytes) {
00045     return typename type_from_x_iterator<planar_ptr<IC,rgb_t> >::view_t(width, height, planar_ptr<IC,rgb_t>(r,g,b), rowsize_in_bytes);
00046 }
00047 
00049 template <typename IC>
00050 inline typename type_from_x_iterator<planar_ptr<IC,rgba_t> >::view_t planar_rgba_view(int width, int height, IC r, IC g, IC b, IC a, ptrdiff_t rowsize_in_bytes) {
00051     return typename type_from_x_iterator<planar_ptr<IC,rgba_t> >::view_t(width, height, planar_ptr<IC,rgba_t>(r,g,b,a), rowsize_in_bytes);
00052 }
00053 
00055 template <typename IC>
00056 inline typename type_from_x_iterator<planar_ptr<IC,cmyk_t> >::view_t planar_cmyk_view(int width, int height, IC c, IC m, IC y, IC k, ptrdiff_t rowsize_in_bytes) {
00057     return typename type_from_x_iterator<planar_ptr<IC,cmyk_t> >::view_t(width, height, planar_ptr<IC,cmyk_t>(c,m,y,k), rowsize_in_bytes);
00058 }
00059 
00061 template <typename IC>
00062 inline typename type_from_x_iterator<planar_ptr<IC,lab_t> >::view_t planar_lab_view(int width, int height, IC l, IC a, IC b, ptrdiff_t rowsize_in_bytes) {
00063     return typename type_from_x_iterator<planar_ptr<IC,lab_t> >::view_t(width, height, planar_ptr<IC,lab_t>(l,a,b), rowsize_in_bytes);
00064 }
00065 
00067 
00068 namespace detail {
00069     template <typename SRC_VIEW, typename DST_P, typename SRC_P>
00070     struct _color_convert_types {
00071         typedef dereference_iterator_adaptor<typename SRC_VIEW::x_iterator, color_convert_deref_fn<DST_P> > x_iterator;
00072         typedef typename type_from_x_iterator<x_iterator>::view_t                                        view_t;
00073     };
00074     // If the SRC view has the same pixel type as the target, there is no need for color conversion
00075     template <typename SRC_VIEW, typename DST_P>
00076     struct _color_convert_types<SRC_VIEW,DST_P,DST_P> {
00077         typedef typename SRC_VIEW::x_iterator   x_iterator;
00078         typedef SRC_VIEW                        view_t;
00079     };
00080 }
00081 
00085 
00088 template <typename SRC_VIEW, typename DST_P>
00089 struct color_convert_types : public detail::_color_convert_types<SRC_VIEW,DST_P, typename SRC_VIEW::value_type> {
00090     GIL_CLASS_REQUIRE(SRC_VIEW, GIL, ImageViewConcept);
00091     GIL_CLASS_REQUIRE(DST_P, GIL, MutablePixelConcept);//why does it have to MutablePixelConcept???
00092 };
00093 
00095 
00097 template <typename DST_P, typename VIEW>
00098 inline typename color_convert_types<VIEW,DST_P>::view_t color_converted_view(const VIEW& src) {
00099     return typename color_convert_types<VIEW,DST_P>::view_t(src);
00100 }
00101 
00103 template <typename VIEW>
00104 inline VIEW flipped_up_down_view(const VIEW& src) { 
00105     return VIEW(src.dimensions(),src.row_begin(src.height()-1),-src.row_bytes());
00106 }
00107 
00109 template <typename VIEW> 
00110 inline typename VIEW::dynamic_step_t flipped_left_right_view(const VIEW& src) {
00111     return typename VIEW::dynamic_step_t(src.dimensions(),make_step_iterator(src.x_at(src.width()-1,0),-src.pix_bytestep()),src.row_bytes());
00112 }
00113 
00115 template <typename VIEW>
00116 inline typename VIEW::dynamic_step_t transposed_view(const VIEW& src) {
00117     return typename VIEW::dynamic_step_t(src.height(),src.width(),make_step_iterator(src.x_at(0,0),src.row_bytes()),src.pix_bytestep());
00118 }
00119 
00121 template <typename VIEW> 
00122 inline typename VIEW::dynamic_step_t rotated90cw_view(const VIEW& src) {
00123     return typename VIEW::dynamic_step_t(src.height(),src.width(),make_step_iterator(src.x_at(0,src.height()-1),-src.row_bytes()),src.pix_bytestep());
00124 }
00125 
00127 template <typename VIEW> 
00128 inline typename VIEW::dynamic_step_t rotated90ccw_view(const VIEW& src) {
00129     return typename VIEW::dynamic_step_t(src.height(),src.width(),make_step_iterator(src.x_at(src.width()-1,0),src.row_bytes()),-src.pix_bytestep());
00130 }
00131 
00133 template <typename VIEW> 
00134 inline typename VIEW::dynamic_step_t rotated180_view(const VIEW& src) { 
00135     return typename VIEW::dynamic_step_t(src.dimensions(),make_step_iterator(src.x_at(src.width()-1,src.height()-1),-src.pix_bytestep()),-src.row_bytes());
00136 }
00137 
00139 template <typename VIEW> 
00140 inline VIEW subimage_view(const VIEW& src, const typename VIEW::point_t& topleft, const typename VIEW::point_t& dimensions) {
00141     return VIEW(dimensions,src.x_at(topleft),src.row_bytes());
00142 }
00143 template <typename VIEW> 
00144 inline VIEW subimage_view(const VIEW& src, int xMin, int yMin, int width, int height) {
00145     return VIEW(width,height,src.x_at(xMin,yMin),src.row_bytes());
00146 }
00147 
00149 template <typename VIEW> 
00150 inline typename VIEW::dynamic_step_t subsampled_view(const VIEW& src, typename VIEW::coord_t xStep, typename VIEW::coord_t yStep) {
00151     assert(xStep>0 && yStep>0);
00152     return typename VIEW::dynamic_step_t((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep,
00153                                             make_step_iterator(src.x_at(0,0),xStep*src.pix_bytestep()),src.row_bytes()*yStep);
00154 }
00155 
00157 template <typename VIEW> 
00158 inline typename VIEW::dynamic_step_t subsampled_view(const VIEW& src, const typename VIEW::point_t& step) { 
00159     return subsampled_view(src,step.x,step.y);
00160 }
00161 
00164 
00168 template <typename VIEW>
00169 class   nth_channel_types {
00170     GIL_CLASS_REQUIRE(VIEW, GIL, ImageViewConcept);
00171     typedef typename VIEW::x_iterator src_x_iterator;
00172 
00173 public:
00174     // Determines whether the channels of a given pixel iterator are adjacent in memory.
00175     // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
00176     BOOST_STATIC_CONSTANT(bool, adjacent=
00177                           !has_dynamic_step<src_x_iterator>::value &&
00178                           (pixel_iterator_traits<src_x_iterator>::is_planar ||
00179                            pixel_iterator_traits< src_x_iterator >::color_space_t::num_channels==1));
00180 
00181     // single-channel interleaved iterator of the same channel type as the source, with a step if the source channels are not adjacent in memory
00182     typedef typename iterator_type<typename channel_traits<typename pixel_iterator_traits<src_x_iterator>::channel_t>::pointer,gray_t,false,!adjacent>::type x_iterator;
00183 
00184     typedef typename type_from_x_iterator<x_iterator>::view_t view_t; 
00185 };
00186 
00187 
00188 namespace detail {
00189     // nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images 
00190     // or images with a step
00191     template <typename VIEW, bool CHANNELS_TOGETHER>
00192     struct __nth_channel_view {
00193         static typename nth_channel_types<VIEW>::view_t apply(const VIEW& src, int n) {
00194             typedef typename nth_channel_types<VIEW>::x_iterator IT;
00195             typedef typename pixel_iterator_traits<IT>::base_t IT_BASE;
00196             IT sit(IT_BASE(&(src(0,0)[n])),src.pix_bytestep());
00197             return typename nth_channel_types<VIEW>::view_t(src.dimensions(),sit, src.row_bytes());
00198         }
00199     };
00200 
00201     // nth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
00202     template <typename VIEW>
00203     struct __nth_channel_view<VIEW,true> {
00204         static typename nth_channel_types<VIEW>::view_t apply(const VIEW& src, int n) {
00205             typedef typename nth_channel_types<VIEW>::x_iterator IT;
00206             return interleaved_view(src.width(),src.height(),(IT)&(src(0,0)[n]), src.row_bytes());
00207         }
00208     };
00209 }
00210 
00212 template <typename VIEW>
00213 typename nth_channel_types<VIEW>::view_t nth_channel_view(const VIEW& src, int n) {
00214     // right now n-th channel view operates only on images that are over real data (not using dereference_iterator_adaptor, for example)
00215     BOOST_STATIC_ASSERT((pixel_iterator_traits<typename VIEW::x_iterator>::pixel_data_is_real));
00216     return detail::__nth_channel_view<VIEW,nth_channel_types<VIEW>::adjacent>::apply(src,n);
00217 }
00219 
00220 ADOBE_GIL_NAMESPACE_END
00221 
00222 #endif