Fix README.md
[gencolormap.git] / colormap.hpp
1 /*
2  * Copyright (C) 2015 Computer Graphics Group, University of Siegen
3  * Written by Martin Lambers <martin.lambers@uni-siegen.de>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23
24 #ifndef COLORMAP_HPP
25 #define COLORMAP_HPP
26
27 /* Generate color maps for scientific visualization purposes.
28  *
29  * Usage:
30  * - Decide which type of color map you need and how many colors the map should
31  *   contain.
32  * - Allocate memory for you color map (3 * unsigned char for each color entry).
33  * - Call the function that generates your color map.
34  *   The return value is always the number of colors that had to be clipped
35  *   to fit into sRGB; you want to keep that number low by adjusting parameters.
36  *
37  * All colors are represented as unsigned char sRGB triplets, with each value in
38  * [0,255].
39  */
40
41 namespace ColorMap {
42
43 /*
44  * Brewer-like color maps, as described in
45  * M. Wijffelaars, R. Vliegen, J.J. van Wijk, E.-J. van der Linden. Generating
46  * color palettes using intuitive parameters. In Computer Graphics Forum, vol. 27,
47  * no. 3, pp. 743-750, 2008.
48  */
49
50 // Create a sequential color map with n colors of the given hue in [0,2*PI].
51
52 const float BrewerSequentialDefaultHue = 4.18879020479f; // 240 deg
53 const float BrewerSequentialDefaultContrast = 0.88f;
54 float BrewerSequentialDefaultContrastForSmallN(int n); // only for discrete color maps, i.e. n <= 9
55 const float BrewerSequentialDefaultSaturation = 0.6f;
56 const float BrewerSequentialDefaultBrightness = 0.75f;
57 const float BrewerSequentialDefaultWarmth = 0.15f;
58
59 int BrewerSequential(int n, unsigned char* srgb_colormap,
60         float hue = BrewerSequentialDefaultHue,
61         float contrast = BrewerSequentialDefaultContrast,
62         float saturation = BrewerSequentialDefaultSaturation,
63         float brightness = BrewerSequentialDefaultBrightness,
64         float warmth = BrewerSequentialDefaultWarmth);
65
66 // Create a diverging color map with n colors. Half of them will have the given
67 // hue (in [0,2*PI]), the other half will have a hue that has the distance given
68 // by divergence (in [0,2*PI]) to that hue, and they will meet in the middle at
69 // a neutral color.
70
71 const float BrewerDivergingDefaultHue = 4.18879020479f; // 240 deg
72 const float BrewerDivergingDefaultDivergence = 4.18879020479f; // 240 deg = 2/3 * 2PI
73 const float BrewerDivergingDefaultContrast = 0.88f;
74 float BrewerDivergingDefaultContrastForSmallN(int n); // only for discrete color maps, i.e. n <= 9
75 const float BrewerDivergingDefaultSaturation = 0.6f;
76 const float BrewerDivergingDefaultBrightness = 0.75f;
77 const float BrewerDivergingDefaultWarmth = 0.15f;
78
79 int BrewerDiverging(int n, unsigned char* srgb_colormap,
80         float hue = BrewerDivergingDefaultHue,
81         float divergence = BrewerDivergingDefaultDivergence,
82         float contrast = BrewerDivergingDefaultContrast,
83         float saturation = BrewerDivergingDefaultSaturation,
84         float brightness = BrewerDivergingDefaultBrightness,
85         float warmth = BrewerDivergingDefaultWarmth);
86
87 // Create a qualitative color map with n colors. The colors will have the same
88 // saturation; lightness and hue will differ. The parameter hue sets the hue of
89 // the first color, and the parameter divergence defines the hue range starting
90 // from that hue that can be used for the colors.
91
92 const float BrewerQualitativeDefaultHue = 0.0f;
93 const float BrewerQualitativeDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
94 const float BrewerQualitativeDefaultContrast = 0.5f;
95 const float BrewerQualitativeDefaultSaturation = 0.5f;
96 const float BrewerQualitativeDefaultBrightness = 0.8f;
97
98 int BrewerQualitative(int n, unsigned char* colormap,
99         float hue = BrewerQualitativeDefaultHue,
100         float divergence = BrewerQualitativeDefaultDivergence,
101         float contrast = BrewerQualitativeDefaultContrast,
102         float saturation = BrewerQualitativeDefaultSaturation,
103         float brightness = BrewerQualitativeDefaultBrightness);
104
105 /*
106  * Perceptually linear (PL) color maps.
107  *
108  * These are computed in CIELUV/LCH to achieve perceptual linearity.
109  * One or two of lightness, saturation, and hue are changed while the other(s)
110  * stay constant.
111  *
112  * For example, color maps of constant lightness are useful for 3D surfaces
113  * because they do not interfere with additional shading.
114  */
115
116 /* Sequential perceptually linear maps */
117
118 // Varying lightness
119
120 const float PLSequentialLightnessDefaultSaturation = 0.45f;
121 const float PLSequentialLightnessDefaultHue = 0.349065850399f; // 20 deg
122
123 int PLSequentialLightness(int n, unsigned char* colormap,
124         float saturation = PLSequentialLightnessDefaultSaturation,
125         float hue = PLSequentialLightnessDefaultHue);
126
127 // Varying saturation
128
129 const float PLSequentialSaturationDefaultLightness = 0.5f;
130 const float PLSequentialSaturationDefaultSaturation = 0.45f;
131 const float PLSequentialSaturationDefaultHue = 0.349065850399f; // 20 deg
132
133 int PLSequentialSaturation(int n, unsigned char* colormap,
134         float lightness = PLSequentialSaturationDefaultLightness,
135         float saturation = PLSequentialSaturationDefaultSaturation,
136         float hue = PLSequentialSaturationDefaultHue);
137
138 // Varying hue (through all colors, rainbow-like)
139
140 const float PLSequentialRainbowDefaultHue = 0.0f;
141 const float PLSequentialRainbowDefaultRotations = -1.5f;
142 const float PLSequentialRainbowDefaultSaturation = 1.1f;
143
144 int PLSequentialRainbow(int n, unsigned char* colormap,
145         float hue = PLSequentialRainbowDefaultHue,
146         float rotations = PLSequentialRainbowDefaultRotations,
147         float saturation = PLSequentialRainbowDefaultSaturation);
148
149 // Varying hue (through physically plausible black body colors at increasing
150 // temperatures).
151 // The defaults are chosen so that we start at red and arrive at the D65 white
152 // point (6500 K), thus excluding the blue colors that occur at higher
153 // temperatures.
154 const float PLSequentialBlackBodyDefaultTemperature = 250.0f;
155 const float PLSequentialBlackBodyDefaultRange = 6250.0f;
156 const float PLSequentialBlackBodyDefaultSaturation = 2.3f;
157
158 int PLSequentialBlackBody(int n, unsigned char* colormap,
159         float temperature = PLSequentialBlackBodyDefaultTemperature,
160         float range = PLSequentialBlackBodyDefaultRange,
161         float saturation = PLSequentialBlackBodyDefaultSaturation);
162
163 /* Diverging perceptually linear maps */
164
165 // Varying lightness
166
167 const float PLDivergingLightnessDefaultLightness = 0.05f;
168 const float PLDivergingLightnessDefaultSaturation = 0.45f;
169 const float PLDivergingLightnessDefaultHue = 0.349065850399f; // 20 deg
170 const float PLDivergingLightnessDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
171
172 int PLDivergingLightness(int n, unsigned char* colormap,
173         float lightness = PLDivergingLightnessDefaultLightness,
174         float saturation = PLDivergingLightnessDefaultSaturation,
175         float hue = PLDivergingLightnessDefaultHue,
176         float divergence = PLDivergingLightnessDefaultDivergence);
177
178 // Varying saturation
179
180 const float PLDivergingSaturationDefaultLightness = 0.5f;
181 const float PLDivergingSaturationDefaultSaturation = 0.45f;
182 const float PLDivergingSaturationDefaultHue = 0.349065850399f; // 20 deg
183 const float PLDivergingSaturationDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
184
185 int PLDivergingSaturation(int n, unsigned char* colormap,
186         float lightness = PLDivergingSaturationDefaultLightness,
187         float saturation = PLDivergingSaturationDefaultSaturation,
188         float hue = PLDivergingSaturationDefaultHue,
189         float divergence = PLDivergingSaturationDefaultDivergence);
190
191 /* Qualitative perceptually linear maps */
192
193 const float PLQualitativeHueDefaultLightness = 0.55f;
194 const float PLQualitativeHueDefaultSaturation = 0.22f;
195 const float PLQualitativeHueDefaultHue = 0.0f;
196
197 int PLQualitativeHue(int n, unsigned char* colormap,
198         float lightness = PLQualitativeHueDefaultLightness,
199         float saturation = PLQualitativeHueDefaultSaturation,
200         float hue = PLQualitativeHueDefaultHue);
201
202 /*
203  * CubeHelix color maps, as described in
204  * Green, D. A., 2011, A colour scheme for the display of astronomical intensity
205  * images, Bulletin of the Astronomical Society of India, 39, 289.
206  */
207
208 // Create a CubeHelix colormap with n colors. The parameter hue (in [0,2*PI])
209 // sets the hue of the first color. The parameter rot sets the number of
210 // rotations. It can be negative for backwards rotation. The saturation parameter
211 // determines the saturation of the colors; higher values may lead to clipping
212 // of colors in the sRGB space. The gamma parameter sets optional gamma correction.
213 // The return value is the number of colors that had to be clipped.
214
215 const float CubeHelixDefaultHue = 0.523598775598f; // 1/12 * 2PI
216 const float CubeHelixDefaultRotations = -1.5f;
217 const float CubeHelixDefaultSaturation = 1.2f;
218 const float CubeHelixDefaultGamma = 1.0f;
219
220 int CubeHelix(int n, unsigned char* colormap,
221         float hue = CubeHelixDefaultHue,
222         float rotations = CubeHelixDefaultRotations,
223         float saturation = CubeHelixDefaultSaturation,
224         float gamma = CubeHelixDefaultGamma);
225
226 /*
227  * Moreland color maps, as described in
228  * K. Moreland, Diverging Color Maps for Scientific Visualization, Proc. Int.
229  * Symp. Visual Computing, December 2009, DOI 10.1007/978-3-642-10520-3_9.
230  */
231
232 // Create a Moreland colormap with n colors. Specify the two endpoints
233 // of the colormap as sRGB colors; all intermediate colors will be generated.
234
235 const unsigned char MorelandDefaultR0 = 180;
236 const unsigned char MorelandDefaultG0 = 4;
237 const unsigned char MorelandDefaultB0 = 38;
238 const unsigned char MorelandDefaultR1 = 59;
239 const unsigned char MorelandDefaultG1 = 76;
240 const unsigned char MorelandDefaultB1 = 192;
241
242 int Moreland(int n, unsigned char* colormap,
243         unsigned char sr0 = MorelandDefaultR0,
244         unsigned char sg0 = MorelandDefaultG0,
245         unsigned char sb0 = MorelandDefaultB0,
246         unsigned char sr1 = MorelandDefaultR1,
247         unsigned char sg1 = MorelandDefaultG1,
248         unsigned char sb1 = MorelandDefaultB1);
249
250 /*
251  * McNames color maps, as described in
252  * J. McNames, An Effective Color Scale for Simultaneous Color and Gray-Scale Publications,
253  * IEEE Signal Processing Magazine 23(1), January 2006, DOI 10.1109/MSP.2006.1593340.
254  *
255  * Note: Use CubeHelix instead! The McNames color maps are perceptually not linear in luminance!
256  */
257
258 // Create a McNames colormap with n colors. Specify the number of
259 // periods.
260
261 const float McNamesDefaultPeriods = 2.0f;
262
263 int McNames(int n, unsigned char* colormap,
264         float periods = McNamesDefaultPeriods);
265
266 }
267
268 #endif