FastLED 3.6.0
Loading...
Searching...
No Matches
scale8.h
Go to the documentation of this file.
1#ifndef __INC_LIB8TION_SCALE_H
2#define __INC_LIB8TION_SCALE_H
3
7
10
20
21
30LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale)
31{
32#if SCALE8_C == 1
33#if (FASTLED_SCALE8_FIXED == 1)
34 return (((uint16_t)i) * (1+(uint16_t)(scale))) >> 8;
35#else
36 return ((uint16_t)i * (uint16_t)(scale) ) >> 8;
37#endif
38#elif SCALE8_AVRASM == 1
39#if defined(LIB8_ATTINY)
40#if (FASTLED_SCALE8_FIXED == 1)
41 uint8_t work=i;
42#else
43 uint8_t work=0;
44#endif
45 uint8_t cnt=0x80;
46 asm volatile(
47#if (FASTLED_SCALE8_FIXED == 1)
48 " inc %[scale] \n\t"
49 " breq DONE_%= \n\t"
50 " clr %[work] \n\t"
51#endif
52 "LOOP_%=: \n\t"
53 /*" sbrc %[scale], 0 \n\t"
54 " add %[work], %[i] \n\t"
55 " ror %[work] \n\t"
56 " lsr %[scale] \n\t"
57 " clc \n\t"*/
58 " sbrc %[scale], 0 \n\t"
59 " add %[work], %[i] \n\t"
60 " ror %[work] \n\t"
61 " lsr %[scale] \n\t"
62 " lsr %[cnt] \n\t"
63 "brcc LOOP_%= \n\t"
64 "DONE_%=: \n\t"
65 : [work] "+r" (work), [cnt] "+r" (cnt)
66 : [scale] "r" (scale), [i] "r" (i)
67 :
68 );
69 return work;
70#else
71 asm volatile(
72#if (FASTLED_SCALE8_FIXED==1)
73 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
74 "mul %0, %1 \n\t"
75 // Add i to r0, possibly setting the carry flag
76 "add r0, %0 \n\t"
77 // load the immediate 0 into i (note, this does _not_ touch any flags)
78 "ldi %0, 0x00 \n\t"
79 // walk and chew gum at the same time
80 "adc %0, r1 \n\t"
81#else
82 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
83 "mul %0, %1 \n\t"
84 /* Move the high 8-bits of the product (r1) back to i */
85 "mov %0, r1 \n\t"
86 /* Restore r1 to "0"; it's expected to always be that */
87#endif
88 "clr __zero_reg__ \n\t"
89
90 : "+a" (i) /* writes to i */
91 : "a" (scale) /* uses scale */
92 : "r0", "r1" /* clobbers r0, r1 */
93 );
94 /* Return the result */
95 return i;
96#endif
97#else
98#error "No implementation for scale8 available."
99#endif
100}
101
102
113{
114#if SCALE8_C == 1 || defined(LIB8_ATTINY)
115 uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
116 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
117 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale;
118 return j;
119#elif SCALE8_AVRASM == 1
120 uint8_t j=0;
121 asm volatile(
122 " tst %[i]\n\t"
123 " breq L_%=\n\t"
124 " mul %[i], %[scale]\n\t"
125 " mov %[j], r1\n\t"
126 " clr __zero_reg__\n\t"
127 " cpse %[scale], r1\n\t"
128 " subi %[j], 0xFF\n\t"
129 "L_%=: \n\t"
130 : [j] "+a" (j)
131 : [i] "a" (i), [scale] "a" (scale)
132 : "r0", "r1"
133 );
134 return j;
135 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
136 // asm volatile(
137 // " tst %0 \n"
138 // " breq L_%= \n"
139 // " mul %0, %1 \n"
140 // " mov %0, r1 \n"
141 // " add %0, %2 \n"
142 // " clr __zero_reg__ \n"
143 // "L_%=: \n"
144 // : "+a" (i)
145 // : "a" (scale), "a" (nonzeroscale)
146 // : "r0", "r1");
147 // // Return the result
148 // return i;
149#else
150#error "No implementation for scale8_video available."
151#endif
152}
153
154
159
160
170{
171#if SCALE8_C == 1
172#if (FASTLED_SCALE8_FIXED == 1)
173 return (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
174#else
175 return ((int)i * (int)(scale) ) >> 8;
176#endif
177#elif SCALE8_AVRASM == 1
178 asm volatile(
179#if (FASTLED_SCALE8_FIXED==1)
180 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
181 "mul %0, %1 \n\t"
182 // Add i to r0, possibly setting the carry flag
183 "add r0, %0 \n\t"
184 // load the immediate 0 into i (note, this does _not_ touch any flags)
185 "ldi %0, 0x00 \n\t"
186 // walk and chew gum at the same time
187 "adc %0, r1 \n\t"
188#else
189 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
190 "mul %0, %1 \n\t"
191 /* Move the high 8-bits of the product (r1) back to i */
192 "mov %0, r1 \n\t"
193#endif
194 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
195 /* "clr __zero_reg__ \n\t" */
196 : "+a" (i) /* writes to i */
197 : "a" (scale) /* uses scale */
198 : "r0", "r1" /* clobbers r0, r1 */
199 );
200 // Return the result
201 return i;
202#else
203#error "No implementation for scale8_LEAVING_R1_DIRTY available."
204#endif
205}
206
217{
218#if SCALE8_C == 1
219#if (FASTLED_SCALE8_FIXED == 1)
220 i = (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
221#else
222 i = ((int)i * (int)(scale) ) >> 8;
223#endif
224#elif SCALE8_AVRASM == 1
225 asm volatile(
226#if (FASTLED_SCALE8_FIXED==1)
227 // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
228 "mul %0, %1 \n\t"
229 // Add i to r0, possibly setting the carry flag
230 "add r0, %0 \n\t"
231 // load the immediate 0 into i (note, this does _not_ touch any flags)
232 "ldi %0, 0x00 \n\t"
233 // walk and chew gum at the same time
234 "adc %0, r1 \n\t"
235#else
236 /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
237 "mul %0, %1 \n\t"
238 /* Move the high 8-bits of the product (r1) back to i */
239 "mov %0, r1 \n\t"
240#endif
241 /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
242 /* "clr __zero_reg__ \n\t" */
243
244 : "+a" (i) /* writes to i */
245 : "a" (scale) /* uses scale */
246 : "r0", "r1" /* clobbers r0, r1 */
247 );
248#else
249#error "No implementation for nscale8_LEAVING_R1_DIRTY available."
250#endif
251}
252
253
263{
264#if SCALE8_C == 1 || defined(LIB8_ATTINY)
265 uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
266 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
267 // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale;
268 return j;
269#elif SCALE8_AVRASM == 1
270 uint8_t j=0;
271 asm volatile(
272 " tst %[i]\n\t"
273 " breq L_%=\n\t"
274 " mul %[i], %[scale]\n\t"
275 " mov %[j], r1\n\t"
276 " breq L_%=\n\t"
277 " subi %[j], 0xFF\n\t"
278 "L_%=: \n\t"
279 : [j] "+a" (j)
280 : [i] "a" (i), [scale] "a" (scale)
281 : "r0", "r1"
282 );
283 return j;
284 // uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
285 // asm volatile(
286 // " tst %0 \n"
287 // " breq L_%= \n"
288 // " mul %0, %1 \n"
289 // " mov %0, r1 \n"
290 // " add %0, %2 \n"
291 // " clr __zero_reg__ \n"
292 // "L_%=: \n"
293 // : "+a" (i)
294 // : "a" (scale), "a" (nonzeroscale)
295 // : "r0", "r1");
296 // // Return the result
297 // return i;
298#else
299#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
300#endif
301}
302
313{
314#if SCALE8_C == 1 || defined(LIB8_ATTINY)
315 i = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
316#elif SCALE8_AVRASM == 1
317 asm volatile(
318 " tst %[i]\n\t"
319 " breq L_%=\n\t"
320 " mul %[i], %[scale]\n\t"
321 " mov %[i], r1\n\t"
322 " breq L_%=\n\t"
323 " subi %[i], 0xFF\n\t"
324 "L_%=: \n\t"
325 : [i] "+a" (i)
326 : [scale] "a" (scale)
327 : "r0", "r1"
328 );
329#else
330#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
331#endif
332}
333
337{
338#if CLEANUP_R1_AVRASM == 1
339 // Restore r1 to "0"; it's expected to always be that
340 asm volatile( "clr __zero_reg__ \n\t" : : : "r1" );
341#endif
342}
343
345
346
357LIB8STATIC void nscale8x3( uint8_t& r, uint8_t& g, uint8_t& b, fract8 scale)
358{
359#if SCALE8_C == 1
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;
365#else
366 r = ((int)r * (int)(scale) ) >> 8;
367 g = ((int)g * (int)(scale) ) >> 8;
368 b = ((int)b * (int)(scale) ) >> 8;
369#endif
370#elif SCALE8_AVRASM == 1
371 r = scale8_LEAVING_R1_DIRTY(r, scale);
372 g = scale8_LEAVING_R1_DIRTY(g, scale);
373 b = scale8_LEAVING_R1_DIRTY(b, scale);
374 cleanup_R1();
375#else
376#error "No implementation for nscale8x3 available."
377#endif
378}
379
392LIB8STATIC void nscale8x3_video( uint8_t& r, uint8_t& g, uint8_t& b, fract8 scale)
393{
394#if SCALE8_C == 1
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
403 cleanup_R1();
404#else
405#error "No implementation for nscale8x3 available."
406#endif
407}
408
418LIB8STATIC void nscale8x2( uint8_t& i, uint8_t& j, fract8 scale)
419{
420#if SCALE8_C == 1
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;
425#else
426 i = ((uint16_t)i * (uint16_t)(scale) ) >> 8;
427 j = ((uint16_t)j * (uint16_t)(scale) ) >> 8;
428#endif
429#elif SCALE8_AVRASM == 1
430 i = scale8_LEAVING_R1_DIRTY(i, scale);
431 j = scale8_LEAVING_R1_DIRTY(j, scale);
432 cleanup_R1();
433#else
434#error "No implementation for nscale8x2 available."
435#endif
436}
437
449LIB8STATIC void nscale8x2_video( uint8_t& i, uint8_t& j, fract8 scale)
450{
451#if SCALE8_C == 1
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
458 cleanup_R1();
459#else
460#error "No implementation for nscale8x2 available."
461#endif
462}
463
464
472LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8( uint16_t i, fract8 scale )
473{
474#if SCALE16BY8_C == 1
475 uint16_t result;
476#if FASTLED_SCALE8_FIXED == 1
477 result = (i * (1+((uint16_t)scale))) >> 8;
478#else
479 result = (i * scale) / 256;
480#endif
481 return result;
482#elif SCALE16BY8_AVRASM == 1
483#if FASTLED_SCALE8_FIXED == 1
484 uint16_t result = 0;
485 asm volatile(
486 // result.A = HighByte( (i.A x scale) + i.A )
487 " mul %A[i], %[scale] \n\t"
488 " add r0, %A[i] \n\t"
489 // " adc r1, [zero] \n\t"
490 // " mov %A[result], r1 \n\t"
491 " adc %A[result], r1 \n\t"
492
493 // result.A-B += i.B x scale
494 " mul %B[i], %[scale] \n\t"
495 " add %A[result], r0 \n\t"
496 " adc %B[result], r1 \n\t"
497
498 // cleanup r1
499 " clr __zero_reg__ \n\t"
500
501 // result.A-B += i.B
502 " add %A[result], %B[i] \n\t"
503 " adc %B[result], __zero_reg__ \n\t"
504
505 : [result] "+r" (result)
506 : [i] "r" (i), [scale] "r" (scale)
507 : "r0", "r1"
508 );
509 return result;
510#else
511 uint16_t result = 0;
512 asm volatile(
513 // result.A = HighByte(i.A x j )
514 " mul %A[i], %[scale] \n\t"
515 " mov %A[result], r1 \n\t"
516 //" clr %B[result] \n\t"
517
518 // result.A-B += i.B x j
519 " mul %B[i], %[scale] \n\t"
520 " add %A[result], r0 \n\t"
521 " adc %B[result], r1 \n\t"
522
523 // cleanup r1
524 " clr __zero_reg__ \n\t"
525
526 : [result] "+r" (result)
527 : [i] "r" (i), [scale] "r" (scale)
528 : "r0", "r1"
529 );
530 return result;
531#endif
532#else
533 #error "No implementation for scale16by8 available."
534#endif
535}
536
543LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale )
544{
545 #if SCALE16_C == 1
546 uint16_t result;
547#if FASTLED_SCALE8_FIXED == 1
548 result = ((uint32_t)(i) * (1+(uint32_t)(scale))) / 65536;
549#else
550 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
551#endif
552 return result;
553#elif SCALE16_AVRASM == 1
554#if FASTLED_SCALE8_FIXED == 1
555 // implemented sort of like
556 // result = ((i * scale) + i ) / 65536
557 //
558 // why not like this, you may ask?
559 // result = (i * (scale+1)) / 65536
560 // the answer is that if scale is 65535, then scale+1
561 // will be zero, which is not what we want.
562 uint32_t result;
563 asm volatile(
564 // result.A-B = i.A x scale.A
565 " mul %A[i], %A[scale] \n\t"
566 // save results...
567 // basic idea:
568 //" mov %A[result], r0 \n\t"
569 //" mov %B[result], r1 \n\t"
570 // which can be written as...
571 " movw %A[result], r0 \n\t"
572 // Because we're going to add i.A-B to
573 // result.A-D, we DO need to keep both
574 // the r0 and r1 portions of the product
575 // UNlike in the 'unfixed scale8' version.
576 // So the movw here is needed.
577 : [result] "=r" (result)
578 : [i] "r" (i),
579 [scale] "r" (scale)
580 : "r0", "r1"
581 );
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),
591 [scale] "r" (scale)
592 : "r0", "r1"
593);
594
595const uint8_t zero = 0;
596asm volatile(
597 // result.B-D += i.B x scale.A
598 " mul %B[i], %A[scale] \n\t"
599
600 " add %B[result], r0 \n\t"
601 " adc %C[result], r1 \n\t"
602 " adc %D[result], %[zero] \n\t"
603
604 // result.B-D += i.A x scale.B
605 " mul %A[i], %B[scale] \n\t"
606
607 " add %B[result], r0 \n\t"
608 " adc %C[result], r1 \n\t"
609 " adc %D[result], %[zero] \n\t"
610
611 // cleanup r1
612 " clr r1 \n\t"
613
614 : [result] "+r" (result)
615 : [i] "r" (i),
616 [scale] "r" (scale),
617 [zero] "r" (zero)
618 : "r0", "r1"
619 );
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),
629 [zero] "r" (zero)
630 );
631
632 result = result >> 16;
633 return result;
634#else
635 uint32_t result;
636 asm volatile(
637 // result.A-B = i.A x scale.A
638 " mul %A[i], %A[scale] \n\t"
639 // save results...
640 // basic idea:
641 //" mov %A[result], r0 \n\t"
642 //" mov %B[result], r1 \n\t"
643 // which can be written as...
644 " movw %A[result], r0 \n\t"
645 // We actually don't need to do anything with r0,
646 // as result.A is never used again here, so we
647 // could just move the high byte, but movw is
648 // one clock cycle, just like mov, so might as
649 // well, in case we want to use this code for
650 // a generic 16x16 multiply somewhere.
651
652 : [result] "=r" (result)
653 : [i] "r" (i),
654 [scale] "r" (scale)
655 : "r0", "r1"
656 );
657
658 asm volatile(
659 // result.C-D = i.B x scale.B
660 " mul %B[i], %B[scale] \n\t"
661 //" mov %C[result], r0 \n\t"
662 //" mov %D[result], r1 \n\t"
663 " movw %C[result], r0 \n\t"
664 : [result] "+r" (result)
665 : [i] "r" (i),
666 [scale] "r" (scale)
667 : "r0", "r1"
668 );
669
670 const uint8_t zero = 0;
671 asm volatile(
672 // result.B-D += i.B x scale.A
673 " mul %B[i], %A[scale] \n\t"
674
675 " add %B[result], r0 \n\t"
676 " adc %C[result], r1 \n\t"
677 " adc %D[result], %[zero] \n\t"
678
679 // result.B-D += i.A x scale.B
680 " mul %A[i], %B[scale] \n\t"
681
682 " add %B[result], r0 \n\t"
683 " adc %C[result], r1 \n\t"
684 " adc %D[result], %[zero] \n\t"
685
686 // cleanup r1
687 " clr r1 \n\t"
688
689 : [result] "+r" (result)
690 : [i] "r" (i),
691 [scale] "r" (scale),
692 [zero] "r" (zero)
693 : "r0", "r1"
694 );
695
696 result = result >> 16;
697 return result;
698#endif
699#else
700 #error "No implementation for scale16 available."
701#endif
702}
704
705
721
724LIB8STATIC uint8_t dim8_raw( uint8_t x)
725{
726 return scale8( x, x);
727}
728
731LIB8STATIC uint8_t dim8_video( uint8_t x)
732{
733 return scale8_video( x, x);
734}
735
737LIB8STATIC uint8_t dim8_lin( uint8_t x )
738{
739 if( x & 0x80 ) {
740 x = scale8( x, x);
741 } else {
742 x += 1;
743 x /= 2;
744 }
745 return x;
746}
747
749LIB8STATIC uint8_t brighten8_raw( uint8_t x)
750{
751 uint8_t ix = 255 - x;
752 return 255 - scale8( ix, ix);
753}
754
756LIB8STATIC uint8_t brighten8_video( uint8_t x)
757{
758 uint8_t ix = 255 - x;
759 return 255 - scale8_video( ix, ix);
760}
761
763LIB8STATIC uint8_t brighten8_lin( uint8_t x )
764{
765 uint8_t ix = 255 - x;
766 if( ix & 0x80 ) {
767 ix = scale8( ix, ix);
768 } else {
769 ix += 1;
770 ix /= 2;
771 }
772 return 255 - ix;
773}
774
777
778#endif
LIB8STATIC uint8_t brighten8_lin(uint8_t x)
Brighten a value (inverse of dim8_lin())
Definition scale8.h:763
LIB8STATIC uint8_t dim8_lin(uint8_t x)
Linear version of the dimming function that halves for values < 128.
Definition scale8.h:737
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:731
LIB8STATIC uint8_t brighten8_video(uint8_t x)
Brighten a value (inverse of dim8_video())
Definition scale8.h:756
LIB8STATIC uint8_t dim8_raw(uint8_t x)
Adjust a scaling value for dimming.
Definition scale8.h:724
LIB8STATIC uint8_t brighten8_raw(uint8_t x)
Brighten a value (inverse of dim8_raw())
Definition scale8.h:749
uint8_t fract8
ANSI: unsigned short _Fract.
Definition lib8tion.h:402
uint16_t fract16
ANSI: unsigned _Fract.
Definition lib8tion.h:412
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:216
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
Definition scale8.h:336
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:169
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:312
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:262
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:543
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:357
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:449
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:112
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:418
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:392
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:472
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:30
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8tion.h:21
#define LIB8STATIC_ALWAYS_INLINE
Define a LIB8TION member function as always static inline.
Definition lib8tion.h:23