Update of /cvsroot/ufraw/ufraw In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv21626
Modified Files: uf_gtk.cc uf_gtk.h ufobject.cc ufobject.h ufraw.h ufraw_conf.c ufraw_lens_ui.c ufraw_lensfun.cc ufraw_settings.cc ufraw_ufraw.c Log Message: Add ufCameraModel, ufLensModel, ufLenfunAuto. Add global reset and auto buttons to the lensfun page. Index: ufobject.cc =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufobject.cc,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- ufobject.cc 2 Mar 2010 20:06:09 -0000 1.7 +++ ufobject.cc 4 Mar 2010 04:52:32 -0000 1.8 @@ -739,6 +739,7 @@ } } _UFGROUP_PARENT(object) = ufgroup; + Event(uf_element_added); return *this; } @@ -884,6 +885,7 @@ } } _UFARRAY_PARENT(object) = ufgroup; + Event(uf_element_added); return *this; } @@ -1001,6 +1003,15 @@ } } +UFBoolean ufstring_is_equal(UFObject *object, const char *string) { + try { + return dynamic_cast<UFString *>(object)->IsEqual(string); + } catch (std::bad_cast &e) { + object->Message(e.what()); + return false; + } +} + UFBoolean ufgroup_has(UFObject *object, UFName name) { try { return dynamic_cast<UFGroup *>(object)->Has(name); Index: uf_gtk.cc =================================================================== RCS file: /cvsroot/ufraw/ufraw/uf_gtk.cc,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- uf_gtk.cc 26 Feb 2010 07:01:04 -0000 1.20 +++ uf_gtk.cc 4 Mar 2010 04:52:32 -0000 1.21 @@ -360,6 +360,8 @@ return; _UFObjectList *list = static_cast<_UFObjectList *>( g_object_get_data(G_OBJECT(data->button), "UFObjectList")); + if (list == NULL) + return; bool isDefault = true; for (_UFObjectList::iterator iter = list->begin(); iter != list->end(); iter++) { @@ -380,7 +382,8 @@ return; } UFNumber &num = *object; - gtk_adjustment_set_value(data->adjustment(0), num.DoubleValue()); + if (data->adjustment(0) != NULL) + gtk_adjustment_set_value(data->adjustment(0), num.DoubleValue()); _ufobject_reset_button_state(object); } @@ -405,6 +408,16 @@ _ufobject_reset_button_state(object); } +static void _ufstring_object_event(UFObject *object, UFEventType type) { + _UFWidgetData *data = static_cast<_UFWidgetData *>(object->UserData()); + if (type == uf_destroyed) { + delete data; + return; + } + UFString &string = *object; + gtk_entry_set_text(GTK_ENTRY(data->gobject[0]), string.StringValue()); +} + static void _ufarray_object_event(UFObject *object, UFEventType type) { _UFWidgetData *data = static_cast<_UFWidgetData *>(object->UserData()); if (type == uf_destroyed) { @@ -475,6 +488,16 @@ return data; } +static _UFWidgetData &_ufstring_widget_data(UFString &string) { + if (string.UserData() != NULL) + return *static_cast<_UFWidgetData *>(string.UserData()); + _UFWidgetData &data = *(new _UFWidgetData); + string.SetUserData(&data); + data.gobject[0] = NULL; + string.SetEventHandle(_ufstring_object_event); + return data; +} + static _UFWidgetData &_ufarray_widget_data(UFArray &array) { if (array.UserData() != NULL) return *static_cast<_UFWidgetData *>(array.UserData()); @@ -533,6 +556,11 @@ static void _ufobject_reset_destroy(GtkWidget * /*widget*/, _UFObjectList *list) { + for (_UFObjectList::iterator iter = list->begin(); + iter != list->end(); iter++) { + _UFWidgetData *data = static_cast<_UFWidgetData *>((*iter)->UserData()); + data->button = NULL; + } delete list; } @@ -563,6 +591,26 @@ _ufobject_reset_button_state(object); } +static void _ufstring_entry_changed(GtkWidget *entry, UFObject *object) { + UFString &string = *object; + string.Set(gtk_entry_get_text(GTK_ENTRY(entry))); + _ufobject_reset_button_state(object); +} + +// Create a new GtkEntry with small width. +// The widget must be added with GTK_EXPAND|GTK_FILL. +GtkWidget *ufstring_entry_new(UFObject *object) { + GtkWidget *entry = gtk_entry_new(); + gtk_widget_set_size_request(entry, 50, -1); + g_signal_connect_after(G_OBJECT(entry), "changed", + G_CALLBACK(_ufstring_entry_changed), object); + UFString &string = *object; + _UFWidgetData &data = _ufstring_widget_data(string); + data.gobject[0] = G_OBJECT(entry); + _ufstring_object_event(object, uf_value_changed); + return entry; +} + static void _ufarray_combo_changed(GtkWidget *combo, UFObject *object) { UFArray &array = *object; int i = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); @@ -570,10 +618,14 @@ _ufobject_reset_button_state(object); } -static void _ufarray_entry_changed(GtkWidget *entry, UFObject *object) { +static bool _ufarray_entry_changed(GtkWidget *entry, GdkEventFocus *event, + UFObject *object) { + if (event->in) + return false; UFArray &array = *object; array.Set(gtk_entry_get_text(GTK_ENTRY(entry))); _ufobject_reset_button_state(object); + return false; } GtkWidget *_ufarray_combo_box_new(UFObject *object, GtkWidget *combo) { @@ -607,8 +659,10 @@ // The widget must be added with GTK_EXPAND|GTK_FILL. GtkWidget *ufarray_combo_box_entry_new(UFObject *object) { GtkWidget *combo = gtk_combo_box_entry_new_text(); + g_signal_connect_after(G_OBJECT(combo), "changed", + G_CALLBACK(_ufarray_combo_changed), object); GtkWidget *entry = gtk_bin_get_child(GTK_BIN(combo)); - g_signal_connect_after(G_OBJECT(entry), "changed", + g_signal_connect_after(G_OBJECT(entry), "focus-out-event", G_CALLBACK(_ufarray_entry_changed), object); return _ufarray_combo_box_new(object, combo); } Index: uf_gtk.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/uf_gtk.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- uf_gtk.h 26 Feb 2010 07:01:04 -0000 1.11 +++ uf_gtk.h 4 Mar 2010 04:52:32 -0000 1.12 @@ -66,7 +66,7 @@ GtkWidget *ufnumber_array_spin_button_new(UFObject *object, int index); GtkWidget *ufobject_reset_button_new(const char *tip); void ufobject_reset_button_add(GtkWidget *button, UFObject *object); -GtkWidget *ufstring_combo_box_new(UFObject *object); +GtkWidget *ufstring_entry_new(UFObject *object); GtkWidget *ufarray_combo_box_new(UFObject *object); GtkWidget *ufarray_combo_box_entry_new(UFObject *object); Index: ufraw_settings.cc =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_settings.cc,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- ufraw_settings.cc 28 Feb 2010 08:48:49 -0000 1.9 +++ ufraw_settings.cc 4 Mar 2010 04:52:32 -0000 1.10 @@ -221,6 +221,32 @@ } }; +extern "C" { UFName ufLensfunAuto = "LensfunAuto"; } +class LensfunAuto : public UFString { +public: + LensfunAuto() : UFString(ufLensfunAuto, "yes") { } + void OriginalValueChangedEvent() { + if (!HasParent()) + return; + if (IsEqual("auto")) { + Set("yes"); + return; + } + if (IsEqual("none")) { + Set("no"); + return; + } + if (!IsEqual("yes") && !IsEqual("no")) + Throw("Invalid value '%s'", StringValue()); +#ifdef HAVE_LENSFUN + if (!Parent().Has(ufLensfun)) + return; + if (IsDefault()) + ufraw_lensfun_init(&Parent()[ufLensfun]); +#endif + } +}; + // ufRawImage is short for 'raw image processing parameters'. extern "C" { UFName ufRawImage = "Image"; } Image::Image(UFObject *root) : UFGroup(ufRawImage), uf(NULL) { @@ -232,6 +258,7 @@ << new ChannelMultipliers ; #ifdef HAVE_LENSFUN + *this << new LensfunAuto; if (root == NULL || root->Name() != ufRawResources) *this << ufraw_lensfun_new(); // Lensfun data is not saved to .ufrawrc #else @@ -330,11 +357,13 @@ class CommandLineImage : public UFGroup { public: CommandLineImage(): UFGroup(ufRawImage) { } - void OriginalValueChangedEvent() { + void Event(UFEventType type) { + if (type != uf_element_added) + return UFObject::Event(type); if (Has(ufTemperature) || Has(ufGreen)) { if (Has(ufWB)) { UFArray &wb = (*this)[ufWB]; - if (!wb.IsEqual(uf_manual_wb)) { + if (!wb.IsEqual(uf_manual_wb) && !wb.IsEqual(uf_camera_wb)) { ufraw_message(UFRAW_WARNING, _("--temperature and --green options override " "the --wb=%s option."), wb.StringValue()); @@ -347,6 +376,8 @@ if (Has(ufWB)) { // We don't have green or temperature so this must be from --wb UFArray &wb = (*this)[ufWB]; + if (wb.IsEqual(uf_auto_wb) || wb.IsEqual(uf_camera_wb)) + return UFObject::Event(type); if (wb.IsEqual("camera")) wb.Set(uf_camera_wb); else if (wb.IsEqual("auto")) @@ -356,6 +387,7 @@ wb.StringValue()); } } + return UFObject::Event(type); } }; Index: ufraw_lens_ui.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_lens_ui.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- ufraw_lens_ui.c 1 Mar 2010 23:34:20 -0000 1.37 +++ ufraw_lens_ui.c 4 Mar 2010 04:52:32 -0000 1.38 @@ -28,19 +28,12 @@ static void camera_set(preview_data *data) { - const char *maker = lf_mlstr_get(CFG->camera->Maker); - const char *model = lf_mlstr_get(CFG->camera->Model); - const char *variant = lf_mlstr_get(CFG->camera->Variant); + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); + const lfCamera *camera = ufraw_lensfun_camera(lensfun); + const char *maker = lf_mlstr_get(camera->Maker); + const char *model = lf_mlstr_get(camera->Model); + const char *variant = lf_mlstr_get(camera->Variant); - if (model != NULL) { - gchar *fm; - if (maker != NULL) - fm = g_strdup_printf("%s, %s", maker, model); - else - fm = g_strdup_printf("%s", model); - gtk_entry_set_text(GTK_ENTRY(data->CameraModel), fm); - g_free(fm); - } char _variant[100]; if (variant != NULL) snprintf(_variant, sizeof(_variant), " (%s)", variant); @@ -52,7 +45,7 @@ "Mount:\t\t%s\n" "Crop factor:\t%.1f"), maker, model, _variant, - CFG->camera->Mount, CFG->camera->CropFactor); + camera->Mount, camera->CropFactor); uf_widget_set_tooltip(data->CameraModel, fm); g_free(fm); } @@ -61,7 +54,8 @@ { preview_data *data = (preview_data *)user_data; lfCamera *cam = g_object_get_data(G_OBJECT(menuitem), "lfCamera"); - lf_camera_copy(CFG->camera, cam); + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); + ufraw_lensfun_set_camera(lensfun, cam); camera_set(data); } @@ -183,24 +177,15 @@ uf_widget_set_tooltip(label, tooltip); } -static void lens_set(preview_data *data) +static void lens_set(GtkWidget *lensModel, preview_data *data) { UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); - lfLens *lens = ufraw_lensfun_transformation_lens(lensfun); + const lfLens *lens = ufraw_lensfun_interpolation_lens(lensfun); gchar *fm; const char *maker = lf_mlstr_get(lens->Maker); const char *model = lf_mlstr_get(lens->Model); - if (model != NULL) { - if (maker != NULL) - fm = g_strdup_printf("%s, %s", maker, model); - else - fm = g_strdup_printf("%s", model); - gtk_entry_set_text(GTK_ENTRY(data->LensModel), fm); - g_free(fm); - } - char focal[100], aperture[100], mounts[200]; if (lens->MinFocal < lens->MaxFocal) @@ -214,8 +199,8 @@ else snprintf(aperture, sizeof(aperture), "%g", lens->MinAperture); + mounts[0] = 0; if (lens->Mounts != NULL) { - mounts[0] = 0; unsigned i; for (i = 0; lens->Mounts[i] != NULL; i++) { if (i > 0) @@ -226,14 +211,14 @@ fm = g_strdup_printf(_("Maker:\t\t%s\n" "Model:\t\t%s\n" "Focal range:\t%s\n" - "Aperture:\t\t%s\n" + "Aperture:\t%s\n" "Crop factor:\t%.1f\n" "Type:\t\t%s\n" "Mounts:\t\t%s"), maker ? maker : "?", model ? model : "?", focal, aperture, lens->CropFactor, lf_get_lens_type_desc(lens->Type, NULL), mounts); - uf_widget_set_tooltip(data->LensModel, fm); + uf_widget_set_tooltip(lensModel, fm); g_free(fm); /* Create the focal/aperture/distance combo boxes */ @@ -253,12 +238,10 @@ gtk_widget_show_all(data->LensParamBox); } -static void lens_menu_select(GtkMenuItem *menuitem, preview_data *data) +static void lens_menu_select(GtkMenuItem *menuitem, UFObject *lensfun) { lfLens *lens = (lfLens *)g_object_get_data(G_OBJECT(menuitem), "lfLens"); - UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); - ufraw_lensfun_interpolate(lensfun, lens); - lens_set(data); + ufraw_lensfun_set_lens(lensfun, lens); } static void lens_menu_fill(preview_data *data, const lfLens *const *lenslist) @@ -268,6 +251,7 @@ gtk_widget_destroy(data->LensMenu); data->LensMenu = NULL; } + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); /* Count all existing lens makers and create a sorted list */ GPtrArray *makers = g_ptr_array_new(); @@ -291,7 +275,7 @@ gtk_widget_show(item); g_object_set_data(G_OBJECT(item), "lfLens", (void *)lenslist[i]); g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(lens_menu_select), data); + G_CALLBACK(lens_menu_select), lensfun); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); } @@ -312,11 +296,13 @@ { (void)button; char make[200], model[200]; + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); + const lfCamera *camera = ufraw_lensfun_camera(lensfun); const gchar *txt = gtk_entry_get_text(GTK_ENTRY(data->LensModel)); parse_maker_model(txt, make, sizeof(make), model, sizeof(model)); lfDatabase *lensdb = ufraw_lensfun_db(); - const lfLens **lenslist = lf_db_find_lenses_hd(lensdb, CFG->camera, + const lfLens **lenslist = lf_db_find_lenses_hd(lensdb, camera, make[0] ? make : NULL, model[0] ? model : NULL, 0); if (lenslist == NULL) return; @@ -331,24 +317,41 @@ { (void)button; + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); + const lfCamera *camera = ufraw_lensfun_camera(lensfun); lfDatabase *lensdb = ufraw_lensfun_db(); - if (CFG->camera != NULL) { - const lfLens **lenslist = lf_db_find_lenses_hd(lensdb, - CFG->camera, NULL, NULL, 0); - if (lenslist == NULL) - return; - lens_menu_fill(data, lenslist); - lf_free(lenslist); - } else { - const lfLens *const *lenslist = lf_db_get_lenses(lensdb); - if (lenslist == NULL) - return; - lens_menu_fill(data, lenslist); - } + const lfLens **lenslist = lf_db_find_lenses_hd(lensdb, + camera, NULL, NULL, 0); + if (lenslist == NULL) + return; + lens_menu_fill(data, lenslist); + lf_free(lenslist); + gtk_menu_popup(GTK_MENU(data->LensMenu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); } +static void auto_lens_button_toggle(GtkToggleButton *button, + UFObject *lensfunAuto) { + if (gtk_toggle_button_get_active(button)) { + if (ufstring_is_equal(lensfunAuto, "yes")) + ufobject_set_string(lensfunAuto, "no"); + else + ufobject_set_string(lensfunAuto, "yes"); + gtk_toggle_button_set_active(button, FALSE); + } +} + +static void auto_lens_event(UFObject *object, UFEventType type) { + if (type != uf_value_changed) + return; + GtkButton *button = ufobject_user_data(object); + if (ufstring_is_equal(object, "yes")) + uf_button_set_stock_image(button, "object-automatic"); + else + uf_button_set_stock_image(button, "object-manual"); +} + /* --- TCA correction page --- */ static void tca_model_changed(GtkComboBox *widget, preview_data *data) @@ -381,7 +384,7 @@ gtk_widget_show_all(data->LensTCATable); } -static void fill_tca_page(preview_data *data, GtkWidget *page) +static void fill_tca_page(preview_data *data, GtkWidget *page, GtkWidget *reset) { GtkWidget *hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(page), hbox, FALSE, FALSE, 0); @@ -397,6 +400,7 @@ uf_widget_set_tooltip(combo, _("Chromatic Aberrations mathematical model")); g_signal_connect_after(G_OBJECT(combo), "changed", G_CALLBACK(tca_model_changed), data); + ufobject_reset_button_add(reset, tca); data->LensTCATable = gtk_table_new(10, 1, FALSE); GtkWidget *f = gtk_frame_new(_("Parameters")); @@ -444,7 +448,8 @@ gtk_widget_show_all(data->LensVignettingTable); } -static void fill_vignetting_page(preview_data *data, GtkWidget *page) +static void fill_vignetting_page(preview_data *data, GtkWidget *page, + GtkWidget *reset) { GtkWidget *hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(page), hbox, FALSE, FALSE, 0); @@ -460,6 +465,7 @@ uf_widget_set_tooltip(combo, _("Optical vignetting mathematical model")); g_signal_connect_after(G_OBJECT(combo), "changed", G_CALLBACK(vignetting_model_changed), data); + ufobject_reset_button_add(reset, vignetting); data->LensVignettingTable = gtk_table_new(10, 1, FALSE); GtkWidget *f = gtk_frame_new(_("Parameters")); @@ -509,7 +515,8 @@ gtk_widget_show_all(data->LensDistortionTable); } -static void fill_distortion_page(preview_data *data, GtkWidget *page) +static void fill_distortion_page(preview_data *data, GtkWidget *page, + GtkWidget *reset) { GtkWidget *hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(page), hbox, FALSE, FALSE, 0); @@ -525,6 +532,7 @@ uf_widget_set_tooltip(combo, _("Lens distortion mathematical model")); g_signal_connect_after(G_OBJECT(combo), "changed", G_CALLBACK(distortion_model_changed), data); + ufobject_reset_button_add(reset, distortion); data->LensDistortionTable = gtk_table_new(10, 1, FALSE); GtkWidget *f = gtk_frame_new(_("Parameters")); @@ -553,7 +561,7 @@ gtk_label_set_text(label, details); } -static GtkWidget *fill_geometry_page(UFObject *ufobject) +static GtkWidget *fill_geometry_page(UFObject *ufobject, GtkWidget *reset) { UFObject *lensfun = ufgroup_element(ufobject, ufLensfun); GtkTable *geometryTable = GTK_TABLE(gtk_table_new(10, 1, FALSE)); @@ -568,6 +576,7 @@ _("The geometry of the lens used to make the shot")); gtk_table_attach(geometryTable, combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); + ufobject_reset_button_add(reset, lensGeometry); GtkWidget *description = gtk_label_new(""); gtk_label_set_line_wrap(GTK_LABEL(description), TRUE); @@ -589,6 +598,7 @@ uf_widget_set_tooltip(combo, _("The target geometry for output image")); gtk_table_attach(geometryTable, combo, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); + ufobject_reset_button_add(reset, targetLensGeometry); description = gtk_label_new(""); gtk_label_set_line_wrap(GTK_LABEL(description), TRUE); @@ -609,6 +619,7 @@ void lens_fill_interface(preview_data *data, GtkWidget *page) { GtkWidget *label, *button, *subpage; + UFObject *lensfun = ufgroup_element(CFG->ufobject, ufLensfun); /* Camera selector */ GtkTable *table = GTK_TABLE(gtk_table_new(10, 10, FALSE)); @@ -618,7 +629,8 @@ gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(table, label, 0, 1, 0, 1, GTK_FILL, 0, 2, 0); - data->CameraModel = gtk_entry_new(); + UFObject *cameraModel = ufgroup_element(lensfun, ufCameraModel); + data->CameraModel = ufstring_entry_new(cameraModel); gtk_table_attach(table, data->CameraModel, 1, 2, 0, 1, GTK_EXPAND|GTK_FILL, 0, 2, 0); @@ -633,13 +645,21 @@ G_CALLBACK(camera_list_clicked), data); gtk_table_attach(table, button, 3, 4, 0, 1, 0, 0, 0, 0); + GtkWidget *reset = ufobject_reset_button_new( + _("Reset all lens correction settings")); + gtk_table_attach(table, reset, 4, 5, 0, 1, 0, 0, 0, 0); + ufobject_reset_button_add(reset, cameraModel); + /* Lens selector */ label = gtk_label_new(_("Lens")); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(table, label, 0, 1, 1, 2, GTK_FILL, 0, 2, 0); - data->LensModel = gtk_entry_new(); - //gtk_entry_set_text(GTK_ENTRY(data->LensModel), ""); + UFObject *lensModel = ufgroup_element(lensfun, ufLensModel); + data->LensModel = ufstring_entry_new(lensModel); + ufobject_reset_button_add(reset, lensModel); + g_signal_connect_after(G_OBJECT(data->LensModel), "changed", + G_CALLBACK(lens_set), data); gtk_table_attach(table, data->LensModel, 1, 2, 1, 2, GTK_EXPAND|GTK_FILL, 0, 2, 0); @@ -654,6 +674,17 @@ G_CALLBACK(lens_list_clicked), data); gtk_table_attach(table, button, 3, 4, 1, 2, 0, 0, 0, 0); + GtkWidget *autoLens = gtk_toggle_button_new(); + gtk_table_attach(table, autoLens, 4, 5, 1, 2, 0, 0, 0, 0); + uf_widget_set_tooltip(autoLens, + _("Automatically find lens and set lens corrections")); + UFObject *lensfunAuto = ufgroup_element(CFG->ufobject, ufLensfunAuto); + g_signal_connect(G_OBJECT(autoLens), "toggled", + G_CALLBACK(auto_lens_button_toggle), lensfunAuto); + ufobject_set_user_data(lensfunAuto, autoLens); + ufobject_set_changed_event_handle(lensfunAuto, auto_lens_event); + auto_lens_event(lensfunAuto, uf_value_changed); + data->LensParamBox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(page), data->LensParamBox, FALSE, FALSE, 2); @@ -663,27 +694,31 @@ /* Create a default lens & camera */ camera_set(data); - lens_set(data); + lens_set(data->LensModel, data); + + ufobject_reset_button_add(reset, ufgroup_element(lensfun, ufFocalLength)); + ufobject_reset_button_add(reset, ufgroup_element(lensfun, ufAperture)); + ufobject_reset_button_add(reset, ufgroup_element(lensfun, ufDistance)); subpage = notebook_page_new(subnb, _("Lateral chromatic aberration"), "tca"); - fill_tca_page(data, subpage); + fill_tca_page(data, subpage, reset); tca_model_changed(NULL, data); subpage = notebook_page_new(subnb, _("Optical vignetting"), "vignetting"); - fill_vignetting_page(data, subpage); + fill_vignetting_page(data, subpage, reset); vignetting_model_changed(NULL, data); subpage = notebook_page_new(subnb, _("Lens distortion"), "distortion"); - fill_distortion_page(data, subpage); + fill_distortion_page(data, subpage, reset); distortion_model_changed(NULL, data); gtk_widget_show_all(subpage); // Need to show the page for set page to work. int pageNum = gtk_notebook_page_num(subnb, page); gtk_notebook_set_current_page(subnb, pageNum); subpage = notebook_page_new(subnb, _("Lens geometry"), "geometry"); - gtk_box_pack_start(GTK_BOX(subpage), fill_geometry_page(CFG->ufobject), - TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(subpage), + fill_geometry_page(CFG->ufobject, reset), TRUE, TRUE, 0); } #endif /* HAVE_LENSFUN */ Index: ufraw.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw.h,v retrieving revision 1.154 retrieving revision 1.155 diff -u -d -r1.154 -r1.155 --- ufraw.h 1 Mar 2010 23:34:20 -0000 1.154 +++ ufraw.h 4 Mar 2010 04:52:32 -0000 1.155 @@ -61,7 +61,10 @@ extern UFName ufTemperature; extern UFName ufGreen; extern UFName ufChannelMultipliers; +extern UFName ufLensfunAuto; extern UFName ufLensfun; +extern UFName ufCameraModel; +extern UFName ufLensModel; extern UFName ufFocalLength; extern UFName ufAperture; extern UFName ufDistance; @@ -82,9 +85,12 @@ UFObject *ufraw_image_new(); #ifdef HAVE_LENSFUN UFObject *ufraw_lensfun_new(); +void ufraw_lensfun_init(UFObject *lensfun); struct lfDatabase *ufraw_lensfun_db(); /* mount/camera/lens database */ -struct lfLens *ufraw_lensfun_transformation_lens(UFObject *lensfun); -void ufraw_lensfun_interpolate(UFObject *lensfun, const struct lfLens *lens); +const struct lfCamera *ufraw_lensfun_camera(const UFObject *lensfun); +void ufraw_lensfun_set_camera(UFObject *lensfun, const struct lfCamera *camera); +const struct lfLens *ufraw_lensfun_interpolation_lens(const UFObject *lensfun); +void ufraw_lensfun_set_lens(UFObject *lensfun, const struct lfLens *lens); #endif struct ufraw_struct *ufraw_image_get_data(UFObject *obj); void ufraw_image_set_data(UFObject *obj, struct ufraw_struct *uf); @@ -121,7 +127,6 @@ ufraw_develop_phase, ufraw_display_phase, ufraw_phases_num } UFRawPhase; typedef enum { grayscale_none, grayscale_lightness, grayscale_luminance, grayscale_value, grayscale_mixer } GrayscaleMode; -typedef enum { lensfun_none, lensfun_auto, lensfun_default } LensfunMode; typedef struct { const char *make; @@ -281,11 +286,6 @@ time_t timestamp; /* Unfortunately dcraw strips make and model, but we need originals too */ char real_make[max_name], real_model[max_name]; - -#ifdef HAVE_LENSFUN - struct lfCamera *camera; /* camera description */ - int lensfunMode; -#endif /* HAVE_LENSFUN */ } conf_data; typedef struct { Index: ufraw_conf.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_conf.c,v retrieving revision 1.165 retrieving revision 1.166 diff -u -d -r1.165 -r1.166 --- ufraw_conf.c 1 Mar 2010 23:34:20 -0000 1.165 +++ ufraw_conf.c 4 Mar 2010 04:52:32 -0000 1.166 @@ -11,9 +11,6 @@ */ #include "ufraw.h" -#ifdef HAVE_LENSFUN -#include <lensfun.h> -#endif #include <string.h> #include <errno.h> #include <math.h> @@ -131,11 +128,6 @@ "", "", "", /* timestamp, make, model */ 0, /* timestamp */ "", "", /* real_make, real_model */ - -#ifdef HAVE_LENSFUN - NULL, /* camera description */ - lensfun_default, /* lensfun starting mode */ -#endif /* HAVE_LENSFUN */ }; static const char *interpolationNames[] = @@ -148,10 +140,6 @@ { "perceptual", "relative", "saturation", "absolute", "disable", NULL }; static const char *grayscaleModeNames[] = { "none", "lightness", "luminance", "value", "mixer", NULL }; -#ifdef HAVE_LENSFUN -static const char *lensfunModeNames[] = - { "none", "auto", NULL }; -#endif void conf_init(conf_data *c) { @@ -1385,15 +1373,6 @@ } dst->intent[out_profile] = src->intent[out_profile]; dst->intent[display_profile] = src->intent[display_profile]; - -#ifdef HAVE_LENSFUN - dst->lensfunMode = src->lensfunMode; - if (src->camera) - { - dst->camera = lf_camera_new (); - lf_camera_copy (dst->camera, src->camera); - } -#endif /* HAVE_LENSFUN */ } /* Copy the transformation information from *src to *dst. */ @@ -1455,9 +1434,6 @@ if (cmd->CropX2 !=-1) conf->CropX2 = cmd->CropX2; if (cmd->CropY2 !=-1) conf->CropY2 = cmd->CropY2; if (cmd->silent!=-1) conf->silent = cmd->silent; -#ifdef HAVE_LENSFUN - if (cmd->lensfunMode!=-1) conf->lensfunMode = cmd->lensfunMode; -#endif if (cmd->compression!=NULLF) conf->compression = cmd->compression; if (cmd->autoExposure) { conf->autoExposure = cmd->autoExposure; @@ -1700,12 +1676,14 @@ *curveName=NULL, *curveFile=NULL, *outTypeName=NULL, *rotateName=NULL, *createIDName=NULL, *outPath=NULL, *output=NULL, *conf=NULL, *interpolationName=NULL, *darkframeFile=NULL, - *restoreName=NULL, *clipName=NULL, *grayscaleName=NULL, - *lensfunName = NULL; + *restoreName=NULL, *clipName=NULL, *grayscaleName=NULL; static const struct option options[] = { { "wb", 1, 0, 'w'}, { "temperature", 1, 0, 't'}, { "green", 1, 0, 'g'}, +#ifdef HAVE_LENSFUN + { "lensfun", 1, 0, 'A'}, +#endif { "base-curve", 1, 0, 'B'}, { "base-curve-file", 1, 0, 'S'}, { "curve", 1, 0, 'c'}, @@ -1737,9 +1715,6 @@ { "crop-top", 1, 0, '2'}, { "crop-right", 1, 0, '3'}, { "crop-bottom", 1, 0, '4'}, -#ifdef HAVE_LENSFUN - { "lensfun", 1, 0, 'A'}, -#endif /* Binary flags that don't have a value are here at the end */ { "zip", 0, 0, 'z'}, { "nozip", 0, 0, 'Z'}, @@ -1760,6 +1735,9 @@ ufgroup_element(tmpImage, ufWB), ufgroup_element(tmpImage, ufTemperature), ufgroup_element(tmpImage, ufGreen), +#ifdef HAVE_LENSFUN + ufgroup_element(tmpImage, ufLensfunAuto), +#endif &baseCurveName, &baseCurveFile, &curveName, &curveFile, &cmd->profile[0][0].gamma, &cmd->profile[0][0].linear, &cmd->saturation, @@ -1771,7 +1749,7 @@ &outTypeName, &cmd->profile[1][0].BitDepth, &rotateName, &createIDName, &outPath, &output, &darkframeFile, &restoreName, &clipName, &conf, - &cmd->CropX1, &cmd->CropY1, &cmd->CropX2, &cmd->CropY2, &lensfunName }; + &cmd->CropX1, &cmd->CropY1, &cmd->CropX2, &cmd->CropY2 }; cmd->autoExposure = disabled_state; cmd->autoBlack = disabled_state; cmd->losslessCompress=-1; @@ -1806,7 +1784,8 @@ switch (c) { case 'w': // --wb case 't': // --temperature - case 'g': // -- green + case 'g': // --green + case 'A': // --lensfun locale = uf_set_locale_C(); if (!ufobject_set_string(optPointer[index], optarg)) { ufraw_message(UFRAW_ERROR, @@ -1878,7 +1857,6 @@ case 'r': case 'u': case 'Y': - case 'A': *(char **)optPointer[index] = optarg; break; case 'O': cmd->overwrite = TRUE; break; @@ -2230,18 +2208,6 @@ return -1; } } -#ifdef HAVE_LENSFUN - cmd->lensfunMode = -1; - if (lensfunName!=NULL) { - cmd->lensfunMode = conf_find_name(lensfunName, lensfunModeNames, -1); - if (cmd->lensfunMode==-1) { - ufraw_message(UFRAW_ERROR, - _("'%s' is not a valid lensfun option."), - lensfunName); - return -1; - } - } -#endif cmd->createID = -1; if (createIDName!=NULL) { if (!strcmp(createIDName, "no")) Index: ufraw_ufraw.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_ufraw.c,v retrieving revision 1.248 retrieving revision 1.249 diff -u -d -r1.248 -r1.249 --- ufraw_ufraw.c 1 Mar 2010 23:34:21 -0000 1.248 +++ ufraw_ufraw.c 4 Mar 2010 04:52:32 -0000 1.249 @@ -35,7 +35,6 @@ #ifdef HAVE_LENSFUN #define UF_LF_TRANSFORM ( \ LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE) -void ufraw_lensfun_init(ufraw_data *uf); static void ufraw_convert_image_vignetting(ufraw_data *uf, ufraw_image_data *img, UFRectangle *area); static void ufraw_convert_image_tca(ufraw_data *uf, ufraw_image_data *img, @@ -456,7 +455,7 @@ } ufraw_image_set_data(uf->conf->ufobject, uf); #ifdef HAVE_LENSFUN - ufraw_lensfun_init(uf); + ufraw_lensfun_init(ufgroup_element(uf->conf->ufobject, ufLensfun)); #endif char *absname = uf_file_set_absolute(uf->filename); @@ -698,7 +697,6 @@ g_free(uf->RawHistogram); #ifdef HAVE_LENSFUN lf_modifier_destroy(uf->TCAmodifier); - lf_camera_destroy(uf->conf->camera); lf_modifier_destroy(uf->modifier); #endif if ( uf->conf->darkframe!=NULL ) { Index: ufobject.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufobject.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- ufobject.h 2 Mar 2010 20:06:09 -0000 1.5 +++ ufobject.h 4 Mar 2010 04:52:32 -0000 1.6 @@ -27,6 +27,7 @@ typedef enum { uf_value_changed, ///< Value changed. uf_default_changed, ///< Default value changed. + uf_element_added, ///< An UFObject was added to a UFGroup or a UFArray. uf_user_data_set, ///< User data was set. uf_destroyed ///< UFObject is being destroyed. } UFEventType; @@ -448,6 +449,10 @@ /// Returns false if @a object is not a UFNumberArray. See \ref C-interface /// and UFNumberArray::Set(const double array[]) for more details. UFBoolean ufnumber_array_set(UFObject *object, const double array[]); +/// Return true if string value is equal to @a string. +/// Return false if it is not equal or if object is not a UFString. +/// See \ref C-interface for more details. +UFBoolean ufstring_is_equal(UFObject *object, const char *string); /// Return true if the UFGroup @a object contains an object called name. /// Return false if it does not, or if object is not a UFGroup. /// See \ref C-interface for more details. Index: ufraw_lensfun.cc =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_lensfun.cc,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- ufraw_lensfun.cc 2 Mar 2010 20:06:09 -0000 1.8 +++ ufraw_lensfun.cc 4 Mar 2010 04:52:32 -0000 1.9 @@ -32,6 +32,7 @@ private: static lfDatabase *_LensDB; public: + lfCamera Camera; lfLens Transformation; lfLens Interpolation; double FocalLengthValue; @@ -50,6 +51,11 @@ return static_cast<Lensfun &>(object.Parent()); return Lensfun::Parent(object.Parent()); } + static const Lensfun &Parent(const UFObject &object) { + if (strcmp(object.Parent().Name(), ufLensfun) == 0) + return static_cast<Lensfun &>(object.Parent()); + return Lensfun::Parent(object.Parent()); + } static lfDatabase *LensDB() { /* Load lens database only once */ if (_LensDB == NULL) { @@ -58,10 +64,79 @@ } return _LensDB; } + void SetCamera(const lfCamera &camera) { + Camera = camera; + const char *maker = lf_mlstr_get(camera.Maker); + const char *model = lf_mlstr_get(camera.Model); + if (model != NULL) { + char *fm; + if (maker != NULL) + fm = g_strdup_printf("%s, %s", maker, model); + else + fm = g_strdup_printf("%s", model); + UFString &CameraModel = (*this)[ufCameraModel]; + CameraModel.Set(fm); + g_free(fm); + } + } + void SetLensModel(const lfLens &lens); + void SetInterpolation(const lfLens &lens); void Interpolate(); void Init(); }; +static void parse_maker_model(const char *txt, char *make, size_t sz_make, + char *model, size_t sz_model) +{ + while (txt[0] != '\0' && isspace(txt[0])) + txt++; + const gchar *sep = strchr(txt, ','); + if (sep != NULL) { + size_t len = sep - txt + 1; + len = MIN(len, sz_make); + g_strlcpy(make, txt, len); + + while (*++sep && isspace(sep[0])) { } + g_strlcpy(model, sep, sz_model); + } else { + g_strlcpy(model, txt, sz_model); + } +} + +extern "C" { UFName ufCameraModel = "CameraModel"; } +class CameraModel : public UFString { +public: + CameraModel() : UFString(ufCameraModel) { } +}; + +extern "C" { UFName ufLensModel = "LensModel"; } +class LensModel : public UFString { +public: + LensModel() : UFString(ufLensModel) { } + void Event(UFEventType type) { + if (type != uf_value_changed) + return UFObject::Event(type); + if (!HasParent()) + return UFObject::Event(type); + Lensfun &Lensfun = Lensfun::Parent(*this); + Lensfun.UFObject::Parent()[ufLensfunAuto].Set("no"); + char make[200], model[200]; + parse_maker_model(StringValue(), make, sizeof(make), + model, sizeof(model)); + const lfLens **lensList = Lensfun.LensDB()->FindLenses(&Lensfun.Camera, + make, model, 0); + if (lensList == NULL) { + lfLens emptyLens; + Lensfun.SetInterpolation(emptyLens); + return UFObject::Event(type); + } + Lensfun.SetInterpolation(*lensList[0]); + Lensfun.Interpolate(); + lf_free(lensList); + return UFObject::Event(type); + } +}; + #define _buffer_size 80 char *_StringNumber(char *buffer, double number) { @@ -146,8 +221,9 @@ 4, 4.8, 5.6, 6.7, 8, 9.5, 11, 13, 16, 19, 22, 27, 32, 38, 45, 0 }; char buffer[_buffer_size]; double min = lens.MinAperture; - if (min > 0) - *this << new UFString(ufPreset, _StringNumber(buffer, min)); + if (min == 0) + return; + *this << new UFString(ufPreset, _StringNumber(buffer, min)); int i = 0; while (apertureValues[i] < min && apertureValues[i] != 0) i++; @@ -198,7 +274,12 @@ return (std::string)indent + "<" + Name() + ">" + num + "</" + Name() + ">\n"; } - + void OriginalValueChangedEvent() { + if (!HasParent()) + return; + lfLens emptyLens; + Lensfun::Parent(*this)[ufLensModel].Reset(); + } }; extern "C" { UFName ufTCA = "TCA"; } @@ -465,6 +546,8 @@ Lensfun::Lensfun() : UFGroup(ufLensfun), FocalLengthValue(0.0), ApertureValue(0.0), DistanceValue(0.0) { *this + << new CameraModel + << new LensModel << new FocalLength << new Aperture << new Distance @@ -476,6 +559,28 @@ ; } +void Lensfun::SetInterpolation(const lfLens &lens) { + Interpolation = lens; + static_cast<UFRaw::FocalLength &>((*this)[ufFocalLength]).CreatePresets(); + static_cast<UFRaw::Aperture &>((*this)[ufAperture]).CreatePresets(); + static_cast<UFRaw::Distance &>((*this)[ufDistance]).CreatePresets(); +} + +void Lensfun::SetLensModel(const lfLens &lens) { + UFString &LensModel = (*this)[ufLensModel]; + const char *maker = lf_mlstr_get(lens.Maker); + const char *model = lf_mlstr_get(lens.Model); + if (model != NULL) { + char *fm; + if (maker != NULL) + fm = g_strdup_printf("%s, %s", maker, model); + else + fm = g_strdup_printf("%s", model); + LensModel.Set(fm); + g_free(fm); + } +} + void Lensfun::Interpolate() { static_cast<TCA &>((*this)[ufTCA]).Interpolate(); static_cast<Vignetting &>((*this)[ufVignetting]).Interpolate(); @@ -486,74 +591,60 @@ void Lensfun::Init() { ufraw_data *uf = ufraw_image_get_data(this); - - char buffer[_buffer_size]; - UFArray &FocalLength = (*this)[ufFocalLength]; - FocalLength.SetDefault(_StringNumber(buffer, uf->conf->focal_len)); - UFArray &Aperture = (*this)[ufAperture]; - Aperture.SetDefault(_StringNumber(buffer, uf->conf->aperture)); - UFArray &Distance = (*this)[ufDistance]; - Distance.SetDefault(_StringNumber(buffer, uf->conf->subject_distance)); - - /* Create a default camera */ - uf->conf->camera = lf_camera_new(); + UFGroup &Image = UFObject::Parent(); /* Set lens and camera from EXIF info, if possible */ if (uf->conf->real_make[0] || uf->conf->real_model[0]) { const lfCamera **cams = LensDB()->FindCameras( uf->conf->real_make, uf->conf->real_model); if (cams != NULL) { - lf_camera_copy(uf->conf->camera, cams[0]); + SetCamera(*cams[0]); lf_free(cams); } } - if (strlen(uf->conf->lensText) > 0) { - const lfLens **lenses = LensDB()->FindLenses( - uf->conf->camera, NULL, uf->conf->lensText); - if (lenses != NULL) { - Interpolation = *lenses[0]; - Transformation = *lenses[0]; - lf_free(lenses); - } - } - if (uf->conf->lensfunMode == lensfun_default) { - if (uf->LoadingID) { - (*this)[ufTCA].Event(uf_value_changed); - (*this)[ufVignetting].Event(uf_value_changed); - (*this)[ufDistortion].Event(uf_value_changed); - return; - } - uf->conf->lensfunMode = lensfun_auto; + UFString &CameraModel = (*this)[ufCameraModel]; + CameraModel.SetDefault(CameraModel.StringValue()); + + char buffer[_buffer_size]; + UFArray &FocalLength = (*this)[ufFocalLength]; + FocalLength.SetDefault(_StringNumber(buffer, uf->conf->focal_len)); + UFArray &Aperture = (*this)[ufAperture]; + Aperture.SetDefault(_StringNumber(buffer, uf->conf->aperture)); + UFArray &Distance = (*this)[ufDistance]; + Distance.SetDefault(_StringNumber(buffer, uf->conf->subject_distance)); + + if (uf->LoadingID) { + (*this)[ufTCA].Event(uf_value_changed); + (*this)[ufVignetting].Event(uf_value_changed); + (*this)[ufDistortion].Event(uf_value_changed); + return; } FocalLength.Reset(); Aperture.Reset(); Distance.Reset(); - if (uf->conf->lensfunMode == lensfun_none) { - (*this)[ufTCA].Reset(); - (*this)[ufVignetting].Reset(); - (*this)[ufDistortion].Reset(); - } else { - static_cast<UFRaw::FocalLength &>(FocalLength).CreatePresets(); - static_cast<UFRaw::Aperture &>(Aperture).CreatePresets(); - static_cast<UFRaw::Distance &>(Distance).CreatePresets(); - Interpolate(); + UFString &LensfunAuto = Image[ufLensfunAuto]; + if (LensfunAuto.IsEqual("yes")) { + if (strlen(uf->conf->lensText) > 0) { + const lfLens **lenses = LensDB()->FindLenses(&Camera, + NULL, uf->conf->lensText); + if (lenses != NULL) { + SetLensModel(*lenses[0]); + LensfunAuto.Set("yes"); + lf_free(lenses); + return; + } + } } + // LensfunAuto == "no" + (*this)[ufTCA].Reset(); + (*this)[ufVignetting].Reset(); + (*this)[ufDistortion].Reset(); } extern "C" { -void ufraw_lensfun_interpolate(UFObject *lensfun, const lfLens *lens) { - Lensfun &Lensfun = dynamic_cast<UFRaw::Lensfun &>(*lensfun); - Lensfun.Interpolation = *lens; - static_cast<FocalLength &>(Lensfun[ufFocalLength]).CreatePresets(); - static_cast<Aperture &>(Lensfun[ufAperture]).CreatePresets(); - static_cast<Distance &>(Lensfun[ufDistance]).CreatePresets(); - Lensfun.Interpolate(); -} -void ufraw_lensfun_init(ufraw_data *uf) { - UFGroup &Image = *uf->conf->ufobject; - UFRaw::Lensfun &Lensfun = static_cast<UFRaw::Lensfun &>(Image[ufLensfun]); - Lensfun.Init(); +void ufraw_lensfun_init(UFObject *lensfun) { + static_cast<UFRaw::Lensfun *>(lensfun)->Init(); } void ufraw_convert_prepare_transform(ufraw_data *uf, @@ -561,11 +652,10 @@ { UFGroup &Image = *uf->conf->ufobject; UFRaw::Lensfun &Lensfun = static_cast<UFRaw::Lensfun &>(Image[ufLensfun]); - conf_data *conf = uf->conf; if (uf->modifier != NULL) uf->modifier->Destroy(); uf->modifier = lfModifier::Create(&Lensfun.Transformation, - conf->camera->CropFactor, width, height); + Lensfun.Camera.CropFactor, width, height); if (uf->modifier == NULL) return; @@ -590,7 +680,7 @@ if (uf->TCAmodifier != NULL) uf->TCAmodifier->Destroy(); uf->TCAmodifier = lfModifier::Create(&Lensfun.Transformation, - uf->conf->camera->CropFactor, img->width, img->height); + Lensfun.Camera.CropFactor, img->width, img->height); if (uf->TCAmodifier == NULL) return; @@ -610,8 +700,22 @@ return new Lensfun(); } -struct lfLens *ufraw_lensfun_transformation_lens(UFObject *lensfun) { - return &static_cast<UFRaw::Lensfun *>(lensfun)->Transformation; +const struct lfCamera *ufraw_lensfun_camera(const UFObject *lensfun) { + return &static_cast<const UFRaw::Lensfun *>(lensfun)->Camera; +} + +void ufraw_lensfun_set_camera(UFObject *lensfun, const struct lfCamera *camera) +{ + static_cast<UFRaw::Lensfun *>(lensfun)->SetCamera(*camera); +} + +const struct lfLens *ufraw_lensfun_interpolation_lens(const UFObject *lensfun) +{ + return &static_cast<const UFRaw::Lensfun *>(lensfun)->Interpolation; +} + +void ufraw_lensfun_set_lens(UFObject *lensfun, const struct lfLens *lens) { + dynamic_cast<UFRaw::Lensfun &>(*lensfun).SetLensModel(*lens); } lfDatabase *ufraw_lensfun_db() { ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ ufraw-cvs mailing list ufraw-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ufraw-cvs