forked from 400plus/400plus
-
Notifications
You must be signed in to change notification settings - Fork 1
/
qexp.c
103 lines (73 loc) · 1.86 KB
/
qexp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <vxworks.h>
#include <stdlib.h>
#include "firmware/camera.h"
#include "main.h"
#include "macros.h"
#include "exposure.h"
#include "settings.h"
#include "utils.h"
#include "intercom.h"
#include "qexp.h"
void qexp_enable(void) {
status.vf_status = VF_STATUS_QEXP;
}
void qexp_disable(void) {
status.vf_status = VF_STATUS_NONE;
}
void qexp_update(void) {
int weight;
ec_t diff, ec_tmp;
av_t av = status.measured_av;
tv_t tv = status.measured_tv;
ec_t ec = status.measured_ec;
av_t av_max = DPData.ef_lens_exist ? DPData.avmax : AV_MAX;
av_t av_min = DPData.ef_lens_exist ? DPData.avo : AV_MIN;
if (status.measuring && abs(status.measured_ec) > QEXP_TOLERANCE) {
// Set lens to maximum aperture
diff = av_min - av;
av += diff;
ec -= diff;
// Set shutter to 1/60
diff = settings.qexp_mintv - tv;
tv += diff;
ec -= diff;
// If under-exposing, increase shutter speed
if (ec < 0) {
diff = MAX(tv + ec, TV_MIN) - tv;
tv += diff;
ec -= diff;
}
// If over-exposing, split the blame
if (ec > 0) {
ec_tmp = ec;
switch (settings.qexp_weight) {
default:
case QEXP_WEIGHT_NONE: weight = 2; break;
case QEXP_WEIGHT_AV : weight = 3; break;
case QEXP_WEIGHT_TV : weight = 1; break;
}
diff = MIN(av + weight * ec_tmp / 4, av_max) - av;
av += diff;
ec -= diff;
weight = 3 - weight;
diff = MIN(tv + weight * ec_tmp / 4, TV_MAX) - tv;
tv += diff;
ec -= diff;
}
// If still over-exposing, one of Av / Tv reached a maximum
if (ec > 0) {
diff = MIN(tv + ec, TV_MAX) - tv;
tv += diff;
ec -= diff;
diff = MIN(av + ec, av_max) - av;
av += diff;
ec -= diff;
}
av = ev_normalize(av);
tv = ev_normalize(tv);
if (av != DPData.av_val)
send_to_intercom(IC_SET_AV_VAL, ev_normalize(av));
if (tv != DPData.tv_val)
send_to_intercom(IC_SET_TV_VAL, ev_normalize(tv));
}
}