Mercurial > geeqie.yaz
annotate src/exif-common.c @ 276:4f526d436873
Implement secure rc file saving.
First data is written to a temporary file, then if nothing
was wrong, this file is renamed to the final name.
This way the risk of corrupted rc file is greatly reduced.
The code is borrowed from ELinks (http://elinks.cz).
author | zas_ |
---|---|
date | Tue, 08 Apr 2008 21:55:58 +0000 |
parents | cccba3e30a44 |
children | 9995c5fb202a |
rev | line source |
---|---|
182 | 1 /* |
2 * GQView | |
3 * (C) 2006 John Ellis | |
4 * | |
5 */ | |
6 | |
7 #ifdef HAVE_CONFIG_H | |
8 # include "config.h" | |
9 #endif | |
10 | |
11 #include <stdio.h> | |
12 #include <string.h> | |
13 #include <fcntl.h> | |
14 #include <unistd.h> | |
15 #include <sys/types.h> | |
16 #include <sys/stat.h> | |
17 #include <sys/mman.h> | |
18 #include <math.h> | |
19 | |
20 #include <glib.h> | |
21 | |
22 #include "intl.h" | |
23 | |
24 #include "gqview.h" | |
25 #include "exif.h" | |
26 | |
239
cccba3e30a44
Remove two unused variables declarations, and add a missing #include.
zas_
parents:
222
diff
changeset
|
27 #include "filelist.h" |
182 | 28 #include "format_raw.h" |
29 #include "ui_fileops.h" | |
30 | |
31 | |
32 /* human readable key list */ | |
33 | |
34 ExifFormattedText ExifFormattedList[] = { | |
35 { "fCamera", N_("Camera") }, | |
36 { "fDateTime", N_("Date") }, | |
37 { "fShutterSpeed", N_("Shutter speed") }, | |
38 { "fAperture", N_("Aperture") }, | |
39 { "fExposureBias", N_("Exposure bias") }, | |
40 { "fISOSpeedRating", N_("ISO sensitivity") }, | |
41 { "fFocalLength", N_("Focal length") }, | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
42 { "fFocalLength35mmFilm",N_("Focal length 35mm") }, |
182 | 43 { "fSubjectDistance", N_("Subject distance") }, |
44 { "fFlash", N_("Flash") }, | |
45 { "fResolution", N_("Resolution") }, | |
46 { NULL, NULL } | |
47 }; | |
48 | |
49 double exif_rational_to_double(ExifRational *r, gint sign) | |
50 { | |
51 if (!r || r->den == 0.0) return 0.0; | |
52 | |
53 if (sign) return (double)((int)r->num) / (double)((int)r->den); | |
54 return (double)r->num / r->den; | |
55 } | |
56 | |
57 double exif_get_rational_as_double(ExifData *exif, const gchar *key) | |
58 { | |
59 ExifRational *r; | |
60 gint sign; | |
61 | |
62 r = exif_get_rational(exif, key, &sign); | |
63 return exif_rational_to_double(r, sign); | |
64 } | |
65 | |
66 static GString *append_comma_text(GString *string, const gchar *text) | |
67 { | |
68 string = g_string_append(string, ", "); | |
69 string = g_string_append(string, text); | |
70 | |
71 return string; | |
72 } | |
73 | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
74 static gchar *remove_common_prefix(gchar *s, gchar *t) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
75 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
76 gint i; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
77 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
78 if (!s || !t) return t; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
79 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
80 for (i = 0; s[i] == t[i]; i++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
81 ; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
82 if (!i) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
83 return t; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
84 if (s[i]==' ' || s[i]==0) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
85 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
86 while (t[i] == ' ') |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
87 i++; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
88 return t + i; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
89 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
90 return s; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
91 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
92 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
93 static double get_crop_factor(ExifData *exif) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
94 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
95 double res_unit_tbl[] = {0.0, 25.4, 25.4, 10.0, 1.0, 0.001 }; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
96 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
97 double xres = exif_get_rational_as_double(exif, "Exif.Photo.FocalPlaneXResolution"); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
98 double yres = exif_get_rational_as_double(exif, "Exif.Photo.FocalPlaneYResolution"); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
99 int res_unit; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
100 int w, h; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
101 double xsize, ysize, size, ratio; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
102 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
103 if (xres == 0.0 || yres == 0.0) return 0.0; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
104 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
105 if (!exif_get_integer(exif, "Exif.Photo.FocalPlaneResolutionUnit", &res_unit)) return 0.0; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
106 if (res_unit < 1 || res_unit > 5) return 0.0; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
107 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
108 if (!exif_get_integer(exif, "Exif.Photo.PixelXDimension", &w)) return 0.0; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
109 if (!exif_get_integer(exif, "Exif.Photo.PixelYDimension", &h)) return 0.0; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
110 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
111 xsize = w * res_unit_tbl[res_unit] / xres; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
112 ysize = h * res_unit_tbl[res_unit] / yres; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
113 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
114 ratio = xsize / ysize; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
115 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
116 if (ratio < 0.5 || ratio > 2.0) return 0.0; /* reasonable ratio */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
117 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
118 size = sqrt(xsize * xsize + ysize * ysize); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
119 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
120 if (size < 1.0 || size > 100.0) return 0.0; /* reasonable sensor size in mm */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
121 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
122 return sqrt(36*36+24*24) / size; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
123 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
124 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
125 |
182 | 126 |
127 gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_valid) | |
128 { | |
129 /* must begin with f, else not formatted */ | |
130 if (key[0] != 'f') | |
131 { | |
132 if (key_valid) *key_valid = FALSE; | |
133 return NULL; | |
134 } | |
135 | |
136 if (key_valid) *key_valid = TRUE; | |
137 | |
138 if (strcmp(key, "fCamera") == 0) | |
139 { | |
140 gchar *text; | |
141 gchar *make = exif_get_data_as_text(exif, "Exif.Image.Make"); | |
142 gchar *model = exif_get_data_as_text(exif, "Exif.Image.Model"); | |
143 gchar *software = exif_get_data_as_text(exif, "Exif.Image.Software"); | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
144 gchar *model2; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
145 gchar *software2; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
146 gint i; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
147 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
148 if (make) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
149 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
150 g_strstrip(make); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
151 #define REMOVE_SUFFIX(str,suff) \ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
152 do { \ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
153 if (g_str_has_suffix(str,suff)) \ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
154 str[strlen(str)-(sizeof(suff)-1)] = 0; \ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
155 } while(0) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
156 REMOVE_SUFFIX(make," Corporation"); /* Pentax */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
157 REMOVE_SUFFIX(make," OPTICAL CO.,LTD"); /* OLYMPUS */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
158 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
159 if (model) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
160 g_strstrip(model); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
161 if (software) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
162 g_strstrip(software); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
163 /* remove superfluous spaces (pentax K100D) */ |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
164 for (i=0; software && software[i]; i++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
165 if (software[i] == ' ' && software[i+1] == ' ') |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
166 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
167 gint j; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
168 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
169 for (j=1; software[i+j]; j++) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
170 if (software[i+j] != ' ') |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
171 break; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
172 memmove(software+i+1, software+i+j, strlen(software+i+j)+1); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
173 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
174 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
175 model2 = remove_common_prefix(make, model); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
176 software2 = remove_common_prefix(model2, software); |
182 | 177 |
178 text = g_strdup_printf("%s%s%s%s%s%s", (make) ? make : "", ((make) && (model)) ? " " : "", | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
179 (model2) ? model2 : "", |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
180 (software2) ? " (" : "", |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
181 (software2) ? software2 : "", |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
182 (software2) ? ")" : ""); |
182 | 183 |
184 g_free(make); | |
185 g_free(model); | |
186 g_free(software); | |
187 return text; | |
188 } | |
189 if (strcmp(key, "fDateTime") == 0) | |
190 { | |
191 gchar *text = exif_get_data_as_text(exif, "Exif.Photo.DateTimeOriginal"); | |
192 gchar *subsec = NULL; | |
193 if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTimeOriginal"); | |
194 if (!text) | |
195 { | |
196 text = exif_get_data_as_text(exif, "Exif.Image.DateTime"); | |
197 if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTime"); | |
198 } | |
199 if (subsec) | |
200 { | |
201 gchar *tmp = text; | |
202 text = g_strconcat(tmp, ".", subsec, NULL); | |
203 g_free(tmp); | |
204 g_free(subsec); | |
205 } | |
206 return text; | |
207 } | |
208 if (strcmp(key, "fShutterSpeed") == 0) | |
209 { | |
210 ExifRational *r; | |
211 | |
212 r = exif_get_rational(exif, "Exif.Photo.ExposureTime", NULL); | |
213 if (r && r->num && r->den) | |
214 { | |
215 double n = (double)r->den / (double)r->num; | |
216 return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "", | |
217 n > 1.0 ? n : 1.0 / n); | |
218 } | |
219 r = exif_get_rational(exif, "Exif.Photo.ShutterSpeedValue", NULL); | |
220 if (r && r->num && r->den) | |
221 { | |
222 double n = pow(2.0, exif_rational_to_double(r, TRUE)); | |
223 | |
224 /* Correct exposure time to avoid values like 1/91s (seen on Minolta DImage 7) */ | |
225 if (n > 1.0 && (int)n - ((int)(n/10))*10 == 1) n--; | |
226 | |
227 return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "", | |
228 n > 1.0 ? floor(n) : 1.0 / n); | |
229 } | |
230 return NULL; | |
231 } | |
232 if (strcmp(key, "fAperture") == 0) | |
233 { | |
234 double n; | |
235 | |
236 n = exif_get_rational_as_double(exif, "Exif.Photo.FNumber"); | |
237 if (n == 0.0) n = exif_get_rational_as_double(exif, "Exif.Photo.ApertureValue"); | |
238 if (n == 0.0) return NULL; | |
239 | |
240 return g_strdup_printf("f/%.1f", n); | |
241 } | |
242 if (strcmp(key, "fExposureBias") == 0) | |
243 { | |
244 ExifRational *r; | |
245 gint sign; | |
246 double n; | |
247 | |
248 r = exif_get_rational(exif, "Exif.Photo.ExposureBiasValue", &sign); | |
249 if (!r) return NULL; | |
250 | |
251 n = exif_rational_to_double(r, sign); | |
252 return g_strdup_printf("%+.1f", n); | |
253 } | |
254 if (strcmp(key, "fFocalLength") == 0) | |
255 { | |
256 double n; | |
257 | |
258 n = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength"); | |
259 if (n == 0.0) return NULL; | |
222
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
260 return g_strdup_printf("%.0f mm", n); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
261 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
262 if (strcmp(key, "fFocalLength35mmFilm") == 0) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
263 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
264 gint n; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
265 double f, c; |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
266 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
267 if (exif_get_integer(exif, "Exif.Photo.FocalLengthIn35mmFilm", &n) && n != 0) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
268 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
269 return g_strdup_printf("%d mm", n); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
270 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
271 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
272 f = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength"); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
273 c = get_crop_factor(exif); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
274 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
275 if (f != 0.0 && c != 0.0) |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
276 { |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
277 return g_strdup_printf("%.0f mm", f * c); |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
278 } |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
279 |
77f1bcc6c161
various exif improvements based on patch by Uwe Ohse
nadvornik
parents:
212
diff
changeset
|
280 return NULL; |
182 | 281 } |
282 if (strcmp(key, "fISOSpeedRating") == 0) | |
283 { | |
284 gchar *text; | |
285 | |
286 text = exif_get_data_as_text(exif, "Exif.Photo.ISOSpeedRatings"); | |
287 /* kodak may set this instead */ | |
288 if (!text) text = exif_get_data_as_text(exif, "Exif.Photo.ExposureIndex"); | |
289 return text; | |
290 } | |
291 if (strcmp(key, "fSubjectDistance") == 0) | |
292 { | |
293 ExifRational *r; | |
294 gint sign; | |
295 double n; | |
296 | |
297 r = exif_get_rational(exif, "Exif.Photo.SubjectDistance", &sign); | |
298 if (!r) return NULL; | |
299 | |
300 if ((long)r->num == 0xffffffff) return g_strdup(_("infinity")); | |
301 if ((long)r->num == 0) return g_strdup(_("unknown")); | |
302 | |
303 n = exif_rational_to_double(r, sign); | |
304 if (n == 0.0) return _("unknown"); | |
305 return g_strdup_printf("%.3f m", n); | |
306 } | |
307 if (strcmp(key, "fFlash") == 0) | |
308 { | |
309 /* grr, flash is a bitmask... */ | |
310 GString *string; | |
311 gchar *text; | |
312 gint n; | |
313 gint v; | |
314 | |
315 if (!exif_get_integer(exif, "Exif.Photo.Flash", &n)) return NULL; | |
316 | |
317 /* Exif 2.1 only defines first 3 bits */ | |
184 | 318 if (n <= 0x07) return exif_get_data_as_text(exif, "Exif.Photo.Flash"); |
182 | 319 |
320 /* must be Exif 2.2 */ | |
321 string = g_string_new(""); | |
322 | |
323 /* flash fired (bit 0) */ | |
324 string = g_string_append(string, (n & 0x01) ? _("yes") : _("no")); | |
325 | |
326 /* flash mode (bits 3, 4) */ | |
327 v = (n >> 3) & 0x03; | |
328 if (v) string = append_comma_text(string, _("mode:")); | |
329 switch (v) | |
330 { | |
331 case 1: | |
332 string = g_string_append(string, _("on")); | |
333 break; | |
334 case 2: | |
335 string = g_string_append(string, _("off")); | |
336 break; | |
337 case 3: | |
338 string = g_string_append(string, _("auto")); | |
339 break; | |
340 } | |
341 | |
342 /* return light (bits 1, 2) */ | |
343 v = (n >> 1) & 0x03; | |
344 if (v == 2) string = append_comma_text(string, _("not detected by strobe")); | |
345 if (v == 3) string = append_comma_text(string, _("detected by strobe")); | |
346 | |
347 /* we ignore flash function (bit 5) */ | |
348 | |
349 /* red-eye (bit 6) */ | |
350 if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction")); | |
351 | |
352 text = string->str; | |
353 g_string_free(string, FALSE); | |
354 return text; | |
355 } | |
356 if (strcmp(key, "fResolution") == 0) | |
357 { | |
358 ExifRational *rx, *ry; | |
359 gchar *units; | |
360 gchar *text; | |
361 | |
362 rx = exif_get_rational(exif, "Exif.Image.XResolution", NULL); | |
363 ry = exif_get_rational(exif, "Exif.Image.YResolution", NULL); | |
364 if (!rx || !ry) return NULL; | |
365 | |
366 units = exif_get_data_as_text(exif, "Exif.Image.ResolutionUnit"); | |
367 text = g_strdup_printf("%0.f x %0.f (%s/%s)", rx->den ? (double)rx->num / rx->den : 1.0, | |
368 ry->den ? (double)ry->num / ry->den : 1.0, | |
369 _("dot"), (units) ? units : _("unknown")); | |
370 | |
371 g_free(units); | |
372 return text; | |
373 } | |
374 | |
375 if (key_valid) *key_valid = FALSE; | |
376 return NULL; | |
377 } | |
378 | |
379 const gchar *exif_get_description_by_key(const gchar *key) | |
380 { | |
381 gint i; | |
382 | |
383 if (!key) return NULL; | |
384 | |
385 i = 0; | |
386 while (ExifFormattedList[i].key != NULL) | |
387 { | |
388 if (strcmp(key, ExifFormattedList[i].key) == 0) return _(ExifFormattedList[i].description); | |
389 i++; | |
390 } | |
391 | |
392 return exif_get_tag_description_by_key(key); | |
393 } | |
184 | 394 |
395 gint exif_get_integer(ExifData *exif, const gchar *key, gint *value) | |
396 { | |
397 ExifItem *item; | |
398 | |
399 item = exif_get_item(exif, key); | |
400 return exif_item_get_integer(item, value); | |
401 } | |
402 | |
403 ExifRational *exif_get_rational(ExifData *exif, const gchar *key, gint *sign) | |
404 { | |
405 ExifItem *item; | |
406 | |
407 item = exif_get_item(exif, key); | |
408 return exif_item_get_rational(item, sign); | |
409 } | |
410 | |
411 gchar *exif_get_data_as_text(ExifData *exif, const gchar *key) | |
412 { | |
413 ExifItem *item; | |
414 gchar *text; | |
415 gint key_valid; | |
416 | |
417 if (!key) return NULL; | |
418 | |
419 text = exif_get_formatted_by_key(exif, key, &key_valid); | |
420 if (key_valid) return text; | |
421 | |
422 item = exif_get_item(exif, key); | |
423 if (item) return exif_item_get_data_as_text(item); | |
424 | |
425 return NULL; | |
426 } | |
188
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
427 |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
428 ExifData *exif_read_fd(FileData *fd, gint parse_color_profile) |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
429 { |
204 | 430 GList *work; |
188
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
431 gchar *sidecar_path = NULL; |
190
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
432 |
204 | 433 if (!fd) return NULL; |
434 | |
435 work = fd->parent ? fd->parent->sidecar_files : fd->sidecar_files; | |
436 | |
212
c7021159079d
differentiate among normal image, raw image and metadata
nadvornik
parents:
204
diff
changeset
|
437 if (filter_file_class(fd->extension, FORMAT_CLASS_RAWIMAGE)) |
188
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
438 { |
190
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
439 while(work) |
188
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
440 { |
190
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
441 FileData *sfd = work->data; |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
442 work = work->next; |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
443 if (strcasecmp(sfd->extension, ".xmp") == 0) |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
444 { |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
445 sidecar_path = sfd->path; |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
446 break; |
c2923efebfdc
whitelist of files that can have an xmp sidecar, sample external command
nadvornik
parents:
188
diff
changeset
|
447 } |
188
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
448 } |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
449 } |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
450 |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
451 |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
452 // FIXME: some caching would be nice |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
453 return exif_read(fd->path, sidecar_path, parse_color_profile); |
0584cb78aa14
write comment and keywords to xmp, sidecars are used if exist
nadvornik
parents:
184
diff
changeset
|
454 } |