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