FastLED 3.9.15
Loading...
Searching...
No Matches
scale8.h
Go to the documentation of this file.
1#pragma once
2
3#include "lib8static.h"
4#include "crgb.h"
5#include "fl/namespace.h"
6#include "fastled_config.h"
7
8#pragma GCC diagnostic push
9#pragma GCC diagnostic ignored "-Wunused-parameter"
10#pragma GCC diagnostic ignored "-Wreturn-type"
11
12
14
18
21
31
41#if SCALE8_C == 1
42#if (FASTLED_SCALE8_FIXED == 1)
43 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
44#else
45 return ((uint16_t)i * (uint16_t)(scale)) >> 8;
46#endif
47#elif SCALE8_AVRASM == 1
48#if defined(LIB8_ATTINY)
49#if (FASTLED_SCALE8_FIXED == 1)
50 uint8_t work = i;
51#else
52 uint8_t work = 0;
53#endif
54 uint8_t cnt = 0x80;
55 asm volatile(
56#if (FASTLED_SCALE8_FIXED == 1)
57 " inc %[scale] \n\t"
58 " breq DONE_%= \n\t"
59 " clr %[work] \n\t"
60#endif
61 "LOOP_%=: \n\t"
62 /*" sbrc %[scale], 0 \n\t"
63 " add %[work], %[i] \n\t"
64 " ror %[work] \n\t"
65 " lsr %[scale] \n\t"
66 " clc \n\t"*/
67 " sbrc %[scale], 0 \n\t"
68 " add %[work], %[i] \n\t"
69 " ror %[work] \n\t"
70 " lsr %[scale] \n\t"
71 " lsr %[cnt] \n\t"
72 "brcc LOOP_%= \n\t"
73 "DONE_%=: \n\t"
74 : [work] "+r"(work), [cnt] "+r"(cnt)
75 : [scale] "r"(scale), [i] "r"(i)
76 :);
77 return work;
78#else
79 asm volatile(
80#if (FASTLED_SCALE8_FIXED == 1)
81 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
82 "mul %0, %1 \n\t"
83 // Add i to r0, possibly setting the carry flag
84 "add r0, %0 \n\t"
85 // load the immediate 0 into i (note, this does _not_ touch any flags)
86 "ldi %0, 0x00 \n\t"
87 // walk and chew gum at the same time
88 "adc %0, r1 \n\t"
89#else
90 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
91 "mul %0, %1 \n\t"
92 /* Move the high 8-bits of the product (r1) back to i */
93 "mov %0, r1 \n\t"
94 /* Restore r1 to "0"; it's expected to always be that */
95#endif
96 "clr __zero_reg__ \n\t"
97
98 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
99 : "r"(scale) /* uses scale */
100 : "r0", "r1" /* clobbers r0, r1 */
101 );
102 /* Return the result */
103 return i;
104#endif
105#else
106#error "No implementation for scale8 available."
107#endif
108}
109
110constexpr uint8_t scale8_constexpr(uint8_t i, fract8 scale) {
111 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
112}
113
124#if SCALE8_C == 1 || defined(LIB8_ATTINY)
125 uint8_t j = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
126 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
127 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) +
128 // nonzeroscale;
129 return j;
130#elif SCALE8_AVRASM == 1
131 uint8_t j = 0;
132 asm volatile(" tst %[i]\n\t"
133 " breq L_%=\n\t"
134 " mul %[i], %[scale]\n\t"
135 " mov %[j], r1\n\t"
136 " clr __zero_reg__\n\t"
137 " cpse %[scale], r1\n\t"
138 " subi %[j], 0xFF\n\t"
139 "L_%=: \n\t"
140 : [j] "+d"(j) // r16-r31, restricted by subi
141 : [i] "r"(i), [scale] "r"(scale)
142 : "r0", "r1");
143 return j;
144 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
145 // asm volatile(
146 // " tst %0 \n"
147 // " breq L_%= \n"
148 // " mul %0, %1 \n"
149 // " mov %0, r1 \n"
150 // " add %0, %2 \n"
151 // " clr __zero_reg__ \n"
152 // "L_%=: \n"
153 // : "+a" (i)
154 // : "a" (scale), "a" (nonzeroscale)
155 // : "r0", "r1");
156 // // Return the result
157 // return i;
158#else
159#error "No implementation for scale8_video available."
160#endif
161}
162
167
177 fract8 scale) {
178#if SCALE8_C == 1
179#if (FASTLED_SCALE8_FIXED == 1)
180 return (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
181#else
182 return ((int)i * (int)(scale)) >> 8;
183#endif
184#elif SCALE8_AVRASM == 1
185 asm volatile(
186#if (FASTLED_SCALE8_FIXED == 1)
187 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
188 "mul %0, %1 \n\t"
189 // Add i to r0, possibly setting the carry flag
190 "add r0, %0 \n\t"
191 // load the immediate 0 into i (note, this does _not_ touch any flags)
192 "ldi %0, 0x00 \n\t"
193 // walk and chew gum at the same time
194 "adc %0, r1 \n\t"
195#else
196 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
197 "mul %0, %1 \n\t"
198 /* Move the high 8-bits of the product (r1) back to i */
199 "mov %0, r1 \n\t"
200#endif
201 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
202 /* "clr __zero_reg__ \n\t" */
203 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
204 : "r"(scale) /* uses scale */
205 : "r0", "r1" /* clobbers r0, r1 */
206 );
207 // Return the result
208 return i;
209#else
210#error "No implementation for scale8_LEAVING_R1_DIRTY available."
211#endif
212}
213
224 fract8 scale) {
225#if SCALE8_C == 1
226#if (FASTLED_SCALE8_FIXED == 1)
227 i = (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
228#else
229 i = ((int)i * (int)(scale)) >> 8;
230#endif
231#elif SCALE8_AVRASM == 1
232 asm volatile(
233#if (FASTLED_SCALE8_FIXED == 1)
234 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
235 "mul %0, %1 \n\t"
236 // Add i to r0, possibly setting the carry flag
237 "add r0, %0 \n\t"
238 // load the immediate 0 into i (note, this does _not_ touch any flags)
239 "ldi %0, 0x00 \n\t"
240 // walk and chew gum at the same time
241 "adc %0, r1 \n\t"
242#else
243 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
244 "mul %0, %1 \n\t"
245 /* Move the high 8-bits of the product (r1) back to i */
246 "mov %0, r1 \n\t"
247#endif
248 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
249 /* "clr __zero_reg__ \n\t" */
250
251 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
252 : "r"(scale) /* uses scale */
253 : "r0", "r1" /* clobbers r0, r1 */
254 );
255#else
256#error "No implementation for nscale8_LEAVING_R1_DIRTY available."
257#endif
258}
259
269 fract8 scale) {
270#if SCALE8_C == 1 || defined(LIB8_ATTINY)
271 uint8_t j = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
272 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
273 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) +
274 // nonzeroscale;
275 return j;
276#elif SCALE8_AVRASM == 1
277 uint8_t j = 0;
278 asm volatile(" tst %[i]\n\t"
279 " breq L_%=\n\t"
280 " mul %[i], %[scale]\n\t"
281 " mov %[j], r1\n\t"
282 " breq L_%=\n\t"
283 " subi %[j], 0xFF\n\t"
284 "L_%=: \n\t"
285 : [j] "+d"(j) // r16-r31, restricted by subi
286 : [i] "r"(i), [scale] "r"(scale)
287 : "r0", "r1");
288 return j;
289 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
290 // asm volatile(
291 // " tst %0 \n"
292 // " breq L_%= \n"
293 // " mul %0, %1 \n"
294 // " mov %0, r1 \n"
295 // " add %0, %2 \n"
296 // " clr __zero_reg__ \n"
297 // "L_%=: \n"
298 // : "+a" (i)
299 // : "a" (scale), "a" (nonzeroscale)
300 // : "r0", "r1");
301 // // Return the result
302 // return i;
303#else
304#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
305#endif
306}
307
318 fract8 scale) {
319#if SCALE8_C == 1 || defined(LIB8_ATTINY)
320 i = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
321#elif SCALE8_AVRASM == 1
322 asm volatile(" tst %[i]\n\t"
323 " breq L_%=\n\t"
324 " mul %[i], %[scale]\n\t"
325 " mov %[i], r1\n\t"
326 " breq L_%=\n\t"
327 " subi %[i], 0xFF\n\t"
328 "L_%=: \n\t"
329 : [i] "+d"(i) // r16-r31, restricted by subi
330 : [scale] "r"(scale)
331 : "r0", "r1");
332#else
333#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
334#endif
335}
336
340#if CLEANUP_R1_AVRASM == 1
341 // Restore r1 to "0"; it's expected to always be that
342 asm volatile("clr __zero_reg__ \n\t" : : : "r1");
343#endif
344}
345
346constexpr CRGB nscale8x3_constexpr(uint8_t r, uint8_t g, uint8_t b, fract8 scale) {
347 return CRGB(((int)r * (int)(scale)) >> 8, ((int)g * (int)(scale)) >> 8,
348 ((int)b * (int)(scale)) >> 8);
349}
350
352
363LIB8STATIC void nscale8x3(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale) {
364#if SCALE8_C == 1
365#if (FASTLED_SCALE8_FIXED == 1)
366 uint16_t scale_fixed = scale + 1;
367 r = (((uint16_t)r) * scale_fixed) >> 8;
368 g = (((uint16_t)g) * scale_fixed) >> 8;
369 b = (((uint16_t)b) * scale_fixed) >> 8;
370#else
371 r = ((int)r * (int)(scale)) >> 8;
372 g = ((int)g * (int)(scale)) >> 8;
373 b = ((int)b * (int)(scale)) >> 8;
374#endif
375#elif SCALE8_AVRASM == 1
379 cleanup_R1();
380#else
381#error "No implementation for nscale8x3 available."
382#endif
383}
384
397LIB8STATIC void nscale8x3_video(uint8_t &r, uint8_t &g, uint8_t &b,
398 fract8 scale) {
399#if SCALE8_C == 1
400 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
401 r = (r == 0) ? 0 : (((int)r * (int)(scale)) >> 8) + nonzeroscale;
402 g = (g == 0) ? 0 : (((int)g * (int)(scale)) >> 8) + nonzeroscale;
403 b = (b == 0) ? 0 : (((int)b * (int)(scale)) >> 8) + nonzeroscale;
404#elif SCALE8_AVRASM == 1
408 cleanup_R1();
409#else
410#error "No implementation for nscale8x3 available."
411#endif
412}
413
423LIB8STATIC void nscale8x2(uint8_t &i, uint8_t &j, fract8 scale) {
424#if SCALE8_C == 1
425#if FASTLED_SCALE8_FIXED == 1
426 uint16_t scale_fixed = scale + 1;
427 i = (((uint16_t)i) * scale_fixed) >> 8;
428 j = (((uint16_t)j) * scale_fixed) >> 8;
429#else
430 i = ((uint16_t)i * (uint16_t)(scale)) >> 8;
431 j = ((uint16_t)j * (uint16_t)(scale)) >> 8;
432#endif
433#elif SCALE8_AVRASM == 1
436 cleanup_R1();
437#else
438#error "No implementation for nscale8x2 available."
439#endif
440}
441
453LIB8STATIC void nscale8x2_video(uint8_t &i, uint8_t &j, fract8 scale) {
454#if SCALE8_C == 1
455 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
456 i = (i == 0) ? 0 : (((int)i * (int)(scale)) >> 8) + nonzeroscale;
457 j = (j == 0) ? 0 : (((int)j * (int)(scale)) >> 8) + nonzeroscale;
458#elif SCALE8_AVRASM == 1
461 cleanup_R1();
462#else
463#error "No implementation for nscale8x2 available."
464#endif
465}
466
475 if (scale == 0) {
476 return 0; // Fixes non zero output when scale == 0 and
477 // FASTLED_SCALE8_FIXED==1
478 }
479#if SCALE16BY8_C == 1
480 uint16_t result;
481#if FASTLED_SCALE8_FIXED == 1
482 result = (((uint32_t)(i) * (1 + ((uint32_t)scale))) >> 8);
483#else
484 result = (i * scale) / 256;
485#endif
486 return result;
487#elif SCALE16BY8_AVRASM == 1
488#if FASTLED_SCALE8_FIXED == 1
489 uint16_t result = 0;
490 asm volatile(
491 // result.A = HighByte( (i.A x scale) + i.A )
492 " mul %A[i], %[scale] \n\t"
493 " add r0, %A[i] \n\t"
494 // " adc r1, [zero] \n\t"
495 // " mov %A[result], r1 \n\t"
496 " adc %A[result], r1 \n\t"
497
498 // result.A-B += i.B x scale
499 " mul %B[i], %[scale] \n\t"
500 " add %A[result], r0 \n\t"
501 " adc %B[result], r1 \n\t"
502
503 // cleanup r1
504 " clr __zero_reg__ \n\t"
505
506 // result.A-B += i.B
507 " add %A[result], %B[i] \n\t"
508 " adc %B[result], __zero_reg__ \n\t"
509
510 : [result] "+r"(result)
511 : [i] "r"(i), [scale] "r"(scale)
512 : "r0", "r1");
513 return result;
514#else
515 uint16_t result = 0;
516 asm volatile(
517 // result.A = HighByte(i.A x j )
518 " mul %A[i], %[scale] \n\t"
519 " mov %A[result], r1 \n\t"
520 //" clr %B[result] \n\t"
521
522 // result.A-B += i.B x j
523 " mul %B[i], %[scale] \n\t"
524 " add %A[result], r0 \n\t"
525 " adc %B[result], r1 \n\t"
526
527 // cleanup r1
528 " clr __zero_reg__ \n\t"
529
530 : [result] "+r"(result)
531 : [i] "r"(i), [scale] "r"(scale)
532 : "r0", "r1");
533 return result;
534#endif
535#else
536#error "No implementation for scale16by8 available."
537#endif
538}
539
546LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale) {
547#if SCALE16_C == 1
548 uint16_t result;
549#if FASTLED_SCALE8_FIXED == 1
550 result = ((uint32_t)(i) * (1 + (uint32_t)(scale))) / 65536;
551#else
552 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
553#endif
554 return result;
555#elif SCALE16_AVRASM == 1
556#if FASTLED_SCALE8_FIXED == 1
557 // implemented sort of like
558 // result = ((i * scale) + i ) / 65536
559 //
560 // why not like this, you may ask?
561 // result = (i * (scale+1)) / 65536
562 // the answer is that if scale is 65535, then scale+1
563 // will be zero, which is not what we want.
564 uint32_t result;
565 asm volatile(
566 // result.A-B = i.A x scale.A
567 " mul %A[i], %A[scale] \n\t"
568 // save results...
569 // basic idea:
570 //" mov %A[result], r0 \n\t"
571 //" mov %B[result], r1 \n\t"
572 // which can be written as...
573 " movw %A[result], r0 \n\t"
574 // Because we're going to add i.A-B to
575 // result.A-D, we DO need to keep both
576 // the r0 and r1 portions of the product
577 // UNlike in the 'unfixed scale8' version.
578 // So the movw here is needed.
579 : [result] "=r"(result)
580 : [i] "r"(i), [scale] "r"(scale)
581 : "r0", "r1");
582
583 asm volatile(
584 // result.C-D = i.B x scale.B
585 " mul %B[i], %B[scale] \n\t"
586 //" mov %C[result], r0 \n\t"
587 //" mov %D[result], r1 \n\t"
588 " movw %C[result], r0 \n\t"
589 : [result] "+r"(result)
590 : [i] "r"(i), [scale] "r"(scale)
591 : "r0", "r1");
592
593 const uint8_t zero = 0;
594 asm volatile(
595 // result.B-D += i.B x scale.A
596 " mul %B[i], %A[scale] \n\t"
597
598 " add %B[result], r0 \n\t"
599 " adc %C[result], r1 \n\t"
600 " adc %D[result], %[zero] \n\t"
601
602 // result.B-D += i.A x scale.B
603 " mul %A[i], %B[scale] \n\t"
604
605 " add %B[result], r0 \n\t"
606 " adc %C[result], r1 \n\t"
607 " adc %D[result], %[zero] \n\t"
608
609 // cleanup r1
610 " clr r1 \n\t"
611
612 : [result] "+r"(result)
613 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
614 : "r0", "r1");
615
616 asm volatile(
617 // result.A-D += i.A-B
618 " add %A[result], %A[i] \n\t"
619 " adc %B[result], %B[i] \n\t"
620 " adc %C[result], %[zero] \n\t"
621 " adc %D[result], %[zero] \n\t"
622 : [result] "+r"(result)
623 : [i] "r"(i), [zero] "r"(zero));
624
625 result = result >> 16;
626 return result;
627#else
628 uint32_t result;
629 asm volatile(
630 // result.A-B = i.A x scale.A
631 " mul %A[i], %A[scale] \n\t"
632 // save results...
633 // basic idea:
634 //" mov %A[result], r0 \n\t"
635 //" mov %B[result], r1 \n\t"
636 // which can be written as...
637 " movw %A[result], r0 \n\t"
638 // We actually don't need to do anything with r0,
639 // as result.A is never used again here, so we
640 // could just move the high byte, but movw is
641 // one clock cycle, just like mov, so might as
642 // well, in case we want to use this code for
643 // a generic 16x16 multiply somewhere.
644
645 : [result] "=r"(result)
646 : [i] "r"(i), [scale] "r"(scale)
647 : "r0", "r1");
648
649 asm volatile(
650 // result.C-D = i.B x scale.B
651 " mul %B[i], %B[scale] \n\t"
652 //" mov %C[result], r0 \n\t"
653 //" mov %D[result], r1 \n\t"
654 " movw %C[result], r0 \n\t"
655 : [result] "+r"(result)
656 : [i] "r"(i), [scale] "r"(scale)
657 : "r0", "r1");
658
659 const uint8_t zero = 0;
660 asm volatile(
661 // result.B-D += i.B x scale.A
662 " mul %B[i], %A[scale] \n\t"
663
664 " add %B[result], r0 \n\t"
665 " adc %C[result], r1 \n\t"
666 " adc %D[result], %[zero] \n\t"
667
668 // result.B-D += i.A x scale.B
669 " mul %A[i], %B[scale] \n\t"
670
671 " add %B[result], r0 \n\t"
672 " adc %C[result], r1 \n\t"
673 " adc %D[result], %[zero] \n\t"
674
675 // cleanup r1
676 " clr r1 \n\t"
677
678 : [result] "+r"(result)
679 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
680 : "r0", "r1");
681
682 result = result >> 16;
683 return result;
684#endif
685#else
686#error "No implementation for scale16 available."
687#endif
688}
689
690
706
709LIB8STATIC uint8_t dim8_raw(uint8_t x) { return scale8(x, x); }
710
713LIB8STATIC uint8_t dim8_video(uint8_t x) { return scale8_video(x, x); }
714
716LIB8STATIC uint8_t dim8_lin(uint8_t x) {
717 if (x & 0x80) {
718 x = scale8(x, x);
719 } else {
720 x += 1;
721 x /= 2;
722 }
723 return x;
724}
725
727LIB8STATIC uint8_t brighten8_raw(uint8_t x) {
728 uint8_t ix = 255 - x;
729 return 255 - scale8(ix, ix);
730}
731
733LIB8STATIC uint8_t brighten8_video(uint8_t x) {
734 uint8_t ix = 255 - x;
735 return 255 - scale8_video(ix, ix);
736}
737
739LIB8STATIC uint8_t brighten8_lin(uint8_t x) {
740 uint8_t ix = 255 - x;
741 if (ix & 0x80) {
742 ix = scale8(ix, ix);
743 } else {
744 ix += 1;
745 ix /= 2;
746 }
747 return 255 - ix;
748}
749
752
754
755#pragma GCC diagnostic pop
int x
Definition Audio.ino:71
UISlider scale("Scale", 1.0f, 0.0f, 1.0f, 0.01f)
Defines the red, green, and blue (RGB) pixel struct.
Contains definitions that can be used to configure FastLED at compile time.
LIB8STATIC uint8_t brighten8_lin(uint8_t x)
Brighten a value (inverse of dim8_lin())
Definition scale8.h:739
LIB8STATIC uint8_t dim8_lin(uint8_t x)
Linear version of the dimming function that halves for values < 128.
Definition scale8.h:716
LIB8STATIC uint8_t dim8_video(uint8_t x)
Adjust a scaling value for dimming for video (value will never go below 1)
Definition scale8.h:713
LIB8STATIC uint8_t brighten8_video(uint8_t x)
Brighten a value (inverse of dim8_video())
Definition scale8.h:733
LIB8STATIC uint8_t dim8_raw(uint8_t x)
Adjust a scaling value for dimming.
Definition scale8.h:709
LIB8STATIC uint8_t brighten8_raw(uint8_t x)
Brighten a value (inverse of dim8_raw())
Definition scale8.h:727
uint8_t fract8
ANSI: unsigned short _Fract.
Definition types.h:36
uint16_t fract16
ANSI: unsigned _Fract.
Definition types.h:46
LIB8STATIC_ALWAYS_INLINE void nscale8_LEAVING_R1_DIRTY(uint8_t &i, fract8 scale)
In place modifying version of scale8() that does not clean up the R1 register on AVR.
Definition scale8.h:223
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
Definition scale8.h:339
constexpr CRGB nscale8x3_constexpr(uint8_t r, uint8_t g, uint8_t b, fract8 scale)
Definition scale8.h:346
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8() does not clean up the R1 register on AVR.
Definition scale8.h:176
LIB8STATIC_ALWAYS_INLINE void nscale8_video_LEAVING_R1_DIRTY(uint8_t &i, fract8 scale)
In place modifying version of scale8_video() that does not clean up the R1 register on AVR.
Definition scale8.h:317
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8_video() does not clean up the R1 register on AVR.
Definition scale8.h:268
LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale)
Scale a 16-bit unsigned value by an 16-bit value, which is treated as the numerator of a fraction who...
Definition scale8.h:546
LIB8STATIC void nscale8x3(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale)
Scale three one-byte values by a fourth one, which is treated as the numerator of a fraction whose de...
Definition scale8.h:363
LIB8STATIC void nscale8x2_video(uint8_t &i, uint8_t &j, fract8 scale)
Scale two one-byte values by a third one, which is treated as the numerator of a fraction whose demom...
Definition scale8.h:453
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video(uint8_t i, fract8 scale)
The "video" version of scale8() guarantees that the output will be only be zero if one or both of the...
Definition scale8.h:123
constexpr uint8_t scale8_constexpr(uint8_t i, fract8 scale)
Definition scale8.h:110
LIB8STATIC void nscale8x2(uint8_t &i, uint8_t &j, fract8 scale)
Scale two one-byte values by a third one, which is treated as the numerator of a fraction whose demom...
Definition scale8.h:423
LIB8STATIC void nscale8x3_video(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale)
Scale three one-byte values by a fourth one, which is treated as the numerator of a fraction whose de...
Definition scale8.h:397
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8(uint16_t i, fract8 scale)
Scale a 16-bit unsigned value by an 8-bit value, which is treated as the numerator of a fraction whos...
Definition scale8.h:474
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:40
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8static.h:10
#define LIB8STATIC_ALWAYS_INLINE
Define a LIB8TION member function as always static inline.
Definition lib8static.h:12
Defines static inlining macros for lib8tion functions.
#define FASTLED_NAMESPACE_END
Definition namespace.h:23
Implements the FastLED namespace macros.
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:55