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;

Reply via email to