Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion src/common/exif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,6 @@ static bool _exif_decode_xmp_data(dt_image_t *img,
if(version == -1 || version > 0)
{
dt_pthread_mutex_lock(&darktable.metadata_threadsafe);
if(!exif_read) dt_metadata_clear(imgs, FALSE);

for(GList *iter = dt_metadata_get_list(); iter; iter = iter->next)
{
Expand All @@ -629,6 +628,12 @@ static bool _exif_decode_xmp_data(dt_image_t *img,
dt_metadata_set_import(img->id, metadata->tagname, value);
free(adr);
}
else if(!exif_read && strstr(metadata->tagname, "Xmp.") == metadata->tagname)
{
// Only remove Xmp. metadata fields, do not touch metadata from other
// sources (e.g. Exif.*).
dt_metadata_unset(img->id, metadata->tagname, FALSE);
}
}
dt_pthread_mutex_unlock(&darktable.metadata_threadsafe);
}
Expand Down Expand Up @@ -2352,6 +2357,52 @@ static bool _exif_decode_exif_data(dt_image_t *img, Exiv2::ExifData &exifData)
}
};

dt_pthread_mutex_lock(&darktable.metadata_threadsafe);
for(GList *iter = dt_metadata_get_list(); iter; iter = iter->next)
{
dt_metadata_t *metadata = (dt_metadata_t *)iter->data;
if(!FIND_EXIF_TAG(metadata->tagname))
{
continue;
}

int ival = pos->toLong();
std::string str = pos->print(&exifData);
char *value = g_locale_to_utf8(str.c_str(), str.length(), NULL, NULL, NULL);
if(value == NULL)
{
// need non-const char* for g_strstrip
value = g_strdup(str.c_str());
}
g_strstrip(value);

gchar *str_value = g_strdup_printf("(%d)", ival);
if(g_strcmp0(value, str_value) == 0)
{
// no string mapping available in exiv2, so we use exiv2's
// default string conversion.
g_free(value);
str = pos->toString();
// for consistency with the handling above. don't want to mix two
// allocators, that causes me headaches.
value = g_strdup(str.c_str());
// no need to keep this around for longer.
str = nullptr;
}
g_free(str_value);

char *adr = value;
// Skip any lang="" or charset=xxx
while(!strncmp(value, "lang=", 5) || !strncmp(value, "charset=", 8))
{
while(*value != ' ' && *value) value++;
while(*value == ' ') value++;
}
dt_metadata_set_import(img->id, metadata->tagname, value);
g_free(adr);
}
dt_pthread_mutex_unlock(&darktable.metadata_threadsafe);

img->exif_inited = TRUE;
return true;
}
Expand Down
28 changes: 28 additions & 0 deletions src/common/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,34 @@ void dt_metadata_set_list_id(const GList *img,
}
}

void dt_metadata_unset(const dt_imgid_t imgid, const char *key, const gboolean undo_on)
{
if(!key || !dt_is_valid_imgid(imgid)) return;

int keyid = dt_metadata_get_keyid(key);
if(keyid == -1) return;

GList *imgs = NULL;
imgs = g_list_prepend(imgs, GINT_TO_POINTER(imgid));
GList *undo = NULL;
if(undo_on) dt_undo_start_group(darktable.undo, DT_UNDO_METADATA);

const gchar *ckey = g_strdup_printf("%d", keyid);
GList *metadata = NULL;
metadata = g_list_append(metadata, (gpointer)ckey);
metadata = g_list_append(metadata, NULL);

_metadata_execute(imgs, metadata, &undo, undo_on, DT_MA_REMOVE);

g_list_free_full(metadata, g_free);
g_list_free(imgs);
if(undo_on)
{
dt_undo_record(darktable.undo, NULL, DT_UNDO_METADATA, undo, _pop_undo, _metadata_undo_data_free);
dt_undo_end_group(darktable.undo);
}
}

gboolean dt_metadata_already_imported(const char *filename, const char *datetime)
{
if(!filename || !datetime)
Expand Down
2 changes: 2 additions & 0 deletions src/common/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ void dt_metadata_set_list(const GList *imgs, GList *key_value, const gboolean un
if clear_on TRUE the image metadata are cleared before attaching the new ones*/
void dt_metadata_set_list_id(const GList *img, const GList *metadata, const gboolean clear_on,
const gboolean undo_on);
/** Unset a specific metadata key for a specific image. Noop if the key isn't set. */
void dt_metadata_unset(const dt_imgid_t imgid, const char *key, const gboolean undo_on);
/** Get metadata (named keys) for a specific image, or all selected for an invalid imgid
For keys which return a string, the caller has to make sure that it
is freed after usage. With mutex lock. */
Expand Down