110#include <glib/gstdio.h>
123#define INIT_UPDATE_INTERVAL 2
124#define MAX_UPDATE_INTERVAL 3.0
128#define PROGRESS_UPDATE_INTERVAL 1
165 while(sqlite3_step(stmt) == SQLITE_ROW)
167 const int32_t imgid = sqlite3_column_int(stmt, 0);
168 t->index = g_list_append(
t->index, GINT_TO_POINTER(imgid));
170 sqlite3_finalize(stmt);
174 int32_t (*fileop_callback)(
const int32_t,
176 const char *desc,
const char *desc_pl)
179 GList *
t = params->index;
180 const guint total = g_list_length(
t);
181 char message[512] = { 0 };
183 gchar *newdir = (gchar *)params->data;
185 g_snprintf(message,
sizeof(message), ngettext(desc, desc_pl, total), total);
190 const int32_t film_id =
dt_film_new(&new_film, newdir);
195 dt_control_log(_(
"failed to create film roll for destination directory, aborting move.."));
199 gboolean completeSuccess =
TRUE;
202 completeSuccess &= (fileop_callback(GPOINTER_TO_INT(
t->data), film_id) != -1);
204 fraction += 1.0 / total;
211 snprintf(collect,
sizeof(collect),
"1:0:0:%s$", new_film.
dirname);
217 g_list_copy(params->index));
235 g_list_free(params->index);
236 params->index = NULL;
238 params->index = NULL;
247 gboolean only_visible)
283 params->index = g_list_append(NULL, GINT_TO_POINTER(imgid));
299 for(GList *
t = params->index;
t;
t = g_list_next(
t))
301 const int32_t imgid = GPOINTER_TO_INT(
t->data);
304 "cannot write XMP file for image %i. The target storage may be unavailable or read-only.\n",
364 const float x =
CLAMPS(xx, 0.0f, 1.0f);
366 const float beta = 0.5f;
370 const float tmp = fabsf(
x / beta - 1.0f);
371 return 1.0f - tmp * tmp;
375 const float tmp1 = (1.0f -
x) / (1.0f - beta);
376 const float tmp2 = tmp1 * tmp1;
377 const float tmp3 = tmp2 * tmp1;
378 return 3.0f * tmp2 - 2.0f * tmp3;
383 const void *
const ivoid,
385 void *exif,
int exif_len, int32_t imgid,
int num,
int total,
398 d->first_imgid = imgid;
410 d->pixels = calloc((
size_t)datai->
width * datai->
height,
sizeof(
float));
411 d->weight = calloc((
size_t)datai->
width * datai->
height,
sizeof(
float));
415 for(
int i = 0;
i < 3;
i++)
417 for(
int k=0;
k<4;
k++)
418 for(
int i=0;
i<3;
i++)
424 dt_control_log(_(
"exposure bracketing only works on raw images."));
431 dt_control_log(_(
"images have to be of same size and orientation!"));
440 const float rad = .5f * efl / eap;
441 const float aperture =
M_PI * rad * rad;
444 const float cal = 100.0f / (aperture * exp * iso);
446 const float photoncnt = 100.0f * aperture * exp / iso;
447 float saturation = 1.0f;
448 d->whitelevel = fmaxf(
d->whitelevel, saturation * cal);
450 for(
int y = 0; y <
d->ht; y++)
451 for(
int x = 0;
x <
d->wd;
x++)
455 const float in = ((
float *)ivoid)[
x +
d->wd * y];
462 float offset = 3000.0f / (float)UINT16_MAX;
467 int xx =
x & ~1, yy = y & ~1;
468 float M = 0.0f,
m = FLT_MAX;
469 if(xx < d->wd - 2 && yy < d->ht - 2)
471 for(
int i = 0;
i < 3;
i++)
472 for(
int j = 0; j < 3; j++)
474 M =
MAX(
M, ((
float *)ivoid)[xx +
i +
d->wd * (yy + j)]);
475 m =
MIN(
m, ((
float *)ivoid)[xx +
i +
d->wd * (yy + j)]);
480 w *=
d->epsw +
envelope((
M + offset) / saturation);
483 if(
M + offset >= saturation)
485 if(
d->weight[
x +
d->wd * y] <= 0.0f)
487 if(
d->weight[
x +
d->wd * y] == 0 || m < -d->
weight[
x +
d->wd * y])
489 if(
m + offset >= saturation)
490 d->pixels[
x +
d->wd * y] = 1.0f;
492 d->pixels[
x +
d->wd * y] = in * cal /
d->whitelevel;
493 d->weight[
x +
d->wd * y]
501 if(
d->weight[
x +
d->wd * y] <= 0.0)
503 d->pixels[
x +
d->wd * y] = 0.0f;
504 d->weight[
x +
d->wd * y] = 0.0f;
506 d->pixels[
x +
d->wd * y] += w * in * cal;
507 d->weight[
x +
d->wd * y] += w;
517 GList *
t = params->index;
518 const guint total = g_list_length(
t);
519 char message[512] = { 0 };
521 snprintf(message,
sizeof(message), ngettext(
"merging %d image",
"merging %d images", total), total);
537 if(
d.abort)
goto end;
539 const int32_t imgid = GPOINTER_TO_INT(
t->data);
541 const gboolean is_scaling =
546 NULL, num, total, NULL, NULL);
551 fraction += 1.0 / (total + 1);
556 if(
d.abort)
goto end;
560 for(
size_t k = 0;
k < (size_t)
d.wd *
d.ht;
k++)
562 if(
d.weight[
k] > 0.0)
d.pixels[
k] = fmaxf(0.0f,
d.pixels[
k] / (
d.whitelevel *
d.weight[
k]));
566 uint8_t *exif = NULL;
568 gboolean from_cache =
TRUE;
574 while(*c !=
'.' && c > pathname) c--;
575 g_strlcpy(c,
"-hdr.dng",
sizeof(pathname) - (c - pathname));
583 (
const uint8_t (*)[6])
d.first_xtrans,
585 (
const float (*))
d.wb_coeffs,
591 while(*c !=
'/' && c > pathname) c--;
595 gchar *directory = g_path_get_dirname((
const gchar *)pathname);
603 g_list_prepend(NULL, GINT_TO_POINTER(imageid)));
617 GList *
t = params->index;
618 const guint total = g_list_length(
t);
619 double fraction = 0.0f;
620 char message[512] = { 0 };
624 snprintf(message,
sizeof(message), ngettext(
"duplicating %d image",
"duplicating %d images", total), total);
628 const int32_t imgid = GPOINTER_TO_INT(
t->data);
632 if(GPOINTER_TO_INT(params->data))
640 fraction += 1.0 / total;
654 const int cw = params->flag;
655 GList *
t = params->index;
656 const guint total = g_list_length(
t);
657 double fraction = 0.0f;
658 char message[512] = { 0 };
662 snprintf(message,
sizeof(message), ngettext(
"flipping %d image",
"flipping %d images", total), total);
666 const int32_t imgid = GPOINTER_TO_INT(
t->data);
669 fraction += 1.0 / total;
680 const int32_t mode = params->flag;
681 GList *
t = params->index;
682 const guint total = g_list_length(
t);
683 char message[512] = { 0 };
684 double fraction = 0.0f;
689 snprintf(message,
sizeof(message), ngettext(
"set %d color image",
"setting %d color images", total), total);
691 snprintf(message,
sizeof(message), ngettext(
"set %d monochrome image",
"setting %d monochrome images", total), total);
696 const int32_t imgid = GPOINTER_TO_INT(
t->data);
703 fprintf(stderr,
"[dt_control_monochrome_images_job_run] got illegal imgid %i\n", imgid);
706 fraction += 1.0 / total;
713 g_list_copy(params->index));
720 const guint
size = g_list_length(l);
722 char *buffer = calloc(
size,
sizeof(num));
723 gboolean first =
TRUE;
729 const int32_t imgid = GPOINTER_TO_INT(l->data);
730 snprintf(num,
sizeof(num),
"%s%6d", first ?
"" :
",", imgid);
731 g_strlcat(buffer, num,
size *
sizeof(num));
740 sqlite3_stmt *stmt = NULL;
742 "UPDATE main.images SET flags = (flags|?1) WHERE id IN (?2)", -1, &stmt, NULL);
746 sqlite3_finalize(stmt);
751 sqlite3_stmt *stmt = NULL;
755 "SELECT DISTINCT folder || '" G_DIR_SEPARATOR_S
"' || filename FROM "
756 "main.images i, main.film_rolls f "
757 "ON i.film_id = f.id WHERE i.id IN (?1)",
761 while(sqlite3_step(stmt) == SQLITE_ROW)
763 list = g_list_prepend(list, g_strdup((
const gchar *)sqlite3_column_text(stmt, 0)));
765 sqlite3_finalize(stmt);
766 return g_list_reverse(list);
772 GList *
t = params->index;
774 const guint total = g_list_length(
t);
775 char message[512] = { 0 };
776 snprintf(message,
sizeof(message), ngettext(
"removing %d image",
"removing %d images", total), total);
778 sqlite3_stmt *stmt = NULL;
781 gboolean remove_ok =
TRUE;
783 "SELECT id FROM main.images WHERE id IN (?2) AND flags&?1=?1", -1, &stmt, NULL);
787 while(sqlite3_step(stmt) == SQLITE_ROW)
789 const int32_t imgid = sqlite3_column_int(stmt, 0);
796 sqlite3_finalize(stmt);
800 dt_control_log(_(
"cannot remove local copy when the original file is not accessible."));
815 double fraction = 0.0f;
818 int32_t imgid = GPOINTER_TO_INT(
t->data);
821 fraction += 1.0 / total;
827 char *imgname = (
char *)list->data;
829 list = g_list_delete_link(list, list);
833 g_list_copy(params->index));
874 GtkWidget *dialog = gtk_message_dialog_new(
876 GTK_DIALOG_DESTROY_WITH_PARENT,
877 GTK_MESSAGE_QUESTION,
880 ? _(
"could not send %s to trash.%s%s")
881 : _(
"could not physically delete %s.%s%s"),
885#ifdef GDK_WINDOWING_QUARTZ
898 gtk_window_set_title(
901 ? _(
"trashing error")
902 : _(
"deletion error"));
903 modal_dialog->
dialog_result = gtk_dialog_run(GTK_DIALOG(dialog));
904 gtk_widget_destroy(dialog);
906 pthread_cond_signal(&modal_dialog->
cond);
924 pthread_cond_init(&modal_dialog.
cond, NULL);
934 pthread_cond_destroy(&modal_dialog.
cond);
943 GFile *gfile = g_file_new_for_path(filename);
948 gboolean delete_success =
FALSE;
949 GError *gerror = NULL;
957 delete_success = g_file_trash(gfile, NULL , &gerror);
962 delete_success = g_file_delete(gfile, NULL , &gerror);
967 || g_error_matches(gerror, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
971 else if(send_to_trash && *delete_on_trash_error)
975 send_to_trash =
FALSE;
979 const char *filename_display = NULL;
980 GFileInfo *gfileinfo = g_file_query_info(
982 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
983 G_FILE_QUERY_INFO_NONE,
987 filename_display = g_file_info_get_attribute_string(
989 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
993 IS_NULL_PTR(filename_display) ? filename : filename_display,
995 g_object_unref(gfileinfo);
1000 send_to_trash =
FALSE;
1006 send_to_trash =
FALSE;
1007 *delete_on_trash_error =
TRUE;
1023 g_error_free(gerror);
1027 g_object_unref(gfile);
1029 return delete_status;
1036 GList *
t = params->index;
1038 char imgidstr[25] = { 0 };
1039 const guint total = g_list_length(
t);
1040 double fraction = 0.0f;
1041 char message[512] = { 0 };
1042 gboolean delete_on_trash_error =
FALSE;
1044 snprintf(message,
sizeof(message), ngettext(
"trashing %d image",
"trashing %d images", total), total);
1046 snprintf(message,
sizeof(message), ngettext(
"deleting %d image",
"deleting %d images", total), total);
1059 "SELECT COUNT(*) FROM main.images WHERE filename IN (SELECT filename FROM "
1060 "main.images WHERE id = ?1) AND film_id IN (SELECT film_id FROM main.images WHERE "
1061 "id = ?1)", -1, &stmt, NULL);
1065 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1067 gboolean from_cache =
FALSE;
1071 char *dirname = g_path_get_dirname(filename);
1076 if(sqlite3_step(stmt) == SQLITE_ROW) duplicates = sqlite3_column_int(stmt, 0);
1077 sqlite3_reset(stmt);
1078 sqlite3_clear_bindings(stmt);
1085 goto delete_next_file;
1087 snprintf(imgidstr,
sizeof(imgidstr),
"%d", imgid);
1094 goto delete_next_file;
1102 for(GList *file_iter = files; file_iter; file_iter = g_list_next(file_iter))
1118 g_strlcat(filename,
".xmp",
sizeof(filename));
1121 snprintf(imgidstr,
sizeof(imgidstr),
"%d", imgid);
1134 fraction += 1.0 / total;
1140 sqlite3_finalize(stmt);
1144 char *imgname = (
char *)list->data;
1146 list = g_list_delete_link(list, list);
1152 g_list_copy(params->index));
1161 GList *
t = params->index;
1165 const gchar *filename =
d->filename;
1166 const gchar *tz =
d->tz;
1178 GTimeZone *tz_camera = (
IS_NULL_PTR(tz)) ? g_time_zone_new_utc() : g_time_zone_new(tz);
1187 int32_t imgid = GPOINTER_TO_INT(
t->data);
1198 GDateTime *utc_time = g_date_time_to_timezone(exif_time,
darktable.
utc_tz);
1199 g_date_time_unref(exif_time);
1207 for(GList *grp = grps; grp; grp = g_list_next(grp))
1209 imgs = g_list_prepend(imgs, grp->data);
1210 g_array_append_val(gloc, geoloc);
1216 g_date_time_unref(utc_time);
1217 }
while((
t = g_list_next(
t)) != NULL);
1218 imgs = g_list_reverse(imgs);
1222 dt_control_log(ngettext(
"applied matched GPX location onto %d image",
1223 "applied matched GPX location onto %d images", cntr), cntr);
1225 g_time_zone_unref(tz_camera);
1227 g_array_unref(gloc);
1240 _(
"moving %d images"));
1246 _(
"copying %d images"));
1252 GList *
t = params->index;
1254 const guint total = g_list_length(
t);
1255 double fraction = 0;
1256 const gboolean is_copy = params->flag == 1;
1257 char message[512] = { 0 };
1260 snprintf(message,
sizeof(message),
1261 ngettext(
"creating local copy of %d image",
"creating local copies of %d images", total), total);
1263 snprintf(message,
sizeof(message),
1264 ngettext(
"removing local copy of %d image",
"removing local copies of %d images", total), total);
1271 gboolean tag_change =
FALSE;
1274 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1291 fraction += 1.0 / total;
1296 g_list_copy(params->index));
1306 GList *
t = params->index;
1307 const guint total = g_list_length(
t);
1308 double fraction = 0.0f;
1309 char message[512] = { 0 };
1310 snprintf(message,
sizeof(message), ngettext(
"refreshing info for %d image",
"refreshing info for %d images", total), total);
1314 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1317 gboolean from_cache =
TRUE;
1319 dt_image_full_path(imgid, sourcefile,
sizeof(sourcefile), &from_cache, __FUNCTION__);
1332 const uint32_t file_class_flags
1336 img->
flags &= ~file_class_flags;
1341 fprintf(stderr,
"[dt_control_refresh_exif_run] couldn't dt_image_cache_get for imgid %i\n", imgid);
1346 fprintf(stderr,
"[dt_control_refresh_exif_run] illegal imgid %i\n", imgid);
1349 fraction += 1.0 / total;
1353 g_list_copy(params->index));
1364 GList *
t = params->index;
1371 gboolean tag_change =
FALSE;
1376 if(mstorage->initialize_store)
1378 if(mstorage->initialize_store(mstorage, sdata, &mformat, &fdata, &
t,
TRUE))
1383 mformat->set_params(mformat, fdata, mformat->params_size(mformat));
1384 mstorage->set_params(mstorage, sdata, mstorage->params_size(mstorage));
1388 uint32_t w, h, fw, fh, sw, sh;
1389 fw = fh = sw = sh = 0;
1390 mstorage->dimension(mstorage, sdata, &sw, &sh);
1391 mformat->dimension(mformat, fdata, &fw, &fh);
1393 if(sw == 0 || fw == 0)
1394 w = sw > fw ? sw : fw;
1396 w = sw < fw ? sw : fw;
1398 if(sh == 0 || fh == 0)
1399 h = sh > fh ? sh : fh;
1401 h = sh < fh ? sh : fh;
1403 const guint total = g_list_length(
t);
1405 dt_control_log(ngettext(
"exporting %d image..",
"exporting %d images..", total), total);
1409 double fraction = 0;
1417 guint tagid = 0, etagid = 0;
1425 metadata.
flags = strtol(metadata.
list->data, NULL, 16);
1426 metadata.
list = g_list_remove(metadata.
list, metadata.
list->data);
1431 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1433 const guint num = total - g_list_length(
t);
1436 char message[512] = { 0 };
1437 snprintf(message,
sizeof(message), _(
"exporting %d / %d to %s"), num, total, mstorage->name(mstorage));
1453 char imgfilename[
PATH_MAX] = { 0 };
1454 gboolean from_cache =
TRUE;
1456 if(!g_file_test(imgfilename, G_FILE_TEST_IS_REGULAR))
1459 fprintf(stderr,
"image `%s' is currently unavailable\n", imgfilename);
1466 if(mstorage->store(mstorage, sdata, imgid, mformat, fdata, num, total,
TRUE,
1473 fraction += 1.0 / total;
1474 if(fraction > 1.0) fraction = 1.0;
1478 metadata.
list = NULL;
1480 if(mstorage->finalize_store) mstorage->finalize_store(mstorage, sdata);
1484 mformat->free_params(mformat, fdata);
1513 params->data = NULL;
1523 const gchar *tz, GList *imgs)
1540 params->index = imgs;
1542 data->
filename = g_strdup(filename);
1543 data->
tz = g_strdup(tz);
1552 N_(
"save history to XMP"),
1558 (
void)check_history;
1571 params->index = g_list_copy((GList *)imgids);
1616 dt_control_log(_(
"removing images from library is only possible in Lighttable view"));
1629 const int number = g_list_length(e->
index);
1636 dialog = gtk_message_dialog_new(
1637 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1638 ngettext(
"Do you really want to remove %d image from Ansel library ?\nThe files will not be deleted on disk.",
1639 "Do you really want to remove %d images from Ansel library ?\nThe files will not be deletetd on disk.", number),
1641#ifdef GDK_WINDOWING_QUARTZ
1645 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(_(
"Remove image from library ?"), _(
"Remove images from library ?"), number));
1646 gint res = gtk_dialog_run(GTK_DIALOG(dialog));
1647 gtk_widget_destroy(dialog);
1648 if(res != GTK_RESPONSE_YES)
1662 dt_control_log(_(
"Deleting images from library is only possible in Lighttable view"));
1675 const int number = g_list_length(e->
index);
1684 dialog = gtk_message_dialog_new(
1685 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1686 ngettext(
"Do you really want to physically delete %d image ?\nThe system trash bin will be used if possible.",
1687 "Do you really want to physically delete %d images ?\nThe system trash bin will be used if possible.", number),
1689#ifdef GDK_WINDOWING_QUARTZ
1693 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(_(
"Remove image from disk ?"), _(
"Remove images from disk ?"), number));
1694 gint res = gtk_dialog_run(GTK_DIALOG(dialog));
1695 gtk_widget_destroy(dialog);
1696 if(res != GTK_RESPONSE_YES)
1709 dt_control_log(_(
"Deleting images from library is only possible in Lighttable view"));
1728 dialog = gtk_message_dialog_new(
1729 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1730 send_to_trash ? _(
"do you really want to physically delete selected image (using trash if possible)?")
1731 : _(
"do you really want to physically delete selected image from disk?"));
1732#ifdef GDK_WINDOWING_QUARTZ
1736 gtk_window_set_title(GTK_WINDOW(dialog), _(
"delete image?"));
1737 gint res = gtk_dialog_run(GTK_DIALOG(dialog));
1738 gtk_widget_destroy(dialog);
1739 if(res != GTK_RESPONSE_YES)
1757 const int number = g_list_length(e->
index);
1764 GtkFileChooserNative *filechooser = gtk_file_chooser_native_new(
1765 _(
"select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1766 _(
"_select as destination"), _(
"_cancel"));
1769 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
1771 dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
1774 g_object_unref(filechooser);
1776 if(
IS_NULL_PTR(dir) || !g_file_test(dir, G_FILE_TEST_IS_DIR))
goto abort;
1784 GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT,
1785 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1786 ngettext(
"do you really want to physically move %d image to %s?\n"
1787 "(all duplicates will be moved along)",
1788 "do you really want to physically move %d images to %s?\n"
1789 "(all duplicates will be moved along)",
1792#ifdef GDK_WINDOWING_QUARTZ
1795 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(
"move image?",
"move images?", number));
1797 gint res = gtk_dialog_run(GTK_DIALOG(dialog));
1798 gtk_widget_destroy(dialog);
1800 if(res != GTK_RESPONSE_YES)
goto abort;
1819 const int number = g_list_length(e->
index);
1826 GtkFileChooserNative *filechooser = gtk_file_chooser_native_new(
1827 _(
"select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1828 _(
"_select as destination"), _(
"_cancel"));
1831 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
1833 dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
1836 g_object_unref(filechooser);
1838 if(
IS_NULL_PTR(dir) || !g_file_test(dir, G_FILE_TEST_IS_DIR))
goto abort;
1846 GtkWidget *dialog = gtk_message_dialog_new(
1847 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1848 ngettext(
"do you really want to physically copy %d image to %s?",
1849 "do you really want to physically copy %d images to %s?", number),
1851#ifdef GDK_WINDOWING_QUARTZ
1854 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(
"copy image?",
"copy images?", number));
1856 gint res = gtk_dialog_run(GTK_DIALOG(dialog));
1857 gtk_widget_destroy(dialog);
1859 if(res != GTK_RESPONSE_YES)
goto abort;
1916 mstorage->free_params(mstorage, sdata);
1925void dt_control_export(GList *imgid_list,
int max_width,
int max_height,
int format_index,
int storage_index,
1926 gboolean high_quality, gboolean export_masks,
char *style,
1940 params->index = imgid_list;
1953 dt_control_log(_(
"failed to get parameters from storage module `%s', aborting export.."),
1954 mstorage->name(mstorage));
1958 data->
sdata = sdata;
1960 g_strlcpy(data->
style, style,
sizeof(data->
style));
1970 mstorage->export_dispatched(mstorage);
1981 GDateTime *datetime_new = g_date_time_add(datetime_original, offset);
1982 g_date_time_unref(datetime_original);
1986 gchar *datetime = g_date_time_format(datetime_new,
"%Y:%m:%d %H:%M:%S,%f");
1988 g_date_time_unref(datetime_new);
1999 GList *
t = params->index;
2002 char message[512] = { 0 };
2010 const guint total = g_list_length(
t);
2012 const char *mes11 = offset ? N_(
"adding time offset to %d image") : N_(
"setting date/time of %d image");
2013 const char *mes12 = offset ? N_(
"adding time offset to %d images") : N_(
"setting date/time of %d images");
2014 snprintf(message,
sizeof(message), ngettext(mes11, mes12, total), total);
2022 for(GList *img =
t; img; img = g_list_next(img))
2026 if(!odt[0])
continue;
2030 if(!ndt[0])
continue;
2034 for(GList *grp = grps; grp; grp = g_list_next(grp))
2036 imgs = g_list_prepend(imgs, grp->data);
2037 g_array_append_val(dtime, ndt);
2043 imgs = g_list_reverse(imgs);
2048 imgs = g_list_copy(
t);
2051 cntr = g_list_length(imgs);
2055 const char *mes21 = offset ? N_(
"added time offset to %d image") : N_(
"set date/time of %d image");
2056 const char *mes22 = offset ? N_(
"added time offset to %d images") : N_(
"set date/time of %d images");
2099 params->index = imgs;
2109 params->data = data;
GList * dt_act_on_get_images()
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
void dt_collection_deserialize(const char *buf)
int dt_collection_update(const dt_collection_t *collection)
@ DT_COLLECTION_PROP_LOCAL_COPY
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_RELOAD
dt_colorspaces_color_profile_type_t
static const dt_colormatrix_t M
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_history_delete_on_image(int32_t imgid)
int32_t dt_image_move(const int32_t imgid, const int32_t filmid)
int32_t dt_image_import(const int32_t film_id, const char *filename, gboolean raise_signals)
void dt_image_path_append_version(const int32_t imgid, char *pathname, size_t pathname_len)
int dt_image_write_sidecar_file(const int32_t imgid)
int32_t dt_image_copy(const int32_t imgid, const int32_t filmid)
void dt_image_get_datetime(const int32_t imgid, char *datetime)
void dt_image_synch_all_xmp(const gchar *pathname)
void dt_image_set_datetimes(const GList *imgs, const GArray *dtime, const gboolean undo_on)
GList * dt_image_find_xmps(const char *filename)
void dt_image_set_datetime(const GList *imgs, const char *datetime, const gboolean undo_on)
void dt_image_set_monochrome_flag(const int32_t imgid, gboolean monochrome)
void dt_image_set_images_locations(const GList *imgs, const GArray *gloc, const gboolean undo_on)
int dt_image_local_copy_set(const int32_t imgid)
void dt_image_remove(const int32_t imgid)
int dt_image_local_copy_reset(const int32_t imgid)
gboolean dt_image_get_xmp_mode()
gboolean dt_image_safe_remove(const int32_t imgid)
void dt_image_flip(const int32_t imgid, const int32_t cw)
int32_t dt_image_duplicate(const int32_t imgid)
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
int dt_conf_get_bool(const char *name)
void dt_conf_set_folder_from_file_chooser(const char *name, GtkFileChooser *chooser)
gboolean dt_conf_is_equal(const char *name, const char *value)
gboolean dt_conf_get_folder_to_file_chooser(const char *name, GtkFileChooser *chooser)
void dt_control_log(const char *msg,...)
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
static dt_job_t * _control_gpx_apply_job_create(const gchar *filename, int32_t filmid, const gchar *tz, GList *imgs)
void dt_control_move_images()
static int32_t dt_control_remove_images_job_run(dt_job_t *job)
void dt_control_refresh_exif()
static gboolean _dt_delete_dialog_main_thread(gpointer user_data)
void dt_control_duplicate_images(gboolean virgin)
void dt_control_export(GList *imgid_list, int max_width, int max_height, int format_index, int storage_index, gboolean high_quality, gboolean export_masks, char *style, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, const gchar *metadata_export)
static int32_t dt_control_refresh_exif_run(dt_job_t *job)
static dt_job_t * dt_control_datetime_job_create(const GTimeSpan offset, const char *datetime, GList *imgs)
static dt_job_t * dt_control_generic_image_job_create(dt_job_execute_callback execute, const char *message, int flag, gpointer data, progress_type_t progress_type, int32_t imgid)
static dt_control_image_enumerator_t * dt_control_export_alloc()
void dt_control_gpx_apply(const gchar *filename, int32_t filmid, const gchar *tz, GList *imgs)
void dt_control_monochrome_images(const int32_t mode)
void * dt_control_image_enumerator_alloc()
void dt_control_write_sidecar_files()
static int dt_control_merge_hdr_bpp(dt_imageio_module_data_t *data)
static int32_t dt_control_export_job_run(dt_job_t *job)
void dt_control_delete_image(int32_t imgid)
static const char * dt_control_merge_hdr_mime(dt_imageio_module_data_t *data)
static int32_t dt_control_delete_images_job_run(dt_job_t *job)
void dt_control_reset_local_copy_images()
static int32_t dt_control_duplicate_images_job_run(dt_job_t *job)
static int32_t dt_control_datetime_job_run(dt_job_t *job)
void dt_control_image_enumerator_cleanup(void *p)
static int32_t dt_control_merge_hdr_job_run(dt_job_t *job)
static int32_t dt_control_local_copy_images_job_run(dt_job_t *job)
static int32_t dt_control_monochrome_images_job_run(dt_job_t *job)
static gint _dt_delete_file_display_modal_dialog(int send_to_trash, const char *filename, const char *error_message)
void dt_control_set_local_copy_images()
void dt_control_datetime(const GTimeSpan offset, const char *datetime, GList *imgs)
static void _add_datetime_offset(const char *odt, const long int offset, char *ndt)
static char * _get_image_list(GList *l)
void dt_control_save_xmp(const int32_t imgid)
static int32_t dt_control_copy_images_job_run(dt_job_t *job)
static dt_job_t * dt_control_generic_images_job_create(dt_job_execute_callback execute, const char *message, int flag, gpointer data, progress_type_t progress_type, gboolean only_visible)
static GList * _get_full_pathname(char *imgs)
static int32_t dt_control_save_xmps_job_run(dt_job_t *job)
static dt_control_image_enumerator_t * dt_control_gpx_apply_alloc()
static void dt_control_gpx_apply_job_cleanup(void *p)
void dt_control_delete_images()
static int32_t dt_control_move_images_job_run(dt_job_t *job)
gboolean dt_control_remove_images()
static int dt_control_merge_hdr_process(dt_imageio_module_data_t *datai, const char *filename, const void *const ivoid, dt_colorspaces_color_profile_type_t over_type, const char *over_filename, void *exif, int exif_len, int32_t imgid, int num, int total, dt_dev_pixelpipe_t *pipe, const gboolean export_masks)
void dt_control_merge_hdr()
static float envelope(const float xx)
static int32_t dt_control_flip_images_job_run(dt_job_t *job)
static void _set_remove_flag(char *imgs)
@ _DT_DELETE_STATUS_SKIP_FILE
@ _DT_DELETE_STATUS_STOP_PROCESSING
@ _DT_DELETE_STATUS_OK_TO_REMOVE
@ _DT_DELETE_STATUS_UNKNOWN
void dt_control_flip_images(const int32_t cw)
static void * dt_control_datetime_alloc()
void dt_control_copy_images()
static void dt_control_datetime_job_cleanup(void *p)
void dt_control_save_xmps(const GList *imgids, const gboolean check_history)
static enum _dt_delete_status delete_file_from_disk(const char *filename, gboolean *delete_on_trash_error)
@ _DT_DELETE_DIALOG_CHOICE_REMOVE
@ _DT_DELETE_DIALOG_CHOICE_CONTINUE
@ _DT_DELETE_DIALOG_CHOICE_DELETE_ALL
@ _DT_DELETE_DIALOG_CHOICE_STOP
@ _DT_DELETE_DIALOG_CHOICE_DELETE
static void dt_control_image_enumerator_job_film_init(dt_control_image_enumerator_t *t, int32_t filmid)
static int32_t dt_control_gpx_apply_job_run(dt_job_t *job)
static int32_t _generic_dt_control_fileop_images_job_run(dt_job_t *job, int32_t(*fileop_callback)(const int32_t, const int32_t), const char *desc, const char *desc_pl)
static void dt_control_export_cleanup(void *p)
static int dt_control_merge_hdr_levels(dt_imageio_module_data_t *data)
static void dt_free_gpointer(gpointer ptr)
#define __OMP_PARALLEL_FOR__(...)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static int FCxtrans(const int row, const int col, global const unsigned char(*const xtrans)[6])
sqlite3 * dt_database_get(const dt_database_t *db)
GDateTime * dt_datetime_exif_to_gdatetime(const char *exif, const GTimeZone *tz)
GDateTime * dt_datetime_img_to_gdatetime(const dt_image_t *img, const GTimeZone *tz)
#define DT_DATETIME_LENGTH
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_cond_wait(pthread_cond_t *cond, dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
boolean dt_win_file_trash(GFile *file, GCancellable *cancellable, GError **error)
static void weight(const float *c1, const float *c2, const float sharpen, dt_aligned_pixel_t weight)
int dt_exif_read(dt_image_t *img, const char *path)
int dt_exif_read_blob(uint8_t **buf, const char *path, const int32_t imgid, const int sRGB, const int out_width, const int out_height, const int dng_mode)
int dt_film_new(dt_film_t *film, const char *directory)
void dt_film_remove_empty()
void dt_gpx_destroy(struct dt_gpx_t *gpx)
gboolean dt_gpx_get_location(struct dt_gpx_t *gpx, GDateTime *timestamp, dt_image_geoloc_t *geoloc)
dt_gpx_t * dt_gpx_new(const gchar *filename)
void dt_grouping_add_grouped_images(GList **images)
GList * dt_grouping_get_group_images(const int32_t imgid)
void dt_ui_notify_user()
draw user's attention
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
gboolean dt_history_copy_and_paste_on_image(const int32_t imgid, const int32_t dest_imgid, GList *ops, const gboolean copy_full, const dt_history_merge_strategy_t mode, const gboolean copy_iop_order, dt_hm_batch_state_t *batch)
@ DT_HISTORY_MERGE_REPLACE
@ DT_IMAGE_HAS_ADDITIONAL_DNG_TAGS
@ DT_IMAGE_MONOCHROME_BAYER
@ DT_IMAGE_BUFFER_RESOLVED
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_cache_set_export_timestamp(dt_image_cache_t *cache, const int32_t imgid)
void dt_image_cache_write_release(dt_image_cache_t *cache, dt_image_t *img, dt_image_cache_write_mode_t mode)
int dt_imageio_export_with_flags(const int32_t imgid, const char *filename, dt_imageio_module_format_t *format, dt_imageio_module_data_t *format_params, const gboolean ignore_exif, const gboolean display_byteorder, const gboolean high_quality, gboolean is_scaling, const gboolean thumbnail_export, const char *filter, const gboolean copy_metadata, const gboolean export_masks, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, dt_imageio_module_storage_t *storage, dt_imageio_module_data_t *storage_params, int num, int total, dt_export_metadata_t *metadata, dt_atomic_int *shutdown)
static void dt_imageio_write_dng(const char *filename, const float *const pixel, const int wd, const int ht, void *exif, const int exif_len, const uint32_t filter, const uint8_t xtrans[6][6], const float whitelevel, const dt_aligned_pixel_t wb_coeffs, const float adobe_XYZ_to_CAM[4][3])
dt_imageio_module_storage_t * dt_imageio_get_storage_by_index(int index)
dt_imageio_module_format_t * dt_imageio_get_format_by_index(int index)
dt_job_state_t dt_control_job_get_state(_dt_job_t *job)
void dt_control_job_cancel(_dt_job_t *job)
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_progress(dt_job_t *job, double value)
void dt_control_job_add_progress(dt_job_t *job, const char *message, gboolean cancellable)
void dt_control_job_set_progress_message(dt_job_t *job, const char *message)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
void dt_control_job_dispose(_dt_job_t *job)
@ DT_JOB_QUEUE_USER_EXPORT
int32_t(* dt_job_execute_callback)(dt_job_t *)
float *const restrict const size_t k
float dt_aligned_pixel_t[4]
gboolean dt_osx_file_trash(const char *filename, GError **error)
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_DEVELOP_IMAGE_CHANGED
This signal is raised when image is changed in darkroom.
@ DT_SIGNAL_FILMROLLS_CHANGED
This signal is raised when a filmroll is deleted/changed but not imported.
@ DT_SIGNAL_GEOTAG_CHANGED
This signal is raised when a geotag is added/deleted/changed
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
struct _GtkWidget GtkWidget
const char * error_message
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_view_manager_t * view_manager
struct dt_control_t * control
char datetime[DT_DATETIME_LENGTH]
dt_iop_color_intent_t icc_intent
dt_imageio_module_data_t * sdata
dt_colorspaces_color_profile_type_t icc_type
char camera_makermodel[128]
uint8_t first_xtrans[6][6]
dt_aligned_pixel_t wb_coeffs
dt_image_orientation_t orientation
float adobe_XYZ_to_CAM[4][3]
dt_image_orientation_t orientation
float adobe_XYZ_to_CAM[4][3]
char filename[DT_MAX_FILENAME_LEN]
dt_aligned_pixel_t wb_coeffs
dt_iop_buffer_type_t datatype
Region of interest passed through the pixelpipe.
void dt_undo_end_group(dt_undo_t *self)
void dt_undo_start_group(dt_undo_t *self, dt_undo_type_t type)
GList * dt_util_str_to_glist(const gchar *separator, const gchar *text)
size_t safe_strlen(const char *str)
check if the string is empty or NULL before calling strlen()