1 /* mnote-apple-entry.c
2 *
3 * Copyright (c) 2018 zhanwang-sky <zhanwang_sky@163.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA.
19 */
20
21 #include <config.h>
22 #include "mnote-apple-entry.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <libexif/exif-entry.h>
29 #include <libexif/exif-format.h>
30 #include <libexif/exif-utils.h>
31 #include <libexif/i18n.h>
32
33 char *
mnote_apple_entry_get_value(MnoteAppleEntry * entry,char * v,unsigned int maxlen)34 mnote_apple_entry_get_value(MnoteAppleEntry *entry, char *v, unsigned int maxlen) {
35 ExifLong vl;
36 ExifSLong vsl;
37 ExifShort vs;
38 ExifSShort vss;
39 ExifRational vr;
40 ExifSRational vsr;
41 size_t size;
42 unsigned char *data;
43
44 if (!entry)
45 return NULL;
46
47 memset(v, 0, maxlen);
48 maxlen--;
49
50 size = entry->size;
51 data = entry->data;
52 switch (entry->tag) {
53 case MNOTE_APPLE_TAG_HDR:
54 if (size < 4) return NULL;
55 if (entry->format != EXIF_FORMAT_SLONG) return NULL;
56 if (entry->components != 1) return NULL;
57
58 vsl = exif_get_slong(data, entry->order);
59 snprintf(v, maxlen, "%d", vsl);
60 break;
61 case MNOTE_APPLE_TAG_IMAGE_UNIQUE_ID:
62 case MNOTE_APPLE_TAG_BURST_UUID:
63 case MNOTE_APPLE_TAG_MEDIA_GROUP_UUID:
64 if (entry->format != EXIF_FORMAT_ASCII) return NULL;
65 strncpy (v, (char *) data, MIN (maxlen-1, size));
66 v[MIN (maxlen-1, size)] = 0;
67 break;
68 default:
69 switch (entry->format) {
70 case EXIF_FORMAT_ASCII:
71 strncpy (v, (char *)data, MIN(maxlen, size));
72 break;
73 case EXIF_FORMAT_SHORT: {
74 size_t i, len = 0;
75
76 for(i=0; i<entry->components; i++) {
77 if (size < 2)
78 break;
79 if (len > maxlen)
80 break;
81 vs = exif_get_short (data, entry->order);
82 snprintf (v+len, maxlen-len, "%hu ", vs);
83 len = strlen(v);
84 data += 2;
85 size -= 2;
86 }
87 }
88 break;
89 case EXIF_FORMAT_SSHORT: {
90 size_t i, len = 0;
91 for(i=0; i<entry->components; i++) {
92 if (size < 2)
93 break;
94 if (len > maxlen)
95 break;
96 vss = exif_get_sshort (data, entry->order);
97 snprintf (v+len, maxlen-len, "%hi ", vss);
98 len = strlen(v);
99 data += 2;
100 size -= 2;
101 }
102 }
103 break;
104 case EXIF_FORMAT_LONG: {
105 size_t i, len = 0;
106 for(i=0; i<entry->components; i++) {
107 if (size < 4)
108 break;
109 if (len > maxlen)
110 break;
111 vl = exif_get_long (data, entry->order);
112 snprintf (v+len, maxlen-len, "%lu ", (long unsigned) vl);
113 len = strlen(v);
114 data += 4;
115 size -= 4;
116 }
117 }
118 break;
119 case EXIF_FORMAT_SLONG: {
120 size_t i, len = 0;
121 for(i=0; i<entry->components; i++) {
122 if (size < 4)
123 break;
124 if (len > maxlen)
125 break;
126 vsl = exif_get_slong (data, entry->order);
127 snprintf (v+len, maxlen-len, "%li ", (long int) vsl);
128 len = strlen(v);
129 data += 4;
130 size -= 4;
131 }
132 }
133 break;
134 case EXIF_FORMAT_RATIONAL:
135 if (size < exif_format_get_size (EXIF_FORMAT_RATIONAL)) return NULL;
136 if (entry->components < 1) return NULL; /* FIXME: could handle more than 1 too */
137 vr = exif_get_rational (data, entry->order);
138 if (!vr.denominator) break;
139 snprintf (v, maxlen, "%2.4f", (double) vr.numerator /
140 vr.denominator);
141 break;
142 case EXIF_FORMAT_SRATIONAL:
143 if (size < exif_format_get_size (EXIF_FORMAT_SRATIONAL)) return NULL;
144 if (entry->components < 1) return NULL; /* FIXME: could handle more than 1 too */
145 vsr = exif_get_srational (data, entry->order);
146 if (!vsr.denominator) break;
147 snprintf (v, maxlen, "%2.4f", (double) vsr.numerator /
148 vsr.denominator);
149 break;
150 case EXIF_FORMAT_UNDEFINED:
151 default:
152 snprintf (v, maxlen, _("%i bytes unknown data"), entry->size);
153 break;
154 }
155 break;
156 }
157
158 return v;
159 }
160