Merge ~r41k0u/ubuntu/+source/libcamera:pisp into ubuntu/+source/libcamera:ubuntu/devel

Proposed by Pragyansh Chaturvedi
Status: Needs review
Proposed branch: ~r41k0u/ubuntu/+source/libcamera:pisp
Merge into: ubuntu/+source/libcamera:ubuntu/devel
Diff against target: 19095 lines (+19026/-2)
7 files modified
debian/changelog (+16/-0)
debian/control (+4/-2)
debian/libcamera-dev.install (+2/-0)
debian/patches/add_pisp_rpi5.patch (+19000/-0)
debian/patches/series (+1/-0)
debian/rules (+2/-0)
debian/source/include-binaries (+1/-0)
Reviewer Review Type Date Requested Status
Simon Quigley (community) Approve
git-ubuntu import Pending
Review via email: mp+477052@code.launchpad.net

Commit message

* Add pisp driver for cameras on Raspberry Pi 5
  - d/p/add_pisp_rpi5.patch: This patch adds the new pisp driver used
    by camera modules on the Raspberry Pi 5 (they used unicam till Rpi4)
    and other changes required by it. IT only supports IMX219 sensor for
    now, but support for all sensors on RPi4 can be added trivially.
  - d/p/series: add new patch to series

Description of the change

This patch adds the new pisp driver from the Raspberry Pi Foundation's
fork of libcamera (https://github.com/raspberrypi/libcamera)
The camera module uses the pisp driver instead of unicam on RPi5, so this
patch is essential to make them work.

To post a comment you must log in.
Revision history for this message
Simon Quigley (tsimonq2) :
review: Approve

Unmerged commits

bb98d86... by Pragyansh Chaturvedi

Update maintainer

504d3b5... by Pragyansh Chaturvedi

changelog

890fe15... by Pragyansh Chaturvedi

* Add pisp driver for cameras on Raspberry Pi 5
  - d/p/add_pisp_rpi5.patch: This patch adds the new pisp driver used
    by camera modules on the Raspberry Pi 5 (they used unicam till Rpi4)
    and other changes required by it. IT only supports IMX219 sensor for
    now, but support for all sensors on RPi4 can be added trivially.
  - d/p/series: add new patch to series
  - d/vendor: add libpisp source archive
  - d/rules: Add custom rules to uncompress libpisp as a subproject
  - d/control: add nlohmann-json-dev as dependency for libpisp
  - d/s/include-binaries: include libpisp source tarball
  - d/libcamera-dev.install: include libpisp installation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 83df129..811bf25 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,19 @@
6+libcamera (0.3.2-2ubuntu1) plucky; urgency=medium
7+
8+ * Add pisp driver for cameras on Raspberry Pi 5
9+ - d/p/add_pisp_rpi5.patch: This patch adds the new pisp driver used
10+ by camera modules on the Raspberry Pi 5 (they used unicam till Rpi4)
11+ and other changes required by it. IT only supports IMX219 sensor for
12+ now, but support for all sensors on RPi4 can be added trivially.
13+ - d/p/series: add new patch to series
14+ - d/vendor: add libpisp source archive
15+ - d/rules: Add custom rules to uncompress libpisp as a subproject
16+ - d/control: add nlohmann-json-dev as dependency for libpisp
17+ - d/s/include-binaries: include libpisp source tarball
18+ - d/libcamera-dev.install: include libpisp installation
19+
20+ -- Pragyansh Chaturvedi <pragyansh.chaturvedi@canonical.com> Fri, 22 Nov 2024 17:58:41 +0530
21+
22 libcamera (0.3.2-2) unstable; urgency=medium
23
24 [ Helmut Grohne ]
25diff --git a/debian/control b/debian/control
26index 87985c1..259261d 100644
27--- a/debian/control
28+++ b/debian/control
29@@ -1,5 +1,6 @@
30 Source: libcamera
31-Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org>
32+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
33+XSBC-Original-Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org>
34 Uploaders: Emmanuel Arias <emmanuelarias30@gmail.com>,
35 IOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>,
36 Andrej Shadura <andrewsh@debian.org>,
37@@ -29,7 +30,8 @@ Build-Depends: debhelper-compat (= 13),
38 python3-ply,
39 python3-pybind11 <!pkg.libcamera.nopython>,
40 python3-yaml,
41- qt6-base-dev [!i386] <!pkg.libcamera.noqt>
42+ qt6-base-dev [!i386] <!pkg.libcamera.noqt>,
43+ nlohmann-json3-dev [!i386]
44 Build-Depends-Indep: doxygen <!nodoc>,
45 doxygen-latex [!sh4] <!nodoc> | texlive-latex-extra <!nodoc>,
46 graphviz <!nodoc>,
47diff --git a/debian/libcamera-dev.install b/debian/libcamera-dev.install
48index 25e9244..442685a 100644
49--- a/debian/libcamera-dev.install
50+++ b/debian/libcamera-dev.install
51@@ -1,3 +1,5 @@
52 usr/include
53 usr/lib/*/l*.so
54 usr/lib/*/pkgconfig/*.pc
55+usr/lib/*/libpisp.so.*
56+usr/share/libpisp/*
57diff --git a/debian/patches/add_pisp_rpi5.patch b/debian/patches/add_pisp_rpi5.patch
58new file mode 100644
59index 0000000..16ff121
60--- /dev/null
61+++ b/debian/patches/add_pisp_rpi5.patch
62@@ -0,0 +1,19000 @@
63+Description: Add pisp driver to make cameras work on Raspbery Pi 5
64+ This patch adds the new pisp driver used on the Raspberry Pi 5 from
65+ the Raspberry Pi Foundation's fork of libcamera
66+ (https://github.com/raspberrypi/libcamera)
67+ The camera module uses the pisp driver instead of unicam on RPi5,
68+ so this patch is essential to make them work. This only supports
69+ the IMX219 sensor for now, but it is trivial to add support for
70+ sensors which already worked on the RPi4.
71+Author: Pragyansh Chaturvedi <pragyansh.chaturvedi@canonical.com>
72+Last-Update: 2024-11-22
73+---
74+--- a/include/libcamera/ipa/meson.build 2024-11-25 21:08:37.649494681 +0530
75++++ b/include/libcamera/ipa/meson.build 2024-11-25 21:08:37.634494077 +0530
76+@@ -65,6 +65,7 @@
77+ pipeline_ipa_mojom_mapping = {
78+ 'ipu3': 'ipu3.mojom',
79+ 'rkisp1': 'rkisp1.mojom',
80++ 'rpi/pisp': 'raspberrypi.mojom',
81+ 'rpi/vc4': 'raspberrypi.mojom',
82+ 'simple': 'soft.mojom',
83+ 'vimc': 'vimc.mojom',
84+--- a/include/libcamera/meson.build 2024-11-25 21:08:37.649494681 +0530
85++++ b/include/libcamera/meson.build 2024-11-25 21:08:37.634494077 +0530
86+@@ -36,6 +36,7 @@
87+ 'controls': {
88+ 'draft': 'control_ids_draft.yaml',
89+ 'core': 'control_ids_core.yaml',
90++ 'rpi/pisp': 'control_ids_rpi.yaml',
91+ 'rpi/vc4': 'control_ids_rpi.yaml',
92+ },
93+
94+--- a/meson.build 2024-11-25 21:08:37.649494681 +0530
95++++ b/meson.build 2024-11-25 21:08:37.634494077 +0530
96+@@ -210,6 +210,7 @@
97+ 'ipu3': arch_x86,
98+ 'mali-c55': arch_arm,
99+ 'rkisp1': arch_arm,
100++ 'rpi/pisp': ['any'],
101+ 'rpi/vc4': arch_arm,
102+ 'simple': ['any'],
103+ 'uvcvideo': ['any'],
104+--- a/meson_options.txt 2024-11-25 21:08:37.649494681 +0530
105++++ b/meson_options.txt 2024-11-25 21:08:37.635494117 +0530
106+@@ -32,7 +32,7 @@
107+
108+ option('ipas',
109+ type : 'array',
110+- choices : ['ipu3', 'rkisp1', 'rpi/vc4', 'simple', 'vimc'],
111++ choices : ['ipu3', 'rkisp1', 'rpi/pisp', 'rpi/vc4', 'simple', 'vimc'],
112+ description : 'Select which IPA modules to build')
113+
114+ option('lc-compliance',
115+@@ -50,6 +50,7 @@
116+ 'ipu3',
117+ 'mali-c55',
118+ 'rkisp1',
119++ 'rpi/pisp',
120+ 'rpi/vc4',
121+ 'simple',
122+ 'uvcvideo',
123+--- a/src/ipa/rpi/cam_helper/cam_helper.cpp 2024-11-25 21:08:37.649494681 +0530
124++++ b/src/ipa/rpi/cam_helper/cam_helper.cpp 2024-11-25 21:08:37.635494117 +0530
125+@@ -156,6 +156,11 @@
126+ }
127+ }
128+
129++void CamHelper::setHwConfig(const Controller::HardwareConfig &hwConfig)
130++{
131++ hwConfig_ = hwConfig;
132++}
133++
134+ void CamHelper::getDelays(int &exposureDelay, int &gainDelay,
135+ int &vblankDelay, int &hblankDelay) const
136+ {
137+--- a/src/ipa/rpi/cam_helper/cam_helper.h 2024-11-25 21:08:37.649494681 +0530
138++++ b/src/ipa/rpi/cam_helper/cam_helper.h 2024-11-25 21:08:37.635494117 +0530
139+@@ -76,6 +76,7 @@
140+ CamHelper(std::unique_ptr<MdParser> parser, unsigned int frameIntegrationDiff);
141+ virtual ~CamHelper();
142+ void setCameraMode(const CameraMode &mode);
143++ void setHwConfig(const Controller::HardwareConfig &hwConfig);
144+ virtual void prepare(libcamera::Span<const uint8_t> buffer,
145+ Metadata &metadata);
146+ virtual void process(StatisticsPtr &stats, Metadata &metadata);
147+@@ -108,6 +109,7 @@
148+
149+ std::unique_ptr<MdParser> parser_;
150+ CameraMode mode_;
151++ Controller::HardwareConfig hwConfig_;
152+
153+ private:
154+ /*
155+--- a/src/ipa/rpi/common/ipa_base.cpp 2024-11-25 21:08:37.649494681 +0530
156++++ b/src/ipa/rpi/common/ipa_base.cpp 2024-11-25 21:08:37.636494158 +0530
157+@@ -96,6 +96,13 @@
158+ { &controls::LensPosition, ControlInfo(0.0f, 32.0f, 1.0f) }
159+ };
160+
161++/* Platform specific controls */
162++const std::map<const std::string, ControlInfoMap::Map> platformControls {
163++ { "pisp", {
164++ { &controls::rpi::ScalerCrops, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) }
165++ } },
166++};
167++
168+ } /* namespace */
169+
170+ LOG_DEFINE_CATEGORY(IPARPI)
171+@@ -153,12 +160,17 @@
172+ lensPresent_ = params.lensPresent;
173+
174+ controller_.initialise();
175++ helper_->setHwConfig(controller_.getHardwareConfig());
176+
177+ /* Return the controls handled by the IPA */
178+ ControlInfoMap::Map ctrlMap = ipaControls;
179+ if (lensPresent_)
180+ ctrlMap.merge(ControlInfoMap::Map(ipaAfControls));
181+
182++ auto platformCtrlsIt = platformControls.find(controller_.getTarget());
183++ if (platformCtrlsIt != platformControls.end())
184++ ctrlMap.merge(ControlInfoMap::Map(platformCtrlsIt->second));
185++
186+ monoSensor_ = params.sensorInfo.cfaPattern == properties::draft::ColorFilterArrangementEnum::MONO;
187+ if (!monoSensor_)
188+ ctrlMap.merge(ControlInfoMap::Map(ipaColourControls));
189+@@ -1070,7 +1082,7 @@
190+ break;
191+ }
192+
193+- case controls::SCALER_CROP: {
194++ case controls::rpi::SCALER_CROPS: {
195+ /* We do nothing with this, but should avoid the warning below. */
196+ break;
197+ }
198+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
199++++ b/src/ipa/rpi/pisp/data/imx219.json 2024-11-25 21:08:37.637494198 +0530
200+@@ -0,0 +1,1187 @@
201++{
202++ "version": 2.0,
203++ "target": "pisp",
204++ "algorithms": [
205++ {
206++ "rpi.black_level":
207++ {
208++ "black_level": 4096
209++ }
210++ },
211++ {
212++ "rpi.lux":
213++ {
214++ "reference_shutter_speed": 21965,
215++ "reference_gain": 1.0,
216++ "reference_aperture": 1.0,
217++ "reference_lux": 800,
218++ "reference_Y": 11460
219++ }
220++ },
221++ {
222++ "rpi.dpc":
223++ {
224++ "strength": 1
225++ }
226++ },
227++ {
228++ "rpi.noise":
229++ {
230++ "reference_constant": 0,
231++ "reference_slope": 3.661
232++ }
233++ },
234++ {
235++ "rpi.geq":
236++ {
237++ "offset": 239,
238++ "slope": 0.00766
239++ }
240++ },
241++ {
242++ "rpi.denoise":
243++ {
244++ "normal":
245++ {
246++ "sdn":
247++ {
248++ "deviation": 1.6,
249++ "strength": 0.5,
250++ "deviation2": 3.2,
251++ "deviation_no_tdn": 3.2,
252++ "strength_no_tdn": 0.75
253++ },
254++ "cdn":
255++ {
256++ "deviation": 200,
257++ "strength": 0.3
258++ },
259++ "tdn":
260++ {
261++ "deviation": 0.8,
262++ "threshold": 0.05
263++ }
264++ },
265++ "hdr":
266++ {
267++ "sdn":
268++ {
269++ "deviation": 1.6,
270++ "strength": 0.5,
271++ "deviation2": 3.2,
272++ "deviation_no_tdn": 3.2,
273++ "strength_no_tdn": 0.75
274++ },
275++ "cdn":
276++ {
277++ "deviation": 200,
278++ "strength": 0.3
279++ },
280++ "tdn":
281++ {
282++ "deviation": 1.3,
283++ "threshold": 0.1
284++ }
285++ },
286++ "night":
287++ {
288++ "sdn":
289++ {
290++ "deviation": 1.6,
291++ "strength": 0.5,
292++ "deviation2": 3.2,
293++ "deviation_no_tdn": 3.2,
294++ "strength_no_tdn": 0.75
295++ },
296++ "cdn":
297++ {
298++ "deviation": 200,
299++ "strength": 0.3
300++ },
301++ "tdn":
302++ {
303++ "deviation": 1.3,
304++ "threshold": 0.1
305++ }
306++ }
307++ }
308++ },
309++ {
310++ "rpi.awb":
311++ {
312++ "priors": [
313++ {
314++ "lux": 0,
315++ "prior":
316++ [
317++ 2000, 1.0,
318++ 3000, 0.0,
319++ 13000, 0.0
320++ ]
321++ },
322++ {
323++ "lux": 800,
324++ "prior":
325++ [
326++ 2000, 0.0,
327++ 6000, 2.0,
328++ 13000, 2.0
329++ ]
330++ },
331++ {
332++ "lux": 1500,
333++ "prior":
334++ [
335++ 2000, 0.0,
336++ 4000, 1.0,
337++ 6000, 6.0,
338++ 6500, 7.0,
339++ 7000, 1.0,
340++ 13000, 1.0
341++ ]
342++ }
343++ ],
344++ "modes":
345++ {
346++ "auto":
347++ {
348++ "lo": 2500,
349++ "hi": 7700
350++ },
351++ "incandescent":
352++ {
353++ "lo": 2500,
354++ "hi": 3000
355++ },
356++ "tungsten":
357++ {
358++ "lo": 3000,
359++ "hi": 3500
360++ },
361++ "fluorescent":
362++ {
363++ "lo": 4000,
364++ "hi": 4700
365++ },
366++ "indoor":
367++ {
368++ "lo": 3000,
369++ "hi": 5000
370++ },
371++ "daylight":
372++ {
373++ "lo": 5500,
374++ "hi": 6500
375++ },
376++ "cloudy":
377++ {
378++ "lo": 7000,
379++ "hi": 8000
380++ }
381++ },
382++ "bayes": 1,
383++ "ct_curve":
384++ [
385++ 2860.0, 0.9514, 0.4156,
386++ 2960.0, 0.9289, 0.4372,
387++ 3603.0, 0.8305, 0.5251,
388++ 4650.0, 0.6756, 0.6433,
389++ 5858.0, 0.6193, 0.6807,
390++ 7580.0, 0.5019, 0.7495
391++ ],
392++ "sensitivity_r": 1.0,
393++ "sensitivity_b": 1.0,
394++ "transverse_pos": 0.03392,
395++ "transverse_neg": 0.034
396++ }
397++ },
398++ {
399++ "rpi.agc":
400++ {
401++ "channels": [
402++ {
403++ "comment": "Channel 0 is normal AGC",
404++ "metering_modes":
405++ {
406++ "centre-weighted":
407++ {
408++ "weights":
409++ [
410++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
411++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
412++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
413++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
414++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
415++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
416++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
417++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
418++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
419++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
420++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
421++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
422++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
423++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
424++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
425++ ]
426++ },
427++ "spot":
428++ {
429++ "weights":
430++ [
431++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
432++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
433++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
434++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
435++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
436++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
437++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
438++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
439++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
440++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
441++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
442++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
443++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
444++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
445++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
446++ ]
447++ },
448++ "matrix":
449++ {
450++ "weights":
451++ [
452++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
453++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
454++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
455++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
456++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
457++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
458++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
459++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
460++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
461++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
462++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
463++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
464++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
465++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
466++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
467++ ]
468++ }
469++ },
470++ "exposure_modes":
471++ {
472++ "normal":
473++ {
474++ "shutter": [ 100, 10000, 30000, 60000, 66666 ],
475++ "gain": [ 1.0, 1.5, 2.0, 4.0, 10.0 ]
476++ },
477++ "short":
478++ {
479++ "shutter": [ 100, 5000, 10000, 20000, 60000 ],
480++ "gain": [ 1.0, 1.5, 2.0, 4.0, 10.0 ]
481++ },
482++ "long":
483++ {
484++ "shutter": [ 100, 10000, 30000, 60000, 90000, 120000 ],
485++ "gain": [ 1.0, 1.5, 2.0, 4.0, 8.0, 12.0 ]
486++ }
487++ },
488++ "constraint_modes":
489++ {
490++ "normal": [
491++ {
492++ "bound": "LOWER",
493++ "q_lo": 0.98,
494++ "q_hi": 1.0,
495++ "y_target":
496++ [
497++ 0, 0.5,
498++ 1000, 0.5
499++ ]
500++ }
501++ ],
502++ "highlight": [
503++ {
504++ "bound": "LOWER",
505++ "q_lo": 0.98,
506++ "q_hi": 1.0,
507++ "y_target":
508++ [
509++ 0, 0.5,
510++ 1000, 0.5
511++ ]
512++ },
513++ {
514++ "bound": "UPPER",
515++ "q_lo": 0.98,
516++ "q_hi": 1.0,
517++ "y_target":
518++ [
519++ 0, 0.8,
520++ 1000, 0.8
521++ ]
522++ }
523++ ],
524++ "shadows": [
525++ {
526++ "bound": "LOWER",
527++ "q_lo": 0.0,
528++ "q_hi": 0.5,
529++ "y_target":
530++ [
531++ 0, 0.17,
532++ 1000, 0.17
533++ ]
534++ }
535++ ]
536++ },
537++ "y_target":
538++ [
539++ 0, 0.16,
540++ 1000, 0.165,
541++ 10000, 0.17
542++ ]
543++ },
544++ {
545++ "comment": "Channel 1 is the HDR short channel",
546++ "desaturate": 0,
547++ "metering_modes":
548++ {
549++ "centre-weighted":
550++ {
551++ "weights":
552++ [
553++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
554++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
555++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
556++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
557++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
558++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
559++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
560++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
561++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
562++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
563++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
564++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
565++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
566++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
567++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
568++ ]
569++ },
570++ "spot":
571++ {
572++ "weights":
573++ [
574++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
575++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
576++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
577++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
578++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
579++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
580++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
581++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
582++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
583++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
584++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
585++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
586++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
587++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
588++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
589++ ]
590++ },
591++ "matrix":
592++ {
593++ "weights":
594++ [
595++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
597++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
598++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
599++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
601++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
602++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
603++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
607++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
608++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
609++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
610++ ]
611++ }
612++ },
613++ "exposure_modes":
614++ {
615++ "normal":
616++ {
617++ "shutter": [ 100, 15000, 30000 ],
618++ "gain": [ 1.0, 1.0, 2.0 ]
619++ },
620++ "short":
621++ {
622++ "shutter": [ 100, 15000, 30000 ],
623++ "gain": [ 1.0, 2.0, 2.0 ]
624++ },
625++ "long":
626++ {
627++ "shutter": [ 100, 15000, 60000 ],
628++ "gain": [ 1.0, 1.0, 1.0 ]
629++ }
630++ },
631++ "constraint_modes":
632++ {
633++ "normal": [
634++ {
635++ "bound": "LOWER",
636++ "q_lo": 0.0,
637++ "q_hi": 0.2,
638++ "y_target":
639++ [
640++ 0, 0.02,
641++ 1000, 0.02
642++ ]
643++ },
644++ {
645++ "bound": "UPPER",
646++ "q_lo": 0.98,
647++ "q_hi": 1.0,
648++ "y_target":
649++ [
650++ 0, 0.7,
651++ 1000, 0.7
652++ ]
653++ },
654++ {
655++ "bound": "LOWER",
656++ "q_lo": 0.0,
657++ "q_hi": 0.2,
658++ "y_target":
659++ [
660++ 0, 0.01,
661++ 1000, 0.01
662++ ]
663++ },
664++ {
665++ "bound": "UPPER",
666++ "q_lo": 0.9,
667++ "q_hi": 1.0,
668++ "y_target":
669++ [
670++ 0, 0.7,
671++ 1000, 0.7
672++ ]
673++ },
674++ {
675++ "bound": "LOWER",
676++ "q_lo": 0.0,
677++ "q_hi": 0.2,
678++ "y_target":
679++ [
680++ 0, 0.005,
681++ 1000, 0.005
682++ ]
683++ }
684++ ],
685++ "highlight": [
686++ {
687++ "bound": "LOWER",
688++ "q_lo": 0.95,
689++ "q_hi": 1.0,
690++ "y_target":
691++ [
692++ 0, 0.5,
693++ 1000, 0.5
694++ ]
695++ },
696++ {
697++ "bound": "UPPER",
698++ "q_lo": 0.95,
699++ "q_hi": 1.0,
700++ "y_target":
701++ [
702++ 0, 0.7,
703++ 1000, 0.7
704++ ]
705++ },
706++ {
707++ "bound": "LOWER",
708++ "q_lo": 0.0,
709++ "q_hi": 0.2,
710++ "y_target":
711++ [
712++ 0, 0.002,
713++ 1000, 0.002
714++ ]
715++ }
716++ ],
717++ "shadows": [
718++ {
719++ "bound": "LOWER",
720++ "q_lo": 0.95,
721++ "q_hi": 1.0,
722++ "y_target":
723++ [
724++ 0, 0.5,
725++ 1000, 0.5
726++ ]
727++ },
728++ {
729++ "bound": "UPPER",
730++ "q_lo": 0.95,
731++ "q_hi": 1.0,
732++ "y_target":
733++ [
734++ 0, 0.7,
735++ 1000, 0.7
736++ ]
737++ },
738++ {
739++ "bound": "LOWER",
740++ "q_lo": 0.0,
741++ "q_hi": 0.2,
742++ "y_target":
743++ [
744++ 0, 0.002,
745++ 1000, 0.002
746++ ]
747++ }
748++ ]
749++ },
750++ "y_target":
751++ [
752++ 0, 0.19,
753++ 1000, 0.19,
754++ 10000, 0.19
755++ ]
756++ },
757++ {
758++ "comment": "Channel 2 is the HDR long channel",
759++ "desaturate": 0,
760++ "metering_modes":
761++ {
762++ "centre-weighted":
763++ {
764++ "weights":
765++ [
766++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
767++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
768++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
769++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
770++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
771++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
772++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
773++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
774++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
775++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
776++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
777++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
778++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
779++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
780++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
781++ ]
782++ },
783++ "spot":
784++ {
785++ "weights":
786++ [
787++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
788++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
789++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
790++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
791++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
792++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
793++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
794++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
795++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
796++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
797++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
798++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
799++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
800++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
801++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
802++ ]
803++ },
804++ "matrix":
805++ {
806++ "weights":
807++ [
808++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
809++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
810++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
811++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
812++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
813++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
814++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
815++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
816++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
817++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
818++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
819++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
820++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
821++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
822++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
823++ ]
824++ }
825++ },
826++ "exposure_modes":
827++ {
828++ "normal":
829++ {
830++ "shutter": [ 100, 20000, 30000, 60000 ],
831++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
832++ },
833++ "short":
834++ {
835++ "shutter": [ 100, 20000, 30000, 60000 ],
836++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
837++ },
838++ "long":
839++ {
840++ "shutter": [ 100, 20000, 30000, 60000 ],
841++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
842++ }
843++ },
844++ "constraint_modes":
845++ {
846++ "normal": [ ],
847++ "highlight": [ ],
848++ "shadows": [ ]
849++ },
850++ "channel_constraints": [
851++ {
852++ "bound": "UPPER",
853++ "channel": 4,
854++ "factor": 8
855++ },
856++ {
857++ "bound": "LOWER",
858++ "channel": 4,
859++ "factor": 2
860++ }
861++ ],
862++ "y_target":
863++ [
864++ 0, 0.16,
865++ 1000, 0.165,
866++ 10000, 0.17
867++ ]
868++ },
869++ {
870++ "comment": "Channel 3 is the night mode channel",
871++ "base_ev": 0.33,
872++ "metering_modes":
873++ {
874++ "centre-weighted":
875++ {
876++ "weights":
877++ [
878++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
879++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
880++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
881++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
882++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
883++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
884++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
885++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
886++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
887++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
888++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
889++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
890++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
891++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
892++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
893++ ]
894++ },
895++ "spot":
896++ {
897++ "weights":
898++ [
899++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
900++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
902++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
903++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
904++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
905++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
906++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
907++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
908++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
909++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
910++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
913++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
914++ ]
915++ },
916++ "matrix":
917++ {
918++ "weights":
919++ [
920++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
921++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
922++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
923++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
924++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
925++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
926++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
927++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
928++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
929++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
930++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
931++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
932++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
933++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
934++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
935++ ]
936++ }
937++ },
938++ "exposure_modes":
939++ {
940++ "normal":
941++ {
942++ "shutter": [ 100, 20000, 66666 ],
943++ "gain": [ 1.0, 2.0, 4.0 ]
944++ },
945++ "short":
946++ {
947++ "shutter": [ 100, 20000, 33333 ],
948++ "gain": [ 1.0, 2.0, 4.0 ]
949++ },
950++ "long":
951++ {
952++ "shutter": [ 100, 20000, 66666, 120000 ],
953++ "gain": [ 1.0, 2.0, 4.0, 4.0 ]
954++ }
955++ },
956++ "constraint_modes":
957++ {
958++ "normal": [
959++ {
960++ "bound": "LOWER",
961++ "q_lo": 0.98,
962++ "q_hi": 1.0,
963++ "y_target":
964++ [
965++ 0, 0.5,
966++ 1000, 0.5
967++ ]
968++ }
969++ ],
970++ "highlight": [
971++ {
972++ "bound": "LOWER",
973++ "q_lo": 0.98,
974++ "q_hi": 1.0,
975++ "y_target":
976++ [
977++ 0, 0.5,
978++ 1000, 0.5
979++ ]
980++ },
981++ {
982++ "bound": "UPPER",
983++ "q_lo": 0.98,
984++ "q_hi": 1.0,
985++ "y_target":
986++ [
987++ 0, 0.8,
988++ 1000, 0.8
989++ ]
990++ }
991++ ],
992++ "shadows": [
993++ {
994++ "bound": "LOWER",
995++ "q_lo": 0.98,
996++ "q_hi": 1.0,
997++ "y_target":
998++ [
999++ 0, 0.5,
1000++ 1000, 0.5
1001++ ]
1002++ }
1003++ ]
1004++ },
1005++ "y_target":
1006++ [
1007++ 0, 0.16,
1008++ 1000, 0.165,
1009++ 10000, 0.17
1010++ ]
1011++ }
1012++ ]
1013++ }
1014++ },
1015++ {
1016++ "rpi.alsc":
1017++ {
1018++ "omega": 1.3,
1019++ "n_iter": 100,
1020++ "luminance_strength": 0.8,
1021++ "calibrations_Cr": [
1022++ {
1023++ "ct": 3000,
1024++ "table":
1025++ [
1026++ 1.418, 1.428, 1.446, 1.454, 1.454, 1.451, 1.441, 1.428, 1.411, 1.391, 1.371, 1.349, 1.334, 1.327, 1.325, 1.325, 1.325, 1.325, 1.331, 1.344, 1.363, 1.383, 1.402, 1.418, 1.433, 1.446, 1.452, 1.453, 1.446, 1.435, 1.415, 1.404,
1027++ 1.428, 1.442, 1.453, 1.455, 1.454, 1.447, 1.431, 1.413, 1.392, 1.371, 1.349, 1.331, 1.318, 1.307, 1.299, 1.299, 1.299, 1.303, 1.313, 1.328, 1.344, 1.363, 1.383, 1.404, 1.424, 1.439, 1.451, 1.453, 1.453, 1.445, 1.431, 1.415,
1028++ 1.436, 1.448, 1.453, 1.455, 1.449, 1.435, 1.415, 1.393, 1.369, 1.345, 1.322, 1.303, 1.287, 1.276, 1.269, 1.268, 1.268, 1.272, 1.283, 1.298, 1.316, 1.337, 1.362, 1.384, 1.406, 1.427, 1.444, 1.454, 1.454, 1.452, 1.438, 1.426,
1029++ 1.441, 1.451, 1.454, 1.451, 1.439, 1.422, 1.396, 1.372, 1.345, 1.319, 1.295, 1.274, 1.257, 1.245, 1.239, 1.238, 1.238, 1.245, 1.255, 1.269, 1.289, 1.311, 1.336, 1.362, 1.388, 1.412, 1.433, 1.448, 1.454, 1.453, 1.445, 1.433,
1030++ 1.445, 1.452, 1.452, 1.445, 1.428, 1.405, 1.379, 1.349, 1.319, 1.295, 1.269, 1.247, 1.229, 1.219, 1.212, 1.211, 1.211, 1.217, 1.228, 1.242, 1.261, 1.286, 1.311, 1.339, 1.367, 1.395, 1.419, 1.439, 1.452, 1.452, 1.451, 1.436,
1031++ 1.448, 1.451, 1.451, 1.435, 1.414, 1.387, 1.358, 1.327, 1.296, 1.269, 1.245, 1.222, 1.205, 1.193, 1.187, 1.185, 1.186, 1.191, 1.202, 1.217, 1.237, 1.261, 1.286, 1.316, 1.346, 1.378, 1.404, 1.429, 1.445, 1.451, 1.451, 1.442,
1032++ 1.448, 1.448, 1.445, 1.427, 1.401, 1.371, 1.338, 1.306, 1.274, 1.245, 1.222, 1.199, 1.183, 1.171, 1.164, 1.162, 1.162, 1.168, 1.181, 1.194, 1.215, 1.237, 1.264, 1.294, 1.325, 1.359, 1.389, 1.418, 1.441, 1.449, 1.449, 1.443,
1033++ 1.449, 1.448, 1.438, 1.415, 1.387, 1.352, 1.318, 1.284, 1.252, 1.223, 1.199, 1.179, 1.161, 1.149, 1.142, 1.142, 1.142, 1.149, 1.159, 1.174, 1.194, 1.215, 1.242, 1.272, 1.307, 1.341, 1.376, 1.405, 1.431, 1.447, 1.447, 1.444,
1034++ 1.448, 1.447, 1.431, 1.405, 1.373, 1.336, 1.301, 1.264, 1.234, 1.204, 1.179, 1.161, 1.143, 1.131, 1.124, 1.123, 1.123, 1.131, 1.141, 1.156, 1.174, 1.197, 1.224, 1.254, 1.288, 1.324, 1.361, 1.394, 1.423, 1.442, 1.444, 1.444,
1035++ 1.447, 1.442, 1.424, 1.393, 1.359, 1.322, 1.284, 1.248, 1.216, 1.187, 1.162, 1.143, 1.128, 1.115, 1.109, 1.108, 1.108, 1.113, 1.124, 1.139, 1.156, 1.179, 1.206, 1.236, 1.272, 1.309, 1.347, 1.382, 1.411, 1.435, 1.443, 1.444,
1036++ 1.444, 1.439, 1.417, 1.383, 1.347, 1.308, 1.271, 1.233, 1.201, 1.173, 1.147, 1.128, 1.115, 1.101, 1.095, 1.093, 1.093, 1.099, 1.111, 1.124, 1.142, 1.165, 1.191, 1.222, 1.258, 1.296, 1.333, 1.372, 1.404, 1.429, 1.441, 1.442,
1037++ 1.443, 1.434, 1.409, 1.375, 1.336, 1.297, 1.257, 1.221, 1.189, 1.159, 1.136, 1.116, 1.101, 1.092, 1.083, 1.082, 1.082, 1.089, 1.099, 1.111, 1.131, 1.153, 1.181, 1.211, 1.246, 1.284, 1.324, 1.361, 1.398, 1.425, 1.441, 1.441,
1038++ 1.443, 1.431, 1.405, 1.369, 1.328, 1.287, 1.247, 1.211, 1.178, 1.149, 1.126, 1.107, 1.092, 1.083, 1.075, 1.073, 1.073, 1.082, 1.089, 1.101, 1.121, 1.143, 1.171, 1.201, 1.237, 1.274, 1.314, 1.353, 1.389, 1.421, 1.439, 1.441,
1039++ 1.442, 1.429, 1.401, 1.364, 1.323, 1.279, 1.241, 1.205, 1.172, 1.144, 1.119, 1.101, 1.085, 1.075, 1.071, 1.067, 1.067, 1.073, 1.082, 1.096, 1.114, 1.136, 1.163, 1.194, 1.229, 1.268, 1.308, 1.348, 1.387, 1.417, 1.439, 1.439,
1040++ 1.443, 1.429, 1.399, 1.362, 1.319, 1.276, 1.237, 1.199, 1.169, 1.141, 1.115, 1.096, 1.081, 1.071, 1.066, 1.063, 1.066, 1.068, 1.078, 1.092, 1.109, 1.132, 1.159, 1.191, 1.226, 1.263, 1.304, 1.346, 1.384, 1.416, 1.438, 1.439,
1041++ 1.443, 1.428, 1.399, 1.361, 1.319, 1.276, 1.236, 1.199, 1.167, 1.139, 1.115, 1.096, 1.081, 1.071, 1.064, 1.062, 1.062, 1.067, 1.077, 1.091, 1.109, 1.131, 1.158, 1.189, 1.224, 1.262, 1.303, 1.345, 1.383, 1.416, 1.438, 1.439,
1042++ 1.444, 1.429, 1.399, 1.361, 1.319, 1.276, 1.236, 1.199, 1.167, 1.139, 1.116, 1.096, 1.081, 1.071, 1.064, 1.063, 1.063, 1.067, 1.077, 1.091, 1.109, 1.131, 1.159, 1.189, 1.224, 1.262, 1.303, 1.345, 1.384, 1.416, 1.438, 1.441,
1043++ 1.444, 1.431, 1.402, 1.364, 1.322, 1.281, 1.239, 1.202, 1.171, 1.142, 1.118, 1.099, 1.084, 1.073, 1.069, 1.065, 1.067, 1.071, 1.079, 1.094, 1.112, 1.135, 1.163, 1.191, 1.227, 1.265, 1.307, 1.348, 1.386, 1.418, 1.438, 1.441,
1044++ 1.447, 1.433, 1.406, 1.369, 1.328, 1.286, 1.244, 1.209, 1.177, 1.148, 1.124, 1.105, 1.089, 1.081, 1.073, 1.071, 1.071, 1.079, 1.085, 1.099, 1.118, 1.141, 1.168, 1.198, 1.233, 1.271, 1.312, 1.352, 1.391, 1.422, 1.441, 1.444,
1045++ 1.448, 1.438, 1.412, 1.376, 1.335, 1.295, 1.255, 1.218, 1.186, 1.157, 1.134, 1.113, 1.098, 1.089, 1.081, 1.079, 1.079, 1.085, 1.094, 1.107, 1.125, 1.149, 1.175, 1.207, 1.242, 1.281, 1.319, 1.359, 1.396, 1.425, 1.445, 1.447,
1046++ 1.449, 1.443, 1.417, 1.384, 1.345, 1.305, 1.266, 1.229, 1.197, 1.169, 1.145, 1.124, 1.111, 1.098, 1.091, 1.089, 1.089, 1.094, 1.107, 1.118, 1.137, 1.159, 1.187, 1.218, 1.253, 1.291, 1.329, 1.369, 1.405, 1.433, 1.447, 1.449,
1047++ 1.453, 1.449, 1.425, 1.395, 1.358, 1.318, 1.281, 1.244, 1.211, 1.183, 1.158, 1.138, 1.124, 1.111, 1.104, 1.103, 1.103, 1.107, 1.118, 1.133, 1.151, 1.174, 1.201, 1.232, 1.267, 1.304, 1.344, 1.379, 1.413, 1.437, 1.449, 1.449,
1048++ 1.457, 1.453, 1.434, 1.405, 1.371, 1.335, 1.297, 1.261, 1.229, 1.199, 1.174, 1.155, 1.138, 1.126, 1.119, 1.117, 1.117, 1.124, 1.133, 1.149, 1.167, 1.189, 1.217, 1.248, 1.284, 1.319, 1.357, 1.393, 1.423, 1.444, 1.452, 1.452,
1049++ 1.459, 1.457, 1.443, 1.418, 1.385, 1.352, 1.314, 1.279, 1.246, 1.218, 1.193, 1.174, 1.155, 1.144, 1.137, 1.136, 1.136, 1.141, 1.151, 1.167, 1.187, 1.208, 1.236, 1.267, 1.301, 1.337, 1.373, 1.405, 1.434, 1.453, 1.455, 1.455,
1050++ 1.461, 1.461, 1.454, 1.429, 1.401, 1.369, 1.333, 1.301, 1.269, 1.239, 1.216, 1.193, 1.177, 1.165, 1.158, 1.156, 1.156, 1.161, 1.171, 1.187, 1.208, 1.229, 1.258, 1.288, 1.321, 1.356, 1.389, 1.419, 1.445, 1.459, 1.459, 1.455,
1051++ 1.462, 1.462, 1.459, 1.442, 1.418, 1.386, 1.354, 1.322, 1.292, 1.262, 1.239, 1.216, 1.199, 1.187, 1.179, 1.178, 1.178, 1.184, 1.194, 1.208, 1.229, 1.253, 1.279, 1.309, 1.342, 1.375, 1.406, 1.433, 1.452, 1.464, 1.464, 1.454,
1052++ 1.461, 1.465, 1.465, 1.454, 1.431, 1.405, 1.376, 1.346, 1.316, 1.288, 1.262, 1.242, 1.223, 1.212, 1.205, 1.203, 1.203, 1.208, 1.218, 1.234, 1.253, 1.279, 1.305, 1.334, 1.363, 1.393, 1.421, 1.445, 1.461, 1.465, 1.464, 1.452,
1053++ 1.459, 1.465, 1.466, 1.461, 1.443, 1.421, 1.395, 1.368, 1.341, 1.316, 1.288, 1.268, 1.251, 1.238, 1.232, 1.229, 1.229, 1.235, 1.246, 1.261, 1.279, 1.305, 1.331, 1.356, 1.385, 1.411, 1.435, 1.454, 1.466, 1.466, 1.464, 1.451,
1054++ 1.454, 1.465, 1.467, 1.466, 1.456, 1.436, 1.414, 1.389, 1.367, 1.341, 1.318, 1.297, 1.279, 1.269, 1.261, 1.259, 1.259, 1.265, 1.274, 1.288, 1.308, 1.331, 1.355, 1.381, 1.404, 1.428, 1.447, 1.462, 1.468, 1.467, 1.457, 1.445,
1055++ 1.447, 1.459, 1.466, 1.467, 1.463, 1.451, 1.434, 1.411, 1.389, 1.367, 1.344, 1.325, 1.311, 1.297, 1.292, 1.289, 1.289, 1.295, 1.303, 1.317, 1.336, 1.356, 1.381, 1.402, 1.423, 1.441, 1.457, 1.467, 1.468, 1.463, 1.451, 1.439,
1056++ 1.438, 1.449, 1.462, 1.464, 1.464, 1.459, 1.446, 1.429, 1.408, 1.388, 1.369, 1.353, 1.339, 1.329, 1.321, 1.321, 1.321, 1.325, 1.333, 1.348, 1.362, 1.379, 1.401, 1.421, 1.439, 1.454, 1.463, 1.465, 1.465, 1.456, 1.442, 1.427,
1057++ 1.429, 1.439, 1.454, 1.464, 1.464, 1.459, 1.449, 1.435, 1.421, 1.402, 1.385, 1.369, 1.353, 1.341, 1.338, 1.337, 1.337, 1.338, 1.348, 1.362, 1.378, 1.395, 1.411, 1.429, 1.445, 1.455, 1.463, 1.464, 1.457, 1.447, 1.427, 1.419
1058++ ]
1059++ },
1060++ {
1061++ "ct": 5000,
1062++ "table":
1063++ [
1064++ 2.163, 2.177, 2.194, 2.196, 2.197, 2.192, 2.181, 2.161, 2.139, 2.113, 2.088, 2.063, 2.047, 2.041, 2.036, 2.036, 2.036, 2.037, 2.046, 2.059, 2.083, 2.113, 2.135, 2.158, 2.181, 2.193, 2.205, 2.205, 2.202, 2.189, 2.171, 2.158,
1065++ 2.169, 2.184, 2.195, 2.196, 2.194, 2.182, 2.163, 2.141, 2.116, 2.088, 2.063, 2.042, 2.025, 2.013, 2.004, 2.004, 2.006, 2.011, 2.022, 2.038, 2.059, 2.083, 2.113, 2.137, 2.162, 2.182, 2.197, 2.204, 2.203, 2.199, 2.183, 2.171,
1066++ 2.177, 2.187, 2.193, 2.193, 2.184, 2.166, 2.142, 2.116, 2.087, 2.057, 2.033, 2.008, 1.991, 1.977, 1.969, 1.969, 1.969, 1.975, 1.988, 2.006, 2.028, 2.055, 2.083, 2.114, 2.139, 2.166, 2.187, 2.199, 2.202, 2.201, 2.189, 2.179,
1067++ 2.183, 2.189, 2.192, 2.186, 2.172, 2.146, 2.119, 2.089, 2.058, 2.026, 2.001, 1.975, 1.956, 1.942, 1.934, 1.932, 1.933, 1.941, 1.955, 1.971, 1.995, 2.023, 2.055, 2.084, 2.119, 2.146, 2.171, 2.191, 2.201, 2.201, 2.194, 2.183,
1068++ 2.186, 2.189, 2.189, 2.177, 2.158, 2.127, 2.096, 2.059, 2.026, 1.998, 1.969, 1.944, 1.925, 1.911, 1.901, 1.901, 1.903, 1.912, 1.924, 1.941, 1.964, 1.995, 2.023, 2.058, 2.091, 2.126, 2.155, 2.181, 2.195, 2.199, 2.198, 2.188,
1069++ 2.189, 2.189, 2.184, 2.166, 2.138, 2.108, 2.071, 2.036, 1.999, 1.969, 1.941, 1.914, 1.894, 1.879, 1.871, 1.871, 1.872, 1.879, 1.893, 1.913, 1.937, 1.964, 1.997, 2.029, 2.065, 2.104, 2.137, 2.169, 2.187, 2.199, 2.199, 2.189,
1070++ 2.187, 2.186, 2.176, 2.154, 2.123, 2.087, 2.044, 2.011, 1.974, 1.941, 1.913, 1.887, 1.868, 1.852, 1.844, 1.843, 1.844, 1.852, 1.866, 1.885, 1.912, 1.937, 1.972, 2.004, 2.042, 2.081, 2.119, 2.154, 2.179, 2.195, 2.196, 2.193,
1071++ 2.187, 2.181, 2.167, 2.141, 2.103, 2.062, 2.023, 1.984, 1.947, 1.916, 1.887, 1.864, 1.841, 1.828, 1.821, 1.819, 1.819, 1.828, 1.842, 1.862, 1.885, 1.913, 1.945, 1.982, 2.021, 2.058, 2.102, 2.137, 2.168, 2.192, 2.193, 2.193,
1072++ 2.182, 2.181, 2.161, 2.127, 2.083, 2.044, 2.002, 1.961, 1.924, 1.891, 1.864, 1.841, 1.819, 1.806, 1.797, 1.797, 1.797, 1.805, 1.819, 1.841, 1.862, 1.892, 1.924, 1.959, 1.999, 2.041, 2.082, 2.123, 2.161, 2.185, 2.191, 2.192,
1073++ 2.182, 2.172, 2.149, 2.112, 2.069, 2.026, 1.982, 1.941, 1.904, 1.871, 1.841, 1.819, 1.799, 1.785, 1.776, 1.776, 1.778, 1.784, 1.798, 1.819, 1.841, 1.869, 1.903, 1.939, 1.977, 2.021, 2.067, 2.108, 2.145, 2.174, 2.189, 2.191,
1074++ 2.181, 2.167, 2.139, 2.098, 2.056, 2.006, 1.965, 1.921, 1.883, 1.851, 1.823, 1.799, 1.783, 1.767, 1.759, 1.758, 1.758, 1.767, 1.783, 1.798, 1.825, 1.851, 1.883, 1.919, 1.959, 2.004, 2.049, 2.094, 2.136, 2.167, 2.187, 2.189,
1075++ 2.179, 2.163, 2.131, 2.087, 2.041, 1.994, 1.948, 1.907, 1.871, 1.835, 1.806, 1.784, 1.767, 1.754, 1.744, 1.742, 1.742, 1.752, 1.767, 1.783, 1.808, 1.838, 1.869, 1.905, 1.945, 1.989, 2.036, 2.083, 2.128, 2.159, 2.183, 2.187,
1076++ 2.178, 2.161, 2.126, 2.082, 2.032, 1.982, 1.936, 1.896, 1.857, 1.823, 1.795, 1.772, 1.754, 1.744, 1.732, 1.731, 1.732, 1.742, 1.752, 1.771, 1.796, 1.824, 1.857, 1.895, 1.934, 1.977, 2.024, 2.071, 2.116, 2.154, 2.181, 2.185,
1077++ 2.177, 2.157, 2.121, 2.074, 2.025, 1.973, 1.927, 1.886, 1.849, 1.815, 1.787, 1.765, 1.746, 1.732, 1.725, 1.722, 1.724, 1.732, 1.743, 1.762, 1.786, 1.813, 1.848, 1.886, 1.924, 1.969, 2.017, 2.066, 2.111, 2.153, 2.179, 2.183,
1078++ 2.177, 2.155, 2.119, 2.072, 2.022, 1.969, 1.925, 1.881, 1.844, 1.811, 1.782, 1.758, 1.739, 1.725, 1.721, 1.717, 1.721, 1.724, 1.739, 1.757, 1.781, 1.809, 1.842, 1.879, 1.921, 1.965, 2.012, 2.062, 2.108, 2.151, 2.179, 2.182,
1079++ 2.177, 2.156, 2.121, 2.071, 2.021, 1.968, 1.922, 1.879, 1.842, 1.811, 1.781, 1.757, 1.739, 1.725, 1.717, 1.715, 1.715, 1.723, 1.737, 1.757, 1.779, 1.808, 1.841, 1.877, 1.918, 1.963, 2.011, 2.061, 2.107, 2.148, 2.179, 2.183,
1080++ 2.178, 2.157, 2.121, 2.072, 2.021, 1.969, 1.922, 1.881, 1.842, 1.811, 1.781, 1.758, 1.739, 1.726, 1.718, 1.717, 1.718, 1.723, 1.737, 1.757, 1.781, 1.809, 1.841, 1.877, 1.918, 1.964, 2.012, 2.061, 2.108, 2.149, 2.179, 2.183,
1081++ 2.178, 2.159, 2.124, 2.074, 2.024, 1.974, 1.926, 1.885, 1.847, 1.813, 1.784, 1.762, 1.743, 1.731, 1.725, 1.719, 1.723, 1.728, 1.742, 1.762, 1.785, 1.814, 1.847, 1.881, 1.922, 1.966, 2.017, 2.065, 2.109, 2.151, 2.181, 2.184,
1082++ 2.181, 2.163, 2.129, 2.082, 2.032, 1.982, 1.934, 1.891, 1.854, 1.822, 1.794, 1.769, 1.751, 1.739, 1.731, 1.727, 1.728, 1.739, 1.747, 1.768, 1.791, 1.821, 1.852, 1.889, 1.929, 1.972, 2.022, 2.071, 2.117, 2.155, 2.182, 2.189,
1083++ 2.184, 2.169, 2.135, 2.091, 2.041, 1.994, 1.947, 1.902, 1.865, 1.833, 1.805, 1.779, 1.762, 1.751, 1.739, 1.739, 1.739, 1.747, 1.761, 1.779, 1.803, 1.831, 1.864, 1.898, 1.941, 1.984, 2.033, 2.079, 2.123, 2.163, 2.188, 2.193,
1084++ 2.185, 2.174, 2.142, 2.099, 2.054, 2.004, 1.959, 1.917, 1.879, 1.846, 1.819, 1.794, 1.779, 1.762, 1.754, 1.753, 1.753, 1.761, 1.777, 1.793, 1.816, 1.843, 1.877, 1.913, 1.953, 1.995, 2.043, 2.091, 2.135, 2.169, 2.191, 2.196,
1085++ 2.191, 2.179, 2.154, 2.118, 2.069, 2.023, 1.977, 1.935, 1.898, 1.865, 1.834, 1.813, 1.794, 1.779, 1.769, 1.769, 1.769, 1.777, 1.793, 1.809, 1.834, 1.863, 1.895, 1.929, 1.972, 2.015, 2.061, 2.105, 2.145, 2.178, 2.195, 2.199,
1086++ 2.197, 2.188, 2.166, 2.129, 2.087, 2.041, 1.997, 1.956, 1.918, 1.884, 1.855, 1.834, 1.813, 1.798, 1.788, 1.788, 1.788, 1.796, 1.809, 1.832, 1.853, 1.881, 1.912, 1.949, 1.991, 2.033, 2.076, 2.119, 2.159, 2.187, 2.202, 2.205,
1087++ 2.202, 2.197, 2.176, 2.148, 2.106, 2.065, 2.021, 1.979, 1.943, 1.909, 1.879, 1.855, 1.835, 1.819, 1.811, 1.811, 1.811, 1.818, 1.832, 1.853, 1.875, 1.904, 1.937, 1.972, 2.013, 2.055, 2.097, 2.138, 2.175, 2.197, 2.206, 2.207,
1088++ 2.205, 2.202, 2.189, 2.162, 2.126, 2.084, 2.044, 2.004, 1.967, 1.935, 1.907, 1.879, 1.861, 1.845, 1.838, 1.835, 1.835, 1.844, 1.855, 1.875, 1.902, 1.928, 1.961, 1.998, 2.033, 2.076, 2.118, 2.155, 2.186, 2.205, 2.208, 2.208,
1089++ 2.207, 2.205, 2.195, 2.175, 2.145, 2.108, 2.069, 2.029, 1.996, 1.963, 1.934, 1.908, 1.885, 1.872, 1.864, 1.863, 1.863, 1.869, 1.884, 1.902, 1.928, 1.956, 1.989, 2.023, 2.059, 2.099, 2.137, 2.172, 2.199, 2.212, 2.213, 2.209,
1090++ 2.207, 2.207, 2.203, 2.188, 2.162, 2.128, 2.094, 2.058, 2.023, 1.993, 1.963, 1.936, 1.916, 1.899, 1.893, 1.892, 1.893, 1.899, 1.912, 1.929, 1.956, 1.986, 2.016, 2.049, 2.084, 2.121, 2.156, 2.187, 2.208, 2.215, 2.215, 2.208,
1091++ 2.205, 2.208, 2.209, 2.199, 2.178, 2.149, 2.117, 2.083, 2.052, 2.023, 1.993, 1.967, 1.947, 1.933, 1.925, 1.922, 1.922, 1.929, 1.943, 1.961, 1.986, 2.015, 2.045, 2.076, 2.109, 2.143, 2.173, 2.198, 2.214, 2.218, 2.216, 2.205,
1092++ 2.201, 2.207, 2.211, 2.211, 2.193, 2.168, 2.141, 2.112, 2.082, 2.052, 2.025, 2.001, 1.981, 1.967, 1.959, 1.958, 1.958, 1.967, 1.975, 1.992, 2.018, 2.046, 2.076, 2.105, 2.136, 2.163, 2.189, 2.208, 2.217, 2.217, 2.212, 2.203,
1093++ 2.194, 2.204, 2.212, 2.213, 2.203, 2.187, 2.165, 2.139, 2.112, 2.083, 2.055, 2.034, 2.016, 2.001, 1.993, 1.993, 1.994, 1.999, 2.011, 2.027, 2.051, 2.077, 2.105, 2.133, 2.158, 2.181, 2.202, 2.217, 2.218, 2.218, 2.206, 2.193,
1094++ 2.185, 2.198, 2.213, 2.214, 2.212, 2.201, 2.184, 2.163, 2.135, 2.111, 2.089, 2.071, 2.052, 2.039, 2.032, 2.031, 2.031, 2.036, 2.048, 2.065, 2.085, 2.106, 2.131, 2.155, 2.178, 2.198, 2.212, 2.219, 2.219, 2.215, 2.201, 2.185,
1095++ 2.176, 2.191, 2.208, 2.217, 2.216, 2.205, 2.195, 2.177, 2.156, 2.133, 2.109, 2.089, 2.071, 2.055, 2.053, 2.053, 2.053, 2.057, 2.065, 2.085, 2.105, 2.123, 2.149, 2.171, 2.192, 2.205, 2.217, 2.219, 2.219, 2.202, 2.185, 2.181
1096++ ]
1097++ }
1098++ ],
1099++ "calibrations_Cb": [
1100++ {
1101++ "ct": 3000,
1102++ "table":
1103++ [
1104++ 2.518, 2.513, 2.503, 2.496, 2.488, 2.484, 2.485, 2.485, 2.486, 2.487, 2.487, 2.489, 2.494, 2.496, 2.496, 2.497, 2.499, 2.499, 2.496, 2.495, 2.492, 2.491, 2.491, 2.491, 2.492, 2.493, 2.495, 2.501, 2.508, 2.516, 2.528, 2.533,
1105++ 2.515, 2.508, 2.495, 2.487, 2.483, 2.481, 2.482, 2.483, 2.485, 2.487, 2.489, 2.491, 2.495, 2.497, 2.498, 2.501, 2.502, 2.502, 2.499, 2.496, 2.494, 2.491, 2.491, 2.489, 2.489, 2.491, 2.493, 2.496, 2.502, 2.511, 2.521, 2.531,
1106++ 2.507, 2.495, 2.486, 2.482, 2.478, 2.477, 2.481, 2.482, 2.484, 2.488, 2.491, 2.495, 2.499, 2.502, 2.506, 2.508, 2.509, 2.508, 2.505, 2.501, 2.497, 2.493, 2.491, 2.489, 2.488, 2.489, 2.489, 2.492, 2.496, 2.501, 2.511, 2.524,
1107++ 2.501, 2.487, 2.482, 2.481, 2.478, 2.477, 2.481, 2.483, 2.487, 2.491, 2.501, 2.503, 2.509, 2.511, 2.518, 2.519, 2.519, 2.519, 2.516, 2.509, 2.504, 2.498, 2.495, 2.493, 2.489, 2.489, 2.488, 2.489, 2.492, 2.498, 2.505, 2.523,
1108++ 2.499, 2.484, 2.481, 2.476, 2.476, 2.476, 2.481, 2.485, 2.492, 2.501, 2.509, 2.514, 2.519, 2.524, 2.528, 2.531, 2.533, 2.533, 2.525, 2.519, 2.514, 2.507, 2.501, 2.497, 2.493, 2.489, 2.489, 2.488, 2.491, 2.494, 2.501, 2.514,
1109++ 2.497, 2.483, 2.478, 2.476, 2.476, 2.478, 2.482, 2.491, 2.499, 2.509, 2.515, 2.522, 2.528, 2.535, 2.539, 2.541, 2.543, 2.542, 2.539, 2.529, 2.522, 2.516, 2.507, 2.502, 2.497, 2.491, 2.489, 2.488, 2.489, 2.492, 2.498, 2.514,
1110++ 2.492, 2.479, 2.476, 2.475, 2.476, 2.481, 2.488, 2.496, 2.505, 2.516, 2.524, 2.532, 2.541, 2.545, 2.552, 2.554, 2.554, 2.554, 2.548, 2.541, 2.532, 2.522, 2.516, 2.507, 2.502, 2.494, 2.491, 2.489, 2.489, 2.492, 2.494, 2.511,
1111++ 2.491, 2.479, 2.476, 2.477, 2.478, 2.482, 2.491, 2.502, 2.514, 2.524, 2.533, 2.543, 2.548, 2.555, 2.562, 2.566, 2.567, 2.562, 2.557, 2.551, 2.541, 2.531, 2.523, 2.512, 2.506, 2.498, 2.493, 2.491, 2.491, 2.491, 2.493, 2.507,
1112++ 2.489, 2.478, 2.476, 2.477, 2.481, 2.485, 2.494, 2.507, 2.517, 2.529, 2.542, 2.548, 2.557, 2.563, 2.567, 2.571, 2.572, 2.571, 2.565, 2.558, 2.549, 2.538, 2.528, 2.521, 2.509, 2.501, 2.494, 2.492, 2.491, 2.491, 2.491, 2.505,
1113++ 2.488, 2.478, 2.477, 2.478, 2.482, 2.489, 2.499, 2.509, 2.523, 2.538, 2.548, 2.556, 2.563, 2.568, 2.573, 2.577, 2.578, 2.577, 2.573, 2.564, 2.555, 2.543, 2.535, 2.524, 2.515, 2.504, 2.495, 2.492, 2.489, 2.488, 2.489, 2.501,
1114++ 2.486, 2.476, 2.475, 2.477, 2.483, 2.491, 2.503, 2.515, 2.529, 2.542, 2.553, 2.562, 2.568, 2.574, 2.581, 2.583, 2.584, 2.581, 2.578, 2.571, 2.562, 2.551, 2.539, 2.531, 2.517, 2.508, 2.497, 2.492, 2.488, 2.487, 2.489, 2.498,
1115++ 2.486, 2.476, 2.475, 2.479, 2.484, 2.492, 2.504, 2.519, 2.533, 2.544, 2.557, 2.566, 2.573, 2.581, 2.584, 2.588, 2.588, 2.586, 2.581, 2.575, 2.567, 2.555, 2.546, 2.534, 2.517, 2.509, 2.499, 2.492, 2.489, 2.485, 2.488, 2.497,
1116++ 2.487, 2.476, 2.476, 2.479, 2.486, 2.494, 2.506, 2.521, 2.535, 2.549, 2.559, 2.571, 2.578, 2.583, 2.589, 2.591, 2.591, 2.591, 2.587, 2.579, 2.571, 2.559, 2.551, 2.538, 2.523, 2.513, 2.503, 2.493, 2.489, 2.486, 2.487, 2.499,
1117++ 2.486, 2.475, 2.475, 2.479, 2.486, 2.495, 2.509, 2.525, 2.541, 2.555, 2.563, 2.573, 2.582, 2.588, 2.591, 2.594, 2.595, 2.592, 2.591, 2.585, 2.574, 2.564, 2.552, 2.541, 2.525, 2.514, 2.503, 2.493, 2.489, 2.486, 2.486, 2.501,
1118++ 2.486, 2.475, 2.475, 2.479, 2.488, 2.497, 2.509, 2.526, 2.542, 2.556, 2.564, 2.575, 2.584, 2.591, 2.595, 2.596, 2.597, 2.595, 2.592, 2.587, 2.577, 2.568, 2.554, 2.542, 2.527, 2.515, 2.504, 2.494, 2.491, 2.487, 2.487, 2.505,
1119++ 2.484, 2.476, 2.475, 2.478, 2.488, 2.498, 2.509, 2.526, 2.542, 2.555, 2.565, 2.576, 2.584, 2.589, 2.595, 2.598, 2.598, 2.597, 2.593, 2.587, 2.578, 2.569, 2.556, 2.543, 2.528, 2.515, 2.504, 2.494, 2.489, 2.485, 2.485, 2.501,
1120++ 2.484, 2.475, 2.475, 2.478, 2.489, 2.498, 2.509, 2.524, 2.539, 2.553, 2.565, 2.576, 2.584, 2.589, 2.594, 2.597, 2.597, 2.596, 2.593, 2.587, 2.577, 2.569, 2.555, 2.543, 2.529, 2.515, 2.503, 2.496, 2.491, 2.485, 2.486, 2.497,
1121++ 2.484, 2.474, 2.474, 2.479, 2.487, 2.497, 2.509, 2.523, 2.539, 2.551, 2.563, 2.574, 2.581, 2.587, 2.592, 2.595, 2.596, 2.595, 2.591, 2.584, 2.574, 2.567, 2.554, 2.541, 2.526, 2.514, 2.503, 2.495, 2.489, 2.485, 2.486, 2.497,
1122++ 2.484, 2.475, 2.475, 2.478, 2.485, 2.494, 2.507, 2.522, 2.535, 2.546, 2.559, 2.568, 2.579, 2.584, 2.589, 2.592, 2.593, 2.592, 2.588, 2.579, 2.571, 2.562, 2.551, 2.537, 2.524, 2.514, 2.501, 2.493, 2.489, 2.486, 2.487, 2.498,
1123++ 2.485, 2.476, 2.475, 2.477, 2.485, 2.491, 2.506, 2.519, 2.531, 2.544, 2.555, 2.563, 2.571, 2.581, 2.584, 2.589, 2.589, 2.588, 2.583, 2.576, 2.566, 2.555, 2.546, 2.534, 2.522, 2.511, 2.499, 2.491, 2.488, 2.486, 2.487, 2.502,
1124++ 2.487, 2.477, 2.475, 2.477, 2.483, 2.489, 2.503, 2.515, 2.525, 2.541, 2.551, 2.559, 2.567, 2.573, 2.579, 2.582, 2.583, 2.582, 2.576, 2.569, 2.562, 2.549, 2.542, 2.527, 2.518, 2.505, 2.497, 2.491, 2.489, 2.487, 2.487, 2.502,
1125++ 2.487, 2.478, 2.475, 2.477, 2.482, 2.489, 2.497, 2.512, 2.522, 2.536, 2.544, 2.551, 2.562, 2.566, 2.573, 2.578, 2.578, 2.575, 2.571, 2.564, 2.556, 2.548, 2.536, 2.523, 2.513, 2.503, 2.493, 2.489, 2.487, 2.486, 2.487, 2.502,
1126++ 2.488, 2.479, 2.477, 2.478, 2.482, 2.488, 2.496, 2.505, 2.516, 2.528, 2.538, 2.547, 2.553, 2.561, 2.565, 2.569, 2.569, 2.568, 2.564, 2.558, 2.549, 2.541, 2.531, 2.517, 2.509, 2.499, 2.492, 2.488, 2.486, 2.484, 2.486, 2.503,
1127++ 2.492, 2.482, 2.479, 2.479, 2.482, 2.487, 2.491, 2.501, 2.512, 2.523, 2.531, 2.541, 2.549, 2.552, 2.558, 2.561, 2.562, 2.559, 2.558, 2.552, 2.542, 2.535, 2.525, 2.514, 2.505, 2.497, 2.491, 2.486, 2.485, 2.484, 2.487, 2.503,
1128++ 2.495, 2.483, 2.479, 2.479, 2.482, 2.487, 2.491, 2.498, 2.508, 2.515, 2.526, 2.533, 2.541, 2.547, 2.551, 2.554, 2.555, 2.554, 2.552, 2.541, 2.537, 2.527, 2.519, 2.507, 2.502, 2.495, 2.488, 2.485, 2.484, 2.485, 2.488, 2.503,
1129++ 2.499, 2.485, 2.483, 2.481, 2.482, 2.486, 2.489, 2.494, 2.504, 2.511, 2.519, 2.527, 2.531, 2.539, 2.542, 2.546, 2.546, 2.545, 2.539, 2.535, 2.527, 2.522, 2.509, 2.505, 2.497, 2.491, 2.486, 2.485, 2.485, 2.487, 2.491, 2.506,
1130++ 2.499, 2.489, 2.483, 2.481, 2.481, 2.483, 2.488, 2.491, 2.499, 2.506, 2.512, 2.519, 2.524, 2.529, 2.535, 2.537, 2.536, 2.534, 2.532, 2.525, 2.522, 2.514, 2.506, 2.499, 2.492, 2.489, 2.485, 2.484, 2.485, 2.488, 2.492, 2.506,
1131++ 2.507, 2.494, 2.486, 2.483, 2.482, 2.482, 2.486, 2.488, 2.495, 2.501, 2.507, 2.511, 2.517, 2.519, 2.523, 2.525, 2.525, 2.523, 2.523, 2.521, 2.514, 2.506, 2.502, 2.496, 2.491, 2.488, 2.485, 2.485, 2.487, 2.489, 2.496, 2.516,
1132++ 2.511, 2.503, 2.489, 2.486, 2.485, 2.485, 2.485, 2.487, 2.489, 2.495, 2.501, 2.505, 2.509, 2.514, 2.517, 2.519, 2.518, 2.517, 2.515, 2.511, 2.505, 2.501, 2.495, 2.492, 2.488, 2.486, 2.485, 2.486, 2.488, 2.492, 2.499, 2.519,
1133++ 2.517, 2.505, 2.494, 2.489, 2.487, 2.486, 2.486, 2.486, 2.489, 2.491, 2.496, 2.499, 2.503, 2.506, 2.508, 2.509, 2.511, 2.509, 2.507, 2.503, 2.501, 2.496, 2.493, 2.489, 2.485, 2.485, 2.486, 2.487, 2.491, 2.495, 2.505, 2.526,
1134++ 2.526, 2.516, 2.504, 2.494, 2.493, 2.489, 2.489, 2.489, 2.489, 2.491, 2.496, 2.498, 2.501, 2.504, 2.506, 2.506, 2.506, 2.505, 2.503, 2.501, 2.499, 2.496, 2.494, 2.491, 2.487, 2.486, 2.489, 2.492, 2.497, 2.505, 2.517, 2.528,
1135++ 2.529, 2.526, 2.508, 2.502, 2.501, 2.498, 2.495, 2.495, 2.495, 2.495, 2.497, 2.499, 2.501, 2.503, 2.504, 2.506, 2.505, 2.505, 2.503, 2.501, 2.499, 2.496, 2.495, 2.494, 2.492, 2.494, 2.494, 2.498, 2.504, 2.513, 2.525, 2.536
1136++ ]
1137++ },
1138++ {
1139++ "ct": 5000,
1140++ "table":
1141++ [
1142++ 1.427, 1.425, 1.423, 1.422, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.422, 1.423, 1.424, 1.425, 1.426, 1.426, 1.426, 1.425, 1.425, 1.424, 1.422, 1.421, 1.421, 1.421, 1.421, 1.422, 1.422, 1.422, 1.424, 1.424, 1.426, 1.428,
1143++ 1.426, 1.424, 1.422, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.422, 1.423, 1.424, 1.425, 1.426, 1.427, 1.427, 1.427, 1.426, 1.425, 1.424, 1.422, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.422, 1.424, 1.427,
1144++ 1.423, 1.421, 1.421, 1.419, 1.419, 1.418, 1.419, 1.419, 1.421, 1.423, 1.425, 1.426, 1.428, 1.429, 1.431, 1.431, 1.431, 1.431, 1.429, 1.426, 1.424, 1.422, 1.421, 1.421, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.422, 1.425,
1145++ 1.422, 1.419, 1.419, 1.419, 1.418, 1.418, 1.419, 1.421, 1.422, 1.426, 1.428, 1.429, 1.433, 1.434, 1.436, 1.436, 1.436, 1.434, 1.432, 1.429, 1.426, 1.424, 1.423, 1.422, 1.421, 1.419, 1.419, 1.419, 1.419, 1.419, 1.421, 1.425,
1146++ 1.422, 1.419, 1.419, 1.418, 1.418, 1.419, 1.419, 1.422, 1.425, 1.429, 1.432, 1.435, 1.436, 1.438, 1.439, 1.439, 1.441, 1.439, 1.435, 1.433, 1.429, 1.427, 1.425, 1.423, 1.422, 1.419, 1.419, 1.418, 1.418, 1.418, 1.419, 1.425,
1147++ 1.422, 1.419, 1.418, 1.418, 1.418, 1.419, 1.421, 1.424, 1.428, 1.432, 1.436, 1.437, 1.439, 1.442, 1.443, 1.445, 1.444, 1.443, 1.441, 1.436, 1.434, 1.431, 1.427, 1.425, 1.422, 1.421, 1.419, 1.418, 1.418, 1.418, 1.419, 1.424,
1148++ 1.422, 1.418, 1.417, 1.418, 1.419, 1.421, 1.423, 1.427, 1.431, 1.436, 1.438, 1.442, 1.444, 1.446, 1.448, 1.449, 1.448, 1.446, 1.445, 1.441, 1.436, 1.434, 1.429, 1.427, 1.423, 1.421, 1.419, 1.418, 1.418, 1.418, 1.418, 1.423,
1149++ 1.421, 1.418, 1.418, 1.418, 1.419, 1.421, 1.424, 1.429, 1.434, 1.438, 1.442, 1.445, 1.447, 1.449, 1.451, 1.452, 1.452, 1.449, 1.447, 1.445, 1.441, 1.436, 1.433, 1.429, 1.425, 1.422, 1.419, 1.419, 1.418, 1.417, 1.418, 1.423,
1150++ 1.421, 1.418, 1.418, 1.419, 1.419, 1.423, 1.426, 1.432, 1.436, 1.441, 1.445, 1.448, 1.449, 1.452, 1.453, 1.454, 1.454, 1.453, 1.451, 1.447, 1.444, 1.439, 1.433, 1.431, 1.427, 1.422, 1.421, 1.419, 1.418, 1.417, 1.418, 1.423,
1151++ 1.421, 1.418, 1.418, 1.419, 1.421, 1.423, 1.428, 1.433, 1.439, 1.443, 1.448, 1.449, 1.453, 1.454, 1.455, 1.456, 1.456, 1.454, 1.453, 1.449, 1.446, 1.441, 1.437, 1.433, 1.429, 1.423, 1.421, 1.419, 1.418, 1.416, 1.417, 1.423,
1152++ 1.421, 1.417, 1.417, 1.419, 1.422, 1.424, 1.429, 1.435, 1.441, 1.444, 1.449, 1.453, 1.454, 1.456, 1.458, 1.459, 1.458, 1.456, 1.454, 1.451, 1.448, 1.442, 1.439, 1.435, 1.429, 1.426, 1.421, 1.419, 1.418, 1.416, 1.417, 1.422,
1153++ 1.419, 1.418, 1.417, 1.419, 1.422, 1.425, 1.429, 1.436, 1.442, 1.446, 1.451, 1.454, 1.456, 1.458, 1.461, 1.461, 1.461, 1.459, 1.456, 1.453, 1.451, 1.446, 1.441, 1.436, 1.431, 1.427, 1.422, 1.419, 1.418, 1.416, 1.417, 1.422,
1154++ 1.419, 1.418, 1.418, 1.421, 1.423, 1.426, 1.431, 1.437, 1.444, 1.449, 1.452, 1.456, 1.458, 1.461, 1.462, 1.463, 1.463, 1.461, 1.458, 1.454, 1.452, 1.447, 1.443, 1.438, 1.432, 1.428, 1.423, 1.421, 1.419, 1.417, 1.417, 1.421,
1155++ 1.419, 1.418, 1.417, 1.421, 1.423, 1.428, 1.432, 1.439, 1.445, 1.451, 1.453, 1.457, 1.459, 1.462, 1.464, 1.465, 1.465, 1.463, 1.461, 1.457, 1.453, 1.449, 1.444, 1.441, 1.432, 1.429, 1.425, 1.421, 1.419, 1.417, 1.418, 1.422,
1156++ 1.418, 1.417, 1.417, 1.419, 1.423, 1.428, 1.433, 1.439, 1.446, 1.451, 1.453, 1.457, 1.461, 1.464, 1.465, 1.466, 1.466, 1.464, 1.462, 1.459, 1.454, 1.451, 1.445, 1.441, 1.436, 1.429, 1.425, 1.422, 1.421, 1.417, 1.417, 1.423,
1157++ 1.417, 1.416, 1.416, 1.419, 1.423, 1.428, 1.433, 1.441, 1.446, 1.451, 1.454, 1.458, 1.461, 1.463, 1.465, 1.466, 1.466, 1.465, 1.463, 1.459, 1.454, 1.451, 1.446, 1.441, 1.437, 1.431, 1.426, 1.422, 1.421, 1.418, 1.418, 1.423,
1158++ 1.417, 1.416, 1.417, 1.418, 1.423, 1.428, 1.433, 1.439, 1.445, 1.451, 1.453, 1.457, 1.461, 1.463, 1.465, 1.466, 1.466, 1.464, 1.462, 1.459, 1.454, 1.451, 1.446, 1.441, 1.437, 1.431, 1.426, 1.422, 1.419, 1.417, 1.417, 1.422,
1159++ 1.417, 1.416, 1.416, 1.418, 1.422, 1.428, 1.433, 1.438, 1.444, 1.449, 1.453, 1.456, 1.459, 1.462, 1.464, 1.465, 1.465, 1.463, 1.461, 1.458, 1.453, 1.449, 1.445, 1.441, 1.435, 1.429, 1.426, 1.421, 1.419, 1.417, 1.417, 1.422,
1160++ 1.418, 1.416, 1.416, 1.418, 1.421, 1.426, 1.432, 1.438, 1.443, 1.447, 1.451, 1.454, 1.458, 1.459, 1.462, 1.463, 1.463, 1.462, 1.459, 1.455, 1.451, 1.447, 1.443, 1.439, 1.434, 1.429, 1.425, 1.421, 1.419, 1.417, 1.417, 1.422,
1161++ 1.418, 1.416, 1.416, 1.418, 1.421, 1.425, 1.431, 1.435, 1.442, 1.445, 1.449, 1.452, 1.455, 1.458, 1.458, 1.461, 1.461, 1.459, 1.456, 1.453, 1.449, 1.445, 1.442, 1.436, 1.433, 1.427, 1.425, 1.421, 1.419, 1.418, 1.418, 1.422,
1162++ 1.419, 1.416, 1.415, 1.417, 1.419, 1.424, 1.429, 1.434, 1.439, 1.443, 1.446, 1.449, 1.452, 1.454, 1.456, 1.457, 1.457, 1.456, 1.453, 1.451, 1.447, 1.443, 1.441, 1.435, 1.431, 1.426, 1.424, 1.421, 1.419, 1.418, 1.418, 1.422,
1163++ 1.419, 1.416, 1.415, 1.416, 1.419, 1.422, 1.426, 1.433, 1.437, 1.441, 1.444, 1.447, 1.449, 1.452, 1.453, 1.455, 1.455, 1.453, 1.451, 1.447, 1.444, 1.441, 1.438, 1.432, 1.428, 1.424, 1.421, 1.419, 1.418, 1.417, 1.417, 1.421,
1164++ 1.419, 1.416, 1.415, 1.416, 1.418, 1.421, 1.425, 1.431, 1.435, 1.438, 1.442, 1.445, 1.446, 1.449, 1.451, 1.451, 1.451, 1.451, 1.447, 1.445, 1.443, 1.439, 1.434, 1.431, 1.427, 1.422, 1.421, 1.418, 1.417, 1.417, 1.417, 1.421,
1165++ 1.418, 1.416, 1.415, 1.416, 1.417, 1.421, 1.423, 1.428, 1.433, 1.437, 1.439, 1.442, 1.444, 1.446, 1.448, 1.449, 1.449, 1.447, 1.445, 1.443, 1.439, 1.437, 1.432, 1.429, 1.425, 1.422, 1.419, 1.417, 1.417, 1.416, 1.416, 1.419,
1166++ 1.418, 1.416, 1.416, 1.416, 1.417, 1.421, 1.422, 1.426, 1.429, 1.433, 1.436, 1.438, 1.441, 1.443, 1.445, 1.446, 1.445, 1.445, 1.443, 1.439, 1.437, 1.434, 1.431, 1.427, 1.424, 1.421, 1.419, 1.417, 1.417, 1.416, 1.416, 1.421,
1167++ 1.419, 1.417, 1.416, 1.416, 1.417, 1.421, 1.422, 1.424, 1.427, 1.429, 1.432, 1.436, 1.437, 1.439, 1.442, 1.443, 1.443, 1.441, 1.439, 1.437, 1.434, 1.431, 1.429, 1.425, 1.422, 1.421, 1.419, 1.417, 1.416, 1.416, 1.417, 1.419,
1168++ 1.421, 1.418, 1.416, 1.417, 1.418, 1.421, 1.421, 1.423, 1.424, 1.427, 1.429, 1.432, 1.434, 1.436, 1.438, 1.439, 1.439, 1.438, 1.436, 1.434, 1.431, 1.429, 1.426, 1.423, 1.422, 1.421, 1.418, 1.417, 1.417, 1.417, 1.417, 1.421,
1169++ 1.423, 1.419, 1.418, 1.418, 1.419, 1.419, 1.421, 1.422, 1.423, 1.424, 1.427, 1.429, 1.432, 1.432, 1.434, 1.435, 1.435, 1.434, 1.433, 1.431, 1.429, 1.426, 1.424, 1.422, 1.421, 1.419, 1.418, 1.417, 1.417, 1.417, 1.418, 1.421,
1170++ 1.425, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.421, 1.421, 1.423, 1.424, 1.426, 1.428, 1.431, 1.431, 1.432, 1.432, 1.431, 1.431, 1.428, 1.425, 1.425, 1.422, 1.421, 1.419, 1.419, 1.418, 1.418, 1.418, 1.418, 1.419, 1.425,
1171++ 1.426, 1.422, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.421, 1.422, 1.424, 1.426, 1.427, 1.428, 1.429, 1.429, 1.429, 1.427, 1.424, 1.423, 1.422, 1.421, 1.419, 1.418, 1.418, 1.418, 1.418, 1.418, 1.418, 1.419, 1.426,
1172++ 1.428, 1.425, 1.421, 1.421, 1.421, 1.421, 1.421, 1.419, 1.419, 1.421, 1.422, 1.423, 1.424, 1.426, 1.426, 1.426, 1.426, 1.425, 1.424, 1.424, 1.422, 1.422, 1.421, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.423, 1.426,
1173++ 1.429, 1.427, 1.424, 1.422, 1.422, 1.422, 1.421, 1.421, 1.421, 1.422, 1.422, 1.422, 1.424, 1.425, 1.426, 1.426, 1.425, 1.425, 1.424, 1.423, 1.422, 1.422, 1.421, 1.421, 1.421, 1.421, 1.419, 1.419, 1.421, 1.422, 1.424, 1.426
1174++ ]
1175++ }
1176++ ],
1177++ "luminance_lut":
1178++ [
1179++ 2.964, 2.872, 2.691, 2.544, 2.416, 2.302, 2.196, 2.093, 2.006, 1.928, 1.852, 1.801, 1.769, 1.752, 1.743, 1.743, 1.743, 1.746, 1.759, 1.784, 1.824, 1.888, 1.968, 2.052, 2.149, 2.253, 2.359, 2.483, 2.626, 2.785, 2.988, 3.051,
1180++ 2.872, 2.748, 2.583, 2.442, 2.313, 2.201, 2.104, 2.012, 1.928, 1.852, 1.791, 1.742, 1.701, 1.671, 1.651, 1.643, 1.643, 1.659, 1.685, 1.721, 1.768, 1.824, 1.888, 1.971, 2.068, 2.152, 2.259, 2.381, 2.514, 2.669, 2.853, 2.988,
1181++ 2.761, 2.655, 2.497, 2.356, 2.226, 2.114, 2.012, 1.928, 1.845, 1.769, 1.707, 1.653, 1.612, 1.583, 1.562, 1.556, 1.556, 1.572, 1.599, 1.635, 1.681, 1.742, 1.806, 1.888, 1.971, 2.068, 2.175, 2.292, 2.431, 2.576, 2.747, 2.853,
1182++ 2.679, 2.571, 2.415, 2.275, 2.151, 2.035, 1.936, 1.845, 1.769, 1.689, 1.623, 1.572, 1.532, 1.501, 1.481, 1.473, 1.473, 1.492, 1.517, 1.556, 1.599, 1.659, 1.731, 1.806, 1.895, 1.992, 2.101, 2.218, 2.349, 2.493, 2.664, 2.753,
1183++ 2.609, 2.492, 2.339, 2.204, 2.079, 1.971, 1.865, 1.772, 1.689, 1.619, 1.551, 1.499, 1.457, 1.423, 1.405, 1.397, 1.397, 1.411, 1.438, 1.477, 1.525, 1.585, 1.659, 1.731, 1.823, 1.922, 2.027, 2.148, 2.275, 2.422, 2.586, 2.683,
1184++ 2.545, 2.426, 2.279, 2.139, 2.014, 1.903, 1.799, 1.702, 1.619, 1.551, 1.482, 1.427, 1.385, 1.353, 1.331, 1.325, 1.325, 1.338, 1.364, 1.403, 1.455, 1.522, 1.585, 1.665, 1.757, 1.858, 1.963, 2.081, 2.207, 2.356, 2.518, 2.615,
1185++ 2.489, 2.367, 2.218, 2.079, 1.956, 1.844, 1.739, 1.642, 1.559, 1.482, 1.426, 1.363, 1.321, 1.287, 1.266, 1.259, 1.259, 1.274, 1.301, 1.339, 1.395, 1.455, 1.523, 1.606, 1.697, 1.797, 1.905, 2.024, 2.154, 2.296, 2.455, 2.563,
1186++ 2.439, 2.316, 2.164, 2.028, 1.906, 1.793, 1.686, 1.589, 1.505, 1.427, 1.363, 1.308, 1.261, 1.229, 1.207, 1.202, 1.202, 1.215, 1.242, 1.283, 1.339, 1.395, 1.467, 1.551, 1.639, 1.742, 1.851, 1.972, 2.104, 2.243, 2.402, 2.515,
1187++ 2.398, 2.262, 2.116, 1.982, 1.861, 1.745, 1.639, 1.541, 1.456, 1.377, 1.308, 1.261, 1.208, 1.177, 1.157, 1.153, 1.153, 1.167, 1.191, 1.233, 1.283, 1.343, 1.418, 1.499, 1.591, 1.696, 1.804, 1.928, 2.057, 2.194, 2.352, 2.471,
1188++ 2.363, 2.222, 2.078, 1.942, 1.818, 1.706, 1.597, 1.501, 1.412, 1.334, 1.266, 1.208, 1.171, 1.134, 1.113, 1.109, 1.109, 1.123, 1.149, 1.191, 1.233, 1.296, 1.371, 1.457, 1.546, 1.654, 1.768, 1.886, 2.014, 2.155, 2.312, 2.436,
1189++ 2.334, 2.188, 2.042, 1.909, 1.783, 1.668, 1.561, 1.464, 1.374, 1.295, 1.228, 1.171, 1.134, 1.098, 1.076, 1.072, 1.072, 1.087, 1.119, 1.149, 1.196, 1.259, 1.332, 1.419, 1.514, 1.616, 1.728, 1.849, 1.981, 2.123, 2.276, 2.406,
1190++ 2.306, 2.159, 2.015, 1.881, 1.753, 1.639, 1.533, 1.434, 1.341, 1.263, 1.195, 1.139, 1.098, 1.074, 1.046, 1.044, 1.045, 1.059, 1.087, 1.119, 1.165, 1.227, 1.302, 1.387, 1.482, 1.586, 1.698, 1.819, 1.953, 2.093, 2.248, 2.383,
1191++ 2.291, 2.141, 1.991, 1.856, 1.732, 1.615, 1.508, 1.409, 1.318, 1.238, 1.171, 1.114, 1.074, 1.046, 1.027, 1.023, 1.025, 1.043, 1.059, 1.095, 1.142, 1.203, 1.278, 1.362, 1.456, 1.559, 1.673, 1.796, 1.928, 2.071, 2.225, 2.359,
1192++ 2.279, 2.118, 1.972, 1.839, 1.715, 1.599, 1.488, 1.389, 1.298, 1.219, 1.153, 1.097, 1.057, 1.027, 1.018, 1.009, 1.013, 1.025, 1.044, 1.078, 1.125, 1.186, 1.258, 1.342, 1.438, 1.541, 1.655, 1.779, 1.909, 2.053, 2.211, 2.351,
1193++ 2.274, 2.108, 1.963, 1.831, 1.706, 1.588, 1.477, 1.376, 1.288, 1.207, 1.139, 1.086, 1.049, 1.021, 1.005, 1.002, 1.004, 1.013, 1.035, 1.069, 1.116, 1.176, 1.246, 1.331, 1.427, 1.531, 1.645, 1.767, 1.899, 2.045, 2.197, 2.351,
1194++ 2.274, 2.106, 1.961, 1.827, 1.701, 1.585, 1.474, 1.374, 1.285, 1.206, 1.139, 1.085, 1.047, 1.019, 1.003, 1.001, 1.001, 1.012, 1.033, 1.067, 1.113, 1.173, 1.245, 1.329, 1.423, 1.529, 1.642, 1.765, 1.897, 2.042, 2.196, 2.349,
1195++ 2.274, 2.108, 1.961, 1.827, 1.701, 1.585, 1.474, 1.374, 1.285, 1.206, 1.139, 1.085, 1.047, 1.021, 1.005, 1.001, 1.004, 1.012, 1.033, 1.068, 1.113, 1.173, 1.246, 1.329, 1.423, 1.529, 1.642, 1.766, 1.897, 2.042, 2.198, 2.349,
1196++ 2.278, 2.116, 1.968, 1.833, 1.707, 1.591, 1.482, 1.382, 1.291, 1.214, 1.147, 1.091, 1.055, 1.028, 1.016, 1.006, 1.012, 1.018, 1.039, 1.074, 1.121, 1.182, 1.255, 1.339, 1.433, 1.538, 1.651, 1.777, 1.911, 2.051, 2.207, 2.351,
1197++ 2.283, 2.127, 1.979, 1.846, 1.723, 1.605, 1.496, 1.397, 1.309, 1.229, 1.162, 1.108, 1.067, 1.041, 1.027, 1.018, 1.018, 1.036, 1.051, 1.087, 1.136, 1.197, 1.269, 1.354, 1.448, 1.554, 1.664, 1.789, 1.922, 2.065, 2.222, 2.365,
1198++ 2.298, 2.145, 1.999, 1.865, 1.744, 1.627, 1.518, 1.421, 1.331, 1.251, 1.183, 1.129, 1.087, 1.065, 1.041, 1.036, 1.036, 1.051, 1.074, 1.107, 1.158, 1.219, 1.292, 1.378, 1.471, 1.575, 1.687, 1.809, 1.942, 2.085, 2.239, 2.378,
1199++ 2.315, 2.174, 2.024, 1.893, 1.768, 1.652, 1.543, 1.445, 1.355, 1.278, 1.211, 1.155, 1.116, 1.087, 1.066, 1.061, 1.061, 1.074, 1.105, 1.137, 1.186, 1.248, 1.322, 1.405, 1.498, 1.602, 1.713, 1.835, 1.965, 2.109, 2.267, 2.399,
1200++ 2.341, 2.206, 2.057, 1.923, 1.799, 1.685, 1.576, 1.479, 1.392, 1.312, 1.244, 1.187, 1.154, 1.116, 1.096, 1.092, 1.092, 1.106, 1.137, 1.173, 1.221, 1.282, 1.356, 1.439, 1.532, 1.635, 1.747, 1.869, 1.997, 2.141, 2.298, 2.425,
1201++ 2.375, 2.244, 2.098, 1.965, 1.839, 1.722, 1.614, 1.519, 1.434, 1.355, 1.288, 1.234, 1.187, 1.155, 1.136, 1.132, 1.132, 1.147, 1.173, 1.219, 1.263, 1.324, 1.398, 1.479, 1.571, 1.674, 1.784, 1.904, 2.035, 2.177, 2.336, 2.455,
1202++ 2.414, 2.286, 2.144, 2.011, 1.883, 1.767, 1.661, 1.566, 1.479, 1.401, 1.335, 1.286, 1.234, 1.202, 1.183, 1.178, 1.178, 1.195, 1.222, 1.263, 1.313, 1.372, 1.444, 1.526, 1.618, 1.718, 1.827, 1.951, 2.081, 2.221, 2.379, 2.498,
1203++ 2.463, 2.339, 2.191, 2.056, 1.931, 1.819, 1.712, 1.616, 1.529, 1.452, 1.392, 1.335, 1.286, 1.254, 1.235, 1.232, 1.232, 1.248, 1.275, 1.313, 1.371, 1.425, 1.495, 1.576, 1.671, 1.768, 1.877, 1.999, 2.128, 2.269, 2.428, 2.541,
1204++ 2.514, 2.396, 2.247, 2.112, 1.988, 1.873, 1.766, 1.671, 1.588, 1.513, 1.452, 1.392, 1.348, 1.316, 1.298, 1.292, 1.292, 1.307, 1.336, 1.373, 1.425, 1.486, 1.552, 1.636, 1.728, 1.826, 1.933, 2.051, 2.183, 2.327, 2.488, 2.587,
1205++ 2.573, 2.459, 2.307, 2.171, 2.049, 1.931, 1.828, 1.731, 1.649, 1.582, 1.513, 1.459, 1.415, 1.381, 1.363, 1.358, 1.358, 1.373, 1.399, 1.439, 1.486, 1.552, 1.617, 1.696, 1.787, 1.888, 1.995, 2.112, 2.244, 2.391, 2.552, 2.652,
1206++ 2.635, 2.525, 2.377, 2.239, 2.111, 1.996, 1.895, 1.799, 1.719, 1.649, 1.582, 1.531, 1.486, 1.454, 1.434, 1.429, 1.429, 1.444, 1.469, 1.507, 1.555, 1.617, 1.692, 1.766, 1.854, 1.954, 2.065, 2.181, 2.313, 2.459, 2.623, 2.722,
1207++ 2.714, 2.604, 2.452, 2.313, 2.188, 2.071, 1.966, 1.876, 1.799, 1.719, 1.656, 1.604, 1.562, 1.529, 1.511, 1.504, 1.504, 1.519, 1.544, 1.583, 1.632, 1.692, 1.766, 1.839, 1.929, 2.029, 2.138, 2.259, 2.391, 2.539, 2.712, 2.811,
1208++ 2.809, 2.698, 2.537, 2.396, 2.277, 2.163, 2.053, 1.965, 1.876, 1.799, 1.741, 1.688, 1.643, 1.613, 1.592, 1.586, 1.586, 1.601, 1.628, 1.666, 1.715, 1.773, 1.839, 1.927, 2.012, 2.111, 2.222, 2.342, 2.477, 2.625, 2.811, 2.926,
1209++ 2.921, 2.809, 2.637, 2.493, 2.376, 2.256, 2.149, 2.053, 1.966, 1.893, 1.832, 1.778, 1.736, 1.708, 1.687, 1.681, 1.681, 1.696, 1.721, 1.757, 1.806, 1.864, 1.929, 2.012, 2.106, 2.199, 2.313, 2.437, 2.577, 2.731, 2.926, 3.051,
1210++ 3.029, 2.921, 2.745, 2.591, 2.474, 2.355, 2.246, 2.146, 2.049, 1.966, 1.893, 1.832, 1.799, 1.776, 1.768, 1.768, 1.768, 1.771, 1.783, 1.809, 1.864, 1.929, 2.012, 2.097, 2.195, 2.297, 2.412, 2.539, 2.682, 2.846, 3.051, 3.123
1211++ ],
1212++ "sigma": 0.00463,
1213++ "sigma_Cb": 0.00149
1214++ }
1215++ },
1216++ {
1217++ "rpi.contrast":
1218++ {
1219++ "ce_enable": 1,
1220++ "lo_max": 1000,
1221++ "gamma_curve":
1222++ [
1223++ 0, 0,
1224++ 1024, 5040,
1225++ 2048, 9338,
1226++ 3072, 12356,
1227++ 4096, 15312,
1228++ 5120, 18051,
1229++ 6144, 20790,
1230++ 7168, 23193,
1231++ 8192, 25744,
1232++ 9216, 27942,
1233++ 10240, 30035,
1234++ 11264, 32005,
1235++ 12288, 33975,
1236++ 13312, 35815,
1237++ 14336, 37600,
1238++ 15360, 39168,
1239++ 16384, 40642,
1240++ 18432, 43379,
1241++ 20480, 45749,
1242++ 22528, 47753,
1243++ 24576, 49621,
1244++ 26624, 51253,
1245++ 28672, 52698,
1246++ 30720, 53796,
1247++ 32768, 54876,
1248++ 36864, 57012,
1249++ 40960, 58656,
1250++ 45056, 59954,
1251++ 49152, 61183,
1252++ 53248, 62355,
1253++ 57344, 63419,
1254++ 61440, 64476,
1255++ 65535, 65535
1256++ ]
1257++ }
1258++ },
1259++ {
1260++ "rpi.ccm":
1261++ {
1262++ "ccms": [
1263++ {
1264++ "ct": 2860,
1265++ "ccm":
1266++ [
1267++ 2.12089, -0.52461, -0.59629,
1268++ -0.85342, 2.80445, -0.95103,
1269++ -0.26897, -1.14788, 2.41685
1270++ ]
1271++ },
1272++ {
1273++ "ct": 2960,
1274++ "ccm":
1275++ [
1276++ 2.26962, -0.54174, -0.72789,
1277++ -0.77008, 2.60271, -0.83262,
1278++ -0.26036, -1.51254, 2.77289
1279++ ]
1280++ },
1281++ {
1282++ "ct": 3603,
1283++ "ccm":
1284++ [
1285++ 2.18644, -0.66148, -0.52496,
1286++ -0.77828, 2.69474, -0.91645,
1287++ -0.25239, -0.83059, 2.08298
1288++ ]
1289++ },
1290++ {
1291++ "ct": 4650,
1292++ "ccm":
1293++ [
1294++ 2.18174, -0.70887, -0.47287,
1295++ -0.70196, 2.76426, -1.06231,
1296++ -0.25157, -0.71978, 1.97135
1297++ ]
1298++ },
1299++ {
1300++ "ct": 5858,
1301++ "ccm":
1302++ [
1303++ 2.32392, -0.88421, -0.43971,
1304++ -0.63821, 2.58348, -0.94527,
1305++ -0.28541, -0.54112, 1.82653
1306++ ]
1307++ },
1308++ {
1309++ "ct": 7580,
1310++ "ccm":
1311++ [
1312++ 2.21175, -0.53242, -0.67933,
1313++ -0.57875, 3.07922, -1.50047,
1314++ -0.27709, -0.73338, 2.01048
1315++ ]
1316++ }
1317++ ]
1318++ }
1319++ },
1320++ {
1321++ "rpi.sharpen":
1322++ {
1323++ "threshold": 0.25,
1324++ "limit": 1.0,
1325++ "strength": 1.0
1326++ }
1327++ },
1328++ {
1329++ "rpi.hdr":
1330++ {
1331++ "Off":
1332++ {
1333++ "cadence": [ 0 ]
1334++ },
1335++ "MultiExposureUnmerged":
1336++ {
1337++ "cadence": [ 1, 2 ],
1338++ "channel_map":
1339++ {
1340++ "short": 1,
1341++ "long": 2
1342++ }
1343++ },
1344++ "SingleExposure":
1345++ {
1346++ "cadence": [ 1 ],
1347++ "channel_map":
1348++ {
1349++ "short": 1
1350++ },
1351++ "spatial_gain": 2.0,
1352++ "tonemap_enable": 1
1353++ },
1354++ "MultiExposure":
1355++ {
1356++ "cadence": [ 1, 2 ],
1357++ "channel_map":
1358++ {
1359++ "short": 1,
1360++ "long": 2
1361++ },
1362++ "stitch_enable": 1,
1363++ "spatial_gain": 2.0,
1364++ "tonemap_enable": 1
1365++ },
1366++ "Night":
1367++ {
1368++ "cadence": [ 3 ],
1369++ "channel_map":
1370++ {
1371++ "short": 3
1372++ },
1373++ "tonemap_enable": 1,
1374++ "tonemap":
1375++ [
1376++ 0, 0,
1377++ 5000, 20000,
1378++ 10000, 30000,
1379++ 20000, 47000,
1380++ 30000, 55000,
1381++ 65535, 65535
1382++ ]
1383++ }
1384++ }
1385++ }
1386++ ]
1387++}
1388+\ No newline at end of file
1389+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1390++++ b/src/ipa/rpi/pisp/data/imx219_noir.json 2024-11-25 21:08:37.638494238 +0530
1391+@@ -0,0 +1,1112 @@
1392++{
1393++ "version": 2.0,
1394++ "target": "pisp",
1395++ "algorithms": [
1396++ {
1397++ "rpi.black_level":
1398++ {
1399++ "black_level": 4096
1400++ }
1401++ },
1402++ {
1403++ "rpi.lux":
1404++ {
1405++ "reference_shutter_speed": 21965,
1406++ "reference_gain": 1.0,
1407++ "reference_aperture": 1.0,
1408++ "reference_lux": 800,
1409++ "reference_Y": 11460
1410++ }
1411++ },
1412++ {
1413++ "rpi.dpc":
1414++ {
1415++ "strength": 1
1416++ }
1417++ },
1418++ {
1419++ "rpi.noise":
1420++ {
1421++ "reference_constant": 0,
1422++ "reference_slope": 3.661
1423++ }
1424++ },
1425++ {
1426++ "rpi.geq":
1427++ {
1428++ "offset": 239,
1429++ "slope": 0.00766
1430++ }
1431++ },
1432++ {
1433++ "rpi.denoise":
1434++ {
1435++ "normal":
1436++ {
1437++ "sdn":
1438++ {
1439++ "deviation": 1.6,
1440++ "strength": 0.5,
1441++ "deviation2": 3.2,
1442++ "deviation_no_tdn": 3.2,
1443++ "strength_no_tdn": 0.75
1444++ },
1445++ "cdn":
1446++ {
1447++ "deviation": 200,
1448++ "strength": 0.3
1449++ },
1450++ "tdn":
1451++ {
1452++ "deviation": 0.8,
1453++ "threshold": 0.05
1454++ }
1455++ },
1456++ "hdr":
1457++ {
1458++ "sdn":
1459++ {
1460++ "deviation": 1.6,
1461++ "strength": 0.5,
1462++ "deviation2": 3.2,
1463++ "deviation_no_tdn": 3.2,
1464++ "strength_no_tdn": 0.75
1465++ },
1466++ "cdn":
1467++ {
1468++ "deviation": 200,
1469++ "strength": 0.3
1470++ },
1471++ "tdn":
1472++ {
1473++ "deviation": 1.3,
1474++ "threshold": 0.1
1475++ }
1476++ },
1477++ "night":
1478++ {
1479++ "sdn":
1480++ {
1481++ "deviation": 1.6,
1482++ "strength": 0.5,
1483++ "deviation2": 3.2,
1484++ "deviation_no_tdn": 3.2,
1485++ "strength_no_tdn": 0.75
1486++ },
1487++ "cdn":
1488++ {
1489++ "deviation": 200,
1490++ "strength": 0.3
1491++ },
1492++ "tdn":
1493++ {
1494++ "deviation": 1.3,
1495++ "threshold": 0.1
1496++ }
1497++ }
1498++ }
1499++ },
1500++ {
1501++ "rpi.awb":
1502++ {
1503++ "bayes": 0
1504++ }
1505++ },
1506++ {
1507++ "rpi.agc":
1508++ {
1509++ "channels": [
1510++ {
1511++ "comment": "Channel 0 is normal AGC",
1512++ "metering_modes":
1513++ {
1514++ "centre-weighted":
1515++ {
1516++ "weights":
1517++ [
1518++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1519++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1520++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1521++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1522++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1523++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1524++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1525++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
1526++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1527++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1528++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1529++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1530++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1531++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1532++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
1533++ ]
1534++ },
1535++ "spot":
1536++ {
1537++ "weights":
1538++ [
1539++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1540++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1541++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1542++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1543++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1544++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1545++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1546++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
1547++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1548++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1549++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1550++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1551++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1552++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1553++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1554++ ]
1555++ },
1556++ "matrix":
1557++ {
1558++ "weights":
1559++ [
1560++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1561++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1562++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1563++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1564++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1565++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1566++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1567++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1568++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1569++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1570++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1571++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1572++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1573++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1574++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1575++ ]
1576++ }
1577++ },
1578++ "exposure_modes":
1579++ {
1580++ "normal":
1581++ {
1582++ "shutter": [ 100, 10000, 30000, 60000, 66666 ],
1583++ "gain": [ 1.0, 1.5, 2.0, 4.0, 10.0 ]
1584++ },
1585++ "short":
1586++ {
1587++ "shutter": [ 100, 5000, 10000, 20000, 60000 ],
1588++ "gain": [ 1.0, 1.5, 2.0, 4.0, 10.0 ]
1589++ },
1590++ "long":
1591++ {
1592++ "shutter": [ 100, 10000, 30000, 60000, 90000, 120000 ],
1593++ "gain": [ 1.0, 1.5, 2.0, 4.0, 8.0, 12.0 ]
1594++ }
1595++ },
1596++ "constraint_modes":
1597++ {
1598++ "normal": [
1599++ {
1600++ "bound": "LOWER",
1601++ "q_lo": 0.98,
1602++ "q_hi": 1.0,
1603++ "y_target":
1604++ [
1605++ 0, 0.5,
1606++ 1000, 0.5
1607++ ]
1608++ }
1609++ ],
1610++ "highlight": [
1611++ {
1612++ "bound": "LOWER",
1613++ "q_lo": 0.98,
1614++ "q_hi": 1.0,
1615++ "y_target":
1616++ [
1617++ 0, 0.5,
1618++ 1000, 0.5
1619++ ]
1620++ },
1621++ {
1622++ "bound": "UPPER",
1623++ "q_lo": 0.98,
1624++ "q_hi": 1.0,
1625++ "y_target":
1626++ [
1627++ 0, 0.8,
1628++ 1000, 0.8
1629++ ]
1630++ }
1631++ ],
1632++ "shadows": [
1633++ {
1634++ "bound": "LOWER",
1635++ "q_lo": 0.0,
1636++ "q_hi": 0.5,
1637++ "y_target":
1638++ [
1639++ 0, 0.17,
1640++ 1000, 0.17
1641++ ]
1642++ }
1643++ ]
1644++ },
1645++ "y_target":
1646++ [
1647++ 0, 0.16,
1648++ 1000, 0.165,
1649++ 10000, 0.17
1650++ ]
1651++ },
1652++ {
1653++ "comment": "Channel 1 is the HDR short channel",
1654++ "desaturate": 0,
1655++ "metering_modes":
1656++ {
1657++ "centre-weighted":
1658++ {
1659++ "weights":
1660++ [
1661++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1662++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1663++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1664++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1665++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1666++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1667++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1668++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
1669++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1670++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1671++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1672++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1673++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1674++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1675++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
1676++ ]
1677++ },
1678++ "spot":
1679++ {
1680++ "weights":
1681++ [
1682++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1683++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1684++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1685++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1686++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1687++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1688++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1689++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
1690++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1691++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1692++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1693++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1694++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1695++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1696++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1697++ ]
1698++ },
1699++ "matrix":
1700++ {
1701++ "weights":
1702++ [
1703++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1704++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1705++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1706++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1707++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1708++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1709++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1710++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1711++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1712++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1713++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1714++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1715++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1716++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1717++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1718++ ]
1719++ }
1720++ },
1721++ "exposure_modes":
1722++ {
1723++ "normal":
1724++ {
1725++ "shutter": [ 100, 15000, 30000 ],
1726++ "gain": [ 1.0, 1.0, 2.0 ]
1727++ },
1728++ "short":
1729++ {
1730++ "shutter": [ 100, 15000, 30000 ],
1731++ "gain": [ 1.0, 2.0, 2.0 ]
1732++ },
1733++ "long":
1734++ {
1735++ "shutter": [ 100, 15000, 60000 ],
1736++ "gain": [ 1.0, 1.0, 1.0 ]
1737++ }
1738++ },
1739++ "constraint_modes":
1740++ {
1741++ "normal": [
1742++ {
1743++ "bound": "LOWER",
1744++ "q_lo": 0.0,
1745++ "q_hi": 0.2,
1746++ "y_target":
1747++ [
1748++ 0, 0.02,
1749++ 1000, 0.02
1750++ ]
1751++ },
1752++ {
1753++ "bound": "UPPER",
1754++ "q_lo": 0.98,
1755++ "q_hi": 1.0,
1756++ "y_target":
1757++ [
1758++ 0, 0.7,
1759++ 1000, 0.7
1760++ ]
1761++ },
1762++ {
1763++ "bound": "LOWER",
1764++ "q_lo": 0.0,
1765++ "q_hi": 0.2,
1766++ "y_target":
1767++ [
1768++ 0, 0.01,
1769++ 1000, 0.01
1770++ ]
1771++ },
1772++ {
1773++ "bound": "UPPER",
1774++ "q_lo": 0.9,
1775++ "q_hi": 1.0,
1776++ "y_target":
1777++ [
1778++ 0, 0.7,
1779++ 1000, 0.7
1780++ ]
1781++ },
1782++ {
1783++ "bound": "LOWER",
1784++ "q_lo": 0.0,
1785++ "q_hi": 0.2,
1786++ "y_target":
1787++ [
1788++ 0, 0.005,
1789++ 1000, 0.005
1790++ ]
1791++ }
1792++ ],
1793++ "highlight": [
1794++ {
1795++ "bound": "LOWER",
1796++ "q_lo": 0.95,
1797++ "q_hi": 1.0,
1798++ "y_target":
1799++ [
1800++ 0, 0.5,
1801++ 1000, 0.5
1802++ ]
1803++ },
1804++ {
1805++ "bound": "UPPER",
1806++ "q_lo": 0.95,
1807++ "q_hi": 1.0,
1808++ "y_target":
1809++ [
1810++ 0, 0.7,
1811++ 1000, 0.7
1812++ ]
1813++ },
1814++ {
1815++ "bound": "LOWER",
1816++ "q_lo": 0.0,
1817++ "q_hi": 0.2,
1818++ "y_target":
1819++ [
1820++ 0, 0.002,
1821++ 1000, 0.002
1822++ ]
1823++ }
1824++ ],
1825++ "shadows": [
1826++ {
1827++ "bound": "LOWER",
1828++ "q_lo": 0.95,
1829++ "q_hi": 1.0,
1830++ "y_target":
1831++ [
1832++ 0, 0.5,
1833++ 1000, 0.5
1834++ ]
1835++ },
1836++ {
1837++ "bound": "UPPER",
1838++ "q_lo": 0.95,
1839++ "q_hi": 1.0,
1840++ "y_target":
1841++ [
1842++ 0, 0.7,
1843++ 1000, 0.7
1844++ ]
1845++ },
1846++ {
1847++ "bound": "LOWER",
1848++ "q_lo": 0.0,
1849++ "q_hi": 0.2,
1850++ "y_target":
1851++ [
1852++ 0, 0.002,
1853++ 1000, 0.002
1854++ ]
1855++ }
1856++ ]
1857++ },
1858++ "y_target":
1859++ [
1860++ 0, 0.19,
1861++ 1000, 0.19,
1862++ 10000, 0.19
1863++ ]
1864++ },
1865++ {
1866++ "comment": "Channel 2 is the HDR long channel",
1867++ "desaturate": 0,
1868++ "metering_modes":
1869++ {
1870++ "centre-weighted":
1871++ {
1872++ "weights":
1873++ [
1874++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1875++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1876++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1877++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1878++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1879++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1880++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1881++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
1882++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1883++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1884++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1885++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1886++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1887++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1888++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
1889++ ]
1890++ },
1891++ "spot":
1892++ {
1893++ "weights":
1894++ [
1895++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1896++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1897++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1898++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1899++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1900++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1901++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1902++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
1903++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
1904++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1905++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1906++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1907++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1908++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1909++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1910++ ]
1911++ },
1912++ "matrix":
1913++ {
1914++ "weights":
1915++ [
1916++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1917++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1918++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1919++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1920++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1921++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1922++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1923++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1924++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1925++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1926++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1927++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1928++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1929++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1930++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1931++ ]
1932++ }
1933++ },
1934++ "exposure_modes":
1935++ {
1936++ "normal":
1937++ {
1938++ "shutter": [ 100, 20000, 30000, 60000 ],
1939++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
1940++ }
1941++ },
1942++ "constraint_modes":
1943++ {
1944++ "normal": [ ],
1945++ "highlight": [ ],
1946++ "shadows": [ ]
1947++ },
1948++ "channel_constraints": [
1949++ {
1950++ "bound": "UPPER",
1951++ "channel": 4,
1952++ "factor": 8
1953++ },
1954++ {
1955++ "bound": "LOWER",
1956++ "channel": 4,
1957++ "factor": 2
1958++ }
1959++ ],
1960++ "y_target":
1961++ [
1962++ 0, 0.16,
1963++ 1000, 0.165,
1964++ 10000, 0.17
1965++ ]
1966++ },
1967++ {
1968++ "comment": "Channel 3 is the night mode channel",
1969++ "base_ev": 0.33,
1970++ "metering_modes":
1971++ {
1972++ "centre-weighted":
1973++ {
1974++ "weights":
1975++ [
1976++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1977++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1978++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1979++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1980++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1981++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1982++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1983++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
1984++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
1985++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
1986++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
1987++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
1988++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1989++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
1990++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
1991++ ]
1992++ },
1993++ "spot":
1994++ {
1995++ "weights":
1996++ [
1997++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1998++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1999++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2000++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2001++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2002++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2003++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2004++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
2005++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2006++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2007++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2008++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2009++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2010++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2011++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2012++ ]
2013++ },
2014++ "matrix":
2015++ {
2016++ "weights":
2017++ [
2018++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2019++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2020++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2021++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2022++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2023++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2024++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2025++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2026++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2027++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2028++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2029++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2030++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2031++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2032++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2033++ ]
2034++ }
2035++ },
2036++ "exposure_modes":
2037++ {
2038++ "normal":
2039++ {
2040++ "shutter": [ 100, 20000, 66666 ],
2041++ "gain": [ 1.0, 2.0, 4.0 ]
2042++ },
2043++ "short":
2044++ {
2045++ "shutter": [ 100, 20000, 33333 ],
2046++ "gain": [ 1.0, 2.0, 4.0 ]
2047++ },
2048++ "long":
2049++ {
2050++ "shutter": [ 100, 20000, 66666, 120000 ],
2051++ "gain": [ 1.0, 2.0, 4.0, 4.0 ]
2052++ }
2053++ },
2054++ "constraint_modes":
2055++ {
2056++ "normal": [
2057++ {
2058++ "bound": "LOWER",
2059++ "q_lo": 0.98,
2060++ "q_hi": 1.0,
2061++ "y_target":
2062++ [
2063++ 0, 0.5,
2064++ 1000, 0.5
2065++ ]
2066++ }
2067++ ],
2068++ "highlight": [
2069++ {
2070++ "bound": "LOWER",
2071++ "q_lo": 0.98,
2072++ "q_hi": 1.0,
2073++ "y_target":
2074++ [
2075++ 0, 0.5,
2076++ 1000, 0.5
2077++ ]
2078++ },
2079++ {
2080++ "bound": "UPPER",
2081++ "q_lo": 0.98,
2082++ "q_hi": 1.0,
2083++ "y_target":
2084++ [
2085++ 0, 0.8,
2086++ 1000, 0.8
2087++ ]
2088++ }
2089++ ],
2090++ "shadows": [
2091++ {
2092++ "bound": "LOWER",
2093++ "q_lo": 0.98,
2094++ "q_hi": 1.0,
2095++ "y_target":
2096++ [
2097++ 0, 0.5,
2098++ 1000, 0.5
2099++ ]
2100++ }
2101++ ]
2102++ },
2103++ "y_target":
2104++ [
2105++ 0, 0.16,
2106++ 1000, 0.165,
2107++ 10000, 0.17
2108++ ]
2109++ }
2110++ ]
2111++ }
2112++ },
2113++ {
2114++ "rpi.alsc":
2115++ {
2116++ "omega": 1.3,
2117++ "n_iter": 100,
2118++ "luminance_strength": 0.8,
2119++ "calibrations_Cr": [
2120++ {
2121++ "ct": 3000,
2122++ "table":
2123++ [
2124++ 1.418, 1.428, 1.446, 1.454, 1.454, 1.451, 1.441, 1.428, 1.411, 1.391, 1.371, 1.349, 1.334, 1.327, 1.325, 1.325, 1.325, 1.325, 1.331, 1.344, 1.363, 1.383, 1.402, 1.418, 1.433, 1.446, 1.452, 1.453, 1.446, 1.435, 1.415, 1.404,
2125++ 1.428, 1.442, 1.453, 1.455, 1.454, 1.447, 1.431, 1.413, 1.392, 1.371, 1.349, 1.331, 1.318, 1.307, 1.299, 1.299, 1.299, 1.303, 1.313, 1.328, 1.344, 1.363, 1.383, 1.404, 1.424, 1.439, 1.451, 1.453, 1.453, 1.445, 1.431, 1.415,
2126++ 1.436, 1.448, 1.453, 1.455, 1.449, 1.435, 1.415, 1.393, 1.369, 1.345, 1.322, 1.303, 1.287, 1.276, 1.269, 1.268, 1.268, 1.272, 1.283, 1.298, 1.316, 1.337, 1.362, 1.384, 1.406, 1.427, 1.444, 1.454, 1.454, 1.452, 1.438, 1.426,
2127++ 1.441, 1.451, 1.454, 1.451, 1.439, 1.422, 1.396, 1.372, 1.345, 1.319, 1.295, 1.274, 1.257, 1.245, 1.239, 1.238, 1.238, 1.245, 1.255, 1.269, 1.289, 1.311, 1.336, 1.362, 1.388, 1.412, 1.433, 1.448, 1.454, 1.453, 1.445, 1.433,
2128++ 1.445, 1.452, 1.452, 1.445, 1.428, 1.405, 1.379, 1.349, 1.319, 1.295, 1.269, 1.247, 1.229, 1.219, 1.212, 1.211, 1.211, 1.217, 1.228, 1.242, 1.261, 1.286, 1.311, 1.339, 1.367, 1.395, 1.419, 1.439, 1.452, 1.452, 1.451, 1.436,
2129++ 1.448, 1.451, 1.451, 1.435, 1.414, 1.387, 1.358, 1.327, 1.296, 1.269, 1.245, 1.222, 1.205, 1.193, 1.187, 1.185, 1.186, 1.191, 1.202, 1.217, 1.237, 1.261, 1.286, 1.316, 1.346, 1.378, 1.404, 1.429, 1.445, 1.451, 1.451, 1.442,
2130++ 1.448, 1.448, 1.445, 1.427, 1.401, 1.371, 1.338, 1.306, 1.274, 1.245, 1.222, 1.199, 1.183, 1.171, 1.164, 1.162, 1.162, 1.168, 1.181, 1.194, 1.215, 1.237, 1.264, 1.294, 1.325, 1.359, 1.389, 1.418, 1.441, 1.449, 1.449, 1.443,
2131++ 1.449, 1.448, 1.438, 1.415, 1.387, 1.352, 1.318, 1.284, 1.252, 1.223, 1.199, 1.179, 1.161, 1.149, 1.142, 1.142, 1.142, 1.149, 1.159, 1.174, 1.194, 1.215, 1.242, 1.272, 1.307, 1.341, 1.376, 1.405, 1.431, 1.447, 1.447, 1.444,
2132++ 1.448, 1.447, 1.431, 1.405, 1.373, 1.336, 1.301, 1.264, 1.234, 1.204, 1.179, 1.161, 1.143, 1.131, 1.124, 1.123, 1.123, 1.131, 1.141, 1.156, 1.174, 1.197, 1.224, 1.254, 1.288, 1.324, 1.361, 1.394, 1.423, 1.442, 1.444, 1.444,
2133++ 1.447, 1.442, 1.424, 1.393, 1.359, 1.322, 1.284, 1.248, 1.216, 1.187, 1.162, 1.143, 1.128, 1.115, 1.109, 1.108, 1.108, 1.113, 1.124, 1.139, 1.156, 1.179, 1.206, 1.236, 1.272, 1.309, 1.347, 1.382, 1.411, 1.435, 1.443, 1.444,
2134++ 1.444, 1.439, 1.417, 1.383, 1.347, 1.308, 1.271, 1.233, 1.201, 1.173, 1.147, 1.128, 1.115, 1.101, 1.095, 1.093, 1.093, 1.099, 1.111, 1.124, 1.142, 1.165, 1.191, 1.222, 1.258, 1.296, 1.333, 1.372, 1.404, 1.429, 1.441, 1.442,
2135++ 1.443, 1.434, 1.409, 1.375, 1.336, 1.297, 1.257, 1.221, 1.189, 1.159, 1.136, 1.116, 1.101, 1.092, 1.083, 1.082, 1.082, 1.089, 1.099, 1.111, 1.131, 1.153, 1.181, 1.211, 1.246, 1.284, 1.324, 1.361, 1.398, 1.425, 1.441, 1.441,
2136++ 1.443, 1.431, 1.405, 1.369, 1.328, 1.287, 1.247, 1.211, 1.178, 1.149, 1.126, 1.107, 1.092, 1.083, 1.075, 1.073, 1.073, 1.082, 1.089, 1.101, 1.121, 1.143, 1.171, 1.201, 1.237, 1.274, 1.314, 1.353, 1.389, 1.421, 1.439, 1.441,
2137++ 1.442, 1.429, 1.401, 1.364, 1.323, 1.279, 1.241, 1.205, 1.172, 1.144, 1.119, 1.101, 1.085, 1.075, 1.071, 1.067, 1.067, 1.073, 1.082, 1.096, 1.114, 1.136, 1.163, 1.194, 1.229, 1.268, 1.308, 1.348, 1.387, 1.417, 1.439, 1.439,
2138++ 1.443, 1.429, 1.399, 1.362, 1.319, 1.276, 1.237, 1.199, 1.169, 1.141, 1.115, 1.096, 1.081, 1.071, 1.066, 1.063, 1.066, 1.068, 1.078, 1.092, 1.109, 1.132, 1.159, 1.191, 1.226, 1.263, 1.304, 1.346, 1.384, 1.416, 1.438, 1.439,
2139++ 1.443, 1.428, 1.399, 1.361, 1.319, 1.276, 1.236, 1.199, 1.167, 1.139, 1.115, 1.096, 1.081, 1.071, 1.064, 1.062, 1.062, 1.067, 1.077, 1.091, 1.109, 1.131, 1.158, 1.189, 1.224, 1.262, 1.303, 1.345, 1.383, 1.416, 1.438, 1.439,
2140++ 1.444, 1.429, 1.399, 1.361, 1.319, 1.276, 1.236, 1.199, 1.167, 1.139, 1.116, 1.096, 1.081, 1.071, 1.064, 1.063, 1.063, 1.067, 1.077, 1.091, 1.109, 1.131, 1.159, 1.189, 1.224, 1.262, 1.303, 1.345, 1.384, 1.416, 1.438, 1.441,
2141++ 1.444, 1.431, 1.402, 1.364, 1.322, 1.281, 1.239, 1.202, 1.171, 1.142, 1.118, 1.099, 1.084, 1.073, 1.069, 1.065, 1.067, 1.071, 1.079, 1.094, 1.112, 1.135, 1.163, 1.191, 1.227, 1.265, 1.307, 1.348, 1.386, 1.418, 1.438, 1.441,
2142++ 1.447, 1.433, 1.406, 1.369, 1.328, 1.286, 1.244, 1.209, 1.177, 1.148, 1.124, 1.105, 1.089, 1.081, 1.073, 1.071, 1.071, 1.079, 1.085, 1.099, 1.118, 1.141, 1.168, 1.198, 1.233, 1.271, 1.312, 1.352, 1.391, 1.422, 1.441, 1.444,
2143++ 1.448, 1.438, 1.412, 1.376, 1.335, 1.295, 1.255, 1.218, 1.186, 1.157, 1.134, 1.113, 1.098, 1.089, 1.081, 1.079, 1.079, 1.085, 1.094, 1.107, 1.125, 1.149, 1.175, 1.207, 1.242, 1.281, 1.319, 1.359, 1.396, 1.425, 1.445, 1.447,
2144++ 1.449, 1.443, 1.417, 1.384, 1.345, 1.305, 1.266, 1.229, 1.197, 1.169, 1.145, 1.124, 1.111, 1.098, 1.091, 1.089, 1.089, 1.094, 1.107, 1.118, 1.137, 1.159, 1.187, 1.218, 1.253, 1.291, 1.329, 1.369, 1.405, 1.433, 1.447, 1.449,
2145++ 1.453, 1.449, 1.425, 1.395, 1.358, 1.318, 1.281, 1.244, 1.211, 1.183, 1.158, 1.138, 1.124, 1.111, 1.104, 1.103, 1.103, 1.107, 1.118, 1.133, 1.151, 1.174, 1.201, 1.232, 1.267, 1.304, 1.344, 1.379, 1.413, 1.437, 1.449, 1.449,
2146++ 1.457, 1.453, 1.434, 1.405, 1.371, 1.335, 1.297, 1.261, 1.229, 1.199, 1.174, 1.155, 1.138, 1.126, 1.119, 1.117, 1.117, 1.124, 1.133, 1.149, 1.167, 1.189, 1.217, 1.248, 1.284, 1.319, 1.357, 1.393, 1.423, 1.444, 1.452, 1.452,
2147++ 1.459, 1.457, 1.443, 1.418, 1.385, 1.352, 1.314, 1.279, 1.246, 1.218, 1.193, 1.174, 1.155, 1.144, 1.137, 1.136, 1.136, 1.141, 1.151, 1.167, 1.187, 1.208, 1.236, 1.267, 1.301, 1.337, 1.373, 1.405, 1.434, 1.453, 1.455, 1.455,
2148++ 1.461, 1.461, 1.454, 1.429, 1.401, 1.369, 1.333, 1.301, 1.269, 1.239, 1.216, 1.193, 1.177, 1.165, 1.158, 1.156, 1.156, 1.161, 1.171, 1.187, 1.208, 1.229, 1.258, 1.288, 1.321, 1.356, 1.389, 1.419, 1.445, 1.459, 1.459, 1.455,
2149++ 1.462, 1.462, 1.459, 1.442, 1.418, 1.386, 1.354, 1.322, 1.292, 1.262, 1.239, 1.216, 1.199, 1.187, 1.179, 1.178, 1.178, 1.184, 1.194, 1.208, 1.229, 1.253, 1.279, 1.309, 1.342, 1.375, 1.406, 1.433, 1.452, 1.464, 1.464, 1.454,
2150++ 1.461, 1.465, 1.465, 1.454, 1.431, 1.405, 1.376, 1.346, 1.316, 1.288, 1.262, 1.242, 1.223, 1.212, 1.205, 1.203, 1.203, 1.208, 1.218, 1.234, 1.253, 1.279, 1.305, 1.334, 1.363, 1.393, 1.421, 1.445, 1.461, 1.465, 1.464, 1.452,
2151++ 1.459, 1.465, 1.466, 1.461, 1.443, 1.421, 1.395, 1.368, 1.341, 1.316, 1.288, 1.268, 1.251, 1.238, 1.232, 1.229, 1.229, 1.235, 1.246, 1.261, 1.279, 1.305, 1.331, 1.356, 1.385, 1.411, 1.435, 1.454, 1.466, 1.466, 1.464, 1.451,
2152++ 1.454, 1.465, 1.467, 1.466, 1.456, 1.436, 1.414, 1.389, 1.367, 1.341, 1.318, 1.297, 1.279, 1.269, 1.261, 1.259, 1.259, 1.265, 1.274, 1.288, 1.308, 1.331, 1.355, 1.381, 1.404, 1.428, 1.447, 1.462, 1.468, 1.467, 1.457, 1.445,
2153++ 1.447, 1.459, 1.466, 1.467, 1.463, 1.451, 1.434, 1.411, 1.389, 1.367, 1.344, 1.325, 1.311, 1.297, 1.292, 1.289, 1.289, 1.295, 1.303, 1.317, 1.336, 1.356, 1.381, 1.402, 1.423, 1.441, 1.457, 1.467, 1.468, 1.463, 1.451, 1.439,
2154++ 1.438, 1.449, 1.462, 1.464, 1.464, 1.459, 1.446, 1.429, 1.408, 1.388, 1.369, 1.353, 1.339, 1.329, 1.321, 1.321, 1.321, 1.325, 1.333, 1.348, 1.362, 1.379, 1.401, 1.421, 1.439, 1.454, 1.463, 1.465, 1.465, 1.456, 1.442, 1.427,
2155++ 1.429, 1.439, 1.454, 1.464, 1.464, 1.459, 1.449, 1.435, 1.421, 1.402, 1.385, 1.369, 1.353, 1.341, 1.338, 1.337, 1.337, 1.338, 1.348, 1.362, 1.378, 1.395, 1.411, 1.429, 1.445, 1.455, 1.463, 1.464, 1.457, 1.447, 1.427, 1.419
2156++ ]
2157++ },
2158++ {
2159++ "ct": 5000,
2160++ "table":
2161++ [
2162++ 2.163, 2.177, 2.194, 2.196, 2.197, 2.192, 2.181, 2.161, 2.139, 2.113, 2.088, 2.063, 2.047, 2.041, 2.036, 2.036, 2.036, 2.037, 2.046, 2.059, 2.083, 2.113, 2.135, 2.158, 2.181, 2.193, 2.205, 2.205, 2.202, 2.189, 2.171, 2.158,
2163++ 2.169, 2.184, 2.195, 2.196, 2.194, 2.182, 2.163, 2.141, 2.116, 2.088, 2.063, 2.042, 2.025, 2.013, 2.004, 2.004, 2.006, 2.011, 2.022, 2.038, 2.059, 2.083, 2.113, 2.137, 2.162, 2.182, 2.197, 2.204, 2.203, 2.199, 2.183, 2.171,
2164++ 2.177, 2.187, 2.193, 2.193, 2.184, 2.166, 2.142, 2.116, 2.087, 2.057, 2.033, 2.008, 1.991, 1.977, 1.969, 1.969, 1.969, 1.975, 1.988, 2.006, 2.028, 2.055, 2.083, 2.114, 2.139, 2.166, 2.187, 2.199, 2.202, 2.201, 2.189, 2.179,
2165++ 2.183, 2.189, 2.192, 2.186, 2.172, 2.146, 2.119, 2.089, 2.058, 2.026, 2.001, 1.975, 1.956, 1.942, 1.934, 1.932, 1.933, 1.941, 1.955, 1.971, 1.995, 2.023, 2.055, 2.084, 2.119, 2.146, 2.171, 2.191, 2.201, 2.201, 2.194, 2.183,
2166++ 2.186, 2.189, 2.189, 2.177, 2.158, 2.127, 2.096, 2.059, 2.026, 1.998, 1.969, 1.944, 1.925, 1.911, 1.901, 1.901, 1.903, 1.912, 1.924, 1.941, 1.964, 1.995, 2.023, 2.058, 2.091, 2.126, 2.155, 2.181, 2.195, 2.199, 2.198, 2.188,
2167++ 2.189, 2.189, 2.184, 2.166, 2.138, 2.108, 2.071, 2.036, 1.999, 1.969, 1.941, 1.914, 1.894, 1.879, 1.871, 1.871, 1.872, 1.879, 1.893, 1.913, 1.937, 1.964, 1.997, 2.029, 2.065, 2.104, 2.137, 2.169, 2.187, 2.199, 2.199, 2.189,
2168++ 2.187, 2.186, 2.176, 2.154, 2.123, 2.087, 2.044, 2.011, 1.974, 1.941, 1.913, 1.887, 1.868, 1.852, 1.844, 1.843, 1.844, 1.852, 1.866, 1.885, 1.912, 1.937, 1.972, 2.004, 2.042, 2.081, 2.119, 2.154, 2.179, 2.195, 2.196, 2.193,
2169++ 2.187, 2.181, 2.167, 2.141, 2.103, 2.062, 2.023, 1.984, 1.947, 1.916, 1.887, 1.864, 1.841, 1.828, 1.821, 1.819, 1.819, 1.828, 1.842, 1.862, 1.885, 1.913, 1.945, 1.982, 2.021, 2.058, 2.102, 2.137, 2.168, 2.192, 2.193, 2.193,
2170++ 2.182, 2.181, 2.161, 2.127, 2.083, 2.044, 2.002, 1.961, 1.924, 1.891, 1.864, 1.841, 1.819, 1.806, 1.797, 1.797, 1.797, 1.805, 1.819, 1.841, 1.862, 1.892, 1.924, 1.959, 1.999, 2.041, 2.082, 2.123, 2.161, 2.185, 2.191, 2.192,
2171++ 2.182, 2.172, 2.149, 2.112, 2.069, 2.026, 1.982, 1.941, 1.904, 1.871, 1.841, 1.819, 1.799, 1.785, 1.776, 1.776, 1.778, 1.784, 1.798, 1.819, 1.841, 1.869, 1.903, 1.939, 1.977, 2.021, 2.067, 2.108, 2.145, 2.174, 2.189, 2.191,
2172++ 2.181, 2.167, 2.139, 2.098, 2.056, 2.006, 1.965, 1.921, 1.883, 1.851, 1.823, 1.799, 1.783, 1.767, 1.759, 1.758, 1.758, 1.767, 1.783, 1.798, 1.825, 1.851, 1.883, 1.919, 1.959, 2.004, 2.049, 2.094, 2.136, 2.167, 2.187, 2.189,
2173++ 2.179, 2.163, 2.131, 2.087, 2.041, 1.994, 1.948, 1.907, 1.871, 1.835, 1.806, 1.784, 1.767, 1.754, 1.744, 1.742, 1.742, 1.752, 1.767, 1.783, 1.808, 1.838, 1.869, 1.905, 1.945, 1.989, 2.036, 2.083, 2.128, 2.159, 2.183, 2.187,
2174++ 2.178, 2.161, 2.126, 2.082, 2.032, 1.982, 1.936, 1.896, 1.857, 1.823, 1.795, 1.772, 1.754, 1.744, 1.732, 1.731, 1.732, 1.742, 1.752, 1.771, 1.796, 1.824, 1.857, 1.895, 1.934, 1.977, 2.024, 2.071, 2.116, 2.154, 2.181, 2.185,
2175++ 2.177, 2.157, 2.121, 2.074, 2.025, 1.973, 1.927, 1.886, 1.849, 1.815, 1.787, 1.765, 1.746, 1.732, 1.725, 1.722, 1.724, 1.732, 1.743, 1.762, 1.786, 1.813, 1.848, 1.886, 1.924, 1.969, 2.017, 2.066, 2.111, 2.153, 2.179, 2.183,
2176++ 2.177, 2.155, 2.119, 2.072, 2.022, 1.969, 1.925, 1.881, 1.844, 1.811, 1.782, 1.758, 1.739, 1.725, 1.721, 1.717, 1.721, 1.724, 1.739, 1.757, 1.781, 1.809, 1.842, 1.879, 1.921, 1.965, 2.012, 2.062, 2.108, 2.151, 2.179, 2.182,
2177++ 2.177, 2.156, 2.121, 2.071, 2.021, 1.968, 1.922, 1.879, 1.842, 1.811, 1.781, 1.757, 1.739, 1.725, 1.717, 1.715, 1.715, 1.723, 1.737, 1.757, 1.779, 1.808, 1.841, 1.877, 1.918, 1.963, 2.011, 2.061, 2.107, 2.148, 2.179, 2.183,
2178++ 2.178, 2.157, 2.121, 2.072, 2.021, 1.969, 1.922, 1.881, 1.842, 1.811, 1.781, 1.758, 1.739, 1.726, 1.718, 1.717, 1.718, 1.723, 1.737, 1.757, 1.781, 1.809, 1.841, 1.877, 1.918, 1.964, 2.012, 2.061, 2.108, 2.149, 2.179, 2.183,
2179++ 2.178, 2.159, 2.124, 2.074, 2.024, 1.974, 1.926, 1.885, 1.847, 1.813, 1.784, 1.762, 1.743, 1.731, 1.725, 1.719, 1.723, 1.728, 1.742, 1.762, 1.785, 1.814, 1.847, 1.881, 1.922, 1.966, 2.017, 2.065, 2.109, 2.151, 2.181, 2.184,
2180++ 2.181, 2.163, 2.129, 2.082, 2.032, 1.982, 1.934, 1.891, 1.854, 1.822, 1.794, 1.769, 1.751, 1.739, 1.731, 1.727, 1.728, 1.739, 1.747, 1.768, 1.791, 1.821, 1.852, 1.889, 1.929, 1.972, 2.022, 2.071, 2.117, 2.155, 2.182, 2.189,
2181++ 2.184, 2.169, 2.135, 2.091, 2.041, 1.994, 1.947, 1.902, 1.865, 1.833, 1.805, 1.779, 1.762, 1.751, 1.739, 1.739, 1.739, 1.747, 1.761, 1.779, 1.803, 1.831, 1.864, 1.898, 1.941, 1.984, 2.033, 2.079, 2.123, 2.163, 2.188, 2.193,
2182++ 2.185, 2.174, 2.142, 2.099, 2.054, 2.004, 1.959, 1.917, 1.879, 1.846, 1.819, 1.794, 1.779, 1.762, 1.754, 1.753, 1.753, 1.761, 1.777, 1.793, 1.816, 1.843, 1.877, 1.913, 1.953, 1.995, 2.043, 2.091, 2.135, 2.169, 2.191, 2.196,
2183++ 2.191, 2.179, 2.154, 2.118, 2.069, 2.023, 1.977, 1.935, 1.898, 1.865, 1.834, 1.813, 1.794, 1.779, 1.769, 1.769, 1.769, 1.777, 1.793, 1.809, 1.834, 1.863, 1.895, 1.929, 1.972, 2.015, 2.061, 2.105, 2.145, 2.178, 2.195, 2.199,
2184++ 2.197, 2.188, 2.166, 2.129, 2.087, 2.041, 1.997, 1.956, 1.918, 1.884, 1.855, 1.834, 1.813, 1.798, 1.788, 1.788, 1.788, 1.796, 1.809, 1.832, 1.853, 1.881, 1.912, 1.949, 1.991, 2.033, 2.076, 2.119, 2.159, 2.187, 2.202, 2.205,
2185++ 2.202, 2.197, 2.176, 2.148, 2.106, 2.065, 2.021, 1.979, 1.943, 1.909, 1.879, 1.855, 1.835, 1.819, 1.811, 1.811, 1.811, 1.818, 1.832, 1.853, 1.875, 1.904, 1.937, 1.972, 2.013, 2.055, 2.097, 2.138, 2.175, 2.197, 2.206, 2.207,
2186++ 2.205, 2.202, 2.189, 2.162, 2.126, 2.084, 2.044, 2.004, 1.967, 1.935, 1.907, 1.879, 1.861, 1.845, 1.838, 1.835, 1.835, 1.844, 1.855, 1.875, 1.902, 1.928, 1.961, 1.998, 2.033, 2.076, 2.118, 2.155, 2.186, 2.205, 2.208, 2.208,
2187++ 2.207, 2.205, 2.195, 2.175, 2.145, 2.108, 2.069, 2.029, 1.996, 1.963, 1.934, 1.908, 1.885, 1.872, 1.864, 1.863, 1.863, 1.869, 1.884, 1.902, 1.928, 1.956, 1.989, 2.023, 2.059, 2.099, 2.137, 2.172, 2.199, 2.212, 2.213, 2.209,
2188++ 2.207, 2.207, 2.203, 2.188, 2.162, 2.128, 2.094, 2.058, 2.023, 1.993, 1.963, 1.936, 1.916, 1.899, 1.893, 1.892, 1.893, 1.899, 1.912, 1.929, 1.956, 1.986, 2.016, 2.049, 2.084, 2.121, 2.156, 2.187, 2.208, 2.215, 2.215, 2.208,
2189++ 2.205, 2.208, 2.209, 2.199, 2.178, 2.149, 2.117, 2.083, 2.052, 2.023, 1.993, 1.967, 1.947, 1.933, 1.925, 1.922, 1.922, 1.929, 1.943, 1.961, 1.986, 2.015, 2.045, 2.076, 2.109, 2.143, 2.173, 2.198, 2.214, 2.218, 2.216, 2.205,
2190++ 2.201, 2.207, 2.211, 2.211, 2.193, 2.168, 2.141, 2.112, 2.082, 2.052, 2.025, 2.001, 1.981, 1.967, 1.959, 1.958, 1.958, 1.967, 1.975, 1.992, 2.018, 2.046, 2.076, 2.105, 2.136, 2.163, 2.189, 2.208, 2.217, 2.217, 2.212, 2.203,
2191++ 2.194, 2.204, 2.212, 2.213, 2.203, 2.187, 2.165, 2.139, 2.112, 2.083, 2.055, 2.034, 2.016, 2.001, 1.993, 1.993, 1.994, 1.999, 2.011, 2.027, 2.051, 2.077, 2.105, 2.133, 2.158, 2.181, 2.202, 2.217, 2.218, 2.218, 2.206, 2.193,
2192++ 2.185, 2.198, 2.213, 2.214, 2.212, 2.201, 2.184, 2.163, 2.135, 2.111, 2.089, 2.071, 2.052, 2.039, 2.032, 2.031, 2.031, 2.036, 2.048, 2.065, 2.085, 2.106, 2.131, 2.155, 2.178, 2.198, 2.212, 2.219, 2.219, 2.215, 2.201, 2.185,
2193++ 2.176, 2.191, 2.208, 2.217, 2.216, 2.205, 2.195, 2.177, 2.156, 2.133, 2.109, 2.089, 2.071, 2.055, 2.053, 2.053, 2.053, 2.057, 2.065, 2.085, 2.105, 2.123, 2.149, 2.171, 2.192, 2.205, 2.217, 2.219, 2.219, 2.202, 2.185, 2.181
2194++ ]
2195++ }
2196++ ],
2197++ "calibrations_Cb": [
2198++ {
2199++ "ct": 3000,
2200++ "table":
2201++ [
2202++ 2.518, 2.513, 2.503, 2.496, 2.488, 2.484, 2.485, 2.485, 2.486, 2.487, 2.487, 2.489, 2.494, 2.496, 2.496, 2.497, 2.499, 2.499, 2.496, 2.495, 2.492, 2.491, 2.491, 2.491, 2.492, 2.493, 2.495, 2.501, 2.508, 2.516, 2.528, 2.533,
2203++ 2.515, 2.508, 2.495, 2.487, 2.483, 2.481, 2.482, 2.483, 2.485, 2.487, 2.489, 2.491, 2.495, 2.497, 2.498, 2.501, 2.502, 2.502, 2.499, 2.496, 2.494, 2.491, 2.491, 2.489, 2.489, 2.491, 2.493, 2.496, 2.502, 2.511, 2.521, 2.531,
2204++ 2.507, 2.495, 2.486, 2.482, 2.478, 2.477, 2.481, 2.482, 2.484, 2.488, 2.491, 2.495, 2.499, 2.502, 2.506, 2.508, 2.509, 2.508, 2.505, 2.501, 2.497, 2.493, 2.491, 2.489, 2.488, 2.489, 2.489, 2.492, 2.496, 2.501, 2.511, 2.524,
2205++ 2.501, 2.487, 2.482, 2.481, 2.478, 2.477, 2.481, 2.483, 2.487, 2.491, 2.501, 2.503, 2.509, 2.511, 2.518, 2.519, 2.519, 2.519, 2.516, 2.509, 2.504, 2.498, 2.495, 2.493, 2.489, 2.489, 2.488, 2.489, 2.492, 2.498, 2.505, 2.523,
2206++ 2.499, 2.484, 2.481, 2.476, 2.476, 2.476, 2.481, 2.485, 2.492, 2.501, 2.509, 2.514, 2.519, 2.524, 2.528, 2.531, 2.533, 2.533, 2.525, 2.519, 2.514, 2.507, 2.501, 2.497, 2.493, 2.489, 2.489, 2.488, 2.491, 2.494, 2.501, 2.514,
2207++ 2.497, 2.483, 2.478, 2.476, 2.476, 2.478, 2.482, 2.491, 2.499, 2.509, 2.515, 2.522, 2.528, 2.535, 2.539, 2.541, 2.543, 2.542, 2.539, 2.529, 2.522, 2.516, 2.507, 2.502, 2.497, 2.491, 2.489, 2.488, 2.489, 2.492, 2.498, 2.514,
2208++ 2.492, 2.479, 2.476, 2.475, 2.476, 2.481, 2.488, 2.496, 2.505, 2.516, 2.524, 2.532, 2.541, 2.545, 2.552, 2.554, 2.554, 2.554, 2.548, 2.541, 2.532, 2.522, 2.516, 2.507, 2.502, 2.494, 2.491, 2.489, 2.489, 2.492, 2.494, 2.511,
2209++ 2.491, 2.479, 2.476, 2.477, 2.478, 2.482, 2.491, 2.502, 2.514, 2.524, 2.533, 2.543, 2.548, 2.555, 2.562, 2.566, 2.567, 2.562, 2.557, 2.551, 2.541, 2.531, 2.523, 2.512, 2.506, 2.498, 2.493, 2.491, 2.491, 2.491, 2.493, 2.507,
2210++ 2.489, 2.478, 2.476, 2.477, 2.481, 2.485, 2.494, 2.507, 2.517, 2.529, 2.542, 2.548, 2.557, 2.563, 2.567, 2.571, 2.572, 2.571, 2.565, 2.558, 2.549, 2.538, 2.528, 2.521, 2.509, 2.501, 2.494, 2.492, 2.491, 2.491, 2.491, 2.505,
2211++ 2.488, 2.478, 2.477, 2.478, 2.482, 2.489, 2.499, 2.509, 2.523, 2.538, 2.548, 2.556, 2.563, 2.568, 2.573, 2.577, 2.578, 2.577, 2.573, 2.564, 2.555, 2.543, 2.535, 2.524, 2.515, 2.504, 2.495, 2.492, 2.489, 2.488, 2.489, 2.501,
2212++ 2.486, 2.476, 2.475, 2.477, 2.483, 2.491, 2.503, 2.515, 2.529, 2.542, 2.553, 2.562, 2.568, 2.574, 2.581, 2.583, 2.584, 2.581, 2.578, 2.571, 2.562, 2.551, 2.539, 2.531, 2.517, 2.508, 2.497, 2.492, 2.488, 2.487, 2.489, 2.498,
2213++ 2.486, 2.476, 2.475, 2.479, 2.484, 2.492, 2.504, 2.519, 2.533, 2.544, 2.557, 2.566, 2.573, 2.581, 2.584, 2.588, 2.588, 2.586, 2.581, 2.575, 2.567, 2.555, 2.546, 2.534, 2.517, 2.509, 2.499, 2.492, 2.489, 2.485, 2.488, 2.497,
2214++ 2.487, 2.476, 2.476, 2.479, 2.486, 2.494, 2.506, 2.521, 2.535, 2.549, 2.559, 2.571, 2.578, 2.583, 2.589, 2.591, 2.591, 2.591, 2.587, 2.579, 2.571, 2.559, 2.551, 2.538, 2.523, 2.513, 2.503, 2.493, 2.489, 2.486, 2.487, 2.499,
2215++ 2.486, 2.475, 2.475, 2.479, 2.486, 2.495, 2.509, 2.525, 2.541, 2.555, 2.563, 2.573, 2.582, 2.588, 2.591, 2.594, 2.595, 2.592, 2.591, 2.585, 2.574, 2.564, 2.552, 2.541, 2.525, 2.514, 2.503, 2.493, 2.489, 2.486, 2.486, 2.501,
2216++ 2.486, 2.475, 2.475, 2.479, 2.488, 2.497, 2.509, 2.526, 2.542, 2.556, 2.564, 2.575, 2.584, 2.591, 2.595, 2.596, 2.597, 2.595, 2.592, 2.587, 2.577, 2.568, 2.554, 2.542, 2.527, 2.515, 2.504, 2.494, 2.491, 2.487, 2.487, 2.505,
2217++ 2.484, 2.476, 2.475, 2.478, 2.488, 2.498, 2.509, 2.526, 2.542, 2.555, 2.565, 2.576, 2.584, 2.589, 2.595, 2.598, 2.598, 2.597, 2.593, 2.587, 2.578, 2.569, 2.556, 2.543, 2.528, 2.515, 2.504, 2.494, 2.489, 2.485, 2.485, 2.501,
2218++ 2.484, 2.475, 2.475, 2.478, 2.489, 2.498, 2.509, 2.524, 2.539, 2.553, 2.565, 2.576, 2.584, 2.589, 2.594, 2.597, 2.597, 2.596, 2.593, 2.587, 2.577, 2.569, 2.555, 2.543, 2.529, 2.515, 2.503, 2.496, 2.491, 2.485, 2.486, 2.497,
2219++ 2.484, 2.474, 2.474, 2.479, 2.487, 2.497, 2.509, 2.523, 2.539, 2.551, 2.563, 2.574, 2.581, 2.587, 2.592, 2.595, 2.596, 2.595, 2.591, 2.584, 2.574, 2.567, 2.554, 2.541, 2.526, 2.514, 2.503, 2.495, 2.489, 2.485, 2.486, 2.497,
2220++ 2.484, 2.475, 2.475, 2.478, 2.485, 2.494, 2.507, 2.522, 2.535, 2.546, 2.559, 2.568, 2.579, 2.584, 2.589, 2.592, 2.593, 2.592, 2.588, 2.579, 2.571, 2.562, 2.551, 2.537, 2.524, 2.514, 2.501, 2.493, 2.489, 2.486, 2.487, 2.498,
2221++ 2.485, 2.476, 2.475, 2.477, 2.485, 2.491, 2.506, 2.519, 2.531, 2.544, 2.555, 2.563, 2.571, 2.581, 2.584, 2.589, 2.589, 2.588, 2.583, 2.576, 2.566, 2.555, 2.546, 2.534, 2.522, 2.511, 2.499, 2.491, 2.488, 2.486, 2.487, 2.502,
2222++ 2.487, 2.477, 2.475, 2.477, 2.483, 2.489, 2.503, 2.515, 2.525, 2.541, 2.551, 2.559, 2.567, 2.573, 2.579, 2.582, 2.583, 2.582, 2.576, 2.569, 2.562, 2.549, 2.542, 2.527, 2.518, 2.505, 2.497, 2.491, 2.489, 2.487, 2.487, 2.502,
2223++ 2.487, 2.478, 2.475, 2.477, 2.482, 2.489, 2.497, 2.512, 2.522, 2.536, 2.544, 2.551, 2.562, 2.566, 2.573, 2.578, 2.578, 2.575, 2.571, 2.564, 2.556, 2.548, 2.536, 2.523, 2.513, 2.503, 2.493, 2.489, 2.487, 2.486, 2.487, 2.502,
2224++ 2.488, 2.479, 2.477, 2.478, 2.482, 2.488, 2.496, 2.505, 2.516, 2.528, 2.538, 2.547, 2.553, 2.561, 2.565, 2.569, 2.569, 2.568, 2.564, 2.558, 2.549, 2.541, 2.531, 2.517, 2.509, 2.499, 2.492, 2.488, 2.486, 2.484, 2.486, 2.503,
2225++ 2.492, 2.482, 2.479, 2.479, 2.482, 2.487, 2.491, 2.501, 2.512, 2.523, 2.531, 2.541, 2.549, 2.552, 2.558, 2.561, 2.562, 2.559, 2.558, 2.552, 2.542, 2.535, 2.525, 2.514, 2.505, 2.497, 2.491, 2.486, 2.485, 2.484, 2.487, 2.503,
2226++ 2.495, 2.483, 2.479, 2.479, 2.482, 2.487, 2.491, 2.498, 2.508, 2.515, 2.526, 2.533, 2.541, 2.547, 2.551, 2.554, 2.555, 2.554, 2.552, 2.541, 2.537, 2.527, 2.519, 2.507, 2.502, 2.495, 2.488, 2.485, 2.484, 2.485, 2.488, 2.503,
2227++ 2.499, 2.485, 2.483, 2.481, 2.482, 2.486, 2.489, 2.494, 2.504, 2.511, 2.519, 2.527, 2.531, 2.539, 2.542, 2.546, 2.546, 2.545, 2.539, 2.535, 2.527, 2.522, 2.509, 2.505, 2.497, 2.491, 2.486, 2.485, 2.485, 2.487, 2.491, 2.506,
2228++ 2.499, 2.489, 2.483, 2.481, 2.481, 2.483, 2.488, 2.491, 2.499, 2.506, 2.512, 2.519, 2.524, 2.529, 2.535, 2.537, 2.536, 2.534, 2.532, 2.525, 2.522, 2.514, 2.506, 2.499, 2.492, 2.489, 2.485, 2.484, 2.485, 2.488, 2.492, 2.506,
2229++ 2.507, 2.494, 2.486, 2.483, 2.482, 2.482, 2.486, 2.488, 2.495, 2.501, 2.507, 2.511, 2.517, 2.519, 2.523, 2.525, 2.525, 2.523, 2.523, 2.521, 2.514, 2.506, 2.502, 2.496, 2.491, 2.488, 2.485, 2.485, 2.487, 2.489, 2.496, 2.516,
2230++ 2.511, 2.503, 2.489, 2.486, 2.485, 2.485, 2.485, 2.487, 2.489, 2.495, 2.501, 2.505, 2.509, 2.514, 2.517, 2.519, 2.518, 2.517, 2.515, 2.511, 2.505, 2.501, 2.495, 2.492, 2.488, 2.486, 2.485, 2.486, 2.488, 2.492, 2.499, 2.519,
2231++ 2.517, 2.505, 2.494, 2.489, 2.487, 2.486, 2.486, 2.486, 2.489, 2.491, 2.496, 2.499, 2.503, 2.506, 2.508, 2.509, 2.511, 2.509, 2.507, 2.503, 2.501, 2.496, 2.493, 2.489, 2.485, 2.485, 2.486, 2.487, 2.491, 2.495, 2.505, 2.526,
2232++ 2.526, 2.516, 2.504, 2.494, 2.493, 2.489, 2.489, 2.489, 2.489, 2.491, 2.496, 2.498, 2.501, 2.504, 2.506, 2.506, 2.506, 2.505, 2.503, 2.501, 2.499, 2.496, 2.494, 2.491, 2.487, 2.486, 2.489, 2.492, 2.497, 2.505, 2.517, 2.528,
2233++ 2.529, 2.526, 2.508, 2.502, 2.501, 2.498, 2.495, 2.495, 2.495, 2.495, 2.497, 2.499, 2.501, 2.503, 2.504, 2.506, 2.505, 2.505, 2.503, 2.501, 2.499, 2.496, 2.495, 2.494, 2.492, 2.494, 2.494, 2.498, 2.504, 2.513, 2.525, 2.536
2234++ ]
2235++ },
2236++ {
2237++ "ct": 5000,
2238++ "table":
2239++ [
2240++ 1.427, 1.425, 1.423, 1.422, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.422, 1.423, 1.424, 1.425, 1.426, 1.426, 1.426, 1.425, 1.425, 1.424, 1.422, 1.421, 1.421, 1.421, 1.421, 1.422, 1.422, 1.422, 1.424, 1.424, 1.426, 1.428,
2241++ 1.426, 1.424, 1.422, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.422, 1.423, 1.424, 1.425, 1.426, 1.427, 1.427, 1.427, 1.426, 1.425, 1.424, 1.422, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.421, 1.422, 1.424, 1.427,
2242++ 1.423, 1.421, 1.421, 1.419, 1.419, 1.418, 1.419, 1.419, 1.421, 1.423, 1.425, 1.426, 1.428, 1.429, 1.431, 1.431, 1.431, 1.431, 1.429, 1.426, 1.424, 1.422, 1.421, 1.421, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.422, 1.425,
2243++ 1.422, 1.419, 1.419, 1.419, 1.418, 1.418, 1.419, 1.421, 1.422, 1.426, 1.428, 1.429, 1.433, 1.434, 1.436, 1.436, 1.436, 1.434, 1.432, 1.429, 1.426, 1.424, 1.423, 1.422, 1.421, 1.419, 1.419, 1.419, 1.419, 1.419, 1.421, 1.425,
2244++ 1.422, 1.419, 1.419, 1.418, 1.418, 1.419, 1.419, 1.422, 1.425, 1.429, 1.432, 1.435, 1.436, 1.438, 1.439, 1.439, 1.441, 1.439, 1.435, 1.433, 1.429, 1.427, 1.425, 1.423, 1.422, 1.419, 1.419, 1.418, 1.418, 1.418, 1.419, 1.425,
2245++ 1.422, 1.419, 1.418, 1.418, 1.418, 1.419, 1.421, 1.424, 1.428, 1.432, 1.436, 1.437, 1.439, 1.442, 1.443, 1.445, 1.444, 1.443, 1.441, 1.436, 1.434, 1.431, 1.427, 1.425, 1.422, 1.421, 1.419, 1.418, 1.418, 1.418, 1.419, 1.424,
2246++ 1.422, 1.418, 1.417, 1.418, 1.419, 1.421, 1.423, 1.427, 1.431, 1.436, 1.438, 1.442, 1.444, 1.446, 1.448, 1.449, 1.448, 1.446, 1.445, 1.441, 1.436, 1.434, 1.429, 1.427, 1.423, 1.421, 1.419, 1.418, 1.418, 1.418, 1.418, 1.423,
2247++ 1.421, 1.418, 1.418, 1.418, 1.419, 1.421, 1.424, 1.429, 1.434, 1.438, 1.442, 1.445, 1.447, 1.449, 1.451, 1.452, 1.452, 1.449, 1.447, 1.445, 1.441, 1.436, 1.433, 1.429, 1.425, 1.422, 1.419, 1.419, 1.418, 1.417, 1.418, 1.423,
2248++ 1.421, 1.418, 1.418, 1.419, 1.419, 1.423, 1.426, 1.432, 1.436, 1.441, 1.445, 1.448, 1.449, 1.452, 1.453, 1.454, 1.454, 1.453, 1.451, 1.447, 1.444, 1.439, 1.433, 1.431, 1.427, 1.422, 1.421, 1.419, 1.418, 1.417, 1.418, 1.423,
2249++ 1.421, 1.418, 1.418, 1.419, 1.421, 1.423, 1.428, 1.433, 1.439, 1.443, 1.448, 1.449, 1.453, 1.454, 1.455, 1.456, 1.456, 1.454, 1.453, 1.449, 1.446, 1.441, 1.437, 1.433, 1.429, 1.423, 1.421, 1.419, 1.418, 1.416, 1.417, 1.423,
2250++ 1.421, 1.417, 1.417, 1.419, 1.422, 1.424, 1.429, 1.435, 1.441, 1.444, 1.449, 1.453, 1.454, 1.456, 1.458, 1.459, 1.458, 1.456, 1.454, 1.451, 1.448, 1.442, 1.439, 1.435, 1.429, 1.426, 1.421, 1.419, 1.418, 1.416, 1.417, 1.422,
2251++ 1.419, 1.418, 1.417, 1.419, 1.422, 1.425, 1.429, 1.436, 1.442, 1.446, 1.451, 1.454, 1.456, 1.458, 1.461, 1.461, 1.461, 1.459, 1.456, 1.453, 1.451, 1.446, 1.441, 1.436, 1.431, 1.427, 1.422, 1.419, 1.418, 1.416, 1.417, 1.422,
2252++ 1.419, 1.418, 1.418, 1.421, 1.423, 1.426, 1.431, 1.437, 1.444, 1.449, 1.452, 1.456, 1.458, 1.461, 1.462, 1.463, 1.463, 1.461, 1.458, 1.454, 1.452, 1.447, 1.443, 1.438, 1.432, 1.428, 1.423, 1.421, 1.419, 1.417, 1.417, 1.421,
2253++ 1.419, 1.418, 1.417, 1.421, 1.423, 1.428, 1.432, 1.439, 1.445, 1.451, 1.453, 1.457, 1.459, 1.462, 1.464, 1.465, 1.465, 1.463, 1.461, 1.457, 1.453, 1.449, 1.444, 1.441, 1.432, 1.429, 1.425, 1.421, 1.419, 1.417, 1.418, 1.422,
2254++ 1.418, 1.417, 1.417, 1.419, 1.423, 1.428, 1.433, 1.439, 1.446, 1.451, 1.453, 1.457, 1.461, 1.464, 1.465, 1.466, 1.466, 1.464, 1.462, 1.459, 1.454, 1.451, 1.445, 1.441, 1.436, 1.429, 1.425, 1.422, 1.421, 1.417, 1.417, 1.423,
2255++ 1.417, 1.416, 1.416, 1.419, 1.423, 1.428, 1.433, 1.441, 1.446, 1.451, 1.454, 1.458, 1.461, 1.463, 1.465, 1.466, 1.466, 1.465, 1.463, 1.459, 1.454, 1.451, 1.446, 1.441, 1.437, 1.431, 1.426, 1.422, 1.421, 1.418, 1.418, 1.423,
2256++ 1.417, 1.416, 1.417, 1.418, 1.423, 1.428, 1.433, 1.439, 1.445, 1.451, 1.453, 1.457, 1.461, 1.463, 1.465, 1.466, 1.466, 1.464, 1.462, 1.459, 1.454, 1.451, 1.446, 1.441, 1.437, 1.431, 1.426, 1.422, 1.419, 1.417, 1.417, 1.422,
2257++ 1.417, 1.416, 1.416, 1.418, 1.422, 1.428, 1.433, 1.438, 1.444, 1.449, 1.453, 1.456, 1.459, 1.462, 1.464, 1.465, 1.465, 1.463, 1.461, 1.458, 1.453, 1.449, 1.445, 1.441, 1.435, 1.429, 1.426, 1.421, 1.419, 1.417, 1.417, 1.422,
2258++ 1.418, 1.416, 1.416, 1.418, 1.421, 1.426, 1.432, 1.438, 1.443, 1.447, 1.451, 1.454, 1.458, 1.459, 1.462, 1.463, 1.463, 1.462, 1.459, 1.455, 1.451, 1.447, 1.443, 1.439, 1.434, 1.429, 1.425, 1.421, 1.419, 1.417, 1.417, 1.422,
2259++ 1.418, 1.416, 1.416, 1.418, 1.421, 1.425, 1.431, 1.435, 1.442, 1.445, 1.449, 1.452, 1.455, 1.458, 1.458, 1.461, 1.461, 1.459, 1.456, 1.453, 1.449, 1.445, 1.442, 1.436, 1.433, 1.427, 1.425, 1.421, 1.419, 1.418, 1.418, 1.422,
2260++ 1.419, 1.416, 1.415, 1.417, 1.419, 1.424, 1.429, 1.434, 1.439, 1.443, 1.446, 1.449, 1.452, 1.454, 1.456, 1.457, 1.457, 1.456, 1.453, 1.451, 1.447, 1.443, 1.441, 1.435, 1.431, 1.426, 1.424, 1.421, 1.419, 1.418, 1.418, 1.422,
2261++ 1.419, 1.416, 1.415, 1.416, 1.419, 1.422, 1.426, 1.433, 1.437, 1.441, 1.444, 1.447, 1.449, 1.452, 1.453, 1.455, 1.455, 1.453, 1.451, 1.447, 1.444, 1.441, 1.438, 1.432, 1.428, 1.424, 1.421, 1.419, 1.418, 1.417, 1.417, 1.421,
2262++ 1.419, 1.416, 1.415, 1.416, 1.418, 1.421, 1.425, 1.431, 1.435, 1.438, 1.442, 1.445, 1.446, 1.449, 1.451, 1.451, 1.451, 1.451, 1.447, 1.445, 1.443, 1.439, 1.434, 1.431, 1.427, 1.422, 1.421, 1.418, 1.417, 1.417, 1.417, 1.421,
2263++ 1.418, 1.416, 1.415, 1.416, 1.417, 1.421, 1.423, 1.428, 1.433, 1.437, 1.439, 1.442, 1.444, 1.446, 1.448, 1.449, 1.449, 1.447, 1.445, 1.443, 1.439, 1.437, 1.432, 1.429, 1.425, 1.422, 1.419, 1.417, 1.417, 1.416, 1.416, 1.419,
2264++ 1.418, 1.416, 1.416, 1.416, 1.417, 1.421, 1.422, 1.426, 1.429, 1.433, 1.436, 1.438, 1.441, 1.443, 1.445, 1.446, 1.445, 1.445, 1.443, 1.439, 1.437, 1.434, 1.431, 1.427, 1.424, 1.421, 1.419, 1.417, 1.417, 1.416, 1.416, 1.421,
2265++ 1.419, 1.417, 1.416, 1.416, 1.417, 1.421, 1.422, 1.424, 1.427, 1.429, 1.432, 1.436, 1.437, 1.439, 1.442, 1.443, 1.443, 1.441, 1.439, 1.437, 1.434, 1.431, 1.429, 1.425, 1.422, 1.421, 1.419, 1.417, 1.416, 1.416, 1.417, 1.419,
2266++ 1.421, 1.418, 1.416, 1.417, 1.418, 1.421, 1.421, 1.423, 1.424, 1.427, 1.429, 1.432, 1.434, 1.436, 1.438, 1.439, 1.439, 1.438, 1.436, 1.434, 1.431, 1.429, 1.426, 1.423, 1.422, 1.421, 1.418, 1.417, 1.417, 1.417, 1.417, 1.421,
2267++ 1.423, 1.419, 1.418, 1.418, 1.419, 1.419, 1.421, 1.422, 1.423, 1.424, 1.427, 1.429, 1.432, 1.432, 1.434, 1.435, 1.435, 1.434, 1.433, 1.431, 1.429, 1.426, 1.424, 1.422, 1.421, 1.419, 1.418, 1.417, 1.417, 1.417, 1.418, 1.421,
2268++ 1.425, 1.421, 1.419, 1.419, 1.419, 1.421, 1.421, 1.421, 1.421, 1.423, 1.424, 1.426, 1.428, 1.431, 1.431, 1.432, 1.432, 1.431, 1.431, 1.428, 1.425, 1.425, 1.422, 1.421, 1.419, 1.419, 1.418, 1.418, 1.418, 1.418, 1.419, 1.425,
2269++ 1.426, 1.422, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.421, 1.422, 1.424, 1.426, 1.427, 1.428, 1.429, 1.429, 1.429, 1.427, 1.424, 1.423, 1.422, 1.421, 1.419, 1.418, 1.418, 1.418, 1.418, 1.418, 1.418, 1.419, 1.426,
2270++ 1.428, 1.425, 1.421, 1.421, 1.421, 1.421, 1.421, 1.419, 1.419, 1.421, 1.422, 1.423, 1.424, 1.426, 1.426, 1.426, 1.426, 1.425, 1.424, 1.424, 1.422, 1.422, 1.421, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.419, 1.423, 1.426,
2271++ 1.429, 1.427, 1.424, 1.422, 1.422, 1.422, 1.421, 1.421, 1.421, 1.422, 1.422, 1.422, 1.424, 1.425, 1.426, 1.426, 1.425, 1.425, 1.424, 1.423, 1.422, 1.422, 1.421, 1.421, 1.421, 1.421, 1.419, 1.419, 1.421, 1.422, 1.424, 1.426
2272++ ]
2273++ }
2274++ ],
2275++ "luminance_lut":
2276++ [
2277++ 2.964, 2.872, 2.691, 2.544, 2.416, 2.302, 2.196, 2.093, 2.006, 1.928, 1.852, 1.801, 1.769, 1.752, 1.743, 1.743, 1.743, 1.746, 1.759, 1.784, 1.824, 1.888, 1.968, 2.052, 2.149, 2.253, 2.359, 2.483, 2.626, 2.785, 2.988, 3.051,
2278++ 2.872, 2.748, 2.583, 2.442, 2.313, 2.201, 2.104, 2.012, 1.928, 1.852, 1.791, 1.742, 1.701, 1.671, 1.651, 1.643, 1.643, 1.659, 1.685, 1.721, 1.768, 1.824, 1.888, 1.971, 2.068, 2.152, 2.259, 2.381, 2.514, 2.669, 2.853, 2.988,
2279++ 2.761, 2.655, 2.497, 2.356, 2.226, 2.114, 2.012, 1.928, 1.845, 1.769, 1.707, 1.653, 1.612, 1.583, 1.562, 1.556, 1.556, 1.572, 1.599, 1.635, 1.681, 1.742, 1.806, 1.888, 1.971, 2.068, 2.175, 2.292, 2.431, 2.576, 2.747, 2.853,
2280++ 2.679, 2.571, 2.415, 2.275, 2.151, 2.035, 1.936, 1.845, 1.769, 1.689, 1.623, 1.572, 1.532, 1.501, 1.481, 1.473, 1.473, 1.492, 1.517, 1.556, 1.599, 1.659, 1.731, 1.806, 1.895, 1.992, 2.101, 2.218, 2.349, 2.493, 2.664, 2.753,
2281++ 2.609, 2.492, 2.339, 2.204, 2.079, 1.971, 1.865, 1.772, 1.689, 1.619, 1.551, 1.499, 1.457, 1.423, 1.405, 1.397, 1.397, 1.411, 1.438, 1.477, 1.525, 1.585, 1.659, 1.731, 1.823, 1.922, 2.027, 2.148, 2.275, 2.422, 2.586, 2.683,
2282++ 2.545, 2.426, 2.279, 2.139, 2.014, 1.903, 1.799, 1.702, 1.619, 1.551, 1.482, 1.427, 1.385, 1.353, 1.331, 1.325, 1.325, 1.338, 1.364, 1.403, 1.455, 1.522, 1.585, 1.665, 1.757, 1.858, 1.963, 2.081, 2.207, 2.356, 2.518, 2.615,
2283++ 2.489, 2.367, 2.218, 2.079, 1.956, 1.844, 1.739, 1.642, 1.559, 1.482, 1.426, 1.363, 1.321, 1.287, 1.266, 1.259, 1.259, 1.274, 1.301, 1.339, 1.395, 1.455, 1.523, 1.606, 1.697, 1.797, 1.905, 2.024, 2.154, 2.296, 2.455, 2.563,
2284++ 2.439, 2.316, 2.164, 2.028, 1.906, 1.793, 1.686, 1.589, 1.505, 1.427, 1.363, 1.308, 1.261, 1.229, 1.207, 1.202, 1.202, 1.215, 1.242, 1.283, 1.339, 1.395, 1.467, 1.551, 1.639, 1.742, 1.851, 1.972, 2.104, 2.243, 2.402, 2.515,
2285++ 2.398, 2.262, 2.116, 1.982, 1.861, 1.745, 1.639, 1.541, 1.456, 1.377, 1.308, 1.261, 1.208, 1.177, 1.157, 1.153, 1.153, 1.167, 1.191, 1.233, 1.283, 1.343, 1.418, 1.499, 1.591, 1.696, 1.804, 1.928, 2.057, 2.194, 2.352, 2.471,
2286++ 2.363, 2.222, 2.078, 1.942, 1.818, 1.706, 1.597, 1.501, 1.412, 1.334, 1.266, 1.208, 1.171, 1.134, 1.113, 1.109, 1.109, 1.123, 1.149, 1.191, 1.233, 1.296, 1.371, 1.457, 1.546, 1.654, 1.768, 1.886, 2.014, 2.155, 2.312, 2.436,
2287++ 2.334, 2.188, 2.042, 1.909, 1.783, 1.668, 1.561, 1.464, 1.374, 1.295, 1.228, 1.171, 1.134, 1.098, 1.076, 1.072, 1.072, 1.087, 1.119, 1.149, 1.196, 1.259, 1.332, 1.419, 1.514, 1.616, 1.728, 1.849, 1.981, 2.123, 2.276, 2.406,
2288++ 2.306, 2.159, 2.015, 1.881, 1.753, 1.639, 1.533, 1.434, 1.341, 1.263, 1.195, 1.139, 1.098, 1.074, 1.046, 1.044, 1.045, 1.059, 1.087, 1.119, 1.165, 1.227, 1.302, 1.387, 1.482, 1.586, 1.698, 1.819, 1.953, 2.093, 2.248, 2.383,
2289++ 2.291, 2.141, 1.991, 1.856, 1.732, 1.615, 1.508, 1.409, 1.318, 1.238, 1.171, 1.114, 1.074, 1.046, 1.027, 1.023, 1.025, 1.043, 1.059, 1.095, 1.142, 1.203, 1.278, 1.362, 1.456, 1.559, 1.673, 1.796, 1.928, 2.071, 2.225, 2.359,
2290++ 2.279, 2.118, 1.972, 1.839, 1.715, 1.599, 1.488, 1.389, 1.298, 1.219, 1.153, 1.097, 1.057, 1.027, 1.018, 1.009, 1.013, 1.025, 1.044, 1.078, 1.125, 1.186, 1.258, 1.342, 1.438, 1.541, 1.655, 1.779, 1.909, 2.053, 2.211, 2.351,
2291++ 2.274, 2.108, 1.963, 1.831, 1.706, 1.588, 1.477, 1.376, 1.288, 1.207, 1.139, 1.086, 1.049, 1.021, 1.005, 1.002, 1.004, 1.013, 1.035, 1.069, 1.116, 1.176, 1.246, 1.331, 1.427, 1.531, 1.645, 1.767, 1.899, 2.045, 2.197, 2.351,
2292++ 2.274, 2.106, 1.961, 1.827, 1.701, 1.585, 1.474, 1.374, 1.285, 1.206, 1.139, 1.085, 1.047, 1.019, 1.003, 1.001, 1.001, 1.012, 1.033, 1.067, 1.113, 1.173, 1.245, 1.329, 1.423, 1.529, 1.642, 1.765, 1.897, 2.042, 2.196, 2.349,
2293++ 2.274, 2.108, 1.961, 1.827, 1.701, 1.585, 1.474, 1.374, 1.285, 1.206, 1.139, 1.085, 1.047, 1.021, 1.005, 1.001, 1.004, 1.012, 1.033, 1.068, 1.113, 1.173, 1.246, 1.329, 1.423, 1.529, 1.642, 1.766, 1.897, 2.042, 2.198, 2.349,
2294++ 2.278, 2.116, 1.968, 1.833, 1.707, 1.591, 1.482, 1.382, 1.291, 1.214, 1.147, 1.091, 1.055, 1.028, 1.016, 1.006, 1.012, 1.018, 1.039, 1.074, 1.121, 1.182, 1.255, 1.339, 1.433, 1.538, 1.651, 1.777, 1.911, 2.051, 2.207, 2.351,
2295++ 2.283, 2.127, 1.979, 1.846, 1.723, 1.605, 1.496, 1.397, 1.309, 1.229, 1.162, 1.108, 1.067, 1.041, 1.027, 1.018, 1.018, 1.036, 1.051, 1.087, 1.136, 1.197, 1.269, 1.354, 1.448, 1.554, 1.664, 1.789, 1.922, 2.065, 2.222, 2.365,
2296++ 2.298, 2.145, 1.999, 1.865, 1.744, 1.627, 1.518, 1.421, 1.331, 1.251, 1.183, 1.129, 1.087, 1.065, 1.041, 1.036, 1.036, 1.051, 1.074, 1.107, 1.158, 1.219, 1.292, 1.378, 1.471, 1.575, 1.687, 1.809, 1.942, 2.085, 2.239, 2.378,
2297++ 2.315, 2.174, 2.024, 1.893, 1.768, 1.652, 1.543, 1.445, 1.355, 1.278, 1.211, 1.155, 1.116, 1.087, 1.066, 1.061, 1.061, 1.074, 1.105, 1.137, 1.186, 1.248, 1.322, 1.405, 1.498, 1.602, 1.713, 1.835, 1.965, 2.109, 2.267, 2.399,
2298++ 2.341, 2.206, 2.057, 1.923, 1.799, 1.685, 1.576, 1.479, 1.392, 1.312, 1.244, 1.187, 1.154, 1.116, 1.096, 1.092, 1.092, 1.106, 1.137, 1.173, 1.221, 1.282, 1.356, 1.439, 1.532, 1.635, 1.747, 1.869, 1.997, 2.141, 2.298, 2.425,
2299++ 2.375, 2.244, 2.098, 1.965, 1.839, 1.722, 1.614, 1.519, 1.434, 1.355, 1.288, 1.234, 1.187, 1.155, 1.136, 1.132, 1.132, 1.147, 1.173, 1.219, 1.263, 1.324, 1.398, 1.479, 1.571, 1.674, 1.784, 1.904, 2.035, 2.177, 2.336, 2.455,
2300++ 2.414, 2.286, 2.144, 2.011, 1.883, 1.767, 1.661, 1.566, 1.479, 1.401, 1.335, 1.286, 1.234, 1.202, 1.183, 1.178, 1.178, 1.195, 1.222, 1.263, 1.313, 1.372, 1.444, 1.526, 1.618, 1.718, 1.827, 1.951, 2.081, 2.221, 2.379, 2.498,
2301++ 2.463, 2.339, 2.191, 2.056, 1.931, 1.819, 1.712, 1.616, 1.529, 1.452, 1.392, 1.335, 1.286, 1.254, 1.235, 1.232, 1.232, 1.248, 1.275, 1.313, 1.371, 1.425, 1.495, 1.576, 1.671, 1.768, 1.877, 1.999, 2.128, 2.269, 2.428, 2.541,
2302++ 2.514, 2.396, 2.247, 2.112, 1.988, 1.873, 1.766, 1.671, 1.588, 1.513, 1.452, 1.392, 1.348, 1.316, 1.298, 1.292, 1.292, 1.307, 1.336, 1.373, 1.425, 1.486, 1.552, 1.636, 1.728, 1.826, 1.933, 2.051, 2.183, 2.327, 2.488, 2.587,
2303++ 2.573, 2.459, 2.307, 2.171, 2.049, 1.931, 1.828, 1.731, 1.649, 1.582, 1.513, 1.459, 1.415, 1.381, 1.363, 1.358, 1.358, 1.373, 1.399, 1.439, 1.486, 1.552, 1.617, 1.696, 1.787, 1.888, 1.995, 2.112, 2.244, 2.391, 2.552, 2.652,
2304++ 2.635, 2.525, 2.377, 2.239, 2.111, 1.996, 1.895, 1.799, 1.719, 1.649, 1.582, 1.531, 1.486, 1.454, 1.434, 1.429, 1.429, 1.444, 1.469, 1.507, 1.555, 1.617, 1.692, 1.766, 1.854, 1.954, 2.065, 2.181, 2.313, 2.459, 2.623, 2.722,
2305++ 2.714, 2.604, 2.452, 2.313, 2.188, 2.071, 1.966, 1.876, 1.799, 1.719, 1.656, 1.604, 1.562, 1.529, 1.511, 1.504, 1.504, 1.519, 1.544, 1.583, 1.632, 1.692, 1.766, 1.839, 1.929, 2.029, 2.138, 2.259, 2.391, 2.539, 2.712, 2.811,
2306++ 2.809, 2.698, 2.537, 2.396, 2.277, 2.163, 2.053, 1.965, 1.876, 1.799, 1.741, 1.688, 1.643, 1.613, 1.592, 1.586, 1.586, 1.601, 1.628, 1.666, 1.715, 1.773, 1.839, 1.927, 2.012, 2.111, 2.222, 2.342, 2.477, 2.625, 2.811, 2.926,
2307++ 2.921, 2.809, 2.637, 2.493, 2.376, 2.256, 2.149, 2.053, 1.966, 1.893, 1.832, 1.778, 1.736, 1.708, 1.687, 1.681, 1.681, 1.696, 1.721, 1.757, 1.806, 1.864, 1.929, 2.012, 2.106, 2.199, 2.313, 2.437, 2.577, 2.731, 2.926, 3.051,
2308++ 3.029, 2.921, 2.745, 2.591, 2.474, 2.355, 2.246, 2.146, 2.049, 1.966, 1.893, 1.832, 1.799, 1.776, 1.768, 1.768, 1.768, 1.771, 1.783, 1.809, 1.864, 1.929, 2.012, 2.097, 2.195, 2.297, 2.412, 2.539, 2.682, 2.846, 3.051, 3.123
2309++ ],
2310++ "sigma": 0.00463,
2311++ "sigma_Cb": 0.00149
2312++ }
2313++ },
2314++ {
2315++ "rpi.contrast":
2316++ {
2317++ "ce_enable": 1,
2318++ "lo_max": 1000,
2319++ "gamma_curve":
2320++ [
2321++ 0, 0,
2322++ 1024, 5040,
2323++ 2048, 9338,
2324++ 3072, 12356,
2325++ 4096, 15312,
2326++ 5120, 18051,
2327++ 6144, 20790,
2328++ 7168, 23193,
2329++ 8192, 25744,
2330++ 9216, 27942,
2331++ 10240, 30035,
2332++ 11264, 32005,
2333++ 12288, 33975,
2334++ 13312, 35815,
2335++ 14336, 37600,
2336++ 15360, 39168,
2337++ 16384, 40642,
2338++ 18432, 43379,
2339++ 20480, 45749,
2340++ 22528, 47753,
2341++ 24576, 49621,
2342++ 26624, 51253,
2343++ 28672, 52698,
2344++ 30720, 53796,
2345++ 32768, 54876,
2346++ 36864, 57012,
2347++ 40960, 58656,
2348++ 45056, 59954,
2349++ 49152, 61183,
2350++ 53248, 62355,
2351++ 57344, 63419,
2352++ 61440, 64476,
2353++ 65535, 65535
2354++ ]
2355++ }
2356++ },
2357++ {
2358++ "rpi.ccm":
2359++ {
2360++ "ccms": [
2361++ {
2362++ "ct": 2498,
2363++ "ccm":
2364++ [
2365++ 1.58731, -0.18011, -0.40721,
2366++ -0.60639, 2.03422, -0.42782,
2367++ -0.19612, -1.69203, 2.88815
2368++ ]
2369++ },
2370++ {
2371++ "ct": 2811,
2372++ "ccm":
2373++ [
2374++ 1.61593, -0.33164, -0.28429,
2375++ -0.55048, 1.97779, -0.42731,
2376++ -0.12042, -1.42847, 2.54889
2377++ ]
2378++ },
2379++ {
2380++ "ct": 2911,
2381++ "ccm":
2382++ [
2383++ 1.62771, -0.41282, -0.21489,
2384++ -0.57991, 2.04176, -0.46186,
2385++ -0.07613, -1.13359, 2.20972
2386++ ]
2387++ },
2388++ {
2389++ "ct": 2919,
2390++ "ccm":
2391++ [
2392++ 1.62661, -0.37736, -0.24925,
2393++ -0.52519, 1.95233, -0.42714,
2394++ -0.10842, -1.34929, 2.45771
2395++ ]
2396++ },
2397++ {
2398++ "ct": 3627,
2399++ "ccm":
2400++ [
2401++ 1.70385, -0.57231, -0.13154,
2402++ -0.47763, 1.85998, -0.38235,
2403++ -0.07467, -0.82678, 1.90145
2404++ ]
2405++ },
2406++ {
2407++ "ct": 4600,
2408++ "ccm":
2409++ [
2410++ 1.68486, -0.61085, -0.07402,
2411++ -0.41927, 2.04016, -0.62089,
2412++ -0.08633, -0.67672, 1.76305
2413++ ]
2414++ },
2415++ {
2416++ "ct": 5716,
2417++ "ccm":
2418++ [
2419++ 1.80439, -0.73699, -0.06739,
2420++ -0.36073, 1.83327, -0.47255,
2421++ -0.08378, -0.56403, 1.64781
2422++ ]
2423++ },
2424++ {
2425++ "ct": 8575,
2426++ "ccm":
2427++ [
2428++ 1.89357, -0.76427, -0.12931,
2429++ -0.27399, 2.15605, -0.88206,
2430++ -0.12035, -0.68256, 1.80292
2431++ ]
2432++ }
2433++ ]
2434++ }
2435++ },
2436++ {
2437++ "rpi.sharpen":
2438++ {
2439++ "threshold": 0.25,
2440++ "limit": 1.0,
2441++ "strength": 1.0
2442++ }
2443++ },
2444++ {
2445++ "rpi.hdr":
2446++ {
2447++ "Off":
2448++ {
2449++ "cadence": [ 0 ]
2450++ },
2451++ "MultiExposureUnmerged":
2452++ {
2453++ "cadence": [ 1, 2 ],
2454++ "channel_map":
2455++ {
2456++ "short": 1,
2457++ "long": 2
2458++ }
2459++ },
2460++ "SingleExposure":
2461++ {
2462++ "cadence": [ 1 ],
2463++ "channel_map":
2464++ {
2465++ "short": 1
2466++ },
2467++ "spatial_gain": 2.0,
2468++ "tonemap_enable": 1
2469++ },
2470++ "MultiExposure":
2471++ {
2472++ "cadence": [ 1, 2 ],
2473++ "channel_map":
2474++ {
2475++ "short": 1,
2476++ "long": 2
2477++ },
2478++ "stitch_enable": 1,
2479++ "spatial_gain": 2.0,
2480++ "tonemap_enable": 1
2481++ },
2482++ "Night":
2483++ {
2484++ "cadence": [ 3 ],
2485++ "channel_map":
2486++ {
2487++ "short": 3
2488++ },
2489++ "tonemap_enable": 1,
2490++ "tonemap":
2491++ [
2492++ 0, 0,
2493++ 5000, 20000,
2494++ 10000, 30000,
2495++ 20000, 47000,
2496++ 30000, 55000,
2497++ 65535, 65535
2498++ ]
2499++ }
2500++ }
2501++ }
2502++ ]
2503++}
2504+\ No newline at end of file
2505+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2506++++ b/src/ipa/rpi/pisp/data/meson.build 2024-11-25 22:51:33.869906612 +0530
2507+@@ -0,0 +1,21 @@
2508++# SPDX-License-Identifier: CC0-1.0
2509++
2510++conf_files = files([
2511++ 'imx219.json',
2512++ 'imx219_noir.json',
2513++ 'imx296.json',
2514++ 'imx296_mono.json',
2515++ 'imx477.json',
2516++ 'imx477_noir.json',
2517++ 'imx477_scientific.json',
2518++ 'imx708.json',
2519++ 'imx708_noir.json',
2520++ 'imx708_wide.json',
2521++ 'imx708_wide_noir.json',
2522++ 'ov5647.json',
2523++ 'ov5647_noir.json',
2524++ 'uncalibrated.json',
2525++])
2526++
2527++install_data(conf_files,
2528++ install_dir : ipa_data_dir / 'rpi' / 'pisp')
2529+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2530++++ b/src/ipa/rpi/pisp/data/uncalibrated.json 2024-11-25 21:08:37.638494238 +0530
2531+@@ -0,0 +1,135 @@
2532++{
2533++ "version": 2.0,
2534++ "target": "pisp",
2535++ "algorithms": [
2536++ {
2537++ "rpi.black_level":
2538++ {
2539++ "black_level": 4096
2540++ }
2541++ },
2542++ {
2543++ "rpi.awb":
2544++ {
2545++ "use_derivatives": 0,
2546++ "bayes": 0
2547++ }
2548++ },
2549++ {
2550++ "rpi.agc":
2551++ {
2552++ "metering_modes":
2553++ {
2554++ "centre-weighted":
2555++ {
2556++ "weights":
2557++ [
2558++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2559++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2560++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2561++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2562++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2563++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2564++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2565++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
2566++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2567++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2568++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2569++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2570++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2571++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2572++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
2573++ ]
2574++ }
2575++ },
2576++ "exposure_modes":
2577++ {
2578++ "normal":
2579++ {
2580++ "shutter": [ 100, 15000, 30000, 60000, 120000 ],
2581++ "gain": [ 1.0, 2.0, 3.0, 4.0, 6.0 ]
2582++ }
2583++ },
2584++ "constraint_modes":
2585++ {
2586++ "normal": [
2587++ {
2588++ "bound": "LOWER",
2589++ "q_lo": 0.98,
2590++ "q_hi": 1.0,
2591++ "y_target":
2592++ [
2593++ 0, 0.4,
2594++ 1000, 0.4
2595++ ]
2596++ }
2597++ ]
2598++ },
2599++ "y_target":
2600++ [
2601++ 0, 0.16,
2602++ 1000, 0.165,
2603++ 10000, 0.17
2604++ ]
2605++ }
2606++ },
2607++ {
2608++ "rpi.ccm":
2609++ {
2610++ "ccms": [
2611++ {
2612++ "ct": 4000,
2613++ "ccm":
2614++ [
2615++ 2.0, -1.0, 0.0,
2616++ -0.5, 2.0, -0.5,
2617++ 0, -1.0, 2.0
2618++ ]
2619++ }
2620++ ]
2621++ }
2622++ },
2623++ {
2624++ "rpi.contrast":
2625++ {
2626++ "ce_enable": 0,
2627++ "gamma_curve":
2628++ [
2629++ 0, 0,
2630++ 1024, 5040,
2631++ 2048, 9338,
2632++ 3072, 12356,
2633++ 4096, 15312,
2634++ 5120, 18051,
2635++ 6144, 20790,
2636++ 7168, 23193,
2637++ 8192, 25744,
2638++ 9216, 27942,
2639++ 10240, 30035,
2640++ 11264, 32005,
2641++ 12288, 33975,
2642++ 13312, 35815,
2643++ 14336, 37600,
2644++ 15360, 39168,
2645++ 16384, 40642,
2646++ 18432, 43379,
2647++ 20480, 45749,
2648++ 22528, 47753,
2649++ 24576, 49621,
2650++ 26624, 51253,
2651++ 28672, 52698,
2652++ 30720, 53796,
2653++ 32768, 54876,
2654++ 36864, 57012,
2655++ 40960, 58656,
2656++ 45056, 59954,
2657++ 49152, 61183,
2658++ 53248, 62355,
2659++ 57344, 63419,
2660++ 61440, 64476,
2661++ 65535, 65535
2662++ ]
2663++ }
2664++ }
2665++ ]
2666++}
2667+\ No newline at end of file
2668+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2669++++ b/src/ipa/rpi/pisp/meson.build 2024-11-25 21:08:37.638494238 +0530
2670+@@ -0,0 +1,49 @@
2671++# SPDX-License-Identifier: CC0-1.0
2672++
2673++ipa_name = 'ipa_rpi_pisp'
2674++
2675++pisp_ipa_deps = [
2676++ libcamera_private,
2677++ libatomic,
2678++ libpisp_dep,
2679++]
2680++
2681++pisp_ipa_libs = [
2682++ rpi_ipa_cam_helper_lib,
2683++ rpi_ipa_common_lib,
2684++ rpi_ipa_controller_lib
2685++]
2686++
2687++pisp_ipa_includes = [
2688++ ipa_includes,
2689++ libipa_includes,
2690++]
2691++
2692++pisp_ipa_sources = files([
2693++ 'pisp.cpp',
2694++])
2695++
2696++pisp_ipa_includes += include_directories('..')
2697++
2698++mod = shared_module(ipa_name, pisp_ipa_sources,
2699++ name_prefix : '',
2700++ include_directories : pisp_ipa_includes,
2701++ dependencies : pisp_ipa_deps,
2702++ link_with : libipa,
2703++ link_whole : pisp_ipa_libs,
2704++ install : true,
2705++ cpp_args : '-Wno-address-of-packed-member',
2706++ install_dir : ipa_install_dir)
2707++
2708++if ipa_sign_module
2709++ custom_target(ipa_name + '.so.sign',
2710++ input : mod,
2711++ output : ipa_name + '.so.sign',
2712++ command : [ipa_sign, ipa_priv_key, '@INPUT@', '@OUTPUT@'],
2713++ install : false,
2714++ build_by_default : true)
2715++endif
2716++
2717++subdir('data')
2718++
2719++ipa_names += ipa_name
2720+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2721++++ b/src/ipa/rpi/pisp/pisp.cpp 2024-11-25 21:08:37.638494238 +0530
2722+@@ -0,0 +1,1068 @@
2723++/* SPDX-License-Identifier: BSD-2-Clause */
2724++/*
2725++ * Copyright (C) 2023, Raspberry Pi Ltd
2726++ *
2727++ * pisp.cpp - Raspberry Pi PiSP IPA
2728++ */
2729++#include <algorithm>
2730++#include <cmath>
2731++#include <mutex>
2732++#include <string>
2733++#include <sys/mman.h>
2734++#include <utility>
2735++#include <vector>
2736++
2737++#include <libcamera/base/log.h>
2738++#include <libcamera/control_ids.h>
2739++#include <libcamera/ipa/ipa_module_info.h>
2740++#include <libipa/pwl.h>
2741++
2742++#include "libpisp/backend/backend.hpp"
2743++#include "libpisp/frontend/frontend.hpp"
2744++
2745++#include "common/ipa_base.h"
2746++#include "controller/af_status.h"
2747++#include "controller/agc_algorithm.h"
2748++#include "controller/alsc_status.h"
2749++#include "controller/awb_algorithm.h"
2750++#include "controller/awb_status.h"
2751++#include "controller/black_level_algorithm.h"
2752++#include "controller/black_level_status.h"
2753++#include "controller/cac_status.h"
2754++#include "controller/ccm_status.h"
2755++#include "controller/contrast_status.h"
2756++#include "controller/denoise_algorithm.h"
2757++#include "controller/denoise_status.h"
2758++#include "controller/dpc_status.h"
2759++#include "controller/geq_status.h"
2760++#include "controller/hdr_status.h"
2761++#include "controller/lux_status.h"
2762++#include "controller/noise_status.h"
2763++#include "controller/saturation_status.h"
2764++#include "controller/sharpen_status.h"
2765++#include "controller/stitch_status.h"
2766++#include "controller/tonemap_status.h"
2767++
2768++using namespace std::literals::chrono_literals;
2769++
2770++namespace libcamera {
2771++
2772++LOG_DECLARE_CATEGORY(IPARPI)
2773++
2774++namespace {
2775++
2776++constexpr unsigned int NumLscCells = PISP_BE_LSC_GRID_SIZE;
2777++constexpr unsigned int NumLscVertexes = NumLscCells + 1;
2778++
2779++inline int32_t clampField(double value, std::size_t fieldBits, std::size_t fracBits = 0,
2780++ bool isSigned = false, const char *desc = nullptr)
2781++{
2782++ ASSERT(fracBits <= fieldBits && fieldBits <= 32);
2783++
2784++ int min = -(isSigned << (fieldBits - 1));
2785++ int max = (1 << (fieldBits - isSigned)) - 1;
2786++ int32_t val =
2787++ std::clamp<int32_t>(std::round(value * (1 << fracBits)), min, max);
2788++
2789++ if (desc && val / (1 << fracBits) != value)
2790++ LOG(IPARPI, Warning)
2791++ << desc << " rounded/clamped to " << val / (1 << fracBits);
2792++
2793++ return val;
2794++}
2795++
2796++int generateLut(const ipa::Pwl &pwl, uint32_t *lut, std::size_t lutSize,
2797++ unsigned int SlopeBits = 14, unsigned int PosBits = 16)
2798++{
2799++ if (pwl.empty())
2800++ return -EINVAL;
2801++
2802++ int lastY = 0;
2803++ for (unsigned int i = 0; i < lutSize; i++) {
2804++ int x, y;
2805++ if (i < 32)
2806++ x = i * 512;
2807++ else if (i < 48)
2808++ x = (i - 32) * 1024 + 16384;
2809++ else
2810++ x = std::min(65535u, (i - 48) * 2048 + 32768);
2811++
2812++ y = pwl.eval(x);
2813++ if (y < 0 || (i && y < lastY)) {
2814++ LOG(IPARPI, Error)
2815++ << "Malformed PWL for Gamma, disabling!";
2816++ return -1;
2817++ }
2818++
2819++ if (i) {
2820++ unsigned int slope = y - lastY;
2821++ if (slope >= (1u << SlopeBits)) {
2822++ slope = (1u << SlopeBits) - 1;
2823++ LOG(IPARPI, Info)
2824++ << ("Maximum Gamma slope exceeded, adjusting!");
2825++ y = lastY + slope;
2826++ }
2827++ lut[i - 1] |= slope << PosBits;
2828++ }
2829++
2830++ lut[i] = y;
2831++ lastY = y;
2832++ }
2833++
2834++ return 0;
2835++}
2836++
2837++void packLscLut(uint32_t packed[NumLscVertexes][NumLscVertexes],
2838++ double const rgb[3][NumLscVertexes][NumLscVertexes])
2839++{
2840++ for (unsigned int y = 0; y < NumLscVertexes; ++y) {
2841++ for (unsigned int x = 0; x < NumLscVertexes; ++x) {
2842++ /* Jointly encode RGB gains in one of 4 ranges: [0.5:1.5), [0:2), [0:4), [0:8) */
2843++ double lo = std::min({ rgb[0][y][x], rgb[1][y][x], rgb[2][y][x] });
2844++ double hi = std::max({ rgb[0][y][x], rgb[1][y][x], rgb[2][y][x] });
2845++ uint32_t range;
2846++ double scale, offset;
2847++ if (lo >= 0.5 && hi < 1.5) {
2848++ range = 0;
2849++ scale = 1024.0;
2850++ offset = -511.5;
2851++ } else if (hi < 2.0) {
2852++ range = 1;
2853++ scale = 512.0;
2854++ offset = 0.5;
2855++ } else if (hi < 4.0) {
2856++ range = 2;
2857++ scale = 256.0;
2858++ offset = 0.5;
2859++ } else {
2860++ range = 3;
2861++ scale = 128.0;
2862++ offset = 0.5;
2863++ }
2864++ int r = clampField(offset + scale * rgb[0][y][x], 10);
2865++ int g = clampField(offset + scale * rgb[1][y][x], 10);
2866++ int b = clampField(offset + scale * rgb[2][y][x], 10);
2867++ packed[y][x] = (range << 30) | (b << 20) | (g << 10) | r;
2868++ }
2869++ }
2870++}
2871++
2872++/*
2873++ * Resamples a srcW x srcH table with central sampling to destW x destH with
2874++ * corner sampling.
2875++ */
2876++void resampleTable(double *dest, int destW, int destH, double const *src,
2877++ int srcW, int srcH)
2878++{
2879++ /*
2880++ * Precalculate and cache the x sampling locations and phases to
2881++ * save recomputing them on every row.
2882++ */
2883++ ASSERT(destW > 1 && destH > 1 && destW <= 64);
2884++ int xLo[64], xHi[64];
2885++ double xf[64];
2886++ double x = -0.5, xInc = srcW / (destW - 1);
2887++ for (int i = 0; i < destW; i++, x += xInc) {
2888++ xLo[i] = floor(x);
2889++ xf[i] = x - xLo[i];
2890++ xHi[i] = xLo[i] < (srcW - 1) ? (xLo[i] + 1) : (srcW - 1);
2891++ xLo[i] = xLo[i] > 0 ? xLo[i] : 0;
2892++ }
2893++
2894++ /* Now march over the output table generating the new values. */
2895++ double y = -0.5, yInc = srcH / (destH - 1);
2896++ for (int j = 0; j < destH; j++, y += yInc) {
2897++ int yLo = floor(y);
2898++ double yf = y - yLo;
2899++ int yHi = yLo < (srcH - 1) ? (yLo + 1) : (srcH - 1);
2900++ yLo = yLo > 0 ? yLo : 0;
2901++ double const *rowAbove = src + yLo * srcW;
2902++ double const *rowBelow = src + yHi * srcW;
2903++ for (int i = 0; i < destW; i++) {
2904++ double above = rowAbove[xLo[i]] * (1 - xf[i]) +
2905++ rowAbove[xHi[i]] * xf[i];
2906++ double below = rowBelow[xLo[i]] * (1 - xf[i]) +
2907++ rowBelow[xHi[i]] * xf[i];
2908++ *(dest++) = above * (1 - yf) + below * yf;
2909++ }
2910++ }
2911++}
2912++
2913++} /* namespace */
2914++
2915++using ::libpisp::BackEnd;
2916++using ::libpisp::FrontEnd;
2917++
2918++namespace ipa::RPi {
2919++
2920++class IpaPiSP final : public IpaBase
2921++{
2922++public:
2923++ IpaPiSP()
2924++ : IpaBase(), fe_(nullptr), be_(nullptr)
2925++ {
2926++ }
2927++
2928++ ~IpaPiSP()
2929++ {
2930++ if (fe_)
2931++ munmap(fe_, sizeof(FrontEnd));
2932++ if (be_)
2933++ munmap(be_, sizeof(BackEnd));
2934++ }
2935++
2936++private:
2937++ int32_t platformInit(const InitParams &params, InitResult *result) override;
2938++ int32_t platformStart(const ControlList &controls, StartResult *result) override;
2939++ int32_t platformConfigure(const ConfigParams &params, ConfigResult *result) override;
2940++
2941++ void platformPrepareIsp(const PrepareParams &params,
2942++ RPiController::Metadata &rpiMetadata) override;
2943++ RPiController::StatisticsPtr platformProcessStats(Span<uint8_t> mem) override;
2944++
2945++ void handleControls(const ControlList &controls) override;
2946++
2947++ void applyWBG(const AwbStatus *awbStatus, const AgcPrepareStatus *agcStatus,
2948++ pisp_be_global_config &global);
2949++ void applyDgOnly(const AgcPrepareStatus *agcPrepareStatus, pisp_be_global_config &global);
2950++ void applyCAC(const CacStatus *cacStatus, pisp_be_global_config &global);
2951++ void applyContrast(const ContrastStatus *contrastStatus,
2952++ pisp_be_global_config &global);
2953++ void applyCCM(const CcmStatus *ccmStatus, pisp_be_global_config &global);
2954++ void applyBlackLevel(const BlackLevelStatus *blackLevelStatus,
2955++ pisp_be_global_config &global);
2956++ void applyLensShading(const AlscStatus *alscStatus,
2957++ pisp_be_global_config &global);
2958++ void applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global);
2959++ void applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global);
2960++ void applyTdn(const TdnStatus *tdnStatus, const DeviceStatus *deviceStatus,
2961++ pisp_be_global_config &global);
2962++ void applyCdn(const CdnStatus *cdnStatus, pisp_be_global_config &global);
2963++ void applyGeq(const GeqStatus *geqStatus, pisp_be_global_config &global);
2964++ void applySaturation(const SaturationStatus *geqStatus,
2965++ pisp_be_global_config &global);
2966++ void applySharpen(const SharpenStatus *sharpenStatus,
2967++ pisp_be_global_config &global);
2968++ bool applyStitch(const StitchStatus *stitchStatus, const DeviceStatus *deviceStatus,
2969++ const AgcStatus *agcStatus, pisp_be_global_config &global);
2970++ void applyTonemap(const TonemapStatus *tonemapStatus,
2971++ pisp_be_global_config &global);
2972++ void applyFocusStats(const NoiseStatus *noiseStatus);
2973++ void applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls);
2974++
2975++ void setDefaultConfig();
2976++ void setStatsAndDebin();
2977++ void setHistogramWeights();
2978++
2979++ /* Frontend/Backend objects passed in from the pipeline handler. */
2980++ SharedFD feFD_;
2981++ SharedFD beFD_;
2982++ FrontEnd *fe_;
2983++ BackEnd *be_;
2984++
2985++ /* TDN/HDR runtime need the following state. */
2986++ bool tdnReset_;
2987++ utils::Duration lastExposure_;
2988++ std::map<std::string, utils::Duration> lastStitchExposures_;
2989++ HdrStatus lastStitchHdrStatus_;
2990++};
2991++
2992++int32_t IpaPiSP::platformInit(const InitParams &params,
2993++ [[maybe_unused]] InitResult *result)
2994++{
2995++ const std::string &target = controller_.getTarget();
2996++ if (target != "pisp") {
2997++ LOG(IPARPI, Error)
2998++ << "Tuning data file target returned \"" << target << "\""
2999++ << ", expected \"pisp\"";
3000++ return -EINVAL;
3001++ }
3002++
3003++ /* Acquire the Frontend and Backend objects. */
3004++ feFD_ = std::move(params.fe);
3005++ beFD_ = std::move(params.be);
3006++
3007++ if (!feFD_.isValid() || !beFD_.isValid()) {
3008++ LOG(IPARPI, Error) << "Invalid FE/BE handles!";
3009++ return -ENODEV;
3010++ }
3011++
3012++ fe_ = static_cast<FrontEnd *>(mmap(nullptr, sizeof(FrontEnd),
3013++ PROT_READ | PROT_WRITE, MAP_SHARED,
3014++ feFD_.get(), 0));
3015++ be_ = static_cast<BackEnd *>(mmap(nullptr, sizeof(BackEnd),
3016++ PROT_READ | PROT_WRITE, MAP_SHARED,
3017++ beFD_.get(), 0));
3018++
3019++ if (!fe_ || !be_) {
3020++ LOG(IPARPI, Error) << "Unable to map FE/BE handles!";
3021++ return -ENODEV;
3022++ }
3023++
3024++ setDefaultConfig();
3025++
3026++ return 0;
3027++}
3028++
3029++int32_t IpaPiSP::platformStart([[maybe_unused]] const ControlList &controls,
3030++ [[maybe_unused]] StartResult *result)
3031++{
3032++ tdnReset_ = true;
3033++
3034++ /* Cause the stitch block to be reset correctly. */
3035++ lastStitchHdrStatus_ = HdrStatus();
3036++
3037++ return 0;
3038++}
3039++
3040++int32_t IpaPiSP::platformConfigure([[maybe_unused]] const ConfigParams &params,
3041++ [[maybe_unused]] ConfigResult *result)
3042++{
3043++ setStatsAndDebin();
3044++ return 0;
3045++}
3046++
3047++void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams &params,
3048++ RPiController::Metadata &rpiMetadata)
3049++{
3050++ std::scoped_lock<RPiController::Metadata> l(rpiMetadata);
3051++
3052++ pisp_be_global_config global;
3053++ be_->GetGlobal(global);
3054++
3055++ global.bayer_enables &= ~(PISP_BE_BAYER_ENABLE_BLC + PISP_BE_BAYER_ENABLE_WBG +
3056++ PISP_BE_BAYER_ENABLE_GEQ + PISP_BE_BAYER_ENABLE_LSC +
3057++ PISP_BE_BAYER_ENABLE_SDN + PISP_BE_BAYER_ENABLE_CDN +
3058++ PISP_BE_BAYER_ENABLE_TDN_OUTPUT + PISP_BE_BAYER_ENABLE_TDN_INPUT +
3059++ PISP_BE_BAYER_ENABLE_STITCH_INPUT + PISP_BE_BAYER_ENABLE_STITCH_OUTPUT +
3060++ PISP_BE_BAYER_ENABLE_STITCH + PISP_BE_BAYER_ENABLE_TONEMAP);
3061++ /* We leave the YCbCr and inverse conversion enabled in case of false colour or sharpening. */
3062++ global.rgb_enables &= ~(PISP_BE_RGB_ENABLE_GAMMA + PISP_BE_RGB_ENABLE_CCM +
3063++ PISP_BE_RGB_ENABLE_SHARPEN + PISP_BE_RGB_ENABLE_SAT_CONTROL);
3064++
3065++ NoiseStatus *noiseStatus = rpiMetadata.getLocked<NoiseStatus>("noise.status");
3066++ AgcPrepareStatus *agcPrepareStatus = rpiMetadata.getLocked<AgcPrepareStatus>("agc.prepare_status");
3067++
3068++ {
3069++ /* All Frontend config goes first, we do not want to hold the FE lock for long! */
3070++ std::scoped_lock<FrontEnd> lf(*fe_);
3071++
3072++ if (noiseStatus)
3073++ applyFocusStats(noiseStatus);
3074++
3075++ BlackLevelStatus *blackLevelStatus =
3076++ rpiMetadata.getLocked<BlackLevelStatus>("black_level.status");
3077++ if (blackLevelStatus)
3078++ applyBlackLevel(blackLevelStatus, global);
3079++
3080++ AwbStatus *awbStatus = rpiMetadata.getLocked<AwbStatus>("awb.status");
3081++ if (awbStatus && agcPrepareStatus) {
3082++ /* Applies digital gain as well. */
3083++ applyWBG(awbStatus, agcPrepareStatus, global);
3084++ } else if (agcPrepareStatus) {
3085++ /* Mono sensor fallback for digital gain. */
3086++ applyDgOnly(agcPrepareStatus, global);
3087++ }
3088++ }
3089++
3090++ CacStatus *cacStatus = rpiMetadata.getLocked<CacStatus>("cac.status");
3091++ if (cacStatus)
3092++ applyCAC(cacStatus, global);
3093++
3094++ ContrastStatus *contrastStatus =
3095++ rpiMetadata.getLocked<ContrastStatus>("contrast.status");
3096++ if (contrastStatus)
3097++ applyContrast(contrastStatus, global);
3098++
3099++ CcmStatus *ccmStatus = rpiMetadata.getLocked<CcmStatus>("ccm.status");
3100++ if (ccmStatus)
3101++ applyCCM(ccmStatus, global);
3102++
3103++ AlscStatus *alscStatus = rpiMetadata.getLocked<AlscStatus>("alsc.status");
3104++ if (alscStatus)
3105++ applyLensShading(alscStatus, global);
3106++
3107++ DpcStatus *dpcStatus = rpiMetadata.getLocked<DpcStatus>("dpc.status");
3108++ if (dpcStatus)
3109++ applyDPC(dpcStatus, global);
3110++
3111++ SdnStatus *sdnStatus = rpiMetadata.getLocked<SdnStatus>("sdn.status");
3112++ if (sdnStatus)
3113++ applySdn(sdnStatus, global);
3114++
3115++ DeviceStatus *deviceStatus = rpiMetadata.getLocked<DeviceStatus>("device.status");
3116++ TdnStatus *tdnStatus = rpiMetadata.getLocked<TdnStatus>("tdn.status");
3117++ if (tdnStatus && deviceStatus)
3118++ applyTdn(tdnStatus, deviceStatus, global);
3119++
3120++ CdnStatus *cdnStatus = rpiMetadata.getLocked<CdnStatus>("cdn.status");
3121++ if (cdnStatus)
3122++ applyCdn(cdnStatus, global);
3123++
3124++ GeqStatus *geqStatus = rpiMetadata.getLocked<GeqStatus>("geq.status");
3125++ if (geqStatus)
3126++ applyGeq(geqStatus, global);
3127++
3128++ SaturationStatus *saturationStatus =
3129++ rpiMetadata.getLocked<SaturationStatus>("saturation.status");
3130++ if (saturationStatus)
3131++ applySaturation(saturationStatus, global);
3132++
3133++ SharpenStatus *sharpenStatus = rpiMetadata.getLocked<SharpenStatus>("sharpen.status");
3134++ if (sharpenStatus)
3135++ applySharpen(sharpenStatus, global);
3136++
3137++ StitchStatus *stitchStatus = rpiMetadata.getLocked<StitchStatus>("stitch.status");
3138++ if (stitchStatus) {
3139++ /*
3140++ * Note that it's the *delayed* AGC status that contains the HDR mode/channel
3141++ * info that pertains to this frame!
3142++ */
3143++ AgcStatus *agcStatus = rpiMetadata.getLocked<AgcStatus>("agc.delayed_status");
3144++ /* prepareIsp() will fetch this value. Maybe pass it back differently? */
3145++ stitchSwapBuffers_ = applyStitch(stitchStatus, deviceStatus, agcStatus, global);
3146++ } else
3147++ lastStitchHdrStatus_ = HdrStatus();
3148++
3149++ TonemapStatus *tonemapStatus = rpiMetadata.getLocked<TonemapStatus>("tonemap.status");
3150++ if (tonemapStatus)
3151++ applyTonemap(tonemapStatus, global);
3152++
3153++ be_->SetGlobal(global);
3154++
3155++ /* Save this for TDN and HDR on the next frame. */
3156++ lastExposure_ = deviceStatus->shutterSpeed * deviceStatus->analogueGain;
3157++
3158++ /* Lens control */
3159++ const AfStatus *afStatus = rpiMetadata.getLocked<AfStatus>("af.status");
3160++ if (afStatus) {
3161++ ControlList lensctrls(lensCtrls_);
3162++ applyAF(afStatus, lensctrls);
3163++ if (!lensctrls.empty())
3164++ setLensControls.emit(lensctrls);
3165++ }
3166++}
3167++
3168++RPiController::StatisticsPtr IpaPiSP::platformProcessStats(Span<uint8_t> mem)
3169++{
3170++ using namespace RPiController;
3171++
3172++ const pisp_statistics *stats = reinterpret_cast<pisp_statistics *>(mem.data());
3173++
3174++ unsigned int i;
3175++ StatisticsPtr statistics =
3176++ std::make_unique<Statistics>(Statistics::AgcStatsPos::PostWb,
3177++ Statistics::ColourStatsPos::PreLsc);
3178++
3179++ /* RGB histograms are not used, so do not populate them. */
3180++ statistics->yHist = RPiController::Histogram(stats->agc.histogram,
3181++ PISP_AGC_STATS_NUM_BINS);
3182++
3183++ statistics->awbRegions.init({ PISP_AWB_STATS_SIZE, PISP_AWB_STATS_SIZE });
3184++ for (i = 0; i < statistics->awbRegions.numRegions(); i++)
3185++ statistics->awbRegions.set(i, { { stats->awb.zones[i].R_sum,
3186++ stats->awb.zones[i].G_sum,
3187++ stats->awb.zones[i].B_sum },
3188++ stats->awb.zones[i].counted, 0 });
3189++
3190++ /* AGC region sums only get collected on floating zones. */
3191++ statistics->agcRegions.init({ 0, 0 }, PISP_FLOATING_STATS_NUM_ZONES);
3192++ for (i = 0; i < statistics->agcRegions.numRegions(); i++)
3193++ statistics->agcRegions.setFloating(i,
3194++ { { 0, 0, 0, stats->agc.floating[i].Y_sum },
3195++ stats->agc.floating[i].counted, 0 });
3196++
3197++ statistics->focusRegions.init({ PISP_CDAF_STATS_SIZE, PISP_CDAF_STATS_SIZE });
3198++ for (i = 0; i < statistics->focusRegions.numRegions(); i++)
3199++ statistics->focusRegions.set(i, { stats->cdaf.foms[i] >> 20, 0, 0 });
3200++
3201++ if (statsMetadataOutput_) {
3202++ Span<const uint8_t> statsSpan(reinterpret_cast<const uint8_t *>(stats),
3203++ sizeof(pisp_statistics));
3204++ libcameraMetadata_.set(controls::rpi::PispStatsOutput, statsSpan);
3205++ }
3206++
3207++ return statistics;
3208++}
3209++
3210++void IpaPiSP::handleControls(const ControlList &controls)
3211++{
3212++ for (auto const &ctrl : controls) {
3213++ switch (ctrl.first) {
3214++ case controls::HDR_MODE:
3215++ case controls::AE_METERING_MODE:
3216++ setHistogramWeights();
3217++ break;
3218++
3219++ case controls::draft::NOISE_REDUCTION_MODE: {
3220++ RPiController::DenoiseAlgorithm *denoise = dynamic_cast<RPiController::DenoiseAlgorithm *>(
3221++ controller_.getAlgorithm("denoise"));
3222++
3223++ if (!denoise) {
3224++ LOG(IPARPI, Warning)
3225++ << "Could not set NOISE_REDUCTION_MODE - no Denoise algorithm";
3226++ return;
3227++ }
3228++
3229++ if (ctrl.second.get<int32_t>() == controls::draft::NoiseReductionModeOff)
3230++ denoise->setMode(RPiController::DenoiseMode::Off);
3231++ else
3232++ denoise->setMode(RPiController::DenoiseMode::ColourHighQuality);
3233++
3234++ break;
3235++ }
3236++ }
3237++ }
3238++}
3239++
3240++void IpaPiSP::applyWBG(const AwbStatus *awbStatus, const AgcPrepareStatus *agcPrepareStatus,
3241++ pisp_be_global_config &global)
3242++{
3243++ pisp_wbg_config wbg;
3244++ pisp_fe_rgby_config rgby = {};
3245++ double dg = agcPrepareStatus ? agcPrepareStatus->digitalGain : 1.0;
3246++
3247++ wbg.gain_r = clampField(dg * awbStatus->gainR, 14, 10);
3248++ wbg.gain_g = clampField(dg * awbStatus->gainG, 14, 10);
3249++ wbg.gain_b = clampField(dg * awbStatus->gainB, 14, 10);
3250++
3251++ /*
3252++ * The YCbCr conversion block should contain the appropriate YCbCr
3253++ * matrix. We should not rely on the CSC0 block as that might be
3254++ * programmed for RGB outputs.
3255++ */
3256++ pisp_be_ccm_config csc;
3257++ be_->GetYcbcr(csc);
3258++
3259++ /* The CSC coefficients already have the << 10 scaling applied. */
3260++ rgby.gain_r = clampField(csc.coeffs[0] * awbStatus->gainR, 14);
3261++ rgby.gain_g = clampField(csc.coeffs[1] * awbStatus->gainG, 14);
3262++ rgby.gain_b = clampField(csc.coeffs[2] * awbStatus->gainB, 14);
3263++
3264++ LOG(IPARPI, Debug) << "Applying WB R: " << awbStatus->gainR << " B: "
3265++ << awbStatus->gainB;
3266++
3267++ be_->SetWbg(wbg);
3268++ fe_->SetRGBY(rgby);
3269++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_WBG;
3270++}
3271++
3272++void IpaPiSP::applyDgOnly(const AgcPrepareStatus *agcPrepareStatus, pisp_be_global_config &global)
3273++{
3274++ pisp_wbg_config wbg;
3275++
3276++ wbg.gain_r = clampField(agcPrepareStatus->digitalGain, 14, 10);
3277++ wbg.gain_g = clampField(agcPrepareStatus->digitalGain, 14, 10);
3278++ wbg.gain_b = clampField(agcPrepareStatus->digitalGain, 14, 10);
3279++
3280++ LOG(IPARPI, Debug) << "Applying DG (only) : " << agcPrepareStatus->digitalGain;
3281++
3282++ be_->SetWbg(wbg);
3283++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_WBG;
3284++}
3285++
3286++void IpaPiSP::applyContrast(const ContrastStatus *contrastStatus,
3287++ pisp_be_global_config &global)
3288++{
3289++ pisp_be_gamma_config gamma;
3290++
3291++ if (!generateLut(contrastStatus->gammaCurve, gamma.lut, PISP_BE_GAMMA_LUT_SIZE)) {
3292++ be_->SetGamma(gamma);
3293++ global.rgb_enables |= PISP_BE_RGB_ENABLE_GAMMA;
3294++ }
3295++}
3296++
3297++void IpaPiSP::applyCCM(const CcmStatus *ccmStatus, pisp_be_global_config &global)
3298++{
3299++ pisp_be_ccm_config ccm = {};
3300++
3301++ for (unsigned int i = 0; i < 9; i++)
3302++ ccm.coeffs[i] = clampField(ccmStatus->matrix[i], 14, 10, true);
3303++
3304++ be_->SetCcm(ccm);
3305++ global.rgb_enables |= PISP_BE_RGB_ENABLE_CCM;
3306++}
3307++
3308++void IpaPiSP::applyCAC(const CacStatus *cacStatus, pisp_be_global_config &global)
3309++{
3310++ pisp_be_cac_config cac = {};
3311++
3312++ for (int x = 0; x < PISP_BE_CAC_GRID_SIZE + 1; x++) {
3313++ for (int y = 0; y < PISP_BE_CAC_GRID_SIZE + 1; y++) {
3314++ cac.lut[y][x][0][0] = clampField(cacStatus->lutRx[y * (PISP_BE_CAC_GRID_SIZE + 1) + x], 7, 5, true);
3315++ cac.lut[y][x][0][1] = clampField(cacStatus->lutRy[y * (PISP_BE_CAC_GRID_SIZE + 1) + x], 7, 5, true);
3316++ cac.lut[y][x][1][0] = clampField(cacStatus->lutBx[y * (PISP_BE_CAC_GRID_SIZE + 1) + x], 7, 5, true);
3317++ cac.lut[y][x][1][1] = clampField(cacStatus->lutBy[y * (PISP_BE_CAC_GRID_SIZE + 1) + x], 7, 5, true);
3318++ }
3319++ }
3320++
3321++ be_->SetCac(cac);
3322++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_CAC;
3323++}
3324++
3325++void IpaPiSP::applyBlackLevel(const BlackLevelStatus *blackLevelStatus, pisp_be_global_config &global)
3326++{
3327++ uint16_t minBlackLevel = std::min({ blackLevelStatus->blackLevelR, blackLevelStatus->blackLevelG,
3328++ blackLevelStatus->blackLevelB });
3329++ pisp_bla_config bla;
3330++
3331++ /*
3332++ * Set the Frontend to adjust the black level to the smallest black level
3333++ * of all channels (in 16-bits).
3334++ */
3335++ bla.black_level_r = blackLevelStatus->blackLevelR;
3336++ bla.black_level_gr = blackLevelStatus->blackLevelG;
3337++ bla.black_level_gb = blackLevelStatus->blackLevelG;
3338++ bla.black_level_b = blackLevelStatus->blackLevelB;
3339++ bla.output_black_level = minBlackLevel;
3340++ fe_->SetBla(bla);
3341++
3342++ /* Frontend Stats and Backend black level correction. */
3343++ bla.black_level_r = bla.black_level_gr =
3344++ bla.black_level_gb = bla.black_level_b = minBlackLevel;
3345++ bla.output_black_level = 0;
3346++ fe_->SetBlc(bla);
3347++ be_->SetBlc(bla);
3348++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_BLC;
3349++}
3350++
3351++void IpaPiSP::applyLensShading(const AlscStatus *alscStatus,
3352++ pisp_be_global_config &global)
3353++{
3354++ pisp_be_lsc_extra lscExtra = {};
3355++ pisp_be_lsc_config lsc = {};
3356++ double rgb[3][NumLscVertexes][NumLscVertexes] = {};
3357++
3358++ resampleTable(&rgb[0][0][0], NumLscVertexes, NumLscVertexes,
3359++ alscStatus->r.data(), NumLscCells, NumLscCells);
3360++ resampleTable(&rgb[1][0][0], NumLscVertexes, NumLscVertexes,
3361++ alscStatus->g.data(), NumLscCells, NumLscCells);
3362++ resampleTable(&rgb[2][0][0], NumLscVertexes, NumLscVertexes,
3363++ alscStatus->b.data(), NumLscCells, NumLscCells);
3364++ packLscLut(lsc.lut_packed, rgb);
3365++ be_->SetLsc(lsc, lscExtra);
3366++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_LSC;
3367++}
3368++
3369++void IpaPiSP::applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global)
3370++{
3371++ pisp_be_dpc_config dpc = {};
3372++
3373++ switch (dpcStatus->strength) {
3374++ case 0: /* "off" */
3375++ break;
3376++ case 1: /* "normal" */
3377++ dpc.coeff_level = 1;
3378++ dpc.coeff_range = 8;
3379++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_DPC;
3380++ break;
3381++ case 2: /* "strong" */
3382++ dpc.coeff_level = 0;
3383++ dpc.coeff_range = 0;
3384++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_DPC;
3385++ break;
3386++ default:
3387++ ASSERT(0);
3388++ }
3389++
3390++ be_->SetDpc(dpc);
3391++}
3392++
3393++void IpaPiSP::applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global)
3394++{
3395++ pisp_be_sdn_config sdn = {};
3396++ pisp_bla_config blc;
3397++
3398++ be_->GetBlc(blc);
3399++ /* All R/G/B black levels are the same value in the BE after FE alignment */
3400++ sdn.black_level = blc.black_level_r;
3401++ /* leakage is "amount of the original pixel we let through", thus 1 - strength */
3402++ sdn.leakage = clampField(1.0 - sdnStatus->strength, 8, 8);
3403++ sdn.noise_constant = clampField(sdnStatus->noiseConstant, 16);
3404++ sdn.noise_slope = clampField(sdnStatus->noiseSlope, 16, 8);
3405++ sdn.noise_constant2 = clampField(sdnStatus->noiseConstant2, 16);
3406++ sdn.noise_slope2 = clampField(sdnStatus->noiseSlope2, 16, 8);
3407++ be_->SetSdn(sdn);
3408++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_SDN;
3409++}
3410++
3411++void IpaPiSP::applyTdn(const TdnStatus *tdnStatus, const DeviceStatus *deviceStatus,
3412++ pisp_be_global_config &global)
3413++{
3414++ utils::Duration exposure = deviceStatus->shutterSpeed * deviceStatus->analogueGain;
3415++ pisp_be_tdn_config tdn = {};
3416++
3417++ double ratio = tdnReset_ ? 1.0 : exposure / lastExposure_;
3418++ if (ratio >= 4.0) {
3419++ /* If the exposure ratio goes above 4x, we need to reset TDN. */
3420++ ratio = 1;
3421++ tdnReset_ = true;
3422++ }
3423++
3424++ LOG(IPARPI, Debug) << "TDN: exposure: " << exposure
3425++ << " last: " << lastExposure_
3426++ << " ratio: " << ratio;
3427++
3428++ pisp_bla_config blc;
3429++ be_->GetBlc(blc);
3430++ /* All R/G/B black levels are the same value in the BE after FE alignment */
3431++ tdn.black_level = blc.black_level_r;
3432++ tdn.ratio = clampField(ratio, 16, 14);
3433++ tdn.noise_constant = clampField(tdnStatus->noiseConstant, 16);
3434++ tdn.noise_slope = clampField(tdnStatus->noiseSlope, 16, 8);
3435++ tdn.threshold = clampField(tdnStatus->threshold, 16, 16);
3436++
3437++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_TDN + PISP_BE_BAYER_ENABLE_TDN_OUTPUT;
3438++
3439++ /* Only enable the TDN Input after a state reset. */
3440++ if (!tdnReset_) {
3441++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_TDN_INPUT;
3442++ tdn.reset = 0;
3443++ } else
3444++ tdn.reset = 1;
3445++
3446++ be_->SetTdn(tdn);
3447++ tdnReset_ = false;
3448++}
3449++
3450++void IpaPiSP::applyCdn(const CdnStatus *cdnStatus, pisp_be_global_config &global)
3451++{
3452++ pisp_be_cdn_config cdn = {};
3453++
3454++ cdn.thresh = clampField(cdnStatus->threshold, 16);
3455++ cdn.iir_strength = clampField(cdnStatus->strength, 8, 8);
3456++ cdn.g_adjust = clampField(0, 8, 8);
3457++ be_->SetCdn(cdn);
3458++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_CDN;
3459++}
3460++
3461++void IpaPiSP::applyGeq(const GeqStatus *geqStatus, pisp_be_global_config &global)
3462++{
3463++ pisp_be_geq_config geq = {};
3464++
3465++ geq.min = 0;
3466++ geq.max = 0xffff;
3467++ geq.offset = clampField(geqStatus->offset, 16);
3468++ geq.slope_sharper = clampField(geqStatus->slope, 10, 10);
3469++ be_->SetGeq(geq);
3470++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_GEQ;
3471++}
3472++
3473++void IpaPiSP::applySaturation(const SaturationStatus *saturationStatus,
3474++ pisp_be_global_config &global)
3475++{
3476++ pisp_be_sat_control_config saturation;
3477++ pisp_wbg_config wbg;
3478++
3479++ saturation.shift_r = std::min<uint8_t>(2, saturationStatus->shiftR);
3480++ saturation.shift_g = std::min<uint8_t>(2, saturationStatus->shiftG);
3481++ saturation.shift_b = std::min<uint8_t>(2, saturationStatus->shiftB);
3482++ be_->SetSatControl(saturation);
3483++
3484++ be_->GetWbg(wbg);
3485++ wbg.gain_r >>= saturationStatus->shiftR;
3486++ wbg.gain_g >>= saturationStatus->shiftG;
3487++ wbg.gain_b >>= saturationStatus->shiftB;
3488++ be_->SetWbg(wbg);
3489++
3490++ global.rgb_enables |= PISP_BE_RGB_ENABLE_SAT_CONTROL;
3491++}
3492++
3493++void IpaPiSP::applySharpen(const SharpenStatus *sharpenStatus,
3494++ pisp_be_global_config &global)
3495++{
3496++ /*
3497++ * This threshold scaling is to normalise the VC4 and PiSP parameter
3498++ * scales in the tuning config.
3499++ */
3500++ static constexpr double ThresholdScaling = 0.25;
3501++ const double scaling = sharpenStatus->threshold * ThresholdScaling;
3502++
3503++ pisp_be_sh_fc_combine_config shfc;
3504++ pisp_be_sharpen_config sharpen;
3505++
3506++ be_->InitialiseSharpen(sharpen, shfc);
3507++ sharpen.threshold_offset0 = clampField(sharpen.threshold_offset0 * scaling, 16);
3508++ sharpen.threshold_offset1 = clampField(sharpen.threshold_offset1 * scaling, 16);
3509++ sharpen.threshold_offset2 = clampField(sharpen.threshold_offset2 * scaling, 16);
3510++ sharpen.threshold_offset3 = clampField(sharpen.threshold_offset3 * scaling, 16);
3511++ sharpen.threshold_offset4 = clampField(sharpen.threshold_offset4 * scaling, 16);
3512++ sharpen.threshold_slope0 = clampField(sharpen.threshold_slope0 * scaling, 12);
3513++ sharpen.threshold_slope1 = clampField(sharpen.threshold_slope1 * scaling, 12);
3514++ sharpen.threshold_slope2 = clampField(sharpen.threshold_slope2 * scaling, 12);
3515++ sharpen.threshold_slope3 = clampField(sharpen.threshold_slope3 * scaling, 12);
3516++ sharpen.threshold_slope4 = clampField(sharpen.threshold_slope4 * scaling, 12);
3517++ sharpen.positive_strength = clampField(sharpen.positive_strength * sharpenStatus->strength, 12);
3518++ sharpen.negative_strength = clampField(sharpen.negative_strength * sharpenStatus->strength, 12);
3519++ sharpen.positive_pre_limit = clampField(sharpen.positive_pre_limit * sharpenStatus->limit, 16);
3520++ sharpen.positive_limit = clampField(sharpen.positive_limit * sharpenStatus->limit, 16);
3521++ sharpen.negative_pre_limit = clampField(sharpen.negative_pre_limit * sharpenStatus->limit, 16);
3522++ sharpen.negative_limit = clampField(sharpen.negative_limit * sharpenStatus->limit, 16);
3523++
3524++ be_->SetSharpen(sharpen);
3525++ /* The conversion to YCbCr and back is always enabled. */
3526++ global.rgb_enables |= PISP_BE_RGB_ENABLE_SHARPEN;
3527++}
3528++
3529++bool IpaPiSP::applyStitch(const StitchStatus *stitchStatus, const DeviceStatus *deviceStatus,
3530++ const AgcStatus *agcStatus, pisp_be_global_config &global)
3531++{
3532++ /*
3533++ * Find out what HDR mode/channel this frame is. Normally this will be in the delayed
3534++ * HDR status (in the AGC status), though after a mode switch this will be absent and
3535++ * the information will have been stored in the hdrStatus_ field.
3536++ */
3537++ const HdrStatus *hdrStatus = &hdrStatus_;
3538++ if (agcStatus)
3539++ hdrStatus = &agcStatus->hdr;
3540++
3541++ bool modeChange = hdrStatus->mode != lastStitchHdrStatus_.mode;
3542++ bool channelChange = !modeChange && hdrStatus->channel != lastStitchHdrStatus_.channel;
3543++ lastStitchHdrStatus_ = *hdrStatus;
3544++
3545++ /* Check for a change of HDR mode. That forces us to start over. */
3546++ if (modeChange)
3547++ lastStitchExposures_.clear();
3548++
3549++ if (hdrStatus->channel != "short" && hdrStatus->channel != "long") {
3550++ /* The channel *must* be long or short, anything else does not make sense. */
3551++ LOG(IPARPI, Warning) << "Stitch channel is not long or short";
3552++ return false;
3553++ }
3554++
3555++ /* Whatever happens, we're going to output this buffer now. */
3556++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_STITCH_OUTPUT;
3557++
3558++ utils::Duration exposure = deviceStatus->shutterSpeed * deviceStatus->analogueGain;
3559++ lastStitchExposures_[hdrStatus->channel] = exposure;
3560++
3561++ /* If the other channel hasn't been seen there's nothing more we can do. */
3562++ std::string otherChannel = hdrStatus->channel == "short" ? "long" : "short";
3563++ if (lastStitchExposures_.find(otherChannel) == lastStitchExposures_.end()) {
3564++ /* The first channel should be "short". */
3565++ if (hdrStatus->channel != "short")
3566++ LOG(IPARPI, Warning) << "First frame is not short";
3567++ return false;
3568++ }
3569++
3570++ /* We have both channels, we need to enable stitching. */
3571++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_STITCH_INPUT + PISP_BE_BAYER_ENABLE_STITCH;
3572++
3573++ utils::Duration otherExposure = lastStitchExposures_[otherChannel];
3574++ bool phaseLong = hdrStatus->channel == "long";
3575++ double ratio = phaseLong ? otherExposure / exposure : exposure / otherExposure;
3576++
3577++ pisp_be_stitch_config stitch = {};
3578++ stitch.exposure_ratio = clampField(ratio, 15, 15);
3579++ if (phaseLong)
3580++ stitch.exposure_ratio |= PISP_BE_STITCH_STREAMING_LONG;
3581++ /* These will be filled in correctly once we have implemented the HDR algorithm. */
3582++ stitch.threshold_lo = stitchStatus->thresholdLo;
3583++ stitch.threshold_diff_power = stitchStatus->diffPower;
3584++ stitch.motion_threshold_256 = stitchStatus->motionThreshold;
3585++ be_->SetStitch(stitch);
3586++
3587++ return channelChange;
3588++}
3589++
3590++void IpaPiSP::applyTonemap(const TonemapStatus *tonemapStatus, pisp_be_global_config &global)
3591++{
3592++ pisp_be_tonemap_config tonemap = {};
3593++
3594++ tonemap.detail_constant = clampField(tonemapStatus->detailConstant, 16);
3595++ tonemap.detail_slope = clampField(tonemapStatus->detailSlope, 16, 8);
3596++ tonemap.iir_strength = clampField(tonemapStatus->iirStrength, 12, 4);
3597++ tonemap.strength = clampField(tonemapStatus->strength, 12, 8);
3598++
3599++ if (!generateLut(tonemapStatus->tonemap, tonemap.lut, PISP_BE_TONEMAP_LUT_SIZE)) {
3600++ be_->SetTonemap(tonemap);
3601++ global.bayer_enables |= PISP_BE_BAYER_ENABLE_TONEMAP;
3602++ }
3603++}
3604++
3605++void IpaPiSP::applyFocusStats(const NoiseStatus *noiseStatus)
3606++{
3607++ pisp_fe_cdaf_stats_config cdaf;
3608++ fe_->GetCdafStats(cdaf);
3609++
3610++ cdaf.noise_constant = noiseStatus->noiseConstant;
3611++ cdaf.noise_slope = noiseStatus->noiseSlope;
3612++ fe_->SetCdafStats(cdaf);
3613++}
3614++
3615++void IpaPiSP::applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls)
3616++{
3617++ if (afStatus->lensSetting) {
3618++ ControlValue v(afStatus->lensSetting.value());
3619++ lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, v);
3620++ }
3621++}
3622++
3623++void IpaPiSP::setDefaultConfig()
3624++{
3625++ std::scoped_lock<FrontEnd> l(*fe_);
3626++
3627++ pisp_be_global_config beGlobal;
3628++ pisp_fe_global_config feGlobal;
3629++
3630++ fe_->GetGlobal(feGlobal);
3631++ be_->GetGlobal(beGlobal);
3632++ /*
3633++ * Always go to YCbCr and back. We need them if the false colour block is enabled,
3634++ * and even for mono sensors if sharpening is enabled. So we're better off enabling
3635++ * them all the time.
3636++ */
3637++ beGlobal.rgb_enables |= PISP_BE_RGB_ENABLE_YCBCR + PISP_BE_RGB_ENABLE_YCBCR_INVERSE;
3638++
3639++ if (!monoSensor()) {
3640++ beGlobal.bayer_enables |= PISP_BE_BAYER_ENABLE_DEMOSAIC;
3641++ beGlobal.rgb_enables |= PISP_BE_RGB_ENABLE_FALSE_COLOUR;
3642++ }
3643++
3644++ /*
3645++ * Ask the AWB algorithm for reasonable gain values so that we can program the
3646++ * front end stats sensibly. We must also factor in the conversion to luminance.
3647++ */
3648++ pisp_fe_rgby_config rgby = {};
3649++ double gainR = 1.5, gainB = 1.5;
3650++ RPiController::AwbAlgorithm *awb = dynamic_cast<RPiController::AwbAlgorithm *>(
3651++ controller_.getAlgorithm("awb"));
3652++ if (awb)
3653++ awb->initialValues(gainR, gainB);
3654++ /* The BT.601 RGB -> Y coefficients will do. The precise values are not critical. */
3655++ rgby.gain_r = clampField(gainR * 0.299, 14, 10);
3656++ rgby.gain_g = clampField(1.0 * .587, 14, 10);
3657++ rgby.gain_b = clampField(gainB * .114, 14, 10);
3658++ fe_->SetRGBY(rgby);
3659++ feGlobal.enables |= PISP_FE_ENABLE_RGBY;
3660++
3661++ /* Also get sensible front end black level defaults, for the same reason. */
3662++ RPiController::BlackLevelAlgorithm *blackLevel = dynamic_cast<RPiController::BlackLevelAlgorithm *>(
3663++ controller_.getAlgorithm("black_level"));
3664++ if (blackLevel) {
3665++ uint16_t blackLevelR, blackLevelG, blackLevelB;
3666++ BlackLevelStatus blackLevelStatus;
3667++
3668++ blackLevel->initialValues(blackLevelR, blackLevelG, blackLevelB);
3669++ blackLevelStatus.blackLevelR = blackLevelR;
3670++ blackLevelStatus.blackLevelG = blackLevelG;
3671++ blackLevelStatus.blackLevelB = blackLevelB;
3672++ applyBlackLevel(&blackLevelStatus, beGlobal);
3673++ feGlobal.enables |= PISP_FE_ENABLE_BLA + PISP_FE_ENABLE_BLC;
3674++ }
3675++
3676++ fe_->SetGlobal(feGlobal);
3677++ be_->SetGlobal(beGlobal);
3678++}
3679++
3680++void IpaPiSP::setStatsAndDebin()
3681++{
3682++ pisp_fe_crop_config crop{ 0, 0, mode_.width, mode_.height };
3683++
3684++ pisp_fe_awb_stats_config awb = {};
3685++ awb.r_lo = awb.g_lo = awb.b_lo = 0;
3686++ awb.r_hi = awb.g_hi = awb.b_hi = 65535 * 0.98;
3687++
3688++ pisp_fe_cdaf_stats_config cdaf = {};
3689++ cdaf.mode = (1 << 4) + (1 << 2) + 1; /* Gr / Gb count with weights of (1, 1) */
3690++
3691++ {
3692++ std::scoped_lock<FrontEnd> l(*fe_);
3693++ pisp_fe_global_config feGlobal;
3694++ fe_->GetGlobal(feGlobal);
3695++ feGlobal.enables |= PISP_FE_ENABLE_AWB_STATS + PISP_FE_ENABLE_AGC_STATS +
3696++ PISP_FE_ENABLE_CDAF_STATS;
3697++
3698++ fe_->SetGlobal(feGlobal);
3699++ fe_->SetStatsCrop(crop);
3700++ fe_->SetAwbStats(awb);
3701++ fe_->SetCdafStats(cdaf);
3702++ }
3703++
3704++ /*
3705++ * Apply the correct AGC region weights to the Frontend. Need to do this
3706++ * out of the Frontend scoped lock.
3707++ */
3708++ setHistogramWeights();
3709++
3710++ pisp_be_global_config beGlobal;
3711++ be_->GetGlobal(beGlobal);
3712++
3713++ if (mode_.binX > 1 || mode_.binY > 1) {
3714++ pisp_be_debin_config debin;
3715++
3716++ be_->GetDebin(debin);
3717++ debin.h_enable = (mode_.binX > 1);
3718++ debin.v_enable = (mode_.binY > 1);
3719++ be_->SetDebin(debin);
3720++ beGlobal.bayer_enables |= PISP_BE_BAYER_ENABLE_DEBIN;
3721++ } else
3722++ beGlobal.bayer_enables &= ~PISP_BE_BAYER_ENABLE_DEBIN;
3723++
3724++ be_->SetGlobal(beGlobal);
3725++}
3726++
3727++void IpaPiSP::setHistogramWeights()
3728++{
3729++ RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
3730++ controller_.getAlgorithm("agc"));
3731++ if (!agc)
3732++ return;
3733++
3734++ const std::vector<double> &weights = agc->getWeights();
3735++
3736++ pisp_fe_agc_stats_config config;
3737++ memset(&config, 0, sizeof(config));
3738++
3739++ /*
3740++ * The AGC software gives us a 15x15 table of weights which we
3741++ * map onto 16x16 in the hardware, ensuring the rightmost column
3742++ * and bottom row all have zero weight. We align everything to
3743++ * the native 2x2 Bayer pixel blocks.
3744++ */
3745++ const Size &size = controller_.getHardwareConfig().agcZoneWeights;
3746++ int width = (mode_.width / size.width) & ~1;
3747++ int height = (mode_.height / size.height) & ~1;
3748++ config.offset_x = ((mode_.width - size.width * width) / 2) & ~1;
3749++ config.offset_y = ((mode_.height - size.height * height) / 2) & ~1;
3750++ config.size_x = width;
3751++ config.size_y = height;
3752++
3753++ unsigned int idx = 0;
3754++ for (unsigned int row = 0; row < size.height; row++) {
3755++ unsigned int col = 0;
3756++ for (; col < size.width / 2; col++) {
3757++ int wt0 = clampField(weights[idx++], 4, 0, false, "agc weights");
3758++ int wt1 = clampField(weights[idx++], 4, 0, false, "agc weights");
3759++ config.weights[row * 8 + col] = (wt1 << 4) | wt0;
3760++ }
3761++ if (size.width & 1)
3762++ config.weights[row * 8 + col] =
3763++ clampField(weights[idx++], 4, 0, false, "agc weights");
3764++ }
3765++
3766++ std::scoped_lock<FrontEnd> l(*fe_);
3767++ fe_->SetAgcStats(config);
3768++}
3769++
3770++} /* namespace ipa::RPi */
3771++
3772++/*
3773++ * External IPA module interface
3774++ */
3775++extern "C" {
3776++const IPAModuleInfo ipaModuleInfo = {
3777++ IPA_MODULE_API_VERSION,
3778++ 1,
3779++ "rpi/pisp",
3780++ "rpi/pisp",
3781++};
3782++
3783++IPAInterface *ipaCreate()
3784++{
3785++ return new ipa::RPi::IpaPiSP();
3786++}
3787++
3788++} /* extern "C" */
3789++
3790++} /* namespace libcamera */
3791+--- a/src/libcamera/control_ids_rpi.yaml 2024-11-25 21:08:37.649494681 +0530
3792++++ b/src/libcamera/control_ids_rpi.yaml 2024-11-25 21:08:37.639494279 +0530
3793+@@ -30,4 +30,41 @@
3794+
3795+ \sa StatsOutputEnable
3796+
3797++ - ScalerCrops:
3798++ type: Rectangle
3799++ size: [n]
3800++ description: |
3801++ An array of rectangles, where each singular value has identical
3802++ functionality to the ScalerCrop control. This control allows the
3803++ Raspberry Pi pipeline handler to control individual scaler crops per
3804++ output stream.
3805++
3806++ The order of rectangles passed into the control must match the order of
3807++ streams configured by the application. The pipeline handler will only
3808++ configure crop retangles up-to the number of output streams configured.
3809++ All subsequent rectangles passed into this control are ignored by the
3810++ pipeline handler.
3811++
3812++ If both rpi::ScalerCrops and ScalerCrop controls are present in a
3813++ ControlList, the latter is discarded, and crops are obtained from this
3814++ control.
3815++
3816++ Note that using different crop rectangles for each output stream with
3817++ this control is only applicable on the Pi5/PiSP platform. This control
3818++ should also be considered temporary/draft and will be replaced with
3819++ official libcamera API support for per-stream controls in the future.
3820++
3821++ \sa ScalerCrop
3822++
3823++ - PispStatsOutput:
3824++ type: uint8_t
3825++ size: [n]
3826++ description: |
3827++ Span of the PiSP Frontend ISP generated statistics for the current
3828++ frame. This is sent in the Request metadata if the StatsOutputEnable is
3829++ set to true. The statistics struct definition can be found in
3830++ https://github.com/raspberrypi/libpisp/blob/main/src/libpisp/frontend/pisp_statistics.h
3831++
3832++ \sa StatsOutputEnable
3833++
3834+ ...
3835+--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp 2024-11-25 21:08:37.649494681 +0530
3836++++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp 2024-11-25 21:08:37.640494319 +0530
3837+@@ -181,12 +181,14 @@
3838+
3839+ rawStreams_.clear();
3840+ outStreams_.clear();
3841++ unsigned int rawStreamIndex = 0;
3842++ unsigned int outStreamIndex = 0;
3843+
3844+- for (const auto &[index, cfg] : utils::enumerate(config_)) {
3845++ for (auto &cfg : config_) {
3846+ if (PipelineHandlerBase::isRaw(cfg.pixelFormat))
3847+- rawStreams_.emplace_back(index, &cfg);
3848++ rawStreams_.emplace_back(rawStreamIndex++, &cfg);
3849+ else
3850+- outStreams_.emplace_back(index, &cfg);
3851++ outStreams_.emplace_back(outStreamIndex++, &cfg);
3852+ }
3853+
3854+ /* Sort the streams so the highest resolution is first. */
3855+@@ -533,6 +535,7 @@
3856+ * Platform specific internal stream configuration. This also assigns
3857+ * external streams which get configured below.
3858+ */
3859++ data->cropParams_.clear();
3860+ ret = data->platformConfigure(rpiConfig);
3861+ if (ret)
3862+ return ret;
3863+@@ -545,12 +548,6 @@
3864+ }
3865+
3866+ /*
3867+- * Set the scaler crop to the value we are using (scaled to native sensor
3868+- * coordinates).
3869+- */
3870+- data->scalerCrop_ = data->scaleIspCrop(data->ispCrop_);
3871+-
3872+- /*
3873+ * Update the ScalerCropMaximum to the correct value for this camera mode.
3874+ * For us, it's the same as the "analogue crop".
3875+ *
3876+@@ -567,9 +564,28 @@
3877+ for (auto const &c : result.controlInfo)
3878+ ctrlMap.emplace(c.first, c.second);
3879+
3880+- /* Add the ScalerCrop control limits based on the current mode. */
3881+- Rectangle ispMinCrop = data->scaleIspCrop(Rectangle(data->ispMinCropSize_));
3882+- ctrlMap[&controls::ScalerCrop] = ControlInfo(ispMinCrop, data->sensorInfo_.analogCrop, data->scalerCrop_);
3883++ const auto cropParamsIt = data->cropParams_.find(0);
3884++ if (cropParamsIt != data->cropParams_.end()) {
3885++ const CameraData::CropParams &cropParams = cropParamsIt->second;
3886++ /*
3887++ * Add the ScalerCrop control limits based on the current mode and
3888++ * the first configured stream.
3889++ */
3890++ Rectangle ispMinCrop = data->scaleIspCrop(Rectangle(cropParams.ispMinCropSize));
3891++ ctrlMap[&controls::ScalerCrop] = ControlInfo(ispMinCrop, data->sensorInfo_.analogCrop,
3892++ data->scaleIspCrop(cropParams.ispCrop));
3893++ if (data->cropParams_.size() == 2) {
3894++ /*
3895++ * The control map for rpi::ScalerCrops has the min value
3896++ * as the default crop for stream 0, max value as the default
3897++ * value for stream 1.
3898++ */
3899++ ctrlMap[&controls::rpi::ScalerCrops] =
3900++ ControlInfo(data->scaleIspCrop(data->cropParams_.at(0).ispCrop),
3901++ data->scaleIspCrop(data->cropParams_.at(1).ispCrop),
3902++ ctrlMap[&controls::ScalerCrop].def());
3903++ }
3904++ }
3905+
3906+ data->controlInfo_ = ControlInfoMap(std::move(ctrlMap), result.controlInfo.idmap());
3907+
3908+@@ -1295,9 +1311,30 @@
3909+
3910+ void CameraData::applyScalerCrop(const ControlList &controls)
3911+ {
3912+- const auto &scalerCrop = controls.get<Rectangle>(controls::ScalerCrop);
3913+- if (scalerCrop) {
3914+- Rectangle nativeCrop = *scalerCrop;
3915++ const auto &scalerCropRPi = controls.get<Span<const Rectangle>>(controls::rpi::ScalerCrops);
3916++ const auto &scalerCropCore = controls.get<Rectangle>(controls::ScalerCrop);
3917++ std::vector<Rectangle> scalerCrops;
3918++
3919++ /*
3920++ * First thing to do is create a vector of crops to apply to each ISP output
3921++ * based on either controls::ScalerCrop or controls::rpi::ScalerCrops if
3922++ * present.
3923++ *
3924++ * If controls::rpi::ScalerCrops is preset, apply the given crops to the
3925++ * ISP output streams, indexed by the same order in which they had been
3926++ * configured. This is not the same as the ISP output index. Otherwise
3927++ * if controls::ScalerCrop is present, apply the same crop to all ISP
3928++ * output streams.
3929++ */
3930++ for (unsigned int i = 0; i < cropParams_.size(); i++) {
3931++ if (scalerCropRPi && i < scalerCropRPi->size())
3932++ scalerCrops.push_back(scalerCropRPi->data()[i]);
3933++ else if (scalerCropCore)
3934++ scalerCrops.push_back(*scalerCropCore);
3935++ }
3936++
3937++ for (auto const &[i, scalerCrop] : utils::enumerate(scalerCrops)) {
3938++ Rectangle nativeCrop = scalerCrop;
3939+
3940+ if (!nativeCrop.width || !nativeCrop.height)
3941+ nativeCrop = { 0, 0, 1, 1 };
3942+@@ -1313,20 +1350,13 @@
3943+ * 2. With the same mid-point, if possible.
3944+ * 3. But it can't go outside the sensor area.
3945+ */
3946+- Size minSize = ispMinCropSize_.expandedToAspectRatio(nativeCrop.size());
3947++ Size minSize = cropParams_.at(i).ispMinCropSize.expandedToAspectRatio(nativeCrop.size());
3948+ Size size = ispCrop.size().expandedTo(minSize);
3949+ ispCrop = size.centeredTo(ispCrop.center()).enclosedIn(Rectangle(sensorInfo_.outputSize));
3950+
3951+- if (ispCrop != ispCrop_) {
3952+- ispCrop_ = ispCrop;
3953+- platformSetIspCrop();
3954+-
3955+- /*
3956+- * Also update the ScalerCrop in the metadata with what we actually
3957+- * used. But we must first rescale that from ISP (camera mode) pixels
3958+- * back into sensor native pixels.
3959+- */
3960+- scalerCrop_ = scaleIspCrop(ispCrop_);
3961++ if (ispCrop != cropParams_.at(i).ispCrop) {
3962++ cropParams_.at(i).ispCrop = ispCrop;
3963++ platformSetIspCrop(cropParams_.at(i).ispIndex, ispCrop);
3964+ }
3965+ }
3966+ }
3967+@@ -1483,7 +1513,18 @@
3968+ request->metadata().set(controls::SensorTimestamp,
3969+ bufferControls.get(controls::SensorTimestamp).value_or(0));
3970+
3971+- request->metadata().set(controls::ScalerCrop, scalerCrop_);
3972++ if (cropParams_.size()) {
3973++ std::vector<Rectangle> crops;
3974++
3975++ for (auto const &[k, v] : cropParams_)
3976++ crops.push_back(scaleIspCrop(v.ispCrop));
3977++
3978++ request->metadata().set(controls::ScalerCrop, crops[0]);
3979++ if (crops.size() > 1) {
3980++ request->metadata().set(controls::rpi::ScalerCrops,
3981++ Span<const Rectangle>(crops.data(), crops.size()));
3982++ }
3983++ }
3984+ }
3985+
3986+ } /* namespace libcamera */
3987+--- a/src/libcamera/pipeline/rpi/common/pipeline_base.h 2024-11-25 21:08:37.649494681 +0530
3988++++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h 2024-11-25 21:08:37.640494319 +0530
3989+@@ -83,7 +83,7 @@
3990+
3991+ Rectangle scaleIspCrop(const Rectangle &ispCrop) const;
3992+ void applyScalerCrop(const ControlList &controls);
3993+- virtual void platformSetIspCrop() = 0;
3994++ virtual void platformSetIspCrop(unsigned int index, const Rectangle &ispCrop) = 0;
3995+
3996+ void cameraTimeout();
3997+ void frameStarted(uint32_t sequence);
3998+@@ -133,9 +133,23 @@
3999+
4000+ /* For handling digital zoom. */
4001+ IPACameraSensorInfo sensorInfo_;
4002+- Rectangle ispCrop_; /* crop in ISP (camera mode) pixels */
4003+- Rectangle scalerCrop_; /* crop in sensor native pixels */
4004+- Size ispMinCropSize_;
4005++
4006++ struct CropParams {
4007++ CropParams(Rectangle ispCrop_, Size ispMinCropSize_, unsigned int ispIndex_)
4008++ : ispCrop(ispCrop_), ispMinCropSize(ispMinCropSize_), ispIndex(ispIndex_)
4009++ {
4010++ }
4011++
4012++ /* Crop in ISP (camera mode) pixels */
4013++ Rectangle ispCrop;
4014++ /* Minimum crop size in ISP output pixels */
4015++ Size ispMinCropSize;
4016++ /* Index of the ISP output channel for this crop */
4017++ unsigned int ispIndex;
4018++ };
4019++
4020++ /* Mapping of CropParams keyed by the output stream order in CameraConfiguration */
4021++ std::map<unsigned int, CropParams> cropParams_;
4022+
4023+ unsigned int dropFrameCount_;
4024+
4025+--- a/src/libcamera/pipeline/rpi/common/rpi_stream.h 2024-11-25 21:08:37.649494681 +0530
4026++++ b/src/libcamera/pipeline/rpi/common/rpi_stream.h 2024-11-25 21:08:37.640494319 +0530
4027+@@ -82,6 +82,11 @@
4028+ * to be applied after ISP processing.
4029+ */
4030+ Needs32bitConv = (1 << 4),
4031++ /*
4032++ * Indicates that the input stream needs a software 16-bit endian
4033++ * conversion to be applied before ISP processing.
4034++ */
4035++ Needs16bitEndianSwap = (1 << 5),
4036+ };
4037+
4038+ using StreamFlags = Flags<StreamFlag>;
4039+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4040++++ b/src/libcamera/pipeline/rpi/pisp/data/example.yaml 2024-11-25 21:08:37.641494359 +0530
4041+@@ -0,0 +1,45 @@
4042++{
4043++ "version": 1.0,
4044++ "target": "pisp",
4045++
4046++ "pipeline_handler":
4047++ {
4048++ # Number of CFE config and stats buffers to allocate and use. A
4049++ # larger number minimises the possibility of dropping frames,
4050++ # but increases the latency for updating the HW configuration.
4051++ #
4052++ # "num_cfe_config_stats_buffers": 12,
4053++
4054++ # Number of jobs to queue ahead to the CFE on startup. A larger
4055++ # number will increase latency for 3A changes, but may reduce
4056++ # avoidable frame drops.
4057++ #
4058++ # "num_cfe_config_queue": 2,
4059++
4060++ # Override any request from the IPA to drop a number of startup
4061++ # frames.
4062++ #
4063++ # "disable_startup_frame_drops": false,
4064++
4065++ # Custom timeout value (in ms) for camera to use. This overrides
4066++ # the value computed by the pipeline handler based on frame
4067++ # durations.
4068++ #
4069++ # Set this value to 0 to use the pipeline handler computed
4070++ # timeout value.
4071++ #
4072++ # "camera_timeout_value_ms": 0,
4073++
4074++ # Disables temporal denoise functionality in the ISP pipeline.
4075++ # Disabling temporal denoise avoids allocating 2 additional
4076++ # Bayer framebuffers required for its operation.
4077++ #
4078++ # "disable_tdn": false,
4079++
4080++ # Disables multiframe HDR functionality in the ISP pipeline.
4081++ # Disabling multiframe HDR avoids allocating 2 additional Bayer
4082++ # framebuffers required for its operation.
4083++ #
4084++ # "disable_hdr": false,
4085++ }
4086++}
4087+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4088++++ b/src/libcamera/pipeline/rpi/pisp/data/meson.build 2024-11-25 21:08:37.641494359 +0530
4089+@@ -0,0 +1,8 @@
4090++# SPDX-License-Identifier: CC0-1.0
4091++
4092++conf_files = files([
4093++ 'example.yaml',
4094++])
4095++
4096++install_data(conf_files,
4097++ install_dir : pipeline_data_dir / 'rpi' / 'pisp')
4098+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4099++++ b/src/libcamera/pipeline/rpi/pisp/meson.build 2024-11-25 21:08:37.641494359 +0530
4100+@@ -0,0 +1,19 @@
4101++# SPDX-License-Identifier: CC0-1.0
4102++
4103++libcamera_internal_sources += files([
4104++ 'pisp.cpp',
4105++])
4106++
4107++librt = cc.find_library('rt', required : true)
4108++libpisp_proj = subproject('libpisp',
4109++ default_options: [
4110++ 'buildtype=release',
4111++ 'default_library=shared',
4112++ ],
4113++ required: false
4114++)
4115++libpisp_dep = libpisp_proj.get_variable('libpisp_dep')
4116++
4117++libcamera_deps += [libpisp_dep, librt]
4118++
4119++subdir('data')
4120+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4121++++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp 2024-11-25 21:08:37.641494359 +0530
4122+@@ -0,0 +1,2304 @@
4123++/* SPDX-License-Identifier: LGPL-2.1-or-later */
4124++/*
4125++ * Copyright (C) 2023, Raspberry Pi Ltd
4126++ *
4127++ * pisp.cpp - Pipeline handler for PiSP based Raspberry Pi devices
4128++ */
4129++
4130++#include <algorithm>
4131++#include <fstream>
4132++#include <memory>
4133++#include <mutex>
4134++#include <numeric>
4135++#include <queue>
4136++#include <set>
4137++#include <sstream>
4138++#include <string>
4139++#include <sys/ioctl.h>
4140++#include <unordered_map>
4141++#include <vector>
4142++
4143++#include <linux/dma-buf.h>
4144++#include <linux/v4l2-controls.h>
4145++#include <linux/videodev2.h>
4146++
4147++#include <libcamera/base/shared_fd.h>
4148++#include <libcamera/formats.h>
4149++
4150++#include "libcamera/internal/device_enumerator.h"
4151++#include "libcamera/internal/shared_mem_object.h"
4152++
4153++#include "libpisp/backend/backend.hpp"
4154++#include "libpisp/common/logging.hpp"
4155++#include "libpisp/common/utils.hpp"
4156++#include "libpisp/common/version.hpp"
4157++#include "libpisp/frontend/frontend.hpp"
4158++#include "libpisp/variants/variant.hpp"
4159++
4160++#include "../common/pipeline_base.h"
4161++#include "../common/rpi_stream.h"
4162++
4163++namespace libcamera {
4164++
4165++LOG_DECLARE_CATEGORY(RPI)
4166++
4167++using StreamFlag = RPi::Stream::StreamFlag;
4168++using StreamParams = RPi::RPiCameraConfiguration::StreamParams;
4169++
4170++namespace {
4171++
4172++enum class Cfe : unsigned int { Output0, Embedded, Stats, Config };
4173++enum class Isp : unsigned int { Input, Output0, Output1, TdnInput, TdnOutput,
4174++ StitchInput, StitchOutput, Config };
4175++
4176++/* Offset for all compressed buffers; mode for TDN and Stitch. */
4177++constexpr unsigned int DefaultCompressionOffset = 2048;
4178++constexpr unsigned int DefaultCompressionMode = 1;
4179++
4180++const std::vector<std::pair<BayerFormat, unsigned int>> BayerToMbusCodeMap{
4181++ { { BayerFormat::BGGR, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR8_1X8, },
4182++ { { BayerFormat::GBRG, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG8_1X8, },
4183++ { { BayerFormat::GRBG, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG8_1X8, },
4184++ { { BayerFormat::RGGB, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB8_1X8, },
4185++ { { BayerFormat::BGGR, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR10_1X10, },
4186++ { { BayerFormat::GBRG, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG10_1X10, },
4187++ { { BayerFormat::GRBG, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG10_1X10, },
4188++ { { BayerFormat::RGGB, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB10_1X10, },
4189++ { { BayerFormat::BGGR, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR12_1X12, },
4190++ { { BayerFormat::GBRG, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG12_1X12, },
4191++ { { BayerFormat::GRBG, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG12_1X12, },
4192++ { { BayerFormat::RGGB, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB12_1X12, },
4193++ { { BayerFormat::BGGR, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR14_1X14, },
4194++ { { BayerFormat::GBRG, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG14_1X14, },
4195++ { { BayerFormat::GRBG, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG14_1X14, },
4196++ { { BayerFormat::RGGB, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB14_1X14, },
4197++ { { BayerFormat::BGGR, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR16_1X16, },
4198++ { { BayerFormat::GBRG, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG16_1X16, },
4199++ { { BayerFormat::GRBG, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG16_1X16, },
4200++ { { BayerFormat::RGGB, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB16_1X16, },
4201++ { { BayerFormat::BGGR, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SBGGR16_1X16, },
4202++ { { BayerFormat::GBRG, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SGBRG16_1X16, },
4203++ { { BayerFormat::GRBG, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SGRBG16_1X16, },
4204++ { { BayerFormat::RGGB, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SRGGB16_1X16, },
4205++ { { BayerFormat::RGGB, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SRGGB16_1X16, },
4206++ { { BayerFormat::MONO, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_Y16_1X16, },
4207++ { { BayerFormat::MONO, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_Y16_1X16, },
4208++};
4209++
4210++unsigned int bayerToMbusCode(const BayerFormat &bayer)
4211++{
4212++ const auto it = std::find_if(BayerToMbusCodeMap.begin(), BayerToMbusCodeMap.end(),
4213++ [bayer](const std::pair<BayerFormat, unsigned int> &match) {
4214++ return bayer == match.first;
4215++ });
4216++
4217++ if (it != BayerToMbusCodeMap.end())
4218++ return it->second;
4219++
4220++ return 0;
4221++}
4222++
4223++uint32_t mbusCodeUnpacked16(unsigned int code)
4224++{
4225++ BayerFormat bayer = BayerFormat::fromMbusCode(code);
4226++ BayerFormat bayer16(bayer.order, 16, BayerFormat::Packing::None);
4227++
4228++ return bayerToMbusCode(bayer16);
4229++}
4230++
4231++uint8_t toPiSPBayerOrder(V4L2PixelFormat format)
4232++{
4233++ BayerFormat bayer = BayerFormat::fromV4L2PixelFormat(format);
4234++
4235++ switch (bayer.order) {
4236++ case BayerFormat::Order::BGGR:
4237++ return PISP_BAYER_ORDER_BGGR;
4238++ case BayerFormat::Order::GBRG:
4239++ return PISP_BAYER_ORDER_GBRG;
4240++ case BayerFormat::Order::GRBG:
4241++ return PISP_BAYER_ORDER_GRBG;
4242++ case BayerFormat::Order::RGGB:
4243++ return PISP_BAYER_ORDER_RGGB;
4244++ case BayerFormat::Order::MONO:
4245++ return PISP_BAYER_ORDER_GREYSCALE;
4246++ default:
4247++ ASSERT(0);
4248++ return -1;
4249++ }
4250++}
4251++
4252++pisp_image_format_config toPiSPImageFormat(V4L2DeviceFormat &format)
4253++{
4254++ pisp_image_format_config image = {};
4255++
4256++ image.width = format.size.width;
4257++ image.height = format.size.height;
4258++ image.stride = format.planes[0].bpl;
4259++
4260++ PixelFormat pix = format.fourcc.toPixelFormat();
4261++
4262++ if (RPi::PipelineHandlerBase::isRaw(pix)) {
4263++ BayerFormat bayer = BayerFormat::fromPixelFormat(pix);
4264++ switch (bayer.packing) {
4265++ case BayerFormat::Packing::None:
4266++ image.format = PISP_IMAGE_FORMAT_BPS_16 +
4267++ PISP_IMAGE_FORMAT_UNCOMPRESSED;
4268++ break;
4269++ case BayerFormat::Packing::PISP1:
4270++ image.format = PISP_IMAGE_FORMAT_COMPRESSION_MODE_1;
4271++ break;
4272++ case BayerFormat::Packing::PISP2:
4273++ image.format = PISP_IMAGE_FORMAT_COMPRESSION_MODE_2;
4274++ break;
4275++ default:
4276++ ASSERT(0);
4277++ }
4278++ return image;
4279++ }
4280++
4281++ switch (pix) {
4282++ case formats::YUV420:
4283++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4284++ PISP_IMAGE_FORMAT_BPS_8 +
4285++ PISP_IMAGE_FORMAT_SAMPLING_420 +
4286++ PISP_IMAGE_FORMAT_PLANARITY_PLANAR;
4287++ image.stride2 = image.stride / 2;
4288++ break;
4289++ case formats::NV12:
4290++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4291++ PISP_IMAGE_FORMAT_BPS_8 +
4292++ PISP_IMAGE_FORMAT_SAMPLING_420 +
4293++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR;
4294++ image.stride2 = image.stride;
4295++ break;
4296++ case formats::NV21:
4297++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4298++ PISP_IMAGE_FORMAT_BPS_8 +
4299++ PISP_IMAGE_FORMAT_SAMPLING_420 +
4300++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR +
4301++ PISP_IMAGE_FORMAT_ORDER_SWAPPED;
4302++ image.stride2 = image.stride;
4303++ break;
4304++ case formats::YUYV:
4305++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4306++ PISP_IMAGE_FORMAT_BPS_8 +
4307++ PISP_IMAGE_FORMAT_SAMPLING_422 +
4308++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED;
4309++ break;
4310++ case formats::UYVY:
4311++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4312++ PISP_IMAGE_FORMAT_BPS_8 +
4313++ PISP_IMAGE_FORMAT_SAMPLING_422 +
4314++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED +
4315++ PISP_IMAGE_FORMAT_ORDER_SWAPPED;
4316++ break;
4317++ case formats::NV16:
4318++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4319++ PISP_IMAGE_FORMAT_BPS_8 +
4320++ PISP_IMAGE_FORMAT_SAMPLING_422 +
4321++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR;
4322++ image.stride2 = image.stride;
4323++ break;
4324++ case formats::NV61:
4325++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL +
4326++ PISP_IMAGE_FORMAT_BPS_8 +
4327++ PISP_IMAGE_FORMAT_SAMPLING_422 +
4328++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR +
4329++ PISP_IMAGE_FORMAT_ORDER_SWAPPED;
4330++ image.stride2 = image.stride;
4331++ break;
4332++ case formats::RGB888:
4333++ case formats::BGR888:
4334++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL;
4335++ break;
4336++ case formats::XRGB8888:
4337++ case formats::XBGR8888:
4338++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL + PISP_IMAGE_FORMAT_BPP_32;
4339++ break;
4340++ case formats::RGBX8888:
4341++ case formats::BGRX8888:
4342++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL + PISP_IMAGE_FORMAT_BPP_32 +
4343++ PISP_IMAGE_FORMAT_ORDER_SWAPPED;
4344++ break;
4345++ case formats::RGB161616:
4346++ case formats::BGR161616:
4347++ image.format = PISP_IMAGE_FORMAT_THREE_CHANNEL + PISP_IMAGE_FORMAT_BPS_16;
4348++ break;
4349++ default:
4350++ LOG(RPI, Error) << "Pixel format " << pix << " unsupported";
4351++ ASSERT(0);
4352++ }
4353++
4354++ return image;
4355++}
4356++
4357++void computeOptimalStride(V4L2DeviceFormat &format)
4358++{
4359++ pisp_image_format_config fmt = toPiSPImageFormat(format);
4360++
4361++ libpisp::compute_optimal_stride(fmt);
4362++
4363++ uint32_t fourcc = format.fourcc.fourcc();
4364++
4365++ /*
4366++ * For YUV420/422 non-multiplanar formats, double the U/V stride for the
4367++ * Y-plane to ensure we get the optimal alignment on all three planes.
4368++ */
4369++ if (fourcc == V4L2_PIX_FMT_YUV420 || fourcc == V4L2_PIX_FMT_YUV422P ||
4370++ fourcc == V4L2_PIX_FMT_YVU420)
4371++ fmt.stride = fmt.stride2 * 2;
4372++
4373++ format.planes[0].bpl = fmt.stride;
4374++ format.planes[1].bpl = fmt.stride2;
4375++ format.planes[2].bpl = fmt.stride2;
4376++
4377++ /*
4378++ * Need to set planesCount correctly so that V4L2VideoDevice::trySetFormatMultiplane()
4379++ * copies the bpl fields correctly.
4380++ */
4381++ const PixelFormat &pixFormat = format.fourcc.toPixelFormat();
4382++ const PixelFormatInfo &info = PixelFormatInfo::info(pixFormat);
4383++ format.planesCount = info.numPlanes();
4384++}
4385++
4386++void setupOutputClipping(const V4L2DeviceFormat &v4l2Format,
4387++ pisp_be_output_format_config &outputFormat)
4388++{
4389++ const PixelFormat &pixFormat = v4l2Format.fourcc.toPixelFormat();
4390++ const PixelFormatInfo &info = PixelFormatInfo::info(pixFormat);
4391++
4392++ if (info.colourEncoding != PixelFormatInfo::ColourEncodingYUV)
4393++ return;
4394++
4395++ if (v4l2Format.colorSpace == ColorSpace::Sycc) {
4396++ outputFormat.lo = 0;
4397++ outputFormat.hi = 65535;
4398++ outputFormat.lo2 = 0;
4399++ outputFormat.hi2 = 65535;
4400++ } else if (v4l2Format.colorSpace == ColorSpace::Smpte170m ||
4401++ v4l2Format.colorSpace == ColorSpace::Rec709) {
4402++ outputFormat.lo = 16 << 8;
4403++ outputFormat.hi = 235 << 8;
4404++ outputFormat.lo2 = 16 << 8;
4405++ outputFormat.hi2 = 240 << 8;
4406++ } else {
4407++ LOG(RPI, Warning)
4408++ << "Unrecognised colour space "
4409++ << ColorSpace::toString(v4l2Format.colorSpace)
4410++ << ", using full range";
4411++ outputFormat.lo = 0;
4412++ outputFormat.hi = 65535;
4413++ outputFormat.lo2 = 0;
4414++ outputFormat.hi2 = 65535;
4415++ }
4416++}
4417++
4418++int dmabufSyncStart(const SharedFD &fd)
4419++{
4420++ struct dma_buf_sync dma_sync {};
4421++ dma_sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
4422++
4423++ int ret = ::ioctl(fd.get(), DMA_BUF_IOCTL_SYNC, &dma_sync);
4424++ if (ret)
4425++ LOG(RPI, Error) << "failed to lock-sync-write dma buf";
4426++
4427++ return ret;
4428++}
4429++
4430++int dmabufSyncEnd(const SharedFD &fd)
4431++{
4432++ struct dma_buf_sync dma_sync {};
4433++ dma_sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
4434++
4435++ int ret = ::ioctl(fd.get(), DMA_BUF_IOCTL_SYNC, &dma_sync);
4436++
4437++ if (ret)
4438++ LOG(RPI, Error) << "failed to unlock-sync-write dma buf";
4439++
4440++ return ret;
4441++}
4442++
4443++void do32BitConversion(void *mem, unsigned int width, unsigned int height,
4444++ unsigned int stride)
4445++{
4446++ /*
4447++ * The arm64 version is actually not that much quicker because the
4448++ * vast bulk of the time is spent waiting for memory.
4449++ */
4450++#if __aarch64__
4451++ for (unsigned int j = 0; j < height; j++) {
4452++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4453++ uint64_t count = (width + 15) / 16;
4454++ uint8_t *dest = ptr + count * 64;
4455++ uint8_t *src = ptr + count * 48;
4456++
4457++ /* Pre-decrement would have been nice. */
4458++ asm volatile("movi v3.16b, #255 \n"
4459++ "1: \n"
4460++ "sub %[src], %[src], #48 \n"
4461++ "sub %[dest], %[dest], #64 \n"
4462++ "subs %[count], %[count], #1 \n"
4463++ "ld3 {v0.16b, v1.16b, v2.16b}, [%[src]] \n"
4464++ "st4 {v0.16b, v1.16b, v2.16b, v3.16b}, [%[dest]] \n"
4465++ "b.gt 1b \n"
4466++ : [count]"+r" (count)
4467++ : [src]"r" (src), [dest]"r" (dest)
4468++ : "cc", "v1", "v2", "v3", "v4", "memory"
4469++ );
4470++ }
4471++#else
4472++ std::vector<uint8_t> incache(3 * width);
4473++ std::vector<uint8_t> outcache(4 * width);
4474++
4475++ memcpy(incache.data(), mem, 3 * width);
4476++ for (unsigned int j = 0; j < height; j++) {
4477++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4478++
4479++ uint8_t *ptr3 = incache.data();
4480++ uint8_t *ptr4 = outcache.data();
4481++ for (unsigned int i = 0; i < width; i++) {
4482++ *(ptr4++) = *(ptr3++);
4483++ *(ptr4++) = *(ptr3++);
4484++ *(ptr4++) = *(ptr3++);
4485++ *(ptr4++) = 255;
4486++ }
4487++
4488++ if (j < height - 1)
4489++ memcpy(incache.data(), ptr + stride, 3 * width);
4490++ memcpy(ptr, outcache.data(), 4 * width);
4491++ }
4492++#endif
4493++}
4494++
4495++void do16BitEndianSwap([[maybe_unused]] void *mem, [[maybe_unused]] unsigned int width,
4496++ [[maybe_unused]] unsigned int height, [[maybe_unused]] unsigned int stride)
4497++{
4498++#if __aarch64__
4499++ for (unsigned int j = 0; j < height; j++) {
4500++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4501++ uint64_t count = (width + 7) / 8;
4502++
4503++ asm volatile("1: \n"
4504++ "ld1 {v1.16b}, [%[ptr]] \n"
4505++ "rev16 v1.16b, v1.16b \n"
4506++ "st1 {v1.16b}, [%[ptr]], #16 \n"
4507++ "subs %[count], %[count], #1 \n"
4508++ "b.gt 1b \n"
4509++ : [count]"+r" (count), [ptr]"+r" (ptr)
4510++ :
4511++ : "cc", "v1", "memory"
4512++ );
4513++ }
4514++#endif
4515++}
4516++
4517++void downscaleInterleaved3(void *mem, unsigned int height, unsigned int src_width,
4518++ unsigned int stride)
4519++{
4520++ std::vector<uint8_t> incache(3 * src_width);
4521++ unsigned int dst_width = src_width / 2;
4522++ std::vector<uint8_t> outcache(3 * dst_width);
4523++
4524++ memcpy(incache.data(), mem, 3 * src_width);
4525++ for (unsigned int j = 0; j < height; j++) {
4526++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4527++
4528++ uint8_t *src = incache.data(), *dst = outcache.data();
4529++ for (unsigned int i = 0; i < dst_width; i++, src += 6, dst += 3) {
4530++ dst[0] = ((int)src[0] + (int)src[3] + 1) >> 1;
4531++ dst[1] = ((int)src[1] + (int)src[4] + 1) >> 1;
4532++ dst[2] = ((int)src[2] + (int)src[5] + 1) >> 1;
4533++ }
4534++
4535++ if (j < height - 1)
4536++ memcpy(incache.data(), ptr + stride, 3 * src_width);
4537++ memcpy(ptr, outcache.data(), 3 * dst_width);
4538++ }
4539++}
4540++
4541++void downscaleInterleaved4(void *mem, unsigned int height, unsigned int src_width,
4542++ unsigned int stride)
4543++{
4544++ std::vector<uint8_t> incache(4 * src_width);
4545++ unsigned int dst_width = src_width / 2;
4546++ std::vector<uint8_t> outcache(4 * dst_width);
4547++
4548++ memcpy(incache.data(), mem, 4 * src_width);
4549++ for (unsigned int j = 0; j < height; j++) {
4550++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4551++
4552++ uint8_t *src = incache.data(), *dst = outcache.data();
4553++ for (unsigned int i = 0; i < dst_width; i++, src += 8, dst += 4) {
4554++ dst[0] = ((int)src[0] + (int)src[4] + 1) >> 1;
4555++ dst[1] = ((int)src[1] + (int)src[5] + 1) >> 1;
4556++ dst[2] = ((int)src[2] + (int)src[6] + 1) >> 1;
4557++ dst[3] = ((int)src[3] + (int)src[7] + 1) >> 1;
4558++ }
4559++
4560++ if (j < height - 1)
4561++ memcpy(incache.data(), ptr + stride, 4 * src_width);
4562++ memcpy(ptr, outcache.data(), 4 * dst_width);
4563++ }
4564++}
4565++
4566++void downscalePlaneInternal(void *mem, unsigned int height, unsigned int src_width,
4567++ unsigned int stride, std::vector<uint8_t> &incache,
4568++ std::vector<uint8_t> &outcache)
4569++{
4570++ unsigned int dst_width = src_width / 2;
4571++ memcpy(incache.data(), mem, src_width);
4572++ for (unsigned int j = 0; j < height; j++) {
4573++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4574++
4575++ uint8_t *src = incache.data(), *dst = outcache.data();
4576++ for (unsigned int i = 0; i < dst_width; i++, src += 2, dst++)
4577++ *dst = ((int)src[0] + (int)src[1] + 1) >> 1;
4578++
4579++ if (j < height - 1)
4580++ memcpy(incache.data(), ptr + stride, src_width);
4581++ memcpy(ptr, outcache.data(), dst_width);
4582++ }
4583++}
4584++
4585++void downscalePlanar420(void *memY, void *memU, void *memV, unsigned int height,
4586++ unsigned int src_width, unsigned int stride)
4587++{
4588++ std::vector<uint8_t> incache(src_width);
4589++ std::vector<uint8_t> outcache(src_width / 2);
4590++
4591++ downscalePlaneInternal(memY, height, src_width, stride, incache, outcache);
4592++ downscalePlaneInternal(memU, height / 2, src_width / 2, stride / 2, incache, outcache);
4593++ downscalePlaneInternal(memV, height / 2, src_width / 2, stride / 2, incache, outcache);
4594++}
4595++
4596++void downscalePlanar422(void *memY, void *memU, void *memV,
4597++ unsigned int height, unsigned int src_width, unsigned int stride)
4598++{
4599++ std::vector<uint8_t> incache(src_width);
4600++ std::vector<uint8_t> outcache(src_width / 2);
4601++
4602++ downscalePlaneInternal(memY, height, src_width, stride, incache, outcache);
4603++ downscalePlaneInternal(memU, height, src_width / 2, stride / 2, incache, outcache);
4604++ downscalePlaneInternal(memV, height, src_width / 2, stride / 2, incache, outcache);
4605++}
4606++
4607++void downscaleInterleavedYuyv(void *mem, unsigned int height, unsigned int src_width,
4608++ unsigned int stride)
4609++{
4610++ std::vector<uint8_t> incache(2 * src_width);
4611++ unsigned int dst_width = src_width / 2;
4612++ std::vector<uint8_t> outcache(2 * dst_width);
4613++
4614++ memcpy(incache.data(), mem, 2 * src_width);
4615++ for (unsigned int j = 0; j < height; j++) {
4616++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4617++
4618++ uint8_t *src = incache.data(), *dst = outcache.data();
4619++ for (unsigned int i = 0; i < dst_width; i++, src += 8, dst += 4) {
4620++ dst[0] = ((int)src[0] + (int)src[2] + 1) >> 1;
4621++ dst[1] = ((int)src[1] + (int)src[5] + 1) >> 1;
4622++ dst[2] = ((int)src[4] + (int)src[6] + 1) >> 1;
4623++ dst[3] = ((int)src[3] + (int)src[7] + 1) >> 1;
4624++ }
4625++
4626++ if (j < height - 1)
4627++ memcpy(incache.data(), ptr + stride, 4 * src_width);
4628++ memcpy(ptr, outcache.data(), 2 * dst_width);
4629++ }
4630++}
4631++
4632++void downscaleInterleavedUyvy(void *mem, unsigned int height, unsigned int src_width,
4633++ unsigned int stride)
4634++{
4635++ std::vector<uint8_t> incache(2 * src_width);
4636++ unsigned int dst_width = src_width / 2;
4637++ std::vector<uint8_t> outcache(2 * dst_width);
4638++
4639++ memcpy(incache.data(), mem, 2 * src_width);
4640++ for (unsigned int j = 0; j < height; j++) {
4641++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4642++
4643++ uint8_t *src = incache.data(), *dst = outcache.data();
4644++ for (unsigned int i = 0; i < dst_width; i++, src += 8, dst += 4) {
4645++ dst[0] = ((int)src[0] + (int)src[4] + 1) >> 1;
4646++ dst[1] = ((int)src[1] + (int)src[3] + 1) >> 1;
4647++ dst[2] = ((int)src[2] + (int)src[6] + 1) >> 1;
4648++ dst[3] = ((int)src[5] + (int)src[7] + 1) >> 1;
4649++ }
4650++
4651++ if (j < height - 1)
4652++ memcpy(incache.data(), ptr + stride, 4 * src_width);
4653++ memcpy(ptr, outcache.data(), 2 * dst_width);
4654++ }
4655++}
4656++
4657++void downscaleInterleaved2Internal(void *mem, unsigned int height, unsigned int src_width,
4658++ unsigned int stride, std::vector<uint8_t> &incache,
4659++ std::vector<uint8_t> &outcache)
4660++{
4661++ unsigned int dst_width = src_width / 2;
4662++ memcpy(incache.data(), mem, 2 * src_width);
4663++ for (unsigned int j = 0; j < height; j++) {
4664++ uint8_t *ptr = (uint8_t *)mem + j * stride;
4665++
4666++ uint8_t *src = incache.data(), *dst = outcache.data();
4667++ for (unsigned int i = 0; i < dst_width; i++, src += 4, dst += 2) {
4668++ dst[0] = ((int)src[0] + (int)src[2] + 1) >> 1;
4669++ dst[1] = ((int)src[1] + (int)src[3] + 1) >> 1;
4670++ }
4671++
4672++ if (j < height - 1)
4673++ memcpy(incache.data(), ptr + stride, 2 * src_width);
4674++ memcpy(ptr, outcache.data(), 2 * dst_width);
4675++ }
4676++}
4677++
4678++void downscaleSemiPlanar420(void *memY, void *memUV, unsigned int height,
4679++ unsigned int src_width, unsigned int stride)
4680++{
4681++ std::vector<uint8_t> incache(src_width);
4682++ std::vector<uint8_t> outcache(src_width / 2);
4683++
4684++ downscalePlaneInternal(memY, height, src_width, stride, incache, outcache);
4685++ downscaleInterleaved2Internal(memUV, height / 2, src_width / 2, stride,
4686++ incache, outcache);
4687++}
4688++
4689++void downscaleStreamBuffer(RPi::Stream *stream, int index)
4690++{
4691++ unsigned int downscale = stream->swDownscale();
4692++ /* Must be a power of 2. */
4693++ ASSERT((downscale & (downscale - 1)) == 0);
4694++
4695++ unsigned int stride = stream->configuration().stride;
4696++ unsigned int dst_width = stream->configuration().size.width;
4697++ unsigned int height = stream->configuration().size.height;
4698++ const PixelFormat &pixFormat = stream->configuration().pixelFormat;
4699++ const RPi::BufferObject &b = stream->getBuffer(index);
4700++ void *mem = b.mapped->planes()[0].data();
4701++ ASSERT(b.mapped);
4702++
4703++ /* Do repeated downscale-by-2 in place until we're done. */
4704++ for (; downscale > 1; downscale >>= 1) {
4705++ unsigned int src_width = downscale * dst_width;
4706++
4707++ if (pixFormat == formats::RGB888 || pixFormat == formats::BGR888) {
4708++ downscaleInterleaved3(mem, height, src_width, stride);
4709++ } else if (pixFormat == formats::XRGB8888 || pixFormat == formats::XBGR8888) {
4710++ /* On some devices these may actually be 24bpp at this point. */
4711++ if (stream->getFlags() & StreamFlag::Needs32bitConv)
4712++ downscaleInterleaved3(mem, height, src_width, stride);
4713++ else
4714++ downscaleInterleaved4(mem, height, src_width, stride);
4715++ } else if (pixFormat == formats::YUV420 || pixFormat == formats::YVU420) {
4716++ /* These may look like either single or multi-planar buffers. */
4717++ void *mem1;
4718++ void *mem2;
4719++ if (b.mapped->planes().size() == 3) {
4720++ mem1 = b.mapped->planes()[1].data();
4721++ mem2 = b.mapped->planes()[2].data();
4722++ } else {
4723++ unsigned int ySize = height * stride;
4724++ mem1 = static_cast<uint8_t *>(mem) + ySize;
4725++ mem2 = static_cast<uint8_t *>(mem1) + ySize / 4;
4726++ }
4727++ downscalePlanar420(mem, mem1, mem2, height, src_width, stride);
4728++ } else if (pixFormat == formats::YUV422 || pixFormat == formats::YVU422) {
4729++ /* These may look like either single or multi-planar buffers. */
4730++ void *mem1;
4731++ void *mem2;
4732++ if (b.mapped->planes().size() == 3) {
4733++ mem1 = b.mapped->planes()[1].data();
4734++ mem2 = b.mapped->planes()[2].data();
4735++ } else {
4736++ unsigned int ySize = height * stride;
4737++ mem1 = static_cast<uint8_t *>(mem) + ySize;
4738++ mem2 = static_cast<uint8_t *>(mem1) + ySize / 2;
4739++ }
4740++ downscalePlanar422(mem, mem1, mem2, height, src_width, stride);
4741++ } else if (pixFormat == formats::YUYV || pixFormat == formats::YVYU) {
4742++ downscaleInterleavedYuyv(mem, height, src_width, stride);
4743++ } else if (pixFormat == formats::UYVY || pixFormat == formats::VYUY) {
4744++ downscaleInterleavedUyvy(mem, height, src_width, stride);
4745++ } else if (pixFormat == formats::NV12 || pixFormat == formats::NV21) {
4746++ /* These may look like either single or multi-planar buffers. */
4747++ void *mem1;
4748++ if (b.mapped->planes().size() == 2)
4749++ mem1 = b.mapped->planes()[1].data();
4750++ else
4751++ mem1 = static_cast<uint8_t *>(mem) + height * stride;
4752++ downscaleSemiPlanar420(mem, mem1, height, src_width, stride);
4753++ } else {
4754++ LOG(RPI, Error) << "Sw downscale unsupported for " << pixFormat;
4755++ ASSERT(0);
4756++ }
4757++ }
4758++}
4759++
4760++/* Return largest width of any of these streams (or of the camera input). */
4761++unsigned int getLargestWidth(const V4L2SubdeviceFormat &sensorFormat,
4762++ const std::vector<StreamParams> &outStreams)
4763++{
4764++ unsigned int largestWidth = sensorFormat.size.width;
4765++
4766++ for (const auto &stream : outStreams)
4767++ largestWidth = std::max(largestWidth, stream.cfg->size.width);
4768++
4769++ return largestWidth;
4770++}
4771++
4772++/* Return the minimum number of pixels required to write out multiples of 16 bytes. */
4773++unsigned int getFormatAlignment(const V4L2PixelFormat &fourcc)
4774++{
4775++ const PixelFormatInfo &info = PixelFormatInfo::info(fourcc);
4776++ unsigned int formatAlignment = 0;
4777++ for (const auto &plane : info.planes) {
4778++ if (plane.bytesPerGroup) {
4779++ /* How many pixels we need in this plane for a multiple of 16 bytes (??). */
4780++ unsigned int align = 16 * info.pixelsPerGroup /
4781++ std::gcd(16u, plane.bytesPerGroup);
4782++ formatAlignment = std::max(formatAlignment, align);
4783++ }
4784++ }
4785++
4786++ return formatAlignment;
4787++}
4788++
4789++/* Calculate the amount of software downscale required (which is a power of 2). */
4790++unsigned int calculateSwDownscale(const V4L2DeviceFormat &format, unsigned int largestWidth,
4791++ unsigned int platformMaxDownscale)
4792++{
4793++ unsigned int formatAlignment = getFormatAlignment(format.fourcc);
4794++ unsigned int maxDownscale = platformMaxDownscale * 16 / formatAlignment;
4795++ unsigned int limitWidth = largestWidth / maxDownscale;
4796++
4797++ unsigned int hwWidth = format.size.width;
4798++ unsigned int swDownscale = 1;
4799++ for (; hwWidth < limitWidth; hwWidth *= 2, swDownscale *= 2);
4800++
4801++ return swDownscale;
4802++}
4803++
4804++} /* namespace */
4805++
4806++using ::libpisp::BackEnd;
4807++using ::libpisp::FrontEnd;
4808++
4809++class PiSPCameraData final : public RPi::CameraData
4810++{
4811++public:
4812++ PiSPCameraData(PipelineHandler *pipe, const libpisp::PiSPVariant &variant)
4813++ : RPi::CameraData(pipe), pispVariant_(variant)
4814++ {
4815++ /* Initialise internal libpisp logging. */
4816++ ::libpisp::logging_init();
4817++ LOG(RPI, Info) << "libpisp version " << ::libpisp::version();
4818++ }
4819++
4820++ ~PiSPCameraData()
4821++ {
4822++ freeBuffers();
4823++ }
4824++
4825++ V4L2VideoDevice::Formats ispFormats() const override
4826++ {
4827++ return isp_[Isp::Output0].dev()->formats();
4828++ }
4829++
4830++ V4L2VideoDevice::Formats rawFormats() const override
4831++ {
4832++ return cfe_[Cfe::Output0].dev()->formats();
4833++ }
4834++
4835++ V4L2VideoDevice *frontendDevice() override
4836++ {
4837++ return cfe_[Cfe::Output0].dev();
4838++ }
4839++
4840++ CameraConfiguration::Status
4841++ platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const override;
4842++
4843++ int platformPipelineConfigure(const std::unique_ptr<YamlObject> &root) override;
4844++
4845++ void platformStart() override;
4846++ void platformStop() override;
4847++ void platformFreeBuffers() override;
4848++
4849++ void cfeBufferDequeue(FrameBuffer *buffer);
4850++ void beInputDequeue(FrameBuffer *buffer);
4851++ void beOutputDequeue(FrameBuffer *buffer);
4852++
4853++ void processStatsComplete(const ipa::RPi::BufferIds &buffers);
4854++ void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers);
4855++ void setCameraTimeout(uint32_t maxFrameLengthMs);
4856++
4857++ /* Array of CFE and ISP device streams and associated buffers/streams. */
4858++ RPi::Device<Cfe, 4> cfe_;
4859++ RPi::Device<Isp, 8> isp_;
4860++
4861++ const libpisp::PiSPVariant &pispVariant_;
4862++
4863++ /* Frontend/Backend objects shared with the IPA. */
4864++ SharedMemObject<FrontEnd> fe_;
4865++ SharedMemObject<BackEnd> be_;
4866++ bool beEnabled_;
4867++
4868++ std::unique_ptr<V4L2Subdevice> csi2Subdev_;
4869++ std::unique_ptr<V4L2Subdevice> feSubdev_;
4870++
4871++ std::vector<FrameBuffer *> tdnBuffers_;
4872++ std::vector<FrameBuffer *> stitchBuffers_;
4873++ unsigned int tdnInputIndex_;
4874++ unsigned int stitchInputIndex_;
4875++
4876++ struct Config {
4877++ /*
4878++ * Number of CFE config and stats buffers to allocate and use. A
4879++ * larger number minimises the possibility of dropping frames,
4880++ * but increases the latency for updating the HW configuration.
4881++ */
4882++ unsigned int numCfeConfigStatsBuffers;
4883++ /*
4884++ * Number of jobs to queue ahead to the CFE on startup.
4885++ * A larger number will increase latency for 3A changes.
4886++ */
4887++ unsigned int numCfeConfigQueue;
4888++ /* Don't use BE temporal denoise and free some memory resources. */
4889++ bool disableTdn;
4890++ /* Don't use BE HDR and free some memory resources. */
4891++ bool disableHdr;
4892++ };
4893++
4894++ Config config_;
4895++
4896++ bool adjustDeviceFormat(V4L2DeviceFormat &format) const;
4897++
4898++private:
4899++ int platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig) override;
4900++
4901++ int platformConfigureIpa([[maybe_unused]] ipa::RPi::ConfigParams &params) override
4902++ {
4903++ return 0;
4904++ }
4905++
4906++ int platformInitIpa(ipa::RPi::InitParams &params) override;
4907++
4908++ int configureEntities(V4L2SubdeviceFormat sensorFormat,
4909++ V4L2SubdeviceFormat &embeddedFormat);
4910++ int configureCfe();
4911++ bool calculateCscConfiguration(const V4L2DeviceFormat &v4l2Format, pisp_be_ccm_config &csc);
4912++ int configureBe(const std::optional<ColorSpace> &yuvColorSpace);
4913++
4914++ void platformSetIspCrop(unsigned int index, const Rectangle &ispCrop) override;
4915++
4916++ void prepareCfe();
4917++ void prepareBe(uint32_t bufferId, bool stitchSwapBuffers);
4918++
4919++ void tryRunPipeline() override;
4920++
4921++ struct CfeJob {
4922++ ControlList sensorControls;
4923++ unsigned int delayContext;
4924++ std::unordered_map<const RPi::Stream *, FrameBuffer *> buffers;
4925++ };
4926++
4927++ std::queue<CfeJob> cfeJobQueue_;
4928++
4929++ bool cfeJobComplete() const
4930++ {
4931++ if (cfeJobQueue_.empty())
4932++ return false;
4933++
4934++ const CfeJob &job = cfeJobQueue_.back();
4935++ return job.buffers.count(&cfe_[Cfe::Output0]) &&
4936++ job.buffers.count(&cfe_[Cfe::Stats]) &&
4937++ (!sensorMetadata_ ||
4938++ job.buffers.count(&cfe_[Cfe::Embedded]));
4939++ }
4940++
4941++ std::string last_dump_file_;
4942++};
4943++
4944++class PipelineHandlerPiSP : public RPi::PipelineHandlerBase
4945++{
4946++public:
4947++ PipelineHandlerPiSP(CameraManager *manager)
4948++ : RPi::PipelineHandlerBase(manager)
4949++ {
4950++ }
4951++
4952++ ~PipelineHandlerPiSP()
4953++ {
4954++ }
4955++
4956++ bool match(DeviceEnumerator *enumerator) override;
4957++
4958++private:
4959++ PiSPCameraData *cameraData(Camera *camera)
4960++ {
4961++ return static_cast<PiSPCameraData *>(camera->_d());
4962++ }
4963++
4964++ int prepareBuffers(Camera *camera) override;
4965++ int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,
4966++ MediaDevice *cfe, MediaDevice *isp) override;
4967++};
4968++
4969++bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)
4970++{
4971++ constexpr unsigned int numCfeDevices = 2;
4972++
4973++ /*
4974++ * Loop over all CFE instances, but return out once a match is found.
4975++ * This is to ensure we correctly enumerate the camera when an instance
4976++ * of the CFE has registered with media controller, but has not registered
4977++ * device nodes due to a sensor subdevice failure.
4978++ */
4979++ for (unsigned int i = 0; i < numCfeDevices; i++) {
4980++ DeviceMatch cfe("rp1-cfe");
4981++ cfe.add("rp1-cfe-fe_image0");
4982++ cfe.add("rp1-cfe-fe_stats");
4983++ cfe.add("rp1-cfe-fe_config");
4984++ MediaDevice *cfeDevice = acquireMediaDevice(enumerator, cfe);
4985++
4986++ if (!cfeDevice) {
4987++ LOG(RPI, Debug) << "Unable to acquire a CFE instance";
4988++ break;
4989++ }
4990++
4991++ DeviceMatch isp("pispbe");
4992++ isp.add("pispbe-input");
4993++ isp.add("pispbe-config");
4994++ isp.add("pispbe-output0");
4995++ isp.add("pispbe-output1");
4996++ isp.add("pispbe-tdn_output");
4997++ isp.add("pispbe-tdn_input");
4998++ isp.add("pispbe-stitch_output");
4999++ isp.add("pispbe-stitch_input");
5000++ MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches