Skip to content

Commit e5d389e

Browse files
agriggioLawrence37
authored andcommitted
metadata: fixed focus distance computation
A wrong focus distance calculation was affecting lensfun vignetting correction
1 parent f93c3dd commit e5d389e

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

rtengine/imagedata.cc

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,71 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) :
309309
focal_len35mm = pos->toFloat();
310310
}
311311

312-
if (find_tag(Exiv2::subjectDistance)) {
313-
focus_dist = (0.01 * std::pow(10, pos->toFloat() / 40));
312+
// if (find_tag(Exiv2::subjectDistance)) {
313+
// focus_dist = pos->toFloat();
314+
// }
315+
/*
316+
* Get the focus distance in meters.
317+
*/
318+
if (find_exif_tag("Exif.NikonLd2.FocusDistance")
319+
|| find_exif_tag("Exif.NikonLd3.FocusDistance")
320+
|| (Exiv2::testVersion(0, 27, 4)
321+
&& find_exif_tag("Exif.NikonLd4.FocusDistance"))) {
322+
float value = pos->toFloat();
323+
focus_dist = (0.01 * std::pow(10, value / 40));
324+
} else if (find_exif_tag("Exif.OlympusFi.FocusDistance")) {
325+
/* the distance is stored as a rational (fraction). according to
326+
* http://www.dpreview.com/forums/thread/1173960?page=4
327+
328+
* some Olympus cameras have a wrong denominator of 10 in there
329+
* while the nominator is always in mm. thus we ignore the
330+
* denominator and divide with 1000.
331+
332+
* "I've checked a number of E-1 and E-300 images, and I agree
333+
* that the FocusDistance looks like it is in mm for the
334+
* E-1. However, it looks more like cm for the E-300.
335+
336+
* For both cameras, this value is stored as a rational. With
337+
* the E-1, the denominator is always 1, while for the E-300 it
338+
* is 10.
339+
340+
* Therefore, it looks like the numerator in both cases is in mm
341+
* (which makes a bit of sense, in an odd sort of way). So I
342+
* think what I will do in ExifTool is to take the numerator and
343+
* divide by 1000 to display the focus distance in meters." --
344+
* Boardhead, dpreview forums in 2005
345+
*/
346+
int nominator = pos->toRational(0).first;
347+
focus_dist = std::max(0.0, (0.001 * nominator));
348+
} else if (find_exif_tag("Exif.CanonFi.FocusDistanceUpper")) {
349+
const float FocusDistanceUpper = pos->toFloat();
350+
if (FocusDistanceUpper <= 0.0f
351+
|| (int)FocusDistanceUpper >= 0xffff) {
352+
focus_dist = 0.0f;
353+
} else {
354+
focus_dist = FocusDistanceUpper / 100.0;
355+
if (find_exif_tag("Exif.CanonFi.FocusDistanceLower")) {
356+
const float FocusDistanceLower = pos->toFloat();
357+
if (FocusDistanceLower > 0.0f && (int)FocusDistanceLower < 0xffff) {
358+
focus_dist += FocusDistanceLower / 100.0;
359+
focus_dist /= 2.0;
360+
}
361+
}
362+
}
363+
} else if (find_exif_tag("Exif.CanonSi.SubjectDistance")) {
364+
focus_dist = pos->toFloat() / 100.0;
365+
} else if (find_tag(Exiv2::subjectDistance)) {
366+
focus_dist = pos->toFloat();
367+
} else if (Exiv2::testVersion(0,27,2) && find_exif_tag("Exif.Sony2Fp.FocusPosition2")) {
368+
const float focus_position = pos->toFloat();
369+
370+
if (focus_position && find_exif_tag("Exif.Photo.FocalLengthIn35mmFilm")) {
371+
const float focal_length_35mm = pos->toFloat();
372+
373+
/* http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3688.msg29653.html#msg29653 */
374+
focus_dist =
375+
(std::pow(2, focus_position / 16 - 5) + 1) * focal_length_35mm / 1000;
376+
}
314377
}
315378

316379
if (find_tag(Exiv2::orientation)) {

0 commit comments

Comments
 (0)