annotate base/ColourMapper.cpp @ 384:6f6ab834449d spectrogram-cache-rejig

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