Color.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #pragma once
  2. #ifndef COLOR_H
  3. #define COLOR_H
  4. #include <cstdint>
  5. #include "esp_attr.h"
  6. union Hsv;
  7. union Rgb {
  8. struct __attribute__ ((packed)) {
  9. uint8_t r, g, b, a;
  10. };
  11. uint32_t value;
  12. Rgb( uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255 ) : r( r ), g( g ), b( b ), a( a ) {}
  13. Rgb( Hsv c );
  14. Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; }
  15. Rgb& operator=( Hsv hsv );
  16. Rgb operator+( Rgb in ) const;
  17. Rgb& operator+=( Rgb in );
  18. bool operator==( Rgb in ) const { return in.value == value; }
  19. Rgb& blend( Rgb in );
  20. void swap( Rgb& o ) { value = o.value; }
  21. void linearize() {
  22. r = channelGamma(r);
  23. g = channelGamma(g);
  24. b = channelGamma(b);
  25. }
  26. uint8_t IRAM_ATTR getGrb( int idx );
  27. void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) {
  28. r = stretch( r, maxR );
  29. g = stretch( g, maxG );
  30. b = stretch( b, maxB );
  31. }
  32. void stretchChannelsEvenly( uint8_t max ) {
  33. stretchChannels( max, max, max );
  34. }
  35. private:
  36. uint8_t stretch( int value, uint8_t max ) {
  37. return ( value * max ) >> 8;
  38. }
  39. uint8_t channelGamma( int channel ) {
  40. /* The optimal gamma correction is x^2.8. However, this is expensive to
  41. * compute. Therefore, we use x^3 for gamma correction. Also, we add a
  42. * bias as the WS2812 LEDs do not turn on for values less than 4. */
  43. if (channel == 0)
  44. return channel;
  45. channel = channel * channel * channel * 251;
  46. channel >>= 24;
  47. return static_cast< uint8_t >( 4 + channel );
  48. }
  49. };
  50. union Hsv {
  51. struct __attribute__ ((packed)) {
  52. uint8_t h, s, v, a;
  53. };
  54. uint32_t value;
  55. Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {}
  56. Hsv( Rgb r );
  57. Hsv& operator=( Hsv h ) { swap( h ); return *this; }
  58. Hsv& operator=( Rgb rgb );
  59. bool operator==( Hsv in ) const { return in.value == value; }
  60. void swap( Hsv& o ) { value = o.value; }
  61. };
  62. #endif //COLOR_H