Bug 492048 - Detect color space in Exif 2.21/DCF 2.0 option files

Some refactoring: add gimp_metadata_get,set_colorspace() and a new
enum GimpMetadataColorspace which so far can be one of { UNSPECIFIED,
UNCALIBRATED, SRGB, ADOBERGB }. The setter is untested and I don't
know if it's doing the right thing, please review. Use the getter in
gimp_image_metadata_load_finish(), so complex metadata logic and
profile creation/setting are separated.
This commit is contained in:
Michael Natterer
2015-09-30 20:47:52 +02:00
parent 15b5b2c8b3
commit 15b7b17b12
4 changed files with 227 additions and 101 deletions

View File

@ -181,81 +181,24 @@ gimp_image_metadata_load_finish (gint32 image_ID,
/* only look for colorspace information from metadata if the
* image didn't contain an embedded color profile
*
* the logic here was mostly taken from darktable and libkexiv2
*/
if (! profile)
{
glong colorspace = -1;
GimpMetadataColorspace colorspace;
if (gexiv2_metadata_has_tag (metadata,
"Exif.Photo.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Photo.ColorSpace");
}
else if (gexiv2_metadata_has_tag (metadata,
"Xmp.exif.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Xmp.exif.ColorSpace");
}
colorspace = gimp_metadata_get_colorspace (metadata);
if (colorspace == 0x01)
{
/* sRGB, a NULL profile will do the right thing */
}
else if (colorspace == 0x02)
switch (colorspace)
{
case GIMP_METADATA_COLORSPACE_UNSPECIFIED:
case GIMP_METADATA_COLORSPACE_UNCALIBRATED:
case GIMP_METADATA_COLORSPACE_SRGB:
/* use sRGB, a NULL profile will do the right thing */
break;
case GIMP_METADATA_COLORSPACE_ADOBERGB:
profile = gimp_color_profile_new_adobe_rgb ();
}
else if (colorspace == 0xffff)
{
gchar *iop_index;
iop_index = gexiv2_metadata_get_tag_string (metadata,
"Exif.Iop.InteroperabilityIndex");
if (! g_strcmp0 (iop_index, "R03"))
{
profile = gimp_color_profile_new_adobe_rgb ();
}
else if (! g_strcmp0 (iop_index, "R98"))
{
/* sRGB, a NULL profile will do the right thing */
}
g_free (iop_index);
}
else if (gexiv2_metadata_has_tag (metadata,
"Exif.Nikon3.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Nikon3.ColorSpace");
if (colorspace == 0x01)
{
/* sRGB, a NULL profile will do the right thing */
}
else if (colorspace == 0x02)
{
profile = gimp_color_profile_new_adobe_rgb ();
}
}
else if (gexiv2_metadata_has_tag (metadata,
"Exif.Canon.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Canon.ColorSpace");
if (colorspace == 0x01)
{
/* sRGB, a NULL profile will do the right thing */
}
else if (colorspace == 0x02)
{
profile = gimp_color_profile_new_adobe_rgb ();
}
break;
}
if (profile)

View File

@ -69,6 +69,7 @@ EXPORTS
gimp_message_handler_type_get_type
gimp_metadata_deserialize
gimp_metadata_duplicate
gimp_metadata_get_colorspace
gimp_metadata_get_resolution
gimp_metadata_is_tag_supported
gimp_metadata_load_from_file
@ -76,6 +77,7 @@ EXPORTS
gimp_metadata_save_to_file
gimp_metadata_serialize
gimp_metadata_set_bits_per_sample
gimp_metadata_set_colorspace
gimp_metadata_set_from_exif
gimp_metadata_set_from_xmp
gimp_metadata_set_pixel_size

View File

@ -856,7 +856,7 @@ gimp_metadata_get_resolution (GimpMetadata *metadata,
* @unit: The image's unit
*
* Sets Exif.Image.XResolution, Exif.Image.YResolution and
* Exif.Image.ResolutionUnit @metadata.
* Exif.Image.ResolutionUnit of @metadata.
*
* Since: 2.10
*/
@ -903,6 +903,175 @@ gimp_metadata_set_resolution (GimpMetadata *metadata,
gexiv2_metadata_set_tag_string (metadata, "Exif.Image.ResolutionUnit", buffer);
}
/**
* gimp_metadata_get_colorspace:
* @metadata: A #GimpMetadata instance.
*
* Returns values based on Exif.Photo.ColorSpace, Xmp.exif.ColorSpace,
* Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace,
* Exif.Canon.ColorSpace of @metadata.
*
* Return value: The colorspace specified by above tags.
*
* Since: 2.10
*/
GimpMetadataColorspace
gimp_metadata_get_colorspace (GimpMetadata *metadata)
{
glong colorspace = -1;
g_return_val_if_fail (GEXIV2_IS_METADATA (metadata),
GIMP_METADATA_COLORSPACE_UNSPECIFIED);
/* the logic here was mostly taken from darktable and libkexiv2 */
if (gexiv2_metadata_has_tag (metadata, "Exif.Photo.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Photo.ColorSpace");
}
else if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Xmp.exif.ColorSpace");
}
if (colorspace == 0x01)
{
return GIMP_METADATA_COLORSPACE_SRGB;
}
else if (colorspace == 0x02)
{
return GIMP_METADATA_COLORSPACE_ADOBERGB;
}
else if (colorspace == 0xffff)
{
gchar *iop_index;
iop_index = gexiv2_metadata_get_tag_string (metadata,
"Exif.Iop.InteroperabilityIndex");
if (! g_strcmp0 (iop_index, "R03"))
{
g_free (iop_index);
return GIMP_METADATA_COLORSPACE_ADOBERGB;
}
else if (! g_strcmp0 (iop_index, "R98"))
{
g_free (iop_index);
return GIMP_METADATA_COLORSPACE_SRGB;
}
g_free (iop_index);
return GIMP_METADATA_COLORSPACE_UNCALIBRATED;
}
else if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Nikon3.ColorSpace");
if (colorspace == 0x01)
{
return GIMP_METADATA_COLORSPACE_SRGB;
}
else if (colorspace == 0x02)
{
return GIMP_METADATA_COLORSPACE_ADOBERGB;
}
}
else if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
{
colorspace = gexiv2_metadata_get_tag_long (metadata,
"Exif.Canon.ColorSpace");
if (colorspace == 0x01)
{
return GIMP_METADATA_COLORSPACE_SRGB;
}
else if (colorspace == 0x02)
{
return GIMP_METADATA_COLORSPACE_ADOBERGB;
}
}
return GIMP_METADATA_COLORSPACE_UNSPECIFIED;
}
/**
* gimp_metadata_set_colorspace:
* @metadata: A #GimpMetadata instance.
* @colorspace: The color space.
*
* Sets Exif.Photo.ColorSpace, Xmp.exif.ColorSpace,
* Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace,
* Exif.Canon.ColorSpace of @metadata.
*
* Since: 2.10
*/
void
gimp_metadata_set_colorspace (GimpMetadata *metadata,
GimpMetadataColorspace colorspace)
{
g_return_if_fail (GEXIV2_IS_METADATA (metadata));
switch (colorspace)
{
case GIMP_METADATA_COLORSPACE_UNSPECIFIED:
gexiv2_metadata_clear_tag (metadata, "Exif.Photo.ColorSpace");
gexiv2_metadata_clear_tag (metadata, "Xmp.exif.ColorSpace");
gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex");
gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace");
gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace");
break;
case GIMP_METADATA_COLORSPACE_UNCALIBRATED:
gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0xffff);
if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0xffff);
gexiv2_metadata_clear_tag (metadata, "Exif.Iop.InteroperabilityIndex");
gexiv2_metadata_clear_tag (metadata, "Exif.Nikon3.ColorSpace");
gexiv2_metadata_clear_tag (metadata, "Exif.Canon.ColorSpace");
break;
case GIMP_METADATA_COLORSPACE_SRGB:
gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x01);
if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x01);
if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex"))
gexiv2_metadata_set_tag_string (metadata,
"Exif.Iop.InteroperabilityIndex", "R98");
if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x01);
if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x01);
break;
case GIMP_METADATA_COLORSPACE_ADOBERGB:
gexiv2_metadata_set_tag_long (metadata, "Exif.Photo.ColorSpace", 0x02);
if (gexiv2_metadata_has_tag (metadata, "Xmp.exif.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Xmp.exif.ColorSpace", 0x02);
if (gexiv2_metadata_has_tag (metadata, "Exif.Iop.InteroperabilityIndex"))
gexiv2_metadata_set_tag_string (metadata,
"Exif.Iop.InteroperabilityIndex", "R03");
if (gexiv2_metadata_has_tag (metadata, "Exif.Nikon3.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Exif.Nikon3.ColorSpace", 0x02);
if (gexiv2_metadata_has_tag (metadata, "Exif.Canon.ColorSpace"))
gexiv2_metadata_set_tag_long (metadata, "Exif.Canon.ColorSpace", 0x02);
break;
}
}
/**
* gimp_metadata_is_tag_supported:
* @tag: A metadata tag name
@ -994,7 +1163,6 @@ gimp_metadata_add (GimpMetadata *src,
}
}
if (gexiv2_metadata_get_supports_xmp (src) &&
gexiv2_metadata_get_supports_xmp (dest))
{

View File

@ -44,45 +44,58 @@ typedef enum
GIMP_METADATA_SAVE_ALL = 0xffffffff
} GimpMetadataSaveFlags;
typedef enum
{
GIMP_METADATA_COLORSPACE_UNSPECIFIED,
GIMP_METADATA_COLORSPACE_UNCALIBRATED,
GIMP_METADATA_COLORSPACE_SRGB,
GIMP_METADATA_COLORSPACE_ADOBERGB
} GimpMetadataColorspace;
GimpMetadata * gimp_metadata_new (void);
GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata);
GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata);
GimpMetadata * gimp_metadata_deserialize (const gchar *metadata_xml);
gchar * gimp_metadata_serialize (GimpMetadata *metadata);
GimpMetadata * gimp_metadata_deserialize (const gchar *metadata_xml);
gchar * gimp_metadata_serialize (GimpMetadata *metadata);
GimpMetadata * gimp_metadata_load_from_file (GFile *file,
GError **error);
gboolean gimp_metadata_save_to_file (GimpMetadata *metadata,
GFile *file,
GError **error);
GimpMetadata * gimp_metadata_load_from_file (GFile *file,
GError **error);
gboolean gimp_metadata_save_to_file (GimpMetadata *metadata,
GFile *file,
GError **error);
gboolean gimp_metadata_set_from_exif (GimpMetadata *metadata,
const guchar *exif_data,
gint exif_data_length,
GError **error);
gboolean gimp_metadata_set_from_xmp (GimpMetadata *metadata,
const guchar *xmp_data,
gint xmp_data_length,
GError **error);
gboolean gimp_metadata_set_from_exif (GimpMetadata *metadata,
const guchar *exif_data,
gint exif_data_length,
GError **error);
gboolean gimp_metadata_set_from_xmp (GimpMetadata *metadata,
const guchar *xmp_data,
gint xmp_data_length,
GError **error);
void gimp_metadata_set_pixel_size (GimpMetadata *metadata,
gint width,
gint height);
void gimp_metadata_set_bits_per_sample (GimpMetadata *metadata,
gint bits_per_sample);
void gimp_metadata_set_pixel_size (GimpMetadata *metadata,
gint width,
gint height);
void gimp_metadata_set_bits_per_sample (GimpMetadata *metadata,
gint bits_per_sample);
gboolean gimp_metadata_get_resolution (GimpMetadata *metadata,
gdouble *xres,
gdouble *yres,
GimpUnit *unit);
void gimp_metadata_set_resolution (GimpMetadata *metadata,
gdouble xres,
gdouble yres,
GimpUnit unit);
gboolean gimp_metadata_get_resolution (GimpMetadata *metadata,
gdouble *xres,
gdouble *yres,
GimpUnit *unit);
void gimp_metadata_set_resolution (GimpMetadata *metadata,
gdouble xres,
gdouble yres,
GimpUnit unit);
gboolean gimp_metadata_is_tag_supported (const gchar *tag,
const gchar *mime_type);
GimpMetadataColorspace
gimp_metadata_get_colorspace (GimpMetadata *metadata);
void gimp_metadata_set_colorspace (GimpMetadata *metadata,
GimpMetadataColorspace colorspace);
gboolean gimp_metadata_is_tag_supported (const gchar *tag,
const gchar *mime_type);
G_END_DECLS