1#ifndef __INC_LIB8TION_SCALE_H
2#define __INC_LIB8TION_SCALE_H
33#if (FASTLED_SCALE8_FIXED == 1)
34 return (((uint16_t)i) * (1+(uint16_t)(scale))) >> 8;
36 return ((uint16_t)i * (uint16_t)(scale) ) >> 8;
38#elif SCALE8_AVRASM == 1
39#if defined(LIB8_ATTINY)
40#if (FASTLED_SCALE8_FIXED == 1)
47#if (FASTLED_SCALE8_FIXED == 1)
58 " sbrc %[scale], 0 \n\t"
59 " add %[work], %[i] \n\t"
65 : [work]
"+r" (work), [cnt]
"+r" (cnt)
66 : [scale]
"r" (scale), [i]
"r" (i)
72#if (FASTLED_SCALE8_FIXED==1)
88 "clr __zero_reg__ \n\t"
98#error "No implementation for scale8 available."
114#if SCALE8_C == 1 || defined(LIB8_ATTINY)
115 uint8_t j = (((int)i * (
int)scale) >> 8) + ((i&&scale)?1:0);
119#elif SCALE8_AVRASM == 1
124 " mul %[i], %[scale]\n\t"
126 " clr __zero_reg__\n\t"
127 " cpse %[scale], r1\n\t"
128 " subi %[j], 0xFF\n\t"
131 : [i]
"a" (i), [scale]
"a" (scale)
150#error "No implementation for scale8_video available."
172#if (FASTLED_SCALE8_FIXED == 1)
173 return (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
175 return ((
int)i * (
int)(scale) ) >> 8;
177#elif SCALE8_AVRASM == 1
179#if (FASTLED_SCALE8_FIXED==1)
203#error "No implementation for scale8_LEAVING_R1_DIRTY available."
219#if (FASTLED_SCALE8_FIXED == 1)
220 i = (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
222 i = ((int)i * (
int)(scale) ) >> 8;
224#elif SCALE8_AVRASM == 1
226#if (FASTLED_SCALE8_FIXED==1)
249#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);
269#elif SCALE8_AVRASM == 1
274 " mul %[i], %[scale]\n\t"
277 " subi %[j], 0xFF\n\t"
280 : [i]
"a" (i), [scale]
"a" (scale)
299#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
314#if SCALE8_C == 1 || defined(LIB8_ATTINY)
315 i = (((int)i * (
int)scale) >> 8) + ((i&&scale)?1:0);
316#elif SCALE8_AVRASM == 1
320 " mul %[i], %[scale]\n\t"
323 " subi %[i], 0xFF\n\t"
326 : [scale]
"a" (scale)
330#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
338#if CLEANUP_R1_AVRASM == 1
340 asm volatile(
"clr __zero_reg__ \n\t" : : :
"r1" );
360#if (FASTLED_SCALE8_FIXED == 1)
361 uint16_t scale_fixed = scale + 1;
362 r = (((uint16_t)r) * scale_fixed) >> 8;
363 g = (((uint16_t)g) * scale_fixed) >> 8;
364 b = (((uint16_t)b) * scale_fixed) >> 8;
366 r = ((int)r * (
int)(scale) ) >> 8;
367 g = ((int)g * (
int)(scale) ) >> 8;
368 b = ((int)b * (
int)(scale) ) >> 8;
370#elif SCALE8_AVRASM == 1
376#error "No implementation for nscale8x3 available."
395 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
396 r = (r == 0) ? 0 : (((int)r * (
int)(scale) ) >> 8) + nonzeroscale;
397 g = (g == 0) ? 0 : (((int)g * (
int)(scale) ) >> 8) + nonzeroscale;
398 b = (b == 0) ? 0 : (((int)b * (
int)(scale) ) >> 8) + nonzeroscale;
399#elif SCALE8_AVRASM == 1
405#error "No implementation for nscale8x3 available."
421#if FASTLED_SCALE8_FIXED == 1
422 uint16_t scale_fixed = scale + 1;
423 i = (((uint16_t)i) * scale_fixed ) >> 8;
424 j = (((uint16_t)j) * scale_fixed ) >> 8;
426 i = ((uint16_t)i * (uint16_t)(scale) ) >> 8;
427 j = ((uint16_t)j * (uint16_t)(scale) ) >> 8;
429#elif SCALE8_AVRASM == 1
434#error "No implementation for nscale8x2 available."
452 uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
453 i = (i == 0) ? 0 : (((int)i * (
int)(scale) ) >> 8) + nonzeroscale;
454 j = (j == 0) ? 0 : (((int)j * (
int)(scale) ) >> 8) + nonzeroscale;
455#elif SCALE8_AVRASM == 1
460#error "No implementation for nscale8x2 available."
476#if FASTLED_SCALE8_FIXED == 1
477 result = (i * (1+((uint16_t)scale))) >> 8;
479 result = (i * scale) / 256;
482#elif SCALE16BY8_AVRASM == 1
483#if FASTLED_SCALE8_FIXED == 1
487 " mul %A[i], %[scale] \n\t"
488 " add r0, %A[i] \n\t"
491 " adc %A[result], r1 \n\t"
494 " mul %B[i], %[scale] \n\t"
495 " add %A[result], r0 \n\t"
496 " adc %B[result], r1 \n\t"
499 " clr __zero_reg__ \n\t"
502 " add %A[result], %B[i] \n\t"
503 " adc %B[result], __zero_reg__ \n\t"
505 : [result]
"+r" (result)
506 : [i]
"r" (i), [scale]
"r" (scale)
514 " mul %A[i], %[scale] \n\t"
515 " mov %A[result], r1 \n\t"
519 " mul %B[i], %[scale] \n\t"
520 " add %A[result], r0 \n\t"
521 " adc %B[result], r1 \n\t"
524 " clr __zero_reg__ \n\t"
526 : [result]
"+r" (result)
527 : [i]
"r" (i), [scale]
"r" (scale)
533 #error "No implementation for scale16by8 available."
547#if FASTLED_SCALE8_FIXED == 1
548 result = ((uint32_t)(i) * (1+(uint32_t)(scale))) / 65536;
550 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
553#elif SCALE16_AVRASM == 1
554#if FASTLED_SCALE8_FIXED == 1
565 " mul %A[i], %A[scale] \n\t"
571 " movw %A[result], r0 \n\t"
577 : [result]
"=r" (result)
585 " mul %B[i], %B[scale] \n\t"
588 " movw %C[result], r0 \n\t"
589 : [result]
"+r" (result)
595const uint8_t zero = 0;
598 " mul %B[i], %A[scale] \n\t"
600 " add %B[result], r0 \n\t"
601 " adc %C[result], r1 \n\t"
602 " adc %D[result], %[zero] \n\t"
605 " mul %A[i], %B[scale] \n\t"
607 " add %B[result], r0 \n\t"
608 " adc %C[result], r1 \n\t"
609 " adc %D[result], %[zero] \n\t"
614 : [result]
"+r" (result)
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)
632 result = result >> 16;
638 " mul %A[i], %A[scale] \n\t"
644 " movw %A[result], r0 \n\t"
652 : [result]
"=r" (result)
660 " mul %B[i], %B[scale] \n\t"
663 " movw %C[result], r0 \n\t"
664 : [result]
"+r" (result)
670 const uint8_t zero = 0;
673 " mul %B[i], %A[scale] \n\t"
675 " add %B[result], r0 \n\t"
676 " adc %C[result], r1 \n\t"
677 " adc %D[result], %[zero] \n\t"
680 " mul %A[i], %B[scale] \n\t"
682 " add %B[result], r0 \n\t"
683 " adc %C[result], r1 \n\t"
684 " adc %D[result], %[zero] \n\t"
689 : [result]
"+r" (result)
696 result = result >> 16;
700 #error "No implementation for scale16 available."
751 uint8_t ix = 255 - x;
752 return 255 -
scale8( ix, ix);
758 uint8_t ix = 255 - x;
765 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 ...
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
#define LIB8STATIC_ALWAYS_INLINE
Define a LIB8TION member function as always static inline.