FastLED 3.9.15
Loading...
Searching...
No Matches

◆ hsv2rgb_rainbow() [2/3]

void hsv2rgb_rainbow ( const CHSV & hsv,
CRGB & rgb )

Definition at line 268 of file hsv2rgb.cpp.hpp.

269{
270 // Yellow has a higher inherent brightness than
271 // any other color; 'pure' yellow is perceived to
272 // be 93% as bright as white. In order to make
273 // yellow appear the correct relative brightness,
274 // it has to be rendered brighter than all other
275 // colors.
276 // Level Y1 is a moderate boost, the default.
277 // Level Y2 is a strong boost.
278 const fl::u8 Y1 = 1;
279 const fl::u8 Y2 = 0;
280
281 // G2: Whether to divide all greens by two.
282 // Depends GREATLY on your particular LEDs
283 const fl::u8 G2 = 0;
284
285 // Gscale: what to scale green down by.
286 // Depends GREATLY on your particular LEDs
287 const fl::u8 Gscale = 0;
288
289
290 fl::u8 hue = hsv.hue;
291 fl::u8 sat = hsv.sat;
292 fl::u8 val = hsv.val;
293
294 fl::u8 offset = hue & 0x1F; // 0..31
295
296 // offset8 = offset * 8
297 fl::u8 offset8 = offset;
298 {
299#if defined(FL_IS_AVR)
300 // Left to its own devices, gcc turns "x <<= 3" into a loop
301 // It's much faster and smaller to just do three single-bit shifts
302 // So this business is to force that.
303 offset8 <<= 1;
304 asm volatile("");
305 offset8 <<= 1;
306 asm volatile("");
307 offset8 <<= 1;
308#else
309 // On ARM and other non-AVR platforms, we just shift 3.
310 offset8 <<= 3;
311#endif
312 }
313
314 fl::u8 third = scale8( offset8, (256 / 3)); // max = 85
315
316 fl::u8 r, g, b;
317
318 if( ! (hue & 0x80) ) {
319 // 0XX
320 if( ! (hue & 0x40) ) {
321 // 00X
322 //section 0-1
323 if( ! (hue & 0x20) ) {
324 // 000
325 //case 0: // R -> O
326 r = K255 - third;
327 g = third;
328 b = 0;
330 } else {
331 // 001
332 //case 1: // O -> Y
333 if( Y1 ) {
334 r = K171;
335 g = K85 + third ;
336 b = 0;
338 }
339 if( Y2 ) {
340 r = K170 + third;
341 //uint8_t twothirds = (third << 1);
342 fl::u8 twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
343 g = K85 + twothirds;
344 b = 0;
346 }
347 }
348 } else {
349 //01X
350 // section 2-3
351 if( ! (hue & 0x20) ) {
352 // 010
353 //case 2: // Y -> G
354 if( Y1 ) {
355 //uint8_t twothirds = (third << 1);
356 fl::u8 twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
357 r = K171 - twothirds;
358 g = K170 + third;
359 b = 0;
361 }
362 if( Y2 ) {
363 r = K255 - offset8;
364 g = K255;
365 b = 0;
367 }
368 } else {
369 // 011
370 // case 3: // G -> A
371 r = 0;
373 g = K255 - third;
374 b = third;
375 }
376 }
377 } else {
378 // section 4-7
379 // 1XX
380 if( ! (hue & 0x40) ) {
381 // 10X
382 if( ! ( hue & 0x20) ) {
383 // 100
384 //case 4: // A -> B
385 r = 0;
387 //uint8_t twothirds = (third << 1);
388 fl::u8 twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
389 g = K171 - twothirds; //K170?
390 b = K85 + twothirds;
391
392 } else {
393 // 101
394 //case 5: // B -> P
395 r = third;
396 g = 0;
398 b = K255 - third;
399
400 }
401 } else {
402 if( ! (hue & 0x20) ) {
403 // 110
404 //case 6: // P -- K
405 r = K85 + third;
406 g = 0;
408 b = K171 - third;
409
410 } else {
411 // 111
412 //case 7: // K -> R
413 r = K170 + third;
414 g = 0;
416 b = K85 - third;
417
418 }
419 }
420 }
421
422 // This is one of the good places to scale the green down,
423 // although the client can scale green down as well.
424 if( G2 ) g = g >> 1;
425 if( Gscale ) g = scale8_video_LEAVING_R1_DIRTY( g, Gscale);
426
427 // Scale down colors if we're desaturated at all
428 // and add the brightness_floor to r, g, and b.
429 if( sat != 255 ) {
430 if( sat == 0) {
431 r = 255; b = 255; g = 255;
432 } else {
433 fl::u8 desat = 255 - sat;
434 desat = scale8_video( desat, desat);
435
436 fl::u8 satscale = 255 - desat;
437 //satscale = sat; // uncomment to revert to pre-2021 saturation behavior
438
439 //nscale8x3_video( r, g, b, sat);
440#if (FASTLED_SCALE8_FIXED==1)
441 r = scale8_LEAVING_R1_DIRTY( r, satscale);
442 asm volatile(""); // Fixes jumping red pixel: https://github.com/FastLED/FastLED/pull/943
443 g = scale8_LEAVING_R1_DIRTY( g, satscale);
444 asm volatile("");
445 b = scale8_LEAVING_R1_DIRTY( b, satscale);
446 asm volatile("");
447 cleanup_R1();
448#else
449 if( r ) r = scale8( r, satscale) + 1;
450 if( g ) g = scale8( g, satscale) + 1;
451 if( b ) b = scale8( b, satscale) + 1;
452#endif
453 fl::u8 brightness_floor = desat;
454 r += brightness_floor;
455 g += brightness_floor;
456 b += brightness_floor;
457 }
458 }
459
460 // Now scale everything down if we're at value < 255.
461 if( val != 255 ) {
462
463 val = scale8_video_LEAVING_R1_DIRTY( val, val);
464 if( val == 0 ) {
465 r=0; g=0; b=0;
466 } else {
467 // nscale8x3_video( r, g, b, val);
468#if (FASTLED_SCALE8_FIXED==1)
469 r = scale8_LEAVING_R1_DIRTY( r, val);
470 asm volatile(""); // Fixes jumping red pixel: https://github.com/FastLED/FastLED/pull/943
471 g = scale8_LEAVING_R1_DIRTY( g, val);
472 asm volatile("");
473 b = scale8_LEAVING_R1_DIRTY( b, val);
474 asm volatile("");
475 cleanup_R1();
476#else
477 if( r ) r = scale8( r, val) + 1;
478 if( g ) g = scale8( g, val) + 1;
479 if( b ) b = scale8( b, val) + 1;
480#endif
481 }
482 }
483
484 // Here we have the old AVR "missing std X+n" problem again
485 // It turns out that fixing it winds up costing more than
486 // not fixing it.
487 // To paraphrase Dr Bronner, profile! profile! profile!
488 //asm volatile( "" : : : "r26", "r27" );
489 //asm volatile (" movw r30, r26 \n" : : : "r30", "r31");
490 rgb.r = r;
491 rgb.g = g;
492 rgb.b = b;
493}
uint8_t hue
Definition advanced.h:94
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
#define FORCE_REFERENCE(var)
Force a variable reference to avoid compiler over-optimization.
unsigned char u8
Definition stdint.h:131

References FORCE_REFERENCE, hue, and offset().

+ Here is the call graph for this function: