/*
 * AXMIspChromaSuppressAlgorithm.cpp
 */

#include "AXMIspChromaSuppressAlgorithm.hpp"
#include "AXMIspChromaSuppressSettings.hpp"
#include <vector>
#include <algorithm>
AXMIspChromaSuppressAlgorithm::AXMIspChromaSuppressAlgorithm() {
	// TODO 自動生成されたコンストラクター・スタブ

}

AXMIspChromaSuppressAlgorithm::~AXMIspChromaSuppressAlgorithm() {
	// TODO Auto-generated destructor stub
}

/*
 * クロマサプレス輝度変調LUT計算
 */
void AXMIspChromaSuppressAlgorithm::CalcLuminanceModulationLUT(BYTE darkStartLuminance, BYTE darkInc, BYTE highColorStartLuminance, BYTE highColorInc, BYTE highColorLimit, BYTE highLightStartLuminance, BYTE highLightInc, BYTE* lut) {

	if (lut == 0) {
		return;
	}
	// 並び替え
	std::vector<BYTE> startLuminance;
	startLuminance.push_back(darkStartLuminance);
	startLuminance.push_back(highColorStartLuminance);
	startLuminance.push_back(highLightStartLuminance);
	std::sort(startLuminance.begin(), startLuminance.end());

	darkStartLuminance      = startLuminance[0];
	highColorStartLuminance = startLuminance[1];
	highLightStartLuminance = startLuminance[2];

	int modulationGainTmp = 0;
	int highLightStartGain = 0;

	for (int i = 0; i < CH_MAX_LUT_SIZE; i++) {
		BYTE luminance = i;
		// 暗部クロマサプレス開始輝度未満
		if (i < darkStartLuminance) {
			modulationGainTmp = (int)(CH_MODULATION_GAIN_BASE - (((darkStartLuminance - luminance) * darkInc) >> 4));
			highLightStartGain = modulationGainTmp;
		}

		// 暗部クロマサプレス開始輝度以上、かつ、高輝度側色強化開始輝度以下
		if (darkStartLuminance <= i && i <= highColorStartLuminance) {
			modulationGainTmp = CH_MODULATION_GAIN_BASE;
			highLightStartGain = modulationGainTmp;
		}

		// 高輝度側色強化開始輝度以上、かつ、ハイライトクロマサプレス開始輝度未満
		if (highColorStartLuminance < i && i <= highLightStartLuminance) {
			modulationGainTmp = (int)(CH_MODULATION_GAIN_BASE + (((luminance - highColorStartLuminance) * highColorInc) >> 4));
			highLightStartGain = modulationGainTmp;
		}

		// 高輝度側アパーチャ補正強化リミットチェック
		if (highColorLimit < modulationGainTmp) {
			highLightStartGain = modulationGainTmp = highColorLimit;
		}

		if (modulationGainTmp < 0) {
			modulationGainTmp = 0;
		}

		// ハイライトクロマサプレス開始輝度以上
		if (highLightStartLuminance < i) {
			modulationGainTmp = (int)(highLightStartGain - (((luminance - highLightStartLuminance) * highLightInc) >> 4));
			if (modulationGainTmp < 0) {
				modulationGainTmp = 0;
			}
		}
		lut[i] = static_cast<BYTE>(modulationGainTmp);
	}
}

/*
 * エッジクロマサプレス輝度変調LUT計算
 */
void AXMIspChromaSuppressAlgorithm::CalcEdgeLuminanceModulationLUT(BYTE startTh, BYTE supprStr, BYTE* lut) {

	if (lut == 0) {
		return;
	}

	int ans = 0;
	for (int i = 0; i < CH_MAX_EDGE_LUT_SIZE; i++) {
		if (i <= startTh) {
			ans = CH_MODULATION_GAIN_BASE;
		}
		else {
			ans = CH_MODULATION_GAIN_BASE - (((i - startTh) * supprStr) >> 4);
		}
		if (ans < 0) {
			lut[i] = 0;
		}
		else {
			lut[i] = (BYTE)ans;
		}
	}
}

