FastLED  3.1
pixelset.h
1 #ifndef __INC_PIXELSET_H
2 #define __INC_PIXELSET_H
3 
4 #include "FastLED.h"
5 
9 template<class PIXEL_TYPE>
10 class CPixelView {
11 public:
12  const int8_t dir;
13  const int len;
14  PIXEL_TYPE * const leds;
15  PIXEL_TYPE * const end_pos;
16 
17 public:
18 
20  inline CPixelView(const CPixelView & other) : dir(other.dir), len(other.len), leds(other.leds), end_pos(other.end_pos) {}
21 
26  inline CPixelView(PIXEL_TYPE *_leds, int _len) : dir(_len < 0 ? -1 : 1), len(_len), leds(_leds), end_pos(_leds + _len) {}
27 
33  inline CPixelView(PIXEL_TYPE *_leds, int _start, int _end) : dir(((_end-_start)<0) ? -1 : 1), len((_end - _start) + dir), leds(_leds + _start), end_pos(_leds + _start + len) {}
34 
37  int size() { return abs(len); }
38 
41  bool reversed() { return len < 0; }
42 
44  bool operator==(const CPixelView & rhs) const { return leds == rhs.leds && len == rhs.len && dir == rhs.dir; }
45 
47  bool operator!=(const CPixelView & rhs) const { return leds != rhs.leds || len != rhs.len || dir != rhs.dir; }
48 
50  inline PIXEL_TYPE & operator[](int x) const { if(dir & 0x80) { return leds[-x]; } else { return leds[x]; } }
51 
56  inline CPixelView operator()(int start, int end) { return CPixelView(leds, start, end); }
57 
61 
63  inline CPixelView operator-() { return CPixelView(leds + len - dir, len - dir, 0); }
64 
66  inline operator PIXEL_TYPE* () const { return leds; }
67 
70  inline CPixelView & operator=(const PIXEL_TYPE & color) {
71  for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) = color; }
72  return *this;
73  }
74 
75 
76  void dump() const {
83  }
84 
87  inline CPixelView & operator=(const CPixelView & rhs) {
88  for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) {
89  (*pixel) = (*rhspixel);
90  }
91  return *this;
92  }
93 
95 
96  inline CPixelView & addToRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) += inc; } return *this; }
99  inline CPixelView & operator+=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) += (*rhspixel); } return *this; }
100 
102  inline CPixelView & subFromRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) -= inc; } return *this; }
104  inline CPixelView & operator-=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) -= (*rhspixel); } return *this; }
105 
107  inline CPixelView & operator++() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
109  inline CPixelView & operator++(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
110 
112  inline CPixelView & operator--() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
114  inline CPixelView & operator--(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
115 
117  inline CPixelView & operator/=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) /= d; } return *this; }
119  inline CPixelView & operator>>=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) >>= d; } return *this; }
121  inline CPixelView & operator*=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) *= d; } return *this; }
122 
124  inline CPixelView & nscale8_video(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this;}
126  inline CPixelView & operator%=(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this; }
128  inline CPixelView & fadeLightBy(uint8_t fadefactor) { return nscale8_video(255 - fadefactor); }
129 
131  inline CPixelView & nscale8(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
133  inline CPixelView & nscale8(PIXEL_TYPE & scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
135  inline CPixelView & nscale8(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel).nscale8((*rhspixel)); } return *this; }
136 
138  inline CPixelView & fadeToBlackBy(uint8_t fade) { return nscale8(255 - fade); }
139 
141  inline CPixelView & operator|=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= rhs; } return *this; }
143  inline CPixelView & operator|=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) |= (*rhspixel); } return *this; }
145  inline CPixelView & operator|=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= d; } return *this; }
146 
148  inline CPixelView & operator&=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= rhs; } return *this; }
150  inline CPixelView & operator&=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) &= (*rhspixel); } return *this; }
152  inline CPixelView & operator&=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= d; } return *this; }
154 
156  inline operator bool() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { if((*pixel)) return true; } return false; }
157 
158  // Color util functions
159  inline CPixelView & fill_solid(const PIXEL_TYPE & color) { *this = color; return *this; }
160  inline CPixelView & fill_solid(const CHSV & color) { if(dir>0) { *this = color; return *this; } }
161 
162  inline CPixelView & fill_rainbow(uint8_t initialhue, uint8_t deltahue=5) {
163  if(dir >= 0) {
164  ::fill_rainbow(leds,len,initialhue,deltahue);
165  } else {
166  ::fill_rainbow(leds+len+1,-len,initialhue,deltahue);
167  }
168  return *this;
169  }
170 
171  inline CPixelView & fill_gradient(const CHSV & startcolor, const CHSV & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
172  if(dir >= 0) {
173  ::fill_gradient(leds,len,startcolor, endcolor, directionCode);
174  } else {
175  ::fill_gradient(leds + len + 1, (-len), endcolor, startcolor, directionCode);
176  }
177  return *this;
178  }
179 
180  inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, TGradientDirectionCode directionCode = SHORTEST_HUES) {
181  if(dir >= 0) {
182  ::fill_gradient(leds, len, c1, c2, c3, directionCode);
183  } else {
184  ::fill_gradient(leds + len + 1, -len, c3, c2, c1, directionCode);
185  }
186  return *this;
187  }
188 
189  inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, const CHSV & c4, TGradientDirectionCode directionCode = SHORTEST_HUES) {
190  if(dir >= 0) {
191  ::fill_gradient(leds, len, c1, c2, c3, c4, directionCode);
192  } else {
193  ::fill_gradient(leds + len + 1, -len, c4, c3, c2, c1, directionCode);
194  }
195  return *this;
196  }
197 
198  inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & startcolor, const PIXEL_TYPE & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
199  if(dir >= 0) {
200  ::fill_gradient_RGB(leds,len,startcolor, endcolor);
201  } else {
202  ::fill_gradient_RGB(leds + len + 1, (-len), endcolor, startcolor);
203  }
204  return *this;
205  }
206 
207  inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3) {
208  if(dir >= 0) {
209  ::fill_gradient_RGB(leds, len, c1, c2, c3);
210  } else {
211  ::fill_gradient_RGB(leds + len + 1, -len, c3, c2, c1);
212  }
213  return *this;
214  }
215 
216  inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3, const PIXEL_TYPE & c4) {
217  if(dir >= 0) {
218  ::fill_gradient_RGB(leds, len, c1, c2, c3, c4);
219  } else {
220  ::fill_gradient_RGB(leds + len + 1, -len, c4, c3, c2, c1);
221  }
222  return *this;
223  }
224 
225  inline CPixelView & nblend(const PIXEL_TYPE & overlay, fract8 amountOfOverlay) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { ::nblend((*pixel), overlay, amountOfOverlay); } return *this; }
226  inline CPixelView & nblend(const CPixelView & rhs, fract8 amountOfOverlay) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { ::nblend((*pixel), (*rhspixel), amountOfOverlay); } return *this; }
227 
228  // Note: only bringing in a 1d blur, not sure 2d blur makes sense when looking at sub arrays
229  inline CPixelView & blur1d(fract8 blur_amount) {
230  if(dir >= 0) {
231  ::blur1d(leds, len, blur_amount);
232  } else {
233  ::blur1d(leds + len + 1, -len, blur_amount);
234  }
235  return *this;
236  }
237 
238  inline CPixelView & napplyGamma_video(float gamma) {
239  if(dir >= 0) {
240  ::napplyGamma_video(leds, len, gamma);
241  } else {
242  ::napplyGamma_video(leds + len + 1, -len, gamma);
243  }
244  return *this;
245  }
246 
247  inline CPixelView & napplyGamma_video(float gammaR, float gammaG, float gammaB) {
248  if(dir >= 0) {
249  ::napplyGamma_video(leds, len, gammaR, gammaG, gammaB);
250  } else {
251  ::napplyGamma_video(leds + len + 1, -len, gammaR, gammaG, gammaB);
252  }
253  return *this;
254  }
255 
256  // TODO: Make this a fully specified/proper iterator
257  template <class T>
259  T * leds;
260  const int8_t dir;
261  public:
262  __attribute__((always_inline)) inline pixelset_iterator_base(const pixelset_iterator_base & rhs) : leds(rhs.leds), dir(rhs.dir) {}
263  __attribute__((always_inline)) inline pixelset_iterator_base(T * _leds, const char _dir) : leds(_leds), dir(_dir) {}
264 
265  __attribute__((always_inline)) inline pixelset_iterator_base& operator++() { leds += dir; return *this; }
266  __attribute__((always_inline)) inline pixelset_iterator_base operator++(int) { pixelset_iterator_base tmp(*this); leds += dir; return tmp; }
267 
268  __attribute__((always_inline)) inline bool operator==(pixelset_iterator_base & other) const { return leds == other.leds; } // && set==other.set; }
269  __attribute__((always_inline)) inline bool operator!=(pixelset_iterator_base & other) const { return leds != other.leds; } // || set != other.set; }
270 
271  __attribute__((always_inline)) inline PIXEL_TYPE& operator*() const { return *leds; }
272  };
273 
276 
277  iterator begin() { return iterator(leds, dir); }
278  iterator end() { return iterator(end_pos, dir); }
279 
280  iterator begin() const { return iterator(leds, dir); }
281  iterator end() const { return iterator(end_pos, dir); }
282 
283  const_iterator cbegin() const { return const_iterator(leds, dir); }
284  const_iterator cend() const { return const_iterator(end_pos, dir); }
285 };
286 
287 typedef CPixelView<CRGB> CRGBSet;
288 
289 __attribute__((always_inline))
290 inline CRGB *operator+(const CRGBSet & pixels, int offset) { return (CRGB*)pixels + offset; }
291 
292 
293 template<int SIZE>
294 class CRGBArray : public CPixelView<CRGB> {
295  CRGB rawleds[SIZE];
296 public:
297  CRGBArray() : CPixelView<CRGB>(rawleds, SIZE) {}
298 };
299 
300 #endif
CPixelView & nscale8(PIXEL_TYPE &scaledown)
Scale every led by the given scale.
Definition: pixelset.h:133
CPixelView operator-()
Access an inclusive subset of the leds in this set, starting from the first.
Definition: pixelset.h:63
CPixelView & operator&=(const PIXEL_TYPE &rhs)
Apply the PIXEL_TYPE &= operator to every pixel in this set with the given PIXEL_TYPE value (bringing...
Definition: pixelset.h:148
CPixelView & operator++(int DUMMY_ARG)
Increment every pixel value in this set.
Definition: pixelset.h:109
CPixelView & fadeLightBy(uint8_t fadefactor)
Fade every led down by the given scale.
Definition: pixelset.h:128
Representation of an RGB pixel (Red, Green, Blue)
Definition: pixeltypes.h:90
CPixelView & operator*=(uint8_t d)
Multiply every led in this set by the given value.
Definition: pixelset.h:121
CPixelView & operator&=(const CPixelView &rhs)
Apply the PIXEL_TYPE &= operator to every pixel in this set with every pixel in the passed in set...
Definition: pixelset.h:150
CPixelView & operator++()
Increment every pixel value in this set.
Definition: pixelset.h:107
CPixelView & addToRGB(uint8_t inc)
Add the passed in value to r,g, b for all the pixels in this set.
Definition: pixelset.h:97
CPixelView & operator=(const PIXEL_TYPE &color)
Assign the passed in color to all elements in this set.
Definition: pixelset.h:70
bool reversed()
Whether or not this set goes backwards.
Definition: pixelset.h:41
CPixelView & operator--()
Decrement every pixel value in this set.
Definition: pixelset.h:112
CPixelView & operator--(int DUMMY_ARG)
Decrement every pixel value in this set.
Definition: pixelset.h:114
CPixelView operator()(int start, int end)
Access an inclusive subset of the leds in this set.
Definition: pixelset.h:56
CPixelView(const CPixelView &other)
PixelSet copy constructor.
Definition: pixelset.h:20
CPixelView & nscale8(CPixelView &rhs)
Scale every led in this set by every led in the other set.
Definition: pixelset.h:135
CPixelView(PIXEL_TYPE *_leds, int _start, int _end)
PixelSet constructor for the given set of leds, with start and end boundaries.
Definition: pixelset.h:33
uint8_t fract8
ANSI unsigned short _Fract.
Definition: lib8tion.h:335
CPixelView & nscale8_video(uint8_t scaledown)
Scale every led by the given scale.
Definition: pixelset.h:124
CPixelView & operator%=(uint8_t scaledown)
Scale down every led by the given scale.
Definition: pixelset.h:126
CPixelView & operator+=(CPixelView &rhs)
Add every pixel in the other set to this set.
Definition: pixelset.h:99
bool operator!=(const CPixelView &rhs) const
do these sets point to the different things (note, this is different from the contents of the set bei...
Definition: pixelset.h:47
Represents a set of CRGB led objects.
Definition: pixelset.h:10
CPixelView & nscale8(uint8_t scaledown)
Scale every led by the given scale.
Definition: pixelset.h:131
central include file for FastLED, defines the CFastLED class/object
CPixelView & fadeToBlackBy(uint8_t fade)
Fade every led down by the given scale.
Definition: pixelset.h:138
CPixelView & operator|=(const CPixelView &rhs)
Apply the PIXEL_TYPE |= operator to every pixel in this set with every pixel in the passed in set...
Definition: pixelset.h:143
CPixelView & operator/=(uint8_t d)
Divide every led by the given value.
Definition: pixelset.h:117
int size()
Get the size of this set.
Definition: pixelset.h:37
bool operator==(const CPixelView &rhs) const
do these sets point to the same thing (note, this is different from the contents of the set being the...
Definition: pixelset.h:44
CPixelView & operator=(const CPixelView &rhs)
Copy the contents of the passed in set to our set.
Definition: pixelset.h:87
void dump() const
Definition: pixelset.h:76
CPixelView & operator-=(CPixelView &rhs)
Subtract every pixel in the other set from this set.
Definition: pixelset.h:104
CPixelView & operator|=(const PIXEL_TYPE &rhs)
Apply the PIXEL_TYPE |= operator to every pixel in this set with the given PIXEL_TYPE value (bringing...
Definition: pixelset.h:141
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
Definition: fastled_delay.h:92
CPixelView & operator|=(uint8_t d)
Apply the PIXEL_TYPE |= operator to every pixel in this set.
Definition: pixelset.h:145
PIXEL_TYPE & operator[](int x) const
access a single element in this set, just like an array operator
Definition: pixelset.h:50
CPixelView(PIXEL_TYPE *_leds, int _len)
pixelset constructor for a pixel set starting at the given PIXEL_TYPE* and going for _len leds...
Definition: pixelset.h:26
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
Definition: pixeltypes.h:23
CPixelView & operator>>=(uint8_t d)
Shift every led in this set right by the given number of bits.
Definition: pixelset.h:119
CPixelView & operator&=(uint8_t d)
APply the PIXEL_TYPE &= operator to every pixel in this set with the passed in value.
Definition: pixelset.h:152
CPixelView & subFromRGB(uint8_t inc)
Subtract the passed in value from r,g,b for all pixels in this set.
Definition: pixelset.h:102