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