diff --git a/src/control/jobs/control_jobs.c b/src/control/jobs/control_jobs.c index 32a2d195bb69..3c4a38aae11c 100644 --- a/src/control/jobs/control_jobs.c +++ b/src/control/jobs/control_jobs.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2010-2025 darktable developers. + Copyright (C) 2010-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,6 +92,7 @@ typedef struct dt_control_export_t // resets things like overwrite // once the export // is dispatched, but we have to keep that information + void *fdata; gboolean high_quality, upscale, export_masks, is_scaling; double scale_factor; char style[128]; @@ -1815,12 +1816,10 @@ static int32_t _control_export_job_run(dt_job_t *job) dt_imageio_get_storage_by_index(settings->storage_index); g_assert(mstorage); dt_imageio_module_data_t *sdata = settings->sdata; + dt_imageio_module_data_t *fdata = settings->fdata; gboolean tag_change = FALSE; - // get a thread-safe fdata struct (one jpeg struct per thread etc): - dt_imageio_module_data_t *fdata = mformat->get_params(mformat); - if(mstorage->initialize_store) { if(mstorage->initialize_store(mstorage, sdata, &mformat, &fdata, @@ -2553,6 +2552,7 @@ void dt_control_export(GList *imgid_list, data->max_height = max_height; data->format_index = format_index; data->storage_index = storage_index; + dt_imageio_module_storage_t *mstorage = dt_imageio_get_storage_by_index(storage_index); g_assert(mstorage); // get shared storage param struct (global sequence counter, one picasa connection etc) @@ -2565,6 +2565,19 @@ void dt_control_export(GList *imgid_list, return; } data->sdata = sdata; + + dt_imageio_module_format_t *mformat = dt_imageio_get_format_by_index(format_index); + g_assert(mformat); + void *fdata = mformat->get_params(mformat); + if(fdata == NULL) + { + dt_control_log(_("failed to get parameters from format module `%s', aborting export.."), + mformat->name()); + dt_control_job_dispose(job); + return; + } + data->fdata = fdata; + data->high_quality = high_quality; data->export_masks = export_masks; data->upscale = ((max_width == 0 && max_height == 0) diff --git a/src/imageio/storage/disk.c b/src/imageio/storage/disk.c index 36bd4675be09..961309f311b8 100644 --- a/src/imageio/storage/disk.c +++ b/src/imageio/storage/disk.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2010-2025 darktable developers. + Copyright (C) 2010-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include "bauhaus/bauhaus.h" #include "common/darktable.h" +#include "common/datetime.h" #include "common/exif.h" #include "common/image.h" #include "common/image_cache.h" @@ -34,6 +35,7 @@ #include "imageio/imageio_common.h" #include "imageio/imageio_module.h" #include "imageio/storage/imageio_storage_api.h" +#include #ifdef GDK_WINDOWING_QUARTZ #include "osx/osx.h" #endif @@ -452,16 +454,38 @@ int store(dt_imageio_module_storage_t *self, // of the changes. if(g_file_test(filename, G_FILE_TEST_EXISTS)) { + GFile *gfile = g_file_new_for_path(filename); + + GFileInfo *info = g_file_query_info + (gfile, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + + GTimeSpan export_file_timestamp = 0; + + if(info) + { + if (g_file_info_has_attribute(info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) + { + time_t mtime = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED); + GDateTime *gdt = g_date_time_new_from_unix_local(mtime); + export_file_timestamp = dt_datetime_gdatetime_to_gtimespan(gdt); + g_date_time_unref(gdt); + } + g_object_unref(info); + } + g_object_unref(gfile); + // get the image data const dt_image_t *img = dt_image_cache_get(imgid, 'r'); const GTimeSpan change_timestamp = img ? img->change_timestamp : 0; - const GTimeSpan export_timestamp = img ? img->export_timestamp : 0; - dt_image_cache_read_release(img); - // check if the export timestamp in the database is more recent than the change - // date, if yes skip the image - if(export_timestamp > change_timestamp) + // check if the exported file is more recent than the change date. + // if yes skip the image + if(export_file_timestamp > change_timestamp) { dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); dt_print(DT_DEBUG_ALWAYS, "[export_job] skipping (not modified since export) `%s'", filename);