text: #pragma once
  
  #include "ofConstants.h"
  #include "ofUtils.h"
  #include "ofColor.h"
  #include "ofMath.h"
  #include <limits>
  
  
  /// \file
  /// ofPixels is an object for working with blocks of pixels, those pixels can
  /// be copied from an image that you've loaded, something that you've drawn
  /// using ofGraphics, or a ofVideoGrabber instance. 
  ///
  /// You can create an image from pixels, using on ofPixels object like so:
  /// 
  /// ~~~~{.cpp}
  /// ofPixels p;
  /// ofLoadImage(p, "pathToImage.jpg");
  /// ~~~~
  ///
  /// ofPixels represents pixels data on the CPU as opposed to an ofTexture
  /// which represents pixel data on the GPU. They can easily be made inter-
  /// operational though:
  /// 
  /// ~~~~{.cpp}
  /// ofTexture tex;
  /// // do some stuff with tex
  /// ofPixels pix;
  /// tex.readToPixels(pix); // now all the pixels from tex are in pix
  /// ~~~~
  ///
  /// You can access the pixels in an ofPixels object with the `[]` operator.
  ///
  /// ~~~~{.cpp}
  /// ofPixels pix;
  /// // put some stuff in the pixels
  /// int i = 0;
  /// while( i < pix.size()) {
  /// 	char c = pix[i];
  /// 	i++;
  /// }
  /// ~~~~
  /// 
  /// You can think of the ofPixels as the CPU side representation of pixel data
  /// that can be sent to the GPU as an ofTexture object. To draw pixels, you
  /// need to put them into an ofTexture and to manipulate an ofTextures pixel
  /// data you need an ofPixels object.
  
  
  enum ofInterpolationMethod {
  	OF_INTERPOLATE_NEAREST_NEIGHBOR =1,
  	OF_INTERPOLATE_BILINEAR			=2,
  	OF_INTERPOLATE_BICUBIC			=3
  };
  
  
  /// \brief A class representing a collection of pixels.
  template <typename PixelType>
  class ofPixels_ {
  public:
  
  	/// \name Construction And Allocation
  	/// \{
  	ofPixels_();
  	~ofPixels_();
  	ofPixels_(const ofPixels_<PixelType> & mom);
  
  	template<typename SrcType>
  	ofPixels_(const ofPixels_<SrcType> & mom);
  
  
  	/// \brief Allocates space for pixel data
  	/// \param w Width of pixel array
  	/// \param h Height of pixel array
  	/// \param channels Number of channels per pixel
  	void allocate(int w, int h, int channels);
  	
  	/// \brief Allocates space for pixel data
  	///
  	/// The pixelFormat can be one of the following:
  	///
  	///     OF_PIXELS_RGB
  	///     OF_PIXELS_RGBA
  	///     OF_PIXELS_BGRA
  	///     OF_PIXELS_MONO
  	/// 
  	/// \param w Width of pixel array
  	/// \param h Height of pixel array
  	/// \param pixelFormat ofPixelFormat defining number of channels per pixel
  	void allocate(int w, int h, ofPixelFormat pixelFormat);
  
  	/// \brief Allocates space for pixel data
  	///
  	/// The imageType can be one of the following:
  	///
  	///     OF_IMAGE_GRAYSCALE
  	///     OF_IMAGE_COLOR
  	///     OF_IMAGE_COLOR_ALPHA
  	/// 
  	/// \param w Width of pixel array
  	/// \param h Height of pixel array
  	/// \param imageType ofImageType defining number of channels per pixel
  	void allocate(int w, int h, ofImageType imageType);
  
  	/// \brief Get whether memory has been allocated for an ofPixels object or not
  	///
  	/// Many operations like copying pixels, etc, automatically allocate
  	/// the memory needed, but it's sometimes good to check.
  	bool isAllocated() const;
  
  	/// \brief Clear all the data from the ofPixels objects. 
  	/// After calling this you'll need to allocate() 
  	/// the ofPixels object again to use it.
  	void clear();
  
  	ofPixels_<PixelType>& operator=(const ofPixels_<PixelType> & mom);
  
  	template<typename SrcType>
  	ofPixels_<PixelType>& operator=(const ofPixels_<SrcType> & mom);
  	
  	/// \}
  	/// \name Set Pixel Data
  	/// \{
  
  	void set(PixelType val);
  	void set(int channel,PixelType val);
  	void setFromPixels(const PixelType * newPixels,int w, int h, int channels);
  	void setFromPixels(const PixelType * newPixels,int w, int h, ofPixelFormat pixelFormat);
  	void setFromPixels(const PixelType * newPixels,int w, int h, ofImageType type);
  	void setFromExternalPixels(PixelType * newPixels,int w, int h, int channels);
  	void setFromExternalPixels(PixelType * newPixels,int w, int h, ofPixelFormat pixelFormat);
  	void setFromAlignedPixels(const PixelType * newPixels, int width, int height, int channels, int stride);
  	void setFromAlignedPixels(const PixelType * newPixels, int width, int height, ofPixelFormat pixelFormat, int stride);
  	
  	void swap(ofPixels_<PixelType> & pix);
  
  	/// \}
  	/// \name Modify Existing Data
  	/// \{
  
  	/// \brief Crop the pixels to a new width and height. 
  	///
  	/// As a word of caution this reallocates memory and can be a bit
  	/// expensive if done a lot.
  	void crop(int x, int y, int width, int height);
  	
  	/// \brief Crop the pixels into the ofPixels reference passed in by `toPix.
  	/// at the `x` and `y` and width the new width and height. 
  	///
  	/// As a word of caution this reallocates memory and can be a bit
  	/// expensive if done a lot.
  	void cropTo(ofPixels_<PixelType> &toPix, int x, int y, int width, int height) const;
  
  	// crop to a new width and height, this reallocates memory.
  	void rotate90(int nClockwiseRotations);
  	void rotate90To(ofPixels_<PixelType> & dst, int nClockwiseRotations) const;
  	void mirrorTo(ofPixels_<PixelType> & dst, bool vertically, bool horizontal) const;
  	
  	/// \brief Mirror the pixels across the vertical and/or horizontal axis.
  	/// \param vertically Set to true to mirror vertically
  	/// \param horizontal Set to true to mirror horizontal
  	void mirror(bool vertically, bool horizontal);
  	
  	/// \brief Resize the ofPixels instance to the dstHeight and dstWidth. 
  	///
  	/// The options for the interpolation methods are as follows:
  	/// 
  	///     OF_INTERPOLATE_NEAREST_NEIGHBOR
  	///     OF_INTERPOLATE_BILINEAR		
  	///     OF_INTERPOLATE_BICUBIC		
  	bool resize(int dstWidth, int dstHeight, ofInterpolationMethod interpMethod=OF_INTERPOLATE_NEAREST_NEIGHBOR);	
  
  	/// \brief Resize the ofPixels instance to the size of the ofPixels object passed in dst. 
  	///
  	/// The options for the interpolation methods are as follows:
  	/// 
  	///     OF_INTERPOLATE_NEAREST_NEIGHBOR
  	///     OF_INTERPOLATE_BILINEAR		
  	///     OF_INTERPOLATE_BICUBIC		
  	bool resizeTo(ofPixels_<PixelType> & dst, ofInterpolationMethod interpMethod=OF_INTERPOLATE_NEAREST_NEIGHBOR) const;
  	
  	/// \brief Paste the ofPixels object into another ofPixels object at the
  	/// specified index, copying data from the ofPixels that the method is
  	/// being called on to the ofPixels object at `&dst`. If the data being
  	/// copied doesn't fit into the destination then the image is cropped.
  	bool pasteInto(ofPixels_<PixelType> &dst, int x, int y) const;
  
  	bool blendInto(ofPixels_<PixelType> &dst, int x, int y) const;
  
  	/// \brief Swaps the R and B channels of an
  	/// image, leaving the G and A channels as is.
  	void swapRgb();
  
  	/// \}
  	/// \name Pixels Access
  	/// \{
  
  	/// \brief Retrieves pixel data from the ofPixel object.
  	///
  	/// \returns A raw pointer to the pixel data.
  	PixelType * getData();
  	const PixelType * getData() const;
  	OF_DEPRECATED_MSG("Use getData instead",PixelType * getPixels());
  	OF_DEPRECATED_MSG("Use getData instead",const PixelType * getPixels() const);
  
  	OF_DEPRECATED_MSG("Accessing pixels as unsigned char*, instead use ofPixels or getPixels().getData() if you are really trying to access the raw data",operator PixelType*());
  	OF_DEPRECATED_MSG("Accessing pixels as unsigned char*, instead use ofPixels or getPixels().getData() if you are really trying to access the raw data",operator const PixelType*());
  
  	
  	/// \brief Get the pixel index at a x,y position
  	///
  	/// ~~~~{.cpp}
  	/// ofColor yellow = ofColor::yellow;
  	/// int ind = pix.getPixelIndex(mouseX, mouseY);
  	/// pix.setPixel(ind, yellow);
  	/// ~~~~
  	int getPixelIndex(int x, int y) const;
  	
  	/// \brief Get the color at a x,y position
  	ofColor_<PixelType> getColor(int x, int y) const;
  
  	/// \brief Get the color at a specific index
  	ofColor_<PixelType> getColor(int index) const;
  	
  	/// \brief Set the color of the pixel at the x,y location
  	void setColor(int x, int y, const ofColor_<PixelType>& color);
  
  	/// \brief Set the color of the pixel at a specific index
  	void setColor(int index, const ofColor_<PixelType>& color);
  
  	/// \brief Set the color of all pixels
  	void setColor(const ofColor_<PixelType>& color);
  
  	/// \brief Provides access to each channel of each pixel. If you have RGB pixel
  	/// data, then you'll have 3 values for each pixel, if you have RGBA,
  	/// you'll have 4
  	const PixelType& operator[](int pos) const;
  	PixelType& operator[](int pos);
  
  	/// \}
  	/// \name Getters
  	/// \{
  
  	/// \brief Get the width of the pixel array.
  	int getWidth() const;
  	
  	/// \brief Get the height of the pixel array.
  	int getHeight() const;
  
  	/// \brief Get the number of bytes per pixel
  	int getBytesPerPixel() const;
  
  	/// \brief Get number of bits per pixel
  	///
  	/// If you have RGB pixel data, this will return 24, if you have RGBA,
  	/// you'll have 32, if you have grayscale, this will return 8.
  	int getBitsPerPixel() const;
  	
  	/// \brief Get how large each channel of a pixel is
  	///
  	/// ofPixels objects that store pixel data as unsigned char are smaller
  	/// than  ofPixels objects that store pixel data as floats.	
  	/// 
  	/// \note This returns bytes, not bits, so you should see ofPixels<float>
  	/// return 4 and ofPixels<unsigned char> return 1.
  	int getBytesPerChannel() const;
  
  	/// \brief Get how large each channel of a pixels is.
  	///
  	/// ofPixels objects that store pixel data as `unsigned char` are smaller
  	/// than ofPixels objects that store pixel data as 'float`.	
  	/// 
  	/// \note This returns bits, not bytes, so you should see ofPixels<float>
  	/// return 32 and ofPixels<unsigned char> return 8.
  	int getBitsPerChannel() const;
  	int getBytesStride() const;
  	
  	/// \brief Get the number of channels that the ofPixels object contains.
  	/// RGB is 3 channels, RGBA is 4, and grayscale is 1.	
  	int getNumChannels() const;
  
  	int getTotalBytes() const;
  
  	int getNumPlanes() const;
  
  	ofPixels_<PixelType> getPlane(int plane);
  	
  	/// \brief Get all values of one channel
  	///
  	/// For instance, the Red pixel values, from the
  	/// ofPixels object, this gives you a grayscale representation of the
  	/// specific channel
  	/// 
  	/// ~~~~{.cpp}
  	///     // Get red pixels
  	/// 	ofPixels rpix = pix.getChannel(0);
  	///     // Get green pixels
  	/// 	ofPixels gpix = pix.getChannel(1);
  	///     // Get blue pixels
  	/// 	ofPixels bpix = pix.getChannel(2);
  	/// ~~~~
  	ofPixels_<PixelType> getChannel(int channel) const;
  	
  	ofPixelFormat getPixelFormat() const;
  
  	/// \brief Get the number of values that the ofPixels object
  	/// contains, so an RGB data 400x400 would be 480,000, whereas RGBA data
  	/// of the same dimensions would be 640,000.
  	int size() const;
  	
  	/// \brief Get the type of the image
  	/// \returns One of the following types: `OF_IMAGE_GRAYSCALE`,
  	/// `OF_IMAGE_COLOR`, `OF_IMAGE_COLOR_ALPHA`
  	ofImageType getImageType() const;
  	
  	/// \}
  	/// \name Setters
  	/// \{
  
  	/// \brief Set all the pixel data for a single channel, for instance, the
  	/// Red pixel values, from an ofPixels object assumed to be a grayscale
  	/// representation of the data that should go into that one channel.
  	void setChannel(int channel, const ofPixels_<PixelType> channelPixels);
  	
  	/// \brief Changes the image type for the ofPixels object
  	///
  	/// \param imageType Can be one of the following: OF_IMAGE_GRAYSCALE, OF_IMAGE_COLOR, OF_IMAGE_COLOR_ALPHA
  	void setImageType(ofImageType imageType);
  
  	void setNumChannels(int numChannels);
  
  	/// \}
  	/// \name Iterator
  	/// \{
  
  	typedef PixelType * iterator;
  	typedef const PixelType * const_iterator;
  	typedef PixelType * reverse_iterator;
  	typedef const PixelType * const_reverse_iterator;
  	iterator begin();
  	iterator end();
  	const_iterator begin() const;
  	const_iterator end() const;
  	reverse_iterator rbegin();
  	reverse_iterator rend();
  	const_reverse_iterator rbegin() const;
  	const_reverse_iterator rend() const;
  
  	/// \}
  	
      /// \cond INTERNAL
  
      struct ConstPixel: public std::iterator<std::forward_iterator_tag,ConstPixel>{
          ConstPixel(const PixelType * pixel, int bytesPerPixel, ofPixelFormat pixelFormat);
          const ConstPixel& operator*() const;
          const ConstPixel* operator->() const;
          ConstPixel& operator++();
          ConstPixel operator++(int);
          ConstPixel operator+(int) const;
          ConstPixel operator-(int) const;
          ConstPixel operator+=(int);
          bool operator!=(ConstPixel const& rhs) const;
          bool operator<(ConstPixel const& rhs) const;
          const PixelType & operator[](int idx) const;
          int getComponentsPerPixel() const;
          ofPixelFormat getPixelFormat() const;
          ofColor_<PixelType> getColor() const;
  
      private:
          const PixelType * pixel;
          int componentsPerPixel;
          ofPixelFormat pixelFormat;
      };
  
  	struct Pixel: public std::iterator<std::forward_iterator_tag,Pixel>{
  		Pixel(PixelType * pixel, int bytesPerPixel, ofPixelFormat pixelFormat);
          const Pixel& operator*() const;
          const Pixel* operator->() const;
          Pixel& operator++();
          Pixel operator++(int);
          Pixel& operator--();
          Pixel operator--(int);
          Pixel operator+(int) const;
          Pixel operator-(int) const;
          Pixel operator+=(int);
          bool operator!=(Pixel const& rhs) const;
          bool operator<(Pixel const& rhs) const;
          Pixel & operator=(Pixel const& rhs);
          Pixel & operator=(ConstPixel const& rhs);
          PixelType & operator[](int idx);
          const PixelType & operator[](int idx) const;
  		int getComponentsPerPixel() const;
  		ofPixelFormat getPixelFormat() const;
  		ofColor_<PixelType> getColor() const;
  
  	private:
  		PixelType * pixel;
  		int componentsPerPixel;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct Pixels{
  		Pixels(PixelType * begin, PixelType * end, int componentsPerPixel, ofPixelFormat pixelFormat);
  		Pixels(Pixel begin, Pixel end);
  		Pixel begin();
  		Pixel end();
  	private:
  		PixelType * _begin;
  		PixelType * _end;
  		int componentsPerPixel;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct Line: public std::iterator<std::forward_iterator_tag,Line>{
  		Line(PixelType * _begin, int stride, int componentsPerPixel, int lineNum, ofPixelFormat pixelFormat);
          const Line& operator*() const;
          const Line* operator->() const;
          Line& operator++();
          Line operator++(int);
          Line& operator--();
          Line operator--(int);
          Line operator+(int) const;
          Line operator+=(int);
          bool operator!=(Line const& rhs) const;
          bool operator<(Line const& rhs) const;
          bool operator>(Line const& rhs) const;
          bool operator>=(Line const& rhs) const;
          PixelType * begin();
          PixelType * end();
          const PixelType * begin() const;
          const PixelType * end() const;
  		int getLineNum() const;
  		ofPixels_<PixelType> asPixels();
  		const ofPixels_<PixelType> asPixels() const;
  		int getStride() const;
  		Pixel getPixel(int pixel);
  		Pixels getPixels();
          Pixels getPixels(int first, int numPixels);
  
  	private:
  		PixelType * _begin;
  		PixelType * _end;
  		int stride;
  		int componentsPerPixel;
  		int lineNum;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct Lines{
  		Lines(PixelType * _begin, PixelType * _end, int stride, int componentsPerPixel, int lines, ofPixelFormat pixelFormat);
  
          Line begin();
  
          Line end();
          
  
  	private:
          PixelType * _begin;
  		PixelType * _end;
  		int stride;
  		int componentsPerPixel;
  		int lines;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct ConstPixels{
  		ConstPixels(const PixelType * begin, const PixelType * end, int componentsPerPixel, ofPixelFormat pixelFormat);
  		ConstPixels(const ConstPixel & begin, const ConstPixel & end);
  		ConstPixel begin() const;
  		ConstPixel end() const;
  	private:
  		const PixelType * _begin;
  		const PixelType * _end;
  		int componentsPerPixel;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct ConstLine: public std::iterator<std::forward_iterator_tag,Line>{
  		ConstLine(const PixelType * _begin, int stride, int componentsPerPixel, int lineNum, ofPixelFormat pixelFormat);
  		const ConstLine& operator*() const;
  		const ConstLine* operator->() const;
  		ConstLine& operator++();
  		ConstLine operator++(int);
  		ConstLine operator+(int) const;
  		ConstLine operator+=(int);
  		bool operator!=(ConstLine const& rhs) const;
  		bool operator<(ConstLine const& rhs) const;
  		const PixelType * begin() const;
  		const PixelType * end() const;
  		int getLineNum() const;
  		int getStride() const;
          ConstPixel getPixel(int pixel) const;
  		ConstPixels getPixels() const;
  		ConstPixels getPixels(int first, int numPixels) const;
  
  	private:
  		const PixelType * _begin;
  		const PixelType * _end;
  		int stride;
  		int componentsPerPixel;
  		int lineNum;
  		ofPixelFormat pixelFormat;
  	};
  
  	struct ConstLines{
  		ConstLines(const PixelType * _begin, const PixelType * _end, int stride, int componentsPerPixel, int lines, ofPixelFormat pixelFormat);
  
  		ConstLine begin() const;
  
  		ConstLine end() const;
  
  	private:
  		const PixelType * _begin;
  		const PixelType * _end;
  		int stride;
  		int componentsPerPixel;
  		int lines;
  		ofPixelFormat pixelFormat;
  	};
  
  	Line getLine(int line);
  	Lines getLines();
      Lines getLines(int first, int numLines);
  	Pixels getPixelsIter();
  	ConstLine getConstLine(int line) const;
  	ConstLines getConstLines() const;
  	ConstLines getConstLines(int first, int numLines) const;
  	ConstPixels getConstPixelsIter() const;
  
      /// \endcond
  
  private:
  	static float bicubicInterpolate(const float *patch, float x,float y, float x2,float y2, float x3,float y3);
  
  	void copyFrom( const ofPixels_<PixelType>& mom );
  
  	template<typename SrcType>
  	void copyFrom( const ofPixels_<SrcType>& mom );
  	
  	PixelType * pixels;
  	int 	width;
  	int 	height;
  
  	//int 	channels; // 1, 3, 4 channels per pixel (grayscale, rgb, rgba)
  	int 	pixelsSize;
  	bool	bAllocated;
  	bool	pixelsOwner;			// if set from external data don't delete it
  	ofPixelFormat pixelFormat;
  
  };
  
  
  typedef ofPixels_<unsigned char> ofPixels;
  typedef ofPixels_<float> ofFloatPixels;
  typedef ofPixels_<unsigned short> ofShortPixels;
  
  
  typedef ofPixels& ofPixelsRef;
  typedef ofFloatPixels& ofFloatPixelsRef;
  typedef ofShortPixels& ofShortPixelsRef;
  
  // sorry for these ones, being templated functions inside a template i needed to do it in the .h
  // they allow to do things like:
  //
  // ofPixels pix;
  // ofFloatPixels pixf;
  // pix = pixf;
  
  template<typename PixelType>
  template<typename SrcType>
  ofPixels_<PixelType>::ofPixels_(const ofPixels_<SrcType> & mom){
  	bAllocated = false;
  	pixelsOwner = false;
  	pixelsSize = 0;
  	pixels = nullptr;
  	width = 0;
  	height = 0;
  	pixelFormat = OF_PIXELS_UNKNOWN;
  	copyFrom( mom );
  }
  
  template<typename PixelType>
  template<typename SrcType>
  ofPixels_<PixelType>& ofPixels_<PixelType>::operator=(const ofPixels_<SrcType> & mom){
  	copyFrom( mom );
  	return *this;
  }
  
  template<typename PixelType>
  template<typename SrcType>
  void ofPixels_<PixelType>::copyFrom(const ofPixels_<SrcType> & mom){
  	if(mom.isAllocated()){
  		allocate(mom.getWidth(),mom.getHeight(),mom.getNumChannels());
  
  		const float srcMax = ( (sizeof(SrcType) == sizeof(float) ) ? 1.f : numeric_limits<SrcType>::max() );
  		const float dstMax = ( (sizeof(PixelType) == sizeof(float) ) ? 1.f : numeric_limits<PixelType>::max() );
  		const float factor = dstMax / srcMax;
  
  		if(sizeof(SrcType) == sizeof(float)) {
  			// coming from float we need a special case to clamp the values
  			for(int i = 0; i < mom.size(); i++){
  				pixels[i] = CLAMP(mom[i], 0, 1) * factor;
  			}
  		} else{
  			// everything else is a straight scaling
  			for(int i = 0; i < mom.size(); i++){
  				pixels[i] = mom[i] * factor;
  			}
  		}
  	}
  }
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::iterator ofPixels_<PixelType>::begin(){
  	return pixels;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::iterator ofPixels_<PixelType>::end(){
  	return pixels + size();
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::begin() const{
  	return pixels;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::end() const{
  	return pixels + size();
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::reverse_iterator ofPixels_<PixelType>::rbegin(){
  	return pixels + (size() - 1);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::reverse_iterator ofPixels_<PixelType>::rend(){
  	return pixels - 1;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_reverse_iterator ofPixels_<PixelType>::rbegin() const{
  	return pixels + (size() - 1);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_reverse_iterator ofPixels_<PixelType>::rend() const{
  	return pixels - 1;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::Pixel::Pixel(PixelType * pixel, int componentsPerPixel, ofPixelFormat pixelFormat)
  :pixel(pixel)
  ,componentsPerPixel(componentsPerPixel)
  ,pixelFormat(pixelFormat){
  
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::Pixel& ofPixels_<PixelType>::Pixel::operator*() const{
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::Pixel* ofPixels_<PixelType>::Pixel::operator->() const{
  	return this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel& ofPixels_<PixelType>::Pixel::operator++(){
  	pixel += componentsPerPixel;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixel::operator++(int){
  	Pixel tmp(*this);
  	operator++();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel& ofPixels_<PixelType>::Pixel::operator--(){
  	pixel -= componentsPerPixel;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixel::operator--(int){
  	Pixel tmp(*this);
  	operator--();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixel::operator+(int i) const{
  	return Pixel(pixel + componentsPerPixel * i, componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixel::operator-(int i) const{
  	return Pixel(pixel - componentsPerPixel * i, componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixel::operator+=(int i){
  	pixel += componentsPerPixel * i;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Pixel::operator!=(Pixel const& rhs) const{
  	return pixel != rhs.pixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Pixel::operator<(Pixel const& rhs) const{
  	return pixel < rhs.pixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel & ofPixels_<PixelType>::Pixel::operator=(Pixel const& rhs){
      for(int i=0;i<componentsPerPixel;++i){
          pixel[i] = rhs[i];
      }
      return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel & ofPixels_<PixelType>::Pixel::operator=(ConstPixel const& rhs){
      for(int i=0;i<componentsPerPixel;++i){
          pixel[i] = rhs[i];
      }
      return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline PixelType & ofPixels_<PixelType>::Pixel::operator[](int idx){
  	return pixel[idx];
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const PixelType & ofPixels_<PixelType>::Pixel::operator[](int idx) const{
  	return pixel[idx];
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::Pixel::getComponentsPerPixel() const{
  	return componentsPerPixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixelFormat ofPixels_<PixelType>::Pixel::getPixelFormat() const{
  	return pixelFormat;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  ofColor_<PixelType> ofPixels_<PixelType>::Pixel::getColor() const{
  	ofColor_<PixelType> c;
  	switch(pixelFormat){
  		case OF_PIXELS_RGB:
  			c.set( pixel[0], pixel[1], pixel[2] );
  			break;
  		case OF_PIXELS_BGR:
  			c.set( pixel[2], pixel[1], pixel[0] );
  			break;
  		case OF_PIXELS_RGBA:
  			c.set( pixel[0], pixel[1], pixel[2], pixel[3] );
  			break;
  		case OF_PIXELS_BGRA:
  			c.set( pixel[2], pixel[1], pixel[0], pixel[3] );
  			break;
  		case OF_PIXELS_GRAY:
  			c.set( pixel[0] );
  			break;
  		case OF_PIXELS_GRAY_ALPHA:
  			c.set( pixel[0], pixel[0], pixel[0], pixel[1] );
  			break;
  		case OF_PIXELS_RGB565:
  		case OF_PIXELS_NV12:
  		case OF_PIXELS_NV21:
  		case OF_PIXELS_YV12:
  		case OF_PIXELS_I420:
  		case OF_PIXELS_YUY2:
  		case OF_PIXELS_UYVY:
  		case OF_PIXELS_Y:
  		case OF_PIXELS_U:
  		case OF_PIXELS_V:
  		case OF_PIXELS_UV:
  		case OF_PIXELS_VU:
  		case OF_PIXELS_UNKNOWN:
  		default:
  			ofLogWarning() << "returning color not supported yet for " << ofToString(pixelFormat) << " format";
  			return 0;
  			break;
  	}
  
  	return c;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::Pixels::Pixels(PixelType * begin, PixelType * end, int componentsPerPixel, ofPixelFormat pixelFormat)
  :_begin(begin)
  ,_end(end)
  ,componentsPerPixel(componentsPerPixel)
  ,pixelFormat(pixelFormat){}
  
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::Pixels::Pixels(Pixel begin, Pixel end)
  :_begin(&begin[0])
  ,_end(&end[0])
  ,componentsPerPixel(begin.getComponentsPerPixel())
  ,pixelFormat(begin.getPixelFormat()){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixels::begin(){
  	return Pixel(_begin,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Pixels::end(){
  	return Pixel(_end,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::Line::Line(PixelType * _begin, int stride, int componentsPerPixel, int lineNum, ofPixelFormat pixelFormat)
  :_begin(_begin)
  ,_end(_begin+stride)
  ,stride(stride)
  ,componentsPerPixel(componentsPerPixel)
  ,lineNum(lineNum)
  ,pixelFormat(pixelFormat){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::Line& ofPixels_<PixelType>::Line::operator*() const{
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::Line* ofPixels_<PixelType>::Line::operator->() const{
  	return this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line& ofPixels_<PixelType>::Line::operator++(){
  	_begin = _end;
  	_end = _begin + stride;
  	++lineNum;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line ofPixels_<PixelType>::Line::operator++(int) {
  	Line tmp(*this);
  	operator++();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line& ofPixels_<PixelType>::Line::operator--(){
  	_end = _begin;
  	_begin = _end - stride;
  	--lineNum;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line ofPixels_<PixelType>::Line::operator--(int) {
  	Line tmp(*this);
  	operator--();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line  ofPixels_<PixelType>::Line::operator+(int i) const{
  	return Line(_begin+stride*i,stride,componentsPerPixel,lineNum+i,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line  ofPixels_<PixelType>::Line::operator+=(int i){
  	_begin = _begin+stride*i;
  	_end = _begin + stride;
  	lineNum += i;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Line::operator!=(typename ofPixels_<PixelType>::Line const& rhs) const{
  	return rhs._begin != _begin || rhs._end != _end || rhs.stride != stride || rhs.lineNum!=lineNum;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Line::operator<(typename ofPixels_<PixelType>::Line const& rhs) const{
  	return _begin < rhs._begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Line::operator>(typename ofPixels_<PixelType>::Line const& rhs) const{
  	return _begin > rhs._begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::Line::operator>=(typename ofPixels_<PixelType>::Line const& rhs) const{
  	return _begin >= rhs._begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::iterator ofPixels_<PixelType>::Line::begin(){
  	return _begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::iterator ofPixels_<PixelType>::Line::end(){
  	return _end;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::Line::begin() const{
  	return _begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::Line::end() const{
  	return _end;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::Line::getLineNum() const{
  	return lineNum;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType> ofPixels_<PixelType>::Line::asPixels(){
  	ofPixels_<PixelType> pixels;
  	pixels.setFromExternalPixels(_begin,stride,1,pixelFormat);
  	return pixels;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const ofPixels_<PixelType> ofPixels_<PixelType>::Line::asPixels() const{
  	ofPixels_<PixelType> pixels;
  	pixels.setFromExternalPixels(_begin,stride,1,pixelFormat);
  	return pixels;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::Line::getStride() const{
  	return stride;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixel ofPixels_<PixelType>::Line::getPixel(int pixel){
      return Pixel(_begin + (pixel*componentsPerPixel), componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixels ofPixels_<PixelType>::Line::getPixels(){
  	return Pixels(_begin,_end,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixels ofPixels_<PixelType>::Line::getPixels(int first, int numPixels){
      return Pixels(&getPixel(first)[0], &getPixel(first+numPixels)[0], componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::Lines::Lines(PixelType * _begin, PixelType * _end, int stride, int componentsPerPixel, int lines, ofPixelFormat pixelFormat)
  :_begin(_begin)
  ,_end(_end)
  ,stride(stride)
  ,componentsPerPixel(componentsPerPixel)
  ,lines(lines)
  ,pixelFormat(pixelFormat){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line ofPixels_<PixelType>::Lines::begin(){
  	return Line(_begin,stride,componentsPerPixel,0,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line ofPixels_<PixelType>::Lines::end(){
  	return Line(_end,stride,componentsPerPixel,lines,pixelFormat);
  }
  
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Line ofPixels_<PixelType>::getLine(int line){
  	return Line(pixels+(width*getNumChannels()*line), width*getNumChannels(), getNumChannels(), line,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Lines ofPixels_<PixelType>::getLines(){
  	return Lines(begin(),end(),width*getNumChannels(),getNumChannels(),getHeight(),pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Lines ofPixels_<PixelType>::getLines(int first, int numLines){
      return Lines(getLine(first).begin(),getLine(first+numLines).begin(),width*getNumChannels(),getNumChannels(),numLines,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::Pixels ofPixels_<PixelType>::getPixelsIter(){
  	return Pixels(begin(),end(),getNumChannels(),pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::ConstPixel::ConstPixel(const PixelType * pixel, int componentsPerPixel, ofPixelFormat pixelFormat)
  :pixel(pixel)
  ,componentsPerPixel(componentsPerPixel)
  ,pixelFormat(pixelFormat){
  
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::ConstPixel& ofPixels_<PixelType>::ConstPixel::operator*() const{
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::ConstPixel* ofPixels_<PixelType>::ConstPixel::operator->() const{
  	return this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel& ofPixels_<PixelType>::ConstPixel::operator++(){
  	pixel += componentsPerPixel;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixel::operator++(int){
  	ConstPixel tmp(*this);
  	operator++();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixel::operator+(int i) const{
  	return ConstPixel(pixel + componentsPerPixel * i, componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixel::operator-(int i) const{
  	return ConstPixel(pixel - componentsPerPixel * i, componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixel::operator+=(int i){
  	pixel += componentsPerPixel * i;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::ConstPixel::operator!=(ConstPixel const& rhs) const{
  	return pixel != rhs.pixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::ConstPixel::operator<(ConstPixel const& rhs) const{
  	return pixel < rhs.pixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const PixelType & ofPixels_<PixelType>::ConstPixel::operator[](int idx) const{
  	return pixel[idx];
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::ConstPixel::getComponentsPerPixel() const{
  	return componentsPerPixel;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixelFormat ofPixels_<PixelType>::ConstPixel::getPixelFormat() const{
  	return pixelFormat;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  ofColor_<PixelType> ofPixels_<PixelType>::ConstPixel::getColor() const{
  	ofColor_<PixelType> c;
  	switch(pixelFormat){
  		case OF_PIXELS_RGB:
  			c.set( pixel[0], pixel[1], pixel[2] );
  			break;
  		case OF_PIXELS_BGR:
  			c.set( pixel[2], pixel[1], pixel[0] );
  			break;
  		case OF_PIXELS_RGBA:
  			c.set( pixel[0], pixel[1], pixel[2], pixel[3] );
  			break;
  		case OF_PIXELS_BGRA:
  			c.set( pixel[2], pixel[1], pixel[0], pixel[3] );
  			break;
  		case OF_PIXELS_GRAY:
  			c.set( pixel[0] );
  			break;
  		case OF_PIXELS_GRAY_ALPHA:
  			c.set( pixel[0], pixel[0], pixel[0], pixel[1] );
  			break;
  		case OF_PIXELS_RGB565:
  		case OF_PIXELS_NV12:
  		case OF_PIXELS_NV21:
  		case OF_PIXELS_YV12:
  		case OF_PIXELS_I420:
  		case OF_PIXELS_YUY2:
  		case OF_PIXELS_UYVY:
  		case OF_PIXELS_Y:
  		case OF_PIXELS_U:
  		case OF_PIXELS_V:
  		case OF_PIXELS_UV:
  		case OF_PIXELS_VU:
  		case OF_PIXELS_UNKNOWN:
  		default:
  			ofLogWarning() << "returning color not supported yet for " << ofToString(pixelFormat) << " format";
  			return 0;
  			break;
  	}
  
  	return c;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::ConstPixels::ConstPixels(const PixelType * begin, const PixelType * end, int componentsPerPixel, ofPixelFormat pixelFormat)
  :_begin(begin)
  ,_end(end)
  ,componentsPerPixel(componentsPerPixel)
  ,pixelFormat(pixelFormat){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::ConstPixels::ConstPixels(const ConstPixel & begin, const ConstPixel & end)
  :_begin(&begin[0])
  ,_end(&end[0])
  ,componentsPerPixel(begin.getComponentsPerPixel())
  ,pixelFormat(begin.getPixelFormat()){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixels::begin() const{
  	return ConstPixel(_begin,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstPixels::end() const{
  	return ConstPixel(_end,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::ConstLine::ConstLine(const PixelType * _begin, int stride, int componentsPerPixel, int lineNum, ofPixelFormat pixelFormat)
  :_begin(_begin)
  ,_end(_begin+stride)
  ,stride(stride)
  ,componentsPerPixel(componentsPerPixel)
  ,lineNum(lineNum)
  ,pixelFormat(pixelFormat){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::ConstLine& ofPixels_<PixelType>::ConstLine::operator*() const{
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline const typename ofPixels_<PixelType>::ConstLine* ofPixels_<PixelType>::ConstLine::operator->() const{
  	return this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine& ofPixels_<PixelType>::ConstLine::operator++(){
  	_begin = _end;
  	_end = _begin + stride;
  	++lineNum;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine ofPixels_<PixelType>::ConstLine::operator++(int) {
  	ConstLine tmp(*this);
  	operator++();
  	return tmp;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine  ofPixels_<PixelType>::ConstLine::operator+(int i) const{
  	return ConstLine(_begin+stride*i,stride,componentsPerPixel,lineNum+i,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine  ofPixels_<PixelType>::ConstLine::operator+=(int i){
  	_begin = _begin+stride*i;
  	_end = _begin + stride;
  	lineNum += i;
  	return *this;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::ConstLine::operator!=(typename ofPixels_<PixelType>::ConstLine const& rhs) const{
  	return rhs._begin != _begin || rhs._end != _end || rhs.stride != stride || rhs.lineNum!=lineNum;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline bool ofPixels_<PixelType>::ConstLine::operator<(typename ofPixels_<PixelType>::ConstLine const& rhs) const{
  	return _begin < rhs._begin || _end < rhs._end;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::ConstLine::begin() const{
  	return _begin;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::const_iterator ofPixels_<PixelType>::ConstLine::end() const{
  	return _end;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::ConstLine::getLineNum() const{
  	return lineNum;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline int ofPixels_<PixelType>::ConstLine::getStride() const{
  	return stride;
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixel ofPixels_<PixelType>::ConstLine::getPixel(int pixel) const{
      return ConstPixel(_begin + (pixel*componentsPerPixel), componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixels ofPixels_<PixelType>::ConstLine::getPixels() const{
  	return ConstPixels(_begin,_end,componentsPerPixel,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixels ofPixels_<PixelType>::ConstLine::getPixels(int first, int numPixels) const{
      return ConstPixels(&getPixel(first)[0], &getPixel(first+numPixels)[0], componentsPerPixel, pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline ofPixels_<PixelType>::ConstLines::ConstLines(const PixelType * _begin, const PixelType * _end, int stride, int componentsPerPixel, int lines, ofPixelFormat pixelFormat)
  :_begin(_begin)
  ,_end(_end)
  ,stride(stride)
  ,componentsPerPixel(componentsPerPixel)
  ,lines(lines)
  ,pixelFormat(pixelFormat){}
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine ofPixels_<PixelType>::ConstLines::begin() const{
  	return ConstLine(_begin,stride,componentsPerPixel,0,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine ofPixels_<PixelType>::ConstLines::end() const{
  	return ConstLine(_end,stride,componentsPerPixel,lines,pixelFormat);
  }
  
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLine ofPixels_<PixelType>::getConstLine(int line) const{
  	return ConstLine(pixels+(width*getNumChannels()*line), width*getNumChannels(), getNumChannels(), line,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLines ofPixels_<PixelType>::getConstLines() const{
  	return ConstLines(begin(),end(),width*getNumChannels(),getNumChannels(),getHeight(),pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstLines ofPixels_<PixelType>::getConstLines(int first, int numLines) const{
      return ConstLines(getConstLine(first).begin(),getConstLine(first+numLines).begin(),width*getNumChannels(),getNumChannels(),numLines,pixelFormat);
  }
  
  //----------------------------------------------------------------------
  template<typename PixelType>
  inline typename ofPixels_<PixelType>::ConstPixels ofPixels_<PixelType>::getConstPixelsIter() const{
  	return ConstPixels(begin(),end(),getNumChannels(),pixelFormat);
  }
  
  namespace std{
  template<typename PixelType>
  void swap(ofPixels_<PixelType> & src, ofPixels_<PixelType> & dst){
  	src.swap(dst);
  }
  }
  