FastLED 3.9.15
Loading...
Searching...
No Matches
scale8.h
Go to the documentation of this file.
2
3#pragma once
4
5#include "lib8tion/config.h"
6#include "crgb.h"
7#include "fl/namespace.h"
8#include "fastled_config.h"
9#include "lib8static.h"
10
15
16
18
22
25
35
45#if SCALE8_C == 1
46#if (FASTLED_SCALE8_FIXED == 1)
47 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
48#else
49 return ((uint16_t)i * (uint16_t)(scale)) >> 8;
50#endif
51#elif SCALE8_AVRASM == 1
52#if defined(LIB8_ATTINY)
53#if (FASTLED_SCALE8_FIXED == 1)
54 uint8_t work = i;
55#else
56 uint8_t work = 0;
57#endif
58 uint8_t cnt = 0x80;
59 asm volatile(
60#if (FASTLED_SCALE8_FIXED == 1)
61 " inc %[scale] \n\t"
62 " breq DONE_%= \n\t"
63 " clr %[work] \n\t"
64#endif
65 "LOOP_%=: \n\t"
66 /*" sbrc %[scale], 0 \n\t"
67 " add %[work], %[i] \n\t"
68 " ror %[work] \n\t"
69 " lsr %[scale] \n\t"
70 " clc \n\t"*/
71 " sbrc %[scale], 0 \n\t"
72 " add %[work], %[i] \n\t"
73 " ror %[work] \n\t"
74 " lsr %[scale] \n\t"
75 " lsr %[cnt] \n\t"
76 "brcc LOOP_%= \n\t"
77 "DONE_%=: \n\t"
78 : [work] "+r"(work), [cnt] "+r"(cnt)
79 : [scale] "r"(scale), [i] "r"(i)
80 :);
81 return work;
82#else
83 asm volatile(
84#if (FASTLED_SCALE8_FIXED == 1)
85 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
86 "mul %0, %1 \n\t"
87 // Add i to r0, possibly setting the carry flag
88 "add r0, %0 \n\t"
89 // load the immediate 0 into i (note, this does _not_ touch any flags)
90 "ldi %0, 0x00 \n\t"
91 // walk and chew gum at the same time
92 "adc %0, r1 \n\t"
93#else
94 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
95 "mul %0, %1 \n\t"
96 /* Move the high 8-bits of the product (r1) back to i */
97 "mov %0, r1 \n\t"
98 /* Restore r1 to "0"; it's expected to always be that */
99#endif
100 "clr __zero_reg__ \n\t"
101
102 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
103 : "r"(scale) /* uses scale */
104 : "r0", "r1" /* clobbers r0, r1 */
105 );
106 /* Return the result */
107 return i;
108#endif
109#else
110#error "No implementation for scale8 available."
111#endif
112}
113
114constexpr uint8_t scale8_constexpr(uint8_t i, fract8 scale) {
115 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
116}
117
128#if SCALE8_C == 1 || defined(LIB8_ATTINY)
129 uint8_t j = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
130 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
131 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) +
132 // nonzeroscale;
133 return j;
134#elif SCALE8_AVRASM == 1
135 uint8_t j = 0;
136 asm volatile(" tst %[i]\n\t"
137 " breq L_%=\n\t"
138 " mul %[i], %[scale]\n\t"
139 " mov %[j], r1\n\t"
140 " clr __zero_reg__\n\t"
141 " cpse %[scale], r1\n\t"
142 " subi %[j], 0xFF\n\t"
143 "L_%=: \n\t"
144 : [j] "+d"(j) // r16-r31, restricted by subi
145 : [i] "r"(i), [scale] "r"(scale)
146 : "r0", "r1");
147 return j;
148 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
149 // asm volatile(
150 // " tst %0 \n"
151 // " breq L_%= \n"
152 // " mul %0, %1 \n"
153 // " mov %0, r1 \n"
154 // " add %0, %2 \n"
155 // " clr __zero_reg__ \n"
156 // "L_%=: \n"
157 // : "+a" (i)
158 // : "a" (scale), "a" (nonzeroscale)
159 // : "r0", "r1");
160 // // Return the result
161 // return i;
162#else
163#error "No implementation for scale8_video available."
164#endif
165}
166
171
181 fract8 scale) {
182#if SCALE8_C == 1
183#if (FASTLED_SCALE8_FIXED == 1)
184 return (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
185#else
186 return ((int)i * (int)(scale)) >> 8;
187#endif
188#elif SCALE8_AVRASM == 1
189 asm volatile(
190#if (FASTLED_SCALE8_FIXED == 1)
191 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
192 "mul %0, %1 \n\t"
193 // Add i to r0, possibly setting the carry flag
194 "add r0, %0 \n\t"
195 // load the immediate 0 into i (note, this does _not_ touch any flags)
196 "ldi %0, 0x00 \n\t"
197 // walk and chew gum at the same time
198 "adc %0, r1 \n\t"
199#else
200 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
201 "mul %0, %1 \n\t"
202 /* Move the high 8-bits of the product (r1) back to i */
203 "mov %0, r1 \n\t"
204#endif
205 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
206 /* "clr __zero_reg__ \n\t" */
207 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
208 : "r"(scale) /* uses scale */
209 : "r0", "r1" /* clobbers r0, r1 */
210 );
211 // Return the result
212 return i;
213#else
214#error "No implementation for scale8_LEAVING_R1_DIRTY available."
215#endif
216}
217
228 fract8 scale) {
229#if SCALE8_C == 1
230#if (FASTLED_SCALE8_FIXED == 1)
231 i = (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
232#else
233 i = ((int)i * (int)(scale)) >> 8;
234#endif
235#elif SCALE8_AVRASM == 1
236 asm volatile(
237#if (FASTLED_SCALE8_FIXED == 1)
238 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
239 "mul %0, %1 \n\t"
240 // Add i to r0, possibly setting the carry flag
241 "add r0, %0 \n\t"
242 // load the immediate 0 into i (note, this does _not_ touch any flags)
243 "ldi %0, 0x00 \n\t"
244 // walk and chew gum at the same time
245 "adc %0, r1 \n\t"
246#else
247 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
248 "mul %0, %1 \n\t"
249 /* Move the high 8-bits of the product (r1) back to i */
250 "mov %0, r1 \n\t"
251#endif
252 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
253 /* "clr __zero_reg__ \n\t" */
254
255 : "+d"(i) /* writes to i; r16-r31, restricted by ldi */
256 : "r"(scale) /* uses scale */
257 : "r0", "r1" /* clobbers r0, r1 */
258 );
259#else
260#error "No implementation for nscale8_LEAVING_R1_DIRTY available."
261#endif
262}
263
273 fract8 scale) {
274#if SCALE8_C == 1 || defined(LIB8_ATTINY)
275 uint8_t j = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
276 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
277 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) +
278 // nonzeroscale;
279 return j;
280#elif SCALE8_AVRASM == 1
281 uint8_t j = 0;
282 asm volatile(" tst %[i]\n\t"
283 " breq L_%=\n\t"
284 " mul %[i], %[scale]\n\t"
285 " mov %[j], r1\n\t"
286 " breq L_%=\n\t"
287 " subi %[j], 0xFF\n\t"
288 "L_%=: \n\t"
289 : [j] "+d"(j) // r16-r31, restricted by subi
290 : [i] "r"(i), [scale] "r"(scale)
291 : "r0", "r1");
292 return j;
293 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
294 // asm volatile(
295 // " tst %0 \n"
296 // " breq L_%= \n"
297 // " mul %0, %1 \n"
298 // " mov %0, r1 \n"
299 // " add %0, %2 \n"
300 // " clr __zero_reg__ \n"
301 // "L_%=: \n"
302 // : "+a" (i)
303 // : "a" (scale), "a" (nonzeroscale)
304 // : "r0", "r1");
305 // // Return the result
306 // return i;
307#else
308#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
309#endif
310}
311
322 fract8 scale) {
323#if SCALE8_C == 1 || defined(LIB8_ATTINY)
324 i = (((int)i * (int)scale) >> 8) + ((i && scale) ? 1 : 0);
325#elif SCALE8_AVRASM == 1
326 asm volatile(" tst %[i]\n\t"
327 " breq L_%=\n\t"
328 " mul %[i], %[scale]\n\t"
329 " mov %[i], r1\n\t"
330 " breq L_%=\n\t"
331 " subi %[i], 0xFF\n\t"
332 "L_%=: \n\t"
333 : [i] "+d"(i) // r16-r31, restricted by subi
334 : [scale] "r"(scale)
335 : "r0", "r1");
336#else
337#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
338#endif
339}
340
344#if CLEANUP_R1_AVRASM == 1
345 // Restore r1 to "0"; it's expected to always be that
346 asm volatile("clr __zero_reg__ \n\t" : : : "r1");
347#endif
348}
349
350constexpr CRGB nscale8x3_constexpr(uint8_t r, uint8_t g, uint8_t b, fract8 scale) {
351 return CRGB(((int)r * (int)(scale)) >> 8, ((int)g * (int)(scale)) >> 8,
352 ((int)b * (int)(scale)) >> 8);
353}
354
356
367LIB8STATIC void nscale8x3(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale) {
368#if SCALE8_C == 1
369#if (FASTLED_SCALE8_FIXED == 1)
370 uint16_t scale_fixed = scale + 1;
371 r = (((uint16_t)r) * scale_fixed) >> 8;
372 g = (((uint16_t)g) * scale_fixed) >> 8;
373 b = (((uint16_t)b) * scale_fixed) >> 8;
374#else
375 r = ((int)r * (int)(scale)) >> 8;
376 g = ((int)g * (int)(scale)) >> 8;
377 b = ((int)b * (int)(scale)) >> 8;
378#endif
379#elif SCALE8_AVRASM == 1
383 cleanup_R1();
384#else
385#error "No implementation for nscale8x3 available."
386#endif
387}
388
401LIB8STATIC void nscale8x3_video(uint8_t &r, uint8_t &g, uint8_t &b,
402 fract8 scale) {
403#if SCALE8_C == 1
404 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
405 r = (r == 0) ? 0 : (((int)r * (int)(scale)) >> 8) + nonzeroscale;
406 g = (g == 0) ? 0 : (((int)g * (int)(scale)) >> 8) + nonzeroscale;
407 b = (b == 0) ? 0 : (((int)b * (int)(scale)) >> 8) + nonzeroscale;
408#elif SCALE8_AVRASM == 1
412 cleanup_R1();
413#else
414#error "No implementation for nscale8x3 available."
415#endif
416}
417
427LIB8STATIC void nscale8x2(uint8_t &i, uint8_t &j, fract8 scale) {
428#if SCALE8_C == 1
429#if FASTLED_SCALE8_FIXED == 1
430 uint16_t scale_fixed = scale + 1;
431 i = (((uint16_t)i) * scale_fixed) >> 8;
432 j = (((uint16_t)j) * scale_fixed) >> 8;
433#else
434 i = ((uint16_t)i * (uint16_t)(scale)) >> 8;
435 j = ((uint16_t)j * (uint16_t)(scale)) >> 8;
436#endif
437#elif SCALE8_AVRASM == 1
440 cleanup_R1();
441#else
442#error "No implementation for nscale8x2 available."
443#endif
444}
445
457LIB8STATIC void nscale8x2_video(uint8_t &i, uint8_t &j, fract8 scale) {
458#if SCALE8_C == 1
459 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
460 i = (i == 0) ? 0 : (((int)i * (int)(scale)) >> 8) + nonzeroscale;
461 j = (j == 0) ? 0 : (((int)j * (int)(scale)) >> 8) + nonzeroscale;
462#elif SCALE8_AVRASM == 1
465 cleanup_R1();
466#else
467#error "No implementation for nscale8x2 available."
468#endif
469}
470
479 if (scale == 0) {
480 return 0; // Fixes non zero output when scale == 0 and
481 // FASTLED_SCALE8_FIXED==1
482 }
483#if SCALE16BY8_C == 1
484 uint16_t result;
485#if FASTLED_SCALE8_FIXED == 1
486 result = (((uint32_t)(i) * (1 + ((uint32_t)scale))) >> 8);
487#else
488 result = (i * scale) / 256;
489#endif
490 return result;
491#elif SCALE16BY8_AVRASM == 1
492#if FASTLED_SCALE8_FIXED == 1
493 uint16_t result = 0;
494 asm volatile(
495 // result.A = HighByte( (i.A x scale) + i.A )
496 " mul %A[i], %[scale] \n\t"
497 " add r0, %A[i] \n\t"
498 // " adc r1, [zero] \n\t"
499 // " mov %A[result], r1 \n\t"
500 " adc %A[result], r1 \n\t"
501
502 // result.A-B += i.B x scale
503 " mul %B[i], %[scale] \n\t"
504 " add %A[result], r0 \n\t"
505 " adc %B[result], r1 \n\t"
506
507 // cleanup r1
508 " clr __zero_reg__ \n\t"
509
510 // result.A-B += i.B
511 " add %A[result], %B[i] \n\t"
512 " adc %B[result], __zero_reg__ \n\t"
513
514 : [result] "+r"(result)
515 : [i] "r"(i), [scale] "r"(scale)
516 : "r0", "r1");
517 return result;
518#else
519 uint16_t result = 0;
520 asm volatile(
521 // result.A = HighByte(i.A x j )
522 " mul %A[i], %[scale] \n\t"
523 " mov %A[result], r1 \n\t"
524 //" clr %B[result] \n\t"
525
526 // result.A-B += i.B x j
527 " mul %B[i], %[scale] \n\t"
528 " add %A[result], r0 \n\t"
529 " adc %B[result], r1 \n\t"
530
531 // cleanup r1
532 " clr __zero_reg__ \n\t"
533
534 : [result] "+r"(result)
535 : [i] "r"(i), [scale] "r"(scale)
536 : "r0", "r1");
537 return result;
538#endif
539#else
540#error "No implementation for scale16by8 available."
541#endif
542}
543
544
551LIB8STATIC uint16_t scale16(uint16_t i, fract16 scale) {
552#if SCALE16_C == 1
553 uint16_t result;
554#if FASTLED_SCALE8_FIXED == 1
555 result = ((uint32_t)(i) * (1 + (uint32_t)(scale))) / 65536;
556#else
557 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
558#endif
559 return result;
560#elif SCALE16_AVRASM == 1
561#if FASTLED_SCALE8_FIXED == 1
562 // implemented sort of like
563 // result = ((i * scale) + i ) / 65536
564 //
565 // why not like this, you may ask?
566 // result = (i * (scale+1)) / 65536
567 // the answer is that if scale is 65535, then scale+1
568 // will be zero, which is not what we want.
569 uint32_t result;
570 asm volatile(
571 // result.A-B = i.A x scale.A
572 " mul %A[i], %A[scale] \n\t"
573 // save results...
574 // basic idea:
575 //" mov %A[result], r0 \n\t"
576 //" mov %B[result], r1 \n\t"
577 // which can be written as...
578 " movw %A[result], r0 \n\t"
579 // Because we're going to add i.A-B to
580 // result.A-D, we DO need to keep both
581 // the r0 and r1 portions of the product
582 // UNlike in the 'unfixed scale8' version.
583 // So the movw here is needed.
584 : [result] "=r"(result)
585 : [i] "r"(i), [scale] "r"(scale)
586 : "r0", "r1");
587
588 asm volatile(
589 // result.C-D = i.B x scale.B
590 " mul %B[i], %B[scale] \n\t"
591 //" mov %C[result], r0 \n\t"
592 //" mov %D[result], r1 \n\t"
593 " movw %C[result], r0 \n\t"
594 : [result] "+r"(result)
595 : [i] "r"(i), [scale] "r"(scale)
596 : "r0", "r1");
597
598 const uint8_t zero = 0;
599 asm volatile(
600 // result.B-D += i.B x scale.A
601 " mul %B[i], %A[scale] \n\t"
602
603 " add %B[result], r0 \n\t"
604 " adc %C[result], r1 \n\t"
605 " adc %D[result], %[zero] \n\t"
606
607 // result.B-D += i.A x scale.B
608 " mul %A[i], %B[scale] \n\t"
609
610 " add %B[result], r0 \n\t"
611 " adc %C[result], r1 \n\t"
612 " adc %D[result], %[zero] \n\t"
613
614 // cleanup r1
615 " clr r1 \n\t"
616
617 : [result] "+r"(result)
618 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
619 : "r0", "r1");
620
621 asm volatile(
622 // result.A-D += i.A-B
623 " add %A[result], %A[i] \n\t"
624 " adc %B[result], %B[i] \n\t"
625 " adc %C[result], %[zero] \n\t"
626 " adc %D[result], %[zero] \n\t"
627 : [result] "+r"(result)
628 : [i] "r"(i), [zero] "r"(zero));
629
630 result = result >> 16;
631 return result;
632#else
633 uint32_t result;
634 asm volatile(
635 // result.A-B = i.A x scale.A
636 " mul %A[i], %A[scale] \n\t"
637 // save results...
638 // basic idea:
639 //" mov %A[result], r0 \n\t"
640 //" mov %B[result], r1 \n\t"
641 // which can be written as...
642 " movw %A[result], r0 \n\t"
643 // We actually don't need to do anything with r0,
644 // as result.A is never used again here, so we
645 // could just move the high byte, but movw is
646 // one clock cycle, just like mov, so might as
647 // well, in case we want to use this code for
648 // a generic 16x16 multiply somewhere.
649
650 : [result] "=r"(result)
651 : [i] "r"(i), [scale] "r"(scale)
652 : "r0", "r1");
653
654 asm volatile(
655 // result.C-D = i.B x scale.B
656 " mul %B[i], %B[scale] \n\t"
657 //" mov %C[result], r0 \n\t"
658 //" mov %D[result], r1 \n\t"
659 " movw %C[result], r0 \n\t"
660 : [result] "+r"(result)
661 : [i] "r"(i), [scale] "r"(scale)
662 : "r0", "r1");
663
664 const uint8_t zero = 0;
665 asm volatile(
666 // result.B-D += i.B x scale.A
667 " mul %B[i], %A[scale] \n\t"
668
669 " add %B[result], r0 \n\t"
670 " adc %C[result], r1 \n\t"
671 " adc %D[result], %[zero] \n\t"
672
673 // result.B-D += i.A x scale.B
674 " mul %A[i], %B[scale] \n\t"
675
676 " add %B[result], r0 \n\t"
677 " adc %C[result], r1 \n\t"
678 " adc %D[result], %[zero] \n\t"
679
680 // cleanup r1
681 " clr r1 \n\t"
682
683 : [result] "+r"(result)
684 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
685 : "r0", "r1");
686
687 result = result >> 16;
688 return result;
689#endif
690#else
691#error "No implementation for scale16 available."
692#endif
693}
694
695
711
714LIB8STATIC uint8_t dim8_raw(uint8_t x) { return scale8(x, x); }
715
718LIB8STATIC uint8_t dim8_video(uint8_t x) { return scale8_video(x, x); }
719
721LIB8STATIC uint8_t dim8_lin(uint8_t x) {
722 if (x & 0x80) {
723 x = scale8(x, x);
724 } else {
725 x += 1;
726 x /= 2;
727 }
728 return x;
729}
730
732LIB8STATIC uint8_t brighten8_raw(uint8_t x) {
733 uint8_t ix = 255 - x;
734 return 255 - scale8(ix, ix);
735}
736
738LIB8STATIC uint8_t brighten8_video(uint8_t x) {
739 uint8_t ix = 255 - x;
740 return 255 - scale8_video(ix, ix);
741}
742
744LIB8STATIC uint8_t brighten8_lin(uint8_t x) {
745 uint8_t ix = 255 - x;
746 if (ix & 0x80) {
747 ix = scale8(ix, ix);
748 } else {
749 ix += 1;
750 ix /= 2;
751 }
752 return 255 - ix;
753}
754
757
759
760#pragma GCC diagnostic pop
int x
Definition simple.h:92
uint16_t scale
Definition Noise.ino:74
#define FL_DISABLE_WARNING_RETURN_TYPE
#define FL_DISABLE_WARNING_IMPLICIT_INT_CONVERSION
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_UNUSED_PARAMETER
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:744
LIB8STATIC uint8_t dim8_lin(uint8_t x)
Linear version of the dimming function that halves for values < 128.
Definition scale8.h:721
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:718
LIB8STATIC uint8_t brighten8_video(uint8_t x)
Brighten a value (inverse of dim8_video())
Definition scale8.h:738
LIB8STATIC uint8_t dim8_raw(uint8_t x)
Adjust a scaling value for dimming.
Definition scale8.h:714
LIB8STATIC uint8_t brighten8_raw(uint8_t x)
Brighten a value (inverse of dim8_raw())
Definition scale8.h:732
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:227
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
Definition scale8.h:343
constexpr CRGB nscale8x3_constexpr(uint8_t r, uint8_t g, uint8_t b, fract8 scale)
Definition scale8.h:350
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:180
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:321
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:272
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:551
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:367
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:457
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:127
constexpr uint8_t scale8_constexpr(uint8_t i, fract8 scale)
Definition scale8.h:114
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:427
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:401
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:478
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:44
#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
#define FASTLED_NAMESPACE_BEGIN
Definition namespace.h:22
Implements the FastLED namespace macros.
u8 fract8
Fixed-Point Fractional Types.
Definition int.h:49
u16 fract16
ANSI: unsigned _Fract.
Definition int.h:59
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:86