mirror of
https://github.com/esphome/esphome.git
synced 2025-10-26 20:53:50 +00:00
[light] Improve gamma correction precision (#11141)
Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
@@ -17,19 +17,19 @@ class ESPColorCorrection {
|
||||
this->color_correct_blue(color.blue), this->color_correct_white(color.white));
|
||||
}
|
||||
inline uint8_t color_correct_red(uint8_t red) const ESPHOME_ALWAYS_INLINE {
|
||||
uint8_t res = esp_scale8(esp_scale8(red, this->max_brightness_.red), this->local_brightness_);
|
||||
uint8_t res = esp_scale8_twice(red, this->max_brightness_.red, this->local_brightness_);
|
||||
return this->gamma_table_[res];
|
||||
}
|
||||
inline uint8_t color_correct_green(uint8_t green) const ESPHOME_ALWAYS_INLINE {
|
||||
uint8_t res = esp_scale8(esp_scale8(green, this->max_brightness_.green), this->local_brightness_);
|
||||
uint8_t res = esp_scale8_twice(green, this->max_brightness_.green, this->local_brightness_);
|
||||
return this->gamma_table_[res];
|
||||
}
|
||||
inline uint8_t color_correct_blue(uint8_t blue) const ESPHOME_ALWAYS_INLINE {
|
||||
uint8_t res = esp_scale8(esp_scale8(blue, this->max_brightness_.blue), this->local_brightness_);
|
||||
uint8_t res = esp_scale8_twice(blue, this->max_brightness_.blue, this->local_brightness_);
|
||||
return this->gamma_table_[res];
|
||||
}
|
||||
inline uint8_t color_correct_white(uint8_t white) const ESPHOME_ALWAYS_INLINE {
|
||||
uint8_t res = esp_scale8(esp_scale8(white, this->max_brightness_.white), this->local_brightness_);
|
||||
uint8_t res = esp_scale8_twice(white, this->max_brightness_.white, this->local_brightness_);
|
||||
return this->gamma_table_[res];
|
||||
}
|
||||
inline Color color_uncorrect(Color color) const ESPHOME_ALWAYS_INLINE {
|
||||
|
||||
@@ -14,6 +14,15 @@ inline static constexpr uint8_t esp_scale8(uint8_t i, uint8_t scale) {
|
||||
return (uint16_t(i) * (1 + uint16_t(scale))) / 256;
|
||||
}
|
||||
|
||||
/// Scale an 8-bit value by two 8-bit scale factors with improved precision.
|
||||
/// This is more accurate than calling esp_scale8() twice because it delays
|
||||
/// truncation until after both multiplications, preserving intermediate precision.
|
||||
/// For example: esp_scale8_twice(value, max_brightness, local_brightness)
|
||||
/// gives better results than esp_scale8(esp_scale8(value, max_brightness), local_brightness)
|
||||
inline static constexpr uint8_t esp_scale8_twice(uint8_t i, uint8_t scale1, uint8_t scale2) {
|
||||
return (uint32_t(i) * (1 + uint32_t(scale1)) * (1 + uint32_t(scale2))) >> 16;
|
||||
}
|
||||
|
||||
struct Color {
|
||||
union {
|
||||
struct {
|
||||
|
||||
Reference in New Issue
Block a user