annotate layer/ColourMapper.cpp @ 782:ddae586bc47b

Restore commit:6a8d922f991d which was apparently reverted in error as commit:c2291e22bf0c
author Chris Cannam
date Tue, 03 Jun 2014 11:10:52 +0100
parents 1a0dfcbffaf1
children 1d526ba11a24
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@376 24 ColourMapper::ColourMapper(int map, float min, float 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@376 72 ColourMapper::map(float value) const
Chris@376 73 {
Chris@376 74 float norm = (value - m_min) / (m_max - m_min);
Chris@376 75 if (norm < 0.f) norm = 0.f;
Chris@376 76 if (norm > 1.f) norm = 1.f;
Chris@376 77
Chris@376 78 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
Chris@376 79 bool hsv = true;
Chris@376 80
Chris@376 81 // float red = 0.f, green = 0.3333f;
Chris@376 82 float blue = 0.6666f, pieslice = 0.3333f;
Chris@376 83
Chris@376 84 if (m_map >= getColourMapCount()) return Qt::black;
Chris@376 85 StandardMap map = (StandardMap)m_map;
Chris@376 86
Chris@376 87 switch (map) {
Chris@376 88
Chris@376 89 case DefaultColours:
Chris@376 90 h = blue - norm * 2.f * pieslice;
Chris@376 91 s = 0.5f + norm/2.f;
Chris@376 92 v = norm;
Chris@376 93 break;
Chris@376 94
Chris@376 95 case WhiteOnBlack:
Chris@376 96 r = g = b = norm;
Chris@376 97 hsv = false;
Chris@376 98 break;
Chris@376 99
Chris@376 100 case BlackOnWhite:
Chris@376 101 r = g = b = 1.f - norm;
Chris@376 102 hsv = false;
Chris@376 103 break;
Chris@376 104
Chris@376 105 case RedOnBlue:
Chris@376 106 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
Chris@376 107 s = 1.f;
Chris@376 108 v = norm;
Chris@376 109 break;
Chris@376 110
Chris@376 111 case YellowOnBlack:
Chris@376 112 h = 0.15f;
Chris@376 113 s = 1.f;
Chris@376 114 v = norm;
Chris@376 115 break;
Chris@376 116
Chris@376 117 case BlueOnBlack:
Chris@376 118 h = blue;
Chris@376 119 s = 1.f;
Chris@376 120 v = norm * 2.f;
Chris@376 121 if (v > 1.f) {
Chris@376 122 v = 1.f;
Chris@376 123 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
Chris@376 124 if (s < 0.f) s = 0.f;
Chris@376 125 if (s > 1.f) s = 1.f;
Chris@376 126 }
Chris@376 127 break;
Chris@376 128
Chris@376 129 case Sunset:
Chris@376 130 r = (norm - 0.24f) * 2.38f;
Chris@376 131 if (r > 1.f) r = 1.f;
Chris@376 132 if (r < 0.f) r = 0.f;
Chris@376 133 g = (norm - 0.64f) * 2.777f;
Chris@376 134 if (g > 1.f) g = 1.f;
Chris@376 135 if (g < 0.f) g = 0.f;
Chris@376 136 b = (3.6f * norm);
Chris@376 137 if (norm > 0.277f) b = 2.f - b;
Chris@376 138 if (b > 1.f) b = 1.f;
Chris@376 139 if (b < 0.f) b = 0.f;
Chris@376 140 hsv = false;
Chris@376 141 break;
Chris@376 142
Chris@376 143 case FruitSalad:
Chris@376 144 h = blue + (pieslice/6.f) - norm;
Chris@376 145 if (h < 0.f) h += 1.f;
Chris@376 146 s = 1.f;
Chris@376 147 v = 1.f;
Chris@376 148 break;
Chris@376 149
Chris@376 150 case Banded:
Chris@376 151 if (norm < 0.125) return Qt::darkGreen;
Chris@376 152 else if (norm < 0.25) return Qt::green;
Chris@376 153 else if (norm < 0.375) return Qt::darkBlue;
Chris@376 154 else if (norm < 0.5) return Qt::blue;
Chris@376 155 else if (norm < 0.625) return Qt::darkYellow;
Chris@376 156 else if (norm < 0.75) return Qt::yellow;
Chris@376 157 else if (norm < 0.875) return Qt::darkRed;
Chris@376 158 else return Qt::red;
Chris@376 159 break;
Chris@376 160
Chris@376 161 case Highlight:
Chris@376 162 if (norm > 0.99) return Qt::white;
Chris@376 163 else return Qt::darkBlue;
Chris@376 164
Chris@376 165 case Printer:
Chris@376 166 if (norm > 0.8) {
Chris@376 167 r = 1.f;
Chris@376 168 } else if (norm > 0.7) {
Chris@376 169 r = 0.9f;
Chris@376 170 } else if (norm > 0.6) {
Chris@376 171 r = 0.8f;
Chris@376 172 } else if (norm > 0.5) {
Chris@376 173 r = 0.7f;
Chris@376 174 } else if (norm > 0.4) {
Chris@376 175 r = 0.6f;
Chris@376 176 } else if (norm > 0.3) {
Chris@376 177 r = 0.5f;
Chris@376 178 } else if (norm > 0.2) {
Chris@376 179 r = 0.4f;
Chris@376 180 } else {
Chris@376 181 r = 0.f;
Chris@376 182 }
Chris@376 183 r = g = b = 1.f - r;
Chris@376 184 hsv = false;
Chris@376 185 break;
Chris@536 186
Chris@536 187 case HighGain:
Chris@536 188 if (norm <= 1.f / 256.f) {
Chris@536 189 norm = 0.f;
Chris@536 190 } else {
Chris@536 191 norm = 0.1f + (powf(((norm - 0.5f) * 2.f), 3.f) + 1.f) / 2.081f;
Chris@536 192 }
Chris@536 193 // now as for Sunset
Chris@536 194 r = (norm - 0.24f) * 2.38f;
Chris@536 195 if (r > 1.f) r = 1.f;
Chris@536 196 if (r < 0.f) r = 0.f;
Chris@536 197 g = (norm - 0.64f) * 2.777f;
Chris@536 198 if (g > 1.f) g = 1.f;
Chris@536 199 if (g < 0.f) g = 0.f;
Chris@536 200 b = (3.6f * norm);
Chris@536 201 if (norm > 0.277f) b = 2.f - b;
Chris@536 202 if (b > 1.f) b = 1.f;
Chris@536 203 if (b < 0.f) b = 0.f;
Chris@536 204 hsv = false;
Chris@536 205 /*
Chris@536 206 if (r > 1.f) r = 1.f;
Chris@536 207 r = g = b = 1.f - r;
Chris@536 208 hsv = false;
Chris@536 209 */
Chris@536 210 break;
Chris@376 211 }
Chris@376 212
Chris@376 213 if (hsv) {
Chris@376 214 return QColor::fromHsvF(h, s, v);
Chris@376 215 } else {
Chris@376 216 return QColor::fromRgbF(r, g, b);
Chris@376 217 }
Chris@376 218 }
Chris@376 219
Chris@376 220 QColor
Chris@376 221 ColourMapper::getContrastingColour() const
Chris@376 222 {
Chris@376 223 if (m_map >= getColourMapCount()) return Qt::white;
Chris@376 224 StandardMap map = (StandardMap)m_map;
Chris@376 225
Chris@376 226 switch (map) {
Chris@376 227
Chris@376 228 case DefaultColours:
Chris@376 229 return QColor(255, 150, 50);
Chris@376 230
Chris@376 231 case WhiteOnBlack:
Chris@376 232 return Qt::red;
Chris@376 233
Chris@376 234 case BlackOnWhite:
Chris@376 235 return Qt::darkGreen;
Chris@376 236
Chris@376 237 case RedOnBlue:
Chris@376 238 return Qt::green;
Chris@376 239
Chris@376 240 case YellowOnBlack:
Chris@376 241 return QColor::fromHsv(240, 255, 255);
Chris@376 242
Chris@376 243 case BlueOnBlack:
Chris@376 244 return Qt::red;
Chris@376 245
Chris@376 246 case Sunset:
Chris@376 247 return Qt::white;
Chris@376 248
Chris@376 249 case FruitSalad:
Chris@376 250 return Qt::white;
Chris@376 251
Chris@376 252 case Banded:
Chris@376 253 return Qt::cyan;
Chris@376 254
Chris@376 255 case Highlight:
Chris@376 256 return Qt::red;
Chris@376 257
Chris@376 258 case Printer:
Chris@376 259 return Qt::red;
Chris@536 260
Chris@536 261 case HighGain:
Chris@536 262 return Qt::red;
Chris@376 263 }
Chris@376 264
Chris@376 265 return Qt::white;
Chris@376 266 }
Chris@376 267
Chris@376 268 bool
Chris@376 269 ColourMapper::hasLightBackground() const
Chris@376 270 {
Chris@376 271 if (m_map >= getColourMapCount()) return false;
Chris@376 272 StandardMap map = (StandardMap)m_map;
Chris@376 273
Chris@376 274 switch (map) {
Chris@376 275
Chris@376 276 case BlackOnWhite:
Chris@376 277 case Printer:
Chris@536 278 case HighGain:
Chris@376 279 return true;
Chris@376 280
Chris@376 281 default:
Chris@376 282 return false;
Chris@376 283 }
Chris@376 284 }
Chris@376 285
Chris@376 286