2017-08-06 19:12:44 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
2017-08-06 19:39:11 +00:00
|
|
|
#include <cstdint>
|
2017-08-10 15:24:23 -07:00
|
|
|
#include <iomanip>
|
2017-08-07 06:15:20 +00:00
|
|
|
#include <iostream>
|
2017-08-06 19:39:11 +00:00
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
#include "array.h"
|
2017-08-10 13:51:39 -07:00
|
|
|
#include "intmath.h"
|
2017-08-07 04:32:01 +00:00
|
|
|
|
2017-08-12 07:38:18 -07:00
|
|
|
constexpr int32_t kMinColor = 0;
|
|
|
|
|
constexpr int32_t kMaxColor = UINT16_MAX;
|
2017-08-06 19:12:44 +00:00
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
template <int32_t C>
|
|
|
|
|
struct Color : public Array<int32_t, C> {
|
|
|
|
|
constexpr int32_t AbsDiff(const Color<C>& other) const;
|
2017-08-12 07:38:18 -07:00
|
|
|
constexpr Color<C> Interpolate(const Color<C>& other, int32_t mul, int32_t div) const;
|
|
|
|
|
constexpr Color<C> Crop() const;
|
2017-08-06 19:12:44 +00:00
|
|
|
};
|
|
|
|
|
|
2017-08-10 15:24:23 -07:00
|
|
|
struct RgbColor : public Color<3> {};
|
|
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
template <int32_t C>
|
|
|
|
|
constexpr int32_t Color<C>::AbsDiff(const Color<C>& other) const {
|
|
|
|
|
int32_t diff = 0;
|
|
|
|
|
for (int32_t c = 0; c < C; ++c) {
|
|
|
|
|
diff += ::AbsDiff(this->at(c), other.at(c));
|
2017-08-10 15:24:23 -07:00
|
|
|
}
|
|
|
|
|
return diff;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
template <int32_t C>
|
2017-08-12 07:38:18 -07:00
|
|
|
constexpr Color<C> Color<C>::Interpolate(const Color<C>& other, int32_t mul, int32_t div) const {
|
2017-08-10 15:24:23 -07:00
|
|
|
Color<C> ret;
|
2017-08-12 11:46:05 -07:00
|
|
|
for (int32_t c = 0; c < C; ++c) {
|
2017-08-10 15:24:23 -07:00
|
|
|
ret.at(c) = ::Interpolate(this->at(c), other.at(c), mul, div);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
2017-08-06 19:12:44 +00:00
|
|
|
}
|
2017-08-07 06:15:20 +00:00
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
template <int32_t C>
|
2017-08-12 07:38:18 -07:00
|
|
|
constexpr Color<C> Color<C>::Crop() const {
|
|
|
|
|
Color<C> ret;
|
2017-08-12 11:46:05 -07:00
|
|
|
for (int32_t c = 0; c < C; ++c) {
|
2017-08-12 07:38:18 -07:00
|
|
|
ret.at(c) = std::max(kMinColor, std::min(kMaxColor, this->at(c)));
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-12 11:46:05 -07:00
|
|
|
template <int32_t C>
|
2017-08-10 15:24:23 -07:00
|
|
|
std::ostream& operator<<(std::ostream& os, const Color<C>& color) {
|
|
|
|
|
os << std::hex << std::setfill('0') << "Color(";
|
2017-08-12 11:46:05 -07:00
|
|
|
for (int32_t c = 0; c < C; ++c) {
|
2017-08-10 15:24:23 -07:00
|
|
|
os << "0x" << std::setw(4) << color.at(0);
|
|
|
|
|
if (c < C - 1) {
|
|
|
|
|
os << ", ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return os << ")" << std::dec;
|
|
|
|
|
}
|