summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/generators.c71
-rw-r--r--src/jpeg-utils.cpp320
-rw-r--r--src/jpeg-utils.h58
3 files changed, 216 insertions, 233 deletions
diff --git a/src/generators.c b/src/generators.c
index 48a377a..1d05eea 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -555,6 +555,27 @@ write_html_album (TGallerySetup *setup,
return res;
}
+static char *
+get_exif_value_cb (gchar **args, gpointer user_data)
+{
+ ExifData *exif = user_data;
+
+ g_return_val_if_fail (exif != NULL, NULL);
+ g_return_val_if_fail (g_strv_length (args) != 2, NULL); /* incl. trailing NULL */
+
+ return get_exif_data (exif, *args);
+}
+
+static char *
+get_exif_value_fixed_cb (gchar **args, gpointer user_data)
+{
+ ExifData *exif = user_data;
+
+ g_return_val_if_fail (exif != NULL, NULL);
+ g_return_val_if_fail (g_strv_length (args) != 2, NULL); /* incl. trailing NULL */
+
+ return get_exif_data_fixed (exif, *args);
+}
/*
* write_html_image: process single image template file
@@ -581,7 +602,7 @@ write_html_image (TGallerySetup *setup,
gchar *img_orig_src;
gchar *img_orig_dst;
gchar *img_orig_dst_page;
- TExifData *exif;
+ ExifData *exif;
unsigned long img_w, img_h;
unsigned long img_orig_w, img_orig_h;
unsigned int item_index, next_item_index, real_item_index, real_total_items;
@@ -676,13 +697,13 @@ write_html_image (TGallerySetup *setup,
/* Get EXIF data from the original image */
exif = NULL;
if (img_orig_src) {
- exif = get_exif (img_orig_src);
+ exif = read_exif (img_orig_src);
if (exif == NULL)
log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_orig_src);
}
/* Try destination image instead, though it might have the metadata stripped */
if (exif == NULL) {
- exif = get_exif (img_dst);
+ exif = read_exif (img_dst);
if (exif == NULL)
log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_dst);
}
@@ -699,25 +720,30 @@ write_html_image (TGallerySetup *setup,
title = g_strdup (item->title);
title_desc = g_strdup (item->title_description);
if (setup->use_iptc_exif && title == NULL && title_desc == NULL && exif != NULL) {
- if (exif->iptc_caption)
- title = g_strdup (exif->iptc_caption);
- if (exif->jpeg_comment) {
+ title = get_exif_data_fixed (exif, IPTC_CAPTION);
+ s1 = get_exif_data_fixed (exif, JPEG_COMMENT);
+ if (s1) {
if (! title)
- title = g_strdup (exif->jpeg_comment);
+ title = g_strdup (s1);
else
- title_desc = g_strdup (exif->jpeg_comment);
+ title_desc = g_strdup (s1);
+ g_free (s1);
}
- if (exif->exif_imgdesc) {
+ s1 = get_exif_data_fixed (exif, EXIF_IMAGE_DESCRIPTION);
+ if (s1) {
if (! title)
- title = g_strdup (exif->exif_imgdesc);
+ title = g_strdup (s1);
/* if (! title_desc) -- disabled
- title_desc = g_strdup (exif->exif_imgdesc); */
+ title_desc = g_strdup (s1); */
+ g_free (s1);
}
- if (exif->exif_usercomment) {
+ s1 = get_exif_data_fixed (exif, EXIF_COMMENT);
+ if (s1) {
if (! title)
- title = g_strdup (exif->exif_usercomment);
+ title = g_strdup (s1);
if (! title_desc)
- title_desc = g_strdup (exif->exif_usercomment);
+ title_desc = g_strdup (s1);
+ g_free (s1);
}
/* Convert line breaks to be visible in the HTML code */
if (title) {
@@ -794,19 +820,8 @@ write_html_image (TGallerySetup *setup,
replace_table_add_key (replace_table, "TEMPLATES_PATH", setup->supplemental_files_use_common_root ? s1 : "");
g_free (s1);
- /* EXIF values */
- if (exif) {
- replace_table_add_key (replace_table, "EXIF_ISO", exif->iso ? exif->iso : "??");
- replace_table_add_key (replace_table, "EXIF_TIME", exif->exposure ? exif->exposure : "??");
- replace_table_add_key (replace_table, "EXIF_APERTURE", exif->aperture ? exif->aperture : "??");
- replace_table_add_key (replace_table, "EXIF_FOCAL_LENGTH", exif->focal_length ? exif->focal_length : "??");
- replace_table_add_key (replace_table, "EXIF_FLASH", exif->flash ? exif->flash : "??");
- replace_table_add_key (replace_table, "EXIF_DATE", exif->datetime ? exif->datetime : "??");
- replace_table_add_key (replace_table, "EXIF_CAMERA_MODEL", exif->camera_model ? exif->camera_model : "??");
- s1 = g_strdup_printf ("(%s)", exif->focal_length_35mm);
- replace_table_add_key (replace_table, "EXIF_FOCAL_35", exif->focal_length_35mm ? s1 : "");
- g_free (s1);
- }
+ replace_table_register_function (replace_table, "get_exif_value", get_exif_value_cb, exif);
+ replace_table_register_function (replace_table, "get_exif_value_fixed", get_exif_value_fixed_cb, exif);
/* Border style */
s1 = item->border_style;
@@ -912,7 +927,7 @@ write_html_image (TGallerySetup *setup,
g_free (imgname);
g_free (preload_imgname);
g_hash_table_destroy (defines);
- free_exif_data (exif);
+ exif_data_free (exif);
replace_table_free (replace_table);
block_parser_free (block_parser);
return res;
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index 34d3997..031ecc0 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -30,204 +30,174 @@
#include "gallery-utils.h"
+struct ExifData {
+ Exiv2::Image::AutoPtr image;
+};
+
/*
- * get_exif: retrieve EXIF informations from a JPEG image
+ * EXIF and IPTC info retrieval, keeps the source file open until freed
*/
-TExifData *
-get_exif (const gchar *filename)
+ExifData *
+read_exif (const gchar *filename)
{
- TExifData *data;
+ ExifData *data;
- data = (TExifData*) g_malloc0 (sizeof (TExifData));
+ data = (ExifData*) g_malloc0 (sizeof (ExifData));
- try
- {
- Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open (filename);
- g_assert (image.get() != 0);
- image->readMetadata();
-
- Exiv2::ExifData &exifData = image->exifData();
- if (! exifData.empty()) {
- /* EXIF::Aperture */
- try {
- float val = exifData["Exif.Photo.FNumber"].toFloat();
- if (val >= 0)
- data->aperture = g_strdup_printf ("f/%.1f", val);
- } catch (...) { }
-
- /* EXIF::Camera model */
- try {
- data->camera_model = g_strdup (exifData["Exif.Image.Model"].toString().c_str());
- } catch (...) { }
-
- /* EXIF::DateTime */
- try {
- const char *val = NULL;
- try {
- val = exifData["Exif.Photo.DateTimeOriginal"].toString().c_str();
- } catch (...) { }
- if (! val || strlen (val) == 0)
- try {
- val = exifData["Exif.Image.DateTime"].toString().c_str();
- } catch (...) { }
-
- if (val && strlen (val) > 0) {
- struct tm tt;
- char conv[1024];
-
- memset (&conv, 0, sizeof (conv));
- memset (&tt, 0, sizeof (struct tm));
-
- if (sscanf (val, "%d:%d:%d %d:%d:%d", &tt.tm_year, &tt.tm_mon, &tt.tm_mday, &tt.tm_hour, &tt.tm_min, &tt.tm_sec) == 6)
- {
- tt.tm_year -= 1900;
- tt.tm_mon--;
- mktime (&tt);
- if (strftime (&conv[0], sizeof (conv), "%c", &tt))
- data->datetime = g_strdup (&conv[0]);
- }
- }
- } catch (...) { }
-
- /* EXIF::Shutter speed */
- try {
- float val = exifData["Exif.Photo.ExposureTime"].toFloat();
- if (val > 0) {
- if (val < 0.5)
- data->exposure = g_strdup_printf ("1/%.0f s", 1/val);
- else
- data->exposure = g_strdup_printf ("%.1f s", val);
- }
- } catch (...) { }
-
- /* EXIF::Flash */
- try {
- long int val = exifData["Exif.Photo.Flash"].toLong();
- if (val > 0 && (val & 1) == 1)
- data->flash = g_strdup ("Flash fired");
- else
- data->flash = g_strdup ("--");
- } catch (...) { }
-
- /* EXIF::Focal length */
- try {
- float val = exifData["Exif.Photo.FocalLength"].toFloat();
- if (val >= 0)
- data->focal_length = g_strdup_printf ("%.0f mm", val);
- } catch (...) { }
-
- /* EXIF::ISO */
- try {
- long int val = exifData["Exif.Photo.ISOSpeedRatings"].toLong();
- if (val > 0)
- data->iso = g_strdup_printf ("%ld", val);
- } catch (...) { }
-
- /* EXIF::Software */
- try {
- data->exif_software = g_strdup (exifData["Exif.Image.Software"].toString().c_str());
- } catch (...) { }
-
- /* EXIF::Image description */
- try {
- data->exif_imgdesc = g_strdup (exifData["Exif.Image.ImageDescription"].toString().c_str());
- } catch (...) { }
-
- /* EXIF::Artist */
- try {
- data->exif_artist = g_strdup (exifData["Exif.Image.Artist"].toString().c_str());
- } catch (...) { }
-
- /* EXIF::Copyright */
- try {
- data->exif_copyright = g_strdup (exifData["Exif.Image.Copyright"].toString().c_str());
- } catch (...) { }
-
- /* EXIF::User comment */
- try {
- data->exif_usercomment = g_strdup (exifData["Exif.Photo.UserComment"].toString().c_str());
- } catch (...) { }
- }
-
- Exiv2::IptcData &iptcData = image->iptcData();
- if (! iptcData.empty()) {
- /* IPTC::Object name */
- try {
- data->iptc_objectname = g_strdup (iptcData["Iptc.Application2.ObjectName"].toString().c_str());
- } catch (...) { }
-
- /* IPTC::Copyright */
- try {
- data->iptc_copyright = g_strdup (iptcData["Iptc.Application2.Copyright"].toString().c_str());
- } catch (...) { }
-
- /* IPTC::Credit */
- try {
- data->iptc_credit = g_strdup (iptcData["Iptc.Application2.Credit"].toString().c_str());
- } catch (...) { }
-
- /* IPTC::Caption */
- try {
- data->iptc_caption = g_strdup (iptcData["Iptc.Application2.Caption"].toString().c_str());
- } catch (...) { }
-
- /* IPTC::Author */
- try {
- data->iptc_author = g_strdup (iptcData["Iptc.Application2.Byline"].toString().c_str());
- } catch (...) { }
- }
-
- /* JPEG::Comment */
- try {
- data->jpeg_comment = g_strdup (image->comment().c_str());
- } catch (...) { }
+ try {
+ data->image = Exiv2::ImageFactory::open (filename);
+ g_assert (data->image.get() != 0);
+ data->image->readMetadata();
}
catch (Exiv2::AnyError& e)
{
- log_error ("get_exif: Caught Exiv2 exception: '%s'\n", e.what());
- free_exif_data (data);
+ log_error ("read_exif: Caught Exiv2 exception: '%s'\n", e.what());
+ exif_data_free (data);
return NULL;
}
return data;
}
-/*
- * free_exif_struct: free allocated structure
- */
void
-free_exif_data (TExifData *data)
+exif_data_free (ExifData *data)
{
if (data) {
- g_free (data->aperture);
- g_free (data->camera_model);
- g_free (data->datetime);
- g_free (data->exposure);
- g_free (data->flash);
- g_free (data->focal_length);
- g_free (data->focal_length_35mm);
- g_free (data->iso);
-
- g_free (data->exif_software);
- g_free (data->exif_imgdesc);
- g_free (data->exif_artist);
- g_free (data->exif_copyright);
- g_free (data->exif_usercomment);
-
- g_free (data->iptc_objectname);
- g_free (data->iptc_copyright);
- g_free (data->iptc_credit);
- g_free (data->iptc_caption);
- g_free (data->iptc_author);
-
- g_free (data->jpeg_comment);
-
+ /* FIXME: free data->image */
g_free (data);
}
}
+/*
+ * Retrieves value of the specified key or NULL if the key does not exist.
+ * The key argument belongs to Exiv2 namespace - see http://exiv2.org/tags.html
+ */
+gchar *
+get_exif_data (ExifData *exif, const gchar *key)
+{
+ try {
+ if (g_strcmp0 (key, JPEG_COMMENT) == 0) {
+ return g_strdup (exif->image->comment().c_str());
+ }
+
+ if (g_str_has_prefix (key, "Exif.")) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ return g_strdup (exifData[key].toString().c_str());
+ }
+ }
+
+ if (g_str_has_prefix (key, "Iptc.")) {
+ Exiv2::IptcData &iptcData = exif->image->iptcData();
+ if (! iptcData.empty()) {
+ return g_strdup (iptcData[key].toString().c_str());
+ }
+ }
+
+ return NULL;
+ }
+ catch (...) {
+ return NULL;
+ }
+}
+
+gchar *
+get_exif_data_fixed (ExifData *exif, const gchar *key)
+{
+ try
+ {
+ if (g_str_has_prefix (key, EXIF_APERTURE)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ float val = exifData["Exif.Photo.FNumber"].toFloat();
+ if (val >= 0)
+ return g_strdup_printf ("f/%.1f", val);
+ }
+ }
+
+ if (g_str_has_prefix (key, EXIF_DATETIME)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ const char *val = NULL;
+ try {
+ val = exifData["Exif.Photo.DateTimeOriginal"].toString().c_str();
+ } catch (...) { }
+ if (! val || strlen (val) == 0)
+ try {
+ val = exifData["Exif.Image.DateTime"].toString().c_str();
+ } catch (...) { }
+
+ if (val && strlen (val) > 0) {
+ struct tm tt;
+ char conv[1024];
+
+ memset (&conv, 0, sizeof (conv));
+ memset (&tt, 0, sizeof (struct tm));
+
+ if (sscanf (val, "%d:%d:%d %d:%d:%d", &tt.tm_year, &tt.tm_mon, &tt.tm_mday, &tt.tm_hour, &tt.tm_min, &tt.tm_sec) == 6)
+ {
+ tt.tm_year -= 1900;
+ tt.tm_mon--;
+ mktime (&tt);
+ if (strftime (&conv[0], sizeof (conv), "%c", &tt))
+ return g_strdup (&conv[0]);
+ }
+ }
+ }
+ }
+
+ if (g_str_has_prefix (key, EXIF_EXPOSURE)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ float val = exifData["Exif.Photo.ExposureTime"].toFloat();
+ if (val > 0) {
+ if (val < 0.5)
+ return g_strdup_printf ("1/%.0f s", 1/val);
+ else
+ return g_strdup_printf ("%.1f s", val);
+ }
+ }
+ }
+
+ if (g_str_has_prefix (key, EXIF_FLASH)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ long int val = exifData["Exif.Photo.Flash"].toLong();
+ if (val > 0 && (val & 1) == 1)
+ return g_strdup ("Flash fired");
+ else
+ return g_strdup ("--");
+ }
+ }
+
+ if (g_str_has_prefix (key, EXIF_FOCAL_LENGTH)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ float val = exifData["Exif.Photo.FocalLength"].toFloat();
+ if (val >= 0)
+ return g_strdup_printf ("%.0f mm", val);
+ }
+ }
+
+ if (g_str_has_prefix (key, EXIF_ISO)) {
+ Exiv2::ExifData &exifData = exif->image->exifData();
+ if (! exifData.empty()) {
+ long int val = exifData["Exif.Photo.ISOSpeedRatings"].toLong();
+ if (val > 0)
+ return g_strdup_printf ("%ld", val);
+ }
+ }
+ }
+ catch (...) {
+ return NULL;
+ }
+
+ return get_exif_data (exif, key);
+}
+
+
static void
autorotate_image (MagickWand *magick_wand)
{
diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h
index a682fd1..05a6a49 100644
--- a/src/jpeg-utils.h
+++ b/src/jpeg-utils.h
@@ -26,43 +26,41 @@ G_BEGIN_DECLS
#define SQUARED_SIMPLE_SHAVE_AMOUNT 5 /* percent */
-
-/* TODO: we want to have numerical values here at some point in the future */
-typedef struct {
- gchar *datetime;
- gchar *camera_model;
- gchar *iso;
- gchar *focal_length;
- gchar *focal_length_35mm;
- gchar *aperture;
- gchar *exposure;
- gchar *flash;
-
- gchar *exif_software;
- gchar *exif_imgdesc;
- gchar *exif_artist;
- gchar *exif_copyright;
- gchar *exif_usercomment;
-
- gchar *iptc_objectname;
- gchar *iptc_copyright;
- gchar *iptc_credit;
- gchar *iptc_caption;
- gchar *iptc_author;
-
- gchar *jpeg_comment;
-} TExifData;
+/* EXIF data known keys */
+#define EXIF_APERTURE "Exif.Photo.FNumber"
+#define EXIF_CAMERA_MODEL "Exif.Image.Model"
+#define EXIF_DATETIME "Exif.Photo.DateTimeOriginal"
+#define EXIF_EXPOSURE "Exif.Photo.ExposureTime"
+#define EXIF_FLASH "Exif.Photo.Flash"
+#define EXIF_FOCAL_LENGTH "Exif.Photo.FocalLength"
+#define EXIF_ISO "Exif.Photo.ISOSpeedRatings"
+#define EXIF_IMAGE_DESCRIPTION "Exif.Image.ImageDescription"
+#define EXIF_ARTIST "Exif.Image.Artist"
+#define EXIF_COPYRIGHT "Exif.Image.Copyright"
+#define EXIF_COMMENT "Exif.Photo.UserComment"
+#define IPTC_COPYRIGHT "Iptc.Application2.Copyright"
+#define IPTC_CAPTION "Iptc.Application2.Caption"
+#define IPTC_AUTHOR "Iptc.Application2.Byline"
+#define JPEG_COMMENT "Jpeg.Comment"
+
+
+typedef struct ExifData ExifData;
/*
- * get_exif: retrieve EXIF info from a JPEG image
+ * EXIF and IPTC info retrieval, keeps the source file open until freed
*/
-TExifData * get_exif (const gchar *filename);
+ExifData * read_exif (const gchar *filename);
+void exif_data_free (ExifData *data);
/*
- * free_exif_struct: free allocated structure
+ * Retrieves the value of the specified key or NULL if the key does not exist.
+ * The key argument belongs to Exiv2 namespace - see http://exiv2.org/tags.html
+ *
+ * The get_exif_data_fixed() function does some pretty printing for selected keys.
*/
-void free_exif_data (TExifData *data);
+gchar * get_exif_data (ExifData *exif, const gchar *key);
+gchar * get_exif_data_fixed (ExifData *exif, const gchar *key);
/*