spek-palette.cc (2529B)
1 #include <assert.h> 2 #include <math.h> 3 4 #include "spek-palette.h" 5 6 // Modified version of Dan Bruton's algorithm: 7 // http://www.physics.sfasu.edu/astro/color/spectra.html 8 static uint32_t spectrum(double level) 9 { 10 level *= 0.6625; 11 double r = 0.0, g = 0.0, b = 0.0; 12 if (level >= 0 && level < 0.15) { 13 r = (0.15 - level) / (0.15 + 0.075); 14 g = 0.0; 15 b = 1.0; 16 } else if (level >= 0.15 && level < 0.275) { 17 r = 0.0; 18 g = (level - 0.15) / (0.275 - 0.15); 19 b = 1.0; 20 } else if (level >= 0.275 && level < 0.325) { 21 r = 0.0; 22 g = 1.0; 23 b = (0.325 - level) / (0.325 - 0.275); 24 } else if (level >= 0.325 && level < 0.5) { 25 r = (level - 0.325) / (0.5 - 0.325); 26 g = 1.0; 27 b = 0.0; 28 } else if (level >= 0.5 && level < 0.6625) { 29 r = 1.0; 30 g = (0.6625 - level) / (0.6625 - 0.5f); 31 b = 0.0; 32 } 33 34 // Intensity correction. 35 double cf = 1.0; 36 if (level >= 0.0 && level < 0.1) { 37 cf = level / 0.1; 38 } 39 cf *= 255.0; 40 41 // Pack RGB values into a 32-bit uint. 42 uint32_t rr = (uint32_t) (r * cf + 0.5); 43 uint32_t gg = (uint32_t) (g * cf + 0.5); 44 uint32_t bb = (uint32_t) (b * cf + 0.5); 45 return (rr << 16) + (gg << 8) + bb; 46 } 47 48 // The default palette used by SoX and written by Rob Sykes. 49 static uint32_t sox(double level) 50 { 51 double r = 0.0; 52 if (level >= 0.13 && level < 0.73) { 53 r = sin((level - 0.13) / 0.60 * M_PI / 2.0); 54 } else if (level >= 0.73) { 55 r = 1.0; 56 } 57 58 double g = 0.0; 59 if (level >= 0.6 && level < 0.91) { 60 g = sin((level - 0.6) / 0.31 * M_PI / 2.0); 61 } else if (level >= 0.91) { 62 g = 1.0; 63 } 64 65 double b = 0.0; 66 if (level < 0.60) { 67 b = 0.5 * sin(level / 0.6 * M_PI); 68 } else if (level >= 0.78) { 69 b = (level - 0.78) / 0.22; 70 } 71 72 // Pack RGB values into a 32-bit uint. 73 uint32_t rr = (uint32_t) (r * 255.0 + 0.5); 74 uint32_t gg = (uint32_t) (g * 255.0 + 0.5); 75 uint32_t bb = (uint32_t) (b * 255.0 + 0.5); 76 return (rr << 16) + (gg << 8) + bb; 77 } 78 79 static uint32_t mono(double level) 80 { 81 uint32_t v = (uint32_t) (level * 255.0 + 0.5); 82 return (v << 16) + (v << 8) + v; 83 } 84 85 uint32_t spek_palette(enum palette palette, double level) { 86 switch (palette) { 87 case PALETTE_SPECTRUM: 88 return spectrum(level); 89 case PALETTE_SOX: 90 return sox(level); 91 case PALETTE_MONO: 92 return mono(level); 93 default: 94 assert(false); 95 return 0; 96 } 97 }