mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-07 03:56:57 +03:00
70 lines
2.0 KiB
C++
70 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include "esp_attr.h"
|
|
union Hsv;
|
|
|
|
union Rgb {
|
|
struct __attribute__ ((packed)) {
|
|
uint8_t r, g, b, a;
|
|
};
|
|
uint32_t value;
|
|
|
|
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 ) {}
|
|
Rgb( Hsv c );
|
|
Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; }
|
|
Rgb& operator=( Hsv hsv );
|
|
Rgb operator+( Rgb in ) const;
|
|
Rgb& operator+=( Rgb in );
|
|
bool operator==( Rgb in ) const { return in.value == value; }
|
|
Rgb& blend( Rgb in );
|
|
void swap( Rgb& o ) { value = o.value; }
|
|
void linearize() {
|
|
r = channelGamma(r);
|
|
g = channelGamma(g);
|
|
b = channelGamma(b);
|
|
}
|
|
|
|
uint8_t IRAM_ATTR getGrb( int idx );
|
|
|
|
void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) {
|
|
r = stretch( r, maxR );
|
|
g = stretch( g, maxG );
|
|
b = stretch( b, maxB );
|
|
}
|
|
|
|
void stretchChannelsEvenly( uint8_t max ) {
|
|
stretchChannels( max, max, max );
|
|
}
|
|
|
|
private:
|
|
uint8_t stretch( int value, uint8_t max ) {
|
|
return ( value * max ) >> 8;
|
|
}
|
|
|
|
uint8_t channelGamma( int channel ) {
|
|
/* The optimal gamma correction is x^2.8. However, this is expensive to
|
|
* compute. Therefore, we use x^3 for gamma correction. Also, we add a
|
|
* bias as the WS2812 LEDs do not turn on for values less than 4. */
|
|
if (channel == 0)
|
|
return channel;
|
|
channel = channel * channel * channel * 251;
|
|
channel >>= 24;
|
|
return static_cast< uint8_t >( 4 + channel );
|
|
}
|
|
};
|
|
|
|
union Hsv {
|
|
struct __attribute__ ((packed)) {
|
|
uint8_t h, s, v, a;
|
|
};
|
|
uint32_t value;
|
|
|
|
Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {}
|
|
Hsv( Rgb r );
|
|
Hsv& operator=( Hsv h ) { swap( h ); return *this; }
|
|
Hsv& operator=( Rgb rgb );
|
|
bool operator==( Hsv in ) const { return in.value == value; }
|
|
void swap( Hsv& o ) { value = o.value; }
|
|
};
|