Color.h 2.0 KB

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