|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TSPECTRUM_INCLUDED
|
|
Toshihiro Shimizu |
890ddd |
#define TSPECTRUM_INCLUDED
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#undef DVAPI
|
|
Toshihiro Shimizu |
890ddd |
#undef DVVAR
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TCOLOR_EXPORTS
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_EXPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_EXPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_IMPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_IMPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#ifdef _MSC_VER
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(disable : 4251)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class DVAPI TSpectrumT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
typedef std::pair<double, t=""> ColorKey;</double,>
|
|
Shinya Kitaoka |
120a6e |
typedef ColorKey Key;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
typedef std::vector<colorkey> KeyTable;</colorkey>
|
|
Shinya Kitaoka |
120a6e |
KeyTable m_keys, m_sortedKeys;
|
|
Shinya Kitaoka |
120a6e |
typedef std::pair<t, t=""> Pair; // premultiplied/not premultiplied</t,>
|
|
Shinya Kitaoka |
120a6e |
std::vector<pair> m_samples;</pair>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline T getActualValue(double s) {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_sortedKeys.empty());
|
|
Shinya Kitaoka |
120a6e |
typename std::vector<colorkey>::const_iterator b;</colorkey>
|
|
Shinya Kitaoka |
120a6e |
b = std::lower_bound(m_sortedKeys.begin(), m_sortedKeys.end(),
|
|
Shinya Kitaoka |
120a6e |
ColorKey(s, T()));
|
|
Shinya Kitaoka |
120a6e |
if (b == m_sortedKeys.end())
|
|
Shinya Kitaoka |
120a6e |
return m_sortedKeys.rbegin()->second;
|
|
Shinya Kitaoka |
120a6e |
else if (b == m_sortedKeys.begin() || areAlmostEqual(b->first, s))
|
|
Shinya Kitaoka |
120a6e |
return b->second;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
typename KeyTable::const_iterator a = b;
|
|
Shinya Kitaoka |
120a6e |
a--;
|
|
Shinya Kitaoka |
120a6e |
assert(a->first < s && s <= b->first);
|
|
Shinya Kitaoka |
120a6e |
double f = (s - a->first) / (b->first - a->first);
|
|
Shinya Kitaoka |
120a6e |
return blend(a->second, b->second, f);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void update() {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_keys.empty());
|
|
Shinya Kitaoka |
120a6e |
m_sortedKeys = m_keys;
|
|
Shinya Kitaoka |
120a6e |
std::sort(m_sortedKeys.begin(), m_sortedKeys.end());
|
|
Shinya Kitaoka |
120a6e |
if (m_samples.empty()) m_samples.resize(100);
|
|
Shinya Kitaoka |
120a6e |
int n = m_samples.size();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < n; i++) {
|
|
Shinya Kitaoka |
120a6e |
T v = getActualValue((double)i / (double)(n - 1));
|
|
Shinya Kitaoka |
120a6e |
m_samples[i].second = v;
|
|
Shinya Kitaoka |
120a6e |
m_samples[i].first = premultiply(v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSpectrumT() : m_keys(), m_sortedKeys(), m_samples() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSpectrumT(const TSpectrumT<t> &s)</t>
|
|
Shinya Kitaoka |
120a6e |
: m_keys(s.m_keys)
|
|
Shinya Kitaoka |
120a6e |
, m_sortedKeys(s.m_sortedKeys)
|
|
Shinya Kitaoka |
120a6e |
, m_samples(s.m_samples) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSpectrumT(int keyCount, ColorKey keys[], int sampleCount = 100)
|
|
Shinya Kitaoka |
120a6e |
: m_keys(keys, keys + keyCount) {
|
|
Shinya Kitaoka |
120a6e |
m_samples.resize(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*SpectrumT(std::map<double, t=""> &keys, int sampleCount=100)</double,>
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
m_keys = keys;
|
|
Shinya Kitaoka |
120a6e |
updateTable(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSpectrumT(const T &a, const T &b, int sampleCount = 100) {
|
|
Shinya Kitaoka |
120a6e |
m_keys.push_back(ColorKey(0, a));
|
|
Shinya Kitaoka |
120a6e |
m_keys.push_back(ColorKey(1, b));
|
|
Shinya Kitaoka |
120a6e |
m_samples.resize(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const TSpectrumT<t> &s) const {</t>
|
|
Shinya Kitaoka |
120a6e |
if (m_keys.size() != s.m_keys.size()) return false;
|
|
Shinya Kitaoka |
120a6e |
typename KeyTable::const_iterator i0, i1;
|
|
Shinya Kitaoka |
120a6e |
for (i0 = m_keys.begin(), i1 = s.m_keys.begin(); i0 != m_keys.end();
|
|
Shinya Kitaoka |
120a6e |
++i0, ++i1) {
|
|
Shinya Kitaoka |
120a6e |
assert(i1 != s.m_keys.end());
|
|
Shinya Kitaoka |
120a6e |
if (i0->first != i1->first) return false;
|
|
Shinya Kitaoka |
120a6e |
if (i0->second != i1->second) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const TSpectrumT<t> &s) const { return !operator==(s); }</t>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
T getValue(double s) const // non premoltiplicati
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
assert(!m_keys.empty());
|
|
Shinya Kitaoka |
120a6e |
int m = m_samples.size();
|
|
Shinya Kitaoka |
120a6e |
assert(m > 1);
|
|
Shinya Kitaoka |
120a6e |
if (s <= 0)
|
|
Shinya Kitaoka |
120a6e |
return m_samples.front().second;
|
|
Shinya Kitaoka |
120a6e |
else if (s >= 1)
|
|
Shinya Kitaoka |
120a6e |
return m_samples.back().second;
|
|
Shinya Kitaoka |
120a6e |
s = s * (m - 1);
|
|
Shinya Kitaoka |
120a6e |
int i = tfloor(s);
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= i && i < m - 1);
|
|
Shinya Kitaoka |
120a6e |
s -= i;
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= s && s < 1);
|
|
Shinya Kitaoka |
120a6e |
T a = m_samples[i].second;
|
|
Shinya Kitaoka |
120a6e |
T b = m_samples[i + 1].second;
|
|
Shinya Kitaoka |
120a6e |
return blend<t>(a, b, s);</t>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T getPremultipliedValue(double s) const // non premoltiplicati
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(!m_keys.empty());
|
|
Shinya Kitaoka |
120a6e |
int m = m_samples.size();
|
|
Shinya Kitaoka |
120a6e |
assert(m > 1);
|
|
Shinya Kitaoka |
120a6e |
if (s <= 0)
|
|
Shinya Kitaoka |
120a6e |
return m_samples.front().first;
|
|
Shinya Kitaoka |
120a6e |
else if (s >= 1)
|
|
Shinya Kitaoka |
120a6e |
return m_samples.back().first;
|
|
Shinya Kitaoka |
120a6e |
s = s * (m - 1);
|
|
Shinya Kitaoka |
120a6e |
int i = tfloor(s);
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= i && i < m - 1);
|
|
Shinya Kitaoka |
120a6e |
s -= i;
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= s && s < 1);
|
|
Shinya Kitaoka |
120a6e |
T a = m_samples[i].first;
|
|
Shinya Kitaoka |
120a6e |
T b = m_samples[i + 1].first;
|
|
Shinya Kitaoka |
120a6e |
return blend<t>(a, b, s);</t>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int getKeyCount() const { return m_keys.size(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Key getKey(int index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < getKeyCount());
|
|
Shinya Kitaoka |
120a6e |
return m_keys[index];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setKey(int index, const Key &key) {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < getKeyCount());
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= key.first && key.first <= 1);
|
|
Shinya Kitaoka |
120a6e |
m_keys[index] = key;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addKey(const Key &key) {
|
|
Shinya Kitaoka |
120a6e |
m_keys.push_back(key);
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void removeKey(int index) {
|
|
Shinya Kitaoka |
120a6e |
if (m_keys.size() <= 1) return;
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < getKeyCount());
|
|
Shinya Kitaoka |
120a6e |
m_keys.erase(m_keys.begin() + index);
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
DVAPI TSpectrumT<tpixel64> convert(const TSpectrumT<tpixel32> &s);</tpixel32></tpixel64>
|
|
Campbell Barton |
8c6c57 |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TSpectrumT<tpixel32>;</tpixel32>
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TSpectrumT<tpixel64>;</tpixel64>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TSpectrumT<tpixel32> TSpectrum;</tpixel32>
|
|
Toshihiro Shimizu |
890ddd |
typedef TSpectrumT<tpixel64> TSpectrum64;</tpixel64>
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
e280ae |
#ifdef _MSC_VER
|
|
Toshihiro Shimizu |
890ddd |
#pragma warning(default : 4251)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|