36#if (FASTLED_SCALE8_FIXED == 1)
37 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
39 return ((uint16_t)i * (uint16_t)(scale)) >> 8;
41#elif SCALE8_AVRASM == 1
42#if defined(LIB8_ATTINY)
43#if (FASTLED_SCALE8_FIXED == 1)
50#if (FASTLED_SCALE8_FIXED == 1)
61 " sbrc %[scale], 0 \n\t"
62 " add %[work], %[i] \n\t"
68 : [work]
"+r"(work), [cnt]
"+r"(cnt)
69 : [scale]
"r"(scale), [i]
"r"(i)
74#if (FASTLED_SCALE8_FIXED == 1)
90 "clr __zero_reg__ \n\t"
100#error "No implementation for scale8 available."
104constexpr uint8_t scale8_constexpr(uint8_t i,
fract8 scale) {
105 return (((uint16_t)i) * (1 + (uint16_t)(scale))) >> 8;
118#if SCALE8_C == 1 || defined(LIB8_ATTINY)
119 uint8_t j = (((int)i * (
int)scale) >> 8) + ((i && scale) ? 1 : 0);
124#elif SCALE8_AVRASM == 1
126 asm volatile(
" tst %[i]\n\t"
128 " mul %[i], %[scale]\n\t"
130 " clr __zero_reg__\n\t"
131 " cpse %[scale], r1\n\t"
132 " subi %[j], 0xFF\n\t"
135 : [i]
"r"(i), [scale]
"r"(scale)
153#error "No implementation for scale8_video available."
173#if (FASTLED_SCALE8_FIXED == 1)
174 return (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
176 return ((
int)i * (
int)(scale)) >> 8;
178#elif SCALE8_AVRASM == 1
180#if (FASTLED_SCALE8_FIXED == 1)
204#error "No implementation for scale8_LEAVING_R1_DIRTY available."
220#if (FASTLED_SCALE8_FIXED == 1)
221 i = (((uint16_t)i) * ((uint16_t)(scale) + 1)) >> 8;
223 i = ((int)i * (
int)(scale)) >> 8;
225#elif SCALE8_AVRASM == 1
227#if (FASTLED_SCALE8_FIXED == 1)
250#error "No implementation for nscale8_LEAVING_R1_DIRTY available."
264#if SCALE8_C == 1 || defined(LIB8_ATTINY)
265 uint8_t j = (((int)i * (
int)scale) >> 8) + ((i && scale) ? 1 : 0);
270#elif SCALE8_AVRASM == 1
272 asm volatile(
" tst %[i]\n\t"
274 " mul %[i], %[scale]\n\t"
277 " subi %[j], 0xFF\n\t"
280 : [i]
"r"(i), [scale]
"r"(scale)
298#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
313#if SCALE8_C == 1 || defined(LIB8_ATTINY)
314 i = (((int)i * (
int)scale) >> 8) + ((i && scale) ? 1 : 0);
315#elif SCALE8_AVRASM == 1
316 asm volatile(
" tst %[i]\n\t"
318 " mul %[i], %[scale]\n\t"
321 " subi %[i], 0xFF\n\t"
327#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
334#if CLEANUP_R1_AVRASM == 1
336 asm volatile(
"clr __zero_reg__ \n\t" : : :
"r1");
340constexpr CRGB nscale8x3_constexpr(uint8_t r, uint8_t g, uint8_t b,
fract8 scale) {
341 return CRGB(((
int)r * (
int)(scale)) >> 8, ((
int)g * (
int)(scale)) >> 8,
342 ((
int)b * (
int)(scale)) >> 8);
359#if (FASTLED_SCALE8_FIXED == 1)
360 uint16_t scale_fixed = scale + 1;
361 r = (((uint16_t)r) * scale_fixed) >> 8;
362 g = (((uint16_t)g) * scale_fixed) >> 8;
363 b = (((uint16_t)b) * scale_fixed) >> 8;
365 r = ((int)r * (
int)(scale)) >> 8;
366 g = ((int)g * (
int)(scale)) >> 8;
367 b = ((int)b * (
int)(scale)) >> 8;
369#elif SCALE8_AVRASM == 1
375#error "No implementation for nscale8x3 available."
394 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
395 r = (r == 0) ? 0 : (((int)r * (
int)(scale)) >> 8) + nonzeroscale;
396 g = (g == 0) ? 0 : (((int)g * (
int)(scale)) >> 8) + nonzeroscale;
397 b = (b == 0) ? 0 : (((int)b * (
int)(scale)) >> 8) + nonzeroscale;
398#elif SCALE8_AVRASM == 1
404#error "No implementation for nscale8x3 available."
419#if FASTLED_SCALE8_FIXED == 1
420 uint16_t scale_fixed = scale + 1;
421 i = (((uint16_t)i) * scale_fixed) >> 8;
422 j = (((uint16_t)j) * scale_fixed) >> 8;
424 i = ((uint16_t)i * (uint16_t)(scale)) >> 8;
425 j = ((uint16_t)j * (uint16_t)(scale)) >> 8;
427#elif SCALE8_AVRASM == 1
432#error "No implementation for nscale8x2 available."
449 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
450 i = (i == 0) ? 0 : (((int)i * (
int)(scale)) >> 8) + nonzeroscale;
451 j = (j == 0) ? 0 : (((int)j * (
int)(scale)) >> 8) + nonzeroscale;
452#elif SCALE8_AVRASM == 1
457#error "No implementation for nscale8x2 available."
475#if FASTLED_SCALE8_FIXED == 1
476 result = (i * (1 + ((uint16_t)scale))) >> 8;
478 result = (i * scale) / 256;
481#elif SCALE16BY8_AVRASM == 1
482#if FASTLED_SCALE8_FIXED == 1
486 " mul %A[i], %[scale] \n\t"
487 " add r0, %A[i] \n\t"
490 " adc %A[result], r1 \n\t"
493 " mul %B[i], %[scale] \n\t"
494 " add %A[result], r0 \n\t"
495 " adc %B[result], r1 \n\t"
498 " clr __zero_reg__ \n\t"
501 " add %A[result], %B[i] \n\t"
502 " adc %B[result], __zero_reg__ \n\t"
504 : [result]
"+r"(result)
505 : [i]
"r"(i), [scale]
"r"(scale)
512 " mul %A[i], %[scale] \n\t"
513 " mov %A[result], r1 \n\t"
517 " mul %B[i], %[scale] \n\t"
518 " add %A[result], r0 \n\t"
519 " adc %B[result], r1 \n\t"
522 " clr __zero_reg__ \n\t"
524 : [result]
"+r"(result)
525 : [i]
"r"(i), [scale]
"r"(scale)
530#error "No implementation for scale16by8 available."
543#if FASTLED_SCALE8_FIXED == 1
544 result = ((uint32_t)(i) * (1 + (uint32_t)(scale))) / 65536;
546 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
549#elif SCALE16_AVRASM == 1
550#if FASTLED_SCALE8_FIXED == 1
561 " mul %A[i], %A[scale] \n\t"
567 " movw %A[result], r0 \n\t"
573 : [result]
"=r"(result)
574 : [i]
"r"(i), [scale]
"r"(scale)
579 " mul %B[i], %B[scale] \n\t"
582 " movw %C[result], r0 \n\t"
583 : [result]
"+r"(result)
584 : [i]
"r"(i), [scale]
"r"(scale)
587 const uint8_t zero = 0;
590 " mul %B[i], %A[scale] \n\t"
592 " add %B[result], r0 \n\t"
593 " adc %C[result], r1 \n\t"
594 " adc %D[result], %[zero] \n\t"
597 " mul %A[i], %B[scale] \n\t"
599 " add %B[result], r0 \n\t"
600 " adc %C[result], r1 \n\t"
601 " adc %D[result], %[zero] \n\t"
606 : [result]
"+r"(result)
607 : [i]
"r"(i), [scale]
"r"(scale), [zero]
"r"(zero)
612 " add %A[result], %A[i] \n\t"
613 " adc %B[result], %B[i] \n\t"
614 " adc %C[result], %[zero] \n\t"
615 " adc %D[result], %[zero] \n\t"
616 : [result]
"+r"(result)
617 : [i]
"r"(i), [zero]
"r"(zero));
619 result = result >> 16;
625 " mul %A[i], %A[scale] \n\t"
631 " movw %A[result], r0 \n\t"
639 : [result]
"=r"(result)
640 : [i]
"r"(i), [scale]
"r"(scale)
645 " mul %B[i], %B[scale] \n\t"
648 " movw %C[result], r0 \n\t"
649 : [result]
"+r"(result)
650 : [i]
"r"(i), [scale]
"r"(scale)
653 const uint8_t zero = 0;
656 " mul %B[i], %A[scale] \n\t"
658 " add %B[result], r0 \n\t"
659 " adc %C[result], r1 \n\t"
660 " adc %D[result], %[zero] \n\t"
663 " mul %A[i], %B[scale] \n\t"
665 " add %B[result], r0 \n\t"
666 " adc %C[result], r1 \n\t"
667 " adc %D[result], %[zero] \n\t"
672 : [result]
"+r"(result)
673 : [i]
"r"(i), [scale]
"r"(scale), [zero]
"r"(zero)
676 result = result >> 16;
680#error "No implementation for scale16 available."
722 uint8_t ix = 255 - x;
723 return 255 -
scale8(ix, ix);
728 uint8_t ix = 255 - x;
734 uint8_t ix = 255 - x;
LIB8STATIC uint8_t brighten8_lin(uint8_t x)
Brighten a value (inverse of dim8_lin())
LIB8STATIC uint8_t dim8_lin(uint8_t x)
Linear version of the dimming function that halves for values < 128.
LIB8STATIC uint8_t dim8_video(uint8_t x)
Adjust a scaling value for dimming for video (value will never go below 1)
LIB8STATIC uint8_t brighten8_video(uint8_t x)
Brighten a value (inverse of dim8_video())
LIB8STATIC uint8_t dim8_raw(uint8_t x)
Adjust a scaling value for dimming.
LIB8STATIC uint8_t brighten8_raw(uint8_t x)
Brighten a value (inverse of dim8_raw())
uint8_t fract8
ANSI: unsigned short _Fract.
uint16_t fract16
ANSI: unsigned _Fract.
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.
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
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.
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.
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.
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...
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...
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...
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...
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...
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...
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...
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 ...
Representation of an RGB pixel (Red, Green, Blue)