From: Foster B. <fos...@us...> - 2006-02-03 18:34:24
|
Update of /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6755/adobe/gil/core Modified Files: algorithm.hpp channel.hpp cmyk.hpp color_convert.hpp gil_concept.hpp gil_config.hpp gray.hpp image.hpp image_view_factory.hpp lab.hpp metafunctions.hpp pixel.hpp pixel_iterator.hpp rgb.hpp rgba.hpp typedefs.hpp utilities.hpp variant.hpp Log Message: asl 1.0.13 Index: image.hpp =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/core/image.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** image.hpp 24 Jan 2006 19:38:49 -0000 1.2 --- image.hpp 3 Feb 2006 18:33:37 -0000 1.3 *************** *** 1,6 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ --- 1,6 ---- /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ *************** *** 11,18 **** //////////////////////////////////////////////////////////////////////////////////////// ! /// \file /// \brief Templated image /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated /// /// --- 11,18 ---- //////////////////////////////////////////////////////////////////////////////////////// ! /// \file /// \brief Templated image /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated /// /// *************** *** 29,37 **** #ifdef _MSC_VER #pragma warning(push) ! #pragma warning(disable : 4244) // conversion from 'gil::image<V,ALLOC>::coord_type' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) #endif //////////////////////////////////////////////////////////////////////////////////////// ! /// \class image_view /// \ingroup ImageView /// \brief A lightweight object that interprets memory as a 2D array of pixels. --- 29,37 ---- #ifdef _MSC_VER #pragma warning(push) ! #pragma warning(disable : 4244) // conversion from 'gil::image<V,ALLOC>::coord_type' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) #endif //////////////////////////////////////////////////////////////////////////////////////// ! /// \class image_view /// \ingroup ImageView /// \brief A lightweight object that interprets memory as a 2D array of pixels. *************** *** 60,175 **** template <typename LOC> class pixel_image_iterator; ! template <typename LOC> // Models 2D Pixel Locator class image_view { ! GIL_CLASS_REQUIRE(LOC, GIL, PixelLocatorConcept); public: // typedefs required by ConstRandomAccessNDImageViewConcept ! static const size_t num_dimensions=2; ! typedef typename LOC::value_type value_type; ! typedef typename LOC::reference reference; // result of dereferencing ! typedef typename LOC::coord_type coord_type; // 1D difference type (same for all dimensions) ! typedef coord_type difference_type; // result of operator-(1d_iterator,1d_iterator) ! typedef value_type domain_type; ! typedef typename LOC::point_type point_type; ! typedef LOC locator; ! typedef image_view<typename LOC::const_type> const_type; // same as this type, but over const values ! template <size_t D> struct axis { ! typedef typename LOC::template axis<D>::coord_type coord_type; // difference_type along each dimension ! typedef typename LOC::template axis<D>::iterator iterator; // 1D iterator type along each dimension ! }; ! typedef pixel_image_iterator<LOC> iterator; // 1D iterator type for each pixel left-to-right inside top-to-bottom ! typedef std::reverse_iterator<iterator> reverse_iterator; ! typedef size_t size_type; // typedefs required by ConstRandomAccess2DImageViewConcept ! typedef locator xy_locator; ! typedef typename xy_locator::x_iterator x_iterator; // pixel iterator along a row ! typedef typename xy_locator::y_iterator y_iterator; // pixel iterator along a column ! typedef typename xy_locator::x_coord_type x_coord_type; ! typedef typename xy_locator::y_coord_type y_coord_type; // typedefs required by ConstRandomAccess2DImageViewConcept ! typedef image_view<typename LOC::dynamic_step_type> dynamic_step_type; ! typedef typename LOC::channel_type channel_type; // type of the channel of a pixel ! typedef typename LOC::color_space_type color_space_type;// tag indicating the color space of an image ! image_view() : _dimensions(0,0) {} ! template <typename VIEW> image_view(const VIEW& iv) : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {} ! template <typename L2> image_view(const point_type& sz , const L2& loc) : _dimensions(sz), _pixels(loc) {} ! template <typename L2> image_view(coord_type width, coord_type height, const L2& loc) : _dimensions(x_coord_type(width),y_coord_type(height)), _pixels(loc) {} ! image_view(const point_type& sz , const x_iterator& x_it, coord_type row_bytes) : _dimensions(sz), _pixels(x_it, row_bytes) {} ! image_view(coord_type width, coord_type height, const x_iterator& x_it, coord_type row_bytes) : _dimensions(x_coord_type(width),y_coord_type(height)), _pixels(x_it, row_bytes) {} ! template <typename VIEW> image_view& operator=(const VIEW& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } ! image_view& operator=(const image_view& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } ! template <typename VIEW> bool operator==(const VIEW& v) const { return pixels()==v.pixels() && dimensions()==v.dimensions(); } ! template <typename VIEW> bool operator!=(const VIEW& v) const { return !(*this==v); } ! template <typename L2> friend void swap(image_view<L2>& x, image_view<L2>& y); ! const point_type& dimensions() const { return _dimensions; } ! const locator& pixels() const { return _pixels; } ! x_coord_type width() const { return dimensions().x; } ! y_coord_type height() const { return dimensions().y; } ! difference_type row_bytes() const { return _pixels.row_bytes(); } // number of bytes per row ! difference_type pix_bytestep() const { return _pixels.pix_bytestep(); } // number of bytes between two adjacent pixels on the same row ! //\{@ ! /// \name 1D navigation ! size_type size() const { return width()*height(); } ! iterator begin() const { return iterator(_pixels,_dimensions.x); } ! iterator end() const { return begin()+size(); } // potential performance problem! ! reverse_iterator rbegin() const { return reverse_iterator(end()); } ! reverse_iterator rend() const { return reverse_iterator(begin()); } ! reference operator[](difference_type i) const { return begin()[i]; } // potential performance problem! ! iterator at(const point_type& p)const { return begin()+p.y*width()+p.x; } ! iterator at(x_coord_type x, y_coord_type y)const { return begin()+y*width()+x; } ! //\}@ ! //\{@ ! /// \name 2-D navigation ! reference operator()(const point_type& p) const { return _pixels(p.x,p.y); } ! reference operator()(x_coord_type x, y_coord_type y)const { return _pixels(x,y); } ! template <size_t D> typename axis<D>::iterator axis_iterator(const point_type& p) const { return _pixels.axis_iterator<D>(p); } ! xy_locator xy_at(x_coord_type x, y_coord_type y) const { return _pixels+point_type(x_coord_type(x),y_coord_type(y)); } ! locator xy_at(const point_type& p) const { return _pixels+p; } ! //\}@ ! //\{@ ! /// \name X navigation ! x_iterator x_at(x_coord_type x, y_coord_type y) const { return _pixels.x_at(x,y); } ! x_iterator x_at(const point_type& p) const { return _pixels.x_at(p); } ! x_iterator row_begin(y_coord_type y) const { return x_at(0,y); } ! x_iterator row_end(y_coord_type y) const { return x_at(width(),y); } ! //\}@ ! //\{@ ! /// \name Y navigation ! y_iterator y_at(x_coord_type x, y_coord_type y) const { return xy_at(x,y).y(); } ! y_iterator y_at(const point_type& p) const { return xy_at(p).y(); } ! y_iterator col_begin(x_coord_type x) const { return y_at(x,0); } ! y_iterator col_end(x_coord_type x) const { return y_at(x,height()); } ! //\}@ private: ! template <typename L2> friend class image_view; ! point_type _dimensions; ! xy_locator _pixels; }; template <typename L2> inline void swap(image_view<L2>& x, image_view<L2>& y) { ! std::swap(x._dimensions,y._dimensions); ! std::swap(x._pixels, y._pixels); // TODO: Extend further } //////////////////////////////////////////////////////////////////////////////////////// ! /// \class image /// \ingroup Image /// \brief container interface over image view --- 60,175 ---- template <typename LOC> class pixel_image_iterator; ! template <typename LOC> // Models 2D Pixel Locator class image_view { ! GIL_CLASS_REQUIRE(LOC, GIL, PixelLocatorConcept); public: // typedefs required by ConstRandomAccessNDImageViewConcept ! static const std::size_t num_dimensions=2; ! typedef typename LOC::value_type value_type; ! typedef typename LOC::reference reference; // result of dereferencing ! typedef typename LOC::coord_type coord_type; // 1D difference type (same for all dimensions) ! typedef coord_type difference_type; // result of operator-(1d_iterator,1d_iterator) ! typedef value_type domain_type; ! typedef typename LOC::point_type point_type; ! typedef LOC locator; ! typedef image_view<typename LOC::const_type> const_type; // same as this type, but over const values ! template <std::size_t D> struct axis { ! typedef typename LOC::template axis<D>::coord_type coord_type; // difference_type along each dimension ! typedef typename LOC::template axis<D>::iterator iterator; // 1D iterator type along each dimension ! }; ! typedef pixel_image_iterator<LOC> iterator; // 1D iterator type for each pixel left-to-right inside top-to-bottom ! typedef std::reverse_iterator<iterator> reverse_iterator; ! typedef size_t size_type; // typedefs required by ConstRandomAccess2DImageViewConcept ! typedef locator xy_locator; ! typedef typename xy_locator::x_iterator x_iterator; // pixel iterator along a row ! typedef typename xy_locator::y_iterator y_iterator; // pixel iterator along a column ! typedef typename xy_locator::x_coord_type x_coord_type; ! typedef typename xy_locator::y_coord_type y_coord_type; // typedefs required by ConstRandomAccess2DImageViewConcept ! typedef image_view<typename LOC::dynamic_step_type> dynamic_step_type; ! typedef typename LOC::channel_type channel_type; // type of the channel of a pixel ! typedef typename LOC::color_space_type color_space_type;// tag indicating the color space of an image ! image_view() : _dimensions(0,0) {} ! template <typename VIEW> image_view(const VIEW& iv) : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {} ! template <typename L2> image_view(const point_type& sz , const L2& loc) : _dimensions(sz), _pixels(loc) {} ! template <typename L2> image_view(coord_type width, coord_type height, const L2& loc) : _dimensions(x_coord_type(width),y_coord_type(height)), _pixels(loc) {} ! image_view(const point_type& sz , const x_iterator& x_it, coord_type row_bytes) : _dimensions(sz), _pixels(x_it, row_bytes) {} ! image_view(coord_type width, coord_type height, const x_iterator& x_it, coord_type row_bytes) : _dimensions(x_coord_type(width),y_coord_type(height)), _pixels(x_it, row_bytes) {} ! template <typename VIEW> image_view& operator=(const VIEW& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } ! image_view& operator=(const image_view& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; } ! template <typename VIEW> bool operator==(const VIEW& v) const { return pixels()==v.pixels() && dimensions()==v.dimensions(); } ! template <typename VIEW> bool operator!=(const VIEW& v) const { return !(*this==v); } ! template <typename L2> friend void swap(image_view<L2>& x, image_view<L2>& y); ! const point_type& dimensions() const { return _dimensions; } ! const locator& pixels() const { return _pixels; } ! x_coord_type width() const { return dimensions().x; } ! y_coord_type height() const { return dimensions().y; } ! difference_type row_bytes() const { return _pixels.row_bytes(); } // number of bytes per row ! difference_type pix_bytestep() const { return _pixels.pix_bytestep(); } // number of bytes between two adjacent pixels on the same row ! //\{@ ! /// \name 1D navigation ! size_type size() const { return width()*height(); } ! iterator begin() const { return iterator(_pixels,_dimensions.x); } ! iterator end() const { return begin()+size(); } // potential performance problem! ! reverse_iterator rbegin() const { return reverse_iterator(end()); } ! reverse_iterator rend() const { return reverse_iterator(begin()); } ! reference operator[](difference_type i) const { return begin()[i]; } // potential performance problem! ! iterator at(const point_type& p)const { return begin()+p.y*width()+p.x; } ! iterator at(x_coord_type x, y_coord_type y)const { return begin()+y*width()+x; } ! //\}@ ! //\{@ ! /// \name 2-D navigation ! reference operator()(const point_type& p) const { return _pixels(p.x,p.y); } ! reference operator()(x_coord_type x, y_coord_type y)const { return _pixels(x,y); } ! template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_type& p) const { return _pixels.axis_iterator<D>(p); } ! xy_locator xy_at(x_coord_type x, y_coord_type y) const { return _pixels+point_type(x_coord_type(x),y_coord_type(y)); } ! locator xy_at(const point_type& p) const { return _pixels+p; } ! //\}@ ! //\{@ ! /// \name X navigation ! x_iterator x_at(x_coord_type x, y_coord_type y) const { return _pixels.x_at(x,y); } ! x_iterator x_at(const point_type& p) const { return _pixels.x_at(p); } ! x_iterator row_begin(y_coord_type y) const { return x_at(0,y); } ! x_iterator row_end(y_coord_type y) const { return x_at(width(),y); } ! //\}@ ! //\{@ ! /// \name Y navigation ! y_iterator y_at(x_coord_type x, y_coord_type y) const { return xy_at(x,y).y(); } ! y_iterator y_at(const point_type& p) const { return xy_at(p).y(); } ! y_iterator col_begin(x_coord_type x) const { return y_at(x,0); } ! y_iterator col_end(x_coord_type x) const { return y_at(x,height()); } ! //\}@ private: ! template <typename L2> friend class image_view; ! point_type _dimensions; ! xy_locator _pixels; }; template <typename L2> inline void swap(image_view<L2>& x, image_view<L2>& y) { ! std::swap(x._dimensions,y._dimensions); ! std::swap(x._pixels, y._pixels); // TODO: Extend further } //////////////////////////////////////////////////////////////////////////////////////// ! /// \class image /// \ingroup Image /// \brief container interface over image view *************** *** 181,297 **** template <typename V2,typename ALLOC2> void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2); ! template <typename V, typename ALLOC=std::allocator<unsigned char> > class image { public: ! typedef ALLOC allocator_type; ! typedef V view_type; ! typedef typename view_type::const_type const_view_type; ! typedef typename view_type::point_type point_type; ! typedef typename view_type::coord_type coord_type; ! typedef coord_type x_coord_type; ! typedef coord_type y_coord_type; ! typedef typename view_type::iterator iterator; ! typedef iterator pointer; ! typedef typename const_view_type::iterator const_iterator; ! typedef const_iterator const_pointer; ! typedef typename view_type::difference_type difference_type; ! typedef typename view_type::value_type value_type; ! typedef typename view_type::reference reference; ! typedef typename const_view_type::reference const_reference; ! typedef typename view_type::size_type size_type; ! typedef typename view_type::reverse_iterator reverse_iterator; ! typedef typename const_view_type::reverse_iterator const_reverse_iterator; ! ! const_iterator begin() const { return const_view(*this).begin(); } ! const_iterator end() const { return const_view(*this).end(); } ! const_reverse_iterator rbegin() const { return const_view(*this).rbegin(); } ! const_reverse_iterator rend() const { return const_view(*this).rend(); } ! iterator begin() { return _view.begin(); } ! iterator end() { return _view.end(); } ! reverse_iterator rbegin() { return _view.rbegin(); } ! reverse_iterator rend() { return _view.rend(); } ! reference operator[](size_type i) { return _view[i]; } ! const_reference operator[](size_type i) const { return const_view(*this)[i]; } // Warning: Slow!! ! size_type size() const { return _view.size(); } ! size_type max_size() const { return size(); } ! bool empty() const { return size()==0; } ! const point_type& dimensions() const { return _view.dimensions(); } ! x_coord_type width() const { return _view.width(); } ! y_coord_type height() const { return _view.height(); } ! image() {} ! // image that allocates own data. Calls new/delete[] ! image(const point_type& dimensions, unsigned int alignment=1) { create_with_own_data(dimensions,alignment); } ! image(x_coord_type width, y_coord_type height, unsigned int alignment=1) { create_with_own_data(point_type(width,height),alignment); } ! image(const image& img) : _alloc(img._alloc) { ! create_with_own_data(const_view(img).dimensions()); // TODO: Use the same alignment ! copy_pixels(const_view(img),_view); } template <typename V2,typename ALLOC2> image(const image<V2,ALLOC2>& img) :_alloc(img._alloc) { ! create_with_own_data(view(img).dimensions()); ! copy_pixels(view(img),_view); } ! template <typename IMG> image& operator=(const IMG& img) { image tmp(img); swap(tmp); return *this; } ! image& operator=(const image& img) { image tmp(img); swap(tmp); return *this; } ! ~image() { ! size_t size_in_bytes=_view.row_bytes()*_view.height(); if(std::iterator_traits<typename V::x_iterator>::is_planar) ! size_in_bytes*=V::color_space_type::num_channels; _alloc.deallocate((unsigned char*)&(_view(0,0)[0]),size_in_bytes); } ! template <typename V2, typename ALLOC2> friend const V2& view(image<V2,ALLOC2>& img); ! template <typename V2, typename ALLOC2> friend const typename V2::const_type& const_view(const image<V2,ALLOC2>& img); ! ALLOC& allocator() { return _alloc; } ! ALLOC const& allocator() const { return _alloc; } ! template <typename V2,typename ALLOC2> ! friend void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2); ! void swap(image& img) { GIL::swap(*this,img); } // required by boost::MutableContainerConcept private: ! view_type _view; // contains pointer to the pixels, the image size and ways to navigate pixels allocator_type _alloc; template <bool> class is_planar {}; ! void create_with_own_data(const point_type& dimensions, unsigned int alignment=1) { ! BOOST_STATIC_ASSERT(!has_dynamic_step<typename V::x_iterator>::value); ! create_with_own_data_(dimensions,alignment,is_planar<std::iterator_traits<typename V::x_iterator>::is_planar>()); ! } ! void create_with_own_data_(const point_type& dimensions, unsigned int alignment, is_planar<false>) { ! size_t rowsize_in_bytes=get_aligned(dimensions.x*sizeof(typename V::value_type),alignment); unsigned char* tmp=_alloc.allocate(rowsize_in_bytes*dimensions.y); ! try { ! _view=V(dimensions,typename V::x_iterator(tmp),rowsize_in_bytes); ! } catch(...) { ! _alloc.deallocate(tmp, rowsize_in_bytes*dimensions.y); ! throw; ! } ! } void create_with_own_data_(const point_type& dimensions, unsigned int alignment, is_planar<true>) { ! size_t planesize_in_bytes=get_aligned(dimensions.x*dimensions.y*sizeof(typename V::channel_type),alignment); ! size_t image_size_in_bytes=planesize_in_bytes*V::color_space_type::num_channels; ! unsigned char* tmp=_alloc.allocate(image_size_in_bytes); ! try { ! _view=V(dimensions, typename V::x_iterator(tmp,planesize_in_bytes),dimensions.x*sizeof(typename V::channel_type)); ! } catch(...) { ! _alloc.deallocate(tmp, image_size_in_bytes); ! throw; ! } } --- 181,297 ---- template <typename V2,typename ALLOC2> void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2); ! template <typename V, typename ALLOC=std::allocator<unsigned char> > class image { public: ! typedef ALLOC allocator_type; ! typedef V view_type; ! typedef typename view_type::const_type const_view_type; ! typedef typename view_type::point_type point_type; ! typedef typename view_type::coord_type coord_type; ! typedef coord_type x_coord_type; ! typedef coord_type y_coord_type; ! typedef typename view_type::iterator iterator; ! typedef iterator pointer; ! typedef typename const_view_type::iterator const_iterator; ! typedef const_iterator const_pointer; ! typedef typename view_type::difference_type difference_type; ! typedef typename view_type::value_type value_type; ! typedef typename view_type::reference reference; ! typedef typename const_view_type::reference const_reference; ! typedef typename view_type::size_type size_type; ! typedef typename view_type::reverse_iterator reverse_iterator; ! typedef typename const_view_type::reverse_iterator const_reverse_iterator; ! ! const_iterator begin() const { return const_view(*this).begin(); } ! const_iterator end() const { return const_view(*this).end(); } ! const_reverse_iterator rbegin() const { return const_view(*this).rbegin(); } ! const_reverse_iterator rend() const { return const_view(*this).rend(); } ! iterator begin() { return _view.begin(); } ! iterator end() { return _view.end(); } ! reverse_iterator rbegin() { return _view.rbegin(); } ! reverse_iterator rend() { return _view.rend(); } ! reference operator[](size_type i) { return _view[i]; } ! const_reference operator[](size_type i) const { return const_view(*this)[i]; } // Warning: Slow!! ! size_type size() const { return _view.size(); } ! size_type max_size() const { return size(); } ! bool empty() const { return size()==0; } ! const point_type& dimensions() const { return _view.dimensions(); } ! x_coord_type width() const { return _view.width(); } ! y_coord_type height() const { return _view.height(); } ! image() {} ! // image that allocates own data. Calls new/delete[] ! image(const point_type& dimensions, unsigned int alignment=1) { create_with_own_data(dimensions,alignment); } ! image(x_coord_type width, y_coord_type height, unsigned int alignment=1) { create_with_own_data(point_type(width,height),alignment); } ! image(const image& img) : _alloc(img._alloc) { ! create_with_own_data(const_view(img).dimensions()); // TODO: Use the same alignment ! copy_pixels(const_view(img),_view); } template <typename V2,typename ALLOC2> image(const image<V2,ALLOC2>& img) :_alloc(img._alloc) { ! create_with_own_data(view(img).dimensions()); ! copy_pixels(view(img),_view); } ! template <typename IMG> image& operator=(const IMG& img) { image tmp(img); swap(tmp); return *this; } ! image& operator=(const image& img) { image tmp(img); swap(tmp); return *this; } ! ~image() { ! std::size_t size_in_bytes=_view.row_bytes()*_view.height(); if(std::iterator_traits<typename V::x_iterator>::is_planar) ! size_in_bytes*=V::color_space_type::num_channels; _alloc.deallocate((unsigned char*)&(_view(0,0)[0]),size_in_bytes); } ! template <typename V2, typename ALLOC2> friend const V2& view(image<V2,ALLOC2>& img); ! template <typename V2, typename ALLOC2> friend const typename V2::const_type& const_view(const image<V2,ALLOC2>& img); ! ALLOC& allocator() { return _alloc; } ! ALLOC const& allocator() const { return _alloc; } ! template <typename V2,typename ALLOC2> ! friend void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2); ! void swap(image& img) { GIL::swap(*this,img); } // required by boost::MutableContainerConcept private: ! view_type _view; // contains pointer to the pixels, the image size and ways to navigate pixels allocator_type _alloc; template <bool> class is_planar {}; ! void create_with_own_data(const point_type& dimensions, unsigned int alignment=1) { ! BOOST_STATIC_ASSERT(!has_dynamic_step<typename V::x_iterator>::value); ! create_with_own_data_(dimensions,alignment,is_planar<std::iterator_traits<typename V::x_iterator>::is_planar>()); ! } ! void create_with_own_data_(const point_type& dimensions, unsigned int alignment, is_planar<false>) { ! std::size_t rowsize_in_bytes=get_aligned(dimensions.x*sizeof(typename V::value_type),alignment); unsigned char* tmp=_alloc.allocate(rowsize_in_bytes*dimensions.y); ! try { ! _view=V(dimensions,typename V::x_iterator(tmp),rowsize_in_bytes); ! } catch(...) { ! _alloc.deallocate(tmp, rowsize_in_bytes*dimensions.y); ! throw; ! } ! } void create_with_own_data_(const point_type& dimensions, unsigned int alignment, is_planar<true>) { ! std::size_t planesize_in_bytes=get_aligned(dimensions.x*dimensions.y*sizeof(typename V::channel_type),alignment); ! std::size_t image_size_in_bytes=planesize_in_bytes*V::color_space_type::num_channels; ! unsigned char* tmp=_alloc.allocate(image_size_in_bytes); ! try { ! _view=V(dimensions, typename V::x_iterator(tmp,planesize_in_bytes),dimensions.x*sizeof(typename V::channel_type)); ! } catch(...) { ! _alloc.deallocate(tmp, image_size_in_bytes); ! throw; ! } } *************** *** 302,306 **** if (&im1==&im2) return true; if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false; ! return std::equal(const_view(im1).begin(),const_view(im1).end(),const_view(im2).begin()); // TODO: change this to equal_pixels (for performance) } template <typename V1,typename V2> --- 302,306 ---- if (&im1==&im2) return true; if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false; ! return std::equal(const_view(im1).begin(),const_view(im1).end(),const_view(im2).begin()); // TODO: change this to equal_pixels (for performance) } template <typename V1,typename V2> *************** *** 309,340 **** template <typename V2,typename ALLOC2> inline void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2) { ! swap(im1._view, im2._view); ! std::swap(im1.allocator(), im2.allocator()); } template <typename C> class variant; namespace detail { ! template <typename VC> // Models View Concept Space ! struct any_image_get_view { ! typedef variant<VC> result_type; ! template <typename V> result_type operator()( image<V>& img) const { return result_type(view(img)); } ! }; ! template <typename VC> // Models ConstView Concept Space ! struct any_image_get_const_view { ! typedef variant<VC> result_type; ! template <typename V> result_type operator()(const image<V>& img) const { return result_type(const_view(img)); } ! }; ! struct any_image_view_get_num_channels { ! typedef int result_type; ! template <typename VIEW> result_type operator()(const VIEW& v) const { ! return VIEW::color_space_type::num_channels; ! } ! }; ! struct any_image_view_get_dimensions { ! typedef point2<ptrdiff_t> result_type; ! template <typename VIEW> result_type operator()(const VIEW& v) const { ! return v.dimensions(); ! } ! }; } --- 309,340 ---- template <typename V2,typename ALLOC2> inline void swap(image<V2,ALLOC2>& im1,image<V2,ALLOC2>& im2) { ! swap(im1._view, im2._view); ! std::swap(im1.allocator(), im2.allocator()); } template <typename C> class variant; namespace detail { ! template <typename VC> // Models View Concept Space ! struct any_image_get_view { ! typedef variant<VC> result_type; ! template <typename V> result_type operator()( image<V>& img) const { return result_type(view(img)); } ! }; ! template <typename VC> // Models ConstView Concept Space ! struct any_image_get_const_view { ! typedef variant<VC> result_type; ! template <typename V> result_type operator()(const image<V>& img) const { return result_type(const_view(img)); } ! }; ! struct any_image_view_get_num_channels { ! typedef int result_type; ! template <typename VIEW> result_type operator()(const VIEW& v) const { ! return VIEW::color_space_type::num_channels; ! } ! }; ! struct any_image_view_get_dimensions { ! typedef point2<ptrdiff_t> result_type; ! template <typename VIEW> result_type operator()(const VIEW& v) const { ! return v.dimensions(); ! } ! }; } *************** *** 352,364 **** /// \brief Returns the non-constant-pixel view of any image. The returned view is any view. See variant.h for more ! template <typename IC> // Models Image Concept Space inline variant<typename IC::view_concept_space> view(variant<IC>& anyImage) { ! return anyImage.apply_visitor(detail::any_image_get_view<typename IC::view_concept_space>()); } /// \brief Returns the constant-pixel view of any image. The returned view is any view. See variant.h for more ! template <typename IC> // Models Image Concept Space inline variant<typename IC::const_view_concept_space> const_view(const variant<IC>& anyImage) { ! return anyImage.apply_visitor(detail::any_image_get_const_view<typename IC::const_view_concept_space>()); } ///@} --- 352,364 ---- /// \brief Returns the non-constant-pixel view of any image. The returned view is any view. See variant.h for more ! template <typename IC> // Models Image Concept Space inline variant<typename IC::view_concept_space> view(variant<IC>& anyImage) { ! return anyImage.apply_visitor(detail::any_image_get_view<typename IC::view_concept_space>()); } /// \brief Returns the constant-pixel view of any image. The returned view is any view. See variant.h for more ! template <typename IC> // Models Image Concept Space inline variant<typename IC::const_view_concept_space> const_view(const variant<IC>& anyImage) { ! return anyImage.apply_visitor(detail::any_image_get_const_view<typename IC::const_view_concept_space>()); } ///@} *************** *** 373,377 **** template <typename C_S> int get_num_channels(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_num_channels()); } --- 373,377 ---- template <typename C_S> int get_num_channels(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_num_channels()); } *************** *** 379,383 **** template <typename C_S> int get_width(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()).x; } --- 379,383 ---- template <typename C_S> int get_width(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()).x; } *************** *** 385,389 **** template <typename C_S> int get_height(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()).y; } --- 385,389 ---- template <typename C_S> int get_height(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()).y; } *************** *** 391,395 **** template <typename C_S> point2<int> get_dimensions(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()); } ///@} --- 391,395 ---- template <typename C_S> point2<int> get_dimensions(const variant<C_S>& img_view) { ! return img_view.apply_visitor(detail::any_image_view_get_dimensions()); } ///@} *************** *** 402,413 **** template <typename IMG> void resize_clobber_image(IMG& img, const typename IMG::point_type& new_size) { ! gil_function_requires<ImageConcept<IMG> >(); ! IMG tmp(new_size); ! swap(tmp,img); } template <typename IMG> void resize_clobber_image(IMG& img, const typename IMG::x_coord_type& width, const typename IMG::y_coord_type& height) { ! resize_clobber_image(img, typename IMG::point_type(width,height)); } ///@} --- 402,413 ---- template <typename IMG> void resize_clobber_image(IMG& img, const typename IMG::point_type& new_size) { ! gil_function_requires<ImageConcept<IMG> >(); ! IMG tmp(new_size); ! swap(tmp,img); } template <typename IMG> void resize_clobber_image(IMG& img, const typename IMG::x_coord_type& width, const typename IMG::y_coord_type& height) { ! resize_clobber_image(img, typename IMG::point_type(width,height)); } ///@} Index: cmyk.hpp =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/core/cmyk.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cmyk.hpp 9 Jan 2006 19:37:55 -0000 1.1 --- cmyk.hpp 3 Feb 2006 18:33:37 -0000 1.2 *************** *** 1,6 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ --- 1,6 ---- /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ *************** *** 14,18 **** /// \brief Support for CMYK color space and variants /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated //////////////////////////////////////////////////////////////////////////////////////// --- 14,18 ---- /// \brief Support for CMYK color space and variants /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated //////////////////////////////////////////////////////////////////////////////////////// *************** *** 35,67 **** /// \ingroup CMYK struct cmyk_tag { ! typedef cmyk_tag base; ! BOOST_STATIC_CONSTANT(int, num_channels=4); }; namespace detail { ! /// \ingroup ColorBase ! /// \ingroup CMYK ! /// \brief cyan, magenta, yellow and black channel values/references/pointers ! /// ! /// Represents a CMYK unit of channel values (when used to construct a pixel), channel references (when used in a planar CMYK reference) ! /// or channel pointers (when used in a CMYK planar pointer) defined in this specific ordering in memory. Also provides channel accessors ! /// v0(), v1(), v2(), v3() agnostic of color space, which allow uniform operations on channels of different color spaces. The accessors also have ! /// consistent mapping between color bases representing order variations of the same color space. For example, v0() returns the red ! /// channel value/reference/pointer in both an rgb color base and in a bgr color base. ! template <typename T> ! struct color_base<T,cmyk_tag> { ! typedef cmyk_tag color_space_type; ! typedef T channel_type; ! typedef typename boost::add_const<channel_type>::type channel_const_type; ! typedef typename boost::add_reference<channel_type>::type channel_reference; ! typedef typename boost::add_reference<channel_const_type>::type channel_const_reference; ! T c,m,y,k; ! color_base() {} ! color_base(channel_type v0, channel_type v1, channel_type v2, channel_type v3) : c(v0), m(v1), y(v2), k(v3) {} ! template <typename T1, typename C1> color_base(const color_base<T1,C1>& cb) : c(cb.c), m(cb.m), y(cb.y), k(cb.k) {} ! template <typename T1, typename C1> color_base( color_base<T1,C1>& cb) : c(cb.c), m(cb.m), y(cb.y), k(cb.k) {} ! }; } --- 35,67 ---- /// \ingroup CMYK struct cmyk_tag { ! typedef cmyk_tag base; ! BOOST_STATIC_CONSTANT(int, num_channels=4); }; namespace detail { ! /// \ingroup ColorBase ! /// \ingroup CMYK ! /// \brief cyan, magenta, yellow and black channel values/references/pointers ! /// ! /// Represents a CMYK unit of channel values (when used to construct a pixel), channel references (when used in a planar CMYK reference) ! /// or channel pointers (when used in a CMYK planar pointer) defined in this specific ordering in memory. Also provides channel accessors ! /// v0(), v1(), v2(), v3() agnostic of color space, which allow uniform operations on channels of different color spaces. The accessors also have ! /// consistent mapping between color bases representing order variations of the same color space. For example, v0() returns the red ! /// channel value/reference/pointer in both an rgb color base and in a bgr color base. ! template <typename T> ! struct color_base<T,cmyk_tag> { ! typedef cmyk_tag color_space_type; ! typedef T channel_type; ! typedef typename boost::add_const<channel_type>::type channel_const_type; ! typedef typename boost::add_reference<channel_type>::type channel_reference; ! typedef typename boost::add_reference<channel_const_type>::type channel_const_reference; ! T c,m,y,k; ! color_base() {} ! color_base(channel_type v0, channel_type v1, channel_type v2, channel_type v3) : c(v0), m(v1), y(v2), k(v3) {} ! template <typename T1, typename C1> color_base(const color_base<T1,C1>& cb) : c(cb.c), m(cb.m), y(cb.y), k(cb.k) {} ! template <typename T1, typename C1> color_base( color_base<T1,C1>& cb) : c(cb.c), m(cb.m), y(cb.y), k(cb.k) {} ! }; } *************** *** 74,78 **** //////////////////////////////////////////////////////////////////////////////////////// ! /// PLANAR CMYK //////////////////////////////////////////////////////////////////////////////////////// --- 74,78 ---- //////////////////////////////////////////////////////////////////////////////////////// ! /// PLANAR CMYK //////////////////////////////////////////////////////////////////////////////////////// *************** *** 86,110 **** template <typename T> struct planar_ptr<T,cmyk_tag> : public planar_ptr_base<T,cmyk_tag> { ! typedef planar_ptr_base<T,cmyk_tag> parent_type; typedef typename parent_type::reference reference; typedef typename parent_type::color_space_type color_space_type; ! planar_ptr() : parent_type(0,0,0,0) {} ! planar_ptr(T* ic, T* im, T* iy, T* ik) : parent_type(ic,im,iy,ik) {} ! // from raw data ! planar_ptr(unsigned char* data, ptrdiff_t step=1) : parent_type((T*)data, (T*)(data+step), (T*)(data+step+step), (T*)(data+step*3)) {} ! planar_ptr(const planar_ptr& ptr) : parent_type(ptr) {} ! planar_ptr& operator=(const planar_ptr& ptr) { this->p=ptr.p; return *this; } ! /// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references. ! /// That allow constructs like pointer = &value or pointer = &reference ! /// Since we should not override operator& that's the best we can do. ! template <typename T1, typename C1> planar_ptr(pixel<T1,C1>* pix) : parent_type(&pix->template v<0>(),&pix->template v<1>(), &pix->template v<2>(), &pix->template v<3>()) { STATIC_ASSERT_COMPATIBLE(T1,C1,T,color_space_type); } ! template <typename T1, typename C1> planar_ptr& operator=(pixel<T1,C1>* pix) { STATIC_ASSERT_COMPATIBLE(T1,C1,T,color_space_type); this->p.template v<0>()=&pix->template v<0>(); --- 86,110 ---- template <typename T> struct planar_ptr<T,cmyk_tag> : public planar_ptr_base<T,cmyk_tag> { ! typedef planar_ptr_base<T,cmyk_tag> parent_type; typedef typename parent_type::reference reference; typedef typename parent_type::color_space_type color_space_type; ! planar_ptr() : parent_type(0,0,0,0) {} ! planar_ptr(T* ic, T* im, T* iy, T* ik) : parent_type(ic,im,iy,ik) {} ! // from raw data ! planar_ptr(unsigned char* data, ptrdiff_t step=1) : parent_type((T*)data, (T*)(data+step), (T*)(data+step+step), (T*)(data+step*3)) {} ! planar_ptr(const planar_ptr& ptr) : parent_type(ptr) {} ! planar_ptr& operator=(const planar_ptr& ptr) { this->p=ptr.p; return *this; } ! /// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references. ! /// That allow constructs like pointer = &value or pointer = &reference ! /// Since we should not override operator& that's the best we can do. ! template <typename T1, typename C1> planar_ptr(pixel<T1,C1>* pix) : parent_type(&pix->template v<0>(),&pix->template v<1>(), &pix->template v<2>(), &pix->template v<3>()) { STATIC_ASSERT_COMPATIBLE(T1,C1,T,color_space_type); } ! template <typename T1, typename C1> planar_ptr& operator=(pixel<T1,C1>* pix) { STATIC_ASSERT_COMPATIBLE(T1,C1,T,color_space_type); this->p.template v<0>()=&pix->template v<0>(); *************** *** 115,119 **** } ! reference dereference() const { return reference(*(this->p.c),*(this->p.m),*(this->p.y),*(this->p.k)); } }; --- 115,119 ---- } ! reference dereference() const { return reference(*(this->p.c),*(this->p.m),*(this->p.y),*(this->p.k)); } }; *************** *** 122,155 **** template <typename T> inline pixel<T&,cmyk_tag> byte_advanced_ref(const planar_ptr<T,cmyk_tag>& p, ptrdiff_t byteDiff) { ! return pixel<T&,cmyk_tag>(*byte_advanced(p.p.c, byteDiff), *byte_advanced(p.p.m, byteDiff), ! *byte_advanced(p.p.y, byteDiff), *byte_advanced(p.p.k, byteDiff)); } namespace detail { ! template <typename CS,int N> struct logical_channel_accessor; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,0> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.c;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.c;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,1> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.m;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.m;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,2> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.y;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.y;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,3> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.k;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.k;} ! }; } --- 122,155 ---- template <typename T> inline pixel<T&,cmyk_tag> byte_advanced_ref(const planar_ptr<T,cmyk_tag>& p, ptrdiff_t byteDiff) { ! return pixel<T&,cmyk_tag>(*byte_advanced(p.p.c, byteDiff), *byte_advanced(p.p.m, byteDiff), ! *byte_advanced(p.p.y, byteDiff), *byte_advanced(p.p.k, byteDiff)); } namespace detail { ! template <typename CS,int N> struct logical_channel_accessor; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,0> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.c;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.c;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,1> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.m;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.m;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,2> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.y;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.y;} ! }; ! /// \ingroup ChannelAccessor ! template <> ! struct logical_channel_accessor<cmyk_tag,3> { ! template <typename T> typename boost::add_reference<T>::type operator()(pixel<T,cmyk_tag>& p) const {return p.k;} ! template <typename T> typename boost::add_reference<typename boost::add_const<T>::type>::type operator()(const pixel<T,cmyk_tag>& p) const {return p.k;} ! }; } Index: pixel.hpp =================================================================== RCS file: /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/core/pixel.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pixel.hpp 9 Jan 2006 19:37:55 -0000 1.1 --- pixel.hpp 3 Feb 2006 18:33:37 -0000 1.2 *************** *** 1,6 **** /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ --- 1,6 ---- /* ! Copyright 2005-2006 Adobe Systems Incorporated ! Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt ! or a copy at http://opensource.adobe.com/licenses.html) */ *************** *** 11,18 **** //////////////////////////////////////////////////////////////////////////////////////// ! /// \file /// \brief generic pixel definitions and utilities /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated /// Last updated on 11-06-2005 /// --- 11,18 ---- //////////////////////////////////////////////////////////////////////////////////////// ! /// \file /// \brief generic pixel definitions and utilities /// \author Lubomir Bourdev and Hailin Jin \n ! /// Adobe Systems Incorporated /// Last updated on 11-06-2005 /// *************** *** 31,217 **** namespace detail { ! /// \addtogroup ColorBase ! /// \brief Represents a bundle of channel values/references/pointers for a specific color space. ! /// ! /// The class is used in three different cases: ! /// - As a base for pixel values, in which case it instantiates into a set of channel values whose relative ordering is specified by C ! /// - As a base for the proxy class representing a reference to a planar pixel, in which case it instantiates into a set of channel references ! /// - In the construction of planar_ptr, the proxy class representing a pointer to a planar pixel, in which case in instantiates into a set of channel pointers ! /// ! /// Color bases also provide color-space independent accessors to the channel values/references/pointers, which allows us to perform color-space-independent ! /// channel operations (see pixel_base for more). ! /// ! /// color_base specializations are provided for each color space. See concrete specializations for more. ! template <typename T, typename C> struct color_base {}; ! /// \ingroup ColorConvert ! /// \brief Color Convertion function object. To be specialized for every src/dst color space ! template <typename T1, typename C1, typename T2, typename C2> ! struct _color_converter { ! template <typename P1, typename P2> void operator()(const P1& src, P2& dst); ! }; ! /// \addtogroup ChannelAccessor ! /// ! /// Returns the N-th logical channel of a pixel. Logical channel indices are the same across related color spaces. For example, the red channel has index 0 in both rgb and bgr ! /// Specialized for each index and each color space. Instead of this class, it would be easier to provide in each color base specialization a ! /// member function templated over the channel index. Unfortunately many compilers don't support fully specialized member functions inside partially specialized classes. ! template <typename CS,int N> struct logical_channel_accessor {}; ! /// \brief Returns the N-th channel of a pixel as laid down in memory ! /// \ingroup ChannelAccessor ! template <typename CS> ! struct physical_channel_accessor { ! // pixel has the structure of an array of T. Getting a reference to the i-th value ! template <typename T> T& operator()(pixel<T,CS>& p,size_t i) const { return ((T*)(&p))[i]; } ! template <typename T> const T& operator()(const pixel<T,CS>& p,size_t i) const {return ((const T*)(&p))[i]; } ! // pixel is an array of _references_ to T. Getting the i-th reference ! template <typename T> T& operator()(pixel<T&,CS>& p,size_t i) const { return *(((T**)((T*)&p))[i]); } ! template <typename T> const T& operator()(pixel<const T&,CS>& p,size_t i) const { return *(((const T**)((const T*)&p))[i]); } ! }; ! /// \brief compile-time recursion for per-channel operations of pixels ! /// \ingroup Pixel ! template <int N> struct recur { ! template <typename P,typename F> static void multiplies_eq(P& p, F x) { ! recur<N-1>::multiplies_eq(p,x); ! p.template v<N>()*=x; ! } ! template <typename P,typename F> static void divides_eq(P& p, F x) { ! recur<N-1>::divides_eq(p,x); ! p.template v<N>()/=x; ! } ! template <typename P1,typename P2> static void set_val(P1& p1, const P2& p2) { ! recur<N-1>::set_val(p1,p2); ! p1.template v<N>()=p2.template v<N>(); ! } ! template <typename P1,typename P2> static void plus_eq(P1& p1, const P2& p2) { ! recur<N-1>::plus_eq(p1,p2); ! p1.template v<N>()+=p2.template v<N>(); ! } ! template <typename P1,typename P2> static void minus_eq(P1& p1, const P2& p2) { ! recur<N-1>::minus_eq(p1,p2); ! p1.template v<N>()-=p2.template v<N>(); ! } ! template <typename P,typename T2> static void set_channels(P& p, T2 v) { ! recur<N-1>::set_channels(p,v); ! p.template v<N>()=v; ! } ! template <typename P1,typename P2> static bool equal_to(const P1& p1, const P2& p2) { ! return recur<N-1>::equal_to(p1,p2) && p1.template v<N>()==p2.template v<N>(); ! } ! template <typename OP,typename P1> ! static void per_channel_op(const P1& p1, OP& op) { ! recur<N-1>::per_channel_op(p1,op); ! op(p1.template v<N>()); ! } ! template <typename OP, typename P1,typename P2> ! static void per_channel_op(const P1& p1, const P2& p2, OP& op) { ! recur<N-1>::per_channel_op(p1,p2,op); ! op(p1.template v<N>(), p2.template v<N>()); ! } ! template <typename OP, typename P1,typename P2, typename P3> ! static void per_channel_op(const P1& p1, const P2& p2, const P3& p3, OP& op) { ! recur<N-1>::per_channel_op(p1,p2,p3,op); ! op(p1.template v<N>(), p2.template v<N>(), p3.template v<N>()); ! } ! template <typename OP,typename P> ! static void per_channel_set_op(P& dst, OP& op) { ! recur<N-1>::per_channel_set_op(dst,op); ! dst.template v<N>()=op(); ! } ! template <typename OP,typename P, typename P1> ! static void per_channel_set_op(P& dst, const P1& src, OP& op) { ! recur<N-1>::per_channel_set_op(dst,src,op); ! dst.template v<N>()=op(src.template v<N>()); ! } ! template <typename OP,typename P,typename P1, typename P2> ! static void per_channel_set_op(P& dst, const P1& src1, const P2& src2, OP& op) { ! recur<N-1>::per_channel_set_op(dst,src1,src2,op); ! dst.template v<N>()=op(src1.template v<N>(), src2.template v<N>()); ! } ! //#ifdef PROVIDE_CONST_VERSIONS ! template <typename OP,typename P1> ! static void per_channel_op(const P1& p1, const OP& op) { ! recur<N-1>::per_channel_op(p1,op); ! op(p1.template v<N>()); ! } ! template <typename OP, typename P1,typename P2> ! static void per_channel_op(const P1& p1, const P2& p2, const OP& op) { ! recur<N-1>::per_channel_op(p1,p2,op); ! op(p1.template v<N>(), p2.template v<N>()); ! } ! template <typename OP, typename P1, typename P2, typename P3> ! static void per_channel_op(const P1& p1, const P2& p2, const P3& p3, const OP& op) { ! recur<N-1>::per_channel_op(p1,p2,p3,op); ! op(p1.template v<N>(), p2.template v<N>(), p3.template v<N>()); ! } ! template <typename OP,typename P> ! static void per_channel_set_op(P& dst, const OP& op) { ! recur<N-1>::per_channel_set_op(dst,op); ! dst.template v<N>()=op(); ! } ! template <typename OP,typename P,typename P1> ! static void per_channel_set_op(P& dst, const P1& src, const OP& op) { ! recur<N-1>::per_channel_set_op(dst,src,op); ! dst.template v<N>()=op(src.template v<N>()); ! } ! template <typename OP,typename P,typename P1,typename P2> ! static void per_channel_set_op(P& dst, const P1& src1, const P2& src2, const OP& op) { ! recur<N-1>::per_channel_set_op(dst,src1,src2,op); ! dst.template v<N>()=op(src1.template v<N>(), src2.template v<N>()); ! } ! //#endif ! }; ! /// \brief termination condition of the compile-time recursion for channel operations on a pixel ! /// \ingroup Pixel ! template<> struct recur<-1> { ! template <typename P, typename F> static void multiplies_eq(P& p, F x) {} ! template <typename P, typename F> static void divides_eq(P& p, F x) {} ! template <typename P1,typename P2> static void set_val(P1& p1, const P2& p2) {} ! template <typename P1,typename P2> static void plus_eq(P1& p1, const P2& p2) {} ! template <typename P1,typename P2> static void minus_eq(P1& p1, const P2& p2) {} ! template <typename P, typename T2> static void set_channels(P& p, T2 v) {} ! template <typename P1,typename P2> static bool equal_to(const P1& p1, const P2& p2) { return true; } ! template <typename OP,typename P1> static void per_channel_op(const P1&,OP&){} ! template <typename OP,typename P1,typename P2> static void per_channel_op(const P1&,const P2&,OP&){} ! template <typename OP,typename P1,typename P2,typename P3> static void per_channel_op(const P1&,const P2&,const P3&,OP&){} ! template <typename OP,typename P> static void per_channel_set_op(P&,OP&){} ! template <typename OP,typename P, typename P1> static void per_channel_set_op(P&,const P1&,OP&){} ! template <typename OP,typename P, typename P1, typename P2> static void per_channel_set_op(P&,const P1&,const P2&,OP&){} ! //#ifdef PROVIDE_CONST_VERSIONS ! template <typename OP,typename P1> static void per_channel_op(const P1&,const OP&){} ! template <typename OP,typename P1,typename P2> static void per_channel_op(const P1&,const P2&,const OP&){} ! template <typename OP,typename P1,typename P2,typename P3> static void per_channel_op(const P1&,const P2&,const P3&,const OP&){} ! template <typename OP,typename P> static void per_channel_set_op(P&,const OP&){} ! template <typename OP,typename P, typename P1> static void per_channel_set_op(P&,const P1&,const OP&){} ! template <typename OP,typename P, typename P1, typename P2> static void per_channel_set_op(P&,const P1&,const P2&,const OP&){} ! //#endif ! }; ! /// \brief compile-time recursion for min/max channel ! /// \ingroup Pixel ! template <int N> ! struct min_max_recur { ! template <typename P> static typename P::channel_value_type max_(const P& p) { ! return std::max(min_max_recur<N-1>::max_(p),p.template v<N>()); ! } ! template <typename P> static typename P::channel_value_type min_(const P& p) { ! return std::min(min_max_recur<N-1>::min_(p),p.template v<N>()); ! } ! }; ! /// \brief termination condition of the compile-time recursion for min/max channel ! /// \ingroup Pixel ! template <> ! struct min_max_recur<0> { ! template <typename P> static typename P::channel_value_type max_(const P& p) { return p.template v<0>(); } ! template <typename P> static typename P::channel_value_type min_(const P& p) { return p.template v<0>(); } ! }; ! } // namespace detail //@{ --- 31,217 ---- namespace detail { ! /// \addtogroup ColorBase ! /// \brief Represents a bundle of channel values/references/pointers for a specific color space. ! /// ! /// The class is used in three different cases: ! /// - As a base for pixel values, in which case it instantiates into a set of channel values whose relative ordering is specified by C ! /// - As a base for the proxy class representing a reference to a planar pixel, in which case it instantiates into a set of channel references ! /// - In the construction of planar_ptr, the proxy class representing a pointer to a planar pixel, in which case in instantiates into a set of channel pointers ! /// ! /// Color bases also provide color-space i... [truncated message content] |