annotate base/ColourMapper.cpp @ 299:576be0d0d218

* Merge transform directory from sv-match-alignment branch (the previous comment included notes for this stuff, but I missed it in the actual merge) * Fix crash when a transform fails to create an output model and the thread that created the transform then deletes its input model thinking it's no longer needed, even though the transform run thread is still using it -- fix is to wait() on the transform before returning the null output model
author Chris Cannam
date Fri, 28 Sep 2007 16:15:06 +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