#include "colour_extractor.h" #include #include // CONSTRUCTORS ColourExtractor::ColourExtractor(size_t h_levels, size_t s_levels, size_t l_levels) :m_pixels(NULL), m_max_colour_count(0), m_h_levels(h_levels), m_s_levels(s_levels), m_l_levels(l_levels) { m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels]; memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t)); } // PROTECTED FUNCS size_t ColourExtractor::quantize(struct ColourHSL hsl) const { size_t result = 0; size_t h_quant = 0; size_t s_quant = 0; size_t l_quant = 0; l_quant = static_cast(round(hsl.l * (m_l_levels - 1))); if (0 == l_quant) { goto end; } s_quant = static_cast(round(hsl.s * (m_s_levels - 1))); if (0 == s_quant) { goto end; } h_quant = static_cast(round(hsl.h / 360.0 * (m_h_levels - 1))); end: result += h_quant; result *= m_s_levels; result += s_quant; result *= m_l_levels; result += l_quant; return result; } struct ColourHSL ColourExtractor::dequantize(size_t colour) const { struct ColourHSL result; size_t h_quant; size_t s_quant; size_t l_quant; l_quant = colour % m_l_levels; colour /= m_l_levels; s_quant = colour % m_s_levels; colour /= m_s_levels; h_quant = colour % m_h_levels; result.h = static_cast(h_quant) * 360.0 / (m_h_levels - 1); result.s = static_cast(s_quant) / (m_s_levels - 1); result.l = static_cast(l_quant) / (m_l_levels - 1); return result; } // PUBLIC FUNCS void ColourExtractor::get_quantization_levels(size_t& h_levels, size_t& s_levels, size_t& l_levels) const { h_levels = m_h_levels; s_levels = m_s_levels; l_levels = m_l_levels; } void ColourExtractor::set_quantization_levels(size_t h_levels, size_t s_levels, size_t l_levels) { delete[] m_pixels; m_h_levels = h_levels; m_s_levels = s_levels; m_l_levels = l_levels; m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels]; memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t)); } size_t ColourExtractor::get_h_quantization_levels() const { return m_h_levels; } void ColourExtractor::set_h_quantization_levels(size_t h_levels) { delete[] m_pixels; m_h_levels = h_levels; m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels]; memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t)); } size_t ColourExtractor::get_s_quantization_levels() const { return m_s_levels; } void ColourExtractor::set_s_quantization_levels(size_t s_levels) { delete[] m_pixels; m_s_levels = s_levels; m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels]; memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t)); } size_t ColourExtractor::get_v_quantization_levels() const { return m_l_levels; } void ColourExtractor::set_v_quantization_levels(size_t l_levels) { delete[] m_pixels; m_l_levels = l_levels; m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels]; memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t)); } void ColourExtractor::add_pixel(struct ColourHSL hsl) { size_t colour_quant; colour_quant = quantize(hsl); m_pixels[colour_quant] += 1; if (m_max_colour_count < m_pixels[colour_quant]) { m_max_colour_count = m_pixels[colour_quant]; } } void ColourExtractor::clear_pixels() { for (size_t i = 0; i < m_h_levels * m_s_levels * m_l_levels; ++i) { m_pixels[i] = 0; } m_max_colour_count = 0; } struct ColourHSL ColourExtractor::extract_colour() const { struct ColourHSL result = {0.0, 0.0, 0.0}; struct ColourHSL temp_colour; size_t max_colour_value = 0; size_t temp_colour_value; double temp_colour_weight; for (size_t i = 0; i < m_h_levels * m_s_levels * m_l_levels; ++i) { if (0 == m_pixels[i]) { continue; } temp_colour = dequantize(i); temp_colour_weight = static_cast(m_pixels[i]); temp_colour_weight /= m_max_colour_count; temp_colour_value = evaluate_colour(temp_colour, temp_colour_weight); if (temp_colour_value > max_colour_value) { result = temp_colour; max_colour_value = temp_colour_value; } } return result; } ColourExtractor::~ColourExtractor() { delete[] m_pixels; }