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