113#include <glib/gstdio.h>
125#define INIT_UPDATE_INTERVAL 2
126#define MAX_UPDATE_INTERVAL 3.0
130#define PROGRESS_UPDATE_INTERVAL 1
163 for(GList *l = ids; l; l = g_list_next(l))
164 t->index = g_list_append(
t->index, l->data);
169 int32_t (*fileop_callback)(
const int32_t,
171 const char *desc,
const char *desc_pl)
174 GList *
t = params->index;
175 const guint total = g_list_length(
t);
176 char message[512] = { 0 };
178 gchar *newdir = (gchar *)params->data;
180 g_snprintf(message,
sizeof(message), ngettext(desc, desc_pl, total), total);
185 const int32_t film_id =
dt_film_new(&new_film, newdir);
190 dt_control_log(_(
"failed to create film roll for destination directory, aborting move.."));
194 gboolean completeSuccess =
TRUE;
197 completeSuccess &= (fileop_callback(GPOINTER_TO_INT(
t->data), film_id) != -1);
199 fraction += 1.0 / total;
206 snprintf(collect,
sizeof(collect),
"1:0:0:%s$", new_film.
dirname);
212 g_list_copy(params->index));
230 g_list_free(params->index);
231 params->index = NULL;
233 params->index = NULL;
242 gboolean only_visible)
278 params->index = g_list_append(NULL, GINT_TO_POINTER(imgid));
291 const gboolean forced = (params->flag == 1);
295 for(GList *
t = params->index;
t;
t = g_list_next(
t))
297 const int32_t imgid = GPOINTER_TO_INT(
t->data);
309 dt_control_log(_(
"cannot write XMP file for image %i: the image cache entry is busy, try again."), imgid);
312 dt_control_log(_(
"cannot write XMP file for image %i: the original file could not be found."), imgid);
315 dt_control_log(_(
"cannot write XMP file for image %i: the target storage may be unavailable or read-only."),
377 const float x =
CLAMPS(xx, 0.0f, 1.0f);
379 const float beta = 0.5f;
383 const float tmp = fabsf(
x / beta - 1.0f);
384 return 1.0f - tmp * tmp;
388 const float tmp1 = (1.0f -
x) / (1.0f - beta);
389 const float tmp2 = tmp1 * tmp1;
390 const float tmp3 = tmp2 * tmp1;
391 return 3.0f * tmp2 - 2.0f * tmp3;
396 const void *
const ivoid,
398 void *exif,
int exif_len, int32_t imgid,
int num,
int total,
411 d->first_imgid = imgid;
423 d->pixels = calloc((
size_t)datai->
width * datai->
height,
sizeof(
float));
424 d->weight = calloc((
size_t)datai->
width * datai->
height,
sizeof(
float));
428 for(
int i = 0;
i < 3;
i++)
430 for(
int k=0;
k<4;
k++)
431 for(
int i=0;
i<3;
i++)
437 dt_control_log(_(
"exposure bracketing only works on raw images."));
444 dt_control_log(_(
"images have to be of same size and orientation!"));
453 const float rad = .5f * efl / eap;
454 const float aperture =
M_PI * rad * rad;
457 const float cal = 100.0f / (aperture * exp * iso);
459 const float photoncnt = 100.0f * aperture * exp / iso;
460 float saturation = 1.0f;
461 d->whitelevel = fmaxf(
d->whitelevel, saturation * cal);
463 for(
int y = 0; y <
d->ht; y++)
464 for(
int x = 0;
x <
d->wd;
x++)
468 const float in = ((
float *)ivoid)[
x +
d->wd * y];
475 float offset = 3000.0f / (float)UINT16_MAX;
480 int xx =
x & ~1, yy = y & ~1;
481 float M = 0.0f,
m = FLT_MAX;
482 if(xx < d->wd - 2 && yy < d->ht - 2)
484 for(
int i = 0;
i < 3;
i++)
485 for(
int j = 0; j < 3; j++)
487 M =
MAX(
M, ((
float *)ivoid)[xx +
i +
d->wd * (yy + j)]);
488 m =
MIN(
m, ((
float *)ivoid)[xx +
i +
d->wd * (yy + j)]);
493 w *=
d->epsw +
envelope((
M + offset) / saturation);
496 if(
M + offset >= saturation)
498 if(
d->weight[
x +
d->wd * y] <= 0.0f)
500 if(
d->weight[
x +
d->wd * y] == 0 || m < -d->
weight[
x +
d->wd * y])
502 if(
m + offset >= saturation)
503 d->pixels[
x +
d->wd * y] = 1.0f;
505 d->pixels[
x +
d->wd * y] = in * cal /
d->whitelevel;
506 d->weight[
x +
d->wd * y]
514 if(
d->weight[
x +
d->wd * y] <= 0.0)
516 d->pixels[
x +
d->wd * y] = 0.0f;
517 d->weight[
x +
d->wd * y] = 0.0f;
519 d->pixels[
x +
d->wd * y] += w * in * cal;
520 d->weight[
x +
d->wd * y] += w;
530 GList *
t = params->index;
531 const guint total = g_list_length(
t);
532 char message[512] = { 0 };
534 snprintf(message,
sizeof(message), ngettext(
"merging %d image",
"merging %d images", total), total);
550 if(
d.abort)
goto end;
552 const int32_t imgid = GPOINTER_TO_INT(
t->data);
554 const gboolean is_scaling =
559 NULL, num, total, NULL, NULL);
564 fraction += 1.0 / (total + 1);
569 if(
d.abort)
goto end;
573 for(
size_t k = 0;
k < (size_t)
d.wd *
d.ht;
k++)
575 if(
d.weight[
k] > 0.0)
d.pixels[
k] = fmaxf(0.0f,
d.pixels[
k] / (
d.whitelevel *
d.weight[
k]));
579 uint8_t *exif = NULL;
581 gboolean from_cache =
TRUE;
587 while(*c !=
'.' && c > pathname) c--;
588 g_strlcpy(c,
"-hdr.dng",
sizeof(pathname) - (c - pathname));
596 (
const uint8_t (*)[6])
d.first_xtrans,
598 (
const float (*))
d.wb_coeffs,
604 while(*c !=
'/' && c > pathname) c--;
608 gchar *
directory = g_path_get_dirname((
const gchar *)pathname);
616 g_list_prepend(NULL, GINT_TO_POINTER(imageid)));
630 GList *
t = params->index;
631 const guint total = g_list_length(
t);
632 double fraction = 0.0f;
633 char message[512] = { 0 };
637 snprintf(message,
sizeof(message), ngettext(
"duplicating %d image",
"duplicating %d images", total), total);
641 const int32_t imgid = GPOINTER_TO_INT(
t->data);
648 if(GPOINTER_TO_INT(params->data))
656 fraction += 1.0 / total;
671 GList *
t = params->index;
672 const guint total = g_list_length(
t);
673 double fraction = 0.0f;
674 char message[512] = { 0 };
678 snprintf(message,
sizeof(message), ngettext(
"flipping %d image",
"flipping %d images", total), total);
682 const int32_t imgid = GPOINTER_TO_INT(
t->data);
685 fraction += 1.0 / total;
696 const int32_t mode = params->flag;
697 GList *
t = params->index;
698 const guint total = g_list_length(
t);
699 char message[512] = { 0 };
700 double fraction = 0.0f;
705 snprintf(message,
sizeof(message), ngettext(
"set %d color image",
"setting %d color images", total), total);
707 snprintf(message,
sizeof(message), ngettext(
"set %d monochrome image",
"setting %d monochrome images", total), total);
712 const int32_t imgid = GPOINTER_TO_INT(
t->data);
719 fprintf(stderr,
"[dt_control_monochrome_images_job_run] got illegal imgid %i\n", imgid);
722 fraction += 1.0 / total;
729 g_list_copy(params->index));
743 GList *resync_imgids = NULL;
746 for(GList *l = pathnames; l; l = g_list_next(l))
749 if(dup_imgid !=
UNKNOWN_IMAGE) resync_imgids = g_list_prepend(resync_imgids, GINT_TO_POINTER(dup_imgid));
754 g_list_free(resync_imgids);
760 GList *
t = params->index;
761 const guint total = g_list_length(
t);
762 char message[512] = { 0 };
763 snprintf(message,
sizeof(message), ngettext(
"removing %d image",
"removing %d images", total), total);
767 gboolean remove_ok =
TRUE;
769 for(GList *l = local_copies; l; l = g_list_next(l))
777 g_list_free(local_copies);
781 dt_control_log(_(
"cannot remove local copy when the original file is not accessible."));
799 double fraction = 0.0f;
802 int32_t imgid = GPOINTER_TO_INT(
t->data);
805 fraction += 1.0 / total;
814 g_list_copy(params->index));
855 GtkWidget *dialog = gtk_message_dialog_new(
857 GTK_DIALOG_DESTROY_WITH_PARENT,
858 GTK_MESSAGE_QUESTION,
861 ? _(
"could not send %s to trash.%s%s")
862 : _(
"could not physically delete %s.%s%s"),
866#ifdef GDK_WINDOWING_QUARTZ
879 gtk_window_set_title(
882 ? _(
"trashing error")
883 : _(
"deletion error"));
884 modal_dialog->
dialog_result = gtk_dialog_run(GTK_DIALOG(dialog));
885 gtk_widget_destroy(dialog);
887 pthread_cond_signal(&modal_dialog->
cond);
905 pthread_cond_init(&modal_dialog.
cond, NULL);
915 pthread_cond_destroy(&modal_dialog.
cond);
924 GFile *gfile = g_file_new_for_path(filename);
929 gboolean delete_success =
FALSE;
930 GError *gerror = NULL;
938 delete_success = g_file_trash(gfile, NULL , &gerror);
943 delete_success = g_file_delete(gfile, NULL , &gerror);
948 || g_error_matches(gerror, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
952 else if(send_to_trash && *delete_on_trash_error)
956 send_to_trash =
FALSE;
960 const char *filename_display = NULL;
961 GFileInfo *gfileinfo = g_file_query_info(
963 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
964 G_FILE_QUERY_INFO_NONE,
968 filename_display = g_file_info_get_attribute_string(
970 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
974 IS_NULL_PTR(filename_display) ? filename : filename_display,
976 g_object_unref(gfileinfo);
981 send_to_trash =
FALSE;
987 send_to_trash =
FALSE;
988 *delete_on_trash_error =
TRUE;
1004 g_error_free(gerror);
1008 g_object_unref(gfile);
1010 return delete_status;
1017 GList *
t = params->index;
1019 const guint total = g_list_length(
t);
1020 double fraction = 0.0f;
1021 char message[512] = { 0 };
1022 gboolean delete_on_trash_error =
FALSE;
1024 snprintf(message,
sizeof(message), ngettext(
"trashing %d image",
"trashing %d images", total), total);
1026 snprintf(message,
sizeof(message), ngettext(
"deleting %d image",
"deleting %d images", total), total);
1037 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1039 gboolean from_cache =
FALSE;
1043 char *dirname = g_path_get_dirname(filename);
1048 const int duplicates = g_list_length(dups);
1056 goto delete_next_file;
1058 GList *one = g_list_prepend(NULL, GINT_TO_POINTER(imgid));
1066 goto delete_next_file;
1074 for(GList *file_iter = files; file_iter; file_iter = g_list_next(file_iter))
1090 g_strlcat(filename,
".xmp",
sizeof(filename));
1093 GList *one = g_list_prepend(NULL, GINT_TO_POINTER(imgid));
1107 fraction += 1.0 / total;
1118 g_list_copy(params->index));
1127 GList *
t = params->index;
1131 const gchar *filename =
d->filename;
1132 const gchar *tz =
d->tz;
1144 GTimeZone *tz_camera = (
IS_NULL_PTR(tz)) ? g_time_zone_new_utc() : g_time_zone_new(tz);
1153 int32_t imgid = GPOINTER_TO_INT(
t->data);
1165 g_date_time_unref(exif_time);
1173 for(GList *grp = grps; grp; grp = g_list_next(grp))
1175 imgs = g_list_prepend(imgs, grp->data);
1176 g_array_append_val(gloc, geoloc);
1182 g_date_time_unref(utc_time);
1183 }
while((
t = g_list_next(
t)) != NULL);
1184 imgs = g_list_reverse(imgs);
1188 dt_control_log(ngettext(
"applied matched GPX location onto %d image",
1189 "applied matched GPX location onto %d images", cntr), cntr);
1191 g_time_zone_unref(tz_camera);
1193 g_array_unref(gloc);
1206 _(
"moving %d images"));
1212 _(
"copying %d images"));
1218 GList *
t = params->index;
1220 const guint total = g_list_length(
t);
1221 double fraction = 0;
1222 const gboolean is_copy = params->flag == 1;
1223 char message[512] = { 0 };
1226 snprintf(message,
sizeof(message),
1227 ngettext(
"creating local copy of %d image",
"creating local copies of %d images", total), total);
1229 snprintf(message,
sizeof(message),
1230 ngettext(
"removing local copy of %d image",
"removing local copies of %d images", total), total);
1237 gboolean tag_change =
FALSE;
1240 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1257 fraction += 1.0 / total;
1262 g_list_copy(params->index));
1272 GList *
t = params->index;
1273 const guint total = g_list_length(
t);
1274 double fraction = 0.0f;
1275 char message[512] = { 0 };
1276 snprintf(message,
sizeof(message), ngettext(
"refreshing info for %d image",
"refreshing info for %d images", total), total);
1280 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1283 gboolean from_cache =
TRUE;
1285 dt_image_full_path(imgid, sourcefile,
sizeof(sourcefile), &from_cache, __FUNCTION__);
1298 const uint32_t file_class_flags
1302 img->
flags &= ~file_class_flags;
1307 fprintf(stderr,
"[dt_control_refresh_exif_run] couldn't dt_image_cache_get for imgid %i\n", imgid);
1312 fprintf(stderr,
"[dt_control_refresh_exif_run] illegal imgid %i\n", imgid);
1315 fraction += 1.0 / total;
1319 g_list_copy(params->index));
1330 GList *
t = params->index;
1337 gboolean tag_change =
FALSE;
1342 if(mstorage->initialize_store)
1344 if(mstorage->initialize_store(mstorage, sdata, &mformat, &fdata, &
t,
TRUE))
1349 mformat->set_params(mformat, fdata, mformat->params_size(mformat));
1350 mstorage->set_params(mstorage, sdata, mstorage->params_size(mstorage));
1354 uint32_t w, h, fw, fh, sw, sh;
1355 fw = fh = sw = sh = 0;
1356 mstorage->dimension(mstorage, sdata, &sw, &sh);
1357 mformat->dimension(mformat, fdata, &fw, &fh);
1359 if(sw == 0 || fw == 0)
1360 w = sw > fw ? sw : fw;
1362 w = sw < fw ? sw : fw;
1364 if(sh == 0 || fh == 0)
1365 h = sh > fh ? sh : fh;
1367 h = sh < fh ? sh : fh;
1369 const guint total = g_list_length(
t);
1371 dt_control_log(ngettext(
"exporting %d image..",
"exporting %d images..", total), total);
1375 double fraction = 0;
1383 guint tagid = 0, etagid = 0;
1391 metadata.
flags = strtol(metadata.
list->data, NULL, 16);
1392 metadata.
list = g_list_remove(metadata.
list, metadata.
list->data);
1397 const int32_t imgid = GPOINTER_TO_INT(
t->data);
1399 const guint num = total - g_list_length(
t);
1402 char message[512] = { 0 };
1403 snprintf(message,
sizeof(message), _(
"exporting %d / %d to %s"), num, total, mstorage->name(mstorage));
1420 gboolean from_cache =
TRUE;
1422 if(!g_file_test(imgfilename, G_FILE_TEST_IS_REGULAR))
1425 fprintf(stderr,
"image `%s' is currently unavailable\n", imgfilename);
1432 if(mstorage->store(mstorage, sdata, imgid, mformat, fdata, num, total,
TRUE,
1439 fraction += 1.0 / total;
1440 if(fraction > 1.0) fraction = 1.0;
1444 metadata.
list = NULL;
1446 if(mstorage->finalize_store) mstorage->finalize_store(mstorage, sdata);
1450 mformat->free_params(mformat, fdata);
1479 params->data = NULL;
1489 const gchar *tz, GList *imgs)
1506 params->index = imgs;
1508 data->
filename = g_strdup(filename);
1509 data->
tz = g_strdup(tz);
1518 N_(
"save history to XMP"),
1524 (
void)check_history;
1537 params->index = g_list_copy((GList *)imgids);
1558 params->index = g_list_copy((GList *)imgids);
1604 dt_control_log(_(
"removing images from library is only possible in Lighttable view"));
1617 const int number = g_list_length(e->
index);
1624 dialog = gtk_message_dialog_new(
1625 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1626 ngettext(
"Do you really want to remove %d image from Ansel library ?\nThe files will not be deleted on disk.",
1627 "Do you really want to remove %d images from Ansel library ?\nThe files will not be deletetd on disk.", number),
1629#ifdef GDK_WINDOWING_QUARTZ
1633 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(_(
"Remove image from library ?"), _(
"Remove images from library ?"), number));
1634 gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
1635 gtk_widget_destroy(dialog);
1636 if(
res != GTK_RESPONSE_YES)
1651 dt_control_log(_(
"Deleting images from library is only possible in Lighttable view"));
1664 const int number = g_list_length(e->
index);
1673 dialog = gtk_message_dialog_new(
1674 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1675 ngettext(
"Do you really want to physically delete %d image ?\nThe system trash bin will be used if possible.",
1676 "Do you really want to physically delete %d images ?\nThe system trash bin will be used if possible.", number),
1678#ifdef GDK_WINDOWING_QUARTZ
1682 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(_(
"Remove image from disk ?"), _(
"Remove images from disk ?"), number));
1683 gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
1684 gtk_widget_destroy(dialog);
1685 if(
res != GTK_RESPONSE_YES)
1699 dt_control_log(_(
"Deleting images from library is only possible in Lighttable view"));
1718 dialog = gtk_message_dialog_new(
1719 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1720 send_to_trash ? _(
"do you really want to physically delete selected image (using trash if possible)?")
1721 : _(
"do you really want to physically delete selected image from disk?"));
1722#ifdef GDK_WINDOWING_QUARTZ
1726 gtk_window_set_title(GTK_WINDOW(dialog), _(
"delete image?"));
1727 gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
1728 gtk_widget_destroy(dialog);
1729 if(
res != GTK_RESPONSE_YES)
1747 const int number = g_list_length(e->
index);
1754 GtkFileChooserNative *filechooser = gtk_file_chooser_native_new(
1755 _(
"select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1756 _(
"_select as destination"), _(
"_cancel"));
1759 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
1761 dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
1764 g_object_unref(filechooser);
1766 if(
IS_NULL_PTR(dir) || !g_file_test(dir, G_FILE_TEST_IS_DIR))
goto abort;
1774 GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT,
1775 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1776 ngettext(
"do you really want to physically move %d image to %s?\n"
1777 "(all duplicates will be moved along)",
1778 "do you really want to physically move %d images to %s?\n"
1779 "(all duplicates will be moved along)",
1782#ifdef GDK_WINDOWING_QUARTZ
1785 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(
"move image?",
"move images?", number));
1787 gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
1788 gtk_widget_destroy(dialog);
1790 if(
res != GTK_RESPONSE_YES)
goto abort;
1809 const int number = g_list_length(e->
index);
1816 GtkFileChooserNative *filechooser = gtk_file_chooser_native_new(
1817 _(
"select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1818 _(
"_select as destination"), _(
"_cancel"));
1821 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
1823 dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
1826 g_object_unref(filechooser);
1828 if(
IS_NULL_PTR(dir) || !g_file_test(dir, G_FILE_TEST_IS_DIR))
goto abort;
1836 GtkWidget *dialog = gtk_message_dialog_new(
1837 GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1838 ngettext(
"do you really want to physically copy %d image to %s?",
1839 "do you really want to physically copy %d images to %s?", number),
1841#ifdef GDK_WINDOWING_QUARTZ
1844 gtk_window_set_title(GTK_WINDOW(dialog), ngettext(
"copy image?",
"copy images?", number));
1846 gint
res = gtk_dialog_run(GTK_DIALOG(dialog));
1847 gtk_widget_destroy(dialog);
1849 if(
res != GTK_RESPONSE_YES)
goto abort;
1906 mstorage->free_params(mstorage, sdata);
1915void dt_control_export(GList *imgid_list,
int max_width,
int max_height,
int format_index,
int storage_index,
1916 gboolean high_quality, gboolean export_masks,
char *style,
1930 params->index = imgid_list;
1943 dt_control_log(_(
"failed to get parameters from storage module `%s', aborting export.."),
1944 mstorage->name(mstorage));
1948 data->
sdata = sdata;
1950 g_strlcpy(data->
style, style,
sizeof(data->
style));
1960 mstorage->export_dispatched(mstorage);
1971 GDateTime *datetime_new = g_date_time_add(datetime_original, offset);
1972 g_date_time_unref(datetime_original);
1976 gchar *datetime = g_date_time_format(datetime_new,
"%Y:%m:%d %H:%M:%S,%f");
1978 g_date_time_unref(datetime_new);
1989 GList *
t = params->index;
1992 char message[512] = { 0 };
2000 const guint total = g_list_length(
t);
2002 const char *mes11 = offset ? N_(
"adding time offset to %d image") : N_(
"setting date/time of %d image");
2003 const char *mes12 = offset ? N_(
"adding time offset to %d images") : N_(
"setting date/time of %d images");
2004 snprintf(message,
sizeof(message), ngettext(mes11, mes12, total), total);
2012 for(GList *img =
t; img; img = g_list_next(img))
2016 if(!odt[0])
continue;
2020 if(!ndt[0])
continue;
2024 for(GList *grp = grps; grp; grp = g_list_next(grp))
2026 imgs = g_list_prepend(imgs, grp->data);
2027 g_array_append_val(dtime, ndt);
2033 imgs = g_list_reverse(imgs);
2038 imgs = g_list_copy(
t);
2041 cntr = g_list_length(imgs);
2045 const char *mes21 = offset ? N_(
"added time offset to %d image") : N_(
"set date/time of %d image");
2046 const char *mes22 = offset ? N_(
"added time offset to %d images") : N_(
"set date/time of %d images");
2089 params->index = imgs;
2099 params->data = data;
GList * dt_act_on_get_images()
GtkWidget * dt_gui_main_window(void)
void dt_ui_notify_user()
draw user's attention
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static void transform(float *x, float *o, const float *m, const float t_h, const float t_v)
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)
dt_collection_t * dt_collection_get_global(void)
int dt_collection_update(const dt_collection_t *collection)
@ DT_COLLECTION_PROP_LOCAL_COPY
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_RELOAD
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static const dt_colormatrix_t M
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)
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)
int32_t dt_image_copy(const int32_t imgid, const int32_t filmid)
int32_t dt_image_duplicate_no_reload(const int32_t imgid)
void dt_image_get_datetime(const int32_t imgid, char *datetime)
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_flip(const int32_t imgid, const dt_image_transform_t transform)
Apply an orientation change to one image, on top of the orientation it already has.
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)
void dt_image_remove_undoable(const int32_t imgid)
Same as dt_image_remove(), and records the removal on the undo stack.
int dt_image_local_copy_set(const int32_t imgid)
dt_image_write_sidecar_result_t dt_image_write_sidecar_file(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()
int32_t dt_image_get_id_full_path(const gchar *filename)
gboolean dt_image_safe_remove(const int32_t imgid)
dt_image_write_sidecar_result_t dt_image_write_sidecar_file_forced(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.
void dt_control_log(const char *msg,...)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
struct dt_control_t * dt_control_get_global(void)
static dt_job_t * _control_gpx_apply_job_create(const gchar *filename, int32_t filmid, const gchar *tz, GList *imgs)
static void _resync_xmp_duplicates(GList *pathnames)
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)
void dt_control_flip_images(const dt_image_transform_t transform)
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)
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 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)
@ _DT_DELETE_STATUS_SKIP_FILE
@ _DT_DELETE_STATUS_STOP_PROCESSING
@ _DT_DELETE_STATUS_OK_TO_REMOVE
@ _DT_DELETE_STATUS_UNKNOWN
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
void dt_control_save_xmps_forced(const GList *imgids)
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)
struct dt_view_manager_t * dt_view_manager_get_global(void)
static int FCxtrans(const int row, const int col, global const unsigned char(*const xtrans)[6])
GDateTime * dt_datetime_exif_to_gdatetime(const char *exif, const GTimeZone *tz)
GTimeZone * dt_datetime_utc_tz(void)
GDateTime * dt_datetime_img_to_gdatetime(const dt_image_t *img, const GTimeZone *tz)
#define DT_DATETIME_LENGTH
gchar * directory
documentation root given after –doc, or NULL
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)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
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)
Wait on cond, releasing mutex for the duration.
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)
What a photograph says about itself: the EXIF, IPTC and XMP tags a camera and a cataloguer write,...
int dt_film_new(dt_film_t *film, const char *directory)
void dt_film_remove_empty()
GList * dt_film_repository_get_image_ids(const int32_t filmid)
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_history_delete_on_image(int32_t imgid)
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
dt_image_write_sidecar_result_t
@ DT_IMAGE_WRITE_SIDECAR_OK
@ DT_IMAGE_WRITE_SIDECAR_IO_ERROR
@ DT_IMAGE_WRITE_SIDECAR_CACHE_BUSY
@ DT_IMAGE_WRITE_SIDECAR_NO_SOURCE_PATH
@ DT_IMAGE_WRITE_SIDECAR_DISABLED
dt_image_transform_t
An orientation change the user asks for, in the coordinates they are looking at.
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
void dt_image_cache_set_export_timestamp(const int32_t imgid)
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
GList * dt_image_repository_get_ids_with_flag_among(GList *imgids, const int flag)
Of the images in imgids, those whose flags carry flag, in row order.
GList * dt_image_repository_get_duplicate_ids(const int32_t imgid)
Every image id sharing imgid's film roll and filename, itself included, in row order – an image and i...
gboolean dt_image_repository_set_flag_among(GList *imgids, const int flag)
Set flag on every image in imgids.
GList * dt_image_repository_get_full_paths(GList *imgids)
"<folder>/<filename>" for every image in imgids, distinct, in row order. Caller owns the strings.
Reading and writing one dt_image_t to and from the library database. The SQL half of what used to be ...
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
#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 void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define __OMP_PARALLEL_FOR__(...)
gboolean dt_osx_file_trash(const char *filename, GError **error)
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
dt_iop_color_intent_t
ICC rendering intent, as stored in iop params and in conf.
@ DT_INTENT_LAST
Count of real intents, and the codebase's "unset" marker – never a user choice.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ 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
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
const char * error_message
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)
dt_undo_t * dt_undo_get_global(void)
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()
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)
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)
The XMP document that carries an image's development: history stack, mask shapes, module order,...