ColourMapper.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006-2007 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "ColourMapper.h"
00017 
00018 #include <iostream>
00019 
00020 #include <cmath>
00021 
00022 ColourMapper::ColourMapper(int map, float min, float max) :
00023     QObject(),
00024     m_map(map),
00025     m_min(min),
00026     m_max(max)
00027 {
00028     if (m_min == m_max) {
00029         std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
00030                   << "), adjusting" << std::endl;
00031         m_max = m_min + 1;
00032     }
00033 }
00034 
00035 ColourMapper::~ColourMapper()
00036 {
00037 }
00038 
00039 int
00040 ColourMapper::getColourMapCount()
00041 {
00042     return 11;
00043 }
00044 
00045 QString
00046 ColourMapper::getColourMapName(int n)
00047 {
00048     if (n >= getColourMapCount()) return tr("<unknown>");
00049     StandardMap map = (StandardMap)n;
00050 
00051     switch (map) {
00052     case DefaultColours:   return tr("Default");
00053     case WhiteOnBlack:     return tr("White on Black");
00054     case BlackOnWhite:     return tr("Black on White");
00055     case RedOnBlue:        return tr("Red on Blue");
00056     case YellowOnBlack:    return tr("Yellow on Black");
00057     case BlueOnBlack:      return tr("Blue on Black");
00058     case Sunset:           return tr("Sunset");
00059     case FruitSalad:       return tr("Fruit Salad");
00060     case Banded:           return tr("Banded");
00061     case Highlight:        return tr("Highlight");
00062     case Printer:          return tr("Printer");
00063     }
00064 
00065     return tr("<unknown>");
00066 }
00067 
00068 QColor
00069 ColourMapper::map(float value) const
00070 {
00071     float norm = (value - m_min) / (m_max - m_min);
00072     if (norm < 0.f) norm = 0.f;
00073     if (norm > 1.f) norm = 1.f;
00074     
00075     float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
00076     bool hsv = true;
00077 
00078 //    float red = 0.f, green = 0.3333f;
00079     float blue = 0.6666f, pieslice = 0.3333f;
00080 
00081     if (m_map >= getColourMapCount()) return Qt::black;
00082     StandardMap map = (StandardMap)m_map;
00083 
00084     switch (map) {
00085 
00086     case DefaultColours:
00087         h = blue - norm * 2.f * pieslice;
00088         s = 0.5f + norm/2.f;
00089         v = norm;
00090         break;
00091 
00092     case WhiteOnBlack:
00093         r = g = b = norm;
00094         hsv = false;
00095         break;
00096 
00097     case BlackOnWhite:
00098         r = g = b = 1.f - norm;
00099         hsv = false;
00100         break;
00101 
00102     case RedOnBlue:
00103         h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
00104         s = 1.f;
00105         v = norm;
00106         break;
00107 
00108     case YellowOnBlack:
00109         h = 0.15f;
00110         s = 1.f;
00111         v = norm;
00112         break;
00113 
00114     case BlueOnBlack:
00115         h = blue;
00116         s = 1.f;
00117         v = norm * 2.f;
00118         if (v > 1.f) {
00119             v = 1.f;
00120             s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
00121             if (s < 0.f) s = 0.f;
00122             if (s > 1.f) s = 1.f;
00123         }
00124         break;
00125 
00126     case Sunset:
00127         r = (norm - 0.24f) * 2.38f;
00128         if (r > 1.f) r = 1.f;
00129         if (r < 0.f) r = 0.f;
00130         g = (norm - 0.64f) * 2.777f;
00131         if (g > 1.f) g = 1.f;
00132         if (g < 0.f) g = 0.f;
00133         b = (3.6f * norm);
00134         if (norm > 0.277f) b = 2.f - b;
00135         if (b > 1.f) b = 1.f;
00136         if (b < 0.f) b = 0.f;
00137         hsv = false;
00138         break;
00139 
00140     case FruitSalad:
00141         h = blue + (pieslice/6.f) - norm;
00142         if (h < 0.f) h += 1.f;
00143         s = 1.f;
00144         v = 1.f;
00145         break;
00146 
00147     case Banded:
00148         if      (norm < 0.125) return Qt::darkGreen;
00149         else if (norm < 0.25)  return Qt::green;
00150         else if (norm < 0.375) return Qt::darkBlue;
00151         else if (norm < 0.5)   return Qt::blue;
00152         else if (norm < 0.625) return Qt::darkYellow;
00153         else if (norm < 0.75)  return Qt::yellow;
00154         else if (norm < 0.875) return Qt::darkRed;
00155         else                   return Qt::red;
00156         break;
00157 
00158     case Highlight:
00159         if (norm > 0.99) return Qt::white;
00160         else return Qt::darkBlue;
00161 
00162     case Printer:
00163         if (norm > 0.8) {
00164             r = 1.f;
00165         } else if (norm > 0.7) {
00166             r = 0.9f;
00167         } else if (norm > 0.6) {
00168             r = 0.8f;
00169         } else if (norm > 0.5) {
00170             r = 0.7f;
00171         } else if (norm > 0.4) {
00172             r = 0.6f;
00173         } else if (norm > 0.3) {
00174             r = 0.5f;
00175         } else if (norm > 0.2) {
00176             r = 0.4f;
00177         } else {
00178             r = 0.f;
00179         }
00180         r = g = b = 1.f - r;
00181         hsv = false;
00182         break;
00183     }
00184 
00185     if (hsv) {
00186         return QColor::fromHsvF(h, s, v);
00187     } else {
00188         return QColor::fromRgbF(r, g, b);
00189     }
00190 }
00191 
00192 QColor
00193 ColourMapper::getContrastingColour() const
00194 {
00195     if (m_map >= getColourMapCount()) return Qt::white;
00196     StandardMap map = (StandardMap)m_map;
00197 
00198     switch (map) {
00199 
00200     case DefaultColours:
00201         return QColor(255, 150, 50);
00202 
00203     case WhiteOnBlack:
00204         return Qt::red;
00205 
00206     case BlackOnWhite:
00207         return Qt::darkGreen;
00208 
00209     case RedOnBlue:
00210         return Qt::green;
00211 
00212     case YellowOnBlack:
00213         return QColor::fromHsv(240, 255, 255);
00214 
00215     case BlueOnBlack:
00216         return Qt::red;
00217 
00218     case Sunset:
00219         return Qt::white;
00220 
00221     case FruitSalad:
00222         return Qt::white;
00223 
00224     case Banded:
00225         return Qt::cyan;
00226 
00227     case Highlight:
00228         return Qt::red;
00229 
00230     case Printer:
00231         return Qt::red;
00232     }
00233 
00234     return Qt::white;
00235 }
00236 
00237 bool
00238 ColourMapper::hasLightBackground() const
00239 {
00240     if (m_map >= getColourMapCount()) return false;
00241     StandardMap map = (StandardMap)m_map;
00242 
00243     switch (map) {
00244 
00245     case BlackOnWhite:
00246     case Printer:
00247         return true;
00248 
00249     default:
00250         return false;
00251     }
00252 }
00253 
00254 

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1