111#include <glib/gstdio.h>
154static void _pop_undo_execute(
const int32_t imgid,
const gboolean before,
const gboolean after);
195 gboolean changed =
FALSE;
225 undomono->
imgid = imgid;
226 undomono->
before = mask_bw;
227 undomono->
after = mask;
233 fprintf(stderr,
"[image] could not dt_image_cache_get imgid %i\n", imgid);
249 for(
int i = 0;
i < count;
i++)
271 return (has_d65 || has_adobe) ?
TRUE :
FALSE;
355 default:
return "unknown";
367 img->
flags &= ~DT_IMAGE_MOSAIC;
447 const char *ctx = context ? context :
"image";
455 const gboolean mosaic = dsc->
filters != 0u;
456 const gboolean xtrans = dsc->
filters == 9u;
457 const gboolean bayer = mosaic && !xtrans;
458 const size_t bpp = dsc->
bpp;
479 const unsigned int flags = (
unsigned int)img->
flags;
482 "[image debug] %s id=%d filename='%s' fullpath='%s'\n",
485 "[image debug] %s size=%dx%d crop=%dx%d+%d+%d orientation=%d psize=%dx%d pixel_aspect=%.6f\n",
489 "[image debug] %s flags=0x%08x raw=%d non_raw=%d ldr=%d hdr=%d sraw=%d 4bayer=%d mosaic=%d xtrans=%d "
490 "bayer=%d mono=%d mono_flags=0x%x mono_workflow=%d mono_preview=%d mono_bayer=%d bw=%d bw_flow=%d "
491 "local_copy=%d has_txt=%d has_wav=%d addl_dng=%d auto_presets=%d no_legacy_presets=%d rejected=%d remove=%d "
492 "has_localcopy=%d has_audio=%d is_hdr_field=%d\n",
493 ctx,
flags, is_raw, !is_raw, is_ldr, is_hdr,
502 "[image debug] %s buf: channels=%u datatype=%s bit_depth=%d bpp=%" G_GSIZE_FORMAT
" filters=%u cst=%d colorspace=%s "
503 "processed_max=[%.4f %.4f %.4f %.4f]\n",
508 "[image debug] %s colorspace=enum:%s d65_color_matrix=[%.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f]\n",
513 "[image debug] %s raw: black=%u separate=[%u %u %u %u] white=%u rawprepare=[%u %u]\n",
518 "[image debug] %s class=%s state=%s needs_rawprepare=%d needs_demosaic=%d is_mosaiced=%d is_sraw=%d has_matrix=%d\n",
527 const char *folder = path + strlen(path);
535 if(*folder == G_DIR_SEPARATOR || *folder ==
'/')
537 if(*folder == G_DIR_SEPARATOR)
540 if(++count >= numparts)
556 if(sqlite3_step(stmt) == SQLITE_ROW)
558 const char *
f = (
char *)sqlite3_column_text(stmt, 0);
559 g_strlcpy(pathname,
f, pathname_len);
561 sqlite3_finalize(stmt);
562 pathname[pathname_len - 1] =
'\0';
570 g_strlcpy(pathname, _(
"orphaned image"), pathname_len);
578 if(sqlite3_step(stmt) == SQLITE_ROW)
580 const char *
f = (
char *)sqlite3_column_text(stmt, 0);
582 g_strlcpy(pathname, c, pathname_len);
586 g_strlcpy(pathname, _(
"orphaned image"), pathname_len);
588 sqlite3_finalize(stmt);
589 pathname[pathname_len - 1] =
'\0';
596 gboolean res =
FALSE;
601 if(!strcmp(config,
"after edit") || !strcmp(config,
"on import") || !strcmp(config,
"always")) res =
TRUE;
604 else if(!strcmp(config,
"TRUE"))
621 gboolean from_cache =
TRUE;
632 g_strlcat(pathname,
".xmp",
sizeof(pathname));
633 return !g_file_test(pathname, G_FILE_TEST_EXISTS);
638 size_t pathname_len, gboolean force_cache)
660 if(!force_cache && img->
fullpath[0] && g_file_test(img->
fullpath, G_FILE_TEST_EXISTS))
662 g_strlcpy(pathname, img->
fullpath, pathname_len);
671 g_strlcpy(pathname, img->
fullpath, pathname_len);
696void dt_image_full_path(
const int32_t imgid,
char *pathname,
size_t pathname_len, gboolean *from_cache,
const char *calling_func)
698 if(imgid < 0)
return;
700 const gboolean prefer_cache = (from_cache && *from_cache);
727 size_t local_copy_len,
char *local_copy_legacy_path,
728 size_t local_copy_legacy_len)
730 if(local_copy_path) local_copy_path[0] =
'\0';
731 if(local_copy_legacy_path) local_copy_legacy_path[0] =
'\0';
734 char *md5_filename = g_compute_checksum_for_string(G_CHECKSUM_MD5, fullpath, strlen(fullpath));
740 const char *c = fullpath + strlen(fullpath);
741 while(*c !=
'.' && c > fullpath) c--;
745 snprintf(local_copy_legacy_path, local_copy_legacy_len,
"%s/img-%d-%s%s", cachedir, imgid, md5_filename, c);
748 snprintf(local_copy_path, local_copy_len,
"%s/img-%s%s", cachedir, md5_filename, c);
759 char *filename = g_strdup(pathname);
761 char *c = pathname + strlen(pathname);
762 while(*c !=
'.' && c > pathname) c--;
763 snprintf(c, pathname + pathname_len - c,
"_%02d", version);
764 c = pathname + strlen(pathname);
765 char *
c2 = filename + strlen(filename);
766 while(*
c2 !=
'.' &&
c2 > filename)
c2--;
767 g_strlcpy(c,
c2, pathname + pathname_len - c);
781 if(sqlite3_step(stmt) == SQLITE_ROW) version = sqlite3_column_int(stmt, 0);
782 sqlite3_finalize(stmt);
818 else if(rating == -1)
863 for(GList *list = (GList *)data; list; list = g_list_next(list))
870 *imgs = g_list_prepend(*imgs, GINT_TO_POINTER(undogeotag->
imgid));
874 ? _(
"geo-location undone for %d images")
875 : _(
"geo-location re-applied to %d images"),
i);
882 for(GList *list = (GList *)data; list; list = g_list_next(list))
889 *imgs = g_list_prepend(*imgs, GINT_TO_POINTER(undodatetime->
imgid));
893 ? _(
"date/time undone for %d images")
894 : _(
"date/time re-applied to %d images"),
i);
910 *imgs = g_list_prepend(*imgs, GINT_TO_POINTER(undo->
new_imgid));
920 *imgs = g_list_prepend(*imgs, GINT_TO_POINTER(undomono->
imgid));
926 GList *l = (GList *)data;
933 for(GList *images = imgs; images; images = g_list_next(images))
935 const int32_t imgid = GPOINTER_TO_INT(images->data);
940 undogeotag->
imgid = imgid;
945 *undo = g_list_append(*undo, undogeotag);
975 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgid));
983 GList **undo,
const gboolean undo_on)
986 for(GList *imgs = (GList *)img; imgs; imgs = g_list_next(imgs))
988 const int32_t imgid = GPOINTER_TO_INT(imgs->data);
993 undogeotag->
imgid = imgid;
998 *undo = g_list_prepend(*undo, undogeotag);
1024 if(imgid <= 0)
return;
1045 if(refresh_filmstrip)
1052 const int iop_flip_MODVER = 2;
1071 for(
const GList *modules =
darktable.
iop; modules; modules = g_list_next(modules))
1074 if(!strcmp(module->op,
"flip"))
1091 "SELECT op_params, enabled"
1092 " FROM main.history"
1093 " WHERE imgid=?1 AND operation='flip'"
1094 " ORDER BY num DESC LIMIT 1", -1,
1098 if(sqlite3_step(stmt) == SQLITE_ROW && sqlite3_column_int(stmt, 1) != 0)
1101 const void *params = sqlite3_column_blob(stmt, 0);
1104 sqlite3_finalize(stmt);
1124 hist->
imgid = imgid;
1170 " FROM main.images AS a JOIN main.images AS b"
1171 " WHERE a.film_id = b.film_id AND a.filename = b.filename"
1172 " AND b.id = ?1 AND a.version = ?2"
1173 " ORDER BY a.id DESC",
1178 if(sqlite3_step(stmt) == SQLITE_ROW)
1180 newid = sqlite3_column_int(stmt, 0);
1182 sqlite3_finalize(stmt);
1185 if(newid != -1)
return newid;
1190 "INSERT INTO main.images"
1191 " (id, group_id, film_id, width, height, filename, maker, model, lens, exposure,"
1192 " aperture, iso, focal_length, focus_distance, datetime_taken, flags,"
1193 " output_width, output_height, crop, raw_parameters, raw_denoise_threshold,"
1194 " raw_auto_bright_threshold, raw_black, raw_maximum,"
1195 " license, sha1sum, orientation, histogram, lightmap,"
1196 " longitude, latitude, altitude, color_matrix, colorspace, version, max_version, history_end,"
1197 " aspect_ratio, exposure_bias, import_timestamp)"
1198 " SELECT NULL, group_id, film_id, width, height, filename, maker, model, lens,"
1199 " exposure, aperture, iso, focal_length, focus_distance, datetime_taken,"
1200 " flags, output_width, output_height, crop, raw_parameters, raw_denoise_threshold,"
1201 " raw_auto_bright_threshold, raw_black, raw_maximum,"
1202 " license, sha1sum, orientation, histogram, lightmap,"
1203 " longitude, latitude, altitude, color_matrix, colorspace, NULL, NULL, 0,"
1204 " aspect_ratio, exposure_bias, import_timestamp"
1205 " FROM main.images WHERE id = ?1",
1210 sqlite3_finalize(stmt);
1213 "SELECT a.id, a.film_id, a.filename, b.max_version"
1214 " FROM main.images AS a JOIN main.images AS b"
1215 " WHERE a.film_id = b.film_id AND a.filename = b.filename AND b.id = ?1"
1216 " ORDER BY a.id DESC",
1222 int32_t max_version = -1;
1223 gchar *filename = NULL;
1224 if(sqlite3_step(stmt) == SQLITE_ROW)
1226 newid = sqlite3_column_int(stmt, 0);
1227 film_id = sqlite3_column_int(stmt, 1);
1228 filename = g_strdup((gchar *)sqlite3_column_text(stmt, 2));
1229 max_version = sqlite3_column_int(stmt, 3);
1231 sqlite3_finalize(stmt);
1237 "INSERT INTO main.color_labels (imgid, color)"
1238 " SELECT ?1, color FROM main.color_labels WHERE imgid = ?2",
1244 sqlite3_finalize(stmt);
1248 "INSERT INTO main.meta_data (id, key, value)"
1249 " SELECT ?1, key, value FROM main.meta_data WHERE id = ?2",
1255 sqlite3_finalize(stmt);
1259 "INSERT INTO main.tagged_images (imgid, tagid, position)"
1260 " SELECT ?1, tagid, "
1261 " (SELECT (IFNULL(MAX(position),0) & 0xFFFFFFFF00000000)"
1262 " FROM main.tagged_images)"
1263 " + (ROW_NUMBER() OVER (ORDER BY imgid) << 32)"
1264 " FROM main.tagged_images AS ti"
1265 " WHERE imgid = ?2",
1271 sqlite3_finalize(stmt);
1275 "INSERT INTO main.module_order (imgid, iop_list, version)"
1276 " SELECT ?1, iop_list, version FROM main.module_order WHERE imgid = ?2",
1282 sqlite3_finalize(stmt);
1286 const int32_t version = (newversion != -1) ? newversion : max_version + 1;
1287 max_version = (newversion != -1) ?
MAX(max_version, newversion) : max_version + 1;
1294 sqlite3_finalize(stmt);
1298 "UPDATE main.images SET max_version=?1 WHERE film_id = ?2 AND filename = ?3", -1,
1305 sqlite3_finalize(stmt);
1322 dupundo->
version = newversion;
1368 "DELETE FROM main.meta_data WHERE id = ?1", -1, &stmt, NULL);
1371 sqlite3_finalize(stmt);
1379 uint32_t found_it = 0;
1386 "SELECT COUNT(imgid) FROM main.history WHERE imgid = ?1", -1,
1390 sqlite3_reset(stmt);
1391 sqlite3_clear_bindings(stmt);
1393 if(sqlite3_step(stmt) == SQLITE_ROW)
1394 found_it = sqlite3_column_int(stmt, 0);
1418 if(strlen(
name) < offset ||
name[offset] !=
'_')
1423 if(!isdigit(
name[
i]))
1426 return name[
i] ==
'.';
1439 const size_t fn_len = strlen(filename);
1440 const char* ext = strrchr(filename,
'.');
1442 const size_t ext_offset = ext - filename;
1445 GList* files = NULL;
1448 static const char xmp[] =
".xmp";
1449 const size_t xmp_len = strlen(xmp);
1451 g_strlcpy(pattern, filename,
sizeof(pattern));
1452 g_strlcpy(pattern + fn_len, xmp,
sizeof(pattern) - fn_len);
1456 files = g_list_prepend(files, g_strdup(pattern));
1460 static const char glob_pattern[] =
"_[0-9]*[0-9]";
1461 const size_t gp_len = strlen(glob_pattern);
1462 if(fn_len + gp_len + xmp_len <
sizeof(pattern))
1465 g_strlcpy(pattern + ext_offset, glob_pattern,
sizeof(pattern) - fn_len);
1466 g_strlcpy(pattern + ext_offset + gp_len, ext,
sizeof(pattern) - ext_offset - gp_len);
1467 g_strlcpy(pattern + fn_len + gp_len, xmp,
sizeof(pattern) - fn_len - gp_len);
1469 if(!glob(pattern, 0, NULL, &globbuf))
1472 for(
size_t i = 0;
i < globbuf.gl_pathc;
i++)
1477 files = g_list_prepend(files, g_strdup(globbuf.gl_pathv[
i]));
1484 return g_list_reverse(files);
1494 int count_xmps_processed = 0;
1500 g_snprintf(pattern,
sizeof(pattern),
"%s.xmp", filename);
1502 for(GList *file_iter = files; file_iter; file_iter = g_list_next(file_iter))
1504 gchar *xmpfilename = file_iter->data;
1508 if(!strncmp(xmpfilename, pattern,
sizeof(pattern)))
1517 gchar *
c3 = xmpfilename + strlen(xmpfilename)
1519 while(*
c3 !=
'.' &&
c3 > xmpfilename)
1522 while(*c4 !=
'_' && c4 > xmpfilename) c4--;
1525 gchar *idfield = g_strndup(c4,
c3 - c4);
1527 version = atoi(idfield);
1534 if(count_xmps_processed == 0)
1540 "UPDATE main.images SET version=?1, max_version = ?1 WHERE id = ?2", -1, &stmt, NULL);
1544 sqlite3_finalize(stmt);
1572 count_xmps_processed++;
1577 return count_xmps_processed;
1581 gboolean lua_locking, gboolean raise_signals)
1589 const char *cc = normalized_filename + strlen(normalized_filename);
1590 for(; *cc !=
'.' && cc > normalized_filename; cc--)
1592 if(!strcasecmp(cc,
".dt") || !strcasecmp(cc,
".dttags") || !strcasecmp(cc,
".xmp"))
1597 char *ext = g_ascii_strdown(cc + 1, -1);
1599 for(
const char **
i = dt_supported_extensions; !
IS_NULL_PTR(*
i);
i++)
1600 if(!strcmp(ext, *
i))
1614 gchar *imgfname = g_path_get_basename(normalized_filename);
1618 dt_control_log(_(
"Image %s is already in library and will not be re-imported.\n"), imgfname);
1629 gchar *
extension = g_strrstr(imgfname,
".");
1649 "INSERT INTO main.images (id, film_id, filename, license, sha1sum, flags, version, "
1650 " max_version, history_end, position, import_timestamp)"
1651 " SELECT NULL, ?1, ?2, '', '', ?3, 0, 0, 0, (IFNULL(MAX(position),0) & 0xFFFFFFFF00000000) + (1 << 32), ?4 "
1661 rc = sqlite3_step(stmt);
1662 if(rc != SQLITE_DONE) fprintf(stderr,
"sqlite3 error %d\n", rc);
1663 sqlite3_finalize(stmt);
1668 gchar *basename = g_strdup(imgfname);
1669 gchar *cc2 = basename + strlen(basename);
1670 for(; *cc2 !=
'.' && cc2 > basename; cc2--)
1673 gchar *sql_pattern = g_strconcat(basename,
".%", NULL);
1676 if(strcmp(ext,
"jpg") != 0 && strcmp(ext,
"jpeg") != 0)
1678 sqlite3_stmt *stmt2;
1684 " WHERE film_id = ?1 AND filename LIKE ?2 AND id = group_id", -1, &stmt2,
1690 if(sqlite3_step(stmt2) == SQLITE_ROW)
1692 int other_id = sqlite3_column_int(stmt2, 0);
1694 gchar *other_basename = g_strdup(other_img->
filename);
1695 gchar *cc3 = other_basename + strlen(other_img->
filename);
1696 for(; *cc3 !=
'.' && cc3 > other_basename; cc3--)
1699 gchar *ext_lowercase = g_ascii_strdown(cc3, -1);
1701 if(!strcmp(ext_lowercase,
"jpg") || !strcmp(ext_lowercase,
"jpeg"))
1705 sqlite3_stmt *stmt3;
1708 "SELECT id FROM main.images WHERE group_id = ?1 AND id != ?1", -1, &stmt3, NULL);
1710 while(sqlite3_step(stmt3) == SQLITE_ROW)
1712 other_id = sqlite3_column_int(stmt3, 0);
1718 sqlite3_finalize(stmt3);
1723 group_id = other_id;
1732 sqlite3_finalize(stmt2);
1736 sqlite3_stmt *stmt2;
1742 " WHERE film_id = ?1 AND filename LIKE ?2 AND id != ?3", -1, &stmt2, NULL);
1747 if(sqlite3_step(stmt2) == SQLITE_ROW)
1748 group_id = sqlite3_column_int(stmt2, 0);
1751 sqlite3_finalize(stmt2);
1755 "UPDATE main.images SET group_id = ?1 WHERE id = ?2",
1760 sqlite3_finalize(stmt);
1771 g_strlcpy(dtfilename, normalized_filename,
sizeof(dtfilename));
1773 g_strlcat(dtfilename,
".xmp",
sizeof(dtfilename));
1783 if((res != 0) && (nb_xmp == 0))
1792 snprintf(tagname,
sizeof(tagname),
"darktable|format|%s", ext);
1811 GList *imgs = g_list_prepend(NULL, GINT_TO_POINTER(
id));
1825 gchar *dir = g_path_get_dirname(filename);
1826 gchar *file = g_path_get_basename(filename);
1831 " FROM main.images, main.film_rolls"
1832 " WHERE film_rolls.folder = ?1"
1833 " AND images.film_id = film_rolls.id"
1834 " AND images.filename = ?2",
1839 if(sqlite3_step(stmt) == SQLITE_ROW)
id=sqlite3_column_int(stmt, 0);
1840 sqlite3_finalize(stmt);
1852 "SELECT id FROM main.images WHERE film_id = ?1 AND filename = ?2",
1856 if(sqlite3_step(stmt) == SQLITE_ROW)
id=sqlite3_column_int(stmt, 0);
1857 sqlite3_finalize(stmt);
1861int32_t
dt_image_import(
const int32_t film_id,
const char *filename, gboolean raise_signals)
1873 memset(img, 0,
sizeof(*img));
1950 for(
int k=0;
k<4;
k++)
1951 for(
int i=0;
i<3;
i++)
1976 int32_t result = -1;
1979 gboolean from_cache =
FALSE;
1981 gchar *newdir = NULL;
1983 sqlite3_stmt *film_stmt;
1985 -1, &film_stmt, NULL);
1987 if(sqlite3_step(film_stmt) == SQLITE_ROW) newdir = g_strdup((gchar *)sqlite3_column_text(film_stmt, 0));
1988 sqlite3_finalize(film_stmt);
1990 gchar copysrcpath[
PATH_MAX] = { 0 };
1991 gchar copydestpath[
PATH_MAX] = { 0 };
1992 GFile *old = NULL, *
new = NULL;
1995 old = g_file_new_for_path(oldimg);
1999 g_snprintf(newimg,
sizeof(newimg),
"%s%c%s", newdir, G_DIR_SEPARATOR, newname);
2000 new = g_file_new_for_path(newimg);
2003 gchar *newBasename = g_file_get_basename(
new);
2004 if(g_strcmp0(newname, newBasename) != 0)
2006 g_object_unref(old);
2008 g_object_unref(
new);
2015 gchar *imgbname = g_path_get_basename(oldimg);
2016 g_snprintf(newimg,
sizeof(newimg),
"%s%c%s", newdir, G_DIR_SEPARATOR, imgbname);
2017 new = g_file_new_for_path(newimg);
2034 GError *moveError = NULL;
2035 gboolean moveStatus = g_file_move(old,
new, 0, NULL, NULL, NULL, &moveError);
2042 sqlite3_stmt *duplicates_stmt;
2048 " WHERE filename IN (SELECT filename FROM main.images WHERE id = ?1)"
2049 " AND film_id IN (SELECT film_id FROM main.images WHERE id = ?1)",
2050 -1, &duplicates_stmt, NULL);
2054 GList *dup_list = NULL;
2056 while(sqlite3_step(duplicates_stmt) == SQLITE_ROW)
2058 const int32_t
id = sqlite3_column_int(duplicates_stmt, 0);
2059 dup_list = g_list_prepend(dup_list, GINT_TO_POINTER(
id));
2061 g_strlcpy(oldxmp, oldimg,
sizeof(oldxmp));
2062 g_strlcpy(newxmp, newimg,
sizeof(newxmp));
2065 g_strlcat(oldxmp,
".xmp",
sizeof(oldxmp));
2066 g_strlcat(newxmp,
".xmp",
sizeof(newxmp));
2068 GFile *goldxmp = g_file_new_for_path(oldxmp);
2069 GFile *gnewxmp = g_file_new_for_path(newxmp);
2071 g_file_move(goldxmp, gnewxmp, 0, NULL, NULL, NULL, NULL);
2073 g_object_unref(goldxmp);
2074 g_object_unref(gnewxmp);
2076 sqlite3_finalize(duplicates_stmt);
2078 dup_list = g_list_reverse(dup_list);
2085 const int id = GPOINTER_TO_INT(dup_list->data);
2091 dup_list = g_list_delete_link(dup_list, dup_list);
2093 g_list_free(dup_list);
2097 if(g_file_test(copysrcpath, G_FILE_TEST_EXISTS))
2107 GFile *cold = g_file_new_for_path(copysrcpath);
2108 GFile *cnew = g_file_new_for_path(copydestpath);
2110 g_clear_error(&moveError);
2111 moveStatus = g_file_move(cold, cnew, 0, NULL, NULL, NULL, &moveError);
2114 fprintf(stderr,
"[dt_image_rename] error moving local copy `%s' -> `%s'\n", copysrcpath, copydestpath);
2116 if(g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
2118 gchar *oldBasename = g_path_get_basename(copysrcpath);
2122 else if(g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_EXISTS)
2123 || g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
2125 gchar *newBasename = g_path_get_basename(copydestpath);
2131 gchar *oldBasename = g_path_get_basename(copysrcpath);
2132 gchar *newBasename = g_path_get_basename(copydestpath);
2133 dt_control_log(_(
"error moving local copy `%s' -> `%s'"), oldBasename, newBasename);
2139 g_object_unref(cold);
2140 g_object_unref(cnew);
2147 if(g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
2156 && (g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_EXISTS)
2157 || g_error_matches(moveError, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)))
2159 dt_control_log(_(
"error moving `%s' -> `%s': file exists"), oldimg, newimg);
2167 g_clear_error(&moveError);
2168 g_object_unref(old);
2169 g_object_unref(
new);
2185 gchar *newdir = NULL;
2186 gchar *filename = NULL;
2187 gboolean from_cache =
FALSE;
2188 gchar *oldFilename = NULL;
2189 gchar *newFilename = NULL;
2194 if(sqlite3_step(stmt) == SQLITE_ROW) newdir = g_strdup((gchar *)sqlite3_column_text(stmt, 0));
2195 sqlite3_finalize(stmt);
2197 GFile *src = NULL, *dest = NULL;
2201 oldFilename = g_path_get_basename(srcpath);
2205 newFilename = g_strdup(newname);
2206 destpath = g_build_filename(newdir, newname, NULL);
2207 dest = g_file_new_for_path(destpath);
2210 gchar *destBasename = g_file_get_basename(dest);
2211 if(g_strcmp0(newname, destBasename) != 0)
2213 g_object_unref(dest);
2220 newFilename = g_path_get_basename(srcpath);
2221 destpath = g_build_filename(newdir, newFilename, NULL);
2222 dest = g_file_new_for_path(destpath);
2226 src = g_file_new_for_path(srcpath);
2236 GError *gerror = NULL;
2237 gboolean copyStatus = g_file_copy(src, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &gerror);
2239 if(copyStatus || g_error_matches(gerror, G_IO_ERROR, G_IO_ERROR_EXISTS))
2241 gchar *dest_image_path = g_file_get_path(dest);
2252 "INSERT INTO main.images"
2253 " (id, group_id, film_id, width, height, filename, maker, model, lens, exposure,"
2254 " aperture, iso, focal_length, focus_distance, datetime_taken, flags,"
2255 " output_width, output_height, crop, raw_parameters, raw_denoise_threshold,"
2256 " raw_auto_bright_threshold, raw_black, raw_maximum,"
2257 " license, sha1sum, orientation, histogram, lightmap,"
2258 " longitude, latitude, altitude, color_matrix, colorspace, version, max_version,"
2259 " aspect_ratio, exposure_bias)"
2260 " SELECT NULL, group_id, ?1 as film_id, width, height, ?2 as filename, maker, model, lens,"
2261 " exposure, aperture, iso, focal_length, focus_distance, datetime_taken,"
2262 " flags, width, height, crop, raw_parameters, raw_denoise_threshold,"
2263 " raw_auto_bright_threshold, raw_black, raw_maximum,"
2264 " license, sha1sum, orientation, histogram, lightmap,"
2265 " longitude, latitude, altitude, color_matrix, colorspace, -1, -1,"
2266 " aspect_ratio, exposure_bias"
2275 sqlite3_finalize(stmt);
2279 "SELECT a.id, a.filename"
2280 " FROM main.images AS a"
2281 " JOIN main.images AS b"
2282 " WHERE a.film_id = ?1 AND a.filename = ?2 AND b.filename = ?3 AND b.id = ?4"
2283 " ORDER BY a.id DESC",
2291 if(sqlite3_step(stmt) == SQLITE_ROW)
2293 newid = sqlite3_column_int(stmt, 0);
2294 filename = g_strdup((gchar *)sqlite3_column_text(stmt, 1));
2296 sqlite3_finalize(stmt);
2304 "INSERT INTO main.color_labels (imgid, color)"
2306 " FROM main.color_labels"
2307 " WHERE imgid = ?2",
2313 sqlite3_finalize(stmt);
2316 "INSERT INTO main.meta_data (id, key, value)"
2317 " SELECT ?1, key, value"
2318 " FROM main.meta_data"
2325 sqlite3_finalize(stmt);
2329 "INSERT INTO main.tagged_images (imgid, tagid, position)"
2330 " SELECT ?1, tagid, "
2331 " (SELECT (IFNULL(MAX(position),0) & 0xFFFFFFFF00000000)"
2332 " FROM main.tagged_images)"
2333 " + (ROW_NUMBER() OVER (ORDER BY imgid) << 32)"
2334 " FROM main.tagged_images AS ti"
2335 " WHERE imgid = ?2",
2341 sqlite3_finalize(stmt);
2344 int32_t max_version = -1;
2348 "SELECT MAX(a.max_version)"
2349 " FROM main.images AS a"
2350 " JOIN main.images AS b"
2351 " WHERE a.film_id = b.film_id AND a.filename = b.filename AND b.id = ?1",
2356 if(sqlite3_step(stmt) == SQLITE_ROW) max_version = sqlite3_column_int(stmt, 0);
2357 sqlite3_finalize(stmt);
2361 max_version = (max_version >= 0) ? max_version + 1 : 0;
2362 int32_t version = max_version;
2366 "UPDATE main.images SET version=?1 WHERE id = ?2", -1, &stmt, NULL);
2370 sqlite3_finalize(stmt);
2374 "UPDATE main.images SET max_version=?1 WHERE film_id = ?2 AND filename = ?3",
2380 sqlite3_finalize(stmt);
2384 int32_t new_group_id = -1;
2388 "SELECT DISTINCT a.group_id"
2389 " FROM main.images AS a"
2390 " JOIN main.images AS b"
2391 " WHERE a.film_id = b.film_id AND a.filename = b.filename"
2392 " AND b.id = ?1 AND a.id != ?1",
2397 if(sqlite3_step(stmt) == SQLITE_ROW) new_group_id = sqlite3_column_int(stmt, 0);
2400 if(sqlite3_step(stmt) == SQLITE_ROW) new_group_id = -1;
2401 sqlite3_finalize(stmt);
2406 if(new_group_id == -1) new_group_id = newid;
2410 "UPDATE main.images SET group_id=?1 WHERE id = ?2", -1, &stmt, NULL);
2415 sqlite3_finalize(stmt);
2427 fprintf(stderr,
"Failed to copy image %s: %s\n", srcpath, gerror->message);
2429 g_object_unref(dest);
2430 g_object_unref(src);
2431 g_clear_error(&gerror);
2449 char local_copy_path[
PATH_MAX] = { 0 };
2450 char local_copy_legacy_path[
PATH_MAX] = { 0 };
2455 g_strlcpy(local_copy_path, img->
local_copy_path,
sizeof(local_copy_path));
2460 g_strlcpy(destpath, existing,
sizeof(destpath));
2462 g_strlcpy(destpath, local_copy_path,
sizeof(destpath));
2471 if(!g_file_test(srcpath, G_FILE_TEST_IS_REGULAR))
2473 dt_control_log(_(
"cannot create local copy when the original file is not accessible."));
2479 GFile *src = g_file_new_for_path(srcpath);
2480 GFile *dest = g_file_new_for_path(destpath);
2483 GError *gerror = NULL;
2485 if(!g_file_copy(src, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &gerror))
2488 g_object_unref(dest);
2489 g_object_unref(src);
2493 g_object_unref(dest);
2494 g_object_unref(src);
2518 " WHERE id!=?1 AND flags&?2=?2"
2519 " AND film_id=(SELECT film_id"
2522 " AND filename=(SELECT filename"
2529 if(sqlite3_step(stmt) == SQLITE_ROW) result = sqlite3_column_int(stmt, 0);
2530 sqlite3_finalize(stmt);
2546 if(!local_copy_exists)
2551 gboolean from_cache =
FALSE;
2557 g_strlcat(locppath,
".xmp",
sizeof(locppath));
2561 if(g_file_test(locppath, G_FILE_TEST_EXISTS) && !g_file_test(destpath, G_FILE_TEST_EXISTS))
2563 dt_control_log(_(
"cannot remove local copy when the original file is not accessible."));
2582 if(g_file_test(locppath, G_FILE_TEST_EXISTS) && strstr(locppath, cachedir))
2584 GFile *dest = g_file_new_for_path(locppath);
2596 g_file_delete(dest, NULL, NULL);
2599 g_object_unref(dest);
2603 g_strlcat(locppath,
".xmp",
sizeof(locppath));
2604 dest = g_file_new_for_path(locppath);
2606 if(g_file_test(locppath, G_FILE_TEST_EXISTS)) g_file_delete(dest, NULL, NULL);
2607 g_object_unref(dest);
2615 img->
flags &= ~DT_IMAGE_LOCAL_COPY;
2643 if(imgid <= 0)
return 0;
2650 "SELECT write_timestamp FROM main.images WHERE id = ?1",
2659 int64_t write_timestamp = 0;
2667 return write_timestamp;
2672 if(imgid <= 0)
return;
2680 "UPDATE main.images SET write_timestamp = STRFTIME('%s', 'now') WHERE id = ?1",
2699 if(write_timestamp <= 0)
return FALSE;
2703 const int64_t change_timestamp_unix = g_date_time_to_unix(gdt);
2704 g_date_time_unref(gdt);
2706 "[xmp] imgid %d change_ts=%lld write_ts=%lld\n",
2707 img->
id, (
long long)change_timestamp_unix, (
long long)write_timestamp);
2708 return change_timestamp_unix <= write_timestamp;
2723 g_strlcpy(filename, imgpath,
sizeof(filename));
2725 g_strlcat(filename,
".xmp",
sizeof(filename));
2727 if(g_file_test(filename, G_FILE_TEST_EXISTS))
2777 GList *imgs = g_list_append(NULL, GINT_TO_POINTER(selected));
2798 GList *imgs = g_list_append(NULL, GINT_TO_POINTER(imgid));
2817 while(sqlite3_step(stmt) == SQLITE_ROW)
2819 const int32_t imgid = sqlite3_column_int(stmt, 0);
2820 gboolean from_cache =
FALSE;
2824 if(g_file_test(filename, G_FILE_TEST_EXISTS))
2826 imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgid));
2829 sqlite3_finalize(stmt);
2831 const int count = g_list_length(imgs);
2836 "%d local copies have been synchronized", count),
2855 GList *l = (GList *)data;
2866 GList **undo,
const gboolean undo_on)
2869 for(GList *imgs = (GList *)img; imgs; imgs = g_list_next(imgs))
2871 const int32_t imgid = GPOINTER_TO_INT(imgs->data);
2877 undodatetime->
imgid = imgid;
2882 *undo = g_list_prepend(*undo, undodatetime);
2907 GList **undo,
const gboolean undo_on)
2909 for(GList *imgs = (GList *)img; imgs; imgs = g_list_next(imgs))
2911 const int32_t imgid = GPOINTER_TO_INT(imgs->data);
2915 undodatetime->
imgid = imgid;
2920 *undo = g_list_prepend(*undo, undodatetime);
2945 size_t len = strlen(image_path);
2946 const char *c = image_path + len;
2947 while((c > image_path) && (*c !=
'.')) c--;
2948 len = c - image_path + 1;
2950 char *result = g_strndup(image_path, len + 3);
2953 result[len + 1] =
'a';
2954 result[len + 2] =
'v';
2955 if(g_file_test(result, G_FILE_TEST_EXISTS))
return result;
2958 result[len + 1] =
'A';
2959 result[len + 2] =
'V';
2960 if(g_file_test(result, G_FILE_TEST_EXISTS))
return result;
2968 gboolean from_cache =
FALSE;
2970 dt_image_full_path(imgid, image_path,
sizeof(image_path), &from_cache, __FUNCTION__);
2977 size_t len = strlen(image_path);
2978 const char *c = image_path + len;
2979 while((c > image_path) && (*c !=
'.')) c--;
2980 len = c - image_path + 1;
2982 char *result = g_strndup(image_path, len + 3);
2985 result[len + 1] =
'x';
2986 result[len + 2] =
't';
2987 if(g_file_test(result, G_FILE_TEST_EXISTS))
return result;
2990 result[len + 1] =
'X';
2991 result[len + 2] =
'T';
2992 if(g_file_test(result, G_FILE_TEST_EXISTS))
return result;
3000 size_t len = strlen(image_path);
3001 const char *c = image_path + len;
3002 while((c > image_path) && (*c !=
'.')) c--;
3003 len = c - image_path + 1;
3005 char *result = g_strndup(image_path, len + 3);
3007 result[len + 1] =
'x';
3008 result[len + 2] =
't';
3036 GFile *src = g_file_new_for_path(src_txt);
3037 GFile *dest = g_file_new_for_path(dest_txt);
3038 GError *gerror = NULL;
3039 gboolean copyStatus = g_file_copy(src, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &gerror);
3041 if(!copyStatus && g_error_matches(gerror, G_IO_ERROR, G_IO_ERROR_EXISTS))
3044 if(!copyStatus && gerror)
3045 fprintf(stderr,
"[dt_image] failed to copy text sidecar `%s' -> `%s': %s\n",
3046 src_txt, dest_txt, gerror->message);
3048 g_clear_error(&gerror);
3049 g_object_unref(dest);
3050 g_object_unref(src);
3067 GFile *src = g_file_new_for_path(src_txt);
3068 GFile *dest = g_file_new_for_path(dest_txt);
3069 GError *gerror = NULL;
3070 const GFileCopyFlags
flags = overwrite ? G_FILE_COPY_OVERWRITE : G_FILE_COPY_NONE;
3071 gboolean moveStatus = g_file_move(src, dest,
flags, NULL, NULL, NULL, &gerror);
3073 if(!moveStatus && gerror)
3074 fprintf(stderr,
"[dt_image] failed to move text sidecar `%s' -> `%s': %s\n",
3075 src_txt, dest_txt, gerror->message);
3077 g_clear_error(&gerror);
3078 g_object_unref(dest);
3079 g_object_unref(src);
3090 gboolean from_cache =
FALSE;
3091 dt_image_full_path(imgid, image_path,
sizeof(image_path), &from_cache, __FUNCTION__);
3093 if(image_path[0] !=
'\0' && g_file_test(image_path, G_FILE_TEST_EXISTS))
3097 dt_image_full_path(imgid, image_path,
sizeof(image_path), &from_cache, __FUNCTION__);
3099 if(from_cache && image_path[0] !=
'\0' && g_file_test(image_path, G_FILE_TEST_EXISTS))
3123 const char *T1 = _(
"<b>WARNING</b>: camera is missing samples!");
3124 const char *T2 = _(
"You must provide samples in <a href='https://raw.pixls.us/'>https://raw.pixls.us/</a>");
3125 char *T3 = g_strdup_printf(_(
"for `%s' `%s'\n"
3126 "in as many format/compression/bit depths as possible"),
3128 const char *T4 = _(
"or the <b>RAW won't be readable</b> in next version.");
3130 char *NL = logmsg ?
"\n\n" :
"\n";
3131 char *PREFIX = logmsg ?
"<big>" :
"";
3132 char *SUFFIX = logmsg ?
"</big>" :
"";
3134 char *msg = g_strconcat(PREFIX, T1, NL, T2, NL, T3, NL, T4, SUFFIX, NULL);
3161 gboolean from_cache =
FALSE;
3163 g_strlcpy(dir, g_path_get_dirname(path),
sizeof(path));
GList * dt_act_on_get_images()
const char * extension(dt_imageio_module_data_t *data)
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_RELOAD
const dt_aligned_pixel_t f
const dt_colormatrix_t matrix
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
gboolean dt_history_set_end(const int32_t imgid, const int32_t history_end)
gboolean dt_history_db_write_history_item(const int32_t imgid, const int num, const char *operation, const void *op_params, const int op_params_size, const int module_version, const gboolean enabled, const void *blendop_params, const int blendop_params_size, const int blendop_version, const int multi_priority, const char *multi_name)
int32_t dt_history_db_get_next_history_num(const int32_t imgid)
gboolean dt_image_is_matrix_correction_supported(const dt_image_t *img)
int32_t dt_image_copy_rename(const int32_t imgid, const int32_t filmid, const gchar *newname)
int32_t dt_image_move(const int32_t imgid, const int32_t filmid)
void dt_image_synch_xmps(const GList *img)
static sqlite3_stmt * _image_altered_stmt
static void _pop_undo(gpointer user_data, const dt_undo_type_t type, dt_undo_data_t data, const dt_undo_action_t action, GList **imgs)
char * dt_image_get_audio_path(const int32_t imgid)
gboolean dt_image_is_raw(const dt_image_t *img)
dt_image_pipe_class_t dt_image_pipe_class(const dt_image_t *img)
int dt_image_get_xmp_rating(const dt_image_t *img)
static int32_t _image_duplicate_with_version_ext(const int32_t imgid, const int32_t newversion)
int32_t dt_image_import(const int32_t film_id, const char *filename, gboolean raise_signals)
static gsize _image_stmt_mutex_inited
void dt_image_check_camera_missing_sample(const struct dt_image_t *img)
dt_image_orientation_t dt_image_get_orientation(const int32_t imgid)
static void _image_set_monochrome_flag(const int32_t imgid, gboolean monochrome, gboolean undo_on)
void dt_image_path_append_version(const int32_t imgid, char *pathname, size_t pathname_len)
static void _set_location(const int32_t imgid, const dt_image_geoloc_t *geoloc)
int dt_image_write_sidecar_file(const int32_t imgid)
static gboolean _image_matrix_has_data(const float *matrix, const int count)
int32_t dt_image_get_id(int32_t film_id, const gchar *filename)
int32_t dt_image_copy(const int32_t imgid, const int32_t filmid)
void dt_image_refresh_makermodel(dt_image_t *img)
static const char * _image_buf_type_to_string(const dt_iop_buffer_type_t type)
int dt_image_monochrome_flags(const dt_image_t *img)
uint32_t dt_image_altered(const int32_t imgid)
int32_t dt_image_import_lua(const int32_t film_id, const char *filename)
void dt_image_get_datetime(const int32_t imgid, char *datetime)
const char * dt_image_pipe_class_name(const dt_image_pipe_class_t klass)
static void _geotag_undo_data_free(gpointer data)
char * dt_image_get_text_path_from_path(const char *image_path)
void dt_image_set_location(const int32_t imgid, const dt_image_geoloc_t *geoloc, const gboolean undo_on, const gboolean group_on)
static dt_pthread_mutex_t _write_timestamp_stmt_mutex
void dt_image_film_roll(const dt_image_t *img, char *pathname, size_t pathname_len)
void dt_image_print_exif(const dt_image_t *img, char *line, size_t line_len)
void dt_image_synch_all_xmp(const gchar *pathname)
void dt_image_get_location(const int32_t imgid, dt_image_geoloc_t *geoloc)
static void _datetime_undo_data_free(gpointer data)
gboolean dt_image_is_hdr(const dt_image_t *img)
int32_t dt_image_duplicate_with_version(const int32_t imgid, const int32_t newversion)
gboolean dt_image_is_monochrome(const dt_image_t *img)
void dt_image_print_debug_info(const dt_image_t *img, const char *context)
void dt_image_init(dt_image_t *img)
void dt_image_buffer_resolve_flags(dt_image_t *img)
static void _move_text_sidecar_if_present(const char *src_image_path, const char *dest_image_path, const gboolean overwrite)
void dt_image_set_datetimes(const GList *imgs, const GArray *dtime, const gboolean undo_on)
static void _write_timestamp_set_now(const int32_t imgid)
static int _write_sidecar_file_from_image_locked(const dt_image_t *img)
static void _image_set_datetimes(const GList *img, const GArray *dtime, GList **undo, const gboolean undo_on)
const char * dt_image_film_roll_name(const char *path)
static int64_t _write_timestamp_get(const int32_t imgid)
float dt_image_get_exposure_bias(const struct dt_image_t *image_storage)
GList * dt_image_find_xmps(const char *filename)
void dt_image_set_datetime(const GList *imgs, const char *datetime, const gboolean undo_on)
static void _pop_undo_execute(const int32_t imgid, const gboolean before, const gboolean after)
gboolean dt_image_is_ldr(const dt_image_t *img)
static int _nb_other_local_copy_for(const int32_t imgid)
gboolean dt_image_pipe_class_is_provisional(const dt_image_t *img)
void dt_image_path_append_version_no_db(int version, char *pathname, size_t pathname_len)
gboolean dt_image_needs_rawprepare(const dt_image_t *img)
void dt_image_set_monochrome_flag(const int32_t imgid, gboolean monochrome)
static void _image_set_datetime(const GList *img, const char *datetime, GList **undo, const gboolean undo_on)
static void _set_datetime(const int32_t imgid, const char *datetime)
void dt_image_set_images_locations(const GList *imgs, const GArray *gloc, const gboolean undo_on)
char * dt_image_get_audio_path_from_path(const char *image_path)
gboolean dt_image_use_monochrome_workflow(const dt_image_t *img)
int dt_image_local_copy_set(const int32_t imgid)
void dt_image_cleanup(void)
static void _write_timestamp_stmt_ensure(void)
static void _image_set_location(GList *imgs, const dt_image_geoloc_t *geoloc, GList **undo, const gboolean undo_on)
void dt_image_film_roll_directory(const dt_image_t *img, char *pathname, size_t pathname_len)
dt_image_path_source_t dt_image_choose_input_path(const dt_image_t *img, char *pathname, size_t pathname_len, gboolean force_cache)
static dt_pthread_mutex_t _image_stmt_mutex
void dt_image_remove(const int32_t imgid)
gboolean dt_image_is_sraw(const dt_image_t *img)
void dt_image_set_flip(const int32_t imgid, const dt_image_orientation_t orientation)
gboolean dt_image_is_mosaiced(const dt_image_t *img)
char * dt_image_camera_missing_sample_message(const struct dt_image_t *img, gboolean logmsg)
int dt_image_get_xmp_rating_from_flags(const int flags)
void dt_image_set_locations(const GList *imgs, const dt_image_geoloc_t *geoloc, const gboolean undo_on)
static void _copy_text_sidecar_if_present(const char *src_image_path, const char *dest_image_path)
static sqlite3_stmt * _write_timestamp_select_stmt
static void _image_stmt_mutex_ensure(void)
int dt_image_read_duplicates(const uint32_t id, const char *filename, const gboolean clear_selection)
static gsize _write_timestamp_stmt_mutex_inited
static void _image_set_images_locations(const GList *img, const GArray *gloc, GList **undo, const gboolean undo_on)
int dt_image_local_copy_reset(const int32_t imgid)
static int32_t _image_import_internal(const int32_t film_id, const char *filename, gboolean lua_locking, gboolean raise_signals)
gboolean dt_image_get_xmp_mode()
static char * _text_path_legacy_if_exists(const char *image_path)
char * dt_image_get_text_path(const int32_t imgid)
int32_t dt_image_get_id_full_path(const gchar *filename)
gboolean dt_image_safe_remove(const int32_t imgid)
void dt_image_set_xmp_rating(dt_image_t *img, const int rating)
char * dt_image_build_text_path_from_path(const char *image_path)
static const char * _image_colorspace_to_string(const dt_image_colorspace_t colorspace)
static char * _text_path_legacy_build(const char *image_path)
void dt_image_flip(const int32_t imgid, const int32_t cw)
static sqlite3_stmt * _write_timestamp_update_stmt
static gboolean _sidecar_is_up_to_date(const dt_image_t *img)
int32_t dt_image_duplicate(const int32_t imgid)
static int32_t _image_duplicate_with_version(const int32_t imgid, const int32_t newversion, const gboolean undo)
void dt_image_local_copy_synch()
int32_t dt_image_rename(const int32_t imgid, const int32_t filmid, const gchar *newname)
void dt_image_synch_xmp(const int selected)
void dt_get_dirname_from_imgid(gchar *dir, 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.
static int _valid_glob_match(const char *const name, size_t offset)
void dt_image_history_changed(const int32_t imgid, const gboolean refresh_filmstrip)
gboolean dt_image_needs_demosaic(const dt_image_t *img)
void dt_image_set_provisional_dsc(dt_image_t *img)
void dt_image_local_copy_paths_from_fullpath(const char *fullpath, int32_t imgid, char *local_copy_path, size_t local_copy_len, char *local_copy_legacy_path, size_t local_copy_legacy_len)
int dt_conf_get_int(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
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...
void dt_control_save_xmp(const int32_t imgid)
void dt_control_save_xmps(const GList *imgids, const gboolean check_history)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
static void dt_free_gpointer(gpointer ptr)
#define DT_MAX_FILENAME_LEN
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
sqlite3 * dt_database_get(const dt_database_t *db)
gboolean dt_datetime_img_to_exif(char *exif, const size_t exif_size, const dt_image_t *img)
GDateTime * dt_datetime_gtimespan_to_gdatetime(const GTimeSpan gts)
GTimeSpan dt_datetime_now_to_gtimespan()
void dt_datetime_exif_to_img(dt_image_t *img, const char *exif)
#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)
#define DT_DEBUG_SQLITE3_BIND_INT64(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_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
int supported(struct dt_imageio_module_storage_t *storage, struct dt_imageio_module_format_t *format)
int dt_exif_xmp_write_with_imgpath(const dt_image_t *image, const char *filename, const char *imgpath)
int dt_exif_read(dt_image_t *img, const char *path)
int dt_exif_xmp_read(dt_image_t *img, const char *filename, const int history_only)
void dt_loc_get_user_cache_dir(char *cachedir, size_t bufsize)
GList * win_image_find_duplicates(const char *filename)
int dt_grouping_remove_from_group(const int32_t image_id)
void dt_grouping_add_grouped_images(GList **images)
void dt_grouping_add_to_group(const int32_t group_id, const int32_t image_id)
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
void dt_history_snapshot_undo_create(const int32_t imgid, int *snap_id, int *history_end)
void dt_history_snapshot_undo_lt_history_data_free(gpointer data)
dt_undo_lt_history_t * dt_history_snapshot_item_init(void)
void dt_history_snapshot_undo_pop(gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, dt_undo_action_t action, GList **imgs)
@ DT_IMAGE_COLORSPACE_NONE
@ DT_IMAGE_COLORSPACE_ADOBE_RGB
@ DT_IMAGE_COLORSPACE_SRGB
@ DT_IMAGE_PATH_LOCAL_COPY_LEGACY
@ DT_IMAGE_PATH_LOCAL_COPY
@ DT_IMAGE_NO_LEGACY_PRESETS
@ DT_IMAGE_HAS_ADDITIONAL_DNG_TAGS
@ DT_IMAGE_AUTO_PRESETS_APPLIED
@ DT_IMAGE_MONOCHROME_BAYER
@ DT_IMAGE_BUFFER_RESOLVED
@ DT_IMAGE_MONOCHROME_WORKFLOW
@ DT_IMAGE_MONOCHROME_PREVIEW
dt_image_pipe_class_t
Mutually-exclusive classification of an image by the early-pipeline processing it requires....
@ DT_IMAGE_PIPE_MOSAIC_RAW
@ DT_IMAGE_PIPE_LINEAR_RAW
static dt_image_orientation_t dt_image_orientation(const dt_image_t *img)
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get_reload(dt_image_cache_t *cache, const int32_t imgid, char mode)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_cache_write_release(dt_image_cache_t *cache, dt_image_t *img, dt_image_cache_write_mode_t mode)
void dt_image_cache_remove(dt_image_cache_t *cache, const int32_t imgid)
gboolean dt_imageio_lookup_makermodel(const char *maker, const char *model, char *mk, int mk_len, char *md, int md_len, char *al, int al_len)
dt_image_flags_t dt_imageio_get_type_from_extension(const char *extension)
Map Exiv2 preview MIME types to decoder format identifiers.
gboolean dt_lightroom_import(int32_t imgid, dt_develop_t *dev, gboolean iauto)
float *const restrict const size_t k
void dt_mipmap_cache_remove(dt_mipmap_cache_t *cache, const int32_t imgid, const gboolean flush_disk)
void dt_mipmap_cache_copy_thumbnails(const dt_mipmap_cache_t *cache, const uint32_t dst_imgid, const uint32_t src_imgid)
dt_mipmap_buffer_dsc_flags flags
#define DT_VIEW_RATINGS_MASK
void dt_selection_clear(dt_selection_t *selection)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ 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_SIGNAL_IMAGE_IMPORT
This signal is raised when a new image is imported (not cloned) 1 uint32_t : the new image id no retu...
const float const int flip
char dt[DT_DATETIME_LENGTH]
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_mipmap_cache_t * mipmap_cache
struct dt_selection_t * selection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_develop_t * develop
struct dt_view_manager_t * view_manager
gboolean camera_missing_sample
GTimeSpan export_timestamp
float exif_focus_distance
dt_boundingbox_t usercrop
GTimeSpan import_timestamp
char camera_makermodel[128]
char camera_legacy_makermodel[128]
dt_image_orientation_t orientation
GTimeSpan change_timestamp
char local_copy_path[PATH_MAX]
GTimeSpan print_timestamp
float d65_color_matrix[9]
dt_image_colorspace_t colorspace
float adobe_XYZ_to_CAM[4][3]
struct dt_cache_entry_t * cache_entry
dt_image_raw_parameters_t legacy_flip
char filename[DT_MAX_FILENAME_LEN]
uint16_t raw_black_level_separate[4]
char local_copy_legacy_path[PATH_MAX]
dt_aligned_pixel_t wb_coeffs
uint32_t fuji_rotation_pos
struct dt_iop_buffer_dsc_t::@29 rawprepare
dt_iop_buffer_type_t datatype
dt_aligned_pixel_t processed_maximum
dt_thumbtable_t * thumbtable_lighttable
dt_thumbtable_t * thumbtable_filmstrip
char after[DT_DATETIME_LENGTH]
char before[DT_DATETIME_LENGTH]
#define dt_thumbtable_refresh_thumbnail(table, imgid, reinit)
void dt_undo_end_group(dt_undo_t *self)
void dt_undo_start_group(dt_undo_t *self, dt_undo_type_t type)
void dt_undo_record(dt_undo_t *self, gpointer user_data, dt_undo_type_t type, dt_undo_data_t data, void(*undo)(gpointer user_data, dt_undo_type_t type, dt_undo_data_t item, dt_undo_action_t action, GList **imgs), void(*free_data)(gpointer data))
gchar * dt_util_str_replace(const gchar *string, const gchar *pattern, const gchar *substitute)
gboolean dt_util_test_image_file(const char *filename)
gchar * dt_util_normalize_path(const gchar *_input)
char * dt_util_format_exposure(const float exposuretime)
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)