From: Foster B. <fos...@us...> - 2006-01-09 19:38:07
|
Update of /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20413 Added 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.12 stragglers --- NEW FILE: image.hpp --- /* 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) */ /*************************************************************************************************/ #ifndef GIL_IMAGE_H #define GIL_IMAGE_H //////////////////////////////////////////////////////////////////////////////////////// /// \file /// \brief Templated image /// \author Lubomir Bourdev and Hailin Jin \n /// Adobe Systems Incorporated /// /// //////////////////////////////////////////////////////////////////////////////////////// #include "gil_config.hpp" #include <memory> #include "pixel_iterator.hpp" ADOBE_GIL_NAMESPACE_BEGIN template <typename V1, typename V2> void copy_pixels(const V1& src, const V2& dst); #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. /// /// Image view consists of a pixel 2D locator (defining the mechanism for navigating in 2D) /// and the image dimensions. /// /// Image views to images are what ranges are to STL containers. They are lightweight objects, /// that don't own the pixels. It is the user's responsibility that the underlying data remains /// valid for the lifetime of the image view. /// /// Similar to iterators and ranges, constness of views does not extend to constness of pixels. /// A const image_view does not allow changing its location in memory (resizing, moving) but does /// not prevent one from changing the pixels. The latter requires an image view whose value_type /// is const. /// /// Images have interfaces consistent with STL 1D random access containers, so they can be used /// directly in STL algorithms like: /// std::fill(img.begin(), img.end(), red_pixel); /// or /// std::transform(img.begin(), img.end(), dst.begin(), color_converter<rgb8_pixel>()); // convert src to RGB /// /// In addition, horizontal, vertical and 2D random access iterators are provided. /// //////////////////////////////////////////////////////////////////////////////////////// template <typename LOC> class pixel_image_iterator; template <typename LOC> // Models 2D Pixel Locator class image_view { GIL_CLASS_REQUIRE(LOC, GIL, XYLocatorConcept); 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 /// /// image is a wrapper over image_view that owns the data. /// Images have deep copy constructor, operator= and operator==. /// A constant image does not allow for modifying its pixels. //////////////////////////////////////////////////////////////////////////////////////// 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; } } }; template <typename V1,typename V2> bool operator==(const image<V1>& im1,const image<V2>& im2) { 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> bool operator!=(const image<V1>& im1,const image<V2>& im2) {return !(im1==im2);} 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(); } }; } ///@{ /// \name view, const_view /// \brief Get an image view from an image /// \ingroup Image /// \brief Returns the non-constant-pixel view of an image template <typename V2, typename ALLOC2> inline const V2& view(image<V2,ALLOC2>& img) { return img._view; } /// \brief Returns the constant-pixel view of an image template <typename V2, typename ALLOC2> inline const typename V2::const_type& const_view(const image<V2,ALLOC2>& img) { return (typename V2::const_type&)img._view; } /// \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>()); } ///@} ///@{ /// \name get_num_channels /// \brief Returns the number of channels of an image view /// \ingroup ImageView template <typename LOC> int get_num_channels(const image_view<LOC>& view) { return image_view<LOC>::color_space_type::num_channels; } 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()); } ///@} ///@{ /// \name get_width, get_height, get_dimensions /// \brief Returns the dimensions of an image view /// \ingroup ImageView /// \brief Returns the width of a templated image view template <typename LOC> int get_width(const image_view<LOC>& view) { return view.width(); } /// \brief Returns the width of any image view 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; } /// \brief Returns the height of a templated image view template <typename LOC> int get_height(const image_view<LOC>& view) { return view.width(); } /// \brief Returns the height of any image view 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; } /// \brief Returns the dimensions of a templated image view template <typename LOC> point2<int> get_dimensions(const image_view<LOC>& view) { return view.dimensions(); } /// \brief Returns the dimensions of any image view 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()); } ///@} ///@{ /// \name resize_clobber_image /// \brief Resizes a given image and invalidates its pixel values. If out of memory exception is thrown the image remains unchanged /// \ingroup Image 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)); } ///@} #ifdef _MSC_VER #pragma warning(pop) #endif ADOBE_GIL_NAMESPACE_END #endif --- NEW FILE: cmyk.hpp --- /* 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) */ /*************************************************************************************************/ #ifndef GIL_CMYK_H #define GIL_CMYK_H //////////////////////////////////////////////////////////////////////////////////////// /// \file /// \brief Support for CMYK color space and variants /// \author Lubomir Bourdev and Hailin Jin \n /// Adobe Systems Incorporated //////////////////////////////////////////////////////////////////////////////////////// #include "gil_config.hpp" #include <boost/type_traits.hpp> ADOBE_GIL_NAMESPACE_BEGIN //forward declarations for pixel and color_base template <typename T, typename C> struct pixel; namespace detail { template <typename T, typename C> struct color_base; } template <typename T, typename C> struct planar_ptr; template <typename T, typename C> struct planar_ptr_base; /// @defgroup CMYK CMYK Color Space /// @ingroup ColorSpaces /// \brief Constructs and utilities specific to the CMYK color space /// \brief CMYK color space identifier /// \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) {} }; } ADOBE_GIL_NAMESPACE_END #include "pixel_iterator.hpp" // these need to be defined after including pixel... ADOBE_GIL_NAMESPACE_BEGIN //////////////////////////////////////////////////////////////////////////////////////// /// PLANAR CMYK //////////////////////////////////////////////////////////////////////////////////////// /// \brief Represents a pointer to a planar CMYK pixel. /// \ingroup PlanarPtr /// \ingroup CMYK /// /// A pointer can be constructed from and assigned to the address of a value, the address of a reference or another pointer /// It can also be dereferenced returning a reference 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>(); this->p.template v<1>()=&pix->template v<1>(); this->p.template v<2>()=&pix->template v<2>(); this->p.template v<3>()=&pix->template v<3>(); return *this; } reference dereference() const { return reference(*(this->p.c),*(this->p.m),*(this->p.y),*(this->p.k)); } }; /// \ingroup byte_advanced_ref /// Advancing a CMYK pixel by a given number of bytes 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;} }; } ADOBE_GIL_NAMESPACE_END #endif --- NEW FILE: pixel.hpp --- /* 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) */ /*************************************************************************************************/ #ifndef GIL_PIXEL_H #define GIL_PIXEL_H //////////////////////////////////////////////////////////////////////////////////////// /// \file /// \brief generic pixel definitions and utilities /// \author Lubomir Bourdev and Hailin Jin \n /// Adobe Systems Incorporated /// Last updated on 11-06-2005 /// //////////////////////////////////////////////////////////////////////////////////////// #include "gil_config.hpp" #include "gil_concept.hpp" #include "channel.hpp" #include <boost/static_assert.hpp> #include <boost/utility/enable_if.hpp> #include <functional> #include "metafunctions.hpp" #include "utilities.hpp" ADOBE_GIL_NAMESPACE_BEGIN 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 templa... [truncated message content] |