1
0
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:
Jeff Brown
2025-10-21 15:11:11 -07:00
committed by GitHub
parent 8500323d39
commit 1ea80594c6
2 changed files with 13 additions and 4 deletions

View File

@@ -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 {

View File

@@ -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 {