Commit 140da1c0 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

Fix metadata write.

Save the type in the metadata itself.  Use md->tagLabel() to get the description, md->value() to get the raw value and md->print() to get the interpreted value.  Use value->read() on the raw value to restore the original
value.  

[bug #623071]
parent 3acb3728
......@@ -203,8 +203,8 @@ set_file_info (GFileInfo *info,
char *description_utf8;
char *formatted_value_utf8;
if (_g_utf8_all_spaces (formatted_value))
return;
/*if (_g_utf8_all_spaces (formatted_value))
return;*/
attribute = exiv2_key_to_attribute (key);
description_utf8 = g_locale_to_utf8 (description, -1, NULL, NULL, NULL);
......@@ -239,11 +239,20 @@ set_file_info (GFileInfo *info,
metadata_info = gth_main_register_metadata_info (&info);
}
if ((metadata_info != NULL) && (metadata_info->type == NULL) && (type_name != NULL))
metadata_info->type = g_strdup (type_name);
if ((metadata_info != NULL) && (metadata_info->display_name == NULL) && (description_utf8 != NULL))
metadata_info->display_name = g_strdup (description_utf8);
metadata = gth_metadata_new ();
g_object_set (metadata, "id", key, "description", description_utf8, "formatted", formatted_value_utf8, "raw", raw_value, NULL);
g_object_set (metadata,
"id", key,
"description", description_utf8,
"formatted", formatted_value_utf8,
"raw", raw_value,
"value-type", type_name,
NULL);
g_file_info_set_attribute_object (info, attribute, G_OBJECT (metadata));
g_object_unref (metadata);
......@@ -264,6 +273,7 @@ set_attribute_from_tagset (GFileInfo *info,
char *description;
char *formatted_value;
char *raw_value;
char *type_name;
metadata = NULL;
for (i = 0; tagset[i] != NULL; i++) {
......@@ -280,8 +290,15 @@ set_attribute_from_tagset (GFileInfo *info,
"description", &description,
"formatted", &formatted_value,
"raw", &raw_value,
"value-type", &type_name,
NULL);
set_file_info (info, attribute, description, formatted_value, raw_value, NULL, NULL);
set_file_info (info,
attribute,
description,
formatted_value,
raw_value,
NULL,
type_name);
}
......@@ -360,24 +377,24 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr image,
if (! exifData.empty()) {
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator md = exifData.begin(); md != end; ++md) {
stringstream value;
value << *md;
stringstream raw_value;
raw_value << md->value();
stringstream short_name;
if (md->ifdId () > Exiv2::ifd1Id) {
stringstream description;
if (! md->tagLabel().empty())
description << md->tagLabel();
else if (md->ifdId () > Exiv2::ifd1Id)
// Must be a MakerNote - include group name
short_name << md->groupName() << "." << md->tagName();
}
else {
description << md->groupName() << "." << md->tagName();
else
// Normal exif tag - just use tag name
short_name << md->tagName();
}
description << md->tagName();
set_file_info (info,
md->key().c_str(),
short_name.str().c_str(),
value.str().c_str(),
md->toString().c_str(),
description.str().c_str(),
md->print().c_str(),
raw_value.str().c_str(),
get_exif_default_category (*md),
md->typeName());
}
......@@ -387,17 +404,20 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr image,
if (! iptcData.empty()) {
Exiv2::IptcData::iterator end = iptcData.end();
for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) {
stringstream value;
value << *md;
stringstream raw_value;
raw_value << md->value();
stringstream short_name;
short_name << md->tagName();
stringstream description;
if (! md->tagLabel().empty())
description << md->tagLabel();
else
description << md->tagName();
set_file_info (info,
md->key().c_str(),
short_name.str().c_str(),
value.str().c_str(),
md->toString().c_str(),
description.str().c_str(),
md->print().c_str(),
raw_value.str().c_str(),
"Iptc",
md->typeName());
}
......@@ -407,17 +427,20 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr image,
if (! xmpData.empty()) {
Exiv2::XmpData::iterator end = xmpData.end();
for (Exiv2::XmpData::iterator md = xmpData.begin(); md != end; ++md) {
stringstream value;
value << *md;
stringstream raw_value;
raw_value << md->value();
stringstream short_name;
short_name << md->groupName() << "." << md->tagName();
stringstream description;
if (! md->tagLabel().empty())
description << md->tagLabel();
else
description << md->groupName() << "." << md->tagName();
set_file_info (info,
md->key().c_str(),
short_name.str().c_str(),
value.str().c_str(),
md->toString().c_str(),
description.str().c_str(),
md->print().c_str(),
raw_value.str().c_str(),
"Xmp::Embedded",
md->typeName());
}
......@@ -523,17 +546,20 @@ exiv2_read_sidecar (GFile *file,
if (! xmpData.empty()) {
Exiv2::XmpData::iterator end = xmpData.end();
for (Exiv2::XmpData::iterator md = xmpData.begin(); md != end; ++md) {
stringstream value;
value << *md;
stringstream raw_value;
raw_value << md->value();
stringstream short_name;
short_name << md->groupName() << "." << md->tagName();
stringstream description;
if (! md->tagLabel().empty())
description << md->tagLabel();
else
description << md->groupName() << "." << md->tagName();
set_file_info (info,
md->key().c_str(),
short_name.str().c_str(),
value.str().c_str(),
md->toString().c_str(),
description.str().c_str(),
md->print().c_str(),
raw_value.str().c_str(),
"Xmp::Sidecar",
md->typeName());
}
......@@ -573,6 +599,28 @@ mandatory_string (Exiv2::ExifData &checkdata,
}
const char *
gth_main_get_metadata_type (GthMetadata *metadata,
const char *key)
{
const char *value_type;
GthMetadataInfo *metadatum_info;
value_type = gth_metadata_get_value_type (metadata);
if (g_strcmp0 (value_type, "Undefined") == 0)
value_type = NULL;
if (value_type != NULL)
return value_type;
metadatum_info = gth_main_get_metadata_info (key);
if (metadatum_info != NULL)
value_type = metadatum_info->type;
return value_type;
}
static Exiv2::DataBuf
exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
GFileInfo *info,
......@@ -598,21 +646,23 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
/* If the metadatum has no value yet, a new empty value
* is created. The type is taken from Exiv2's tag
* lookup tables. If the tag is not found in the table,
* the type defaults to Ascii.
* We always create the metadatum explicilty if the
* the type defaults to ASCII.
* We always create the metadatum explicitly if the
* type is available to avoid type errors.
* See bug #610389 for more details. The original
* expanation is here:
* explanation is here:
* http://uk.groups.yahoo.com/group/exiv2/message/1472
*/
GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
const char *raw_value = gth_metadata_get_raw (metadatum);
const char *value_type = gth_main_get_metadata_type (metadatum, key);
if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) && (value_type != NULL)) {
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
value->read (raw_value);
Exiv2::ExifKey exif_key(key);
ed.add (exif_key, value.get());
}
ed[key] = gth_metadata_get_raw (metadatum);
}
catch (Exiv2::AnyError& e) {
/* we don't care about invalid key errors */
......@@ -699,14 +749,16 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
char *key = exiv2_key_from_attribute (attributes[i]);
try {
/* See the exif data code above for an explanation. */
GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
const char *raw_value = gth_metadata_get_raw (metadatum);
const char *value_type = gth_main_get_metadata_type (metadatum, key);
if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) && (value_type != NULL)) {
/* See the exif data code above for an explanation. */
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
value->read (raw_value);
Exiv2::IptcKey iptc_key(key);
id.add (iptc_key, value.get());
}
id[key] = gth_metadata_get_raw (metadatum);
}
catch (Exiv2::AnyError& e) {
/* we don't care about invalid key errors */
......@@ -733,17 +785,15 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
xd.erase (iter);
try {
const char *value = gth_metadata_get_raw (metadatum);
const char *raw_value = gth_metadata_get_raw (metadatum);
const char *value_type = gth_main_get_metadata_type (metadatum, key);
if ((value != NULL) && strcmp (value, "") != 0) {
if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) && (value_type != NULL)) {
/* See the exif data code above for an explanation. */
GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
Exiv2::XmpKey xmp_key(key);
xd.add (xmp_key, value.get());
}
xd[key] = gth_metadata_get_raw (metadatum);
Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
value->read (raw_value);
Exiv2::XmpKey xmp_key(key);
xd.add (xmp_key, value.get());
}
}
catch (Exiv2::AnyError& e) {
......
......@@ -514,7 +514,7 @@ gth_file_data_get_attribute_as_string (GthFileData *file_data,
case G_FILE_ATTRIBUTE_TYPE_OBJECT:
obj = g_file_info_get_attribute_object (file_data->info, id);
if (GTH_IS_METADATA (obj))
g_object_get (obj, "formatted", &value, NULL);
value = g_strdup (gth_metadata_get_formatted (GTH_METADATA (obj)));
else if (GTH_IS_STRING_LIST (obj))
value = gth_string_list_join (GTH_STRING_LIST (obj), " ");
else
......
......@@ -408,7 +408,7 @@ gth_main_register_metadata_info (GthMetadataInfo *metadata_info)
GthMetadataInfo *info;
if ((metadata_info->display_name != NULL) && (strstr (metadata_info->display_name, "0x") != NULL))
return NULL;
metadata_info->flags = GTH_METADATA_ALLOW_NOWHERE;
g_static_mutex_lock (&metadata_info_mutex);
......
......@@ -30,7 +30,8 @@ enum {
GTH_METADATA_ID,
GTH_METADATA_DESCRIPTION,
GTH_METADATA_RAW,
GTH_METADATA_FORMATTED
GTH_METADATA_FORMATTED,
GTH_METADATA_VALUE_TYPE
};
struct _GthMetadataPrivate {
......@@ -38,6 +39,7 @@ struct _GthMetadataPrivate {
char *description;
char *raw;
char *formatted;
char *value_type;
};
static gpointer gth_metadata_parent_class = NULL;
......@@ -65,6 +67,9 @@ gth_metadata_get_property (GObject *object,
case GTH_METADATA_FORMATTED:
g_value_set_string (value, self->priv->formatted);
break;
case GTH_METADATA_VALUE_TYPE:
g_value_set_string (value, self->priv->value_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -94,6 +99,9 @@ gth_metadata_set_property (GObject *object,
case GTH_METADATA_FORMATTED:
_g_strset (&self->priv->formatted, g_value_get_string (value));
break;
case GTH_METADATA_VALUE_TYPE:
_g_strset (&self->priv->value_type, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -112,6 +120,7 @@ gth_metadata_finalize (GObject *obj)
g_free (self->priv->description);
g_free (self->priv->raw);
g_free (self->priv->formatted);
g_free (self->priv->value_type);
G_OBJECT_CLASS (gth_metadata_parent_class)->finalize (obj);
}
......@@ -155,6 +164,13 @@ gth_metadata_class_init (GthMetadataClass *klass)
"Metadata formatted value",
NULL,
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass),
GTH_METADATA_VALUE_TYPE,
g_param_spec_string ("value-type",
"Type",
"Metadata type",
NULL,
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}
......@@ -166,6 +182,7 @@ gth_metadata_instance_init (GthMetadata *self)
self->priv->description = NULL;
self->priv->raw = NULL;
self->priv->formatted = NULL;
self->priv->value_type = NULL;
}
......@@ -221,6 +238,13 @@ gth_metadata_get_formatted (GthMetadata *metadata)
}
const char *
gth_metadata_get_value_type (GthMetadata *metadata)
{
return metadata->priv->value_type;
}
GthMetadataInfo *
gth_metadata_info_dup (GthMetadataInfo *info)
{
......
......@@ -77,6 +77,7 @@ GthMetadata * gth_metadata_new (void);
const char * gth_metadata_get_id (GthMetadata *metadata);
const char * gth_metadata_get_raw (GthMetadata *metadata);
const char * gth_metadata_get_formatted (GthMetadata *metadata);
const char * gth_metadata_get_value_type (GthMetadata *metadata);
GthMetadataInfo * gth_metadata_info_dup (GthMetadataInfo *info);
void set_attribute_from_string (GFileInfo *info,
const char *key,
......
......@@ -261,8 +261,10 @@ pixbuf_task_save_current_pixbuf (GthPixbufListTask *self,
file_data = gth_file_data_new (file, ((GthFileData *) self->priv->current->data)->info);
else
file_data = g_object_ref (self->priv->current->data);
_g_object_unref (self->priv->new_pixbuf);
self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (self->priv->task)->dest);
_gdk_pixbuf_save_async (self->priv->new_pixbuf,
file_data,
gth_file_data_get_mime_type (file_data),
......@@ -472,6 +474,7 @@ gth_pixbuf_list_task_init (GthPixbufListTask *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskPrivate);
self->priv->original_pixbuf = NULL;
self->priv->new_pixbuf = NULL;
self->priv->destination_folder = NULL;
self->priv->overwrite_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
self->priv->mime_type = NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment