static void temp_changed(dt_iop_module_t *self) { dt_iop_temperature_gui_data_t *g = (dt_iop_temperature_gui_data_t *)self->gui_data; dt_iop_temperature_params_t *p = (dt_iop_temperature_params_t *)self->params; dt_iop_temperature_params_t *fp = (dt_iop_temperature_params_t *)self->default_params; const float temp_out = dt_bauhaus_slider_get(g->scale_k_out); const float temp_in = dt_bauhaus_slider_get(g->scale_k); const float tint = dt_bauhaus_slider_get(g->scale_tint); float original_temperature_rgb[3], intended_temperature_rgb[3]; convert_k_to_rgb (temp_in, original_temperature_rgb); convert_k_to_rgb (temp_out, intended_temperature_rgb); p->temp_out = temp_out; p->coeffs[0] = fp->coeffs[0] * intended_temperature_rgb[0] / original_temperature_rgb[0]; p->coeffs[1] = fp->coeffs[1] * tint * intended_temperature_rgb[1] / original_temperature_rgb[1]; p->coeffs[2] = fp->coeffs[2] * intended_temperature_rgb[2] / original_temperature_rgb[2]; // normalize: p->coeffs[0] /= p->coeffs[1]; p->coeffs[2] /= p->coeffs[1]; p->coeffs[1] = 1.0f; darktable.gui->reset = 1; dt_bauhaus_slider_set(g->scale_r, p->coeffs[0]); dt_bauhaus_slider_set(g->scale_g, p->coeffs[1]); dt_bauhaus_slider_set(g->scale_b, p->coeffs[2]); darktable.gui->reset = 0; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void temp_changed(dt_iop_module_t *self) { dt_iop_temperature_gui_data_t *g = (dt_iop_temperature_gui_data_t *)self->gui_data; dt_iop_temperature_params_t *p = (dt_iop_temperature_params_t *)self->params; const float temp = dt_bauhaus_slider_get(g->scale_k); const float tint = dt_bauhaus_slider_get(g->scale_tint); convert_k_to_rgb(temp, p->coeffs); // apply green tint p->coeffs[1] /= tint; // relative to daylight wb: for(int k=0; k<3; k++) p->coeffs[k] = g->daylight_wb[k]/p->coeffs[k]; // normalize: p->coeffs[0] /= p->coeffs[1]; p->coeffs[2] /= p->coeffs[1]; p->coeffs[1] = 1.0f; darktable.gui->reset = 1; dt_bauhaus_slider_set(g->scale_r, p->coeffs[0]); dt_bauhaus_slider_set(g->scale_g, p->coeffs[1]); dt_bauhaus_slider_set(g->scale_b, p->coeffs[2]); darktable.gui->reset = 0; dt_dev_add_history_item(darktable.develop, self, TRUE); }
static gfloat * preprocess (GeglChantO *o) { gfloat *coeffs = g_new (gfloat, 3); gfloat original_temperature_rgb[3]; gfloat intended_temperature_rgb[3]; convert_k_to_rgb (o->original_temperature, original_temperature_rgb); convert_k_to_rgb (o->intended_temperature, intended_temperature_rgb); coeffs[0] = original_temperature_rgb[0] / intended_temperature_rgb[0]; coeffs[1] = original_temperature_rgb[1] / intended_temperature_rgb[1]; coeffs[2] = original_temperature_rgb[2] / intended_temperature_rgb[2]; return coeffs; }
// binary search inversion inspired by ufraw's RGB_to_Temperature: static void convert_rgb_to_k(float rgb[3], const float temp_out, float *temp, float *tint) { float tmin, tmax, tmp[3], original_temperature_rgb[3], intended_temperature_rgb[3]; for(int k=0; k<3; k++) tmp[k] = rgb[k]; tmin = DT_IOP_LOWEST_TEMPERATURE; tmax = DT_IOP_HIGHEST_TEMPERATURE; convert_k_to_rgb (temp_out, intended_temperature_rgb); for (*temp=(tmax+tmin)/2; tmax-tmin>1; *temp=(tmax+tmin)/2) { convert_k_to_rgb (*temp, original_temperature_rgb); tmp[0] = intended_temperature_rgb[0] / original_temperature_rgb[0]; tmp[1] = intended_temperature_rgb[1] / original_temperature_rgb[1]; tmp[2] = intended_temperature_rgb[2] / original_temperature_rgb[2]; if (tmp[2]/tmp[0] < rgb[2]/rgb[0]) tmax = *temp; else tmin = *temp; } *tint = (rgb[1]/rgb[0]) / (tmp[1]/tmp[0]); }
// binary search inversion inspired by ufraw's RGB_to_Temperature: static void convert_rgb_to_k(float rgb[3], float *temp, float *tint) { float tmin, tmax, tmp[3]; for(int k = 0; k < 3; k++) tmp[k] = rgb[k]; tmin = DT_IOP_LOWEST_TEMPERATURE; tmax = DT_IOP_HIGHEST_TEMPERATURE; for(*temp = (tmax + tmin) / 2; tmax - tmin > 1; *temp = (tmax + tmin) / 2) { convert_k_to_rgb(*temp, tmp); if(tmp[2] / tmp[0] > rgb[2] / rgb[0]) tmax = *temp; else tmin = *temp; } *tint = (tmp[1] / tmp[0]) / (rgb[1] / rgb[0]); if(*tint < 0.2f) *tint = 0.2f; if(*tint > 2.5f) *tint = 2.5f; }