annotate layer/ColourMapper.cpp @ 944:78c152e4db95

Merge from branch tonioni
author Chris Cannam
date Mon, 20 Apr 2015 09:12:17 +0100
parents 6e2a034f7117
children 2a85ab180d08
rev   line source
Chris@376 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@376 2
Chris@376 3 /*
Chris@376 4 Sonic Visualiser
Chris@376 5 An audio file viewer and annotation editor.
Chris@376 6 Centre for Digital Music, Queen Mary, University of London.
Chris@376 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@376 8
Chris@376 9 This program is free software; you can redistribute it and/or
Chris@376 10 modify it under the terms of the GNU General Public License as
Chris@376 11 published by the Free Software Foundation; either version 2 of the
Chris@376 12 License, or (at your option) any later version. See the file
Chris@376 13 COPYING included with this distribution for more information.
Chris@376 14 */
Chris@376 15
Chris@376 16 #include "ColourMapper.h"
Chris@376 17
Chris@376 18 #include <iostream>
Chris@376 19
Chris@376 20 #include <cmath>
Chris@376 21
Chris@682 22 #include "base/Debug.h"
Chris@682 23
Chris@902 24 ColourMapper::ColourMapper(int map, double min, double max) :
Chris@376 25 QObject(),
Chris@376 26 m_map(map),
Chris@376 27 m_min(min),
Chris@376 28 m_max(max)
Chris@376 29 {
Chris@376 30 if (m_min == m_max) {
Chris@682 31 cerr << "WARNING: ColourMapper: min == max (== " << m_min
Chris@682 32 << "), adjusting" << endl;
Chris@376 33 m_max = m_min + 1;
Chris@376 34 }
Chris@376 35 }
Chris@376 36
Chris@376 37 ColourMapper::~ColourMapper()
Chris@376 38 {
Chris@376 39 }
Chris@376 40
Chris@376 41 int
Chris@376 42 ColourMapper::getColourMapCount()
Chris@376 43 {
Chris@536 44 return 12;
Chris@376 45 }
Chris@376 46
Chris@376 47 QString
Chris@376 48 ColourMapper::getColourMapName(int n)
Chris@376 49 {
Chris@376 50 if (n >= getColourMapCount()) return tr("<unknown>");
Chris@376 51 StandardMap map = (StandardMap)n;
Chris@376 52
Chris@376 53 switch (map) {
Chris@376 54 case DefaultColours: return tr("Default");
Chris@376 55 case WhiteOnBlack: return tr("White on Black");
Chris@376 56 case BlackOnWhite: return tr("Black on White");
Chris@376 57 case RedOnBlue: return tr("Red on Blue");
Chris@376 58 case YellowOnBlack: return tr("Yellow on Black");
Chris@376 59 case BlueOnBlack: return tr("Blue on Black");
Chris@376 60 case Sunset: return tr("Sunset");
Chris@376 61 case FruitSalad: return tr("Fruit Salad");
Chris@376 62 case Banded: return tr("Banded");
Chris@376 63 case Highlight: return tr("Highlight");
Chris@376 64 case Printer: return tr("Printer");
Chris@536 65 case HighGain: return tr("High Gain");
Chris@376 66 }
Chris@376 67
Chris@376 68 return tr("<unknown>");
Chris@376 69 }
Chris@376 70
Chris@376 71 QColor
Chris@902 72 ColourMapper::map(double value) const
Chris@376 73 {
Chris@902 74 double norm = (value - m_min) / (m_max - m_min);
Chris@902 75 if (norm < 0.0) norm = 0.0;
Chris@902 76 if (norm > 1.0) norm = 1.0;
Chris@376 77
Chris@902 78 double h = 0.0, s = 0.0, v = 0.0, r = 0.0, g = 0.0, b = 0.0;
Chris@376 79 bool hsv = true;
Chris@376 80
Chris@911 81 double blue = 0.6666, pieslice = 0.3333;
Chris@376 82
Chris@376 83 if (m_map >= getColourMapCount()) return Qt::black;
Chris@376 84 StandardMap map = (StandardMap)m_map;
Chris@376 85
Chris@376 86 switch (map) {
Chris@376 87
Chris@376 88 case DefaultColours:
Chris@902 89 h = blue - norm * 2.0 * pieslice;
Chris@902 90 s = 0.5f + norm/2.0;
Chris@376 91 v = norm;
Chris@376 92 break;
Chris@376 93
Chris@376 94 case WhiteOnBlack:
Chris@376 95 r = g = b = norm;
Chris@376 96 hsv = false;
Chris@376 97 break;
Chris@376 98
Chris@376 99 case BlackOnWhite:
Chris@902 100 r = g = b = 1.0 - norm;
Chris@376 101 hsv = false;
Chris@376 102 break;
Chris@376 103
Chris@376 104 case RedOnBlue:
Chris@902 105 h = blue - pieslice/4.0 + norm * (pieslice + pieslice/4.0);
Chris@902 106 s = 1.0;
Chris@376 107 v = norm;
Chris@376 108 break;
Chris@376 109
Chris@376 110 case YellowOnBlack:
Chris@902 111 h = 0.15;
Chris@902 112 s = 1.0;
Chris@376 113 v = norm;
Chris@376 114 break;
Chris@376 115
Chris@376 116 case BlueOnBlack:
Chris@376 117 h = blue;
Chris@902 118 s = 1.0;
Chris@902 119 v = norm * 2.0;
Chris@902 120 if (v > 1.0) {
Chris@902 121 v = 1.0;
Chris@904 122 s = 1.0 - (sqrt(norm) - 0.707) * 3.413;
Chris@902 123 if (s < 0.0) s = 0.0;
Chris@902 124 if (s > 1.0) s = 1.0;
Chris@376 125 }
Chris@376 126 break;
Chris@376 127
Chris@376 128 case Sunset:
Chris@902 129 r = (norm - 0.24) * 2.38;
Chris@902 130 if (r > 1.0) r = 1.0;
Chris@902 131 if (r < 0.0) r = 0.0;
Chris@902 132 g = (norm - 0.64) * 2.777;
Chris@902 133 if (g > 1.0) g = 1.0;
Chris@902 134 if (g < 0.0) g = 0.0;
Chris@376 135 b = (3.6f * norm);
Chris@902 136 if (norm > 0.277) b = 2.0 - b;
Chris@902 137 if (b > 1.0) b = 1.0;
Chris@902 138 if (b < 0.0) b = 0.0;
Chris@376 139 hsv = false;
Chris@376 140 break;
Chris@376 141
Chris@376 142 case FruitSalad:
Chris@902 143 h = blue + (pieslice/6.0) - norm;
Chris@902 144 if (h < 0.0) h += 1.0;
Chris@902 145 s = 1.0;
Chris@902 146 v = 1.0;
Chris@376 147 break;
Chris@376 148
Chris@376 149 case Banded:
Chris@376 150 if (norm < 0.125) return Qt::darkGreen;
Chris@376 151 else if (norm < 0.25) return Qt::green;
Chris@376 152 else if (norm < 0.375) return Qt::darkBlue;
Chris@376 153 else if (norm < 0.5) return Qt::blue;
Chris@376 154 else if (norm < 0.625) return Qt::darkYellow;
Chris@376 155 else if (norm < 0.75) return Qt::yellow;
Chris@376 156 else if (norm < 0.875) return Qt::darkRed;
Chris@376 157 else return Qt::red;
Chris@376 158 break;
Chris@376 159
Chris@376 160 case Highlight:
Chris@376 161 if (norm > 0.99) return Qt::white;
Chris@376 162 else return Qt::darkBlue;
Chris@376 163
Chris@376 164 case Printer:
Chris@376 165 if (norm > 0.8) {
Chris@902 166 r = 1.0;
Chris@376 167 } else if (norm > 0.7) {
Chris@902 168 r = 0.9;
Chris@376 169 } else if (norm > 0.6) {
Chris@902 170 r = 0.8;
Chris@376 171 } else if (norm > 0.5) {
Chris@902 172 r = 0.7;
Chris@376 173 } else if (norm > 0.4) {
Chris@902 174 r = 0.6;
Chris@376 175 } else if (norm > 0.3) {
Chris@902 176 r = 0.5;
Chris@376 177 } else if (norm > 0.2) {
Chris@902 178 r = 0.4;
Chris@376 179 } else {
Chris@902 180 r = 0.0;
Chris@376 181 }
Chris@902 182 r = g = b = 1.0 - r;
Chris@376 183 hsv = false;
Chris@376 184 break;
Chris@536 185
Chris@536 186 case HighGain:
Chris@902 187 if (norm <= 1.0 / 256.0) {
Chris@902 188 norm = 0.0;
Chris@536 189 } else {
Chris@904 190 norm = 0.1f + (pow(((norm - 0.5) * 2.0), 3.0) + 1.0) / 2.081;
Chris@536 191 }
Chris@536 192 // now as for Sunset
Chris@902 193 r = (norm - 0.24) * 2.38;
Chris@902 194 if (r > 1.0) r = 1.0;
Chris@902 195 if (r < 0.0) r = 0.0;
Chris@902 196 g = (norm - 0.64) * 2.777;
Chris@902 197 if (g > 1.0) g = 1.0;
Chris@902 198 if (g < 0.0) g = 0.0;
Chris@536 199 b = (3.6f * norm);
Chris@902 200 if (norm > 0.277) b = 2.0 - b;
Chris@902 201 if (b > 1.0) b = 1.0;
Chris@902 202 if (b < 0.0) b = 0.0;
Chris@536 203 hsv = false;
Chris@536 204 /*
Chris@902 205 if (r > 1.0) r = 1.0;
Chris@902 206 r = g = b = 1.0 - r;
Chris@536 207 hsv = false;
Chris@536 208 */
Chris@536 209 break;
Chris@376 210 }
Chris@376 211
Chris@376 212 if (hsv) {
Chris@376 213 return QColor::fromHsvF(h, s, v);
Chris@376 214 } else {
Chris@376 215 return QColor::fromRgbF(r, g, b);
Chris@376 216 }
Chris@376 217 }
Chris@376 218
Chris@376 219 QColor
Chris@376 220 ColourMapper::getContrastingColour() const
Chris@376 221 {
Chris@376 222 if (m_map >= getColourMapCount()) return Qt::white;
Chris@376 223 StandardMap map = (StandardMap)m_map;
Chris@376 224
Chris@376 225 switch (map) {
Chris@376 226
Chris@376 227 case DefaultColours:
Chris@376 228 return QColor(255, 150, 50);
Chris@376 229
Chris@376 230 case WhiteOnBlack:
Chris@376 231 return Qt::red;
Chris@376 232
Chris@376 233 case BlackOnWhite:
Chris@376 234 return Qt::darkGreen;
Chris@376 235
Chris@376 236 case RedOnBlue:
Chris@376 237 return Qt::green;
Chris@376 238
Chris@376 239 case YellowOnBlack:
Chris@376 240 return QColor::fromHsv(240, 255, 255);
Chris@376 241
Chris@376 242 case BlueOnBlack:
Chris@376 243 return Qt::red;
Chris@376 244
Chris@376 245 case Sunset:
Chris@376 246 return Qt::white;
Chris@376 247
Chris@376 248 case FruitSalad:
Chris@376 249 return Qt::white;
Chris@376 250
Chris@376 251 case Banded:
Chris@376 252 return Qt::cyan;
Chris@376 253
Chris@376 254 case Highlight:
Chris@376 255 return Qt::red;
Chris@376 256
Chris@376 257 case Printer:
Chris@376 258 return Qt::red;
Chris@536 259
Chris@536 260 case HighGain:
Chris@536 261 return Qt::red;
Chris@376 262 }
Chris@376 263
Chris@376 264 return Qt::white;
Chris@376 265 }
Chris@376 266
Chris@376 267 bool
Chris@376 268 ColourMapper::hasLightBackground() const
Chris@376 269 {
Chris@376 270 if (m_map >= getColourMapCount()) return false;
Chris@376 271 StandardMap map = (StandardMap)m_map;
Chris@376 272
Chris@376 273 switch (map) {
Chris@376 274
Chris@376 275 case BlackOnWhite:
Chris@376 276 case Printer:
Chris@536 277 case HighGain:
Chris@376 278 return true;
Chris@376 279
Chris@805 280 case DefaultColours:
Chris@805 281 case Sunset:
Chris@805 282 case WhiteOnBlack:
Chris@805 283 case RedOnBlue:
Chris@805 284 case YellowOnBlack:
Chris@805 285 case BlueOnBlack:
Chris@805 286 case FruitSalad:
Chris@805 287 case Banded:
Chris@805 288 case Highlight:
Chris@805 289
Chris@376 290 default:
Chris@376 291 return false;
Chris@376 292 }
Chris@376 293 }
Chris@376 294
Chris@376 295