Chris@16: /* Chris@16: Copyright 2005-2007 Adobe Systems Incorporated Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: See http://opensource.adobe.com/gil for most recent version including documentation. Chris@16: */ Chris@16: /*************************************************************************************************/ Chris@16: Chris@16: #ifndef GIL_IMAGE_VIEW_H Chris@16: #define GIL_IMAGE_VIEW_H Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file Chris@16: /// \brief image view class Chris@16: /// \author Lubomir Bourdev and Hailin Jin \n Chris@16: /// Adobe Systems Incorporated Chris@16: /// \date 2005-2007 \n Last updated on February 12, 2007 Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include "gil_config.hpp" Chris@16: #include "iterator_from_2d.hpp" Chris@16: Chris@16: //#ifdef _MSC_VER Chris@16: //#pragma warning(push) Chris@16: //#pragma warning(disable : 4244) // conversion from 'gil::image::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) Chris@16: //#endif Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// \class image_view Chris@16: /// \ingroup ImageViewModel PixelBasedModel Chris@16: /// \brief A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,PixelBasedConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept Chris@16: /// Chris@16: /// Image view consists of a pixel 2D locator (defining the mechanism for navigating in 2D) Chris@16: /// and the image dimensions. Chris@16: /// Chris@16: /// Image views to images are what ranges are to STL containers. They are lightweight objects, Chris@16: /// that don't own the pixels. It is the user's responsibility that the underlying data remains Chris@16: /// valid for the lifetime of the image view. Chris@16: /// Chris@16: /// Similar to iterators and ranges, constness of views does not extend to constness of pixels. Chris@16: /// A const \p image_view does not allow changing its location in memory (resizing, moving) but does Chris@16: /// not prevent one from changing the pixels. The latter requires an image view whose value_type Chris@16: /// is const. Chris@16: /// Chris@16: /// Images have interfaces consistent with STL 1D random access containers, so they can be used Chris@16: /// directly in STL algorithms like: Chris@16: /// \code Chris@16: /// std::fill(img.begin(), img.end(), red_pixel); Chris@16: /// \endcode Chris@16: /// Chris@16: /// In addition, horizontal, vertical and 2D random access iterators are provided. Chris@16: /// Chris@16: /// Note also that \p image_view does not require that its element type be a pixel. It could be Chris@16: /// instantiated with a locator whose \p value_type models only \p Regular. In this case the image Chris@16: /// view models the weaker RandomAccess2DImageViewConcept, and does not model PixelBasedConcept. Chris@16: /// Many generic algorithms don't require the elements to be pixels. Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: template // Models 2D Pixel Locator Chris@16: class image_view { Chris@16: public: Chris@16: Chris@16: // typedefs required by ConstRandomAccessNDImageViewConcept Chris@16: static const std::size_t num_dimensions=2; Chris@16: typedef typename Loc::value_type value_type; Chris@16: typedef typename Loc::reference reference; // result of dereferencing Chris@16: typedef typename Loc::coord_t coord_t; // 1D difference type (same for all dimensions) Chris@16: typedef coord_t difference_type; // result of operator-(1d_iterator,1d_iterator) Chris@16: typedef typename Loc::point_t point_t; Chris@16: typedef Loc locator; Chris@16: typedef image_view const_t; // same as this type, but over const values Chris@16: template struct axis { Chris@16: typedef typename Loc::template axis::coord_t coord_t; // difference_type along each dimension Chris@16: typedef typename Loc::template axis::iterator iterator; // 1D iterator type along each dimension Chris@16: }; Chris@16: typedef iterator_from_2d iterator; // 1D iterator type for each pixel left-to-right inside top-to-bottom Chris@16: typedef std::reverse_iterator reverse_iterator; Chris@16: typedef std::size_t size_type; Chris@16: Chris@16: // typedefs required by ConstRandomAccess2DImageViewConcept Chris@16: typedef locator xy_locator; Chris@16: typedef typename xy_locator::x_iterator x_iterator; // pixel iterator along a row Chris@16: typedef typename xy_locator::y_iterator y_iterator; // pixel iterator along a column Chris@16: typedef typename xy_locator::x_coord_t x_coord_t; Chris@16: typedef typename xy_locator::y_coord_t y_coord_t; Chris@16: Chris@16: template struct add_deref { Chris@16: typedef image_view::type> type; Chris@16: static type make(const image_view& iv, const Deref& d) { return type(iv.dimensions(), Loc::template add_deref::make(iv.pixels(),d)); } Chris@16: }; Chris@16: Chris@16: image_view() : _dimensions(0,0) {} Chris@16: template image_view(const View& iv) : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {} Chris@16: Chris@16: template image_view(const point_t& sz , const L2& loc) : _dimensions(sz), _pixels(loc) {} Chris@16: template image_view(coord_t width, coord_t height, const L2& loc) : _dimensions(x_coord_t(width),y_coord_t(height)), _pixels(loc) {} Chris@16: Chris@16: template image_view& operator=(const View& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } Chris@16: image_view& operator=(const image_view& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } Chris@16: Chris@16: template bool operator==(const View& v) const { return pixels()==v.pixels() && dimensions()==v.dimensions(); } Chris@16: template bool operator!=(const View& v) const { return !(*this==v); } Chris@16: Chris@16: template friend void swap(image_view& x, image_view& y); Chris@16: Chris@16: const point_t& dimensions() const { return _dimensions; } Chris@16: const locator& pixels() const { return _pixels; } Chris@16: x_coord_t width() const { return dimensions().x; } Chris@16: y_coord_t height() const { return dimensions().y; } Chris@16: std::size_t num_channels() const { return gil::num_channels::value; } Chris@16: bool is_1d_traversable() const { return _pixels.is_1d_traversable(width()); } Chris@16: Chris@16: //\{@ Chris@16: /// \name 1D navigation Chris@16: size_type size() const { return width()*height(); } Chris@16: iterator begin() const { return iterator(_pixels,_dimensions.x); } Chris@16: iterator end() const { return begin()+(difference_type)size(); } // potential performance problem! Chris@16: reverse_iterator rbegin() const { return reverse_iterator(end()); } Chris@16: reverse_iterator rend() const { return reverse_iterator(begin()); } Chris@16: reference operator[](difference_type i) const { return begin()[i]; } // potential performance problem! Chris@16: iterator at(difference_type i)const { return begin()+i; } Chris@16: iterator at(const point_t& p) const { return begin()+p.y*width()+p.x; } Chris@16: iterator at(x_coord_t x, y_coord_t y)const { return begin()+y*width()+x; } Chris@16: Chris@16: //\}@ Chris@16: Chris@16: //\{@ Chris@16: /// \name 2-D navigation Chris@16: reference operator()(const point_t& p) const { return _pixels(p.x,p.y); } Chris@16: reference operator()(x_coord_t x, y_coord_t y)const { return _pixels(x,y); } Chris@16: template typename axis::iterator axis_iterator(const point_t& p) const { return _pixels.axis_iterator(p); } Chris@16: xy_locator xy_at(x_coord_t x, y_coord_t y) const { return _pixels+point_t(x_coord_t(x),y_coord_t(y)); } Chris@16: locator xy_at(const point_t& p) const { return _pixels+p; } Chris@16: //\}@ Chris@16: Chris@16: //\{@ Chris@16: /// \name X navigation Chris@16: x_iterator x_at(x_coord_t x, y_coord_t y) const { return _pixels.x_at(x,y); } Chris@16: x_iterator x_at(const point_t& p) const { return _pixels.x_at(p); } Chris@16: x_iterator row_begin(y_coord_t y) const { return x_at(0,y); } Chris@16: x_iterator row_end(y_coord_t y) const { return x_at(width(),y); } Chris@16: //\}@ Chris@16: Chris@16: //\{@ Chris@16: /// \name Y navigation Chris@16: y_iterator y_at(x_coord_t x, y_coord_t y) const { return xy_at(x,y).y(); } Chris@16: y_iterator y_at(const point_t& p) const { return xy_at(p).y(); } Chris@16: y_iterator col_begin(x_coord_t x) const { return y_at(x,0); } Chris@16: y_iterator col_end(x_coord_t x) const { return y_at(x,height()); } Chris@16: //\}@ Chris@16: Chris@16: private: Chris@16: template friend class image_view; Chris@16: Chris@16: point_t _dimensions; Chris@16: xy_locator _pixels; Chris@16: }; Chris@16: Chris@16: template Chris@16: inline void swap(image_view& x, image_view& y) { Chris@16: using std::swap; Chris@16: swap(x._dimensions,y._dimensions); Chris@16: swap(x._pixels, y._pixels); // TODO: Extend further Chris@16: } Chris@16: Chris@16: ///////////////////////////// Chris@16: // PixelBasedConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct channel_type > : public channel_type {}; Chris@16: Chris@16: template Chris@16: struct color_space_type > : public color_space_type {}; Chris@16: Chris@16: template Chris@16: struct channel_mapping_type > : public channel_mapping_type {}; Chris@16: Chris@16: template Chris@16: struct is_planar > : public is_planar {}; Chris@16: Chris@16: ///////////////////////////// Chris@16: // HasDynamicXStepTypeConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct dynamic_x_step_type > { Chris@16: typedef image_view::type> type; Chris@16: }; Chris@16: Chris@16: ///////////////////////////// Chris@16: // HasDynamicYStepTypeConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct dynamic_y_step_type > { Chris@16: typedef image_view::type> type; Chris@16: }; Chris@16: Chris@16: ///////////////////////////// Chris@16: // HasTransposedTypeConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct transposed_type > { Chris@16: typedef image_view::type> type; Chris@16: }; Chris@16: Chris@16: } } // namespace boost::gil Chris@16: Chris@16: //#ifdef _MSC_VER Chris@16: //#pragma warning(pop) Chris@16: //#endif Chris@16: Chris@16: #endif