FastLED 3.9.3
Loading...
Searching...
No Matches
brightness_bitshifter.h
1#pragma once
2
3#include <stdint.h>
4
5
6
7inline uint8_t brightness_bitshifter8(uint8_t *brightness_src, uint8_t *brightness_dst, uint8_t max_shifts) {
8 uint8_t src = *brightness_src;
9 if (*brightness_dst == 0 || src == 0) {
10 return 0;
11 }
12 // Steal brightness from brightness_src and give it to brightness_dst.
13 // After this function concludes the multiplication of brightness_dst and brightness_src will remain
14 // constant.
15 // This algorithm is a little difficult to follow and I don't understand why it works that well,
16 // however I did work it out manually and has something to do with how numbers respond to bitshifts.
17 uint8_t curr = *brightness_dst;
18 uint8_t shifts = 0;
19 for (uint8_t i = 0; i < max_shifts && src > 1; i++) {
20 if (curr & 0b10000000) {
21 // next shift will overflow
22 break;
23 }
24 curr <<= 1;
25 src >>= 1;
26 shifts++;
27 }
28 // write out the output values.
29 *brightness_dst = curr;
30 *brightness_src = src;
31 return shifts;
32}
33
34// Return value is the number of shifts on the src. Multiply this by the number of steps to get the
35// the number of shifts on the dst.
36inline uint8_t brightness_bitshifter16(uint8_t *brightness_src, uint16_t *brightness_dst, uint8_t max_shifts, uint8_t steps=2) {
37 uint8_t src = *brightness_src;
38 if (*brightness_src == 0 || *brightness_src == 0) {
39 return 0;
40 }
41 uint16_t overflow_mask = 0b1000000000000000;
42 for (uint8_t i = 1; i < steps; i++) {
43 overflow_mask >>= 1;
44 overflow_mask |= 0b1000000000000000;
45 }
46 const uint8_t underflow_mask = 0x1;
47 // Steal brightness from brightness_src and give it to brightness_dst.
48 // After this function concludes the multiplication of brightness_dst and brightness_src will remain
49 // constant.
50 uint16_t curr = *brightness_dst;
51 uint8_t shifts = 0;
52 for (uint8_t i = 0; i < max_shifts; i++) {
53 if (src & underflow_mask) {
54 break;
55 }
56 if (curr & overflow_mask) {
57 // next shift will overflow
58 break;
59 }
60 curr <<= steps;
61 src >>= 1;
62 shifts++;
63 }
64 // write out the output values.
65 *brightness_dst = curr;
66 *brightness_src = src;
67 return shifts;
68}
69
70