/* * WARNING: unlike commit_params, which is thread safe wrt gui thread and * pipes, this function lives in the pipeline thread, and NOT thread safe! */ static void commit_params_late(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece) { dt_iop_exposure_data_t *d = (dt_iop_exposure_data_t *)piece->data; dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; if(d->mode == EXPOSURE_MODE_DEFLICKER) { if(g && piece->pipe->type == DT_DEV_PIXELPIPE_FULL) { dt_pthread_mutex_lock(&g->lock); d->exposure = g->deflicker_computed_exposure; dt_pthread_mutex_unlock(&g->lock); } if(piece->pipe->type == DT_DEV_PIXELPIPE_PREVIEW || isnan(d->exposure)) { compute_correction(self, piece, piece->histogram, &piece->histogram_stats, &d->exposure); } } if(g && piece->pipe->type == DT_DEV_PIXELPIPE_PREVIEW) { dt_pthread_mutex_lock(&g->lock); g->deflicker_computed_exposure = d->exposure; dt_pthread_mutex_unlock(&g->lock); } }
/* * WARNING: unlike commit_params, which is thread safe wrt gui thread and * pipes, this function lives in the pipeline thread, and NOT thread safe! */ static void commit_params_late (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece) { dt_iop_exposure_data_t *d = (dt_iop_exposure_data_t *)piece->data; if(d->mode == EXPOSURE_MODE_DEFLICKER) { compute_correction(self, piece, self->histogram, &self->histogram_stats, &d->exposure); } }
static void deflicker_process (dt_iop_module_t *self) { if(!(self->dev->image_storage.flags & DT_IMAGE_RAW)) return; dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)self->params; float correction; if(p->deflicker && !compute_correction(self, &correction)) exposure_set_white(self, exposure2white(correction)); }
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece) { dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)p1; dt_iop_exposure_data_t *d = (dt_iop_exposure_data_t *)piece->data; dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; d->black = p->black; d->exposure = p->exposure; piece->request_histogram &= ~(DT_REQUEST_ON); piece->request_histogram |= (DT_REQUEST_ONLY_IN_GUI); d->deflicker_percentile = p->deflicker_percentile; d->deflicker_target_level = p->deflicker_target_level; if(p->mode == EXPOSURE_MODE_DEFLICKER && dt_image_is_raw(&self->dev->image_storage)) { if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_SOURCEFILE) { if(g) { // histogram is precomputed and cached compute_correction(self, piece, g->deflicker_histogram, &g->deflicker_histogram_stats, &d->exposure); } else { uint32_t *histogram = NULL; dt_dev_histogram_stats_t histogram_stats; deflicker_prepare_histogram(self, &histogram, &histogram_stats); compute_correction(self, piece, histogram, &histogram_stats, &d->exposure); free(histogram); } d->mode = EXPOSURE_MODE_MANUAL; } else { if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_THUMBNAIL) { d->mode = EXPOSURE_MODE_DEFLICKER; piece->request_histogram |= (DT_REQUEST_ON); if(!self->dev->gui_attached) piece->request_histogram &= ~(DT_REQUEST_ONLY_IN_GUI); piece->histogram_params.bins_count = 16384; /* * in principle, we do not need/want histogram in FULL pipe * because we will use histogram from preview pipe there, * but it might happen that for some reasons we do not have * histogram of preview pipe yet - e.g. on first pipe run * (just after setting mode to automatic) */ d->exposure = NAN; // commit_params_late() will compute exposure later } } } else { d->mode = EXPOSURE_MODE_MANUAL; } }
void commit_params (struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece) { dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)p1; dt_iop_exposure_data_t *d = (dt_iop_exposure_data_t *)piece->data; dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data; d->black = p->black; d->exposure = p->exposure; self->request_histogram &= ~(DT_REQUEST_ON); self->request_histogram |= (DT_REQUEST_ONLY_IN_GUI); self->request_histogram_source = (DT_DEV_PIXELPIPE_PREVIEW); if(self->dev->gui_attached) { g->reprocess_on_next_expose = FALSE; } gboolean histogram_is_good = ((self->histogram_stats.bins_count == 16384) && (self->histogram != NULL)); d->deflicker_percentile = p->deflicker_percentile; d->deflicker_target_level = p->deflicker_target_level; if(p->mode == EXPOSURE_MODE_DEFLICKER && dt_image_is_raw(&self->dev->image_storage)) { if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_SOURCEFILE) { if(self->dev->gui_attached) { // histogram is precomputed and cached compute_correction(self, piece, g->deflicker_histogram, &g->deflicker_histogram_stats, &d->exposure); } else { uint32_t *histogram = NULL; dt_dev_histogram_stats_t histogram_stats; deflicker_prepare_histogram(self, &histogram, &histogram_stats); compute_correction(self, piece, histogram, &histogram_stats, &d->exposure); free(histogram); } d->mode = EXPOSURE_MODE_MANUAL; } else { if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_THUMBNAIL) { self->request_histogram |= (DT_REQUEST_ON); gboolean failed = !histogram_is_good; if(self->dev->gui_attached && histogram_is_good) { /* * if in GUI, user might zoomed main view => we would get histogram of * only part of image, so if in GUI we must always use histogram of * preview pipe, which is always full-size and have biggest size */ d->mode = EXPOSURE_MODE_DEFLICKER; commit_params_late(self, piece); d->mode = EXPOSURE_MODE_MANUAL; if(isnan(d->exposure)) failed = TRUE; } else if(failed || !(self->dev->gui_attached && histogram_is_good)) { d->mode = EXPOSURE_MODE_DEFLICKER; //commit_params_late() will compute correct d->exposure later self->request_histogram &= ~(DT_REQUEST_ONLY_IN_GUI); self->request_histogram_source = (DT_DEV_PIXELPIPE_ANY); if(failed && self->dev->gui_attached) { /* * but sadly we do not yet have a histogram to do so, so this time * we process asif not in gui, and in expose() immediately * reprocess, thus everything works as expected */ g->reprocess_on_next_expose = TRUE; } } } } } else { d->mode = EXPOSURE_MODE_MANUAL; } }