summaryrefslogtreecommitdiff
path: root/src/exif.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2012-01-27 20:23:03 +0100
committerDaniel Friesel <derf@finalrewind.org>2012-01-27 20:23:03 +0100
commit4252f6eb96ef00d5907dceda3af8c581917d7aa1 (patch)
tree7850c29f32d7bbb2be61d865b2900f24c7d54eb7 /src/exif.c
parentf32e4f8b3876b5cf063b92fa8988a7bda3672795 (diff)
optional exif support (build with exif=1), initial patch import
Diffstat (limited to 'src/exif.c')
-rw-r--r--src/exif.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/exif.c b/src/exif.c
new file mode 100644
index 0000000..02154e4
--- /dev/null
+++ b/src/exif.c
@@ -0,0 +1,197 @@
+/* exif.c
+
+Copyright (C) 2012 Dennis Real.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifdef HAVE_LIBEXIF
+
+#include <stdio.h>
+#include <string.h>
+#include <libexif/exif-data.h>
+
+#include "feh.h"
+#include "options.h"
+#include "debug.h"
+#include "exif.h"
+
+
+
+/* remove all spaces on the right end of a string */
+static void exif_trim_spaces(char *str)
+{
+ char *end;
+
+ for (end = str; *str!='\0'; str++)
+ {
+ if (*str != ' ')
+ {
+ end = str;
+ }
+ }
+ *++end = '\0';
+}
+
+
+/* show given exif tag content */
+static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
+{
+ char s[MAX_EXIF_DATA];
+
+ if ( (d != NULL) && (buffer != NULL) && (maxsize>0) )
+ {
+ ExifEntry *entry = exif_content_get_entry(d->ifd[ifd], tag);
+ if (entry != NULL)
+ {
+ /* Get the contents of the tag in human-readable form */
+ exif_entry_get_value(entry, s, maxsize);
+
+ /* Don't bother printing it if it's entirely blank */
+ exif_trim_spaces(s);
+ if (*s != '\0')
+ {
+ D(("%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s));
+ snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s);
+ }
+ }
+ }
+}
+
+
+
+/* Show the given MakerNote tag if it exists */
+static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)
+{
+ ExifMnoteData *mn = NULL;
+ int i, num;
+ char buf[1024];
+
+ if ( (d!=NULL) && (buffer!=NULL) && (maxsize > 0) )
+ {
+ mn = exif_data_get_mnote_data(d);
+ }
+ else
+ {
+ return;
+ }
+
+ if ( mn != NULL )
+ {
+ num = exif_mnote_data_count(mn);
+
+ /* Loop through all MakerNote tags, searching for the desired one */
+ for (i=0; i < num; ++i)
+ {
+ if (exif_mnote_data_get_id(mn, i) == tag)
+ {
+ if (exif_mnote_data_get_value(mn, i, buf, sizeof(buf)))
+ {
+ /* Don't bother printing it if it's entirely blank */
+ exif_trim_spaces(buf);
+ if (*buf != '\0')
+ {
+ snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_mnote_data_get_title(mn, i), buf);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/* return data structure with exif data if available */
+ExifData * exif_get_data(char *path)
+{
+ ExifData *ed = NULL;
+
+ /* Load an ExifData object from an EXIF file */
+ ed = exif_data_new_from_file(path);
+ if (ed == NULL)
+ {
+ D(("File not readable or no Exif data present in %s\n", path));
+ }
+
+ return(ed);
+}
+
+
+
+/* get exif data in readable form */
+void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ ExifEntry *entry = NULL;
+ char buf[64];
+
+ if ( (buffer == NULL) || (maxsize == 0) )
+ {
+ return;
+ }
+ else if (ed == NULL )
+ {
+ snprintf(buffer, (size_t)maxsize, "%s\n", "No Exif data in file.");
+ return;
+ }
+ else if ( ed != NULL )
+ {
+ /* normal exif tags */
+ exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MAKE, buffer, maxsize);
+ exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MODEL, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buffer + strlen(buffer), maxsize - strlen(buffer));
+ exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH_ENERGY, buffer + strlen(buffer), maxsize - strlen(buffer));
+
+ /* vendor specific makernote tags */
+ entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
+ if (entry != NULL)
+ {
+
+ if (exif_entry_get_value(entry, buf, sizeof(buf)))
+ {
+ exif_trim_spaces(buf);
+
+ /* Nikon */
+ if ( strcmp(buf, "Nikon") != 0 )
+ {
+ /* Digital Vari-Program */
+ exif_get_mnote_tag(ed, 171, buffer + strlen(buffer), maxsize - strlen(buffer));
+ }
+
+ }
+ }
+ }
+}
+
+#endif