Hi,
I love darktable, but the lens I use the most is never recognized by
automatically by the lens correction module. The result is that I have
to manually select my lens for every photo, which not particularly
enjoyable.
I thought this problem could be solved if the user's lens selection was
stored. That is, darktable could store the mapping from "camera+lens
exif string" to "camera+lens lensfun string" whenever the user selects a
lens explicitly. This could then be looked up if the lensfun search fails.
I've attached a patch file that implements this in a pretty simple way.
It seems to work for me (but I haven't done extensive testing).
The same thing could be done for the camera too, of course.
I'm curious to see what people think.
- Corey
___________________________________________________________________________
darktable developer mailing list
to unsubscribe send a mail to [email protected]
diff --git a/src/iop/lens.c b/src/iop/lens.c
index 84b41bd..b93df25 100644
--- a/src/iop/lens.c
+++ b/src/iop/lens.c
@@ -329,6 +329,54 @@ static char *_lens_sanitize(const char *orig_lens)
}
}
+static void _new_lens_make_model_strings(const dt_image_t * const img,
+ gchar ** const camera_lens_make_str,
+ gchar ** const camera_lens_model_str) {
+ /*
+ ** make new strings that are the exif of the lens make and model,
+ ** appended with "_make" and "_model". the two strings are intended
+ ** to be keys in the dt_conf to lookup the lensfun make and model
+ ** that the user chose.
+ **
+ ** caller should call g_free() on both strings.
+ */
+ if (img && camera_lens_make_str && camera_lens_model_str) {
+ char *new_lens = _lens_sanitize(img->exif_lens);
+ *camera_lens_make_str = g_strjoin("_", img->exif_model, new_lens,
+ "make", NULL);
+ *camera_lens_model_str = g_strjoin("_", img->exif_model, new_lens,
+ "model", NULL);
+ free(new_lens);
+ }
+}
+
+const lfLens** try_load_usersel_lens_from_conf(const dt_image_t * const img,
+ const lfCamera* cam,
+ lfDatabase *dt_iop_lensfun_db) {
+ /*
+ ** try to load a user selected lens from dt_conf using the exif lens info
+ **
+ ** caller should free with lf_free()
+ */
+ gchar *camera_lens_make_str = 0;
+ gchar *camera_lens_model_str = 0;
+ _new_lens_make_model_strings( img,
+ &camera_lens_make_str,
+ &camera_lens_model_str );
+ gchar *lfmake = dt_conf_get_string(camera_lens_make_str);
+ gchar *lfmodel = dt_conf_get_string(camera_lens_model_str);
+ g_free(camera_lens_make_str);
+ g_free(camera_lens_model_str);
+ const lfLens **lenslist = lf_db_find_lenses_hd(dt_iop_lensfun_db, cam,
+ lfmake[0] ? lfmake : NULL,
+ lfmodel[0] ? lfmodel : NULL,
+ 0);
+ //LF_SEARCH_SORT_AND_UNIQUIFY);
+ g_free(lfmake);
+ g_free(lfmodel);
+ return lenslist;
+}
+
void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid,
const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
{
@@ -1144,6 +1192,16 @@ void reload_defaults(dt_iop_module_t *module)
dt_pthread_mutex_unlock(&darktable.plugin_threadsafe);
}
+ if (!lens) {
+ const lfLens** ulenslist = try_load_usersel_lens_from_conf(img, cam[0],
+ gd->db);
+ if (ulenslist) {
+ lens = ulenslist;
+ } else {
+ lf_free(ulenslist);
+ }
+ }
+
if(lens)
{
int lens_i = 0;
@@ -1766,7 +1824,21 @@ static void lens_menu_select(GtkMenuItem *menuitem, gpointer user_data)
dt_iop_module_t *self = (dt_iop_module_t *)user_data;
dt_iop_lensfun_gui_data_t *g = (dt_iop_lensfun_gui_data_t *)self->gui_data;
dt_iop_lensfun_params_t *p = (dt_iop_lensfun_params_t *)self->params;
- lens_set(self, (lfLens *)g_object_get_data(G_OBJECT(menuitem), "lfLens"));
+ const lfLens *l = (lfLens *)g_object_get_data(G_OBJECT(menuitem), "lfLens");
+ lens_set(self, l);
+ /* store the selected lens in the conf for lookup next time */
+ const dt_image_t * const img = &self->dev->image_storage;
+ if (img) {
+ gchar *camera_lens_make_str = 0;
+ gchar *camera_lens_model_str = 0;
+ _new_lens_make_model_strings(img,
+ &camera_lens_make_str,
+ &camera_lens_model_str);
+ dt_conf_set_string(camera_lens_make_str, l->Maker);
+ dt_conf_set_string(camera_lens_model_str, l->Model);
+ g_free(camera_lens_make_str);
+ g_free(camera_lens_model_str);
+ }
if(darktable.gui->reset) return;
p->modified = 1;
const float scale = get_autoscale(self, p, g->camera);
@@ -2281,8 +2353,16 @@ void gui_update(struct dt_iop_module_t *self)
model[0] ? model : NULL, 0);
if(lenslist)
lens_set(self, lenslist[0]);
- else
- lens_set(self, NULL);
+ else {
+ const lfLens** ulenslist = try_load_usersel_lens_from_conf(
+ &(self->dev->image_storage), g->camera, dt_iop_lensfun_db);
+ if (ulenslist) {
+ lens_set(self, ulenslist[0]);
+ } else {
+ lens_set(self, NULL);
+ }
+ lf_free(ulenslist);
+ }
lf_free(lenslist);
dt_pthread_mutex_unlock(&darktable.plugin_threadsafe);
}
@@ -2314,6 +2394,7 @@ void gui_cleanup(struct dt_iop_module_t *self)
self->gui_data = NULL;
}
+
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;