You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

373 lines
16 KiB

#include "rk_aiq_isp39_modules.h"
#define RK_SHARP_V34_LUMA_POINT_NUM (8)
#define RK_SHARP_V34_PBF_DIAM 3
#define RK_SHARP_V34_RF_DIAM 5
#define RK_SHARP_V34_BF_DIAM 3
#define RK_SHARP_V34_AVG_DIAM 3
#define RK_SHARP_V34_SHARP_ADJ_GAIN_TABLE_LEN 14
#define RK_SHARP_V34_STRENGTH_TABLE_LEN 22
#define RK_SHARP_V34_SHARP_STRG_FIX_BITS 2
#define RK_SHARP_V34_GAUS_RATIO_FIX_BITS 7
#define RK_SHARP_V34_BF_RATIO_FIX_BITS 7
#define RK_SHARP_V34_PBFCOEFF_FIX_BITS 7
#define RK_SHARP_V34_RFCOEFF_FIX_BITS 7
#define RK_SHARP_V34_HBFCOEFF_FIX_BITS 7
#define RK_SHARP_V34_GLOBAL_GAIN_FIX_BITS 4
#define RK_SHARP_V34_GLOBAL_GAIN_ALPHA_FIX_BITS 3
#define RK_SHARP_V34_LOCAL_GAIN_FIX_BITS 4
#define RK_SHARP_V34_LOCAL_GAIN_SACLE_FIX_BITS 7
#define RK_SHARP_V34_ADJ_GAIN_FIX_BITS 10
#define RK_SHARP_V34_STRENGTH_TABLE_FIX_BITS 7
#define RK_SHARP_V34_TEX_FIX_BITS 10
void rk_aiq_sharp34_params_cvt(void * attr, isp_params_t* isp_params, common_cvt_info_t *cvtinfo)
{
int i, tmp;
float fPercent = 1.0f;
int rows = cvtinfo->rawHeight;
int cols = cvtinfo->rawWidth;
struct isp39_sharp_cfg *pFix = &isp_params->isp_cfg->others.sharp_cfg;
sharp_param_t *sharp_param = (sharp_param_t *) attr;
sharp_params_static_t* psta = &sharp_param->sta;
sharp_params_dyn_t* pdyn = &sharp_param->dyn;
int sum_coeff, offset;
int pbf_sigma_shift = 0;
int bf_sigma_shift = 0;
// SHARP_EN (0x0000)
// pFix->bypass = 0;
// TODO
//pFix->center_mode = pSelect->hw_sharp_centerPosition_mode;
if (pdyn->shpScl_locSgmStrg.hw_sharpT_locSgmStrg_mode == sharp_locGlbSgmStrgMix_mode )
pFix->local_gain_bypass = 0;
else
pFix->local_gain_bypass = 1;
if (cols > 3072 && rows > 1728) {
pFix->radius_step_mode = 1;
} else {
pFix->radius_step_mode = 0;
}
if (pdyn->shpScl_texDetect.hw_sharpT_estNsClip_mode == sharp_preNsSgmStats_mode)
pFix->noise_clip_mode = 0;
else
pFix->noise_clip_mode = 1;
if (pdyn->shpScl_texDetect.hw_sharpT_estNsFilt_mode == sharp_allFilt_mode )
pFix->noise_filt_sel = 0;
else
pFix->noise_filt_sel = 1;
if (pdyn->sharpOpt.hw_sharpT_shpSrc_mode == sharp_hfExactPreBfOut_mode) {
pFix->baselmg_sel = 0;
}
if (pdyn->sharpOpt.hw_sharpT_shpSrc_mode == sharp_sharpIn_mode) {
pFix->baselmg_sel = 1;
}
if (pdyn->sharpOpt.sw_sharpT_bwEdgClipIdx_mode == sharp_lpfPix_mode) {
pFix->clipldx_sel = 1;
} else {
pFix->clipldx_sel = 0;
}
pFix->tex2wgt_en = pdyn->sharpOpt.hw_sharpT_texShpSclRemap_en;
// SHARP_RATIO (0x0004)
tmp = (int)ROUND_F(pdyn->hfExtra_preBifilt.hw_sharpT_bifiltOut_alpha / fPercent *
(1 << RK_SHARP_V34_BF_RATIO_FIX_BITS));
pFix->pre_bifilt_alpha = CLIP(tmp, 0, 0x80);
tmp = (int)ROUND_F(pdyn->hfExtra_lpf.hw_sharpT_lpfOut_alpha / fPercent *
(1 << RK_SHARP_V34_GAUS_RATIO_FIX_BITS));
pFix->guide_filt_alpha = CLIP(tmp, 0, 0x80);
tmp = (int)ROUND_F(pdyn->hfExtra_hfBifilt.hw_sharpT_biFiltOut_alpha / fPercent *
(1 << RK_SHARP_V34_BF_RATIO_FIX_BITS));
pFix->detail_bifilt_alpha = CLIP(tmp, 0, 0x80);
tmp = (int)ROUND_F((pdyn->sharpOpt.hw_sharpT_hfHiGlbShpScl_val + pdyn->sharpOpt.hw_sharpT_hfMidGlbShpScl_val) *
fPercent * (1 << RK_SHARP_V34_SHARP_STRG_FIX_BITS));
pFix->global_sharp_strg = CLIP(tmp, 0, 127);
// SHARP_LUMA_DX (0x0008)
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM - 1; i++) {
tmp = (int16_t)LOG2(pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.idx[i + 1] -
pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.idx[i]);
pFix->luma2table_idx[i] = CLIP(tmp, 0, 15);
}
// SHARP_PBF_SIGMA_INV_0 (0x000c - 0x0014)
// pre bf sigma inv
int sigma_deci_bits = 9;
int sigma_inte_bits = 1;
int max_val = 0;
int min_val = 65536;
int shf_bits = 0;
short sigma_bits[3];
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
int cur_sigma =
FLOOR((pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.val[i] * pdyn->hfExtra_preBifilt.sw_sharpT_rgeSgm_scale +
pdyn->hfExtra_preBifilt.sw_sharpT_rgeSgm_offset) /
fPercent);
if (max_val < cur_sigma) max_val = cur_sigma;
if (min_val > cur_sigma) min_val = cur_sigma;
}
sigma_bits[0] = FLOOR(log((float)min_val) / log((float)2));
sigma_bits[1] = MAX(sigma_inte_bits - sigma_bits[0], 0);
sigma_bits[2] = sigma_deci_bits + sigma_bits[0];
pbf_sigma_shift = sigma_bits[2] - 5;
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
tmp = (int16_t)ROUND_F(
1.0f /
(pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.val[i] * pdyn->hfExtra_preBifilt.sw_sharpT_rgeSgm_scale +
pdyn->hfExtra_preBifilt.sw_sharpT_rgeSgm_offset) *
fPercent * (1 << sigma_bits[2]));
pFix->pbf_sigma_inv[i] = CLIP(tmp, 0, 4095);
}
// SHARP_BF_SIGMA_INV_0 (0x0018 - 0x0020)
// bf sigma inv
sigma_deci_bits = 9;
sigma_inte_bits = 1;
max_val = 0;
min_val = 65536;
shf_bits = 0;
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
int cur_sigma =
FLOOR((pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.val[i] * pdyn->hfExtra_hfBifilt.sw_sharpT_rgeSgm_scale +
pdyn->hfExtra_hfBifilt.sw_sharpT_rgeSgm_offset) /
fPercent);
if (max_val < cur_sigma) max_val = cur_sigma;
if (min_val > cur_sigma) min_val = cur_sigma;
}
sigma_bits[0] = FLOOR(log((float)min_val) / log((float)2.0f));
sigma_bits[1] = MAX(sigma_inte_bits - sigma_bits[0], 0);
sigma_bits[2] = sigma_deci_bits + sigma_bits[0];
bf_sigma_shift = sigma_bits[2] - 5;
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
tmp = (int16_t)ROUND_F(
1.0f /
(pdyn->hfExtra_sgmEnv.sw_sharpC_luma2Sigma_curve.val[i] * pdyn->hfExtra_hfBifilt.sw_sharpT_rgeSgm_scale +
pdyn->hfExtra_hfBifilt.sw_sharpT_rgeSgm_offset) *
fPercent * (1 << sigma_bits[2]));
pFix->bf_sigma_inv[i] = CLIP(tmp, 0, 4095);
}
// SHARP_SIGMA_SHIFT (0x00024)
pFix->pbf_sigma_shift = CLIP(pbf_sigma_shift, 0, 15);
pFix->bf_sigma_shift = CLIP(bf_sigma_shift, 0, 15);
// EHF_TH (0x0028 - 0x0030)
for (int i = 0; i < 8; i++)
pFix->luma2strg_val[i] = CLIP(pdyn->shpScl_hf.hw_sharpT_luma2hfScl_val[i], 0, 1023);
// SHARP_SHARP_CLIP_HF (0x0034 - 0x003c)
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
tmp = (int)(pdyn->sharpOpt.hw_sharpT_luma2WhtEdg_maxLimit[i] * fPercent);
pFix->luma2posclip_val[i] = CLIP(tmp, 0, 1023);
}
// SHARP_SHARP_PBF_COEF (0x00040)
// filter coeff
// bf coeff
// rk_sharp_V34_pbfCoeff : [4], [1], [0]
float pre_bila_filter[3];
if (pdyn->hfExtra_preBifilt.sw_sharpT_filtCfg_mode == sharp_cfgByFiltStrg_mode) {
float dis_table_3x3[3] = {0.0, 1.0, 2.0};
double e = 2.71828182845905;
float sigma = pdyn->hfExtra_preBifilt.sw_sharpT_filtSpatial_strg;
float sum_gauss_coeff = 0.0;
for (int i = 0; i < 3; i++) {
float tmp = pow(e, -dis_table_3x3[i] / 2.0 / sigma / sigma);
pre_bila_filter[i] = tmp;
}
sum_gauss_coeff = pre_bila_filter[0] + 4 * pre_bila_filter[1] + 4 * pre_bila_filter[2];
for (int i = 0; i < 3; i++) {
pre_bila_filter[i] = pre_bila_filter[i] / sum_gauss_coeff;
}
} else {
for (int i = 0; i < 3; i++) {
pre_bila_filter[i] = pdyn->hfExtra_preBifilt.hw_sharpT_filtSpatial_wgt[i];
}
}
tmp = (int)ROUND_F(pre_bila_filter[0] * (1 << RK_SHARP_V34_PBFCOEFF_FIX_BITS));
pFix->pbf_coef0 = CLIP(tmp, 0, 127);
tmp = (int)ROUND_F(pre_bila_filter[1] * (1 << RK_SHARP_V34_PBFCOEFF_FIX_BITS));
pFix->pbf_coef1 = CLIP(tmp, 0, 127);
tmp = (int)ROUND_F(pre_bila_filter[2] * (1 << RK_SHARP_V34_PBFCOEFF_FIX_BITS));
pFix->pbf_coef2 = CLIP(tmp, 0, 127);
sum_coeff = pFix->pbf_coef0 + 4 * pFix->pbf_coef1 + 4 * pFix->pbf_coef2;
offset = (1 << RK_SHARP_V34_PBFCOEFF_FIX_BITS) - sum_coeff;
tmp = (int)(pFix->pbf_coef0 + offset);
pFix->pbf_coef0 = CLIP(tmp, 0, 127);
// SHARP_SHARP_BF_COEF (0x00044)
// rk_sharp_V34_rfCoeff : [4], [1], [0]
float bila_filter[3];
if (pdyn->hfExtra_hfBifilt.sw_sharpT_filtCfg_mode == sharp_cfgByFiltStrg_mode) {
float dis_table_3x3[3] = {0.0, 1.0, 2.0};
double e = 2.71828182845905;
float sigma = pdyn->hfExtra_hfBifilt.sw_sharpT_filtSpatial_strg;
float sum_gauss_coeff = 0.0;
for (int i = 0; i < 3; i++) {
float tmp = pow(e, -dis_table_3x3[i] / 2.0 / sigma / sigma);
bila_filter[i] = tmp;
}
sum_gauss_coeff = bila_filter[0] + 4 * bila_filter[1] + 4 * bila_filter[2];
for (int i = 0; i < 3; i++) {
bila_filter[i] = bila_filter[i] / sum_gauss_coeff;
}
} else {
for (int i = 0; i < 3; i++) {
bila_filter[i] = pdyn->hfExtra_hfBifilt.hw_sharpT_filtSpatial_wgt[i];
}
}
tmp = (int)ROUND_F(bila_filter[0] * (1 << RK_SHARP_V34_RFCOEFF_FIX_BITS));
pFix->bf_coef0 = CLIP(tmp, 0, 127);
tmp = (int)ROUND_F(bila_filter[1] * (1 << RK_SHARP_V34_RFCOEFF_FIX_BITS));
pFix->bf_coef1 = CLIP(tmp, 0, 127);
tmp = (int)ROUND_F(bila_filter[2] * (1 << RK_SHARP_V34_RFCOEFF_FIX_BITS));
pFix->bf_coef2 = CLIP(tmp, 0, 127);
sum_coeff = pFix->bf_coef0 + 4 * pFix->bf_coef1 + 4 * pFix->bf_coef2;
offset = (1 << RK_SHARP_V34_PBFCOEFF_FIX_BITS) - sum_coeff;
tmp = (int)(pFix->bf_coef0 + offset);
pFix->bf_coef0 = CLIP(tmp, 0, 127);
float kernel0_ratio = pdyn->sharpOpt.hw_sharpT_hfHiGlbShpScl_val /
(pdyn->sharpOpt.hw_sharpT_hfHiGlbShpScl_val + pdyn->sharpOpt.hw_sharpT_hfMidGlbShpScl_val);
float kernel1_ratio = pdyn->sharpOpt.hw_sharpT_hfMidGlbShpScl_val /
(pdyn->sharpOpt.hw_sharpT_hfHiGlbShpScl_val + pdyn->sharpOpt.hw_sharpT_hfMidGlbShpScl_val);
if (pdyn->hfExtra_lpf.sw_sharpT_filtCfg_mode == sharp_cfgBy2SwLpfStrg_mode) {
float dis_table_5x5[6] = {0.0f, 1.0f, 2.0f, 4.0f, 5.0f, 8.0f};
float dis_table_3x3[6] = {0.0f, 1.0f, 2.0f, 1000.0f, 1000.0f, 1000.0f};
float gaus_table[6];
float gaus_table1[6];
float gaus_table_combine[6];
float sigma = pdyn->hfExtra_lpf.sw_sharpT_hfHi_strg;
float sigma1 = pdyn->hfExtra_lpf.sw_sharpT_hfMid_strg;
double e = 2.71828182845905;
for (int k = 0; k < 6; k++) {
float tmp0 = pow(e, -dis_table_3x3[k] / 2.0 / sigma / sigma);
gaus_table[k] = tmp0;
}
for (int k = 0; k < 6; k++) {
float tmp1 = pow(e, -dis_table_5x5[k] / 2.0 / sigma1 / sigma1);
gaus_table1[k] = tmp1;
}
float sumTable = 0;
sumTable = gaus_table[0] + 4 * gaus_table[1] + 4 * gaus_table[2] + 4 * gaus_table[3] +
8 * gaus_table[4] + 4 * gaus_table[5];
float sumTable1 = 0;
sumTable1 = gaus_table1[0] + 4 * gaus_table1[1] + 4 * gaus_table1[2] + 4 * gaus_table1[3] +
8 * gaus_table1[4] + 4 * gaus_table1[5];
for (int k = 0; k < 6; k++) {
// gaus_table[k] = gaus_table[k] / sumTable;
gaus_table_combine[k] = kernel0_ratio * gaus_table[k] / sumTable +
kernel1_ratio * gaus_table1[k] / sumTable1;
pFix->img_lpf_coeff[k] =
ROUND_F(gaus_table_combine[k] * (1 << RK_SHARP_V34_HBFCOEFF_FIX_BITS));
}
} else {
for (int k = 0; k < 6; k++) {
float range_coeff = pdyn->hfExtra_lpf.hw_sharpT_lpf_wgt[k];
pFix->img_lpf_coeff[k] =
ROUND_F(range_coeff * (1 << RK_SHARP_V34_HBFCOEFF_FIX_BITS));
}
}
sum_coeff = pFix->img_lpf_coeff[0] + 4 * pFix->img_lpf_coeff[1] + 4 * pFix->img_lpf_coeff[2] +
4 * pFix->img_lpf_coeff[3] + 8 * pFix->img_lpf_coeff[4] +
4 * pFix->img_lpf_coeff[5];
offset = (1 << RK_SHARP_V34_RFCOEFF_FIX_BITS) - sum_coeff;
tmp = (int)(pFix->img_lpf_coeff[0] + offset);
pFix->img_lpf_coeff[0] = CLIP(tmp, 0, 127);
// gain
tmp = pdyn->shpScl_locSgmStrg.hw_sharpT_glbSgmStrg_val * (1 << RK_SHARP_V34_GLOBAL_GAIN_FIX_BITS);
pFix->global_gain = CLIP(tmp, 0, 1023);
tmp = pdyn->shpScl_locSgmStrg.hw_sharpT_glbSgmStrg_alpha * (1 << RK_SHARP_V34_GLOBAL_GAIN_ALPHA_FIX_BITS);
pFix->gain_merge_alpha = CLIP(tmp, 0, 8);
tmp = pdyn->shpScl_locSgmStrg.hw_sharpT_localSgmStrg_scale * (1 << RK_SHARP_V34_LOCAL_GAIN_SACLE_FIX_BITS);
pFix->local_gain_scale = CLIP(tmp, 0, 128);
// gain adjust strength
for (int i = 0; i < RK_SHARP_V34_SHARP_ADJ_GAIN_TABLE_LEN; i++) {
tmp = ROUND_F(pdyn->sharpOpt.hw_sharpT_locSgmStrg2ShpScl_val[i] * (1 << RK_SHARP_V34_ADJ_GAIN_FIX_BITS));
pFix->gain2strg_val[i] = CLIP(tmp, 0, 16384);
}
// CENTER
tmp = cols / 2;
pFix->center_x = CLIP(tmp, 0, 8191);
tmp = rows / 2;
pFix->center_y = CLIP(tmp, 0, 8191);
// gain dis strength
for (int i = 0; i < RK_SHARP_V34_STRENGTH_TABLE_LEN; i++) {
tmp = ROUND_F(pdyn->sharpOpt.hw_sharpT_radiDist2ShpScl_val[i] *
(1 << RK_SHARP_V34_STRENGTH_TABLE_FIX_BITS));
pFix->distance2strg_val[i] = CLIP(tmp, 0, 128);
}
// SHARP_SHARP_CLIP_NEG (0x008c - 0x0094)
for (int i = 0; i < RK_SHARP_V34_LUMA_POINT_NUM; i++) {
tmp = (int)(pdyn->sharpOpt.hw_sharpT_luma2BkEdg_maxLimit[i] * fPercent);
pFix->luma2neg_clip_val[i] = CLIP(tmp, 0, 1023);
}
// TEXTURE0
tmp = ROUND_F(pdyn->shpScl_texDetect.hw_sharpT_estNsManual_maxLimit);
pFix->noise_max_limit = CLIP(tmp, 0, 1023);
// TEXTURE1
pFix->noise_norm_bit = pdyn->shpScl_texDetect.hw_sharpT_estNsNorize_shift;
pFix->tex_wgt_mode = pdyn->sharpOpt.hw_sharpT_shpOpt_mode;
float tex_coef = pdyn->sharpOpt.hw_sharpT_tex2ShpScl_scale;
int tex_reserve_level = 0;
if (tex_coef >= 16 && tex_coef <= 31)
tex_reserve_level = 0;
else if (tex_coef >= 8 && tex_coef < 16)
tex_reserve_level = 1;
else if (tex_coef >= 4 && tex_coef < 8)
tex_reserve_level = 2;
else if (tex_coef >= 2 && tex_coef < 4)
tex_reserve_level = 3;
else if (tex_coef >= 1 && tex_coef < 2)
tex_reserve_level = 4;
else if (tex_coef >= 0.5 && tex_coef < 1)
tex_reserve_level = 5;
else if (tex_coef >= 0.25 && tex_coef < 0.5)
tex_reserve_level = 6;
else if (tex_coef >= 0.125 && tex_coef < 0.25)
tex_reserve_level = 7;
else if (tex_coef >= 0.0625 && tex_coef < 0.125)
tex_reserve_level = 8;
else if (tex_coef >= 0.03125 && tex_coef < 0.0625)
tex_reserve_level = 9;
else if (tex_coef < 0.03125)
tex_reserve_level = 10;
pFix->tex_reserve_level = tex_reserve_level;
tmp = ROUND_F(tex_coef * (1 << (tex_reserve_level + RK_SHARP_V34_TEX_FIX_BITS)));
pFix->tex_wet_scale = CLIP(tmp, 0, 31 * (1 << RK_SHARP_V34_TEX_FIX_BITS));
// TEXTURE_LUT
for (int i = 0; i < 17; i++) {
pFix->tex2wgt_val[i] = pdyn->sharpOpt.hw_sharpT_texShpSclRemap_val[i];
}
// TEXTURE2
tmp = ROUND_F(pdyn->shpScl_texDetect.hw_sharpT_estNs_scale * (1 << RK_SHARP_V34_ADJ_GAIN_FIX_BITS));
pFix->noise_strg = CLIP(tmp, 0, 16383);
for (int i = 0; i < 17; i++) pFix->detail2strg_val[i] = pdyn->sharpOpt.hw_sharpT_hfScl2ShpScl_val[i];
return;
}