lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006-2007 Chris Cannam and QMUL. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #include "ColourMapper.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: ColourMapper::ColourMapper(int map, float min, float max) : lbajardsilogic@0: QObject(), lbajardsilogic@0: m_map(map), lbajardsilogic@0: m_min(min), lbajardsilogic@0: m_max(max) lbajardsilogic@0: { lbajardsilogic@0: if (m_min == m_max) { lbajardsilogic@0: std::cerr << "WARNING: ColourMapper: min == max (== " << m_min lbajardsilogic@0: << "), adjusting" << std::endl; lbajardsilogic@0: m_max = m_min + 1; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: ColourMapper::~ColourMapper() lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int lbajardsilogic@0: ColourMapper::getColourMapCount() lbajardsilogic@0: { lbajardsilogic@0: return 10; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QString lbajardsilogic@0: ColourMapper::getColourMapName(int n) lbajardsilogic@0: { lbajardsilogic@0: if (n >= getColourMapCount()) return tr(""); lbajardsilogic@0: StandardMap map = (StandardMap)n; lbajardsilogic@0: lbajardsilogic@0: switch (map) { lbajardsilogic@0: case DefaultColours: return tr("Default"); lbajardsilogic@0: case WhiteOnBlack: return tr("White on Black"); lbajardsilogic@0: case BlackOnWhite: return tr("Black on White"); lbajardsilogic@0: case RedOnBlue: return tr("Red on Blue"); lbajardsilogic@0: case YellowOnBlack: return tr("Yellow on Black"); lbajardsilogic@0: case BlueOnBlack: return tr("Blue on Black"); lbajardsilogic@0: case Sunset: return tr("Sunset"); lbajardsilogic@0: case FruitSalad: return tr("Fruit Salad"); lbajardsilogic@0: case Banded: return tr("Banded"); lbajardsilogic@0: case Highlight: return tr("Highlight"); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: return tr(""); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QColor lbajardsilogic@0: ColourMapper::map(float value) const lbajardsilogic@0: { lbajardsilogic@0: float norm = (value - m_min) / (m_max - m_min); lbajardsilogic@0: if (norm < 0.f) norm = 0.f; lbajardsilogic@0: if (norm > 1.f) norm = 1.f; lbajardsilogic@0: lbajardsilogic@0: float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f; lbajardsilogic@0: bool hsv = true; lbajardsilogic@0: lbajardsilogic@0: // float red = 0.f, green = 0.3333f; lbajardsilogic@0: float blue = 0.6666f, pieslice = 0.3333f; lbajardsilogic@0: lbajardsilogic@0: if (m_map >= getColourMapCount()) return Qt::black; lbajardsilogic@0: StandardMap map = (StandardMap)m_map; lbajardsilogic@0: lbajardsilogic@0: switch (map) { lbajardsilogic@0: lbajardsilogic@0: case DefaultColours: lbajardsilogic@0: h = blue - norm * 2.f * pieslice; lbajardsilogic@0: s = 0.5f + norm/2.f; lbajardsilogic@0: v = norm; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case WhiteOnBlack: lbajardsilogic@0: r = g = b = norm; lbajardsilogic@0: hsv = false; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case BlackOnWhite: lbajardsilogic@0: r = g = b = 1.f - norm; lbajardsilogic@0: hsv = false; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case RedOnBlue: lbajardsilogic@0: h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f); lbajardsilogic@0: s = 1.f; lbajardsilogic@0: v = norm; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case YellowOnBlack: lbajardsilogic@0: h = 0.15f; lbajardsilogic@0: s = 1.f; lbajardsilogic@0: v = norm; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case BlueOnBlack: lbajardsilogic@0: h = blue; lbajardsilogic@0: s = 1.f; lbajardsilogic@0: v = norm * 2.f; lbajardsilogic@0: if (v > 1.f) { lbajardsilogic@0: v = 1.f; lbajardsilogic@0: s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f; lbajardsilogic@0: if (s < 0.f) s = 0.f; lbajardsilogic@0: if (s > 1.f) s = 1.f; lbajardsilogic@0: } lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case Sunset: lbajardsilogic@0: r = (norm - 0.24f) * 2.38f; lbajardsilogic@0: if (r > 1.f) r = 1.f; lbajardsilogic@0: if (r < 0.f) r = 0.f; lbajardsilogic@0: g = (norm - 0.64f) * 2.777f; lbajardsilogic@0: if (g > 1.f) g = 1.f; lbajardsilogic@0: if (g < 0.f) g = 0.f; lbajardsilogic@0: b = (3.6f * norm); lbajardsilogic@0: if (norm > 0.277f) b = 2.f - b; lbajardsilogic@0: if (b > 1.f) b = 1.f; lbajardsilogic@0: if (b < 0.f) b = 0.f; lbajardsilogic@0: hsv = false; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case FruitSalad: lbajardsilogic@0: h = blue + (pieslice/6.f) - norm; lbajardsilogic@0: if (h < 0.f) h += 1.f; lbajardsilogic@0: s = 1.f; lbajardsilogic@0: v = 1.f; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case Banded: lbajardsilogic@0: if (norm < 0.125) return Qt::darkGreen; lbajardsilogic@0: else if (norm < 0.25) return Qt::green; lbajardsilogic@0: else if (norm < 0.375) return Qt::darkBlue; lbajardsilogic@0: else if (norm < 0.5) return Qt::blue; lbajardsilogic@0: else if (norm < 0.625) return Qt::darkYellow; lbajardsilogic@0: else if (norm < 0.75) return Qt::yellow; lbajardsilogic@0: else if (norm < 0.875) return Qt::darkRed; lbajardsilogic@0: else return Qt::red; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case Highlight: lbajardsilogic@0: if (norm > 0.99) return Qt::white; lbajardsilogic@0: else return Qt::darkBlue; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (hsv) { lbajardsilogic@0: return QColor::fromHsvF(h, s, v); lbajardsilogic@0: } else { lbajardsilogic@0: return QColor::fromRgbF(r, g, b); lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QColor lbajardsilogic@0: ColourMapper::getContrastingColour() const lbajardsilogic@0: { lbajardsilogic@0: if (m_map >= getColourMapCount()) return Qt::white; lbajardsilogic@0: StandardMap map = (StandardMap)m_map; lbajardsilogic@0: lbajardsilogic@0: switch (map) { lbajardsilogic@0: lbajardsilogic@0: case DefaultColours: lbajardsilogic@0: return QColor(255, 150, 50); lbajardsilogic@0: lbajardsilogic@0: case WhiteOnBlack: lbajardsilogic@0: return Qt::red; lbajardsilogic@0: lbajardsilogic@0: case BlackOnWhite: lbajardsilogic@0: return Qt::darkGreen; lbajardsilogic@0: lbajardsilogic@0: case RedOnBlue: lbajardsilogic@0: return Qt::green; lbajardsilogic@0: lbajardsilogic@0: case YellowOnBlack: lbajardsilogic@0: return QColor::fromHsv(240, 255, 255); lbajardsilogic@0: lbajardsilogic@0: case BlueOnBlack: lbajardsilogic@0: return Qt::red; lbajardsilogic@0: lbajardsilogic@0: case Sunset: lbajardsilogic@0: return Qt::white; lbajardsilogic@0: lbajardsilogic@0: case FruitSalad: lbajardsilogic@0: return Qt::white; lbajardsilogic@0: lbajardsilogic@0: case Banded: lbajardsilogic@0: return Qt::cyan; lbajardsilogic@0: lbajardsilogic@0: case Highlight: lbajardsilogic@0: return Qt::red; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: return Qt::white; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: