| 36 | /// @note HD108 uses RGB wire order: pixel[0]=Red, pixel[1]=Green, pixel[2]=Blue |
| 37 | template <typename InputIterator, typename OutputIterator> |
| 38 | void encodeHD108(InputIterator first, InputIterator last, OutputIterator out, |
| 39 | u8 global_brightness = 255) FL_NOEXCEPT { |
| 40 | // Start frame: 64 bits (8 bytes) of 0x00 |
| 41 | for (int i = 0; i < 8; i++) { |
| 42 | *out++ = 0x00; |
| 43 | } |
| 44 | |
| 45 | // Compute brightness header bytes (cached for all LEDs) |
| 46 | u8 f0, f1; |
| 47 | hd108BrightnessHeader(global_brightness, &f0, &f1); |
| 48 | |
| 49 | // LED data: 2-byte header + 6-byte RGB16 (count as we go) |
| 50 | size_t num_leds = 0; |
| 51 | while (first != last) { |
| 52 | const fl::array<u8, BYTES_PER_PIXEL_RGB>& pixel = *first; |
| 53 | |
| 54 | // Apply gamma correction (2.8) to 16-bit (RGB order: 0=R, 1=G, 2=B) |
| 55 | u16 r16 = hd108GammaCorrect(pixel[0]); // Red |
| 56 | u16 g16 = hd108GammaCorrect(pixel[1]); // Green |
| 57 | u16 b16 = hd108GammaCorrect(pixel[2]); // Blue |
| 58 | |
| 59 | // Transmit: 2 header + 6 color bytes (16-bit RGB, big-endian) |
| 60 | *out++ = f0; |
| 61 | *out++ = f1; |
| 62 | *out++ = static_cast<u8>(r16 >> 8); |
| 63 | *out++ = static_cast<u8>(r16 & 0xFF); |
| 64 | *out++ = static_cast<u8>(g16 >> 8); |
| 65 | *out++ = static_cast<u8>(g16 & 0xFF); |
| 66 | *out++ = static_cast<u8>(b16 >> 8); |
| 67 | *out++ = static_cast<u8>(b16 & 0xFF); |
| 68 | |
| 69 | ++first; |
| 70 | ++num_leds; |
| 71 | } |
| 72 | |
| 73 | // End frame: (num_leds / 2) + 4 bytes of 0xFF |
| 74 | const size_t latch = num_leds / 2 + 4; |
| 75 | for (size_t i = 0; i < latch; i++) { |
| 76 | *out++ = 0xFF; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | /// @brief Encode pixel data in HD108 format with per-LED brightness |
| 81 | /// @tparam InputIterator Iterator yielding fl::array<u8, 3> (3 bytes in wire order) |
no test coverage detected