| 17 | } |
| 18 | |
| 19 | static HSV16 RGBtoHSV16(const CRGB &rgb) { |
| 20 | // Work with 8-bit values directly |
| 21 | u8 r = rgb.r; |
| 22 | u8 g = rgb.g; |
| 23 | u8 b = rgb.b; |
| 24 | |
| 25 | // Find min and max |
| 26 | u8 mx = max(r, max(g, b)); |
| 27 | u8 mn = min(r, min(g, b)); |
| 28 | u8 delta = mx - mn; |
| 29 | |
| 30 | u16 h = 0; |
| 31 | u16 s = 0; |
| 32 | u16 v = scale8_to_16_accurate(mx); |
| 33 | |
| 34 | // Calculate saturation using improved scaling |
| 35 | if (mx > 0) { |
| 36 | // s = (delta * 65535) / mx, but with better accuracy |
| 37 | // Use the same technique as scale8_to_16_accurate but for arbitrary denominator |
| 38 | if (delta == mx) { |
| 39 | s = 65535; // Saturation is 100% |
| 40 | } else { |
| 41 | s = (u16)(((u32)delta * 65535 + (mx >> 1)) / mx); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | // Calculate hue using improved algorithms |
| 46 | if (delta > 0) { |
| 47 | u32 hue_calc = 0; |
| 48 | |
| 49 | if (mx == r) { |
| 50 | // Hue in red sector (0-60 degrees) |
| 51 | if (g >= b) { |
| 52 | // Use improved division: hue_calc = (g - b) * 65535 / (6 * delta) |
| 53 | u32 numerator = (u32)(g - b) * 65535; |
| 54 | if (delta <= 42) { // 6 * 42 = 252, safe for small delta |
| 55 | hue_calc = numerator / (6 * delta); |
| 56 | } else { |
| 57 | hue_calc = numerator / delta / 6; // Avoid overflow |
| 58 | } |
| 59 | } else { |
| 60 | u32 numerator = (u32)(b - g) * 65535; |
| 61 | if (delta <= 42) { |
| 62 | hue_calc = 65535 - numerator / (6 * delta); |
| 63 | } else { |
| 64 | hue_calc = 65535 - numerator / delta / 6; |
| 65 | } |
| 66 | } |
| 67 | } else if (mx == g) { |
| 68 | // Hue in green sector (60-180 degrees) |
| 69 | // Handle signed arithmetic properly to avoid integer underflow |
| 70 | i32 signed_diff = (i32)b - (i32)r; |
| 71 | u32 sector_offset = 65535 / 3; // 60 degrees (120 degrees in 16-bit space) |
| 72 | |
| 73 | if (signed_diff >= 0) { |
| 74 | // Positive case: b >= r |
| 75 | u32 numerator = (u32)signed_diff * 65535; |
| 76 | if (delta <= 42) { |
no test coverage detected