/*=========================================================================== FUNCTION isp_tintless_close DESCRIPTION close the library and free all allocated memory ===========================================================================*/ static tintless_return_t isp_tintless_close(void ** const res) { tintless_return_t rc = TINTLESS_SUCCESS; tintless_lib_t * tintless_lib = NULL; CDBG_TINTLESS("%s: Enter\n",__func__); if (res != NULL) tintless_lib = (tintless_lib_t *) *res; if (tintless_lib) { CDBG_TINTLESS("%s: tint_lib %p, deinit_func %p \n", __func__, tintless_lib, tintless_lib->deinit_func); if (tintless_lib->deinit_func) { tintless_lib->deinit_func(&tintless_lib->dmlroc_res); } if (tintless_lib->plib) { dlclose(tintless_lib->plib); } free(*res); *res = NULL; } else { rc = TINTLESS_LIB_NOT_LOADED; } CDBG_TINTLESS("%s: close/unload tintless lib %d", __func__, rc); return rc; } /* isp_tintless_close */
/*=========================================================================== FUNCTION isp_tintless_stat_config DESCRIPTION Update the stat params for the tintless algo. Should be called after the BG stat config has been called. ===========================================================================*/ static tintless_return_t isp_tintless_bg_pca_stat_config(void * const res, tintless_stats_config_t * cfg) { tintless_return_t rc; tintless_cfg_t c; tintless_lib_t * const tintless_lib = (tintless_lib_t *) res; CDBG_TINTLESS("%s: Enter \n", __func__); CDBG_TINTLESS("%s: stats : camif hxw %d x %d, hxw %d x %d, type %d",__func__, cfg->camif_win_h, cfg->camif_win_w, cfg->stat_elem_h, cfg->stat_elem_w, cfg->stats_type); if (tintless_lib == NULL) { rc = TINTLESS_LIB_NOT_LOADED; } else { CDBG_ERROR("%s: pointer okay \n", __func__); c.stats = cfg; if (tintless_lib->updates & ( 1 << UPDATES_STAT_CONFIG)) { rc = isp_tintless_config(tintless_lib, UPDATES_STAT_CONFIG, c); CDBG_ERROR("%s: lib returned config err=%d", __func__, rc); } else { CDBG_ERROR("%s: Stat cfg updates not needed", __func__); rc = TINTLESS_UPDATES_NOT_SUPPORTED; } } return rc; } /* isp_tintless_stat_config */
/*=========================================================================== FUNCTION isp_tintless_update_chromatix_params DESCRIPTION Update the tintless related chromatix tuning parameters. ===========================================================================*/ static tintless_return_t isp_tintless_update_chromatix_params( void * const res, chromatix_color_tint_correction_type * p) { tintless_return_t rc; tintless_cfg_t param; tintless_lib_t * const tintless_lib = (tintless_lib_t *) res; CDBG_TINTLESS("%s: chromatix : strength %d",__func__, p->tint_correction_strength); if (tintless_lib == NULL || tintless_lib->init_func == NULL) { rc = TINTLESS_LIB_NOT_LOADED; } else { param.chromatix = p; if (tintless_lib->updates & ( 1 << UPDATES_CHROMATIX_PARAMS)) { rc = isp_tintless_config(tintless_lib, UPDATES_CHROMATIX_PARAMS, param); CDBG_ERROR("%s: lib returned config err=%d", __func__, rc); } else { CDBG_ERROR("%s: chromatix parameter updates not needed", __func__); rc = TINTLESS_UPDATES_NOT_SUPPORTED; } } return rc; } /* isp_tintless_update_chromatix_params */
/*=========================================================================== FUNCTION isp_tintless_mesh_config DESCRIPTION Update the stat params for the tintless algo. Should be called after the BG stat config has been called. ===========================================================================*/ static tintless_return_t isp_tintless_mesh_config(void * const res, tintless_mesh_config_t * cfg) { tintless_return_t rc; tintless_cfg_t c; tintless_lib_t * const tintless_lib = (tintless_lib_t *) res; CDBG_TINTLESS("%s: mesh : col, row %d ,%d offset h,v %d,%d, SG hxw %d x %d, subgrids %d",__func__, cfg->num_mesh_elem_cols, cfg->num_mesh_elem_rows, cfg->offset_horizontal, cfg->offset_vertical, cfg->subgrid_height, cfg->subgrid_width, cfg->subgrids); if (tintless_lib == NULL || tintless_lib->init_func == NULL) { rc = TINTLESS_LIB_NOT_LOADED; } else { c.mesh = cfg; if (tintless_lib->updates & ( 1 << UPDATES_MESH_CONFIG)) { rc = isp_tintless_config(tintless_lib, UPDATES_MESH_CONFIG, c); CDBG_ERROR("%s: lib returned mesh config err=%d", __func__, rc); } else { CDBG_ERROR("%s: Mesh cfg updates not needed", __func__); rc = TINTLESS_UPDATES_NOT_SUPPORTED; } } return rc; } /* isp_tintless_mesh_config */
/*=========================================================================== FUNCTION isp_tintless_algo DESCRIPTION calling the main algorithm for tintless processing ===========================================================================*/ static tintless_return_t isp_tintless_algo(void * const res, tintless_stats_t * be_stats, tintless_mesh_rolloff_array_t * ptable_3a, tintless_mesh_rolloff_array_t * ptable_cur, tintless_mesh_rolloff_array_t * const ptable_correction) { tintless_return_t rc; tintless_lib_t * const tintless_lib = (tintless_lib_t *) res; dmlroc_mesh_rolloff_array_t p_tbl_3a; dmlroc_mesh_rolloff_array_t p_tbl_correction; dmlroc_bayer_stats_info_t pbayer_r, pbayer_gr, pbayer_gb, pbayer_b; CDBG_TINTLESS("%s: Enter !\n", __func__); if (tintless_lib == NULL || tintless_lib->update_func == NULL) { rc = TINTLESS_LIB_NOT_LOADED; } else { p_tbl_3a.table_size = MESH_ROLL_OFF_V4_TABLE_SIZE; p_tbl_3a.r_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_3a->r_gain; p_tbl_3a.gr_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_3a->gr_gain; p_tbl_3a.gb_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_3a->gb_gain; p_tbl_3a.b_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_3a->b_gain; p_tbl_correction.table_size = MESH_ROLL_OFF_V4_TABLE_SIZE; p_tbl_correction.r_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_correction->r_gain; p_tbl_correction.gr_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_correction->gr_gain; p_tbl_correction.gb_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_correction->gb_gain; p_tbl_correction.b_gain = (float (*)[DMLROC_MESH_ROLLOFF_WIDTH])ptable_correction->b_gain; pbayer_r.channel_counts = be_stats->r.channel_counts; pbayer_r.channel_sums = be_stats->r.channel_sums; pbayer_r.array_length = be_stats->r.array_length; pbayer_gr.channel_counts = be_stats->gr.channel_counts; pbayer_gr.channel_sums = be_stats->gr.channel_sums; pbayer_gr.array_length = be_stats->gr.array_length; pbayer_gb.channel_counts = be_stats->gb.channel_counts; pbayer_gb.channel_sums = be_stats->gb.channel_sums; pbayer_gb.array_length = be_stats->gb.array_length; pbayer_b.channel_counts = be_stats->b.channel_counts; pbayer_b.channel_sums = be_stats->b.channel_sums; pbayer_b.array_length = be_stats->b.array_length; rc = translate_return_code( tintless_lib->update_func(tintless_lib->dmlroc_res, &pbayer_r, &pbayer_gr, &pbayer_gb, &pbayer_b, NULL, &p_tbl_3a, &p_tbl_correction)); } if (rc != TINTLESS_SUCCESS) { CDBG_ERROR("%s: dmlroCorrection returned err=%d", __func__, rc); } return rc; } /* isp_tintless_algo */
/*=========================================================================== FUNCTION isp_tintless_algo DESCRIPTION calling the main algorithm for tintless processing ===========================================================================*/ static tintless_return_t isp_tintless_bg_pca_algo(void * const res, tintless_stats_t * bg_stats, tintless_mesh_rolloff_array_t * ptable_3a, tintless_mesh_rolloff_array_t * ptable_cur, tintless_mesh_rolloff_array_t * const ptable_correction) { tintless_return_t rc; tintless_lib_t * const tintless_lib = (tintless_lib_t *) res; mesh_rolloff_array_t p_tbl_3a; mesh_rolloff_array_t p_tbl_correction; bayer_grid_stats_info_t pbayer_r, pbayer_gr, pbayer_gb, pbayer_b; CDBG_TINTLESS("%s: Enter !\n", __func__); if (tintless_lib == NULL || tintless_lib->update_func == NULL) { rc = TINTLESS_LIB_NOT_LOADED; } else { pbayer_r.channel_counts = bg_stats->r.channel_counts; pbayer_r.channel_sums = bg_stats->r.channel_sums; pbayer_r.array_length = bg_stats->r.array_length; pbayer_gr.channel_counts = bg_stats->gr.channel_counts; pbayer_gr.channel_sums = bg_stats->gr.channel_sums; pbayer_gr.array_length = bg_stats->gr.array_length; pbayer_gb.channel_counts = bg_stats->gb.channel_counts; pbayer_gb.channel_sums = bg_stats->gb.channel_sums; pbayer_gb.array_length = bg_stats->gb.array_length; pbayer_b.channel_counts = bg_stats->b.channel_counts; pbayer_b.channel_sums = bg_stats->b.channel_sums; pbayer_b.array_length = bg_stats->b.array_length; rc = translate_return_code( tintless_lib->update_func(&pbayer_r, &pbayer_gr, &pbayer_gb, &pbayer_b, (mesh_rolloff_array_t *)ptable_cur, (mesh_rolloff_array_t *)ptable_3a, (mesh_rolloff_array_t *)ptable_correction)); } if (rc != TINTLESS_SUCCESS) { CDBG_ERROR("%s: dmlroCorrection returned err=%d", __func__, rc); } return rc; } /* isp_tintless_algo */
/*=========================================================================== FUNCTION isp_tintless_open DESCRIPTION ===========================================================================*/ static tintless_return_t isp_tintless_open(void ** const res, uint32_t * updates_needed) { tintless_return_t rc = TINTLESS_LIB_NOT_LOADED; dmlroc_version_t v; tintless_lib_t * tintless_lib = NULL; tintless_lib_t ** pp_tintless; char lib_name[BUFF_SIZE_255] = { 0 }; CDBG_TINTLESS("%s : Enter!\n", __func__); if (res != NULL){ pp_tintless = (tintless_lib_t **)res; } else { CDBG_ERROR("%s : res pointer NULL!\n", __func__); goto ERROR; } *pp_tintless = (tintless_lib_t *) malloc(sizeof (tintless_lib_t)); if (*pp_tintless == NULL) { rc = TINTLESS_NO_MEMORY; goto ERROR; } tintless_lib = (tintless_lib_t *) *pp_tintless; memset(tintless_lib, 0, sizeof(tintless_lib_t)); strlcpy(lib_name, "libmmcamera_tintless_algo.so", BUFF_SIZE_255); dlerror(); tintless_lib->plib = dlopen(lib_name, RTLD_NOW); if (!tintless_lib->plib) { CDBG_ERROR("%s:Failed to dlopen %s: %s", __func__, lib_name, dlerror()); goto ERROR; } *(void **)&(tintless_lib->init_func) = dlsym(tintless_lib->plib, "dmlroc_init"); if (!tintless_lib->init_func) CDBG_ERROR("%s:init Failed to dlsym %s: %s", __func__, lib_name, dlerror()); *(void **)&(tintless_lib->update_func) = dlsym(tintless_lib->plib, "dmlroc_entry"); if (!tintless_lib->update_func) CDBG_ERROR("%s:update Failed to dlsym %s: %s", __func__, lib_name, dlerror()); *(void **)&(tintless_lib->get_version_func) = dlsym(tintless_lib->plib, "dmlroc_get_version"); if (!tintless_lib->get_version_func) CDBG_ERROR("%s:version Failed to dlsym %s: %s", __func__, lib_name, dlerror()); *(void **)&(tintless_lib->deinit_func) = dlsym(tintless_lib->plib, "dmlroc_deinit"); if (!tintless_lib->deinit_func) CDBG_ERROR("%s:deinit Failed to dlsym %s: %s", __func__, lib_name, dlerror()); if (!tintless_lib->init_func || !tintless_lib->update_func || !tintless_lib->get_version_func || !tintless_lib->deinit_func) { CDBG_ERROR("%s:Failed to dlsym %s: %s", __func__, lib_name, dlerror()); goto ERROR; } // subscribe to cfg updates *updates_needed = (TINTLESS_UPDATE_STATS | TINTLESS_UPDATE_MESH | TINTLESS_UPDATE_CHROMATIX_PARAMS); tintless_lib->updates = *updates_needed; tintless_lib->cfg.tint_correction_strength = UINT8_MAX; return TINTLESS_SUCCESS; ERROR: if (tintless_lib != NULL) { if (tintless_lib->plib) { dlclose(tintless_lib->plib); } free(tintless_lib); *pp_tintless = NULL; } return rc; } /* isp_tintless_open */