summaryrefslogtreecommitdiff
path: root/src/exif.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2012-04-04 21:24:12 +0200
committerDaniel Friesel <derf@finalrewind.org>2012-04-04 21:24:12 +0200
commitbb954ff134e4299d4251e0376363271c3feccc56 (patch)
tree2bf3d2dde7dc56aad24a222f611e6622a01b84db /src/exif.c
parent82a976e0909e02ba8c25e4fd10d0e56a3e5c13ca (diff)
Lots of EXIF mode fixes and improvements by Dennis Real (closes #87)
Squashed commit of the following: commit 58dd2e303c5ee380527d92a3fa3d6baeeacb50a1 Merge: cf6f032 82a976e Author: Dennis Real <github@tildepipe.org> Date: Sat Mar 31 18:43:47 2012 +0200 Merge branch 'master' of git://github.com/derf/feh commit cf6f0320c15abd753951990a963d5c94b180bbde Merge: 10b7b1e 877e634 Author: Dennis Real <github@tildepipe.org> Date: Sun Mar 25 19:07:30 2012 +0200 Merge branch 'master' of git://github.com/derf/feh commit 10b7b1e3e10ba650b240a742947cb6850bbadd23 Author: Dennis Real <github@tildepipe.org> Date: Sat Mar 24 14:41:15 2012 +0100 Support for Canon Exif makernote tags commit 3c284dc81dcb26249114b7ecf32ed0000f492b8b Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:44:32 2012 +0100 Support for Active D-Lightning commit ad5aea8cb853cc9d1b322c69f4812ad0bcb08ef3 Merge: cc6de20 9c43b64 Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:01:38 2012 +0100 Merge remote branch 'upstream/master' commit cc6de20061eaa7172aa0184e03df947da14d713e Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:00:30 2012 +0100 Nikon makernote parts changed commit e401bd9c78a82b8290ec524e56b7c832631725e6 Author: Dennis Real <github@tildepipe.org> Date: Wed Mar 21 19:47:15 2012 +0100 1. Own module for nikon maker notes 2. Support for AFInfo2 commit 39cbd1ed2b6693beea5e974a6ae83207c6e9a826 Merge: 9e1bbf8 a100123 Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 22:22:28 2012 +0100 Merge remote branch 'upstream/master' commit 9e1bbf874500e99506baffec3c6b54ed04e60a2f Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 22:20:58 2012 +0100 - exif handling changed - gps info added if available commit 8e96382805eb77a82209df9d71dbf9c0dd1c4cdb Merge: 77fa5ac 29cd868 Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 19:13:47 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit 77fa5aca182435f2771511832ea198d027393ceb Merge: 93a90e6 3b2756b Author: Dennis Real <github@tildepipe.org> Date: Wed Mar 7 17:18:07 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit 93a90e60d0cf093ca71c34f4f5dbfde974f433f0 Merge: a81465d 52d5da9 Author: Dennis Real <github@tildepipe.org> Date: Tue Mar 6 21:42:40 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit a81465d019593cfd1e506eb66f20f6b5e10488f3 Merge: a19e50d 31afac4 Author: Dennis Real <github@tildepipe.org> Date: Mon Mar 5 17:23:40 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit a19e50deb749c5188bdbc75a5c1cd6ab1f3f3a3a Merge: 1c89da1 fe9a16b Author: Dennis Real <github@tildepipe.org> Date: Sun Mar 4 15:35:45 2012 +0100 Merge branch 'master' of ssh://github.com/reald/feh commit 1c89da1269089d98529a6635c36d014da1b08eb4 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:37:22 2012 +0100 test case adapted to new testfile commit bb3c9d3571e43f913c6f659fefd9cd34971fd004 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:34:51 2012 +0100 test file with some exif data added commit fe9a16bce3f06d45acf103fc4439c1af2dc4ac6c Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:37:22 2012 +0100 test case adapted to new testfile commit e0bedc0438cf4ab4eafe43afca0886ad63591560 Merge: 46801fe 69ecc5c Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:36:08 2012 +0100 Merge remote branch 'upstream/master' commit 46801fee8de26f4e0af2ed294c3a4f7fc1c45ca3 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:34:51 2012 +0100 test file with some exif data added
Diffstat (limited to 'src/exif.c')
-rw-r--r--src/exif.c239
1 files changed, 158 insertions, 81 deletions
diff --git a/src/exif.c b/src/exif.c
index dcf2a88..a30b2ef 100644
--- a/src/exif.c
+++ b/src/exif.c
@@ -28,16 +28,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdio.h>
#include <string.h>
#include <libexif/exif-data.h>
+#include <limits.h>
#include "feh.h"
#include "options.h"
#include "debug.h"
#include "exif.h"
+#include "exif_canon.h"
#include "exif_nikon.h"
+#include "exif_cfg.h"
/* remove all spaces on the right end of a string */
-static void exif_trim_spaces(char *str)
+void exif_trim_spaces(char *str)
{
char *end;
@@ -45,25 +48,27 @@ static void exif_trim_spaces(char *str)
{
if (*str != ' ')
{
- end = str+1;
+ end = str + 1;
}
}
*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) )
+/* show given exif tag content with tag name */
+void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
+{
+ char s[EXIF_MAX_DATA];
+ ExifEntry *entry = NULL;
+
+ if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) )
{
- ExifEntry *entry = exif_content_get_entry(d->ifd[ifd], tag);
+ 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);
+ exif_entry_get_value(entry, s, EXIF_MAX_DATA);
/* Don't bother printing it if it's entirely blank */
exif_trim_spaces(s);
@@ -78,8 +83,36 @@ static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, un
+/* show given exif tag content without tag name */
+void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
+{
+ char s[EXIF_MAX_DATA];
+ ExifEntry *entry = NULL;
+
+ if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) )
+ {
+ 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, EXIF_MAX_DATA);
+
+ /* 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);
+ }
+ }
+ }
+
+}
+
+
+
/* Show the given MakerNote tag if it exists */
-static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)
+void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)
{
ExifMnoteData *mn = NULL;
int i, num;
@@ -101,6 +134,11 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi
/* Loop through all MakerNote tags, searching for the desired one */
for (i=0; i < num; ++i)
{
+ D(("%d/%d %d 0x%2x %s; %s\n", i, num, exif_mnote_data_get_id(mn, i),
+ exif_mnote_data_get_id(mn, i),
+ exif_mnote_data_get_name(mn,i),
+ exif_mnote_data_get_title(mn, i) ));
+
if (exif_mnote_data_get_id(mn, i) == tag)
{
if (exif_mnote_data_get_value(mn, i, buf, sizeof(buf)))
@@ -109,6 +147,7 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi
exif_trim_spaces(buf);
if (*buf != '\0')
{
+ D(("%s\n", buf));
snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_mnote_data_get_title(mn, i), buf);
}
}
@@ -119,6 +158,70 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi
+/* get gps coordinates if available */
+void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize)
+{
+ char buf[EXIF_STD_BUF_LEN];
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, buf, sizeof(buf));
+ if ( buf[0] != '\0' )
+ {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "GPS: %s ", buf);
+ }
+ else
+ {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, buf, sizeof(buf));
+ if ( buf[0] != '\0' )
+ {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf);
+ }
+ else
+ {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, buf, sizeof(buf));
+ if ( buf[0] != '\0' )
+ {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), ", %s ", buf);
+ }
+ else
+ {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, buf, sizeof(buf));
+ if ( buf[0] != '\0' )
+ {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf);
+ }
+ else
+ {
+ return;
+ }
+
+ buf[0] = '\0';
+ exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_MAP_DATUM, buf, sizeof(buf));
+ if ( buf[0] != '\0' )
+ {
+ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "(%s)\n", buf);
+ }
+ else
+ {
+ return;
+ }
+
+}
+
+
+
/* return data structure with exif data if available */
ExifData * exif_get_data(char *path)
{
@@ -136,15 +239,14 @@ ExifData * exif_get_data(char *path)
-/* get exif data in readable form */
+
+/* get all exif data in readable form */
void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
{
ExifEntry *entry = NULL;
- char buf[128];
- unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */
- unsigned int version = 0;
- unsigned int length = 0;
-
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned short int i = 0;
+
if ( (buffer == NULL) || (maxsize == 0) )
{
return;
@@ -156,27 +258,14 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
}
else
{
- /* 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 */
+ /* show normal exif tags. list must be defined in exif_cfg.h */
+ while ( (Exif_tag_list[i].ifd != EXIF_IFD_COUNT) && (i < USHRT_MAX) )
+ {
+ exif_get_tag(ed, Exif_tag_list[i].ifd, Exif_tag_list[i].tag, buffer + strlen(buffer), maxsize - strlen(buffer));
+ i++;
+ }
+
+ /* show vendor specific makernote tags */
entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
if (entry != NULL)
{
@@ -184,58 +273,46 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
if (exif_entry_get_value(entry, buf, sizeof(buf)))
{
exif_trim_spaces(buf);
-
- /* Nikon */
- if ( strcmp(buf, "Nikon") != 0 )
- {
- /* this is a nikon camera */
-
- buf[0] = '\0';
- exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
- exif_trim_spaces(buf);
- if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
+ if ( (strcmp(buf, "NIKON CORPORATION") == 0)
+ || (strcmp(buf, "Nikon") == 0)
+ || (strcmp(buf, "NIKON") == 0)
+ )
+ {
+ /* show nikon makernote exif tags. list must be defined in exif_cfg.h */
+ i=0;
+ while ( (Exif_makernote_nikon_tag_list[i] != EXIF_NIKON_MAKERNOTE_END) && (i < USHRT_MAX) )
{
- /* extended flash info if it was fired */
-
- /* Flash Setting */
- exif_get_mnote_tag(ed, 8, buffer + strlen(buffer), maxsize - strlen(buffer));
- /* Flash Mode */
- exif_get_mnote_tag(ed, 9, buffer + strlen(buffer), maxsize - strlen(buffer));
- /* flash exposure bracket value */
- exif_get_mnote_tag(ed, 24, buffer + strlen(buffer), maxsize - strlen(buffer));
- /* Flash used */
- exif_get_mnote_tag(ed, 135, buffer + strlen(buffer), maxsize - strlen(buffer));
-
- /* Flash info: control mode. */
- /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */
- buf[0] = '\0';
- exif_get_mnote_tag(ed, 168, buf, sizeof(buf));
- sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*10s%02X", &length, &version, &exn_fcm);
- exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK;
-
- if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX)
- && ( ((length == 22) && (version == '3')) /* Nikon FlashInfo0103 */
- || ((length == 22) && (version == '4')) /* Nikon FlashInfo0104 */
- || ((length == 21) && (version == '2')) /* Nikon FlashInfo0102 */
- || ((length == 19) && (version == '0')) /* Nikon FlashInfo0100 */
- )
- )
- {
- snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "NikonFlashControlMode: %s\n",
- EXN_NikonFlashControlModeValues[exn_fcm]);
- }
+ exn_get_mnote_nikon_tags(ed, Exif_makernote_nikon_tag_list[i],
+ buffer + strlen(buffer), maxsize - strlen(buffer));
+ i++;
}
- /* Lens */
- exif_get_mnote_tag(ed, 132, buffer + strlen(buffer), maxsize - strlen(buffer));
- /* Digital Vari-Program */
- exif_get_mnote_tag(ed, 171, buffer + strlen(buffer), maxsize - strlen(buffer));
}
-
+ else if ( (strcmp(buf, "Canon") == 0) )
+ {
+ /* show canon makernote exif tags. list must be defined in exif_cfg.h */
+ i=0;
+ while ( (Exif_makernote_canon_tag_list[i] != EXIF_CANON_MAKERNOTE_END) && (i < USHRT_MAX) )
+ {
+ exc_get_mnote_canon_tags(ed, Exif_makernote_canon_tag_list[i],
+ buffer + strlen(buffer), maxsize - strlen(buffer));
+ i++;
+ }
+
+ }
+ else
+ {
+ }
}
+
}
+
+ /* show gps coordinates */
+ exif_get_gps_coords(ed, buffer + strlen(buffer), maxsize - strlen(buffer));
+
}
+
}
#endif