annotate layer/ColourMapper.cpp @ 541:e233627a923e

* spiff up thumbwheels
author Chris Cannam
date Mon, 03 Aug 2009 12:55:00 +0000
parents aca01b3af29f
children 1a0dfcbffaf1
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@376 22 ColourMapper::ColourMapper(int map, float min, float max) :
Chris@376 23 QObject(),
Chris@376 24 m_map(map),
Chris@376 25 m_min(min),
Chris@376 26 m_max(max)
Chris@376 27 {
Chris@376 28 if (m_min == m_max) {
Chris@376 29 std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
Chris@376 30 << "), adjusting" << std::endl;
Chris@376 31 m_max = m_min + 1;
Chris@376 32 }
Chris@376 33 }
Chris@376 34
Chris@376 35 ColourMapper::~ColourMapper()
Chris@376 36 {
Chris@376 37 }
Chris@376 38
Chris@376 39 int
Chris@376 40 ColourMapper::getColourMapCount()
Chris@376 41 {
Chris@536 42 return 12;
Chris@376 43 }
Chris@376 44
Chris@376 45 QString
Chris@376 46 ColourMapper::getColourMapName(int n)
Chris@376 47 {
Chris@376 48 if (n >= getColourMapCount()) return tr("<unknown>");
Chris@376 49 StandardMap map = (StandardMap)n;
Chris@376 50
Chris@376 51 switch (map) {
Chris@376 52 case DefaultColours: return tr("Default");
Chris@376 53 case WhiteOnBlack: return tr("White on Black");
Chris@376 54 case BlackOnWhite: return tr("Black on White");
Chris@376 55 case RedOnBlue: return tr("Red on Blue");
Chris@376 56 case YellowOnBlack: return tr("Yellow on Black");
Chris@376 57 case BlueOnBlack: return tr("Blue on Black");
Chris@376 58 case Sunset: return tr("Sunset");
Chris@376 59 case FruitSalad: return tr("Fruit Salad");
Chris@376 60 case Banded: return tr("Banded");
Chris@376 61 case Highlight: return tr("Highlight");
Chris@376 62 case Printer: return tr("Printer");
Chris@536 63 case HighGain: return tr("High Gain");
Chris@376 64 }
Chris@376 65
Chris@376 66 return tr("<unknown>");
Chris@376 67 }
Chris@376 68
Chris@376 69 QColor
Chris@376 70 ColourMapper::map(float value) const
Chris@376 71 {
Chris@376 72 float norm = (value - m_min) / (m_max - m_min);
Chris@376 73 if (norm < 0.f) norm = 0.f;
Chris@376 74 if (norm > 1.f) norm = 1.f;
Chris@376 75
Chris@376 76 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
Chris@376 77 bool hsv = true;
Chris@376 78
Chris@376 79 // float red = 0.f, green = 0.3333f;
Chris@376 80 float blue = 0.6666f, pieslice = 0.3333f;
Chris@376 81
Chris@376 82 if (m_map >= getColourMapCount()) return Qt::black;
Chris@376 83 StandardMap map = (StandardMap)m_map;
Chris@376 84
Chris@376 85 switch (map) {
Chris@376 86
Chris@376 87 case DefaultColours:
Chris@376 88 h = blue - norm * 2.f * pieslice;
Chris@376 89 s = 0.5f + norm/2.f;
Chris@376 90 v = norm;
Chris@376 91 break;
Chris@376 92
Chris@376 93 case WhiteOnBlack:
Chris@376 94 r = g = b = norm;
Chris@376 95 hsv = false;
Chris@376 96 break;
Chris@376 97
Chris@376 98 case BlackOnWhite:
Chris@376 99 r = g = b = 1.f - norm;
Chris@376 100 hsv = false;
Chris@376 101 break;
Chris@376 102
Chris@376 103 case RedOnBlue:
Chris@376 104 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
Chris@376 105 s = 1.f;
Chris@376 106 v = norm;
Chris@376 107 break;
Chris@376 108
Chris@376 109 case YellowOnBlack:
Chris@376 110 h = 0.15f;
Chris@376 111 s = 1.f;
Chris@376 112 v = norm;
Chris@376 113 break;
Chris@376 114
Chris@376 115 case BlueOnBlack:
Chris@376 116 h = blue;
Chris@376 117 s = 1.f;
Chris@376 118 v = norm * 2.f;
Chris@376 119 if (v > 1.f) {
Chris@376 120 v = 1.f;
Chris@376 121 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
Chris@376 122 if (s < 0.f) s = 0.f;
Chris@376 123 if (s > 1.f) s = 1.f;
Chris@376 124 }
Chris@376 125 break;
Chris@376 126
Chris@376 127 case Sunset:
Chris@376 128 r = (norm - 0.24f) * 2.38f;
Chris@376 129 if (r > 1.f) r = 1.f;
Chris@376 130 if (r < 0.f) r = 0.f;
Chris@376 131 g = (norm - 0.64f) * 2.777f;
Chris@376 132 if (g > 1.f) g = 1.f;
Chris@376 133 if (g < 0.f) g = 0.f;
Chris@376 134 b = (3.6f * norm);
Chris@376 135 if (norm > 0.277f) b = 2.f - b;
Chris@376 136 if (b > 1.f) b = 1.f;
Chris@376 137 if (b < 0.f) b = 0.f;
Chris@376 138 hsv = false;
Chris@376 139 break;
Chris@376 140
Chris@376 141 case FruitSalad:
Chris@376 142 h = blue + (pieslice/6.f) - norm;
Chris@376 143 if (h < 0.f) h += 1.f;
Chris@376 144 s = 1.f;
Chris@376 145 v = 1.f;
Chris@376 146 break;
Chris@376 147
Chris@376 148 case Banded:
Chris@376 149 if (norm < 0.125) return Qt::darkGreen;
Chris@376 150 else if (norm < 0.25) return Qt::green;
Chris@376 151 else if (norm < 0.375) return Qt::darkBlue;
Chris@376 152 else if (norm < 0.5) return Qt::blue;
Chris@376 153 else if (norm < 0.625) return Qt::darkYellow;
Chris@376 154 else if (norm < 0.75) return Qt::yellow;
Chris@376 155 else if (norm < 0.875) return Qt::darkRed;
Chris@376 156 else return Qt::red;
Chris@376 157 break;
Chris@376 158
Chris@376 159 case Highlight:
Chris@376 160 if (norm > 0.99) return Qt::white;
Chris@376 161 else return Qt::darkBlue;
Chris@376 162
Chris@376 163 case Printer:
Chris@376 164 if (norm > 0.8) {
Chris@376 165 r = 1.f;
Chris@376 166 } else if (norm > 0.7) {
Chris@376 167 r = 0.9f;
Chris@376 168 } else if (norm > 0.6) {
Chris@376 169 r = 0.8f;
Chris@376 170 } else if (norm > 0.5) {
Chris@376 171 r = 0.7f;
Chris@376 172 } else if (norm > 0.4) {
Chris@376 173 r = 0.6f;
Chris@376 174 } else if (norm > 0.3) {
Chris@376 175 r = 0.5f;
Chris@376 176 } else if (norm > 0.2) {
Chris@376 177 r = 0.4f;
Chris@376 178 } else {
Chris@376 179 r = 0.f;
Chris@376 180 }
Chris@376 181 r = g = b = 1.f - r;
Chris@376 182 hsv = false;
Chris@376 183 break;
Chris@536 184
Chris@536 185 case HighGain:
Chris@536 186 if (norm <= 1.f / 256.f) {
Chris@536 187 norm = 0.f;
Chris@536 188 } else {
Chris@536 189 norm = 0.1f + (powf(((norm - 0.5f) * 2.f), 3.f) + 1.f) / 2.081f;
Chris@536 190 }
Chris@536 191 // now as for Sunset
Chris@536 192 r = (norm - 0.24f) * 2.38f;
Chris@536 193 if (r > 1.f) r = 1.f;
Chris@536 194 if (r < 0.f) r = 0.f;
Chris@536 195 g = (norm - 0.64f) * 2.777f;
Chris@536 196 if (g > 1.f) g = 1.f;
Chris@536 197 if (g < 0.f) g = 0.f;
Chris@536 198 b = (3.6f * norm);
Chris@536 199 if (norm > 0.277f) b = 2.f - b;
Chris@536 200 if (b > 1.f) b = 1.f;
Chris@536 201 if (b < 0.f) b = 0.f;
Chris@536 202 hsv = false;
Chris@536 203 /*
Chris@536 204 if (r > 1.f) r = 1.f;
Chris@536 205 r = g = b = 1.f - r;
Chris@536 206 hsv = false;
Chris@536 207 */
Chris@536 208 break;
Chris@376 209 }
Chris@376 210
Chris@376 211 if (hsv) {
Chris@376 212 return QColor::fromHsvF(h, s, v);
Chris@376 213 } else {
Chris@376 214 return QColor::fromRgbF(r, g, b);
Chris@376 215 }
Chris@376 216 }
Chris@376 217
Chris@376 218 QColor
Chris@376 219 ColourMapper::getContrastingColour() const
Chris@376 220 {
Chris@376 221 if (m_map >= getColourMapCount()) return Qt::white;
Chris@376 222 StandardMap map = (StandardMap)m_map;
Chris@376 223
Chris@376 224 switch (map) {
Chris@376 225
Chris@376 226 case DefaultColours:
Chris@376 227 return QColor(255, 150, 50);
Chris@376 228
Chris@376 229 case WhiteOnBlack:
Chris@376 230 return Qt::red;
Chris@376 231
Chris@376 232 case BlackOnWhite:
Chris@376 233 return Qt::darkGreen;
Chris@376 234
Chris@376 235 case RedOnBlue:
Chris@376 236 return Qt::green;
Chris@376 237
Chris@376 238 case YellowOnBlack:
Chris@376 239 return QColor::fromHsv(240, 255, 255);
Chris@376 240
Chris@376 241 case BlueOnBlack:
Chris@376 242 return Qt::red;
Chris@376 243
Chris@376 244 case Sunset:
Chris@376 245 return Qt::white;
Chris@376 246
Chris@376 247 case FruitSalad:
Chris@376 248 return Qt::white;
Chris@376 249
Chris@376 250 case Banded:
Chris@376 251 return Qt::cyan;
Chris@376 252
Chris@376 253 case Highlight:
Chris@376 254 return Qt::red;
Chris@376 255
Chris@376 256 case Printer:
Chris@376 257 return Qt::red;
Chris@536 258
Chris@536 259 case HighGain:
Chris@536 260 return Qt::red;
Chris@376 261 }
Chris@376 262
Chris@376 263 return Qt::white;
Chris@376 264 }
Chris@376 265
Chris@376 266 bool
Chris@376 267 ColourMapper::hasLightBackground() const
Chris@376 268 {
Chris@376 269 if (m_map >= getColourMapCount()) return false;
Chris@376 270 StandardMap map = (StandardMap)m_map;
Chris@376 271
Chris@376 272 switch (map) {
Chris@376 273
Chris@376 274 case BlackOnWhite:
Chris@376 275 case Printer:
Chris@536 276 case HighGain:
Chris@376 277 return true;
Chris@376 278
Chris@376 279 default:
Chris@376 280 return false;
Chris@376 281 }
Chris@376 282 }
Chris@376 283
Chris@376 284