1 /*
2 * libexif example program to display the contents of a number of specific
3 * EXIF and MakerNote tags. The tags selected are those that may aid in
4 * identification of the photographer who took the image.
5 *
6 * Placed into the public domain by Dan Fandrich
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <libexif/exif-data.h>
12
13 /* Remove spaces on the right of the string */
trim_spaces(char * buf)14 static void trim_spaces(char *buf)
15 {
16 char *s = buf-1;
17 for (; *buf; ++buf) {
18 if (*buf != ' ')
19 s = buf;
20 }
21 *++s = 0; /* nul terminate the string on the first of the final spaces */
22 }
23
24 /* Show the tag name and contents if the tag exists */
show_tag(ExifData * d,ExifIfd ifd,ExifTag tag)25 static void show_tag(ExifData *d, ExifIfd ifd, ExifTag tag)
26 {
27 /* See if this tag exists */
28 ExifEntry *entry = exif_content_get_entry(d->ifd[ifd],tag);
29 if (entry) {
30 char buf[1024];
31
32 /* Get the contents of the tag in human-readable form */
33 exif_entry_get_value(entry, buf, sizeof(buf));
34
35 /* Don't bother printing it if it's entirely blank */
36 trim_spaces(buf);
37 if (*buf) {
38 printf("%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), buf);
39 }
40 }
41 }
42
43 /* Show the given MakerNote tag if it exists */
show_mnote_tag(ExifData * d,unsigned tag)44 static void show_mnote_tag(ExifData *d, unsigned tag)
45 {
46 ExifMnoteData *mn = exif_data_get_mnote_data(d);
47 if (mn) {
48 int num = exif_mnote_data_count(mn);
49 int i;
50
51 /* Loop through all MakerNote tags, searching for the desired one */
52 for (i=0; i < num; ++i) {
53 char buf[1024];
54 if (exif_mnote_data_get_id(mn, i) == tag) {
55 if (exif_mnote_data_get_value(mn, i, buf, sizeof(buf))) {
56 /* Don't bother printing it if it's entirely blank */
57 trim_spaces(buf);
58 if (*buf) {
59 printf("%s: %s\n", exif_mnote_data_get_title(mn, i),
60 buf);
61 }
62 }
63 }
64 }
65 }
66 }
67
main(int argc,char ** argv)68 int main(int argc, char **argv)
69 {
70 ExifData *ed;
71 ExifEntry *entry;
72
73 if (argc < 2) {
74 printf("Usage: %s image.jpg\n", argv[0]);
75 printf("Displays tags potentially relating to ownership "
76 "of the image.\n");
77 return 1;
78 }
79
80 /* Load an ExifData object from an EXIF file */
81 ed = exif_data_new_from_file(argv[1]);
82 if (!ed) {
83 printf("File not readable or no EXIF data in file %s\n", argv[1]);
84 return 2;
85 }
86
87 /* Show all the tags that might contain information about the
88 * photographer
89 */
90 show_tag(ed, EXIF_IFD_0, EXIF_TAG_ARTIST);
91 show_tag(ed, EXIF_IFD_0, EXIF_TAG_XP_AUTHOR);
92 show_tag(ed, EXIF_IFD_0, EXIF_TAG_COPYRIGHT);
93
94 /* These are much less likely to be useful */
95 show_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_USER_COMMENT);
96 show_tag(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION);
97 show_tag(ed, EXIF_IFD_1, EXIF_TAG_IMAGE_DESCRIPTION);
98
99 /* A couple of MakerNote tags can contain useful data. Read the
100 * manufacturer tag to see if this image could have one of the recognized
101 * MakerNote tags.
102 */
103 entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
104 if (entry) {
105 char buf[64];
106
107 /* Get the contents of the manufacturer tag as a string */
108 if (exif_entry_get_value(entry, buf, sizeof(buf))) {
109 trim_spaces(buf);
110
111 if (!strcmp(buf, "Canon")) {
112 show_mnote_tag(ed, 9); /* MNOTE_CANON_TAG_OWNER */
113
114 } else if (!strcmp(buf, "Asahi Optical Co.,Ltd.") ||
115 !strcmp(buf, "PENTAX Corporation")) {
116 show_mnote_tag(ed, 0x23); /* MNOTE_PENTAX2_TAG_HOMETOWN_CITY */
117 }
118 }
119 }
120
121 /* Free the EXIF data */
122 exif_data_unref(ed);
123
124 return 0;
125 }
126