| 88 | /// @note HD108 uses RGB wire order: pixel[0]=Red, pixel[1]=Green, pixel[2]=Blue |
| 89 | template <typename InputIterator, typename BrightnessIterator, typename OutputIterator> |
| 90 | void encodeHD108_HD(InputIterator first, InputIterator last, |
| 91 | BrightnessIterator brightness_first, OutputIterator out) FL_NOEXCEPT { |
| 92 | // Start frame: 64 bits (8 bytes) of 0x00 |
| 93 | for (int i = 0; i < 8; i++) { |
| 94 | *out++ = 0x00; |
| 95 | } |
| 96 | |
| 97 | // Brightness conversion cache (avoid recomputing same values) |
| 98 | u8 lastBrightness8 = 0; |
| 99 | u8 lastF0 = 0xFF, lastF1 = 0xFF; // Invalid markers |
| 100 | |
| 101 | // LED data: 2-byte header + 6-byte RGB16 (count as we go) |
| 102 | size_t num_leds = 0; |
| 103 | while (first != last) { |
| 104 | const fl::array<u8, BYTES_PER_PIXEL_RGB>& pixel = *first; |
| 105 | u8 brightness = *brightness_first; |
| 106 | |
| 107 | // Apply gamma correction (2.8) to 16-bit (RGB order: 0=R, 1=G, 2=B) |
| 108 | u16 r16 = hd108GammaCorrect(pixel[0]); // Red |
| 109 | u16 g16 = hd108GammaCorrect(pixel[1]); // Green |
| 110 | u16 b16 = hd108GammaCorrect(pixel[2]); // Blue |
| 111 | |
| 112 | // Compute brightness header (with caching) |
| 113 | u8 f0, f1; |
| 114 | if (brightness == lastBrightness8 && lastF0 != 0xFF) { |
| 115 | f0 = lastF0; |
| 116 | f1 = lastF1; |
| 117 | } else { |
| 118 | hd108BrightnessHeader(brightness, &f0, &f1); |
| 119 | lastBrightness8 = brightness; |
| 120 | lastF0 = f0; |
| 121 | lastF1 = f1; |
| 122 | } |
| 123 | |
| 124 | // Transmit: 2 header + 6 color bytes (16-bit RGB, big-endian) |
| 125 | *out++ = f0; |
| 126 | *out++ = f1; |
| 127 | *out++ = static_cast<u8>(r16 >> 8); |
| 128 | *out++ = static_cast<u8>(r16 & 0xFF); |
| 129 | *out++ = static_cast<u8>(g16 >> 8); |
| 130 | *out++ = static_cast<u8>(g16 & 0xFF); |
| 131 | *out++ = static_cast<u8>(b16 >> 8); |
| 132 | *out++ = static_cast<u8>(b16 & 0xFF); |
| 133 | |
| 134 | ++first; |
| 135 | ++brightness_first; |
| 136 | ++num_leds; |
| 137 | } |
| 138 | |
| 139 | // End frame: (num_leds / 2) + 4 bytes of 0xFF |
| 140 | const size_t latch = num_leds / 2 + 4; |
| 141 | for (size_t i = 0; i < latch; i++) { |
| 142 | *out++ = 0xFF; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | } // namespace fl |
no test coverage detected