Toshihiro Shimizu 890ddd
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
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
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>
Toshihiro Shimizu 890ddd
class DVAPI TSpectrumT
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef std::pair<double, t=""> ColorKey;</double,>
Toshihiro Shimizu 890ddd
	typedef ColorKey Key;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	typedef std::vector<colorkey> KeyTable;</colorkey>
Toshihiro Shimizu 890ddd
	KeyTable m_keys, m_sortedKeys;
Toshihiro Shimizu 890ddd
	typedef std::pair<t, t=""> Pair; // premultiplied/not premultiplied</t,>
Toshihiro Shimizu 890ddd
	std::vector<pair> m_samples;</pair>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inline T getActualValue(double s)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(!m_sortedKeys.empty());
Toshihiro Shimizu 890ddd
		typename std::vector<colorkey>::const_iterator b;</colorkey>
Toshihiro Shimizu 890ddd
		b = std::lower_bound(m_sortedKeys.begin(), m_sortedKeys.end(), ColorKey(s, T()));
Toshihiro Shimizu 890ddd
		if (b == m_sortedKeys.end())
Toshihiro Shimizu 890ddd
			return m_sortedKeys.rbegin()->second;
Toshihiro Shimizu 890ddd
		else if (b == m_sortedKeys.begin() || areAlmostEqual(b->first, s))
Toshihiro Shimizu 890ddd
			return b->second;
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			typename KeyTable::const_iterator a = b;
Toshihiro Shimizu 890ddd
			a--;
Toshihiro Shimizu 890ddd
			assert(a->first < s && s <= b->first);
Toshihiro Shimizu 890ddd
			double f = (s - a->first) / (b->first - a->first);
Toshihiro Shimizu 890ddd
			return blend(a->second, b->second, f);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void update()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(!m_keys.empty());
Toshihiro Shimizu 890ddd
		m_sortedKeys = m_keys;
Toshihiro Shimizu 890ddd
		std::sort(m_sortedKeys.begin(), m_sortedKeys.end());
Toshihiro Shimizu 890ddd
		if (m_samples.empty())
Toshihiro Shimizu 890ddd
			m_samples.resize(100);
Toshihiro Shimizu 890ddd
		int n = m_samples.size();
Toshihiro Shimizu 890ddd
		for (int i = 0; i < n; i++) {
Toshihiro Shimizu 890ddd
			T v = getActualValue((double)i / (double)(n - 1));
Toshihiro Shimizu 890ddd
			m_samples[i].second = v;
Toshihiro Shimizu 890ddd
			m_samples[i].first = premultiply(v);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TSpectrumT()
Toshihiro Shimizu 890ddd
		: m_keys(), m_sortedKeys(), m_samples() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSpectrumT(const TSpectrumT<t> &s)</t>
Toshihiro Shimizu 890ddd
		: m_keys(s.m_keys), m_sortedKeys(s.m_sortedKeys), m_samples(s.m_samples) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSpectrumT(int keyCount, ColorKey keys[], int sampleCount = 100)
Toshihiro Shimizu 890ddd
		: m_keys(keys, keys + keyCount)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_samples.resize(sampleCount);
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*SpectrumT(std::map<double, t=""> &keys, int sampleCount=100)</double,>
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    m_keys = keys;
Toshihiro Shimizu 890ddd
    updateTable(sampleCount);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSpectrumT(const T &a, const T &b, int sampleCount = 100)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_keys.push_back(ColorKey(0, a));
Toshihiro Shimizu 890ddd
		m_keys.push_back(ColorKey(1, b));
Toshihiro Shimizu 890ddd
		m_samples.resize(sampleCount);
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator==(const TSpectrumT<t> &s) const</t>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_keys.size() != s.m_keys.size())
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		typename KeyTable::const_iterator i0, i1;
Toshihiro Shimizu 890ddd
		for (i0 = m_keys.begin(),
Toshihiro Shimizu 890ddd
			i1 = s.m_keys.begin();
Toshihiro Shimizu 890ddd
			 i0 != m_keys.end();
Toshihiro Shimizu 890ddd
			 ++i0, ++i1) {
Toshihiro Shimizu 890ddd
			assert(i1 != s.m_keys.end());
Toshihiro Shimizu 890ddd
			if (i0->first != i1->first)
Toshihiro Shimizu 890ddd
				return false;
Toshihiro Shimizu 890ddd
			if (i0->second != i1->second)
Toshihiro Shimizu 890ddd
				return false;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator!=(const TSpectrumT<t> &s) const</t>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return !operator==(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T getValue(double s) const // non premoltiplicati
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(!m_keys.empty());
Toshihiro Shimizu 890ddd
		int m = m_samples.size();
Toshihiro Shimizu 890ddd
		assert(m > 1);
Toshihiro Shimizu 890ddd
		if (s <= 0)
Toshihiro Shimizu 890ddd
			return m_samples.front().second;
Toshihiro Shimizu 890ddd
		else if (s >= 1)
Toshihiro Shimizu 890ddd
			return m_samples.back().second;
Toshihiro Shimizu 890ddd
		s = s * (m - 1);
Toshihiro Shimizu 890ddd
		int i = tfloor(s);
Toshihiro Shimizu 890ddd
		assert(0 <= i && i < m - 1);
Toshihiro Shimizu 890ddd
		s -= i;
Toshihiro Shimizu 890ddd
		assert(0 <= s && s < 1);
Toshihiro Shimizu 890ddd
		T a = m_samples[i].second;
Toshihiro Shimizu 890ddd
		T b = m_samples[i + 1].second;
Toshihiro Shimizu 890ddd
		return blend<t>(a, b, s);</t>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T getPremultipliedValue(double s) const // non premoltiplicati
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(!m_keys.empty());
Toshihiro Shimizu 890ddd
		int m = m_samples.size();
Toshihiro Shimizu 890ddd
		assert(m > 1);
Toshihiro Shimizu 890ddd
		if (s <= 0)
Toshihiro Shimizu 890ddd
			return m_samples.front().first;
Toshihiro Shimizu 890ddd
		else if (s >= 1)
Toshihiro Shimizu 890ddd
			return m_samples.back().first;
Toshihiro Shimizu 890ddd
		s = s * (m - 1);
Toshihiro Shimizu 890ddd
		int i = tfloor(s);
Toshihiro Shimizu 890ddd
		assert(0 <= i && i < m - 1);
Toshihiro Shimizu 890ddd
		s -= i;
Toshihiro Shimizu 890ddd
		assert(0 <= s && s < 1);
Toshihiro Shimizu 890ddd
		T a = m_samples[i].first;
Toshihiro Shimizu 890ddd
		T b = m_samples[i + 1].first;
Toshihiro Shimizu 890ddd
		return blend<t>(a, b, s);</t>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getKeyCount() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return m_keys.size();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Key getKey(int index) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(0 <= index && index < getKeyCount());
Toshihiro Shimizu 890ddd
		return m_keys[index];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setKey(int index, const Key &key)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(0 <= index && index < getKeyCount());
Toshihiro Shimizu 890ddd
		assert(0 <= key.first && key.first <= 1);
Toshihiro Shimizu 890ddd
		m_keys[index] = key;
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addKey(const Key &key)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_keys.push_back(key);
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void removeKey(int index)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_keys.size() <= 1)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		assert(0 <= index && index < getKeyCount());
Toshihiro Shimizu 890ddd
		m_keys.erase(m_keys.begin() + index);
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
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
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#pragma warning(default : 4251)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif