1 /*
2 * * Copyright (C) 2006-2011 Anders Brander <anders@brander.dk>,
3 * * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include <rawstudio.h>
21 #include <libxml/encoding.h>
22 #include "config.h"
23
24 static GHashTable *lens_fix_hash_table;
25
26 static gchar *
lens_fix_str_hash(RS_MAKE make,gint id,gdouble min_focal,gdouble max_focal)27 lens_fix_str_hash(RS_MAKE make, gint id, gdouble min_focal, gdouble max_focal)
28 {
29 return g_strdup_printf("%d %d:%0.1f:%0.1f", (int)make, id, min_focal, max_focal);
30 }
31
32 static const gchar*
lens_fix_find(RS_MAKE make,gint id,gdouble min_focal,gdouble max_focal)33 lens_fix_find(RS_MAKE make, gint id, gdouble min_focal, gdouble max_focal)
34 {
35 gchar *str_hash = lens_fix_str_hash(make, id, min_focal, max_focal);
36 const gchar* lens_name = g_hash_table_lookup(lens_fix_hash_table, str_hash);
37 g_free(str_hash);
38 return lens_name;
39 }
40
41 static gboolean
lens_fix_insert(RS_MAKE make,gint id,gdouble min_focal,gdouble max_focal,const gchar * name)42 lens_fix_insert(RS_MAKE make, gint id, gdouble min_focal, gdouble max_focal, const gchar* name)
43 {
44 gchar *str_hash = lens_fix_str_hash(make, id, min_focal, max_focal); /* May NOT be freed */
45
46 if (!lens_fix_find(make, id, min_focal, max_focal))
47 g_hash_table_insert(lens_fix_hash_table, str_hash, g_strdup(name));
48 else
49 g_free(str_hash);
50
51 lens_fix_find(make, id, min_focal, max_focal);
52 return TRUE;
53 }
54
55 /* These are lenses for Canon, where there is no known 3rd party lenses */
56 /* This table is mainly used for Canon cameras, where there is no text indication of lenses */
57
58 static gchar*
get_canon_name_from_lens_id(gint lens_id)59 get_canon_name_from_lens_id(gint lens_id)
60 {
61 gchar* id = NULL;
62 switch (lens_id)
63 {
64 case 1: id = g_strdup("Canon EF 50mm f/1.8"); break;
65 case 2: id = g_strdup("Canon EF 28mm f/2.8"); break;
66 case 3: id = g_strdup("Canon EF 135mm f/2.8 Soft"); break;
67 case 5: id = g_strdup("Canon EF 35-70mm f/3.5-4.5"); break;
68 case 7: id = g_strdup("Canon EF 100-300mm f/5.6L"); break;
69 case 9: id = g_strdup("Canon EF 70-210mm f/4"); break;
70 case 11: id = g_strdup("Canon EF 35mm f/2"); break;
71 case 13: id = g_strdup("Canon EF 15mm f/2.8 Fisheye"); break;
72 case 14: id = g_strdup("Canon EF 50-200mm f/3.5-4.5L"); break;
73 case 15: id = g_strdup("Canon EF 50-200mm f/3.5-4.5"); break;
74 case 16: id = g_strdup("Canon EF 35-135mm f/3.5-4.5"); break;
75 case 17: id = g_strdup("Canon EF 35-70mm f/3.5-4.5A"); break;
76 case 18: id = g_strdup("Canon EF 28-70mm f/3.5-4.5"); break;
77 case 20: id = g_strdup("Canon EF 100-200mm f/4.5A"); break;
78 case 21: id = g_strdup("Canon EF 80-200mm f/2.8L"); break;
79 case 23: id = g_strdup("Canon EF 35-105mm f/3.5-4.5"); break;
80 case 24: id = g_strdup("Canon EF 35-80mm f/4-5.6 Power Zoom"); break;
81 case 25: id = g_strdup("Canon EF 35-80mm f/4-5.6 Power Zoom"); break;
82 case 27: id = g_strdup("Canon EF 35-80mm f/4-5.6"); break;
83 case 29: id = g_strdup("Canon EF 50mm f/1.8 II"); break;
84 case 30: id = g_strdup("Canon EF 35-105mm f/4.5-5.6"); break;
85 case 33: id = g_strdup("Voigtlander or Zeiss Lens"); break;
86 case 35: id = g_strdup("Canon EF 35-80mm f/4-5.6"); break;
87 case 36: id = g_strdup("Canon EF 38-76mm f/4.5-5.6"); break;
88 case 38: id = g_strdup("Canon EF 80-200mm f/4.5-5.6"); break;
89 case 39: id = g_strdup("Canon EF 75-300mm f/4-5.6"); break;
90 case 40: id = g_strdup("Canon EF 28-80mm f/3.5-5.6"); break;
91 case 41: id = g_strdup("Canon EF 28-90mm f/4-5.6"); break;
92 case 43: id = g_strdup("Canon EF 28-105mm f/4-5.6"); break;
93 case 44: id = g_strdup("Canon EF 90-300mm f/4.5-5.6"); break;
94 case 45: id = g_strdup("Canon EF-S 18-55mm f/3.5-5.6 [II]"); break;
95 case 46: id = g_strdup("Canon EF 28-90mm f/4-5.6"); break;
96 case 48: id = g_strdup("Canon EF-S 18-55mm f/3.5-5.6 IS"); break;
97 case 49: id = g_strdup("Canon EF-S 55-250mm f/4-5.6 IS"); break;
98 case 50: id = g_strdup("Canon EF-S 18-200mm f/3.5-5.6 IS"); break;
99 case 51: id = g_strdup("Canon EF-S 18-135mm f/3.5-5.6 IS"); break;
100 case 52: id = g_strdup("Canon EF-S 18-55mm f/3.5-5.6 IS II"); break;
101 case 94: id = g_strdup("Canon TS-E 17mm f/4L"); break;
102 case 95: id = g_strdup("Canon TS-E 24.0mm f/3.5 L II"); break;
103 case 124: id = g_strdup("Canon MP-E 65mm f/2.8 1-5x Macro Photo"); break;
104 case 125: id = g_strdup("Canon TS-E 24mm f/3.5L"); break;
105 case 126: id = g_strdup("Canon TS-E 45mm f/2.8"); break;
106 case 127: id = g_strdup("Canon TS-E 90mm f/2.8"); break;
107 case 129: id = g_strdup("Canon EF 300mm f/2.8L"); break;
108 case 130: id = g_strdup("Canon EF 50mm f/1.0L"); break;
109 case 132: id = g_strdup("Canon EF 1200mm f/5.6L"); break;
110 case 134: id = g_strdup("Canon EF 600mm f/4L IS"); break;
111 case 135: id = g_strdup("Canon EF 200mm f/1.8L"); break;
112 case 136: id = g_strdup("Canon EF 300mm f/2.8L"); break;
113 case 138: id = g_strdup("Canon EF 28-80mm f/2.8-4L"); break;
114 case 139: id = g_strdup("Canon EF 400mm f/2.8L"); break;
115 case 140: id = g_strdup("Canon EF 500mm f/4.5L"); break;
116 case 141: id = g_strdup("Canon EF 500mm f/4.5L"); break;
117 case 142: id = g_strdup("Canon EF 300mm f/2.8L IS"); break;
118 case 143: id = g_strdup("Canon EF 500mm f/4L IS"); break;
119 case 144: id = g_strdup("Canon EF 35-135mm f/4-5.6 USM"); break;
120 case 145: id = g_strdup("Canon EF 100-300mm f/4.5-5.6 USM"); break;
121 case 146: id = g_strdup("Canon EF 70-210mm f/3.5-4.5 USM"); break;
122 case 147: id = g_strdup("Canon EF 35-135mm f/4-5.6 USM"); break;
123 case 148: id = g_strdup("Canon EF 28-80mm f/3.5-5.6 USM"); break;
124 case 149: id = g_strdup("Canon EF 100mm f/2 USM"); break;
125 case 151: id = g_strdup("Canon EF 200mm f/2.8L"); break;
126 case 154: id = g_strdup("Canon EF 20mm f/2.8 USM"); break;
127 case 155: id = g_strdup("Canon EF 85mm f/1.8 USM"); break;
128 case 162: id = g_strdup("Canon EF 200mm f/2.8L"); break;
129 case 163: id = g_strdup("Canon EF 300mm f/4L"); break;
130 case 164: id = g_strdup("Canon EF 400mm f/5.6L"); break;
131 case 165: id = g_strdup("Canon EF 70-200mm f/2.8 L"); break;
132 case 166: id = g_strdup("Canon EF 70-200mm f/2.8 L + 1.4x"); break;
133 case 167: id = g_strdup("Canon EF 70-200mm f/2.8 L + 2x"); break;
134 case 168: id = g_strdup("Canon EF 28mm f/1.8 USM"); break;
135 case 170: id = g_strdup("Canon EF 200mm f/2.8L II"); break;
136 case 171: id = g_strdup("Canon EF 300mm f/4L"); break;
137 case 172: id = g_strdup("Canon EF 400mm f/5.6L"); break;
138 case 175: id = g_strdup("Canon EF 400mm f/2.8L"); break;
139 case 176: id = g_strdup("Canon EF 24-85mm f/3.5-4.5 USM"); break;
140 case 177: id = g_strdup("Canon EF 300mm f/4L IS"); break;
141 case 178: id = g_strdup("Canon EF 28-135mm f/3.5-5.6 IS"); break;
142 case 179: id = g_strdup("Canon EF 24mm f/1.4L"); break;
143 case 180: id = g_strdup("Canon EF 35mm f/1.4L"); break;
144 case 181: id = g_strdup("Canon EF 100-400mm f/4.5-5.6L IS + 1.4x"); break;
145 case 182: id = g_strdup("Canon EF 100-400mm f/4.5-5.6L IS + 2x"); break;
146 case 183: id = g_strdup("Canon EF 100-400mm f/4.5-5.6L IS"); break;
147 case 184: id = g_strdup("Canon EF 400mm f/2.8L + 2x"); break;
148 case 185: id = g_strdup("Canon EF 600mm f/4L IS"); break;
149 case 186: id = g_strdup("Canon EF 70-200mm f/4L"); break;
150 case 187: id = g_strdup("Canon EF 70-200mm f/4L + 1.4x"); break;
151 case 188: id = g_strdup("Canon EF 70-200mm f/4L + 2x"); break;
152 case 189: id = g_strdup("Canon EF 70-200mm f/4L + 2.8x"); break;
153 case 190: id = g_strdup("Canon EF 100mm f/2.8 Macro"); break;
154 case 191: id = g_strdup("Canon EF 400mm f/4 DO IS"); break;
155 case 193: id = g_strdup("Canon EF 35-80mm f/4-5.6 USM"); break;
156 case 194: id = g_strdup("Canon EF 80-200mm f/4.5-5.6 USM"); break;
157 case 195: id = g_strdup("Canon EF 35-105mm f/4.5-5.6 USM"); break;
158 case 196: id = g_strdup("Canon EF 75-300mm f/4-5.6 USM"); break;
159 case 197: id = g_strdup("Canon EF 75-300mm f/4-5.6 IS USM"); break;
160 case 198: id = g_strdup("Canon EF 50mm f/1.4 USM"); break;
161 case 199: id = g_strdup("Canon EF 28-80mm f/3.5-5.6 USM"); break;
162 case 200: id = g_strdup("Canon EF 75-300mm f/4-5.6 USM"); break;
163 case 201: id = g_strdup("Canon EF 28-80mm f/3.5-5.6 USM"); break;
164 case 202: id = g_strdup("Canon EF 28-80mm f/3.5-5.6 USM IV"); break;
165 case 208: id = g_strdup("Canon EF 22-55mm f/4-5.6 USM"); break;
166 case 209: id = g_strdup("Canon EF 55-200mm f/4.5-5.6"); break;
167 case 210: id = g_strdup("Canon EF 28-90mm f/4-5.6 USM"); break;
168 case 211: id = g_strdup("Canon EF 28-200mm f/3.5-5.6 USM"); break;
169 case 212: id = g_strdup("Canon EF 28-105mm f/4-5.6 USM"); break;
170 case 213: id = g_strdup("Canon EF 90-300mm f/4.5-5.6 USM"); break;
171 case 214: id = g_strdup("Canon EF-S 18-55mm f/3.5-5.6 USM"); break;
172 case 215: id = g_strdup("Canon EF 55-200mm f/4.5-5.6 II USM"); break;
173 case 224: id = g_strdup("Canon EF 70-200mm f/2.8L IS"); break;
174 case 225: id = g_strdup("Canon EF 70-200mm f/2.8L IS + 1.4x"); break;
175 case 226: id = g_strdup("Canon EF 70-200mm f/2.8L IS + 2x"); break;
176 case 227: id = g_strdup("Canon EF 70-200mm f/2.8L IS + 2.8x"); break;
177 case 228: id = g_strdup("Canon EF 28-105mm f/3.5-4.5 USM"); break;
178 case 229: id = g_strdup("Canon EF 16-35mm f/2.8L"); break;
179 case 230: id = g_strdup("Canon EF 24-70mm f/2.8L"); break;
180 case 231: id = g_strdup("Canon EF 17-40mm f/4L"); break;
181 case 232: id = g_strdup("Canon EF 70-300mm f/4.5-5.6 DO IS USM"); break;
182 case 233: id = g_strdup("Canon EF 28-300mm f/3.5-5.6L IS"); break;
183 case 234: id = g_strdup("Canon EF-S 17-85mm f4-5.6 IS USM"); break;
184 case 235: id = g_strdup("Canon EF-S 10-22mm f/3.5-4.5 USM"); break;
185 case 236: id = g_strdup("Canon EF-S 60mm f/2.8 Macro USM"); break;
186 case 237: id = g_strdup("Canon EF 24-105mm f/4L IS"); break;
187 case 238: id = g_strdup("Canon EF 70-300mm f/4-5.6 IS USM"); break;
188 case 239: id = g_strdup("Canon EF 85mm f/1.2L II"); break;
189 case 240: id = g_strdup("Canon EF-S 17-55mm f/2.8 IS USM"); break;
190 case 241: id = g_strdup("Canon EF 50mm f/1.2L"); break;
191 case 242: id = g_strdup("Canon EF 70-200mm f/4L IS"); break;
192 case 243: id = g_strdup("Canon EF 70-200mm f/4L IS + 1.4x"); break;
193 case 244: id = g_strdup("Canon EF 70-200mm f/4L IS + 2x"); break;
194 case 245: id = g_strdup("Canon EF 70-200mm f/4L IS + 2.8x"); break;
195 case 246: id = g_strdup("Canon EF 16-35mm f/2.8L II"); break;
196 case 247: id = g_strdup("Canon EF 14mm f/2.8L II USM"); break;
197 case 248: id = g_strdup("Canon EF 200mm f/2L IS"); break;
198 case 249: id = g_strdup("Canon EF 800mm f/5.6L IS"); break;
199 case 250: id = g_strdup("Canon EF 24 f/1.4L II"); break;
200 case 251: id = g_strdup("Canon EF 70-200mm f/2.8L IS II USM"); break;
201 case 254: id = g_strdup("Canon EF 100mm f/2.8L Macro IS USM"); break;
202 case 488: id = g_strdup("Canon EF-S 15-85mm f/3.5-5.6 IS USM"); break;
203 }
204 return id;
205 }
206
207 static RS_MAKE
translate_maker_name(const gchar * maker)208 translate_maker_name(const gchar *maker)
209 {
210 if (0 == g_strcmp0(maker, "canon"))
211 return MAKE_CANON;
212 if (0 == g_strcmp0(maker, "cikon"))
213 return MAKE_NIKON;
214 if (0 == g_strcmp0(maker, "casio"))
215 return MAKE_CASIO;
216 if (0 == g_strcmp0(maker, "olympus"))
217 return MAKE_OLYMPUS;
218 if (0 == g_strcmp0(maker, "kodak"))
219 return MAKE_KODAK;
220 if (0 == g_strcmp0(maker, "leica"))
221 return MAKE_LEICA;
222 if (0 == g_strcmp0(maker, "minolta"))
223 return MAKE_MINOLTA;
224 if (0 == g_strcmp0(maker, "hasselblad"))
225 return MAKE_HASSELBLAD;
226 if (0 == g_strcmp0(maker, "panasonic"))
227 return MAKE_PANASONIC;
228 if (0 == g_strcmp0(maker, "pentax"))
229 return MAKE_PENTAX;
230 if (0 == g_strcmp0(maker, "fujifilm"))
231 return MAKE_FUJIFILM;
232 if (0 == g_strcmp0(maker, "phase one"))
233 return MAKE_PHASEONE;
234 if (0 == g_strcmp0(maker, "ricoh"))
235 return MAKE_RICOH;
236 if (0 == g_strcmp0(maker, "sony"))
237 return MAKE_SONY;
238 g_debug("Warning: Could not identify camera in lens-fix DB: %s", maker);
239 return MAKE_UNKNOWN;
240 }
241
242
243 gboolean
rs_lens_fix_init(void)244 rs_lens_fix_init(void)
245 {
246 lens_fix_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
247
248 xmlDocPtr doc;
249 xmlNodePtr cur;
250 xmlNodePtr entry = NULL;
251 xmlChar *val;
252
253 gint lens_id;
254 gdouble min_focal = 0.0, max_focal = 0.0;
255 gchar *camera_make = NULL;
256 gchar *lens_name = NULL;
257
258 gchar *filename = g_build_filename(PACKAGE_DATA_DIR, PACKAGE, "lens_fix.xml", NULL);
259
260 if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
261 {
262 g_warning("Cannot read lens fix file: %s ", filename);
263 return FALSE;
264 }
265
266 doc = xmlParseFile(filename);
267 if (!doc)
268 {
269 g_warning("Error parsing lens fix file: %s ", filename);
270 return FALSE;
271 }
272
273 g_free(filename);
274
275 cur = xmlDocGetRootElement(doc);
276 if (cur && (xmlStrcmp(cur->name, BAD_CAST "rawstudio-lens-fix") == 0))
277 {
278 cur = cur->xmlChildrenNode;
279 while(cur)
280 {
281 if ((!xmlStrcmp(cur->name, BAD_CAST "lens")))
282 {
283 lens_id = atoi((char *) xmlGetProp(cur, BAD_CAST "id"));
284 min_focal = rs_atof((char *) xmlGetProp(cur, BAD_CAST "min-focal"));
285 max_focal = rs_atof((char *) xmlGetProp(cur, BAD_CAST "max-focal"));
286 camera_make = g_ascii_strdown((gchar *) xmlGetProp(cur, BAD_CAST "make"), -1);
287
288 entry = cur->xmlChildrenNode;
289 while (entry)
290 {
291 if (!xmlStrcmp(entry->name, BAD_CAST "name"))
292 {
293 val = xmlNodeListGetString(doc, entry->xmlChildrenNode, 1);
294 lens_name = g_strdup((gchar *) val);
295 xmlFree(val);
296 }
297 entry = entry->next;
298 }
299 if (lens_name)
300 {
301 RS_MAKE camera_maker_id = translate_maker_name(camera_make);
302 lens_fix_insert(camera_maker_id, lens_id, min_focal, max_focal, lens_name);
303 }
304 }
305 cur = cur->next;
306 }
307 }
308 else
309 g_warning("Did not recognize the format in %s", filename);
310
311 xmlFreeDoc(doc);
312 return FALSE;
313 }
314
315 gboolean
rs_lens_fix(RSMetadata * meta)316 rs_lens_fix(RSMetadata *meta)
317 {
318 if (!lens_fix_hash_table)
319 {
320 g_warning("rs_lens_fix_init() has not been run - lens \"fixing\" will is disabled.");
321 return FALSE;
322 }
323
324 if (meta->make == MAKE_CANON && meta->lens_id > 0)
325 {
326 gchar *lens = get_canon_name_from_lens_id(meta->lens_id);
327 if (lens)
328 {
329 meta->lens_identifier = lens;
330 return TRUE;
331 }
332 }
333
334 const gchar* lens_name = lens_fix_find(meta->make, meta->lens_id, meta->lens_min_focal, meta->lens_max_focal);
335 if (lens_name)
336 {
337 meta->lens_identifier = g_strdup(lens_name);
338 return TRUE;
339 }
340 return TRUE;
341 }
342