1 /*
2 * Copyright (C) 2014 Brian Matherly (pez4brian@yahoo.com)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include <vector>
20 //#define GRADIENTLUT_PRINT
21 #ifdef GRADIENTLUT_PRINT
22 #include <cstdio>
23 #endif
24
25 class GradientLut
26 {
27 public:
28 struct Color {
29 uint8_t r;
30 uint8_t g;
31 uint8_t b;
32 };
33
34 void setDepth(size_t depth);
35 void fillRange(double startPos, const Color& startColor,
36 double endPos, const Color& endColor);
37 const Color& operator[](double pos) const;
38 void print() const;
39
40 private:
41 std::vector<Color> lut;
42 };
43
44 /**
45 * Set the size of the look-up table.
46 */
setDepth(size_t depth)47 void GradientLut::setDepth(size_t depth) {
48 lut.resize(depth);
49 }
50
51 /**
52 * Fill a part of the look-up table.
53 * The indexes in the table and their corresponding colors will be calculated
54 * proportionally to the depth of the LUT.
55 */
fillRange(double startPos,const GradientLut::Color & startColor,double endPos,const GradientLut::Color & endColor)56 void GradientLut::fillRange( double startPos, const GradientLut::Color& startColor,
57 double endPos, const GradientLut::Color& endColor ) {
58 unsigned int startIndex = (double)(lut.size() - 1) * startPos + 0.5;
59 unsigned int endIndex = (double)(lut.size() - 1) * endPos + 0.5;
60 unsigned int span = endIndex - startIndex;
61
62 if(span < 1) span = 1;
63
64 for(unsigned int i = 0; i <= span; i++) {
65 Color color;
66 double ratio = (double)i / (double)span;
67
68 color.r = startColor.r + ratio * ((double)endColor.r - (double)startColor.r);
69 color.g = startColor.g + ratio * ((double)endColor.g - (double)startColor.g);
70 color.b = startColor.b + ratio * ((double)endColor.b - (double)startColor.b);
71 lut[i + startIndex] = color;
72 }
73 }
74
75 /**
76 * Get a color value for a given position in the table.
77 * The index in the table will be calculated proportionally to the depth of the
78 * LUT.
79 */
operator [](double pos) const80 const GradientLut::Color& GradientLut::operator[](double pos) const {
81 unsigned int size = lut.size();
82 unsigned int index = (double)size * pos;
83 if(index >= size) {
84 index = size - 1;
85 }
86 return lut[index];
87 };
88
89 /**
90 * Debug print function.
91 */
print() const92 void GradientLut::print() const {
93 #ifdef GRADIENTLUT_PRINT
94 printf("LUT:\tIndex\tRed\tGreen\tBlue\n");
95 for(int i = 0; i < lut.size(); i++) {
96 const Color& color = lut[i];
97 printf("\t%3d\t%02x\t%02x\t%02x\n", i, color.r, color.g, color.b);
98 }
99 #endif
100 }
101