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

Proposed by Pragyansh Chaturvedi
Status: Merged
Merge reported by: Pragyansh Chaturvedi
Merged at revision: d3a0e77e79ced33b7825afbfc16d347806527d08
Proposed branch: ~r41k0u/ubuntu/+source/libcamera:ubuntu/devel
Merge into: ubuntu/+source/libcamera:ubuntu/devel
Diff against target: 15639 lines (+15601/-1)
5 files modified
debian/changelog (+17/-0)
debian/control (+2/-1)
debian/patches/add_syncmode_and_tensors.patch (+15479/-0)
debian/patches/fix_pisp_cfe_entities.patch (+101/-0)
debian/patches/series (+2/-0)
Reviewer Review Type Date Requested Status
Dave Jones (community) Needs Fixing
Review via email: mp+485502@code.launchpad.net

Commit message

* d/p/add_syncmode_and_tensors.patch: Add SyncMode controls
  and CNN Tensors to enable rpicam-apps (LP: #2109901)
* d/p/fix_pisp_cfe_entities.patch: Allow both old and new CFE
  entity match strings so camera modules can be detected on
  Raspberry Pi 5 using libcamera0.5 (LP: #2110144)

To post a comment you must log in.
Revision history for this message
Pragyansh Chaturvedi (r41k0u) wrote :
Revision history for this message
Pragyansh Chaturvedi (r41k0u) wrote (last edit ):
Revision history for this message
Dave Jones (waveform) wrote :

As discussed on MM, the second patch looks fine. The first patch needs a bug number (2109901 will do given that's what it's fixing), and ideally should be split so we can include a valid origin (some commit in github.com/raspberrypi/libcamera) for the bulk of it.

review: Needs Fixing
Revision history for this message
Pragyansh Chaturvedi (r41k0u) wrote :

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 2fb1577..659eb45 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,20 @@
6+libcamera (0.5.0-1ubuntu2) questing; urgency=medium
7+
8+ * d/p/fix_pisp_cfe_entities.patch: Allow both old and new CFE
9+ entity match strings so camera modules can be detected on
10+ Raspberry Pi 5 using libcamera0.5 (LP: #2110144)
11+
12+ -- Pragyansh Chaturvedi <pragyansh.chaturvedi@canonical.com> Wed, 07 May 2025 21:15:01 +0530
13+
14+libcamera (0.5.0-1ubuntu1) questing; urgency=medium
15+
16+ * d/p/add_syncmode_and_tensors.patch: Add SyncMode controls
17+ and CNN Tensors to enable rpicam-apps (LP: #2109901)
18+ - This patch adds the SyncMode IPA controls and the IMX500 tesnors
19+ and camera data required for rpicam-apps on the Raspberry Pi.
20+
21+ -- Pragyansh Chaturvedi <pragyansh.chaturvedi@canonical.com> Tue, 06 May 2025 12:40:28 +0530
22+
23 libcamera (0.5.0-1) experimental; urgency=medium
24
25 * New upstream version 0.5.0
26diff --git a/debian/control b/debian/control
27index 4c8fb9e..ba49615 100644
28--- a/debian/control
29+++ b/debian/control
30@@ -1,5 +1,6 @@
31 Source: libcamera
32-Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org>
33+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
34+XSBC-Original-Maintainer: Debian Multimedia Maintainers <debian-multimedia@lists.debian.org>
35 Uploaders: Emmanuel Arias <emmanuelarias30@gmail.com>,
36 IOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>,
37 Andrej Shadura <andrewsh@debian.org>,
38diff --git a/debian/patches/add_syncmode_and_tensors.patch b/debian/patches/add_syncmode_and_tensors.patch
39new file mode 100644
40index 0000000..d5ec68a
41--- /dev/null
42+++ b/debian/patches/add_syncmode_and_tensors.patch
43@@ -0,0 +1,15479 @@
44+Description: Add SyncMode controls and CNN Tensors to enable
45+ rpicam-apps and picamera2 on Raspberry Pis. This patch adds the
46+ Sync controls and the CNN tensors used on the Raspberry Pi 5 from
47+ the Raspberry Pi Foundation's fork of libcamera
48+ (https://github.com/raspberrypi/libcamera)
49+ The camera modules on the Raspberry Pi use rpicam-apps, which
50+ needs this patch in libcamera, so this patch is essential to
51+ make them work.
52+Author: Pragyansh Chaturvedi <pragyansh.chaturvedi@canonical.com>
53+Last-Update: 2025-05-06
54+---
55+--- a/src/ipa/rpi/common/ipa_base.cpp 2025-05-08 00:06:16.067331148 +0530
56++++ b/src/ipa/rpi/common/ipa_base.cpp 2025-05-08 00:06:16.043331520 +0530
57+@@ -28,6 +28,8 @@
58+ #include "controller/lux_status.h"
59+ #include "controller/sharpen_algorithm.h"
60+ #include "controller/statistics.h"
61++#include "controller/sync_algorithm.h"
62++#include "controller/sync_status.h"
63+
64+ namespace libcamera {
65+
66+@@ -84,8 +86,11 @@
67+ { &controls::FrameDurationLimits,
68+ ControlInfo(INT64_C(33333), INT64_C(120000),
69+ static_cast<int64_t>(defaultMinFrameDuration.get<std::micro>())) },
70++ { &controls::rpi::SyncMode, ControlInfo(controls::rpi::SyncModeValues) },
71++ { &controls::rpi::SyncFrames, ControlInfo(1, 1000000, 100) },
72+ { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },
73+ { &controls::rpi::StatsOutputEnable, ControlInfo(false, true, false) },
74++ { &controls::rpi::CnnEnableInputTensor, ControlInfo(false, true, false) },
75+ };
76+
77+ /* IPA controls handled conditionally, if the sensor is not mono */
78+@@ -125,7 +130,7 @@
79+ IpaBase::IpaBase()
80+ : controller_(), frameLengths_(FrameLengthsQueueSize, 0s), statsMetadataOutput_(false),
81+ stitchSwapBuffers_(false), frameCount_(0), mistrustCount_(0), lastRunTimestamp_(0),
82+- firstStart_(true), flickerState_({ 0, 0s })
83++ firstStart_(true), flickerState_({ 0, 0s }), cnnEnableInputTensor_(false)
84+ {
85+ }
86+
87+@@ -405,6 +410,7 @@
88+
89+ rpiMetadata.clear();
90+ fillDeviceStatus(params.sensorControls, ipaContext);
91++ fillSyncParams(params, ipaContext);
92+
93+ if (params.buffers.embedded) {
94+ /*
95+@@ -503,10 +509,24 @@
96+ helper_->process(statistics, rpiMetadata);
97+ controller_.process(statistics, &rpiMetadata);
98+
99++ /* Send any sync algorithm outputs back to the pipeline handler */
100++ Duration offset(0s);
101++ struct SyncStatus syncStatus;
102++ if (rpiMetadata.get("sync.status", syncStatus) == 0) {
103++ if (minFrameDuration_ != maxFrameDuration_)
104++ LOG(IPARPI, Error) << "Sync algorithm enabled with variable framerate. "
105++ << minFrameDuration_ << " " << maxFrameDuration_;
106++ offset = syncStatus.frameDurationOffset;
107++
108++ libcameraMetadata_.set(controls::rpi::SyncReady, syncStatus.ready);
109++ if (syncStatus.timerKnown)
110++ libcameraMetadata_.set(controls::rpi::SyncTimer, syncStatus.timerValue);
111++ }
112++
113+ struct AgcStatus agcStatus;
114+ if (rpiMetadata.get("agc.status", agcStatus) == 0) {
115+ ControlList ctrls(sensorCtrls_);
116+- applyAGC(&agcStatus, ctrls);
117++ applyAGC(&agcStatus, ctrls, offset);
118+ setDelayedControls.emit(ctrls, ipaContext);
119+ setCameraTimeoutValue();
120+ }
121+@@ -743,6 +763,7 @@
122+ using RPiController::ContrastAlgorithm;
123+ using RPiController::DenoiseAlgorithm;
124+ using RPiController::HdrAlgorithm;
125++ using RPiController::SyncAlgorithm;
126+
127+ /* Clear the return metadata buffer. */
128+ libcameraMetadata_.clear();
129+@@ -1334,6 +1355,39 @@
130+ statsMetadataOutput_ = ctrl.second.get<bool>();
131+ break;
132+
133++ case controls::rpi::CNN_ENABLE_INPUT_TENSOR:
134++ cnnEnableInputTensor_ = ctrl.second.get<bool>();
135++ break;
136++
137++ case controls::rpi::SYNC_MODE: {
138++ SyncAlgorithm *sync = dynamic_cast<SyncAlgorithm *>(controller_.getAlgorithm("sync"));
139++
140++ if (sync) {
141++ int mode = ctrl.second.get<int32_t>();
142++ SyncAlgorithm::Mode m = SyncAlgorithm::Mode::Off;
143++ if (mode == controls::rpi::SyncModeServer) {
144++ m = SyncAlgorithm::Mode::Server;
145++ LOG(IPARPI, Info) << "Sync mode set to server";
146++ } else if (mode == controls::rpi::SyncModeClient) {
147++ m = SyncAlgorithm::Mode::Client;
148++ LOG(IPARPI, Info) << "Sync mode set to client";
149++ }
150++ sync->setMode(m);
151++ }
152++ break;
153++ }
154++
155++ case controls::rpi::SYNC_FRAMES: {
156++ SyncAlgorithm *sync = dynamic_cast<SyncAlgorithm *>(controller_.getAlgorithm("sync"));
157++
158++ if (sync) {
159++ int frames = ctrl.second.get<int32_t>();
160++ if (frames > 0)
161++ sync->setReadyFrame(frames);
162++ }
163++ break;
164++ }
165++
166+ default:
167+ LOG(IPARPI, Warning)
168+ << "Ctrl " << controls::controls.at(ctrl.first)->name()
169+@@ -1370,6 +1424,19 @@
170+ rpiMetadata_[ipaContext].set("device.status", deviceStatus);
171+ }
172+
173++void IpaBase::fillSyncParams(const PrepareParams &params, unsigned int ipaContext)
174++{
175++ RPiController::SyncAlgorithm *sync = dynamic_cast<RPiController::SyncAlgorithm *>(
176++ controller_.getAlgorithm("sync"));
177++ if (!sync)
178++ return;
179++
180++ SyncParams syncParams;
181++ syncParams.wallClock = *params.sensorControls.get(controls::FrameWallClock);
182++ syncParams.sensorTimestamp = *params.sensorControls.get(controls::SensorTimestamp);
183++ rpiMetadata_[ipaContext].set("sync.params", syncParams);
184++}
185++
186+ void IpaBase::reportMetadata(unsigned int ipaContext)
187+ {
188+ RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext];
189+@@ -1520,6 +1587,51 @@
190+ libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelNone);
191+ }
192+
193++ const std::shared_ptr<uint8_t[]> *inputTensor =
194++ rpiMetadata.getLocked<std::shared_ptr<uint8_t[]>>("cnn.input_tensor");
195++ if (cnnEnableInputTensor_ && inputTensor) {
196++ unsigned int size = *rpiMetadata.getLocked<unsigned int>("cnn.input_tensor_size");
197++ Span<const uint8_t> tensor{ inputTensor->get(), size };
198++ libcameraMetadata_.set(controls::rpi::CnnInputTensor, tensor);
199++ /* No need to keep these big buffers anymore */
200++ rpiMetadata.eraseLocked("cnn.input_tensor");
201++ }
202++
203++ const RPiController::CnnInputTensorInfo *inputTensorInfo =
204++ rpiMetadata.getLocked<RPiController::CnnInputTensorInfo>("cnn.input_tensor_info");
205++ if (inputTensorInfo) {
206++ Span<const uint8_t> tensorInfo{ reinterpret_cast<const uint8_t *>(inputTensorInfo),
207++ sizeof(*inputTensorInfo) };
208++ libcameraMetadata_.set(controls::rpi::CnnInputTensorInfo, tensorInfo);
209++ }
210++
211++ const std::shared_ptr<float[]> *outputTensor =
212++ rpiMetadata.getLocked<std::shared_ptr<float[]>>("cnn.output_tensor");
213++ if (outputTensor) {
214++ unsigned int size = *rpiMetadata.getLocked<unsigned int>("cnn.output_tensor_size");
215++ Span<const float> tensor{ reinterpret_cast<const float *>(outputTensor->get()),
216++ size };
217++ libcameraMetadata_.set(controls::rpi::CnnOutputTensor, tensor);
218++ /* No need to keep these big buffers anymore */
219++ rpiMetadata.eraseLocked("cnn.output_tensor");
220++ }
221++
222++ const RPiController::CnnOutputTensorInfo *outputTensorInfo =
223++ rpiMetadata.getLocked<RPiController::CnnOutputTensorInfo>("cnn.output_tensor_info");
224++ if (outputTensorInfo) {
225++ Span<const uint8_t> tensorInfo{ reinterpret_cast<const uint8_t *>(outputTensorInfo),
226++ sizeof(*outputTensorInfo) };
227++ libcameraMetadata_.set(controls::rpi::CnnOutputTensorInfo, tensorInfo);
228++ }
229++
230++ const RPiController::CnnKpiInfo *kpiInfo =
231++ rpiMetadata.getLocked<RPiController::CnnKpiInfo>("cnn.kpi_info");
232++ if (kpiInfo) {
233++ libcameraMetadata_.set(controls::rpi::CnnKpiInfo,
234++ { static_cast<int32_t>(kpiInfo->dnnRuntime),
235++ static_cast<int32_t>(kpiInfo->dspRuntime) });
236++ }
237++
238+ metadataReady.emit(libcameraMetadata_);
239+ }
240+
241+@@ -1548,14 +1660,22 @@
242+ * value possible.
243+ */
244+ Duration maxExposureTime = Duration::max();
245+- helper_->getBlanking(maxExposureTime, minFrameDuration_, maxFrameDuration_);
246++ auto [vblank, hblank] = helper_->getBlanking(maxExposureTime, minFrameDuration_, maxFrameDuration_);
247+
248+ RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
249+ controller_.getAlgorithm("agc"));
250+ agc->setMaxExposureTime(maxExposureTime);
251++
252++ RPiController::SyncAlgorithm *sync = dynamic_cast<RPiController::SyncAlgorithm *>(
253++ controller_.getAlgorithm("sync"));
254++ if (sync) {
255++ Duration duration = (mode_.height + vblank) * ((mode_.width + hblank) * 1.0s / mode_.pixelRate);
256++ LOG(IPARPI, Debug) << "setting sync frame duration to " << duration;
257++ sync->setFrameDuration(duration);
258++ }
259+ }
260+
261+-void IpaBase::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
262++void IpaBase::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls, Duration frameDurationOffset)
263+ {
264+ const int32_t minGainCode = helper_->gainCode(mode_.minAnalogueGain);
265+ const int32_t maxGainCode = helper_->gainCode(mode_.maxAnalogueGain);
266+@@ -1570,7 +1690,8 @@
267+
268+ /* getBlanking might clip exposure time to the fps limits. */
269+ Duration exposure = agcStatus->exposureTime;
270+- auto [vblank, hblank] = helper_->getBlanking(exposure, minFrameDuration_, maxFrameDuration_);
271++ auto [vblank, hblank] = helper_->getBlanking(exposure, minFrameDuration_ - frameDurationOffset,
272++ maxFrameDuration_ - frameDurationOffset);
273+ int32_t exposureLines = helper_->exposureLines(exposure,
274+ helper_->hblankToLineLength(hblank));
275+
276+--- a/src/ipa/rpi/pisp/data/imx219.json 2025-05-08 00:06:16.067331148 +0530
277++++ b/src/ipa/rpi/pisp/data/imx219.json 2025-05-08 00:06:16.044331505 +0530
278+@@ -1182,6 +1182,11 @@
279+ ]
280+ }
281+ }
282++ },
283++ {
284++ "rpi.sync":
285++ {
286++ }
287+ }
288+ ]
289+ }
290+\ No newline at end of file
291+--- a/src/ipa/rpi/pisp/data/imx219_noir.json 2025-05-08 00:06:16.067331148 +0530
292++++ b/src/ipa/rpi/pisp/data/imx219_noir.json 2025-05-08 00:06:16.045331489 +0530
293+@@ -1107,6 +1107,11 @@
294+ ]
295+ }
296+ }
297++ },
298++ {
299++ "rpi.sync":
300++ {
301++ }
302+ }
303+ ]
304+ }
305+\ No newline at end of file
306+--- a/src/ipa/rpi/pisp/data/meson.build 2025-05-08 00:06:16.067331148 +0530
307++++ b/src/ipa/rpi/pisp/data/meson.build 2025-05-08 00:06:16.045331489 +0530
308+@@ -12,6 +12,7 @@
309+ 'imx477.json',
310+ 'imx477_noir.json',
311+ 'imx477_scientific.json',
312++ 'imx500.json',
313+ 'imx519.json',
314+ 'imx708.json',
315+ 'imx708_noir.json',
316+--- a/src/libcamera/control_ids_rpi.yaml 2025-05-08 00:06:16.067331148 +0530
317++++ b/src/libcamera/control_ids_rpi.yaml 2025-05-08 00:06:16.046331474 +0530
318+@@ -71,4 +71,230 @@
319+
320+ \sa StatsOutputEnable
321+
322++ - CnnOutputTensor:
323++ type: float
324++ size: [n]
325++ direction: out
326++ description: |
327++ This control returns a span of floating point values that represent the
328++ output tensors from a Convolutional Neural Network (CNN). The size and
329++ format of this array of values is entirely dependent on the neural
330++ network used, and further post-processing may need to be performed at
331++ the application level to generate the final desired output. This control
332++ is agnostic of the hardware or software used to generate the output
333++ tensors.
334++
335++ The structure of the span is described by the CnnOutputTensorInfo
336++ control.
337++
338++ \sa CnnOutputTensorInfo
339++
340++ - CnnOutputTensorInfo:
341++ type: uint8_t
342++ size: [n]
343++ direction: out
344++ description: |
345++ This control returns the structure of the CnnOutputTensor. This structure
346++ takes the following form:
347++
348++ constexpr unsigned int NetworkNameLen = 64;
349++ constexpr unsigned int MaxNumTensors = 8;
350++ constexpr unsigned int MaxNumDimensions = 8;
351++
352++ struct CnnOutputTensorInfo {
353++ char networkName[NetworkNameLen];
354++ uint32_t numTensors;
355++ OutputTensorInfo info[MaxNumTensors];
356++ };
357++
358++ with
359++
360++ struct OutputTensorInfo {
361++ uint32_t tensorDataNum;
362++ uint32_t numDimensions;
363++ uint16_t size[MaxNumDimensions];
364++ };
365++
366++ networkName is the name of the CNN used,
367++ numTensors is the number of output tensors returned,
368++ tensorDataNum gives the number of elements in each output tensor,
369++ numDimensions gives the dimensionality of each output tensor,
370++ size gives the size of each dimension in each output tensor.
371++
372++ \sa CnnOutputTensor
373++
374++ - CnnEnableInputTensor:
375++ type: bool
376++ direction: in
377++ description: |
378++ Boolean to control if the IPA returns the input tensor used by the CNN
379++ to generate the output tensors via the CnnInputTensor control. Because
380++ the input tensor may be relatively large, for efficiency reason avoid
381++ enabling input tensor output unless required for debugging purposes.
382++
383++ \sa CnnInputTensor
384++
385++ - CnnInputTensor:
386++ type: uint8_t
387++ size: [n]
388++ direction: out
389++ description: |
390++ This control returns a span of uint8_t pixel values that represent the
391++ input tensor for a Convolutional Neural Network (CNN). The size and
392++ format of this array of values is entirely dependent on the neural
393++ network used, and further post-processing (e.g. pixel normalisations) may
394++ need to be performed at the application level to generate the final input
395++ image.
396++
397++ The structure of the span is described by the CnnInputTensorInfo
398++ control.
399++
400++ \sa CnnInputTensorInfo
401++
402++ - CnnInputTensorInfo:
403++ type: uint8_t
404++ size: [n]
405++ direction: out
406++ description: |
407++ This control returns the structure of the CnnInputTensor. This structure
408++ takes the following form:
409++
410++ constexpr unsigned int NetworkNameLen = 64;
411++
412++ struct CnnInputTensorInfo {
413++ char networkName[NetworkNameLen];
414++ uint32_t width;
415++ uint32_t height;
416++ uint32_t numChannels;
417++ };
418++
419++ where
420++
421++ networkName is the name of the CNN used,
422++ width and height are the input tensor image width and height in pixels,
423++ numChannels is the number of channels in the input tensor image.
424++
425++ \sa CnnInputTensor
426++
427++ - CnnKpiInfo:
428++ type: int32_t
429++ size: [2]
430++ direction: out
431++ description: |
432++ This control returns performance metrics for the CNN processing stage.
433++ Two values are returned in this span, the runtime of the CNN/DNN stage
434++ and the DSP stage in milliseconds.
435++
436++ - SyncMode:
437++ type: int32_t
438++ direction: in
439++ description: |
440++ Enable or disable camera synchronisation ("sync") mode.
441++
442++ When sync mode is enabled, a camera will synchronise frames temporally
443++ with other cameras, either attached to the same device or a different
444++ one. There should be one "server" device, which broadcasts timing
445++ information to one or more "clients". Communication is one-way, from
446++ server to clients only, and it is only clients that adjust their frame
447++ timings to match the server.
448++
449++ Sync mode requires all cameras to be running at (as far as possible) the
450++ same fixed framerate. Clients may continue to make adjustments to keep
451++ their cameras synchronised with the server for the duration of the
452++ session, though any updates after the initial ones should remain small.
453++
454++ \sa SyncReady
455++ \sa SyncTimer
456++ \sa SyncFrames
457++
458++ enum:
459++ - name: SyncModeOff
460++ value: 0
461++ description: Disable sync mode.
462++ - name: SyncModeServer
463++ value: 1
464++ description: |
465++ Enable sync mode, act as server. The server broadcasts timing
466++ messages to any clients that are listening, so that the clients can
467++ synchronise their camera frames with the server's.
468++ - name: SyncModeClient
469++ value: 2
470++ description: |
471++ Enable sync mode, act as client. A client listens for any server
472++ messages, and arranges for its camera frames to synchronise as
473++ closely as possible with the server's. Many clients can listen out
474++ for the same server. Clients can also be started ahead of any
475++ servers, causing them merely to wait for the server to start.
476++
477++ - SyncReady:
478++ type: bool
479++ direction: out
480++ description: |
481++ When using the camera synchronisation algorithm, the server broadcasts
482++ timing information to the clients. This also includes the time (some
483++ number of frames in the future, called the "ready time") at which the
484++ server will signal its controlling application, using this control, to
485++ start using the image frames.
486++
487++ The client receives the "ready time" from the server, and will signal
488++ its application to start using the frames at this same moment.
489++
490++ While this control value is false, applications (on both client and
491++ server) should continue to wait, and not use the frames.
492++
493++ Once this value becomes true, it means that this is the first frame
494++ where the server and its clients have agreed that they will both be
495++ synchronised and that applications should begin consuming frames.
496++ Thereafter, this control will continue to signal the value true for
497++ the rest of the session.
498++
499++ \sa SyncMode
500++ \sa SyncTimer
501++ \sa SyncFrames
502++
503++ - SyncTimer:
504++ type: int64_t
505++ direction: out
506++ description: |
507++ This reports the amount of time, in microseconds, until the "ready
508++ time", at which the server and client will signal their controlling
509++ applications that the frames are now synchronised and should be
510++ used. The value may be refined slightly over time, becoming more precise
511++ as the "ready time" approaches.
512++
513++ Servers always report this value, whereas clients will omit this control
514++ until they have received a message from the server that enables them to
515++ calculate it.
516++
517++ Normally the value will start positive (the "ready time" is in the
518++ future), and decrease towards zero, before becoming negative (the "ready
519++ time" has elapsed). So there should be just one frame where the timer
520++ value is, or is very close to, zero - the one for which the SyncReady
521++ control becomes true. At this moment, the value indicates how closely
522++ synchronised the client believes it is with the server.
523++
524++ But note that if frames are being dropped, then the "near zero" valued
525++ frame, or indeed any other, could be skipped. In these cases the timer
526++ value allows an application to deduce that this has happened.
527++
528++ \sa SyncMode
529++ \sa SyncReady
530++ \sa SyncFrames
531++
532++ - SyncFrames:
533++ type: int32_t
534++ direction: in
535++ description: |
536++ The number of frames the server should wait, after enabling
537++ SyncModeServer, before signalling (via the SyncReady control) that
538++ frames should be used. This therefore determines the "ready time" for
539++ all synchronised cameras.
540++
541++ This control value should be set only for the device that is to act as
542++ the server, before or at the same moment at which SyncModeServer is
543++ enabled.
544++
545++ \sa SyncMode
546++ \sa SyncReady
547++ \sa SyncTimer
548+ ...
549+--- a/src/libcamera/pipeline/rpi/vc4/data/meson.build 2025-05-08 00:06:16.067331148 +0530
550++++ b/src/libcamera/pipeline/rpi/vc4/data/meson.build 2025-05-08 00:06:16.047331458 +0530
551+@@ -2,6 +2,7 @@
552+
553+ conf_files = files([
554+ 'example.yaml',
555++ 'rpi_apps.yaml',
556+ ])
557+
558+ install_data(conf_files,
559+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
560++++ b/src/libcamera/pipeline/rpi/vc4/data/rpi_apps.yaml 2025-05-08 00:06:16.047331458 +0530
561+@@ -0,0 +1,45 @@
562++{
563++ "version": 1.0,
564++ "target": "bcm2835",
565++
566++ "pipeline_handler":
567++ {
568++ # The minimum number of internal buffers to be allocated for
569++ # Unicam. This value must be greater than 0, but less than or
570++ # equal to min_total_unicam_buffers.
571++ #
572++ # A larger number of internal buffers can reduce the occurrence
573++ # of frame drops during high CPU loads, but might also cause
574++ # additional latency in the system.
575++ #
576++ # Note that the pipeline handler might override this value and
577++ # not allocate any internal buffers if it knows they will never
578++ # be used. For example if the RAW stream is marked as mandatory
579++ # and there are no dropped frames signalled for algorithm
580++ # convergence.
581++ #
582++ "min_unicam_buffers": 2,
583++
584++ # The minimum total (internal + external) buffer count used for
585++ # Unicam. The number of internal buffers allocated for Unicam is
586++ # given by:
587++ #
588++ # internal buffer count = max(min_unicam_buffers,
589++ # min_total_unicam_buffers - external buffer count)
590++ #
591++ "min_total_unicam_buffers": 4,
592++
593++ # Override any request from the IPA to drop a number of startup
594++ # frames.
595++ #
596++ # "disable_startup_frame_drops": false,
597++
598++ # The application will always provide a request buffer for the
599++ # RAW stream, if it has been configured.
600++ "raw_mandatory_stream": true,
601++
602++ # The application will always provide a request buffer for the
603++ # Output 0 stream, if it has been configured.
604++ "output0_mandatory_stream": true,
605++ }
606++}
607+--- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp 2025-05-08 00:06:16.067331148 +0530
608++++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp 2025-05-08 00:06:16.048331443 +0530
609+@@ -104,6 +104,16 @@
610+ * minTotalUnicamBuffers >= minUnicamBuffers
611+ */
612+ unsigned int minTotalUnicamBuffers;
613++ /*
614++ * The application will always provide a request buffer for the
615++ * RAW stream, if it has been configured.
616++ */
617++ bool rawMandatoryStream;
618++ /*
619++ * The application will always provide a request buffer for the
620++ * Output 0 stream, if it has been configured.
621++ */
622++ bool output0MandatoryStream;
623+ };
624+
625+ Config config_;
626+@@ -219,16 +229,47 @@
627+ int PipelineHandlerVc4::prepareBuffers(Camera *camera)
628+ {
629+ Vc4CameraData *data = cameraData(camera);
630+- unsigned int numRawBuffers = 0;
631++ unsigned int minUnicamBuffers = data->config_.minUnicamBuffers;
632++ unsigned int minTotalUnicamBuffers = data->config_.minTotalUnicamBuffers;
633++ unsigned int numRawBuffers = 0, minIspBuffers = 1;
634+ int ret;
635+
636+- for (Stream *s : camera->streams()) {
637+- if (BayerFormat::fromPixelFormat(s->configuration().pixelFormat).isValid()) {
638+- numRawBuffers = s->configuration().bufferCount;
639+- break;
640++ if (data->unicam_[Unicam::Image].getFlags() & StreamFlag::External) {
641++ numRawBuffers = data->unicam_[Unicam::Image].getBuffers().size();
642++ /*
643++ * If the application provides a guarantees that Unicam
644++ * image buffers will always be provided for the RAW stream
645++ * in a Request, we need:
646++ * - at least 1 internal Unicam buffer to handle startup frame drops,
647++ * - no internal Unicam buffers if there are no startup frame drops.
648++ */
649++ if (data->config_.rawMandatoryStream) {
650++ if (data->dropFrameCount_) {
651++ minUnicamBuffers = 2;
652++ minTotalUnicamBuffers = 2;
653++ } else {
654++ minUnicamBuffers = 0;
655++ minTotalUnicamBuffers = 0;
656++ }
657+ }
658+ }
659+
660++ if (data->isp_[Isp::Output0].getFlags() & StreamFlag::External) {
661++ /*
662++ * Since the ISP runs synchronous with the IPA and requests,
663++ * we only ever need a maximum of one internal buffer. Any
664++ * buffers the application wants to hold onto will already
665++ * be exported through PipelineHandlerRPi::exportFrameBuffers().
666++ *
667++ * However, as above, if the application provides a guarantee
668++ * that the buffer will always be provided for the ISP Output0
669++ * stream in a Request, we don't need any internal buffers
670++ * allocated.
671++ */
672++ if (!data->dropFrameCount_ && data->config_.output0MandatoryStream)
673++ minIspBuffers = 0;
674++ }
675++
676+ /* Decide how many internal buffers to allocate. */
677+ for (auto const stream : data->streams_) {
678+ unsigned int numBuffers;
679+@@ -236,7 +277,6 @@
680+ * For Unicam, allocate a minimum number of buffers for internal
681+ * use as we want to avoid any frame drops.
682+ */
683+- const unsigned int minBuffers = data->config_.minTotalUnicamBuffers;
684+ if (stream == &data->unicam_[Unicam::Image]) {
685+ /*
686+ * If an application has configured a RAW stream, allocate
687+@@ -244,8 +284,9 @@
688+ * we have at least minUnicamBuffers of internal buffers
689+ * to use to minimise frame drops.
690+ */
691+- numBuffers = std::max<int>(data->config_.minUnicamBuffers,
692+- minBuffers - numRawBuffers);
693++ numBuffers = std::max<int>(minUnicamBuffers,
694++ minTotalUnicamBuffers - numRawBuffers);
695++ LOG(RPI, Debug) << "Unicam::Image numBuffers " << numBuffers;
696+ } else if (stream == &data->isp_[Isp::Input]) {
697+ /*
698+ * ISP input buffers are imported from Unicam, so follow
699+@@ -253,8 +294,9 @@
700+ * available.
701+ */
702+ numBuffers = numRawBuffers +
703+- std::max<int>(data->config_.minUnicamBuffers,
704+- minBuffers - numRawBuffers);
705++ std::max<int>(minUnicamBuffers,
706++ minTotalUnicamBuffers - numRawBuffers);
707++ LOG(RPI, Debug) << "Isp::Input numBuffers " << numBuffers;
708+
709+ } else if (stream == &data->unicam_[Unicam::Embedded]) {
710+ /*
711+@@ -273,14 +315,18 @@
712+ * buffers, as these will be recycled quicker.
713+ */
714+ numBuffers = 12;
715++ } else if (stream == &data->isp_[Isp::Output0]) {
716++ /* Buffer count for this is handled in the earlier loop above. */
717++ numBuffers = minIspBuffers;
718++ LOG(RPI, Debug) << "Isp::Output0 numBuffers " << numBuffers;
719+ } else {
720+ /*
721+- * Since the ISP runs synchronous with the IPA and requests,
722+- * we only ever need one set of internal buffers. Any buffers
723+- * the application wants to hold onto will already be exported
724+- * through PipelineHandlerRPi::exportFrameBuffers().
725++ * Same reasoning as for ISP Output 0, we only ever need
726++ * a maximum of one internal buffer for Output1 (required
727++ * for colour denoise) and ISP statistics.
728+ */
729+ numBuffers = 1;
730++ LOG(RPI, Debug) << "Other numBuffers " << numBuffers;
731+ }
732+
733+ LOG(RPI, Debug) << "Preparing " << numBuffers
734+@@ -498,6 +544,8 @@
735+ config_ = {
736+ .minUnicamBuffers = 2,
737+ .minTotalUnicamBuffers = 4,
738++ .rawMandatoryStream = false,
739++ .output0MandatoryStream = false,
740+ };
741+
742+ if (!root)
743+@@ -521,6 +569,10 @@
744+ phConfig["min_unicam_buffers"].get<unsigned int>(config_.minUnicamBuffers);
745+ config_.minTotalUnicamBuffers =
746+ phConfig["min_total_unicam_buffers"].get<unsigned int>(config_.minTotalUnicamBuffers);
747++ config_.rawMandatoryStream =
748++ phConfig["raw_mandatory_stream"].get<bool>(config_.rawMandatoryStream);
749++ config_.output0MandatoryStream =
750++ phConfig["output0_mandatory_stream"].get<bool>(config_.output0MandatoryStream);
751+
752+ if (config_.minTotalUnicamBuffers < config_.minUnicamBuffers) {
753+ LOG(RPI, Error) << "Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers";
754+@@ -781,9 +833,15 @@
755+ auto [ctrl, delayContext] = delayedCtrls_->get(buffer->metadata().sequence);
756+ /*
757+ * Add the frame timestamp to the ControlList for the IPA to use
758+- * as it does not receive the FrameBuffer object.
759++ * as it does not receive the FrameBuffer object. Also derive a
760++ * corresponding wallclock value.
761+ */
762+- ctrl.set(controls::SensorTimestamp, buffer->metadata().timestamp);
763++ wallClockRecovery_.addSample();
764++ uint64_t sensorTimestamp = buffer->metadata().timestamp;
765++ uint64_t wallClockTimestamp = wallClockRecovery_.getOutput(sensorTimestamp / 1000);
766++
767++ ctrl.set(controls::SensorTimestamp, sensorTimestamp);
768++ ctrl.set(controls::FrameWallClock, wallClockTimestamp);
769+ bayerQueue_.push({ buffer, std::move(ctrl), delayContext });
770+ } else {
771+ embeddedQueue_.push(buffer);
772+--- a/src/libcamera/v4l2_videodevice.cpp 2025-05-08 00:06:16.067331148 +0530
773++++ b/src/libcamera/v4l2_videodevice.cpp 2025-05-08 00:06:16.048331443 +0530
774+@@ -1625,7 +1625,7 @@
775+ }
776+
777+ /**
778+- * \brief Queue a buffer to the video device
779++ * \brief Queue a buffer to the video device if possible
780+ * \param[in] buffer The buffer to be queued
781+ *
782+ * For capture video devices the \a buffer will be filled with data by the
783+@@ -1639,14 +1639,14 @@
784+ * Note that queueBuffer() will fail if the device is in the process of being
785+ * stopped from a streaming state through streamOff().
786+ *
787++ * V4L2 only allows upto VIDEO_MAX_FRAME frames to be queued at a time, so if
788++ * we reach this limit, store the framebuffers in a pending queue, and try to
789++ * enqueue once a buffer has been dequeued.
790++ *
791+ * \return 0 on success or a negative error code otherwise
792+ */
793+ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer)
794+ {
795+- struct v4l2_plane v4l2Planes[VIDEO_MAX_PLANES] = {};
796+- struct v4l2_buffer buf = {};
797+- int ret;
798+-
799+ if (state_ == State::Stopping) {
800+ LOG(V4L2, Error) << "Device is in a stopping state.";
801+ return -ESHUTDOWN;
802+@@ -1662,133 +1662,25 @@
803+ return -ENOENT;
804+ }
805+
806+- ret = cache_->get(*buffer);
807+- if (ret < 0)
808+- return ret;
809+-
810+- buf.index = ret;
811+- buf.type = bufferType_;
812+- buf.memory = memoryType_;
813+- buf.field = V4L2_FIELD_NONE;
814+-
815+- bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type);
816+- const std::vector<FrameBuffer::Plane> &planes = buffer->planes();
817+- const unsigned int numV4l2Planes = format_.planesCount;
818+-
819+- /*
820+- * Ensure that the frame buffer has enough planes, and that they're
821+- * contiguous if the V4L2 format requires them to be.
822+- */
823+- if (planes.size() < numV4l2Planes) {
824+- LOG(V4L2, Error) << "Frame buffer has too few planes";
825+- return -EINVAL;
826+- }
827+-
828+- if (planes.size() != numV4l2Planes && !buffer->_d()->isContiguous()) {
829+- LOG(V4L2, Error) << "Device format requires contiguous buffer";
830+- return -EINVAL;
831+- }
832+-
833+- if (buf.memory == V4L2_MEMORY_DMABUF) {
834+- if (multiPlanar) {
835+- for (unsigned int p = 0; p < numV4l2Planes; ++p)
836+- v4l2Planes[p].m.fd = planes[p].fd.get();
837+- } else {
838+- buf.m.fd = planes[0].fd.get();
839+- }
840+- }
841+-
842+- if (multiPlanar) {
843+- buf.length = numV4l2Planes;
844+- buf.m.planes = v4l2Planes;
845+- }
846+-
847+- if (V4L2_TYPE_IS_OUTPUT(buf.type)) {
848+- const FrameMetadata &metadata = buffer->metadata();
849+-
850+- for (const auto &plane : metadata.planes()) {
851+- if (!plane.bytesused)
852+- LOG(V4L2, Warning) << "byteused == 0 is deprecated";
853+- }
854+-
855+- if (numV4l2Planes != planes.size()) {
856+- /*
857+- * If we have a multi-planar buffer with a V4L2
858+- * single-planar format, coalesce all planes. The length
859+- * and number of bytes used may only differ in the last
860+- * plane as any other situation can't be represented.
861+- */
862+- unsigned int bytesused = 0;
863+- unsigned int length = 0;
864+-
865+- for (auto [i, plane] : utils::enumerate(planes)) {
866+- bytesused += metadata.planes()[i].bytesused;
867+- length += plane.length;
868+-
869+- if (i != planes.size() - 1 && bytesused != length) {
870+- LOG(V4L2, Error)
871+- << "Holes in multi-planar buffer not supported";
872+- return -EINVAL;
873+- }
874+- }
875+-
876+- if (multiPlanar) {
877+- v4l2Planes[0].bytesused = bytesused;
878+- v4l2Planes[0].length = length;
879+- } else {
880+- buf.bytesused = bytesused;
881+- buf.length = length;
882+- }
883+- } else if (multiPlanar) {
884+- /*
885+- * If we use the multi-planar API, fill in the planes.
886+- * The number of planes in the frame buffer and in the
887+- * V4L2 buffer is guaranteed to be equal at this point.
888+- */
889+- for (auto [i, plane] : utils::enumerate(planes)) {
890+- v4l2Planes[i].bytesused = metadata.planes()[i].bytesused;
891+- v4l2Planes[i].length = plane.length;
892+- }
893+- } else {
894+- /*
895+- * Single-planar API with a single plane in the buffer
896+- * is trivial to handle.
897+- */
898+- buf.bytesused = metadata.planes()[0].bytesused;
899+- buf.length = planes[0].length;
900+- }
901++ if (queuedBuffers_.size() == VIDEO_MAX_FRAME) {
902++ LOG(V4L2, Debug) << "V4L2 queue has " << VIDEO_MAX_FRAME
903++ << " already queued, differing queueing.";
904+
905+- /*
906+- * Timestamps are to be supplied if the device is a mem-to-mem
907+- * device. The drivers will have V4L2_BUF_FLAG_TIMESTAMP_COPY
908+- * set hence these timestamps will be copied from the output
909+- * buffers to capture buffers. If the device is not mem-to-mem,
910+- * there is no harm in setting the timestamps as they will be
911+- * ignored (and over-written).
912+- */
913+- buf.timestamp.tv_sec = metadata.timestamp / 1000000000;
914+- buf.timestamp.tv_usec = (metadata.timestamp / 1000) % 1000000;
915++ pendingBuffersToQueue_.push(buffer);
916++ return 0;
917+ }
918+
919+- LOG(V4L2, Debug) << "Queueing buffer " << buf.index;
920+-
921+- ret = ioctl(VIDIOC_QBUF, &buf);
922+- if (ret < 0) {
923+- LOG(V4L2, Error)
924+- << "Failed to queue buffer " << buf.index << ": "
925+- << strerror(-ret);
926+- return ret;
927+- }
928++ if (!pendingBuffersToQueue_.empty()) {
929++ LOG(V4L2, Debug) << "Adding buffer " << buffer
930++ << " to the pending queue and replacing with "
931++ << pendingBuffersToQueue_.front();
932+
933+- if (queuedBuffers_.empty()) {
934+- fdBufferNotifier_->setEnabled(true);
935+- if (watchdogDuration_)
936+- watchdog_.start(std::chrono::duration_cast<std::chrono::milliseconds>(watchdogDuration_));
937++ pendingBuffersToQueue_.push(buffer);
938++ buffer = pendingBuffersToQueue_.front();
939++ pendingBuffersToQueue_.pop();
940+ }
941+
942+- queuedBuffers_[buf.index] = buffer;
943+-
944+- return 0;
945++ return queueToDevice(buffer);
946+ }
947+
948+ /**
949+@@ -1816,6 +1708,11 @@
950+ * This function dequeues the next available buffer from the device. If no
951+ * buffer is available to be dequeued it will return nullptr immediately.
952+ *
953++ * Once a buffer is dequeued from the device, this function may also enqueue
954++ * a buffer that has been placed in the pending queue (due to reaching the V4L2
955++ * queue size limit. Note that if this enqueue fails, we log the error, but
956++ * continue running this function to completion.
957++ *
958+ * \return A pointer to the dequeued buffer on success, or nullptr otherwise
959+ */
960+ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
961+@@ -1868,6 +1765,20 @@
962+ FrameBuffer *buffer = it->second;
963+ queuedBuffers_.erase(it);
964+
965++ if (!pendingBuffersToQueue_.empty()) {
966++ FrameBuffer *pending = pendingBuffersToQueue_.front();
967++
968++ pendingBuffersToQueue_.pop();
969++ /*
970++ * If the pending buffer enqueue fails, we must continue this
971++ * function to completion for the dequeue operation.
972++ */
973++ if (queueToDevice(pending))
974++ LOG(V4L2, Error)
975++ << "Failed to re-queue pending buffer "
976++ << pending;
977++ }
978++
979+ if (queuedBuffers_.empty()) {
980+ fdBufferNotifier_->setEnabled(false);
981+ watchdog_.stop();
982+@@ -1967,6 +1878,168 @@
983+ }
984+
985+ /**
986++ * \brief Queue a buffer to the video device if possible
987++ * \param[in] buffer The buffer to be queued
988++ *
989++ * For capture video devices the \a buffer will be filled with data by the
990++ * device. For output video devices the \a buffer shall contain valid data and
991++ * will be processed by the device. Once the device has finished processing the
992++ * buffer, it will be available for dequeue.
993++ *
994++ * The best available V4L2 buffer is picked for \a buffer using the V4L2 buffer
995++ * cache.
996++ *
997++ * Note that queueToDevice() will fail if the device is in the process of being
998++ * stopped from a streaming state through streamOff().
999++ *
1000++ * \return 0 on success or a negative error code otherwise
1001++ */
1002++int V4L2VideoDevice::queueToDevice(FrameBuffer *buffer)
1003++{
1004++ struct v4l2_plane v4l2Planes[VIDEO_MAX_PLANES] = {};
1005++ struct v4l2_buffer buf = {};
1006++ int ret;
1007++
1008++ /*
1009++ * Pipeline handlers should not requeue buffers after releasing the
1010++ * buffers on the device. Any occurence of this error should be fixed
1011++ * in the pipeline handler directly.
1012++ */
1013++ if (!cache_) {
1014++ LOG(V4L2, Fatal) << "No BufferCache available to queue.";
1015++ return -ENOENT;
1016++ }
1017++
1018++ ret = cache_->get(*buffer);
1019++ if (ret < 0)
1020++ return ret;
1021++
1022++ buf.index = ret;
1023++ buf.type = bufferType_;
1024++ buf.memory = memoryType_;
1025++ buf.field = V4L2_FIELD_NONE;
1026++
1027++ bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type);
1028++ const std::vector<FrameBuffer::Plane> &planes = buffer->planes();
1029++ const unsigned int numV4l2Planes = format_.planesCount;
1030++
1031++ /*
1032++ * Ensure that the frame buffer has enough planes, and that they're
1033++ * contiguous if the V4L2 format requires them to be.
1034++ */
1035++ if (planes.size() < numV4l2Planes) {
1036++ LOG(V4L2, Error) << "Frame buffer has too few planes";
1037++ return -EINVAL;
1038++ }
1039++
1040++ if (planes.size() != numV4l2Planes && !buffer->_d()->isContiguous()) {
1041++ LOG(V4L2, Error) << "Device format requires contiguous buffer";
1042++ return -EINVAL;
1043++ }
1044++
1045++ if (buf.memory == V4L2_MEMORY_DMABUF) {
1046++ if (multiPlanar) {
1047++ for (unsigned int p = 0; p < numV4l2Planes; ++p)
1048++ v4l2Planes[p].m.fd = planes[p].fd.get();
1049++ } else {
1050++ buf.m.fd = planes[0].fd.get();
1051++ }
1052++ }
1053++
1054++ if (multiPlanar) {
1055++ buf.length = numV4l2Planes;
1056++ buf.m.planes = v4l2Planes;
1057++ }
1058++
1059++ if (V4L2_TYPE_IS_OUTPUT(buf.type)) {
1060++ const FrameMetadata &metadata = buffer->metadata();
1061++
1062++ for (const auto &plane : metadata.planes()) {
1063++ if (!plane.bytesused)
1064++ LOG(V4L2, Warning) << "byteused == 0 is deprecated";
1065++ }
1066++
1067++ if (numV4l2Planes != planes.size()) {
1068++ /*
1069++ * If we have a multi-planar buffer with a V4L2
1070++ * single-planar format, coalesce all planes. The length
1071++ * and number of bytes used may only differ in the last
1072++ * plane as any other situation can't be represented.
1073++ */
1074++ unsigned int bytesused = 0;
1075++ unsigned int length = 0;
1076++
1077++ for (auto [i, plane] : utils::enumerate(planes)) {
1078++ bytesused += metadata.planes()[i].bytesused;
1079++ length += plane.length;
1080++
1081++ if (i != planes.size() - 1 && bytesused != length) {
1082++ LOG(V4L2, Error)
1083++ << "Holes in multi-planar buffer not supported";
1084++ return -EINVAL;
1085++ }
1086++ }
1087++
1088++ if (multiPlanar) {
1089++ v4l2Planes[0].bytesused = bytesused;
1090++ v4l2Planes[0].length = length;
1091++ } else {
1092++ buf.bytesused = bytesused;
1093++ buf.length = length;
1094++ }
1095++ } else if (multiPlanar) {
1096++ /*
1097++ * If we use the multi-planar API, fill in the planes.
1098++ * The number of planes in the frame buffer and in the
1099++ * V4L2 buffer is guaranteed to be equal at this point.
1100++ */
1101++ for (auto [i, plane] : utils::enumerate(planes)) {
1102++ v4l2Planes[i].bytesused = metadata.planes()[i].bytesused;
1103++ v4l2Planes[i].length = plane.length;
1104++ }
1105++ } else {
1106++ /*
1107++ * Single-planar API with a single plane in the buffer
1108++ * is trivial to handle.
1109++ */
1110++ buf.bytesused = metadata.planes()[0].bytesused;
1111++ buf.length = planes[0].length;
1112++ }
1113++
1114++ /*
1115++ * Timestamps are to be supplied if the device is a mem-to-mem
1116++ * device. The drivers will have V4L2_BUF_FLAG_TIMESTAMP_COPY
1117++ * set hence these timestamps will be copied from the output
1118++ * buffers to capture buffers. If the device is not mem-to-mem,
1119++ * there is no harm in setting the timestamps as they will be
1120++ * ignored (and over-written).
1121++ */
1122++ buf.timestamp.tv_sec = metadata.timestamp / 1000000000;
1123++ buf.timestamp.tv_usec = (metadata.timestamp / 1000) % 1000000;
1124++ }
1125++
1126++ LOG(V4L2, Debug) << "Queueing buffer " << buf.index;
1127++
1128++ ret = ioctl(VIDIOC_QBUF, &buf);
1129++ if (ret < 0) {
1130++ LOG(V4L2, Error)
1131++ << "Failed to queue buffer " << buf.index << ": "
1132++ << strerror(-ret);
1133++ return ret;
1134++ }
1135++
1136++ if (queuedBuffers_.empty()) {
1137++ fdBufferNotifier_->setEnabled(true);
1138++ if (watchdogDuration_)
1139++ watchdog_.start(std::chrono::duration_cast<std::chrono::milliseconds>(watchdogDuration_));
1140++ }
1141++
1142++ queuedBuffers_[buf.index] = buffer;
1143++
1144++ return 0;
1145++}
1146++
1147++/**
1148+ * \var V4L2VideoDevice::bufferReady
1149+ * \brief A Signal emitted when a framebuffer completes
1150+ */
1151+--- a/src/ipa/rpi/pisp/data/imx296.json 2025-05-08 00:06:16.067331148 +0530
1152++++ b/src/ipa/rpi/pisp/data/imx296.json 2025-05-08 00:06:16.048331443 +0530
1153+@@ -1189,6 +1189,11 @@
1154+ ]
1155+ }
1156+ }
1157++ },
1158++ {
1159++ "rpi.sync":
1160++ {
1161++ }
1162+ }
1163+ ]
1164+ }
1165+\ No newline at end of file
1166+--- a/src/ipa/rpi/pisp/data/imx296_mono.json 2025-05-08 00:06:16.067331148 +0530
1167++++ b/src/ipa/rpi/pisp/data/imx296_mono.json 2025-05-08 00:06:16.048331443 +0530
1168+@@ -955,6 +955,11 @@
1169+ ]
1170+ }
1171+ }
1172++ },
1173++ {
1174++ "rpi.sync":
1175++ {
1176++ }
1177+ }
1178+ ]
1179+ }
1180+\ No newline at end of file
1181+--- a/src/ipa/rpi/pisp/data/imx477.json 2025-05-08 00:06:16.067331148 +0530
1182++++ b/src/ipa/rpi/pisp/data/imx477.json 2025-05-08 00:06:16.049331427 +0530
1183+@@ -1181,6 +1181,11 @@
1184+ ]
1185+ }
1186+ }
1187++ },
1188++ {
1189++ "rpi.sync":
1190++ {
1191++ }
1192+ }
1193+ ]
1194+ }
1195+\ No newline at end of file
1196+--- a/src/ipa/rpi/pisp/data/imx477_noir.json 2025-05-08 00:06:16.067331148 +0530
1197++++ b/src/ipa/rpi/pisp/data/imx477_noir.json 2025-05-08 00:06:16.049331427 +0530
1198+@@ -1143,6 +1143,11 @@
1199+ ]
1200+ }
1201+ }
1202++ },
1203++ {
1204++ "rpi.sync":
1205++ {
1206++ }
1207+ }
1208+ ]
1209+ }
1210+\ No newline at end of file
1211+--- a/src/ipa/rpi/pisp/data/imx477_scientific.json 2025-05-08 00:06:16.067331148 +0530
1212++++ b/src/ipa/rpi/pisp/data/imx477_scientific.json 2025-05-08 00:06:16.049331427 +0530
1213+@@ -541,6 +541,11 @@
1214+ "limit": 1.0,
1215+ "strength": 1.0
1216+ }
1217++ },
1218++ {
1219++ "rpi.sync":
1220++ {
1221++ }
1222+ }
1223+ ]
1224+ }
1225+\ No newline at end of file
1226+--- a/src/ipa/rpi/pisp/data/imx708.json 2025-05-08 00:06:16.067331148 +0530
1227++++ b/src/ipa/rpi/pisp/data/imx708.json 2025-05-08 00:06:16.049331427 +0530
1228+@@ -1265,6 +1265,11 @@
1229+ ]
1230+ }
1231+ }
1232++ },
1233++ {
1234++ "rpi.sync":
1235++ {
1236++ }
1237+ }
1238+ ]
1239+ }
1240+\ No newline at end of file
1241+--- a/src/ipa/rpi/pisp/data/imx708_noir.json 2025-05-08 00:06:16.067331148 +0530
1242++++ b/src/ipa/rpi/pisp/data/imx708_noir.json 2025-05-08 00:06:16.050331412 +0530
1243+@@ -1228,6 +1228,11 @@
1244+ ]
1245+ }
1246+ }
1247++ },
1248++ {
1249++ "rpi.syc":
1250++ {
1251++ }
1252+ }
1253+ ]
1254+ }
1255+\ No newline at end of file
1256+--- a/src/ipa/rpi/pisp/data/imx708_wide.json 2025-05-08 00:06:16.067331148 +0530
1257++++ b/src/ipa/rpi/pisp/data/imx708_wide.json 2025-05-08 00:06:16.050331412 +0530
1258+@@ -1288,6 +1288,11 @@
1259+ ]
1260+ }
1261+ }
1262++ },
1263++ {
1264++ "rpi.sync":
1265++ {
1266++ }
1267+ }
1268+ ]
1269+ }
1270+\ No newline at end of file
1271+--- a/src/ipa/rpi/pisp/data/imx708_wide_noir.json 2025-05-08 00:06:16.067331148 +0530
1272++++ b/src/ipa/rpi/pisp/data/imx708_wide_noir.json 2025-05-08 00:06:16.050331412 +0530
1273+@@ -1143,6 +1143,11 @@
1274+ ]
1275+ }
1276+ }
1277++ },
1278++ {
1279++ "rpi.sync":
1280++ {
1281++ }
1282+ }
1283+ ]
1284+ }
1285+\ No newline at end of file
1286+--- a/src/ipa/rpi/pisp/data/ov5647.json 2025-05-08 00:06:16.067331148 +0530
1287++++ b/src/ipa/rpi/pisp/data/ov5647.json 2025-05-08 00:06:16.050331412 +0530
1288+@@ -1181,6 +1181,11 @@
1289+ ]
1290+ }
1291+ }
1292++ },
1293++ {
1294++ "rpi.sync":
1295++ {
1296++ }
1297+ }
1298+ ]
1299+ }
1300+\ No newline at end of file
1301+--- a/src/ipa/rpi/pisp/data/ov5647_noir.json 2025-05-08 00:06:16.067331148 +0530
1302++++ b/src/ipa/rpi/pisp/data/ov5647_noir.json 2025-05-08 00:06:16.050331412 +0530
1303+@@ -1116,6 +1116,11 @@
1304+ ]
1305+ }
1306+ }
1307++ },
1308++ {
1309++ "rpi.sync":
1310++ {
1311++ }
1312+ }
1313+ ]
1314+ }
1315+\ No newline at end of file
1316+--- a/src/ipa/rpi/vc4/data/meson.build 2025-05-08 00:06:16.067331148 +0530
1317++++ b/src/ipa/rpi/vc4/data/meson.build 2025-05-08 00:06:16.051331396 +0530
1318+@@ -14,6 +14,7 @@
1319+ 'imx477.json',
1320+ 'imx477_noir.json',
1321+ 'imx477_scientific.json',
1322++ 'imx500.json',
1323+ 'imx519.json',
1324+ 'imx708.json',
1325+ 'imx708_noir.json',
1326+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1327++++ b/src/ipa/rpi/vc4/data/imx500.json 2025-05-08 00:06:16.051331396 +0530
1328+@@ -0,0 +1,468 @@
1329++{
1330++ "version": 2.0,
1331++ "target": "bcm2835",
1332++ "algorithms": [
1333++ {
1334++ "rpi.black_level":
1335++ {
1336++ "black_level": 4096
1337++ }
1338++ },
1339++ {
1340++ "rpi.dpc": { }
1341++ },
1342++ {
1343++ "rpi.lux":
1344++ {
1345++ "reference_shutter_speed": 10369,
1346++ "reference_gain": 2.0,
1347++ "reference_aperture": 1.0,
1348++ "reference_lux": 950,
1349++ "reference_Y": 12457
1350++ }
1351++ },
1352++ {
1353++ "rpi.noise":
1354++ {
1355++ "reference_constant": 0,
1356++ "reference_slope": 2.747
1357++ }
1358++ },
1359++ {
1360++ "rpi.geq":
1361++ {
1362++ "offset": 223,
1363++ "slope": 0.00933
1364++ }
1365++ },
1366++ {
1367++ "rpi.sdn": { }
1368++ },
1369++ {
1370++ "rpi.awb":
1371++ {
1372++ "priors": [
1373++ {
1374++ "lux": 0,
1375++ "prior":
1376++ [
1377++ 2000, 1.0,
1378++ 3000, 0.0,
1379++ 13000, 0.0
1380++ ]
1381++ },
1382++ {
1383++ "lux": 800,
1384++ "prior":
1385++ [
1386++ 2000, 0.0,
1387++ 6000, 2.0,
1388++ 13000, 2.0
1389++ ]
1390++ },
1391++ {
1392++ "lux": 1500,
1393++ "prior":
1394++ [
1395++ 2000, 0.0,
1396++ 4000, 1.0,
1397++ 6000, 6.0,
1398++ 6500, 7.0,
1399++ 7000, 1.0,
1400++ 13000, 1.0
1401++ ]
1402++ }
1403++ ],
1404++ "modes":
1405++ {
1406++ "auto":
1407++ {
1408++ "lo": 2800,
1409++ "hi": 8000
1410++ },
1411++ "incandescent":
1412++ {
1413++ "lo": 2800,
1414++ "hi": 3000
1415++ },
1416++ "tungsten":
1417++ {
1418++ "lo": 3000,
1419++ "hi": 3500
1420++ },
1421++ "fluorescent":
1422++ {
1423++ "lo": 4000,
1424++ "hi": 4700
1425++ },
1426++ "indoor":
1427++ {
1428++ "lo": 3000,
1429++ "hi": 5000
1430++ },
1431++ "daylight":
1432++ {
1433++ "lo": 5500,
1434++ "hi": 6500
1435++ },
1436++ "cloudy":
1437++ {
1438++ "lo": 7000,
1439++ "hi": 7600
1440++ }
1441++ },
1442++ "bayes": 1,
1443++ "ct_curve":
1444++ [
1445++ 2800.0, 0.7126, 0.3567,
1446++ 2860.0, 0.6681, 0.4042,
1447++ 2880.0, 0.6651, 0.4074,
1448++ 3580.0, 0.5674, 0.5091,
1449++ 3650.0, 0.5629, 0.5137,
1450++ 4500.0, 0.4792, 0.5982,
1451++ 4570.0, 0.4752, 0.6022,
1452++ 5648.0, 0.4137, 0.6628,
1453++ 5717.0, 0.4116, 0.6648,
1454++ 7600.0, 0.3609, 0.7138
1455++ ],
1456++ "sensitivity_r": 1.0,
1457++ "sensitivity_b": 1.0,
1458++ "transverse_pos": 0.02798,
1459++ "transverse_neg": 0.02626
1460++ }
1461++ },
1462++ {
1463++ "rpi.agc":
1464++ {
1465++ "metering_modes":
1466++ {
1467++ "centre-weighted":
1468++ {
1469++ "weights":
1470++ [
1471++ 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0
1472++ ]
1473++ },
1474++ "spot":
1475++ {
1476++ "weights":
1477++ [
1478++ 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1479++ ]
1480++ },
1481++ "matrix":
1482++ {
1483++ "weights":
1484++ [
1485++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1486++ ]
1487++ }
1488++ },
1489++ "exposure_modes":
1490++ {
1491++ "normal":
1492++ {
1493++ "shutter": [ 100, 10000, 30000, 60000, 120000 ],
1494++ "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ]
1495++ },
1496++ "short":
1497++ {
1498++ "shutter": [ 100, 5000, 10000, 20000, 120000 ],
1499++ "gain": [ 1.0, 2.0, 4.0, 6.0, 6.0 ]
1500++ }
1501++ },
1502++ "constraint_modes":
1503++ {
1504++ "normal": [
1505++ {
1506++ "bound": "LOWER",
1507++ "q_lo": 0.98,
1508++ "q_hi": 1.0,
1509++ "y_target":
1510++ [
1511++ 0, 0.5,
1512++ 1000, 0.5
1513++ ]
1514++ }
1515++ ],
1516++ "highlight": [
1517++ {
1518++ "bound": "LOWER",
1519++ "q_lo": 0.98,
1520++ "q_hi": 1.0,
1521++ "y_target":
1522++ [
1523++ 0, 0.5,
1524++ 1000, 0.5
1525++ ]
1526++ },
1527++ {
1528++ "bound": "UPPER",
1529++ "q_lo": 0.98,
1530++ "q_hi": 1.0,
1531++ "y_target":
1532++ [
1533++ 0, 0.8,
1534++ 1000, 0.8
1535++ ]
1536++ }
1537++ ]
1538++ },
1539++ "y_target":
1540++ [
1541++ 0, 0.16,
1542++ 1000, 0.165,
1543++ 10000, 0.17
1544++ ]
1545++ }
1546++ },
1547++ {
1548++ "rpi.alsc":
1549++ {
1550++ "omega": 1.3,
1551++ "n_iter": 100,
1552++ "luminance_strength": 0.8,
1553++ "calibrations_Cr": [
1554++ {
1555++ "ct": 2800,
1556++ "table":
1557++ [
1558++ 1.613, 1.617, 1.621, 1.621, 1.615, 1.607, 1.604, 1.603, 1.603, 1.603, 1.607, 1.619, 1.626, 1.626, 1.622, 1.615,
1559++ 1.613, 1.616, 1.617, 1.615, 1.599, 1.583, 1.571, 1.564, 1.564, 1.571, 1.584, 1.603, 1.621, 1.624, 1.622, 1.618,
1560++ 1.613, 1.614, 1.614, 1.599, 1.577, 1.546, 1.529, 1.521, 1.521, 1.529, 1.548, 1.582, 1.603, 1.621, 1.621, 1.621,
1561++ 1.613, 1.613, 1.604, 1.577, 1.546, 1.521, 1.489, 1.481, 1.481, 1.491, 1.525, 1.548, 1.582, 1.612, 1.621, 1.623,
1562++ 1.614, 1.612, 1.595, 1.561, 1.521, 1.489, 1.475, 1.453, 1.453, 1.479, 1.491, 1.525, 1.567, 1.606, 1.623, 1.624,
1563++ 1.614, 1.612, 1.593, 1.555, 1.513, 1.477, 1.454, 1.452, 1.453, 1.455, 1.481, 1.519, 1.563, 1.604, 1.624, 1.626,
1564++ 1.615, 1.612, 1.593, 1.555, 1.513, 1.477, 1.458, 1.452, 1.453, 1.459, 1.481, 1.519, 1.563, 1.604, 1.625, 1.626,
1565++ 1.615, 1.614, 1.599, 1.564, 1.525, 1.496, 1.477, 1.459, 1.459, 1.481, 1.497, 1.531, 1.572, 1.609, 1.626, 1.627,
1566++ 1.614, 1.614, 1.609, 1.581, 1.552, 1.525, 1.496, 1.488, 1.488, 1.497, 1.531, 1.558, 1.591, 1.619, 1.626, 1.626,
1567++ 1.614, 1.616, 1.618, 1.607, 1.581, 1.552, 1.535, 1.529, 1.529, 1.538, 1.558, 1.591, 1.616, 1.631, 1.631, 1.625,
1568++ 1.613, 1.618, 1.619, 1.621, 1.607, 1.591, 1.579, 1.575, 1.575, 1.582, 1.597, 1.616, 1.631, 1.632, 1.631, 1.625,
1569++ 1.611, 1.616, 1.622, 1.623, 1.621, 1.615, 1.614, 1.614, 1.614, 1.615, 1.619, 1.631, 1.633, 1.633, 1.629, 1.624
1570++ ]
1571++ },
1572++ {
1573++ "ct": 4000,
1574++ "table":
1575++ [
1576++ 2.051, 2.057, 2.058, 2.058, 2.052, 2.045, 2.041, 2.041, 2.041, 2.042, 2.047, 2.062, 2.071, 2.071, 2.068, 2.061,
1577++ 2.051, 2.053, 2.055, 2.051, 2.033, 2.014, 2.001, 1.995, 1.995, 2.004, 2.019, 2.042, 2.064, 2.069, 2.068, 2.062,
1578++ 2.051, 2.051, 2.051, 2.033, 2.005, 1.971, 1.951, 1.943, 1.943, 1.953, 1.976, 2.016, 2.042, 2.064, 2.065, 2.065,
1579++ 2.049, 2.049, 2.037, 2.005, 1.971, 1.939, 1.904, 1.894, 1.894, 1.906, 1.947, 1.976, 2.016, 2.053, 2.065, 2.066,
1580++ 2.051, 2.048, 2.028, 1.987, 1.939, 1.904, 1.884, 1.858, 1.858, 1.891, 1.906, 1.947, 1.998, 2.044, 2.066, 2.068,
1581++ 2.051, 2.048, 2.025, 1.981, 1.929, 1.886, 1.858, 1.855, 1.857, 1.861, 1.892, 1.939, 1.992, 2.041, 2.068, 2.068,
1582++ 2.052, 2.048, 2.025, 1.981, 1.929, 1.886, 1.863, 1.855, 1.858, 1.864, 1.892, 1.939, 1.992, 2.041, 2.068, 2.069,
1583++ 2.053, 2.052, 2.033, 1.992, 1.944, 1.911, 1.886, 1.864, 1.864, 1.892, 1.912, 1.953, 2.003, 2.048, 2.069, 2.069,
1584++ 2.053, 2.053, 2.046, 2.013, 1.978, 1.944, 1.911, 1.901, 1.901, 1.912, 1.953, 1.985, 2.023, 2.059, 2.069, 2.069,
1585++ 2.053, 2.055, 2.058, 2.044, 2.013, 1.978, 1.959, 1.951, 1.951, 1.961, 1.985, 2.023, 2.054, 2.071, 2.071, 2.068,
1586++ 2.052, 2.058, 2.059, 2.061, 2.044, 2.025, 2.011, 2.005, 2.005, 2.014, 2.031, 2.054, 2.071, 2.075, 2.072, 2.068,
1587++ 2.051, 2.056, 2.064, 2.064, 2.061, 2.055, 2.052, 2.052, 2.052, 2.054, 2.058, 2.071, 2.077, 2.077, 2.072, 2.067
1588++ ]
1589++ }
1590++ ],
1591++ "calibrations_Cb": [
1592++ {
1593++ "ct": 2800,
1594++ "table":
1595++ [
1596++ 2.878, 2.876, 2.864, 2.851, 2.847, 2.847, 2.849, 2.854, 2.854, 2.854, 2.854, 2.854, 2.861, 2.873, 2.885, 2.887,
1597++ 2.876, 2.871, 2.859, 2.852, 2.849, 2.849, 2.854, 2.855, 2.855, 2.855, 2.854, 2.852, 2.854, 2.861, 2.875, 2.885,
1598++ 2.872, 2.869, 2.859, 2.856, 2.854, 2.856, 2.859, 2.863, 2.863, 2.861, 2.855, 2.852, 2.853, 2.855, 2.867, 2.875,
1599++ 2.872, 2.871, 2.865, 2.859, 2.858, 2.863, 2.869, 2.877, 2.877, 2.872, 2.861, 2.856, 2.854, 2.857, 2.863, 2.873,
1600++ 2.872, 2.871, 2.868, 2.865, 2.866, 2.872, 2.886, 2.899, 2.899, 2.879, 2.872, 2.861, 2.857, 2.859, 2.862, 2.871,
1601++ 2.872, 2.871, 2.869, 2.869, 2.872, 2.886, 2.901, 2.909, 2.903, 2.899, 2.879, 2.865, 2.859, 2.859, 2.861, 2.869,
1602++ 2.872, 2.871, 2.871, 2.871, 2.873, 2.886, 2.906, 2.909, 2.908, 2.902, 2.879, 2.865, 2.859, 2.859, 2.861, 2.868,
1603++ 2.872, 2.871, 2.871, 2.869, 2.873, 2.884, 2.892, 2.907, 2.903, 2.889, 2.875, 2.864, 2.859, 2.859, 2.861, 2.868,
1604++ 2.875, 2.872, 2.868, 2.867, 2.869, 2.874, 2.884, 2.889, 2.889, 2.877, 2.866, 2.859, 2.859, 2.861, 2.864, 2.872,
1605++ 2.877, 2.875, 2.867, 2.864, 2.865, 2.869, 2.874, 2.877, 2.877, 2.868, 2.861, 2.859, 2.859, 2.863, 2.872, 2.881,
1606++ 2.882, 2.877, 2.868, 2.863, 2.863, 2.863, 2.868, 2.869, 2.868, 2.865, 2.863, 2.861, 2.863, 2.871, 2.881, 2.883,
1607++ 2.885, 2.882, 2.872, 2.864, 2.861, 2.861, 2.865, 2.865, 2.865, 2.864, 2.863, 2.863, 2.866, 2.872, 2.882, 2.891
1608++ ]
1609++ },
1610++ {
1611++ "ct": 4000,
1612++ "table":
1613++ [
1614++ 1.919, 1.919, 1.913, 1.909, 1.909, 1.909, 1.911, 1.912, 1.912, 1.911, 1.909, 1.909, 1.911, 1.914, 1.919, 1.921,
1615++ 1.919, 1.916, 1.913, 1.911, 1.909, 1.912, 1.914, 1.915, 1.914, 1.913, 1.911, 1.909, 1.909, 1.911, 1.915, 1.919,
1616++ 1.916, 1.915, 1.915, 1.914, 1.914, 1.918, 1.921, 1.921, 1.921, 1.919, 1.915, 1.911, 1.909, 1.911, 1.913, 1.916,
1617++ 1.916, 1.916, 1.916, 1.916, 1.919, 1.924, 1.928, 1.932, 1.932, 1.928, 1.919, 1.915, 1.911, 1.911, 1.912, 1.914,
1618++ 1.916, 1.917, 1.918, 1.919, 1.924, 1.928, 1.937, 1.945, 1.945, 1.932, 1.928, 1.919, 1.915, 1.912, 1.912, 1.913,
1619++ 1.916, 1.918, 1.919, 1.923, 1.928, 1.937, 1.946, 1.949, 1.946, 1.945, 1.931, 1.922, 1.916, 1.912, 1.912, 1.913,
1620++ 1.916, 1.918, 1.919, 1.923, 1.928, 1.937, 1.948, 1.949, 1.948, 1.945, 1.931, 1.922, 1.916, 1.912, 1.912, 1.912,
1621++ 1.915, 1.917, 1.918, 1.922, 1.927, 1.933, 1.938, 1.946, 1.945, 1.935, 1.928, 1.919, 1.915, 1.912, 1.912, 1.912,
1622++ 1.916, 1.916, 1.917, 1.918, 1.922, 1.927, 1.933, 1.935, 1.935, 1.928, 1.921, 1.915, 1.913, 1.912, 1.912, 1.914,
1623++ 1.917, 1.916, 1.916, 1.915, 1.917, 1.921, 1.925, 1.926, 1.926, 1.921, 1.918, 1.913, 1.913, 1.913, 1.916, 1.919,
1624++ 1.918, 1.917, 1.915, 1.913, 1.913, 1.916, 1.919, 1.921, 1.921, 1.918, 1.914, 1.913, 1.913, 1.915, 1.918, 1.921,
1625++ 1.919, 1.919, 1.914, 1.912, 1.912, 1.913, 1.914, 1.915, 1.915, 1.915, 1.913, 1.913, 1.913, 1.915, 1.919, 1.922
1626++ ]
1627++ }
1628++ ],
1629++ "luminance_lut":
1630++ [
1631++ 3.029, 2.888, 2.497, 2.201, 1.954, 1.761, 1.711, 1.711, 1.711, 1.713, 1.778, 1.975, 2.225, 2.526, 2.925, 3.069,
1632++ 2.888, 2.562, 2.203, 1.999, 1.762, 1.602, 1.495, 1.447, 1.447, 1.503, 1.616, 1.785, 2.019, 2.229, 2.594, 2.925,
1633++ 2.577, 2.319, 2.004, 1.762, 1.602, 1.391, 1.284, 1.241, 1.241, 1.294, 1.409, 1.616, 1.785, 2.031, 2.349, 2.607,
1634++ 2.451, 2.155, 1.861, 1.607, 1.391, 1.284, 1.137, 1.095, 1.095, 1.154, 1.294, 1.409, 1.631, 1.891, 2.185, 2.483,
1635++ 2.393, 2.056, 1.765, 1.501, 1.288, 1.137, 1.091, 1.004, 1.011, 1.095, 1.154, 1.309, 1.527, 1.796, 2.088, 2.425,
1636++ 2.393, 2.015, 1.722, 1.455, 1.245, 1.097, 1.004, 1.001, 1.001, 1.016, 1.115, 1.266, 1.482, 1.752, 2.046, 2.425,
1637++ 2.393, 2.015, 1.722, 1.455, 1.245, 1.097, 1.014, 1.001, 1.011, 1.017, 1.115, 1.266, 1.482, 1.752, 2.046, 2.425,
1638++ 2.399, 2.071, 1.777, 1.515, 1.301, 1.158, 1.097, 1.017, 1.017, 1.114, 1.169, 1.323, 1.543, 1.809, 2.102, 2.429,
1639++ 2.471, 2.178, 1.881, 1.628, 1.419, 1.301, 1.158, 1.117, 1.117, 1.169, 1.323, 1.439, 1.657, 1.915, 2.213, 2.501,
1640++ 2.622, 2.358, 2.034, 1.799, 1.628, 1.419, 1.315, 1.271, 1.271, 1.327, 1.439, 1.657, 1.824, 2.067, 2.394, 2.662,
1641++ 2.959, 2.622, 2.255, 2.034, 1.799, 1.644, 1.536, 1.489, 1.489, 1.548, 1.664, 1.824, 2.066, 2.284, 2.662, 3.018,
1642++ 3.099, 2.959, 2.559, 2.249, 1.994, 1.803, 1.756, 1.756, 1.756, 1.759, 1.824, 2.022, 2.281, 2.601, 3.018, 3.155
1643++ ],
1644++ "sigma": 0.00096,
1645++ "sigma_Cb": 0.00125
1646++ }
1647++ },
1648++ {
1649++ "rpi.contrast":
1650++ {
1651++ "ce_enable": 1,
1652++ "gamma_curve":
1653++ [
1654++ 0, 0,
1655++ 1024, 5040,
1656++ 2048, 9338,
1657++ 3072, 12356,
1658++ 4096, 15312,
1659++ 5120, 18051,
1660++ 6144, 20790,
1661++ 7168, 23193,
1662++ 8192, 25744,
1663++ 9216, 27942,
1664++ 10240, 30035,
1665++ 11264, 32005,
1666++ 12288, 33975,
1667++ 13312, 35815,
1668++ 14336, 37600,
1669++ 15360, 39168,
1670++ 16384, 40642,
1671++ 18432, 43379,
1672++ 20480, 45749,
1673++ 22528, 47753,
1674++ 24576, 49621,
1675++ 26624, 51253,
1676++ 28672, 52698,
1677++ 30720, 53796,
1678++ 32768, 54876,
1679++ 36864, 57012,
1680++ 40960, 58656,
1681++ 45056, 59954,
1682++ 49152, 61183,
1683++ 53248, 62355,
1684++ 57344, 63419,
1685++ 61440, 64476,
1686++ 65535, 65535
1687++ ]
1688++ }
1689++ },
1690++ {
1691++ "rpi.ccm":
1692++ {
1693++ "ccms": [
1694++ {
1695++ "ct": 2800,
1696++ "ccm":
1697++ [
1698++ 1.61505, -0.29143, -0.32361,
1699++ -0.36502, 1.73067, -0.36565,
1700++ 0.05048, -1.11795, 2.06747
1701++ ]
1702++ },
1703++ {
1704++ "ct": 2860,
1705++ "ccm":
1706++ [
1707++ 1.61304, -0.35407, -0.25897,
1708++ -0.49934, 1.98721, -0.48786,
1709++ -0.03138, -0.70205, 1.73343
1710++ ]
1711++ },
1712++ {
1713++ "ct": 2880,
1714++ "ccm":
1715++ [
1716++ 1.61025, -0.33823, -0.27202,
1717++ -0.49191, 1.99155, -0.49964,
1718++ -0.02357, -0.74144, 1.76501
1719++ ]
1720++ },
1721++ {
1722++ "ct": 3580,
1723++ "ccm":
1724++ [
1725++ 1.67102, -0.45799, -0.21303,
1726++ -0.43726, 1.89058, -0.45332,
1727++ -0.04778, -0.57899, 1.62678
1728++ ]
1729++ },
1730++ {
1731++ "ct": 3650,
1732++ "ccm":
1733++ [
1734++ 1.66289, -0.44966, -0.21324,
1735++ -0.42687, 1.86716, -0.44029,
1736++ -0.04423, -0.55781, 1.60204
1737++ ]
1738++ },
1739++ {
1740++ "ct": 4500,
1741++ "ccm":
1742++ [
1743++ 1.59699, -0.35409, -0.24291,
1744++ -0.38812, 1.97453, -0.58641,
1745++ -0.05398, -0.50715, 1.56113
1746++ ]
1747++ },
1748++ {
1749++ "ct": 4570,
1750++ "ccm":
1751++ [
1752++ 1.62669, -0.38858, -0.23811,
1753++ -0.38608, 1.97311, -0.58703,
1754++ -0.05461, -0.52526, 1.57986
1755++ ]
1756++ },
1757++ {
1758++ "ct": 5648,
1759++ "ccm":
1760++ [
1761++ 1.77461, -0.60797, -0.16664,
1762++ -0.33734, 1.82254, -0.48521,
1763++ -0.06916, -0.43139, 1.50056
1764++ ]
1765++ },
1766++ {
1767++ "ct": 5717,
1768++ "ccm":
1769++ [
1770++ 1.76115, -0.59353, -0.16763,
1771++ -0.33521, 1.82009, -0.48488,
1772++ -0.07309, -0.42667, 1.49976
1773++ ]
1774++ },
1775++ {
1776++ "ct": 7600,
1777++ "ccm":
1778++ [
1779++ 1.71087, -0.34863, -0.36223,
1780++ -0.31392, 2.24605, -0.93213,
1781++ -0.08447, -0.72208, 1.80655
1782++ ]
1783++ }
1784++ ]
1785++ }
1786++ },
1787++ {
1788++ "rpi.sharpen": { }
1789++ },
1790++ {
1791++ "rpi.sync":
1792++ {
1793++ }
1794++ }
1795++ ]
1796++}
1797+\ No newline at end of file
1798+--- a/src/ipa/rpi/pisp/data/imx290.json 2025-05-08 00:06:16.067331148 +0530
1799++++ b/src/ipa/rpi/pisp/data/imx290.json 2025-05-08 00:06:16.052331381 +0530
1800+@@ -336,6 +336,11 @@
1801+ }
1802+ ]
1803+ }
1804++ },
1805++ {
1806++ "rpi.sync":
1807++ {
1808++ }
1809+ }
1810+ ]
1811+ }
1812+\ No newline at end of file
1813+--- a/src/ipa/rpi/pisp/data/imx296_16mm.json 2025-05-08 00:06:16.067331148 +0530
1814++++ b/src/ipa/rpi/pisp/data/imx296_16mm.json 2025-05-08 00:06:16.052331381 +0530
1815+@@ -1242,6 +1242,11 @@
1816+ ]
1817+ }
1818+ }
1819++ },
1820++ {
1821++ "rpi.sync":
1822++ {
1823++ }
1824+ }
1825+ ]
1826+ }
1827+\ No newline at end of file
1828+--- a/src/ipa/rpi/pisp/data/imx296_6mm.json 2025-05-08 00:06:16.067331148 +0530
1829++++ b/src/ipa/rpi/pisp/data/imx296_6mm.json 2025-05-08 00:06:16.052331381 +0530
1830+@@ -1242,6 +1242,11 @@
1831+ ]
1832+ }
1833+ }
1834++ },
1835++ {
1836++ "rpi.sync":
1837++ {
1838++ }
1839+ }
1840+ ]
1841+ }
1842+\ No newline at end of file
1843+--- a/src/ipa/rpi/pisp/data/imx378.json 2025-05-08 00:06:16.067331148 +0530
1844++++ b/src/ipa/rpi/pisp/data/imx378.json 2025-05-08 00:06:16.052331381 +0530
1845+@@ -629,6 +629,11 @@
1846+ },
1847+ {
1848+ "rpi.sharpen": { }
1849++ },
1850++ {
1851++ "rpi.sync":
1852++ {
1853++ }
1854+ }
1855+ ]
1856+ }
1857+\ No newline at end of file
1858+--- a/src/ipa/rpi/pisp/data/imx477_16mm.json 2025-05-08 00:06:16.067331148 +0530
1859++++ b/src/ipa/rpi/pisp/data/imx477_16mm.json 2025-05-08 00:06:16.053331365 +0530
1860+@@ -1235,6 +1235,11 @@
1861+ ]
1862+ }
1863+ }
1864++ },
1865++ {
1866++ "rpi.sync":
1867++ {
1868++ }
1869+ }
1870+ ]
1871+ }
1872+\ No newline at end of file
1873+--- a/src/ipa/rpi/pisp/data/imx477_6mm.json 2025-05-08 00:06:16.067331148 +0530
1874++++ b/src/ipa/rpi/pisp/data/imx477_6mm.json 2025-05-08 00:06:16.053331365 +0530
1875+@@ -1235,6 +1235,11 @@
1876+ ]
1877+ }
1878+ }
1879++ },
1880++ {
1881++ "rpi.sync":
1882++ {
1883++ }
1884+ }
1885+ ]
1886+ }
1887+\ No newline at end of file
1888+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1889++++ b/src/ipa/rpi/pisp/data/imx500.json 2025-05-08 00:06:16.053331365 +0530
1890+@@ -0,0 +1,1214 @@
1891++{
1892++ "version": 2.0,
1893++ "target": "pisp",
1894++ "algorithms": [
1895++ {
1896++ "rpi.black_level":
1897++ {
1898++ "black_level": 4096
1899++ }
1900++ },
1901++ {
1902++ "rpi.lux":
1903++ {
1904++ "reference_shutter_speed": 10369,
1905++ "reference_gain": 2.0,
1906++ "reference_aperture": 1.0,
1907++ "reference_lux": 950,
1908++ "reference_Y": 12457
1909++ }
1910++ },
1911++ {
1912++ "rpi.dpc":
1913++ {
1914++ "strength": 1
1915++ }
1916++ },
1917++ {
1918++ "rpi.noise":
1919++ {
1920++ "reference_constant": 0,
1921++ "reference_slope": 2.747
1922++ }
1923++ },
1924++ {
1925++ "rpi.geq":
1926++ {
1927++ "offset": 223,
1928++ "slope": 0.00933
1929++ }
1930++ },
1931++ {
1932++ "rpi.denoise":
1933++ {
1934++ "normal":
1935++ {
1936++ "sdn":
1937++ {
1938++ "deviation": 1.6,
1939++ "strength": 0.5,
1940++ "deviation2": 3.2,
1941++ "deviation_no_tdn": 3.2,
1942++ "strength_no_tdn": 0.75
1943++ },
1944++ "cdn":
1945++ {
1946++ "deviation": 200,
1947++ "strength": 0.3
1948++ },
1949++ "tdn":
1950++ {
1951++ "deviation": 0.8,
1952++ "threshold": 0.05
1953++ }
1954++ },
1955++ "hdr":
1956++ {
1957++ "sdn":
1958++ {
1959++ "deviation": 1.6,
1960++ "strength": 0.5,
1961++ "deviation2": 3.2,
1962++ "deviation_no_tdn": 3.2,
1963++ "strength_no_tdn": 0.75
1964++ },
1965++ "cdn":
1966++ {
1967++ "deviation": 200,
1968++ "strength": 0.3
1969++ },
1970++ "tdn":
1971++ {
1972++ "deviation": 1.3,
1973++ "threshold": 0.1
1974++ }
1975++ },
1976++ "night":
1977++ {
1978++ "sdn":
1979++ {
1980++ "deviation": 1.6,
1981++ "strength": 0.5,
1982++ "deviation2": 3.2,
1983++ "deviation_no_tdn": 3.2,
1984++ "strength_no_tdn": 0.75
1985++ },
1986++ "cdn":
1987++ {
1988++ "deviation": 200,
1989++ "strength": 0.3
1990++ },
1991++ "tdn":
1992++ {
1993++ "deviation": 1.3,
1994++ "threshold": 0.1
1995++ }
1996++ }
1997++ }
1998++ },
1999++ {
2000++ "rpi.awb":
2001++ {
2002++ "priors": [
2003++ {
2004++ "lux": 0,
2005++ "prior":
2006++ [
2007++ 2000, 1.0,
2008++ 3000, 0.0,
2009++ 13000, 0.0
2010++ ]
2011++ },
2012++ {
2013++ "lux": 800,
2014++ "prior":
2015++ [
2016++ 2000, 0.0,
2017++ 6000, 2.0,
2018++ 13000, 2.0
2019++ ]
2020++ },
2021++ {
2022++ "lux": 1500,
2023++ "prior":
2024++ [
2025++ 2000, 0.0,
2026++ 4000, 1.0,
2027++ 6000, 6.0,
2028++ 6500, 7.0,
2029++ 7000, 1.0,
2030++ 13000, 1.0
2031++ ]
2032++ }
2033++ ],
2034++ "modes":
2035++ {
2036++ "auto":
2037++ {
2038++ "lo": 2800,
2039++ "hi": 7700
2040++ },
2041++ "incandescent":
2042++ {
2043++ "lo": 2800,
2044++ "hi": 3000
2045++ },
2046++ "tungsten":
2047++ {
2048++ "lo": 3000,
2049++ "hi": 3500
2050++ },
2051++ "fluorescent":
2052++ {
2053++ "lo": 4000,
2054++ "hi": 4700
2055++ },
2056++ "indoor":
2057++ {
2058++ "lo": 3000,
2059++ "hi": 5000
2060++ },
2061++ "daylight":
2062++ {
2063++ "lo": 5500,
2064++ "hi": 6500
2065++ },
2066++ "cloudy":
2067++ {
2068++ "lo": 7000,
2069++ "hi": 7600
2070++ }
2071++ },
2072++ "bayes": 1,
2073++ "ct_curve":
2074++ [
2075++ 2800.0, 0.7115, 0.3579,
2076++ 2860.0, 0.6671, 0.4058,
2077++ 2880.0, 0.6641, 0.4089,
2078++ 3580.0, 0.5665, 0.5113,
2079++ 3650.0, 0.5621, 0.5159,
2080++ 4500.0, 0.4799, 0.5997,
2081++ 4570.0, 0.4752, 0.6046,
2082++ 5648.0, 0.4139, 0.6657,
2083++ 5717.0, 0.4118, 0.6678,
2084++ 7600.0, 0.3625, 0.7162
2085++ ],
2086++ "sensitivity_r": 1.0,
2087++ "sensitivity_b": 1.0,
2088++ "transverse_pos": 0.02822,
2089++ "transverse_neg": 0.02678
2090++ }
2091++ },
2092++ {
2093++ "rpi.agc":
2094++ {
2095++ "channels": [
2096++ {
2097++ "comment": "Channel 0 is normal AGC",
2098++ "metering_modes":
2099++ {
2100++ "centre-weighted":
2101++ {
2102++ "weights":
2103++ [
2104++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2105++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2106++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2107++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2108++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2109++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2110++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2111++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
2112++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2113++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2114++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2115++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2116++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2117++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2118++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
2119++ ]
2120++ },
2121++ "spot":
2122++ {
2123++ "weights":
2124++ [
2125++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2126++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2127++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2128++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2129++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2130++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2131++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2132++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
2133++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2134++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2135++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2136++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2137++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2138++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2139++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2140++ ]
2141++ },
2142++ "matrix":
2143++ {
2144++ "weights":
2145++ [
2146++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2147++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2148++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2149++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2150++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2151++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2152++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2153++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2154++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2155++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2156++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2157++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2158++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2159++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2160++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2161++ ]
2162++ }
2163++ },
2164++ "exposure_modes":
2165++ {
2166++ "normal":
2167++ {
2168++ "shutter": [ 100, 10000, 30000, 60000, 66666 ],
2169++ "gain": [ 1.0, 1.5, 2.0, 4.0, 8.0 ]
2170++ },
2171++ "short":
2172++ {
2173++ "shutter": [ 100, 5000, 10000, 20000, 60000 ],
2174++ "gain": [ 1.0, 1.5, 2.0, 4.0, 8.0 ]
2175++ },
2176++ "long":
2177++ {
2178++ "shutter": [ 100, 10000, 30000, 60000, 90000, 120000 ],
2179++ "gain": [ 1.0, 1.5, 2.0, 4.0, 8.0, 12.0 ]
2180++ }
2181++ },
2182++ "constraint_modes":
2183++ {
2184++ "normal": [
2185++ {
2186++ "bound": "LOWER",
2187++ "q_lo": 0.98,
2188++ "q_hi": 1.0,
2189++ "y_target":
2190++ [
2191++ 0, 0.5,
2192++ 1000, 0.5
2193++ ]
2194++ }
2195++ ],
2196++ "highlight": [
2197++ {
2198++ "bound": "LOWER",
2199++ "q_lo": 0.98,
2200++ "q_hi": 1.0,
2201++ "y_target":
2202++ [
2203++ 0, 0.5,
2204++ 1000, 0.5
2205++ ]
2206++ },
2207++ {
2208++ "bound": "UPPER",
2209++ "q_lo": 0.98,
2210++ "q_hi": 1.0,
2211++ "y_target":
2212++ [
2213++ 0, 0.8,
2214++ 1000, 0.8
2215++ ]
2216++ }
2217++ ],
2218++ "shadows": [
2219++ {
2220++ "bound": "LOWER",
2221++ "q_lo": 0.0,
2222++ "q_hi": 0.5,
2223++ "y_target":
2224++ [
2225++ 0, 0.17,
2226++ 1000, 0.17
2227++ ]
2228++ }
2229++ ]
2230++ },
2231++ "y_target":
2232++ [
2233++ 0, 0.16,
2234++ 1000, 0.165,
2235++ 10000, 0.17
2236++ ]
2237++ },
2238++ {
2239++ "comment": "Channel 1 is the HDR short channel",
2240++ "desaturate": 0,
2241++ "metering_modes":
2242++ {
2243++ "centre-weighted":
2244++ {
2245++ "weights":
2246++ [
2247++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2248++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2249++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2250++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2251++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2252++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2253++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2254++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
2255++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2256++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2257++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2258++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2259++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2260++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2261++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
2262++ ]
2263++ },
2264++ "spot":
2265++ {
2266++ "weights":
2267++ [
2268++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2269++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2270++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2271++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2272++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2273++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2274++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2275++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
2276++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2277++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2278++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2279++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2280++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2281++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2282++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2283++ ]
2284++ },
2285++ "matrix":
2286++ {
2287++ "weights":
2288++ [
2289++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2290++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2291++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2292++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2293++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2294++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2295++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2296++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2297++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2298++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2299++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2300++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2301++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2302++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2303++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2304++ ]
2305++ }
2306++ },
2307++ "exposure_modes":
2308++ {
2309++ "normal":
2310++ {
2311++ "shutter": [ 100, 20000, 60000 ],
2312++ "gain": [ 1.0, 1.0, 1.0 ]
2313++ },
2314++ "short":
2315++ {
2316++ "shutter": [ 100, 20000, 60000 ],
2317++ "gain": [ 1.0, 1.0, 1.0 ]
2318++ },
2319++ "long":
2320++ {
2321++ "shutter": [ 100, 20000, 60000 ],
2322++ "gain": [ 1.0, 1.0, 1.0 ]
2323++ }
2324++ },
2325++ "constraint_modes":
2326++ {
2327++ "normal": [
2328++ {
2329++ "bound": "LOWER",
2330++ "q_lo": 0.95,
2331++ "q_hi": 1.0,
2332++ "y_target":
2333++ [
2334++ 0, 0.5,
2335++ 1000, 0.5
2336++ ]
2337++ },
2338++ {
2339++ "bound": "UPPER",
2340++ "q_lo": 0.95,
2341++ "q_hi": 1.0,
2342++ "y_target":
2343++ [
2344++ 0, 0.7,
2345++ 1000, 0.7
2346++ ]
2347++ },
2348++ {
2349++ "bound": "LOWER",
2350++ "q_lo": 0.0,
2351++ "q_hi": 0.2,
2352++ "y_target":
2353++ [
2354++ 0, 0.002,
2355++ 1000, 0.002
2356++ ]
2357++ }
2358++ ],
2359++ "highlight": [
2360++ {
2361++ "bound": "LOWER",
2362++ "q_lo": 0.95,
2363++ "q_hi": 1.0,
2364++ "y_target":
2365++ [
2366++ 0, 0.5,
2367++ 1000, 0.5
2368++ ]
2369++ },
2370++ {
2371++ "bound": "UPPER",
2372++ "q_lo": 0.95,
2373++ "q_hi": 1.0,
2374++ "y_target":
2375++ [
2376++ 0, 0.7,
2377++ 1000, 0.7
2378++ ]
2379++ },
2380++ {
2381++ "bound": "LOWER",
2382++ "q_lo": 0.0,
2383++ "q_hi": 0.2,
2384++ "y_target":
2385++ [
2386++ 0, 0.002,
2387++ 1000, 0.002
2388++ ]
2389++ }
2390++ ],
2391++ "shadows": [
2392++ {
2393++ "bound": "LOWER",
2394++ "q_lo": 0.95,
2395++ "q_hi": 1.0,
2396++ "y_target":
2397++ [
2398++ 0, 0.5,
2399++ 1000, 0.5
2400++ ]
2401++ },
2402++ {
2403++ "bound": "UPPER",
2404++ "q_lo": 0.95,
2405++ "q_hi": 1.0,
2406++ "y_target":
2407++ [
2408++ 0, 0.7,
2409++ 1000, 0.7
2410++ ]
2411++ },
2412++ {
2413++ "bound": "LOWER",
2414++ "q_lo": 0.0,
2415++ "q_hi": 0.2,
2416++ "y_target":
2417++ [
2418++ 0, 0.002,
2419++ 1000, 0.002
2420++ ]
2421++ }
2422++ ]
2423++ },
2424++ "y_target":
2425++ [
2426++ 0, 0.16,
2427++ 1000, 0.165,
2428++ 10000, 0.17
2429++ ]
2430++ },
2431++ {
2432++ "comment": "Channel 2 is the HDR long channel",
2433++ "desaturate": 0,
2434++ "metering_modes":
2435++ {
2436++ "centre-weighted":
2437++ {
2438++ "weights":
2439++ [
2440++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2441++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2442++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2443++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2444++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2445++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2446++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2447++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
2448++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2449++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2450++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2451++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2452++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2453++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2454++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
2455++ ]
2456++ },
2457++ "spot":
2458++ {
2459++ "weights":
2460++ [
2461++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2462++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2463++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2464++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2465++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2466++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2467++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2468++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
2469++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2470++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2471++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2472++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2473++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2474++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2475++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2476++ ]
2477++ },
2478++ "matrix":
2479++ {
2480++ "weights":
2481++ [
2482++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2483++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2484++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2485++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2486++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2487++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2488++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2489++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2490++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2491++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2492++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2493++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2494++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2495++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2496++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2497++ ]
2498++ }
2499++ },
2500++ "exposure_modes":
2501++ {
2502++ "normal":
2503++ {
2504++ "shutter": [ 100, 20000, 30000, 60000 ],
2505++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
2506++ },
2507++ "short":
2508++ {
2509++ "shutter": [ 100, 20000, 30000, 60000 ],
2510++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
2511++ },
2512++ "long":
2513++ {
2514++ "shutter": [ 100, 20000, 30000, 60000 ],
2515++ "gain": [ 1.0, 2.0, 4.0, 8.0 ]
2516++ }
2517++ },
2518++ "constraint_modes":
2519++ {
2520++ "normal": [ ],
2521++ "highlight": [ ],
2522++ "shadows": [ ]
2523++ },
2524++ "channel_constraints": [
2525++ {
2526++ "bound": "UPPER",
2527++ "channel": 4,
2528++ "factor": 8
2529++ },
2530++ {
2531++ "bound": "LOWER",
2532++ "channel": 4,
2533++ "factor": 2
2534++ }
2535++ ],
2536++ "y_target":
2537++ [
2538++ 0, 0.16,
2539++ 1000, 0.165,
2540++ 10000, 0.17
2541++ ]
2542++ },
2543++ {
2544++ "comment": "Channel 3 is the night mode channel",
2545++ "base_ev": 0.33,
2546++ "metering_modes":
2547++ {
2548++ "centre-weighted":
2549++ {
2550++ "weights":
2551++ [
2552++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2553++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2554++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2555++ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2556++ 1, 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 1, 1,
2557++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
2558++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2559++ 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1, 1,
2560++ 1, 1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1, 1,
2561++ 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 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, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
2564++ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2565++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0,
2566++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
2567++ ]
2568++ },
2569++ "spot":
2570++ {
2571++ "weights":
2572++ [
2573++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2574++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2575++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2576++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2577++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2578++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2579++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2580++ 0, 0, 0, 0, 0, 1, 2, 3, 2, 1, 0, 0, 0, 0, 0,
2581++ 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0,
2582++ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
2583++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2584++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2585++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2586++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2587++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2588++ ]
2589++ },
2590++ "matrix":
2591++ {
2592++ "weights":
2593++ [
2594++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2595++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2596++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2597++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2598++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2599++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2600++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2601++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2602++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2603++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2604++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2605++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2606++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2607++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2608++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2609++ ]
2610++ }
2611++ },
2612++ "exposure_modes":
2613++ {
2614++ "normal":
2615++ {
2616++ "shutter": [ 100, 20000, 66666 ],
2617++ "gain": [ 1.0, 2.0, 4.0 ]
2618++ },
2619++ "short":
2620++ {
2621++ "shutter": [ 100, 20000, 33333 ],
2622++ "gain": [ 1.0, 2.0, 4.0 ]
2623++ },
2624++ "long":
2625++ {
2626++ "shutter": [ 100, 20000, 66666, 120000 ],
2627++ "gain": [ 1.0, 2.0, 4.0, 4.0 ]
2628++ }
2629++ },
2630++ "constraint_modes":
2631++ {
2632++ "normal": [
2633++ {
2634++ "bound": "LOWER",
2635++ "q_lo": 0.98,
2636++ "q_hi": 1.0,
2637++ "y_target":
2638++ [
2639++ 0, 0.5,
2640++ 1000, 0.5
2641++ ]
2642++ }
2643++ ],
2644++ "highlight": [
2645++ {
2646++ "bound": "LOWER",
2647++ "q_lo": 0.98,
2648++ "q_hi": 1.0,
2649++ "y_target":
2650++ [
2651++ 0, 0.5,
2652++ 1000, 0.5
2653++ ]
2654++ },
2655++ {
2656++ "bound": "UPPER",
2657++ "q_lo": 0.98,
2658++ "q_hi": 1.0,
2659++ "y_target":
2660++ [
2661++ 0, 0.8,
2662++ 1000, 0.8
2663++ ]
2664++ }
2665++ ],
2666++ "shadows": [
2667++ {
2668++ "bound": "LOWER",
2669++ "q_lo": 0.98,
2670++ "q_hi": 1.0,
2671++ "y_target":
2672++ [
2673++ 0, 0.5,
2674++ 1000, 0.5
2675++ ]
2676++ }
2677++ ]
2678++ },
2679++ "y_target":
2680++ [
2681++ 0, 0.16,
2682++ 1000, 0.16,
2683++ 10000, 0.17
2684++ ]
2685++ }
2686++ ]
2687++ }
2688++ },
2689++ {
2690++ "rpi.alsc":
2691++ {
2692++ "omega": 1.3,
2693++ "n_iter": 100,
2694++ "luminance_strength": 0.8,
2695++ "calibrations_Cr": [
2696++ {
2697++ "ct": 2800,
2698++ "table":
2699++ [
2700++ 1.607, 1.613, 1.616, 1.619, 1.621, 1.623, 1.624, 1.623, 1.623, 1.621, 1.619, 1.618, 1.616, 1.614, 1.614, 1.613, 1.613, 1.614, 1.616, 1.616, 1.618, 1.621, 1.623, 1.626, 1.626, 1.626, 1.626, 1.625, 1.622, 1.618, 1.611, 1.605,
2701++ 1.609, 1.614, 1.616, 1.619, 1.621, 1.623, 1.623, 1.622, 1.621, 1.617, 1.613, 1.609, 1.607, 1.605, 1.603, 1.602, 1.602, 1.603, 1.605, 1.608, 1.613, 1.616, 1.621, 1.625, 1.626, 1.626, 1.626, 1.625, 1.623, 1.619, 1.612, 1.609,
2702++ 1.612, 1.615, 1.616, 1.617, 1.621, 1.622, 1.622, 1.619, 1.615, 1.609, 1.602, 1.598, 1.594, 1.591, 1.589, 1.587, 1.587, 1.589, 1.593, 1.595, 1.601, 1.607, 1.615, 1.621, 1.624, 1.626, 1.627, 1.626, 1.623, 1.621, 1.616, 1.611,
2703++ 1.612, 1.614, 1.615, 1.617, 1.619, 1.621, 1.619, 1.615, 1.608, 1.601, 1.593, 1.585, 1.581, 1.577, 1.573, 1.572, 1.572, 1.574, 1.578, 1.582, 1.588, 1.595, 1.606, 1.615, 1.621, 1.625, 1.626, 1.626, 1.624, 1.621, 1.616, 1.613,
2704++ 1.612, 1.613, 1.615, 1.617, 1.619, 1.619, 1.616, 1.608, 1.601, 1.589, 1.581, 1.572, 1.565, 1.559, 1.558, 1.556, 1.556, 1.557, 1.562, 1.568, 1.574, 1.585, 1.595, 1.606, 1.615, 1.622, 1.626, 1.626, 1.626, 1.623, 1.617, 1.614,
2705++ 1.612, 1.613, 1.615, 1.617, 1.617, 1.616, 1.611, 1.601, 1.589, 1.578, 1.566, 1.556, 1.549, 1.543, 1.539, 1.538, 1.538, 1.541, 1.546, 1.552, 1.561, 1.572, 1.585, 1.597, 1.607, 1.618, 1.624, 1.626, 1.626, 1.623, 1.617, 1.615,
2706++ 1.612, 1.613, 1.616, 1.616, 1.616, 1.612, 1.604, 1.592, 1.578, 1.566, 1.553, 1.542, 1.533, 1.527, 1.523, 1.522, 1.522, 1.524, 1.529, 1.536, 1.546, 1.561, 1.572, 1.586, 1.601, 1.611, 1.619, 1.625, 1.625, 1.624, 1.619, 1.617,
2707++ 1.612, 1.613, 1.614, 1.615, 1.614, 1.607, 1.597, 1.584, 1.567, 1.553, 1.541, 1.529, 1.518, 1.511, 1.507, 1.506, 1.506, 1.507, 1.513, 1.519, 1.531, 1.546, 1.561, 1.576, 1.591, 1.605, 1.616, 1.623, 1.625, 1.624, 1.621, 1.618,
2708++ 1.612, 1.613, 1.614, 1.614, 1.611, 1.601, 1.589, 1.573, 1.555, 1.541, 1.529, 1.513, 1.503, 1.496, 1.493, 1.489, 1.489, 1.492, 1.498, 1.506, 1.519, 1.531, 1.549, 1.566, 1.582, 1.599, 1.613, 1.621, 1.625, 1.625, 1.621, 1.619,
2709++ 1.612, 1.613, 1.614, 1.613, 1.607, 1.598, 1.583, 1.567, 1.547, 1.529, 1.513, 1.503, 1.489, 1.482, 1.478, 1.476, 1.476, 1.481, 1.485, 1.494, 1.506, 1.519, 1.537, 1.556, 1.575, 1.593, 1.608, 1.621, 1.625, 1.625, 1.622, 1.619,
2710++ 1.612, 1.614, 1.614, 1.613, 1.606, 1.594, 1.577, 1.558, 1.539, 1.519, 1.503, 1.489, 1.479, 1.471, 1.466, 1.464, 1.464, 1.467, 1.473, 1.484, 1.494, 1.509, 1.528, 1.549, 1.568, 1.588, 1.605, 1.619, 1.626, 1.626, 1.623, 1.621,
2711++ 1.614, 1.614, 1.614, 1.612, 1.602, 1.591, 1.572, 1.552, 1.532, 1.512, 1.495, 1.479, 1.471, 1.463, 1.456, 1.455, 1.455, 1.459, 1.466, 1.473, 1.485, 1.502, 1.522, 1.542, 1.562, 1.584, 1.602, 1.618, 1.626, 1.626, 1.623, 1.622,
2712++ 1.614, 1.614, 1.614, 1.611, 1.601, 1.585, 1.568, 1.547, 1.526, 1.506, 1.488, 1.473, 1.463, 1.456, 1.449, 1.447, 1.447, 1.452, 1.459, 1.467, 1.478, 1.496, 1.515, 1.537, 1.559, 1.581, 1.601, 1.617, 1.626, 1.626, 1.624, 1.623,
2713++ 1.614, 1.614, 1.614, 1.611, 1.601, 1.584, 1.564, 1.544, 1.522, 1.502, 1.484, 1.469, 1.458, 1.449, 1.446, 1.443, 1.443, 1.447, 1.452, 1.461, 1.475, 1.492, 1.511, 1.533, 1.556, 1.578, 1.599, 1.616, 1.625, 1.626, 1.625, 1.621,
2714++ 1.614, 1.614, 1.614, 1.609, 1.599, 1.583, 1.563, 1.542, 1.521, 1.499, 1.482, 1.466, 1.455, 1.447, 1.443, 1.441, 1.442, 1.443, 1.449, 1.459, 1.473, 1.489, 1.509, 1.531, 1.554, 1.577, 1.597, 1.615, 1.625, 1.626, 1.626, 1.622,
2715++ 1.615, 1.614, 1.614, 1.609, 1.599, 1.583, 1.563, 1.542, 1.519, 1.499, 1.481, 1.466, 1.454, 1.447, 1.442, 1.439, 1.439, 1.443, 1.449, 1.459, 1.472, 1.489, 1.509, 1.531, 1.554, 1.576, 1.597, 1.615, 1.625, 1.626, 1.626, 1.622,
2716++ 1.615, 1.615, 1.614, 1.609, 1.599, 1.584, 1.563, 1.542, 1.521, 1.499, 1.482, 1.466, 1.454, 1.447, 1.442, 1.441, 1.442, 1.443, 1.449, 1.459, 1.472, 1.489, 1.509, 1.532, 1.554, 1.577, 1.598, 1.615, 1.625, 1.627, 1.627, 1.624,
2717++ 1.615, 1.615, 1.614, 1.611, 1.601, 1.586, 1.565, 1.544, 1.522, 1.502, 1.483, 1.469, 1.458, 1.451, 1.447, 1.443, 1.443, 1.448, 1.453, 1.462, 1.475, 1.493, 1.513, 1.534, 1.558, 1.579, 1.601, 1.616, 1.626, 1.628, 1.628, 1.624,
2718++ 1.615, 1.616, 1.615, 1.611, 1.601, 1.588, 1.568, 1.547, 1.526, 1.506, 1.488, 1.473, 1.462, 1.456, 1.451, 1.448, 1.448, 1.453, 1.458, 1.466, 1.481, 1.497, 1.517, 1.538, 1.561, 1.582, 1.603, 1.617, 1.628, 1.628, 1.628, 1.624,
2719++ 1.615, 1.615, 1.615, 1.613, 1.605, 1.589, 1.573, 1.552, 1.531, 1.511, 1.494, 1.479, 1.469, 1.462, 1.456, 1.455, 1.455, 1.458, 1.466, 1.473, 1.486, 1.503, 1.522, 1.543, 1.564, 1.585, 1.605, 1.621, 1.629, 1.629, 1.627, 1.624,
2720++ 1.615, 1.616, 1.616, 1.614, 1.607, 1.594, 1.576, 1.557, 1.538, 1.518, 1.501, 1.487, 1.479, 1.469, 1.463, 1.462, 1.462, 1.466, 1.473, 1.483, 1.494, 1.509, 1.529, 1.549, 1.571, 1.591, 1.609, 1.621, 1.629, 1.629, 1.627, 1.624,
2721++ 1.614, 1.615, 1.616, 1.615, 1.611, 1.599, 1.582, 1.564, 1.546, 1.527, 1.511, 1.499, 1.487, 1.479, 1.475, 1.473, 1.474, 1.476, 1.483, 1.493, 1.504, 1.518, 1.538, 1.557, 1.577, 1.596, 1.612, 1.625, 1.631, 1.631, 1.627, 1.624,
2722++ 1.613, 1.615, 1.616, 1.615, 1.613, 1.604, 1.589, 1.573, 1.555, 1.538, 1.522, 1.511, 1.499, 1.492, 1.488, 1.487, 1.487, 1.489, 1.494, 1.504, 1.518, 1.529, 1.548, 1.567, 1.586, 1.604, 1.617, 1.627, 1.631, 1.631, 1.626, 1.622,
2723++ 1.612, 1.614, 1.616, 1.616, 1.615, 1.608, 1.596, 1.582, 1.566, 1.549, 1.537, 1.522, 1.514, 1.507, 1.503, 1.501, 1.501, 1.504, 1.509, 1.518, 1.529, 1.544, 1.561, 1.578, 1.594, 1.609, 1.623, 1.629, 1.631, 1.631, 1.626, 1.623,
2724++ 1.612, 1.614, 1.616, 1.618, 1.618, 1.614, 1.604, 1.592, 1.577, 1.563, 1.549, 1.537, 1.529, 1.523, 1.518, 1.518, 1.518, 1.521, 1.526, 1.533, 1.544, 1.559, 1.574, 1.591, 1.604, 1.617, 1.626, 1.632, 1.632, 1.631, 1.626, 1.623,
2725++ 1.612, 1.613, 1.617, 1.619, 1.619, 1.619, 1.612, 1.601, 1.588, 1.576, 1.563, 1.552, 1.543, 1.538, 1.536, 1.535, 1.536, 1.538, 1.542, 1.549, 1.559, 1.574, 1.588, 1.601, 1.613, 1.623, 1.631, 1.633, 1.633, 1.631, 1.626, 1.623,
2726++ 1.612, 1.613, 1.617, 1.619, 1.621, 1.621, 1.618, 1.611, 1.601, 1.588, 1.577, 1.568, 1.561, 1.555, 1.552, 1.552, 1.552, 1.556, 1.558, 1.566, 1.576, 1.588, 1.599, 1.611, 1.621, 1.628, 1.633, 1.634, 1.634, 1.631, 1.625, 1.622,
2727++ 1.611, 1.612, 1.617, 1.619, 1.622, 1.623, 1.621, 1.616, 1.609, 1.601, 1.591, 1.583, 1.577, 1.574, 1.571, 1.569, 1.569, 1.573, 1.577, 1.582, 1.591, 1.601, 1.611, 1.621, 1.628, 1.634, 1.635, 1.635, 1.634, 1.631, 1.625, 1.622,
2728++ 1.609, 1.612, 1.616, 1.618, 1.622, 1.623, 1.624, 1.622, 1.617, 1.611, 1.603, 1.597, 1.593, 1.589, 1.588, 1.587, 1.587, 1.589, 1.593, 1.598, 1.605, 1.612, 1.621, 1.628, 1.633, 1.635, 1.635, 1.635, 1.633, 1.631, 1.624, 1.622,
2729++ 1.607, 1.611, 1.615, 1.618, 1.621, 1.624, 1.624, 1.624, 1.622, 1.618, 1.613, 1.609, 1.607, 1.603, 1.603, 1.603, 1.603, 1.605, 1.608, 1.613, 1.617, 1.621, 1.628, 1.634, 1.635, 1.635, 1.635, 1.633, 1.632, 1.628, 1.623, 1.619,
2730++ 1.605, 1.609, 1.614, 1.617, 1.619, 1.624, 1.625, 1.625, 1.625, 1.624, 1.621, 1.619, 1.617, 1.617, 1.617, 1.617, 1.617, 1.618, 1.621, 1.623, 1.627, 1.629, 1.633, 1.635, 1.635, 1.634, 1.633, 1.632, 1.631, 1.625, 1.619, 1.617,
2731++ 1.602, 1.606, 1.613, 1.617, 1.619, 1.624, 1.625, 1.626, 1.627, 1.626, 1.626, 1.625, 1.625, 1.624, 1.624, 1.624, 1.625, 1.625, 1.626, 1.628, 1.631, 1.633, 1.634, 1.635, 1.634, 1.634, 1.633, 1.632, 1.631, 1.625, 1.617, 1.608
2732++ ]
2733++ },
2734++ {
2735++ "ct": 4000,
2736++ "table":
2737++ [
2738++ 2.044, 2.051, 2.055, 2.059, 2.061, 2.063, 2.064, 2.063, 2.062, 2.062, 2.058, 2.058, 2.057, 2.055, 2.054, 2.054, 2.055, 2.056, 2.057, 2.059, 2.062, 2.065, 2.068, 2.071, 2.072, 2.072, 2.072, 2.071, 2.069, 2.065, 2.055, 2.047,
2739++ 2.048, 2.051, 2.055, 2.058, 2.059, 2.061, 2.062, 2.061, 2.059, 2.053, 2.049, 2.046, 2.043, 2.042, 2.039, 2.039, 2.039, 2.041, 2.044, 2.047, 2.053, 2.059, 2.065, 2.068, 2.072, 2.072, 2.072, 2.071, 2.069, 2.064, 2.058, 2.052,
2740++ 2.049, 2.052, 2.054, 2.057, 2.059, 2.059, 2.059, 2.057, 2.052, 2.044, 2.037, 2.033, 2.029, 2.024, 2.023, 2.021, 2.021, 2.023, 2.028, 2.034, 2.038, 2.048, 2.057, 2.064, 2.068, 2.071, 2.072, 2.072, 2.069, 2.065, 2.058, 2.056,
2741++ 2.051, 2.052, 2.054, 2.057, 2.058, 2.058, 2.057, 2.052, 2.044, 2.034, 2.026, 2.018, 2.012, 2.008, 2.005, 2.004, 2.004, 2.006, 2.012, 2.017, 2.024, 2.034, 2.047, 2.056, 2.064, 2.069, 2.072, 2.072, 2.071, 2.067, 2.061, 2.057,
2742++ 2.051, 2.052, 2.054, 2.056, 2.057, 2.057, 2.052, 2.045, 2.034, 2.021, 2.011, 2.001, 1.995, 1.988, 1.986, 1.985, 1.985, 1.988, 1.994, 1.999, 2.009, 2.022, 2.033, 2.047, 2.056, 2.066, 2.071, 2.072, 2.071, 2.069, 2.062, 2.061,
2743++ 2.051, 2.051, 2.053, 2.054, 2.055, 2.053, 2.046, 2.036, 2.021, 2.008, 1.994, 1.983, 1.975, 1.969, 1.965, 1.964, 1.965, 1.968, 1.973, 1.981, 1.991, 2.006, 2.021, 2.034, 2.048, 2.061, 2.066, 2.071, 2.071, 2.069, 2.063, 2.061,
2744++ 2.051, 2.051, 2.053, 2.053, 2.053, 2.048, 2.039, 2.025, 2.008, 1.993, 1.979, 1.965, 1.956, 1.949, 1.945, 1.944, 1.945, 1.948, 1.953, 1.961, 1.973, 1.991, 2.006, 2.022, 2.036, 2.052, 2.064, 2.069, 2.069, 2.069, 2.064, 2.061,
2745++ 2.051, 2.051, 2.051, 2.052, 2.049, 2.043, 2.031, 2.014, 1.994, 1.979, 1.964, 1.949, 1.939, 1.931, 1.925, 1.924, 1.924, 1.927, 1.934, 1.943, 1.957, 1.973, 1.991, 2.009, 2.028, 2.045, 2.058, 2.067, 2.069, 2.069, 2.064, 2.062,
2746++ 2.049, 2.049, 2.049, 2.049, 2.046, 2.036, 2.021, 2.002, 1.981, 1.964, 1.949, 1.931, 1.919, 1.911, 1.907, 1.905, 1.905, 1.909, 1.915, 1.926, 1.941, 1.957, 1.977, 1.997, 2.018, 2.037, 2.053, 2.064, 2.069, 2.069, 2.064, 2.062,
2747++ 2.049, 2.049, 2.049, 2.049, 2.041, 2.029, 2.011, 1.992, 1.969, 1.949, 1.931, 1.918, 1.904, 1.894, 1.889, 1.888, 1.888, 1.892, 1.898, 1.909, 1.926, 1.941, 1.962, 1.984, 2.008, 2.031, 2.048, 2.062, 2.069, 2.069, 2.066, 2.064,
2748++ 2.049, 2.051, 2.049, 2.049, 2.041, 2.024, 2.005, 1.984, 1.961, 1.938, 1.918, 1.904, 1.891, 1.879, 1.874, 1.873, 1.873, 1.877, 1.884, 1.898, 1.909, 1.929, 1.951, 1.973, 1.999, 2.025, 2.044, 2.062, 2.069, 2.069, 2.066, 2.064,
2749++ 2.051, 2.051, 2.051, 2.046, 2.035, 2.021, 1.999, 1.976, 1.952, 1.928, 1.908, 1.891, 1.879, 1.869, 1.862, 1.861, 1.861, 1.865, 1.875, 1.884, 1.899, 1.919, 1.943, 1.966, 1.992, 2.018, 2.039, 2.059, 2.069, 2.069, 2.067, 2.065,
2750++ 2.051, 2.051, 2.049, 2.046, 2.035, 2.017, 1.995, 1.969, 1.946, 1.921, 1.901, 1.881, 1.869, 1.861, 1.852, 1.851, 1.851, 1.856, 1.865, 1.875, 1.892, 1.911, 1.936, 1.961, 1.988, 2.014, 2.037, 2.057, 2.068, 2.069, 2.067, 2.066,
2751++ 2.051, 2.051, 2.049, 2.045, 2.034, 2.015, 1.992, 1.968, 1.941, 1.916, 1.895, 1.876, 1.862, 1.852, 1.849, 1.845, 1.845, 1.849, 1.856, 1.869, 1.886, 1.907, 1.931, 1.956, 1.984, 2.011, 2.037, 2.056, 2.068, 2.069, 2.068, 2.067,
2752++ 2.052, 2.051, 2.049, 2.044, 2.033, 2.013, 1.991, 1.964, 1.937, 1.915, 1.892, 1.873, 1.859, 1.849, 1.845, 1.841, 1.843, 1.844, 1.853, 1.865, 1.883, 1.906, 1.928, 1.954, 1.981, 2.009, 2.035, 2.055, 2.067, 2.068, 2.068, 2.068,
2753++ 2.051, 2.051, 2.049, 2.044, 2.032, 2.013, 1.991, 1.964, 1.937, 1.914, 1.891, 1.873, 1.858, 1.849, 1.842, 1.839, 1.839, 1.844, 1.853, 1.865, 1.883, 1.904, 1.928, 1.953, 1.981, 2.008, 2.034, 2.054, 2.067, 2.069, 2.069, 2.068,
2754++ 2.053, 2.052, 2.051, 2.045, 2.032, 2.015, 1.991, 1.965, 1.938, 1.914, 1.891, 1.874, 1.859, 1.849, 1.844, 1.841, 1.843, 1.845, 1.853, 1.866, 1.883, 1.904, 1.929, 1.954, 1.981, 2.009, 2.034, 2.055, 2.068, 2.069, 2.069, 2.068,
2755++ 2.053, 2.053, 2.051, 2.045, 2.035, 2.016, 1.993, 1.967, 1.942, 1.918, 1.894, 1.878, 1.863, 1.854, 1.849, 1.844, 1.845, 1.851, 1.857, 1.869, 1.885, 1.907, 1.932, 1.957, 1.985, 2.012, 2.037, 2.055, 2.069, 2.071, 2.069, 2.067,
2756++ 2.054, 2.053, 2.052, 2.047, 2.036, 2.019, 1.995, 1.972, 1.947, 1.922, 1.899, 1.882, 1.869, 1.861, 1.854, 1.851, 1.851, 1.857, 1.864, 1.873, 1.892, 1.913, 1.936, 1.962, 1.989, 2.014, 2.039, 2.058, 2.071, 2.071, 2.069, 2.067,
2757++ 2.053, 2.053, 2.053, 2.049, 2.039, 2.022, 2.002, 1.977, 1.951, 1.928, 1.907, 1.891, 1.877, 1.868, 1.861, 1.859, 1.859, 1.864, 1.873, 1.882, 1.899, 1.919, 1.943, 1.967, 1.994, 2.018, 2.043, 2.061, 2.072, 2.072, 2.069, 2.067,
2758++ 2.053, 2.054, 2.053, 2.051, 2.045, 2.027, 2.008, 1.984, 1.959, 1.937, 1.917, 1.901, 1.889, 1.877, 1.869, 1.869, 1.869, 1.873, 1.882, 1.894, 1.909, 1.928, 1.951, 1.975, 2.001, 2.025, 2.046, 2.063, 2.072, 2.072, 2.069, 2.068,
2759++ 2.053, 2.054, 2.055, 2.052, 2.047, 2.034, 2.014, 1.993, 1.971, 1.948, 1.929, 1.914, 1.901, 1.889, 1.885, 1.882, 1.883, 1.886, 1.894, 1.908, 1.921, 1.939, 1.961, 1.984, 2.007, 2.029, 2.051, 2.066, 2.072, 2.072, 2.068, 2.068,
2760++ 2.052, 2.054, 2.054, 2.054, 2.051, 2.039, 2.023, 2.002, 1.982, 1.962, 1.944, 1.929, 1.914, 1.906, 1.901, 1.899, 1.899, 1.903, 1.909, 1.921, 1.936, 1.951, 1.973, 1.995, 2.018, 2.038, 2.057, 2.068, 2.072, 2.072, 2.068, 2.065,
2761++ 2.051, 2.054, 2.055, 2.056, 2.054, 2.047, 2.031, 2.012, 1.994, 1.975, 1.959, 1.944, 1.932, 1.923, 1.918, 1.917, 1.917, 1.921, 1.927, 1.936, 1.951, 1.968, 1.988, 2.009, 2.028, 2.047, 2.061, 2.071, 2.073, 2.072, 2.067, 2.064,
2762++ 2.052, 2.054, 2.055, 2.057, 2.057, 2.053, 2.039, 2.027, 2.007, 1.991, 1.975, 1.959, 1.951, 1.943, 1.938, 1.938, 1.938, 1.939, 1.944, 1.955, 1.968, 1.987, 2.003, 2.022, 2.038, 2.056, 2.066, 2.072, 2.075, 2.073, 2.068, 2.067,
2763++ 2.052, 2.053, 2.057, 2.059, 2.059, 2.058, 2.051, 2.037, 2.021, 2.007, 1.991, 1.978, 1.968, 1.962, 1.958, 1.958, 1.959, 1.961, 1.966, 1.974, 1.987, 2.003, 2.019, 2.036, 2.051, 2.063, 2.071, 2.075, 2.075, 2.073, 2.068, 2.068,
2764++ 2.052, 2.053, 2.057, 2.061, 2.062, 2.062, 2.057, 2.049, 2.036, 2.021, 2.009, 1.998, 1.988, 1.983, 1.978, 1.978, 1.978, 1.981, 1.986, 1.994, 2.006, 2.019, 2.035, 2.049, 2.061, 2.069, 2.075, 2.077, 2.077, 2.074, 2.069, 2.067,
2765++ 2.051, 2.053, 2.057, 2.061, 2.063, 2.064, 2.063, 2.056, 2.048, 2.036, 2.026, 2.016, 2.008, 2.005, 2.001, 1.999, 2.001, 2.003, 2.007, 2.013, 2.025, 2.035, 2.048, 2.061, 2.068, 2.075, 2.079, 2.078, 2.077, 2.074, 2.069, 2.067,
2766++ 2.049, 2.053, 2.057, 2.059, 2.064, 2.065, 2.065, 2.063, 2.056, 2.048, 2.041, 2.033, 2.028, 2.023, 2.021, 2.021, 2.021, 2.023, 2.028, 2.033, 2.042, 2.049, 2.061, 2.069, 2.074, 2.078, 2.079, 2.079, 2.077, 2.073, 2.068, 2.064,
2767++ 2.046, 2.052, 2.054, 2.059, 2.063, 2.065, 2.066, 2.066, 2.064, 2.057, 2.051, 2.047, 2.045, 2.039, 2.039, 2.038, 2.039, 2.041, 2.045, 2.049, 2.055, 2.061, 2.071, 2.074, 2.077, 2.078, 2.078, 2.077, 2.075, 2.071, 2.065, 2.061,
2768++ 2.045, 2.051, 2.054, 2.059, 2.062, 2.065, 2.067, 2.068, 2.067, 2.065, 2.061, 2.058, 2.057, 2.056, 2.056, 2.056, 2.057, 2.058, 2.059, 2.062, 2.067, 2.071, 2.075, 2.077, 2.078, 2.077, 2.077, 2.076, 2.074, 2.068, 2.061, 2.056,
2769++ 2.043, 2.049, 2.056, 2.058, 2.061, 2.067, 2.068, 2.069, 2.069, 2.069, 2.068, 2.068, 2.065, 2.065, 2.065, 2.066, 2.067, 2.068, 2.068, 2.069, 2.073, 2.074, 2.077, 2.078, 2.078, 2.076, 2.076, 2.075, 2.071, 2.067, 2.057, 2.051
2770++ ]
2771++ }
2772++ ],
2773++ "calibrations_Cb": [
2774++ {
2775++ "ct": 2800,
2776++ "table":
2777++ [
2778++ 2.896, 2.894, 2.882, 2.876, 2.871, 2.863, 2.857, 2.855, 2.852, 2.852, 2.852, 2.852, 2.855, 2.857, 2.859, 2.863, 2.863, 2.862, 2.859, 2.859, 2.861, 2.863, 2.863, 2.864, 2.867, 2.869, 2.875, 2.879, 2.892, 2.897, 2.899, 2.904,
2779++ 2.888, 2.883, 2.877, 2.874, 2.865, 2.859, 2.852, 2.848, 2.846, 2.845, 2.845, 2.848, 2.849, 2.849, 2.851, 2.852, 2.854, 2.853, 2.852, 2.852, 2.852, 2.852, 2.851, 2.853, 2.857, 2.865, 2.873, 2.876, 2.882, 2.883, 2.897, 2.901,
2780++ 2.881, 2.878, 2.875, 2.867, 2.859, 2.853, 2.848, 2.846, 2.844, 2.844, 2.845, 2.847, 2.849, 2.849, 2.851, 2.851, 2.852, 2.852, 2.852, 2.851, 2.849, 2.849, 2.849, 2.851, 2.854, 2.857, 2.865, 2.873, 2.877, 2.881, 2.885, 2.892,
2781++ 2.881, 2.877, 2.873, 2.867, 2.859, 2.852, 2.849, 2.847, 2.846, 2.847, 2.848, 2.849, 2.851, 2.851, 2.852, 2.853, 2.854, 2.854, 2.854, 2.853, 2.852, 2.851, 2.851, 2.851, 2.851, 2.856, 2.861, 2.869, 2.875, 2.879, 2.885, 2.891,
2782++ 2.877, 2.874, 2.871, 2.867, 2.861, 2.856, 2.851, 2.848, 2.847, 2.848, 2.849, 2.851, 2.852, 2.853, 2.855, 2.856, 2.856, 2.856, 2.855, 2.854, 2.851, 2.849, 2.849, 2.851, 2.851, 2.853, 2.858, 2.864, 2.872, 2.875, 2.881, 2.888,
2783++ 2.873, 2.872, 2.871, 2.867, 2.861, 2.857, 2.853, 2.851, 2.849, 2.851, 2.851, 2.852, 2.854, 2.856, 2.857, 2.858, 2.858, 2.858, 2.857, 2.855, 2.854, 2.851, 2.849, 2.849, 2.851, 2.852, 2.855, 2.863, 2.869, 2.873, 2.877, 2.888,
2784++ 2.872, 2.872, 2.871, 2.868, 2.862, 2.858, 2.854, 2.853, 2.852, 2.853, 2.854, 2.857, 2.859, 2.859, 2.862, 2.863, 2.863, 2.862, 2.861, 2.857, 2.854, 2.853, 2.852, 2.851, 2.851, 2.851, 2.853, 2.859, 2.866, 2.872, 2.875, 2.885,
2785++ 2.872, 2.872, 2.871, 2.867, 2.861, 2.858, 2.855, 2.854, 2.854, 2.855, 2.857, 2.861, 2.862, 2.863, 2.866, 2.868, 2.869, 2.868, 2.865, 2.862, 2.857, 2.855, 2.855, 2.852, 2.851, 2.851, 2.853, 2.856, 2.862, 2.869, 2.876, 2.882,
2786++ 2.872, 2.872, 2.869, 2.865, 2.861, 2.859, 2.857, 2.856, 2.855, 2.858, 2.861, 2.862, 2.865, 2.868, 2.871, 2.873, 2.872, 2.871, 2.869, 2.865, 2.861, 2.858, 2.856, 2.854, 2.853, 2.852, 2.853, 2.856, 2.861, 2.869, 2.872, 2.879,
2787++ 2.874, 2.872, 2.869, 2.865, 2.863, 2.861, 2.859, 2.858, 2.859, 2.859, 2.862, 2.865, 2.868, 2.873, 2.877, 2.879, 2.879, 2.877, 2.873, 2.871, 2.865, 2.859, 2.857, 2.854, 2.854, 2.853, 2.855, 2.856, 2.861, 2.868, 2.872, 2.879,
2788++ 2.874, 2.873, 2.871, 2.866, 2.864, 2.863, 2.862, 2.862, 2.862, 2.863, 2.866, 2.868, 2.875, 2.882, 2.885, 2.886, 2.886, 2.884, 2.881, 2.873, 2.871, 2.864, 2.858, 2.856, 2.855, 2.855, 2.856, 2.857, 2.861, 2.868, 2.871, 2.879,
2789++ 2.874, 2.874, 2.872, 2.867, 2.865, 2.864, 2.864, 2.864, 2.865, 2.866, 2.868, 2.875, 2.882, 2.891, 2.897, 2.897, 2.896, 2.894, 2.888, 2.882, 2.873, 2.867, 2.862, 2.857, 2.857, 2.857, 2.857, 2.858, 2.862, 2.866, 2.871, 2.878,
2790++ 2.874, 2.874, 2.872, 2.869, 2.867, 2.865, 2.865, 2.865, 2.868, 2.868, 2.874, 2.882, 2.891, 2.899, 2.906, 2.907, 2.906, 2.903, 2.895, 2.888, 2.877, 2.868, 2.864, 2.862, 2.858, 2.858, 2.858, 2.859, 2.861, 2.867, 2.871, 2.877,
2791++ 2.875, 2.874, 2.871, 2.869, 2.868, 2.868, 2.868, 2.869, 2.869, 2.872, 2.878, 2.885, 2.899, 2.907, 2.912, 2.914, 2.914, 2.907, 2.903, 2.893, 2.879, 2.869, 2.866, 2.862, 2.859, 2.859, 2.859, 2.859, 2.861, 2.864, 2.868, 2.877,
2792++ 2.876, 2.874, 2.872, 2.869, 2.869, 2.869, 2.869, 2.869, 2.871, 2.875, 2.881, 2.894, 2.902, 2.912, 2.917, 2.919, 2.917, 2.914, 2.906, 2.894, 2.882, 2.874, 2.866, 2.863, 2.861, 2.859, 2.858, 2.859, 2.859, 2.863, 2.867, 2.876,
2793++ 2.873, 2.873, 2.869, 2.871, 2.869, 2.869, 2.869, 2.871, 2.872, 2.877, 2.884, 2.894, 2.902, 2.912, 2.921, 2.921, 2.919, 2.917, 2.907, 2.895, 2.882, 2.874, 2.868, 2.862, 2.859, 2.857, 2.857, 2.858, 2.859, 2.862, 2.866, 2.872,
2794++ 2.872, 2.872, 2.871, 2.871, 2.869, 2.869, 2.869, 2.871, 2.873, 2.878, 2.885, 2.894, 2.905, 2.914, 2.921, 2.922, 2.921, 2.917, 2.907, 2.896, 2.884, 2.874, 2.867, 2.863, 2.861, 2.859, 2.858, 2.858, 2.859, 2.863, 2.867, 2.871,
2795++ 2.871, 2.872, 2.871, 2.869, 2.868, 2.869, 2.869, 2.871, 2.875, 2.878, 2.884, 2.893, 2.905, 2.915, 2.919, 2.921, 2.919, 2.916, 2.907, 2.895, 2.884, 2.873, 2.868, 2.864, 2.862, 2.859, 2.858, 2.858, 2.861, 2.863, 2.866, 2.871,
2796++ 2.872, 2.872, 2.871, 2.869, 2.868, 2.868, 2.871, 2.873, 2.875, 2.877, 2.884, 2.893, 2.905, 2.909, 2.916, 2.919, 2.916, 2.911, 2.904, 2.894, 2.884, 2.873, 2.867, 2.864, 2.861, 2.859, 2.859, 2.858, 2.861, 2.863, 2.866, 2.873,
2797++ 2.873, 2.872, 2.871, 2.869, 2.867, 2.868, 2.869, 2.872, 2.873, 2.876, 2.882, 2.889, 2.899, 2.905, 2.909, 2.911, 2.911, 2.904, 2.899, 2.891, 2.881, 2.869, 2.865, 2.864, 2.861, 2.858, 2.858, 2.858, 2.861, 2.863, 2.865, 2.875,
2798++ 2.876, 2.874, 2.871, 2.869, 2.869, 2.869, 2.869, 2.869, 2.872, 2.873, 2.879, 2.886, 2.894, 2.899, 2.903, 2.903, 2.903, 2.899, 2.893, 2.883, 2.875, 2.869, 2.864, 2.862, 2.859, 2.858, 2.857, 2.857, 2.861, 2.863, 2.866, 2.875,
2799++ 2.876, 2.876, 2.873, 2.871, 2.869, 2.868, 2.868, 2.869, 2.869, 2.872, 2.875, 2.881, 2.887, 2.894, 2.895, 2.898, 2.898, 2.893, 2.887, 2.877, 2.872, 2.865, 2.862, 2.861, 2.859, 2.858, 2.857, 2.859, 2.862, 2.864, 2.868, 2.875,
2800++ 2.876, 2.877, 2.875, 2.871, 2.869, 2.867, 2.866, 2.866, 2.869, 2.871, 2.874, 2.878, 2.883, 2.887, 2.891, 2.891, 2.891, 2.887, 2.881, 2.874, 2.867, 2.863, 2.861, 2.859, 2.859, 2.858, 2.858, 2.861, 2.864, 2.866, 2.869, 2.875,
2801++ 2.876, 2.877, 2.875, 2.871, 2.868, 2.866, 2.864, 2.865, 2.867, 2.869, 2.872, 2.875, 2.879, 2.882, 2.885, 2.885, 2.883, 2.882, 2.878, 2.873, 2.865, 2.861, 2.859, 2.858, 2.857, 2.858, 2.859, 2.862, 2.866, 2.868, 2.875, 2.879,
2802++ 2.878, 2.878, 2.876, 2.871, 2.868, 2.864, 2.863, 2.863, 2.865, 2.867, 2.869, 2.872, 2.874, 2.879, 2.881, 2.881, 2.881, 2.878, 2.874, 2.868, 2.863, 2.859, 2.858, 2.858, 2.857, 2.859, 2.861, 2.864, 2.869, 2.874, 2.879, 2.883,
2803++ 2.879, 2.879, 2.876, 2.871, 2.865, 2.863, 2.863, 2.863, 2.862, 2.863, 2.867, 2.869, 2.871, 2.873, 2.874, 2.875, 2.875, 2.874, 2.871, 2.864, 2.862, 2.859, 2.858, 2.857, 2.857, 2.859, 2.863, 2.868, 2.874, 2.878, 2.881, 2.886,
2804++ 2.881, 2.881, 2.879, 2.871, 2.866, 2.863, 2.862, 2.861, 2.859, 2.861, 2.864, 2.868, 2.868, 2.869, 2.871, 2.871, 2.871, 2.871, 2.866, 2.863, 2.862, 2.859, 2.857, 2.858, 2.858, 2.859, 2.865, 2.872, 2.877, 2.879, 2.883, 2.887,
2805++ 2.881, 2.882, 2.879, 2.875, 2.869, 2.865, 2.862, 2.861, 2.859, 2.862, 2.863, 2.866, 2.868, 2.869, 2.871, 2.869, 2.869, 2.867, 2.866, 2.864, 2.863, 2.861, 2.858, 2.859, 2.858, 2.864, 2.867, 2.874, 2.879, 2.883, 2.887, 2.889,
2806++ 2.881, 2.883, 2.881, 2.881, 2.871, 2.868, 2.865, 2.862, 2.861, 2.863, 2.864, 2.867, 2.868, 2.869, 2.871, 2.871, 2.869, 2.868, 2.868, 2.867, 2.865, 2.863, 2.862, 2.863, 2.866, 2.867, 2.872, 2.876, 2.881, 2.886, 2.891, 2.897,
2807++ 2.885, 2.886, 2.884, 2.882, 2.874, 2.869, 2.866, 2.863, 2.861, 2.861, 2.862, 2.865, 2.866, 2.867, 2.871, 2.871, 2.868, 2.867, 2.867, 2.867, 2.865, 2.863, 2.862, 2.865, 2.867, 2.867, 2.872, 2.877, 2.881, 2.886, 2.891, 2.898,
2808++ 2.886, 2.889, 2.887, 2.882, 2.874, 2.869, 2.866, 2.863, 2.862, 2.861, 2.861, 2.862, 2.861, 2.862, 2.863, 2.863, 2.863, 2.862, 2.861, 2.861, 2.862, 2.862, 2.863, 2.863, 2.864, 2.867, 2.872, 2.876, 2.881, 2.884, 2.889, 2.898,
2809++ 2.907, 2.892, 2.889, 2.876, 2.874, 2.869, 2.865, 2.863, 2.861, 2.859, 2.861, 2.861, 2.861, 2.859, 2.861, 2.862, 2.862, 2.861, 2.859, 2.861, 2.861, 2.862, 2.862, 2.863, 2.863, 2.864, 2.868, 2.874, 2.879, 2.883, 2.888, 2.899
2810++ ]
2811++ },
2812++ {
2813++ "ct": 4000,
2814++ "table":
2815++ [
2816++ 1.929, 1.927, 1.922, 1.919, 1.916, 1.914, 1.911, 1.909, 1.908, 1.908, 1.909, 1.909, 1.911, 1.911, 1.912, 1.913, 1.914, 1.913, 1.912, 1.912, 1.911, 1.911, 1.912, 1.912, 1.912, 1.913, 1.915, 1.916, 1.922, 1.923, 1.927, 1.928,
2817++ 1.925, 1.923, 1.919, 1.917, 1.914, 1.911, 1.909, 1.908, 1.906, 1.907, 1.908, 1.909, 1.911, 1.911, 1.911, 1.912, 1.913, 1.912, 1.911, 1.911, 1.911, 1.909, 1.909, 1.909, 1.909, 1.911, 1.914, 1.915, 1.919, 1.919, 1.922, 1.924,
2818++ 1.921, 1.919, 1.918, 1.914, 1.912, 1.909, 1.908, 1.907, 1.906, 1.907, 1.908, 1.909, 1.911, 1.911, 1.911, 1.912, 1.912, 1.911, 1.911, 1.911, 1.909, 1.908, 1.908, 1.908, 1.909, 1.909, 1.912, 1.915, 1.917, 1.918, 1.921, 1.921,
2819++ 1.921, 1.919, 1.917, 1.914, 1.913, 1.909, 1.909, 1.908, 1.908, 1.909, 1.911, 1.912, 1.913, 1.913, 1.914, 1.914, 1.913, 1.913, 1.912, 1.912, 1.911, 1.909, 1.909, 1.909, 1.908, 1.909, 1.911, 1.914, 1.916, 1.918, 1.919, 1.921,
2820++ 1.918, 1.918, 1.917, 1.914, 1.913, 1.911, 1.909, 1.909, 1.909, 1.911, 1.912, 1.913, 1.914, 1.915, 1.916, 1.916, 1.916, 1.915, 1.914, 1.914, 1.912, 1.911, 1.909, 1.908, 1.908, 1.908, 1.909, 1.912, 1.915, 1.916, 1.917, 1.918,
2821++ 1.917, 1.917, 1.916, 1.915, 1.913, 1.912, 1.911, 1.911, 1.912, 1.913, 1.913, 1.914, 1.916, 1.917, 1.917, 1.917, 1.918, 1.918, 1.916, 1.915, 1.914, 1.912, 1.911, 1.909, 1.908, 1.908, 1.909, 1.911, 1.913, 1.915, 1.916, 1.917,
2822++ 1.916, 1.916, 1.916, 1.915, 1.914, 1.913, 1.913, 1.913, 1.913, 1.915, 1.917, 1.918, 1.919, 1.919, 1.921, 1.921, 1.921, 1.921, 1.919, 1.918, 1.915, 1.914, 1.912, 1.909, 1.908, 1.908, 1.908, 1.909, 1.913, 1.914, 1.915, 1.916,
2823++ 1.915, 1.916, 1.916, 1.915, 1.914, 1.914, 1.913, 1.914, 1.915, 1.918, 1.919, 1.922, 1.922, 1.924, 1.925, 1.925, 1.925, 1.924, 1.923, 1.921, 1.918, 1.915, 1.914, 1.911, 1.909, 1.908, 1.908, 1.909, 1.912, 1.913, 1.915, 1.915,
2824++ 1.915, 1.915, 1.915, 1.915, 1.914, 1.914, 1.915, 1.915, 1.917, 1.919, 1.922, 1.923, 1.924, 1.927, 1.928, 1.929, 1.929, 1.927, 1.925, 1.923, 1.921, 1.918, 1.915, 1.913, 1.911, 1.909, 1.908, 1.909, 1.912, 1.913, 1.914, 1.916,
2825++ 1.915, 1.915, 1.915, 1.916, 1.915, 1.915, 1.916, 1.917, 1.919, 1.922, 1.923, 1.925, 1.928, 1.929, 1.932, 1.933, 1.933, 1.932, 1.929, 1.926, 1.922, 1.919, 1.916, 1.914, 1.912, 1.911, 1.911, 1.911, 1.912, 1.913, 1.915, 1.917,
2826++ 1.916, 1.916, 1.916, 1.916, 1.916, 1.917, 1.918, 1.919, 1.921, 1.923, 1.925, 1.928, 1.933, 1.935, 1.937, 1.939, 1.939, 1.936, 1.934, 1.929, 1.926, 1.921, 1.917, 1.915, 1.913, 1.912, 1.911, 1.911, 1.913, 1.913, 1.914, 1.915,
2827++ 1.916, 1.917, 1.917, 1.917, 1.917, 1.918, 1.919, 1.921, 1.923, 1.925, 1.927, 1.933, 1.935, 1.941, 1.943, 1.944, 1.944, 1.941, 1.938, 1.934, 1.929, 1.924, 1.921, 1.916, 1.915, 1.913, 1.911, 1.911, 1.912, 1.914, 1.914, 1.914,
2828++ 1.917, 1.917, 1.917, 1.917, 1.917, 1.919, 1.921, 1.922, 1.925, 1.927, 1.931, 1.935, 1.941, 1.945, 1.949, 1.949, 1.949, 1.946, 1.941, 1.938, 1.931, 1.925, 1.921, 1.917, 1.916, 1.915, 1.913, 1.912, 1.912, 1.913, 1.913, 1.914,
2829++ 1.916, 1.917, 1.917, 1.917, 1.917, 1.919, 1.921, 1.923, 1.925, 1.928, 1.931, 1.938, 1.945, 1.949, 1.953, 1.954, 1.954, 1.949, 1.946, 1.941, 1.932, 1.926, 1.922, 1.919, 1.916, 1.915, 1.914, 1.912, 1.912, 1.912, 1.913, 1.914,
2830++ 1.915, 1.917, 1.917, 1.918, 1.919, 1.921, 1.922, 1.924, 1.926, 1.929, 1.934, 1.941, 1.946, 1.952, 1.955, 1.956, 1.955, 1.953, 1.947, 1.941, 1.933, 1.928, 1.922, 1.919, 1.916, 1.915, 1.913, 1.912, 1.912, 1.911, 1.913, 1.914,
2831++ 1.915, 1.916, 1.917, 1.919, 1.919, 1.921, 1.922, 1.924, 1.926, 1.931, 1.935, 1.941, 1.947, 1.952, 1.956, 1.956, 1.956, 1.953, 1.948, 1.941, 1.933, 1.928, 1.923, 1.919, 1.916, 1.914, 1.913, 1.911, 1.911, 1.911, 1.912, 1.914,
2832++ 1.915, 1.916, 1.917, 1.918, 1.919, 1.921, 1.922, 1.924, 1.927, 1.931, 1.935, 1.941, 1.947, 1.952, 1.956, 1.956, 1.956, 1.953, 1.948, 1.941, 1.933, 1.927, 1.922, 1.919, 1.917, 1.915, 1.913, 1.912, 1.911, 1.912, 1.912, 1.914,
2833++ 1.915, 1.915, 1.916, 1.917, 1.919, 1.921, 1.922, 1.925, 1.928, 1.931, 1.935, 1.941, 1.947, 1.952, 1.955, 1.956, 1.954, 1.951, 1.947, 1.941, 1.933, 1.927, 1.923, 1.919, 1.917, 1.914, 1.913, 1.911, 1.911, 1.912, 1.913, 1.913,
2834++ 1.915, 1.915, 1.916, 1.917, 1.918, 1.919, 1.922, 1.925, 1.928, 1.931, 1.935, 1.941, 1.946, 1.949, 1.953, 1.954, 1.951, 1.948, 1.945, 1.941, 1.933, 1.927, 1.923, 1.918, 1.917, 1.914, 1.912, 1.911, 1.911, 1.912, 1.913, 1.913,
2835++ 1.915, 1.916, 1.916, 1.917, 1.917, 1.919, 1.921, 1.924, 1.926, 1.929, 1.933, 1.938, 1.944, 1.946, 1.949, 1.949, 1.948, 1.946, 1.942, 1.937, 1.931, 1.924, 1.921, 1.918, 1.917, 1.913, 1.912, 1.911, 1.911, 1.911, 1.912, 1.912,
2836++ 1.915, 1.916, 1.916, 1.917, 1.917, 1.919, 1.921, 1.922, 1.924, 1.927, 1.931, 1.936, 1.938, 1.944, 1.944, 1.944, 1.944, 1.942, 1.938, 1.933, 1.926, 1.923, 1.919, 1.918, 1.915, 1.912, 1.911, 1.911, 1.911, 1.911, 1.912, 1.912,
2837++ 1.915, 1.916, 1.916, 1.917, 1.917, 1.919, 1.919, 1.921, 1.922, 1.926, 1.929, 1.931, 1.936, 1.938, 1.939, 1.941, 1.941, 1.938, 1.933, 1.929, 1.924, 1.921, 1.918, 1.916, 1.914, 1.912, 1.912, 1.911, 1.911, 1.911, 1.913, 1.913,
2838++ 1.915, 1.916, 1.917, 1.917, 1.916, 1.917, 1.918, 1.919, 1.921, 1.924, 1.927, 1.929, 1.932, 1.934, 1.936, 1.936, 1.935, 1.933, 1.929, 1.927, 1.922, 1.918, 1.916, 1.914, 1.913, 1.912, 1.912, 1.911, 1.912, 1.913, 1.914, 1.914,
2839++ 1.916, 1.917, 1.917, 1.917, 1.916, 1.915, 1.916, 1.918, 1.919, 1.922, 1.924, 1.927, 1.929, 1.931, 1.933, 1.933, 1.932, 1.929, 1.928, 1.925, 1.919, 1.917, 1.914, 1.913, 1.912, 1.912, 1.912, 1.912, 1.914, 1.914, 1.916, 1.916,
2840++ 1.916, 1.917, 1.917, 1.917, 1.915, 1.914, 1.915, 1.916, 1.917, 1.919, 1.921, 1.924, 1.926, 1.928, 1.929, 1.929, 1.929, 1.928, 1.925, 1.922, 1.919, 1.917, 1.914, 1.913, 1.912, 1.912, 1.912, 1.913, 1.915, 1.916, 1.917, 1.918,
2841++ 1.917, 1.917, 1.917, 1.916, 1.914, 1.913, 1.914, 1.914, 1.916, 1.917, 1.919, 1.921, 1.922, 1.924, 1.925, 1.926, 1.926, 1.925, 1.923, 1.919, 1.918, 1.915, 1.913, 1.913, 1.911, 1.911, 1.912, 1.915, 1.917, 1.917, 1.919, 1.921,
2842++ 1.917, 1.917, 1.917, 1.916, 1.914, 1.913, 1.913, 1.913, 1.913, 1.914, 1.917, 1.919, 1.921, 1.922, 1.922, 1.922, 1.922, 1.921, 1.919, 1.918, 1.916, 1.914, 1.913, 1.913, 1.912, 1.912, 1.914, 1.916, 1.917, 1.918, 1.921, 1.921,
2843++ 1.917, 1.918, 1.918, 1.917, 1.915, 1.913, 1.913, 1.912, 1.913, 1.913, 1.916, 1.918, 1.921, 1.921, 1.921, 1.921, 1.921, 1.919, 1.919, 1.918, 1.915, 1.914, 1.913, 1.913, 1.912, 1.914, 1.915, 1.917, 1.919, 1.921, 1.921, 1.923,
2844++ 1.917, 1.918, 1.919, 1.919, 1.917, 1.914, 1.914, 1.912, 1.913, 1.913, 1.915, 1.918, 1.919, 1.919, 1.921, 1.921, 1.919, 1.919, 1.919, 1.918, 1.916, 1.915, 1.914, 1.914, 1.914, 1.915, 1.917, 1.918, 1.919, 1.922, 1.923, 1.925,
2845++ 1.918, 1.921, 1.919, 1.919, 1.915, 1.914, 1.912, 1.911, 1.912, 1.913, 1.913, 1.915, 1.917, 1.918, 1.918, 1.919, 1.919, 1.918, 1.918, 1.918, 1.915, 1.915, 1.914, 1.914, 1.914, 1.915, 1.916, 1.918, 1.919, 1.921, 1.924, 1.926,
2846++ 1.921, 1.921, 1.919, 1.918, 1.914, 1.913, 1.911, 1.911, 1.911, 1.911, 1.911, 1.912, 1.912, 1.913, 1.913, 1.914, 1.914, 1.913, 1.912, 1.913, 1.913, 1.913, 1.913, 1.913, 1.912, 1.913, 1.915, 1.917, 1.918, 1.919, 1.923, 1.927,
2847++ 1.933, 1.924, 1.919, 1.914, 1.913, 1.913, 1.911, 1.909, 1.909, 1.909, 1.911, 1.911, 1.911, 1.911, 1.912, 1.912, 1.912, 1.911, 1.911, 1.911, 1.911, 1.911, 1.911, 1.911, 1.911, 1.912, 1.913, 1.916, 1.918, 1.919, 1.921, 1.927
2848++ ]
2849++ }
2850++ ],
2851++ "luminance_lut":
2852++ [
2853++ 3.676, 3.541, 3.263, 3.031, 2.824, 2.635, 2.471, 2.327, 2.204, 2.101, 2.018, 1.949, 1.913, 1.891, 1.879, 1.879, 1.879, 1.882, 1.898, 1.928, 1.979, 2.058, 2.149, 2.256, 2.389, 2.537, 2.712, 2.909, 3.124, 3.372, 3.676, 3.786,
2854++ 3.541, 3.353, 3.095, 2.871, 2.663, 2.481, 2.333, 2.219, 2.106, 2.018, 1.945, 1.882, 1.831, 1.793, 1.769, 1.762, 1.762, 1.777, 1.809, 1.854, 1.912, 1.979, 2.058, 2.155, 2.271, 2.391, 2.553, 2.745, 2.961, 3.196, 3.478, 3.676,
2855++ 3.364, 3.207, 2.959, 2.736, 2.535, 2.359, 2.219, 2.106, 2.018, 1.923, 1.846, 1.779, 1.726, 1.686, 1.661, 1.653, 1.653, 1.671, 1.702, 1.749, 1.809, 1.881, 1.964, 2.058, 2.155, 2.278, 2.429, 2.614, 2.828, 3.061, 3.324, 3.478,
2856++ 3.238, 3.078, 2.838, 2.614, 2.418, 2.259, 2.129, 2.021, 1.923, 1.834, 1.748, 1.678, 1.623, 1.584, 1.559, 1.549, 1.549, 1.567, 1.598, 1.646, 1.709, 1.783, 1.879, 1.964, 2.066, 2.183, 2.323, 2.494, 2.703, 2.933, 3.189, 3.333,
2857++ 3.132, 2.966, 2.725, 2.506, 2.319, 2.171, 2.048, 1.937, 1.834, 1.748, 1.654, 1.583, 1.528, 1.488, 1.463, 1.455, 1.455, 1.473, 1.505, 1.551, 1.613, 1.694, 1.783, 1.879, 1.986, 2.102, 2.232, 2.391, 2.589, 2.819, 3.072, 3.219,
2858++ 3.038, 2.863, 2.622, 2.411, 2.236, 2.095, 1.972, 1.858, 1.749, 1.654, 1.572, 1.495, 1.439, 1.402, 1.378, 1.371, 1.371, 1.388, 1.419, 1.465, 1.527, 1.613, 1.694, 1.798, 1.908, 2.027, 2.155, 2.303, 2.489, 2.714, 2.968, 3.119,
2859++ 2.951, 2.767, 2.531, 2.326, 2.163, 2.027, 1.901, 1.782, 1.671, 1.572, 1.495, 1.417, 1.363, 1.327, 1.303, 1.296, 1.296, 1.312, 1.342, 1.388, 1.452, 1.527, 1.616, 1.721, 1.835, 1.958, 2.086, 2.228, 2.402, 2.621, 2.872, 3.033,
2860++ 2.876, 2.683, 2.451, 2.255, 2.101, 1.965, 1.836, 1.712, 1.599, 1.499, 1.417, 1.354, 1.296, 1.259, 1.236, 1.231, 1.231, 1.246, 1.275, 1.319, 1.388, 1.452, 1.542, 1.649, 1.768, 1.895, 2.026, 2.165, 2.331, 2.538, 2.783, 2.956,
2861++ 2.809, 2.611, 2.383, 2.197, 2.044, 1.908, 1.777, 1.649, 1.536, 1.436, 1.354, 1.296, 1.237, 1.201, 1.179, 1.173, 1.173, 1.189, 1.218, 1.268, 1.319, 1.391, 1.479, 1.585, 1.706, 1.837, 1.971, 2.112, 2.269, 2.466, 2.707, 2.888,
2862++ 2.753, 2.546, 2.323, 2.147, 1.998, 1.858, 1.723, 1.596, 1.482, 1.384, 1.302, 1.237, 1.195, 1.153, 1.131, 1.124, 1.124, 1.141, 1.171, 1.218, 1.268, 1.339, 1.427, 1.531, 1.651, 1.784, 1.923, 2.065, 2.219, 2.406, 2.643, 2.829,
2863++ 2.705, 2.491, 2.276, 2.105, 1.956, 1.814, 1.677, 1.549, 1.436, 1.339, 1.259, 1.195, 1.153, 1.113, 1.091, 1.084, 1.084, 1.101, 1.137, 1.171, 1.226, 1.295, 1.381, 1.484, 1.604, 1.738, 1.882, 2.025, 2.176, 2.361, 2.587, 2.783,
2864++ 2.669, 2.446, 2.239, 2.072, 1.923, 1.777, 1.638, 1.511, 1.397, 1.303, 1.224, 1.162, 1.113, 1.086, 1.057, 1.052, 1.052, 1.069, 1.101, 1.137, 1.193, 1.261, 1.345, 1.448, 1.567, 1.701, 1.846, 1.992, 2.145, 2.323, 2.545, 2.747,
2865++ 2.642, 2.412, 2.209, 2.045, 1.895, 1.749, 1.608, 1.479, 1.369, 1.275, 1.197, 1.134, 1.086, 1.057, 1.034, 1.027, 1.027, 1.051, 1.069, 1.111, 1.166, 1.233, 1.318, 1.419, 1.537, 1.671, 1.816, 1.966, 2.119, 2.291, 2.509, 2.719,
2866++ 2.626, 2.389, 2.191, 2.026, 1.876, 1.727, 1.585, 1.457, 1.348, 1.254, 1.178, 1.116, 1.067, 1.034, 1.024, 1.012, 1.014, 1.027, 1.051, 1.092, 1.146, 1.214, 1.298, 1.398, 1.516, 1.651, 1.794, 1.945, 2.099, 2.271, 2.486, 2.703,
2867++ 2.619, 2.374, 2.177, 2.016, 1.864, 1.714, 1.572, 1.445, 1.335, 1.243, 1.166, 1.104, 1.056, 1.024, 1.011, 1.003, 1.009, 1.014, 1.039, 1.081, 1.135, 1.202, 1.286, 1.385, 1.502, 1.637, 1.783, 1.933, 2.088, 2.259, 2.469, 2.697,
2868++ 2.619, 2.372, 2.175, 2.013, 1.861, 1.711, 1.569, 1.442, 1.333, 1.241, 1.164, 1.102, 1.054, 1.021, 1.004, 1.001, 1.001, 1.011, 1.038, 1.079, 1.134, 1.202, 1.283, 1.383, 1.501, 1.633, 1.779, 1.931, 2.085, 2.256, 2.465, 2.697,
2869++ 2.619, 2.372, 2.175, 2.013, 1.861, 1.711, 1.569, 1.442, 1.333, 1.241, 1.164, 1.102, 1.054, 1.021, 1.004, 1.002, 1.002, 1.011, 1.038, 1.081, 1.135, 1.202, 1.283, 1.383, 1.501, 1.633, 1.779, 1.931, 2.085, 2.256, 2.465, 2.697,
2870++ 2.623, 2.385, 2.187, 2.022, 1.871, 1.722, 1.579, 1.452, 1.342, 1.251, 1.173, 1.111, 1.064, 1.031, 1.017, 1.005, 1.011, 1.021, 1.048, 1.089, 1.144, 1.211, 1.293, 1.394, 1.511, 1.644, 1.789, 1.941, 2.094, 2.265, 2.477, 2.699,
2871++ 2.636, 2.409, 2.207, 2.039, 1.888, 1.741, 1.601, 1.472, 1.361, 1.268, 1.191, 1.129, 1.081, 1.051, 1.031, 1.021, 1.021, 1.045, 1.064, 1.106, 1.161, 1.227, 1.311, 1.412, 1.529, 1.664, 1.808, 1.957, 2.109, 2.282, 2.499, 2.714,
2872++ 2.664, 2.441, 2.233, 2.066, 1.914, 1.769, 1.628, 1.499, 1.389, 1.294, 1.216, 1.153, 1.106, 1.081, 1.051, 1.045, 1.045, 1.064, 1.092, 1.131, 1.186, 1.254, 1.338, 1.441, 1.559, 1.693, 1.836, 1.985, 2.138, 2.313, 2.534, 2.739,
2873++ 2.697, 2.477, 2.265, 2.094, 1.943, 1.801, 1.662, 1.535, 1.422, 1.326, 1.247, 1.185, 1.141, 1.106, 1.081, 1.075, 1.075, 1.092, 1.129, 1.161, 1.217, 1.286, 1.371, 1.474, 1.594, 1.728, 1.869, 2.015, 2.168, 2.348, 2.573, 2.775,
2874++ 2.739, 2.528, 2.308, 2.133, 1.982, 1.842, 1.705, 1.579, 1.465, 1.368, 1.287, 1.224, 1.185, 1.141, 1.119, 1.114, 1.114, 1.129, 1.161, 1.205, 1.256, 1.327, 1.413, 1.519, 1.639, 1.772, 1.911, 2.054, 2.209, 2.394, 2.628, 2.818,
2875++ 2.793, 2.587, 2.361, 2.179, 2.028, 1.889, 1.757, 1.631, 1.517, 1.419, 1.337, 1.277, 1.224, 1.187, 1.165, 1.159, 1.159, 1.175, 1.205, 1.256, 1.304, 1.377, 1.465, 1.571, 1.691, 1.823, 1.959, 2.099, 2.258, 2.451, 2.693, 2.876,
2876++ 2.856, 2.661, 2.428, 2.239, 2.082, 1.946, 1.817, 1.693, 1.579, 1.479, 1.396, 1.337, 1.277, 1.241, 1.219, 1.214, 1.214, 1.231, 1.259, 1.304, 1.368, 1.436, 1.526, 1.634, 1.753, 1.883, 2.015, 2.154, 2.318, 2.523, 2.772, 2.943,
2877++ 2.931, 2.745, 2.505, 2.305, 2.144, 2.008, 1.882, 1.761, 1.648, 1.549, 1.471, 1.396, 1.342, 1.303, 1.281, 1.275, 1.275, 1.293, 1.323, 1.368, 1.436, 1.506, 1.595, 1.702, 1.821, 1.946, 2.075, 2.215, 2.388, 2.603, 2.857, 3.023,
2878++ 3.013, 2.842, 2.599, 2.387, 2.215, 2.076, 1.952, 1.836, 1.726, 1.627, 1.549, 1.471, 1.416, 1.377, 1.353, 1.347, 1.347, 1.365, 1.397, 1.444, 1.506, 1.593, 1.674, 1.779, 1.893, 2.014, 2.142, 2.289, 2.472, 2.696, 2.955, 3.108,
2879++ 3.107, 2.945, 2.699, 2.481, 2.296, 2.151, 2.027, 1.915, 1.808, 1.719, 1.627, 1.555, 1.501, 1.461, 1.435, 1.429, 1.429, 1.447, 1.479, 1.529, 1.593, 1.674, 1.761, 1.862, 1.971, 2.088, 2.219, 2.374, 2.568, 2.805, 3.064, 3.211,
2880++ 3.218, 3.058, 2.814, 2.589, 2.392, 2.235, 2.108, 1.997, 1.897, 1.808, 1.719, 1.649, 1.593, 1.553, 1.527, 1.521, 1.521, 1.539, 1.572, 1.622, 1.686, 1.761, 1.858, 1.947, 2.051, 2.168, 2.304, 2.474, 2.682, 2.923, 3.183, 3.327,
2881++ 3.342, 3.187, 2.939, 2.712, 2.506, 2.337, 2.198, 2.085, 1.995, 1.897, 1.818, 1.751, 1.695, 1.654, 1.629, 1.621, 1.621, 1.641, 1.674, 1.723, 1.786, 1.858, 1.947, 2.039, 2.139, 2.259, 2.408, 2.593, 2.807, 3.053, 3.319, 3.475,
2882++ 3.495, 3.329, 3.071, 2.845, 2.634, 2.455, 2.303, 2.185, 2.085, 1.995, 1.919, 1.855, 1.801, 1.763, 1.738, 1.731, 1.731, 1.749, 1.781, 1.828, 1.888, 1.959, 2.039, 2.139, 2.238, 2.367, 2.531, 2.728, 2.949, 3.195, 3.475, 3.658,
2883++ 3.669, 3.495, 3.218, 2.987, 2.776, 2.588, 2.426, 2.294, 2.185, 2.097, 2.024, 1.961, 1.911, 1.875, 1.851, 1.844, 1.844, 1.862, 1.893, 1.937, 1.995, 2.063, 2.142, 2.238, 2.352, 2.497, 2.675, 2.877, 3.101, 3.356, 3.658, 3.843,
2884++ 3.837, 3.669, 3.367, 3.123, 2.912, 2.721, 2.552, 2.407, 2.291, 2.185, 2.097, 2.024, 1.975, 1.954, 1.944, 1.944, 1.944, 1.946, 1.965, 1.995, 2.063, 2.142, 2.236, 2.345, 2.471, 2.628, 2.812, 3.018, 3.248, 3.517, 3.843, 3.988
2885++ ],
2886++ "sigma": 0.00072,
2887++ "sigma_Cb": 0.00079
2888++ }
2889++ },
2890++ {
2891++ "rpi.contrast":
2892++ {
2893++ "ce_enable": 1,
2894++ "gamma_curve":
2895++ [
2896++ 0, 0,
2897++ 1024, 5040,
2898++ 2048, 9338,
2899++ 3072, 12356,
2900++ 4096, 15312,
2901++ 5120, 18051,
2902++ 6144, 20790,
2903++ 7168, 23193,
2904++ 8192, 25744,
2905++ 9216, 27942,
2906++ 10240, 30035,
2907++ 11264, 32005,
2908++ 12288, 33975,
2909++ 13312, 35815,
2910++ 14336, 37600,
2911++ 15360, 39168,
2912++ 16384, 40642,
2913++ 18432, 43379,
2914++ 20480, 45749,
2915++ 22528, 47753,
2916++ 24576, 49621,
2917++ 26624, 51253,
2918++ 28672, 52698,
2919++ 30720, 53796,
2920++ 32768, 54876,
2921++ 36864, 57012,
2922++ 40960, 58656,
2923++ 45056, 59954,
2924++ 49152, 61183,
2925++ 53248, 62355,
2926++ 57344, 63419,
2927++ 61440, 64476,
2928++ 65535, 65535
2929++ ]
2930++ }
2931++ },
2932++ {
2933++ "rpi.ccm":
2934++ {
2935++ "ccms": [
2936++ {
2937++ "ct": 2800,
2938++ "ccm":
2939++ [
2940++ 1.60099, -0.27615, -0.32485,
2941++ -0.36173, 1.73154, -0.36981,
2942++ 0.05061, -1.11212, 2.06152
2943++ ]
2944++ },
2945++ {
2946++ "ct": 2860,
2947++ "ccm":
2948++ [
2949++ 1.61273, -0.35631, -0.25641,
2950++ -0.49273, 1.98065, -0.48793,
2951++ -0.03047, -0.69949, 1.72997
2952++ ]
2953++ },
2954++ {
2955++ "ct": 2880,
2956++ "ccm":
2957++ [
2958++ 1.60615, -0.34009, -0.26606,
2959++ -0.48642, 1.98548, -0.49906,
2960++ -0.02324, -0.73793, 1.76117
2961++ ]
2962++ },
2963++ {
2964++ "ct": 3580,
2965++ "ccm":
2966++ [
2967++ 1.68146, -0.47435, -0.20711,
2968++ -0.42387, 1.87351, -0.44963,
2969++ -0.03582, -0.59119, 1.62701
2970++ ]
2971++ },
2972++ {
2973++ "ct": 3650,
2974++ "ccm":
2975++ [
2976++ 1.66879, -0.45734, -0.21146,
2977++ -0.42285, 1.86266, -0.43981,
2978++ -0.04212, -0.55689, 1.59902
2979++ ]
2980++ },
2981++ {
2982++ "ct": 4500,
2983++ "ccm":
2984++ [
2985++ 1.58737, -0.34781, -0.23956,
2986++ -0.38604, 1.97168, -0.58564,
2987++ -0.05469, -0.50253, 1.55722
2988++ ]
2989++ },
2990++ {
2991++ "ct": 4570,
2992++ "ccm":
2993++ [
2994++ 1.61538, -0.38095, -0.23443,
2995++ -0.38067, 1.96743, -0.58675,
2996++ -0.05282, -0.52277, 1.57559
2997++ ]
2998++ },
2999++ {
3000++ "ct": 5648,
3001++ "ccm":
3002++ [
3003++ 1.76567, -0.60063, -0.16504,
3004++ -0.33153, 1.81445, -0.48292,
3005++ -0.06404, -0.43593, 1.49997
3006++ ]
3007++ },
3008++ {
3009++ "ct": 5717,
3010++ "ccm":
3011++ [
3012++ 1.75403, -0.58859, -0.16543,
3013++ -0.32727, 1.80986, -0.48259,
3014++ -0.06479, -0.43555, 1.50035
3015++ ]
3016++ },
3017++ {
3018++ "ct": 7600,
3019++ "ccm":
3020++ [
3021++ 1.71011, -0.33715, -0.37296,
3022++ -0.31253, 2.25037, -0.93784,
3023++ -0.08325, -0.71623, 1.79948
3024++ ]
3025++ }
3026++ ]
3027++ }
3028++ },
3029++ {
3030++ "rpi.cac": { }
3031++ },
3032++ {
3033++ "rpi.sharpen":
3034++ {
3035++ "threshold": 0.25,
3036++ "limit": 1.0,
3037++ "strength": 1.0
3038++ }
3039++ },
3040++ {
3041++ "rpi.hdr":
3042++ {
3043++ "Off":
3044++ {
3045++ "cadence": [ 0 ]
3046++ },
3047++ "MultiExposureUnmerged":
3048++ {
3049++ "cadence": [ 1, 2 ],
3050++ "channel_map":
3051++ {
3052++ "short": 1,
3053++ "long": 2
3054++ }
3055++ },
3056++ "SingleExposure":
3057++ {
3058++ "cadence": [ 1 ],
3059++ "channel_map":
3060++ {
3061++ "short": 1
3062++ },
3063++ "spatial_gain": 2.0,
3064++ "tonemap_enable": 1
3065++ },
3066++ "MultiExposure":
3067++ {
3068++ "cadence": [ 1, 2 ],
3069++ "channel_map":
3070++ {
3071++ "short": 1,
3072++ "long": 2
3073++ },
3074++ "stitch_enable": 1,
3075++ "spatial_gain": 2.0,
3076++ "tonemap_enable": 1
3077++ },
3078++ "Night":
3079++ {
3080++ "cadence": [ 3 ],
3081++ "channel_map":
3082++ {
3083++ "night": 3
3084++ },
3085++ "tonemap_enable": 1,
3086++ "tonemap":
3087++ [
3088++ 0, 0,
3089++ 5000, 20000,
3090++ 10000, 30000,
3091++ 20000, 47000,
3092++ 30000, 55000,
3093++ 65535, 65535
3094++ ]
3095++ }
3096++ }
3097++ },
3098++ {
3099++ "rpi.sync":
3100++ {
3101++ }
3102++ }
3103++ ]
3104++}
3105+\ No newline at end of file
3106+--- a/src/ipa/rpi/pisp/data/imx519.json 2025-05-08 00:06:16.067331148 +0530
3107++++ b/src/ipa/rpi/pisp/data/imx519.json 2025-05-08 00:06:16.054331350 +0530
3108+@@ -629,6 +629,11 @@
3109+ },
3110+ {
3111+ "rpi.sharpen": { }
3112++ },
3113++ {
3114++ "rpi.sync":
3115++ {
3116++ }
3117+ }
3118+ ]
3119+ }
3120+\ No newline at end of file
3121+--- a/src/ipa/rpi/pisp/data/ov9281_mono.json 2025-05-08 00:06:16.067331148 +0530
3122++++ b/src/ipa/rpi/pisp/data/ov9281_mono.json 2025-05-08 00:06:16.054331350 +0530
3123+@@ -210,6 +210,11 @@
3124+ 65535, 65535
3125+ ]
3126+ }
3127++ },
3128++ {
3129++ "rpi.sync":
3130++ {
3131++ }
3132+ }
3133+ ]
3134+ }
3135+\ No newline at end of file
3136+--- a/src/ipa/rpi/pisp/data/se327m12.json 2025-05-08 00:06:16.067331148 +0530
3137++++ b/src/ipa/rpi/pisp/data/se327m12.json 2025-05-08 00:06:16.054331350 +0530
3138+@@ -634,6 +634,11 @@
3139+ "strength": 0.5,
3140+ "limit": 0.5
3141+ }
3142++ },
3143++ {
3144++ "rpi.sync":
3145++ {
3146++ }
3147+ }
3148+ ]
3149+ }
3150+\ No newline at end of file
3151+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3152++++ b/src/ipa/rpi/cam_helper/cam_helper_imx500.cpp 2025-05-08 00:06:16.054331350 +0530
3153+@@ -0,0 +1,330 @@
3154++/* SPDX-License-Identifier: BSD-2-Clause */
3155++/*
3156++ * Copyright (C) 2024, Raspberry Pi Ltd
3157++ *
3158++ * cam_helper_imx500.cpp - camera helper for imx500 sensor
3159++ */
3160++
3161++#include <algorithm>
3162++#include <assert.h>
3163++#include <cmath>
3164++#include <fstream>
3165++#include <memory>
3166++#include <stddef.h>
3167++#include <stdio.h>
3168++#include <stdlib.h>
3169++#include <string.h>
3170++
3171++#include <libcamera/base/log.h>
3172++#include <libcamera/base/span.h>
3173++
3174++#include <libcamera/control_ids.h>
3175++
3176++#include "imx500_tensor_parser/imx500_tensor_parser.h"
3177++
3178++#include "cam_helper.h"
3179++#include "md_parser.h"
3180++
3181++using namespace RPiController;
3182++using namespace libcamera;
3183++using libcamera::utils::Duration;
3184++
3185++namespace libcamera {
3186++LOG_DECLARE_CATEGORY(IPARPI)
3187++}
3188++
3189++/*
3190++ * We care about two gain registers and a pair of exposure registers. Their
3191++ * I2C addresses from the Sony IMX500 datasheet:
3192++ */
3193++constexpr uint32_t expHiReg = 0x0202;
3194++constexpr uint32_t expLoReg = 0x0203;
3195++constexpr uint32_t gainHiReg = 0x0204;
3196++constexpr uint32_t gainLoReg = 0x0205;
3197++constexpr uint32_t frameLengthHiReg = 0x0340;
3198++constexpr uint32_t frameLengthLoReg = 0x0341;
3199++constexpr uint32_t lineLengthHiReg = 0x0342;
3200++constexpr uint32_t lineLengthLoReg = 0x0343;
3201++constexpr uint32_t temperatureReg = 0x013a;
3202++constexpr std::initializer_list<uint32_t> registerList = { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg,
3203++ lineLengthHiReg, lineLengthLoReg, temperatureReg };
3204++
3205++class CamHelperImx500 : public CamHelper
3206++{
3207++public:
3208++ CamHelperImx500();
3209++ uint32_t gainCode(double gain) const override;
3210++ double gain(uint32_t gainCode) const override;
3211++ void prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override;
3212++ std::pair<uint32_t, uint32_t> getBlanking(Duration &exposure, Duration minFrameDuration,
3213++ Duration maxFrameDuration) const override;
3214++ bool sensorEmbeddedDataPresent() const override;
3215++
3216++private:
3217++ /*
3218++ * Smallest difference between the frame length and integration time,
3219++ * in units of lines.
3220++ */
3221++ static constexpr int frameIntegrationDiff = 22;
3222++ /* Maximum frame length allowable for long exposure calculations. */
3223++ static constexpr int frameLengthMax = 0xffdc;
3224++ /* Largest long exposure scale factor given as a left shift on the frame length. */
3225++ static constexpr int longExposureShiftMax = 7;
3226++
3227++ void parseInferenceData(libcamera::Span<const uint8_t> buffer, Metadata &metadata);
3228++ void populateMetadata(const MdParser::RegisterMap &registers,
3229++ Metadata &metadata) const override;
3230++
3231++ std::unique_ptr<uint8_t[]> savedInputTensor_;
3232++};
3233++
3234++CamHelperImx500::CamHelperImx500()
3235++ : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff)
3236++{
3237++}
3238++
3239++uint32_t CamHelperImx500::gainCode(double gain) const
3240++{
3241++ return static_cast<uint32_t>(1024 - 1024 / gain);
3242++}
3243++
3244++double CamHelperImx500::gain(uint32_t gainCode) const
3245++{
3246++ return 1024.0 / (1024 - gainCode);
3247++}
3248++
3249++void CamHelperImx500::prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata)
3250++{
3251++ MdParser::RegisterMap registers;
3252++ DeviceStatus deviceStatus;
3253++
3254++ if (metadata.get("device.status", deviceStatus)) {
3255++ LOG(IPARPI, Error) << "DeviceStatus not found from DelayedControls";
3256++ return;
3257++ }
3258++
3259++ parseEmbeddedData(buffer, metadata);
3260++
3261++ /*
3262++ * The DeviceStatus struct is first populated with values obtained from
3263++ * DelayedControls. If this reports frame length is > frameLengthMax,
3264++ * it means we are using a long exposure mode. Since the long exposure
3265++ * scale factor is not returned back through embedded data, we must rely
3266++ * on the existing exposure lines and frame length values returned by
3267++ * DelayedControls.
3268++ *
3269++ * Otherwise, all values are updated with what is reported in the
3270++ * embedded data.
3271++ */
3272++ if (deviceStatus.frameLength > frameLengthMax) {
3273++ DeviceStatus parsedDeviceStatus;
3274++
3275++ metadata.get("device.status", parsedDeviceStatus);
3276++ parsedDeviceStatus.exposureTime = deviceStatus.exposureTime;
3277++ parsedDeviceStatus.frameLength = deviceStatus.frameLength;
3278++ metadata.set("device.status", parsedDeviceStatus);
3279++
3280++ LOG(IPARPI, Debug) << "Metadata updated for long exposure: "
3281++ << parsedDeviceStatus;
3282++ }
3283++
3284++ parseInferenceData(buffer, metadata);
3285++}
3286++
3287++std::pair<uint32_t, uint32_t> CamHelperImx500::getBlanking(Duration &exposure,
3288++ Duration minFrameDuration,
3289++ Duration maxFrameDuration) const
3290++{
3291++ uint32_t frameLength, exposureLines;
3292++ unsigned int shift = 0;
3293++
3294++ auto [vblank, hblank] = CamHelper::getBlanking(exposure, minFrameDuration,
3295++ maxFrameDuration);
3296++
3297++ frameLength = mode_.height + vblank;
3298++ Duration lineLength = hblankToLineLength(hblank);
3299++
3300++ /*
3301++ * Check if the frame length calculated needs to be setup for long
3302++ * exposure mode. This will require us to use a long exposure scale
3303++ * factor provided by a shift operation in the sensor.
3304++ */
3305++ while (frameLength > frameLengthMax) {
3306++ if (++shift > longExposureShiftMax) {
3307++ shift = longExposureShiftMax;
3308++ frameLength = frameLengthMax;
3309++ break;
3310++ }
3311++ frameLength >>= 1;
3312++ }
3313++
3314++ if (shift) {
3315++ /* Account for any rounding in the scaled frame length value. */
3316++ frameLength <<= shift;
3317++ exposureLines = CamHelperImx500::exposureLines(exposure, lineLength);
3318++ exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff);
3319++ exposure = CamHelperImx500::exposure(exposureLines, lineLength);
3320++ }
3321++
3322++ return { frameLength - mode_.height, hblank };
3323++}
3324++
3325++bool CamHelperImx500::sensorEmbeddedDataPresent() const
3326++{
3327++ return true;
3328++}
3329++
3330++void CamHelperImx500::parseInferenceData(libcamera::Span<const uint8_t> buffer,
3331++ Metadata &metadata)
3332++{
3333++ /* Inference data comes after 2 lines of embedded data. */
3334++ constexpr unsigned int StartLine = 2;
3335++ size_t bytesPerLine = (mode_.width * mode_.bitdepth) >> 3;
3336++ if (hwConfig_.dataBufferStrided)
3337++ bytesPerLine = (bytesPerLine + 15) & ~15;
3338++
3339++ if (buffer.size() <= StartLine * bytesPerLine)
3340++ return;
3341++
3342++ /* Check if an input tensor is needed - this is sticky! */
3343++ bool enableInputTensor = false;
3344++ metadata.get("cnn.enable_input_tensor", enableInputTensor);
3345++
3346++ /* Cache the DNN metadata for fast parsing. */
3347++ unsigned int tensorBufferSize = buffer.size() - (StartLine * bytesPerLine);
3348++ std::unique_ptr<uint8_t[]> cache = std::make_unique<uint8_t[]>(tensorBufferSize);
3349++ memcpy(cache.get(), buffer.data() + StartLine * bytesPerLine, tensorBufferSize);
3350++ Span<const uint8_t> tensors(cache.get(), tensorBufferSize);
3351++
3352++ std::unordered_map<TensorType, IMX500Tensors> offsets = RPiController::imx500SplitTensors(tensors);
3353++ auto itIn = offsets.find(TensorType::InputTensor);
3354++ auto itOut = offsets.find(TensorType::OutputTensor);
3355++
3356++ if (itIn != offsets.end() && itOut != offsets.end()) {
3357++ const unsigned int inputTensorOffset = itIn->second.offset;
3358++ const unsigned int outputTensorOffset = itOut->second.offset;
3359++ const unsigned int inputTensorSize = outputTensorOffset - inputTensorOffset;
3360++ Span<const uint8_t> inputTensor;
3361++
3362++ if (itIn->second.valid) {
3363++ if (itOut->second.valid) {
3364++ /* Valid input and output tensor, get the span directly from the current cache. */
3365++ inputTensor = Span<const uint8_t>(cache.get() + inputTensorOffset,
3366++ inputTensorSize);
3367++ } else {
3368++ /*
3369++ * Invalid output tensor with valid input tensor.
3370++ * This is likely because the DNN takes longer than
3371++ * a frame time to generate the output tensor.
3372++ *
3373++ * In such cases, we don't process the input tensor,
3374++ * but simply save it for when the next output
3375++ * tensor is valid. This way, we ensure that both
3376++ * valid input and output tensors are in lock-step.
3377++ */
3378++ savedInputTensor_ = std::make_unique<uint8_t[]>(inputTensorSize);
3379++ memcpy(savedInputTensor_.get(), cache.get() + inputTensorOffset,
3380++ inputTensorSize);
3381++ }
3382++ } else if (itOut->second.valid && savedInputTensor_) {
3383++ /*
3384++ * Invalid input tensor with valid output tensor. This is
3385++ * likely because the DNN takes longer than a frame time
3386++ * to generate the output tensor.
3387++ *
3388++ * In such cases, use the previously saved input tensor
3389++ * if possible.
3390++ */
3391++ inputTensor = Span<const uint8_t>(savedInputTensor_.get(), inputTensorSize);
3392++ }
3393++
3394++ if (inputTensor.size()) {
3395++ IMX500InputTensorInfo inputTensorInfo;
3396++ if (!imx500ParseInputTensor(inputTensorInfo, inputTensor)) {
3397++ CnnInputTensorInfo exported{};
3398++ exported.width = inputTensorInfo.width;
3399++ exported.height = inputTensorInfo.height;
3400++ exported.numChannels = inputTensorInfo.channels;
3401++ strncpy(exported.networkName, inputTensorInfo.networkName.c_str(),
3402++ sizeof(exported.networkName));
3403++ exported.networkName[sizeof(exported.networkName) - 1] = '\0';
3404++ metadata.set("cnn.input_tensor_info", exported);
3405++ metadata.set("cnn.input_tensor", std::move(inputTensorInfo.data));
3406++ metadata.set("cnn.input_tensor_size", inputTensorInfo.size);
3407++ }
3408++
3409++ /* We can now safely clear the saved input tensor. */
3410++ savedInputTensor_.reset();
3411++ }
3412++ }
3413++
3414++ if (itOut != offsets.end() && itOut->second.valid) {
3415++ unsigned int outputTensorOffset = itOut->second.offset;
3416++ Span<const uint8_t> outputTensor(cache.get() + outputTensorOffset,
3417++ tensorBufferSize - outputTensorOffset);
3418++
3419++ IMX500OutputTensorInfo outputTensorInfo;
3420++ if (!imx500ParseOutputTensor(outputTensorInfo, outputTensor)) {
3421++ CnnOutputTensorInfo exported{};
3422++ if (outputTensorInfo.numTensors < MaxNumTensors) {
3423++ exported.numTensors = outputTensorInfo.numTensors;
3424++ for (unsigned int i = 0; i < exported.numTensors; i++) {
3425++ exported.info[i].tensorDataNum = outputTensorInfo.tensorDataNum[i];
3426++ exported.info[i].numDimensions = outputTensorInfo.numDimensions[i];
3427++ for (unsigned int j = 0; j < exported.info[i].numDimensions; j++)
3428++ exported.info[i].size[j] = outputTensorInfo.vecDim[i][j].size;
3429++ }
3430++ } else {
3431++ LOG(IPARPI, Debug)
3432++ << "IMX500 output tensor info export failed, numTensors > MaxNumTensors";
3433++ }
3434++ strncpy(exported.networkName, outputTensorInfo.networkName.c_str(),
3435++ sizeof(exported.networkName));
3436++ exported.networkName[sizeof(exported.networkName) - 1] = '\0';
3437++ metadata.set("cnn.output_tensor_info", exported);
3438++ metadata.set("cnn.output_tensor", std::move(outputTensorInfo.data));
3439++ metadata.set("cnn.output_tensor_size", outputTensorInfo.totalSize);
3440++
3441++ auto itKpi = offsets.find(TensorType::Kpi);
3442++ if (itKpi != offsets.end()) {
3443++ constexpr unsigned int DnnRuntimeOffset = 9;
3444++ constexpr unsigned int DspRuntimeOffset = 10;
3445++ CnnKpiInfo kpi;
3446++
3447++ uint8_t *k = cache.get() + itKpi->second.offset;
3448++ kpi.dnnRuntime = k[4 * DnnRuntimeOffset + 3] << 24 |
3449++ k[4 * DnnRuntimeOffset + 2] << 16 |
3450++ k[4 * DnnRuntimeOffset + 1] << 8 |
3451++ k[4 * DnnRuntimeOffset];
3452++ kpi.dspRuntime = k[4 * DspRuntimeOffset + 3] << 24 |
3453++ k[4 * DspRuntimeOffset + 2] << 16 |
3454++ k[4 * DspRuntimeOffset + 1] << 8 |
3455++ k[4 * DspRuntimeOffset];
3456++ metadata.set("cnn.kpi_info", kpi);
3457++ }
3458++ }
3459++ }
3460++}
3461++
3462++void CamHelperImx500::populateMetadata(const MdParser::RegisterMap &registers,
3463++ Metadata &metadata) const
3464++{
3465++ DeviceStatus deviceStatus;
3466++
3467++ deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 +
3468++ registers.at(lineLengthLoReg));
3469++ deviceStatus.exposureTime = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
3470++ deviceStatus.lineLength);
3471++ deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
3472++ deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
3473++ deviceStatus.sensorTemperature = std::clamp<int8_t>(registers.at(temperatureReg), -20, 80);
3474++
3475++ metadata.set("device.status", deviceStatus);
3476++}
3477++
3478++static CamHelper *create()
3479++{
3480++ return new CamHelperImx500();
3481++}
3482++
3483++static RegisterCamHelper reg_imx500("imx500", &create);
3484+\ No newline at end of file
3485+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3486++++ b/src/ipa/rpi/cam_helper/imx500_tensor_parser/apParams.flatbuffers_generated.h 2025-05-08 00:06:16.055331334 +0530
3487+@@ -0,0 +1,544 @@
3488++// automatically generated by the FlatBuffers compiler, do not modify
3489++
3490++
3491++#ifndef FLATBUFFERS_GENERATED_APPARAMSFLATBUFFERS_APPARAMS_FB_H_
3492++#define FLATBUFFERS_GENERATED_APPARAMSFLATBUFFERS_APPARAMS_FB_H_
3493++
3494++#include "flatbuffers/flatbuffers.h"
3495++
3496++namespace apParams {
3497++namespace fb {
3498++
3499++struct FBDimension;
3500++
3501++struct FBInputTensor;
3502++
3503++struct FBOutputTensor;
3504++
3505++struct FBNetwork;
3506++
3507++struct FBApParams;
3508++
3509++struct FBDimension FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
3510++ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
3511++ VT_ID = 4,
3512++ VT_SIZE = 6,
3513++ VT_SERIALIZATIONINDEX = 8,
3514++ VT_PADDING = 10
3515++ };
3516++ uint8_t id() const {
3517++ return GetField<uint8_t>(VT_ID, 0);
3518++ }
3519++ uint16_t size() const {
3520++ return GetField<uint16_t>(VT_SIZE, 0);
3521++ }
3522++ uint8_t serializationIndex() const {
3523++ return GetField<uint8_t>(VT_SERIALIZATIONINDEX, 0);
3524++ }
3525++ uint8_t padding() const {
3526++ return GetField<uint8_t>(VT_PADDING, 0);
3527++ }
3528++ bool Verify(flatbuffers::Verifier &verifier) const {
3529++ return VerifyTableStart(verifier) &&
3530++ VerifyField<uint8_t>(verifier, VT_ID) &&
3531++ VerifyField<uint16_t>(verifier, VT_SIZE) &&
3532++ VerifyField<uint8_t>(verifier, VT_SERIALIZATIONINDEX) &&
3533++ VerifyField<uint8_t>(verifier, VT_PADDING) &&
3534++ verifier.EndTable();
3535++ }
3536++};
3537++
3538++struct FBDimensionBuilder {
3539++ flatbuffers::FlatBufferBuilder &fbb_;
3540++ flatbuffers::uoffset_t start_;
3541++ void add_id(uint8_t id) {
3542++ fbb_.AddElement<uint8_t>(FBDimension::VT_ID, id, 0);
3543++ }
3544++ void add_size(uint16_t size) {
3545++ fbb_.AddElement<uint16_t>(FBDimension::VT_SIZE, size, 0);
3546++ }
3547++ void add_serializationIndex(uint8_t serializationIndex) {
3548++ fbb_.AddElement<uint8_t>(FBDimension::VT_SERIALIZATIONINDEX, serializationIndex, 0);
3549++ }
3550++ void add_padding(uint8_t padding) {
3551++ fbb_.AddElement<uint8_t>(FBDimension::VT_PADDING, padding, 0);
3552++ }
3553++ explicit FBDimensionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
3554++ : fbb_(_fbb) {
3555++ start_ = fbb_.StartTable();
3556++ }
3557++ FBDimensionBuilder &operator=(const FBDimensionBuilder &);
3558++ flatbuffers::Offset<FBDimension> Finish() {
3559++ const auto end = fbb_.EndTable(start_);
3560++ auto o = flatbuffers::Offset<FBDimension>(end);
3561++ return o;
3562++ }
3563++};
3564++
3565++inline flatbuffers::Offset<FBDimension> CreateFBDimension(
3566++ flatbuffers::FlatBufferBuilder &_fbb,
3567++ uint8_t id = 0,
3568++ uint16_t size = 0,
3569++ uint8_t serializationIndex = 0,
3570++ uint8_t padding = 0) {
3571++ FBDimensionBuilder builder_(_fbb);
3572++ builder_.add_size(size);
3573++ builder_.add_padding(padding);
3574++ builder_.add_serializationIndex(serializationIndex);
3575++ builder_.add_id(id);
3576++ return builder_.Finish();
3577++}
3578++
3579++struct FBInputTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
3580++ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
3581++ VT_ID = 4,
3582++ VT_NAME = 6,
3583++ VT_NUMOFDIMENSIONS = 8,
3584++ VT_DIMENSIONS = 10,
3585++ VT_SHIFT = 12,
3586++ VT_SCALE = 14,
3587++ VT_FORMAT = 16
3588++ };
3589++ uint8_t id() const {
3590++ return GetField<uint8_t>(VT_ID, 0);
3591++ }
3592++ const flatbuffers::String *name() const {
3593++ return GetPointer<const flatbuffers::String *>(VT_NAME);
3594++ }
3595++ uint8_t numOfDimensions() const {
3596++ return GetField<uint8_t>(VT_NUMOFDIMENSIONS, 0);
3597++ }
3598++ const flatbuffers::Vector<flatbuffers::Offset<FBDimension>> *dimensions() const {
3599++ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<FBDimension>> *>(VT_DIMENSIONS);
3600++ }
3601++ uint16_t shift() const {
3602++ return GetField<uint16_t>(VT_SHIFT, 0);
3603++ }
3604++ float scale() const {
3605++ return GetField<float>(VT_SCALE, 0.0f);
3606++ }
3607++ uint8_t format() const {
3608++ return GetField<uint8_t>(VT_FORMAT, 0);
3609++ }
3610++ bool Verify(flatbuffers::Verifier &verifier) const {
3611++ return VerifyTableStart(verifier) &&
3612++ VerifyField<uint8_t>(verifier, VT_ID) &&
3613++ VerifyOffset(verifier, VT_NAME) &&
3614++ verifier.VerifyString(name()) &&
3615++ VerifyField<uint8_t>(verifier, VT_NUMOFDIMENSIONS) &&
3616++ VerifyOffset(verifier, VT_DIMENSIONS) &&
3617++ verifier.VerifyVector(dimensions()) &&
3618++ verifier.VerifyVectorOfTables(dimensions()) &&
3619++ VerifyField<uint16_t>(verifier, VT_SHIFT) &&
3620++ VerifyField<float>(verifier, VT_SCALE) &&
3621++ VerifyField<uint8_t>(verifier, VT_FORMAT) &&
3622++ verifier.EndTable();
3623++ }
3624++};
3625++
3626++struct FBInputTensorBuilder {
3627++ flatbuffers::FlatBufferBuilder &fbb_;
3628++ flatbuffers::uoffset_t start_;
3629++ void add_id(uint8_t id) {
3630++ fbb_.AddElement<uint8_t>(FBInputTensor::VT_ID, id, 0);
3631++ }
3632++ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
3633++ fbb_.AddOffset(FBInputTensor::VT_NAME, name);
3634++ }
3635++ void add_numOfDimensions(uint8_t numOfDimensions) {
3636++ fbb_.AddElement<uint8_t>(FBInputTensor::VT_NUMOFDIMENSIONS, numOfDimensions, 0);
3637++ }
3638++ void add_dimensions(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBDimension>>> dimensions) {
3639++ fbb_.AddOffset(FBInputTensor::VT_DIMENSIONS, dimensions);
3640++ }
3641++ void add_shift(uint16_t shift) {
3642++ fbb_.AddElement<uint16_t>(FBInputTensor::VT_SHIFT, shift, 0);
3643++ }
3644++ void add_scale(float scale) {
3645++ fbb_.AddElement<float>(FBInputTensor::VT_SCALE, scale, 0.0f);
3646++ }
3647++ void add_format(uint8_t format) {
3648++ fbb_.AddElement<uint8_t>(FBInputTensor::VT_FORMAT, format, 0);
3649++ }
3650++ explicit FBInputTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
3651++ : fbb_(_fbb) {
3652++ start_ = fbb_.StartTable();
3653++ }
3654++ FBInputTensorBuilder &operator=(const FBInputTensorBuilder &);
3655++ flatbuffers::Offset<FBInputTensor> Finish() {
3656++ const auto end = fbb_.EndTable(start_);
3657++ auto o = flatbuffers::Offset<FBInputTensor>(end);
3658++ return o;
3659++ }
3660++};
3661++
3662++inline flatbuffers::Offset<FBInputTensor> CreateFBInputTensor(
3663++ flatbuffers::FlatBufferBuilder &_fbb,
3664++ uint8_t id = 0,
3665++ flatbuffers::Offset<flatbuffers::String> name = 0,
3666++ uint8_t numOfDimensions = 0,
3667++ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBDimension>>> dimensions = 0,
3668++ uint16_t shift = 0,
3669++ float scale = 0.0f,
3670++ uint8_t format = 0) {
3671++ FBInputTensorBuilder builder_(_fbb);
3672++ builder_.add_scale(scale);
3673++ builder_.add_dimensions(dimensions);
3674++ builder_.add_name(name);
3675++ builder_.add_shift(shift);
3676++ builder_.add_format(format);
3677++ builder_.add_numOfDimensions(numOfDimensions);
3678++ builder_.add_id(id);
3679++ return builder_.Finish();
3680++}
3681++
3682++inline flatbuffers::Offset<FBInputTensor> CreateFBInputTensorDirect(
3683++ flatbuffers::FlatBufferBuilder &_fbb,
3684++ uint8_t id = 0,
3685++ const char *name = nullptr,
3686++ uint8_t numOfDimensions = 0,
3687++ const std::vector<flatbuffers::Offset<FBDimension>> *dimensions = nullptr,
3688++ uint16_t shift = 0,
3689++ float scale = 0.0f,
3690++ uint8_t format = 0) {
3691++ auto name__ = name ? _fbb.CreateString(name) : 0;
3692++ auto dimensions__ = dimensions ? _fbb.CreateVector<flatbuffers::Offset<FBDimension>>(*dimensions) : 0;
3693++ return apParams::fb::CreateFBInputTensor(
3694++ _fbb,
3695++ id,
3696++ name__,
3697++ numOfDimensions,
3698++ dimensions__,
3699++ shift,
3700++ scale,
3701++ format);
3702++}
3703++
3704++struct FBOutputTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
3705++ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
3706++ VT_ID = 4,
3707++ VT_NAME = 6,
3708++ VT_NUMOFDIMENSIONS = 8,
3709++ VT_DIMENSIONS = 10,
3710++ VT_BITSPERELEMENT = 12,
3711++ VT_SHIFT = 14,
3712++ VT_SCALE = 16,
3713++ VT_FORMAT = 18
3714++ };
3715++ uint8_t id() const {
3716++ return GetField<uint8_t>(VT_ID, 0);
3717++ }
3718++ const flatbuffers::String *name() const {
3719++ return GetPointer<const flatbuffers::String *>(VT_NAME);
3720++ }
3721++ uint8_t numOfDimensions() const {
3722++ return GetField<uint8_t>(VT_NUMOFDIMENSIONS, 0);
3723++ }
3724++ const flatbuffers::Vector<flatbuffers::Offset<FBDimension>> *dimensions() const {
3725++ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<FBDimension>> *>(VT_DIMENSIONS);
3726++ }
3727++ uint8_t bitsPerElement() const {
3728++ return GetField<uint8_t>(VT_BITSPERELEMENT, 0);
3729++ }
3730++ uint16_t shift() const {
3731++ return GetField<uint16_t>(VT_SHIFT, 0);
3732++ }
3733++ float scale() const {
3734++ return GetField<float>(VT_SCALE, 0.0f);
3735++ }
3736++ uint8_t format() const {
3737++ return GetField<uint8_t>(VT_FORMAT, 0);
3738++ }
3739++ bool Verify(flatbuffers::Verifier &verifier) const {
3740++ return VerifyTableStart(verifier) &&
3741++ VerifyField<uint8_t>(verifier, VT_ID) &&
3742++ VerifyOffset(verifier, VT_NAME) &&
3743++ verifier.VerifyString(name()) &&
3744++ VerifyField<uint8_t>(verifier, VT_NUMOFDIMENSIONS) &&
3745++ VerifyOffset(verifier, VT_DIMENSIONS) &&
3746++ verifier.VerifyVector(dimensions()) &&
3747++ verifier.VerifyVectorOfTables(dimensions()) &&
3748++ VerifyField<uint8_t>(verifier, VT_BITSPERELEMENT) &&
3749++ VerifyField<uint16_t>(verifier, VT_SHIFT) &&
3750++ VerifyField<float>(verifier, VT_SCALE) &&
3751++ VerifyField<uint8_t>(verifier, VT_FORMAT) &&
3752++ verifier.EndTable();
3753++ }
3754++};
3755++
3756++struct FBOutputTensorBuilder {
3757++ flatbuffers::FlatBufferBuilder &fbb_;
3758++ flatbuffers::uoffset_t start_;
3759++ void add_id(uint8_t id) {
3760++ fbb_.AddElement<uint8_t>(FBOutputTensor::VT_ID, id, 0);
3761++ }
3762++ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
3763++ fbb_.AddOffset(FBOutputTensor::VT_NAME, name);
3764++ }
3765++ void add_numOfDimensions(uint8_t numOfDimensions) {
3766++ fbb_.AddElement<uint8_t>(FBOutputTensor::VT_NUMOFDIMENSIONS, numOfDimensions, 0);
3767++ }
3768++ void add_dimensions(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBDimension>>> dimensions) {
3769++ fbb_.AddOffset(FBOutputTensor::VT_DIMENSIONS, dimensions);
3770++ }
3771++ void add_bitsPerElement(uint8_t bitsPerElement) {
3772++ fbb_.AddElement<uint8_t>(FBOutputTensor::VT_BITSPERELEMENT, bitsPerElement, 0);
3773++ }
3774++ void add_shift(uint16_t shift) {
3775++ fbb_.AddElement<uint16_t>(FBOutputTensor::VT_SHIFT, shift, 0);
3776++ }
3777++ void add_scale(float scale) {
3778++ fbb_.AddElement<float>(FBOutputTensor::VT_SCALE, scale, 0.0f);
3779++ }
3780++ void add_format(uint8_t format) {
3781++ fbb_.AddElement<uint8_t>(FBOutputTensor::VT_FORMAT, format, 0);
3782++ }
3783++ explicit FBOutputTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
3784++ : fbb_(_fbb) {
3785++ start_ = fbb_.StartTable();
3786++ }
3787++ FBOutputTensorBuilder &operator=(const FBOutputTensorBuilder &);
3788++ flatbuffers::Offset<FBOutputTensor> Finish() {
3789++ const auto end = fbb_.EndTable(start_);
3790++ auto o = flatbuffers::Offset<FBOutputTensor>(end);
3791++ return o;
3792++ }
3793++};
3794++
3795++inline flatbuffers::Offset<FBOutputTensor> CreateFBOutputTensor(
3796++ flatbuffers::FlatBufferBuilder &_fbb,
3797++ uint8_t id = 0,
3798++ flatbuffers::Offset<flatbuffers::String> name = 0,
3799++ uint8_t numOfDimensions = 0,
3800++ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBDimension>>> dimensions = 0,
3801++ uint8_t bitsPerElement = 0,
3802++ uint16_t shift = 0,
3803++ float scale = 0.0f,
3804++ uint8_t format = 0) {
3805++ FBOutputTensorBuilder builder_(_fbb);
3806++ builder_.add_scale(scale);
3807++ builder_.add_dimensions(dimensions);
3808++ builder_.add_name(name);
3809++ builder_.add_shift(shift);
3810++ builder_.add_format(format);
3811++ builder_.add_bitsPerElement(bitsPerElement);
3812++ builder_.add_numOfDimensions(numOfDimensions);
3813++ builder_.add_id(id);
3814++ return builder_.Finish();
3815++}
3816++
3817++inline flatbuffers::Offset<FBOutputTensor> CreateFBOutputTensorDirect(
3818++ flatbuffers::FlatBufferBuilder &_fbb,
3819++ uint8_t id = 0,
3820++ const char *name = nullptr,
3821++ uint8_t numOfDimensions = 0,
3822++ const std::vector<flatbuffers::Offset<FBDimension>> *dimensions = nullptr,
3823++ uint8_t bitsPerElement = 0,
3824++ uint16_t shift = 0,
3825++ float scale = 0.0f,
3826++ uint8_t format = 0) {
3827++ auto name__ = name ? _fbb.CreateString(name) : 0;
3828++ auto dimensions__ = dimensions ? _fbb.CreateVector<flatbuffers::Offset<FBDimension>>(*dimensions) : 0;
3829++ return apParams::fb::CreateFBOutputTensor(
3830++ _fbb,
3831++ id,
3832++ name__,
3833++ numOfDimensions,
3834++ dimensions__,
3835++ bitsPerElement,
3836++ shift,
3837++ scale,
3838++ format);
3839++}
3840++
3841++struct FBNetwork FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
3842++ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
3843++ VT_ID = 4,
3844++ VT_NAME = 6,
3845++ VT_TYPE = 8,
3846++ VT_INPUTTENSORS = 10,
3847++ VT_OUTPUTTENSORS = 12
3848++ };
3849++ uint16_t id() const {
3850++ return GetField<uint16_t>(VT_ID, 0);
3851++ }
3852++ const flatbuffers::String *name() const {
3853++ return GetPointer<const flatbuffers::String *>(VT_NAME);
3854++ }
3855++ const flatbuffers::String *type() const {
3856++ return GetPointer<const flatbuffers::String *>(VT_TYPE);
3857++ }
3858++ const flatbuffers::Vector<flatbuffers::Offset<FBInputTensor>> *inputTensors() const {
3859++ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<FBInputTensor>> *>(VT_INPUTTENSORS);
3860++ }
3861++ const flatbuffers::Vector<flatbuffers::Offset<FBOutputTensor>> *outputTensors() const {
3862++ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<FBOutputTensor>> *>(VT_OUTPUTTENSORS);
3863++ }
3864++ bool Verify(flatbuffers::Verifier &verifier) const {
3865++ return VerifyTableStart(verifier) &&
3866++ VerifyField<uint16_t>(verifier, VT_ID) &&
3867++ VerifyOffset(verifier, VT_NAME) &&
3868++ verifier.VerifyString(name()) &&
3869++ VerifyOffset(verifier, VT_TYPE) &&
3870++ verifier.VerifyString(type()) &&
3871++ VerifyOffset(verifier, VT_INPUTTENSORS) &&
3872++ verifier.VerifyVector(inputTensors()) &&
3873++ verifier.VerifyVectorOfTables(inputTensors()) &&
3874++ VerifyOffset(verifier, VT_OUTPUTTENSORS) &&
3875++ verifier.VerifyVector(outputTensors()) &&
3876++ verifier.VerifyVectorOfTables(outputTensors()) &&
3877++ verifier.EndTable();
3878++ }
3879++};
3880++
3881++struct FBNetworkBuilder {
3882++ flatbuffers::FlatBufferBuilder &fbb_;
3883++ flatbuffers::uoffset_t start_;
3884++ void add_id(uint16_t id) {
3885++ fbb_.AddElement<uint16_t>(FBNetwork::VT_ID, id, 0);
3886++ }
3887++ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
3888++ fbb_.AddOffset(FBNetwork::VT_NAME, name);
3889++ }
3890++ void add_type(flatbuffers::Offset<flatbuffers::String> type) {
3891++ fbb_.AddOffset(FBNetwork::VT_TYPE, type);
3892++ }
3893++ void add_inputTensors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBInputTensor>>> inputTensors) {
3894++ fbb_.AddOffset(FBNetwork::VT_INPUTTENSORS, inputTensors);
3895++ }
3896++ void add_outputTensors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBOutputTensor>>> outputTensors) {
3897++ fbb_.AddOffset(FBNetwork::VT_OUTPUTTENSORS, outputTensors);
3898++ }
3899++ explicit FBNetworkBuilder(flatbuffers::FlatBufferBuilder &_fbb)
3900++ : fbb_(_fbb) {
3901++ start_ = fbb_.StartTable();
3902++ }
3903++ FBNetworkBuilder &operator=(const FBNetworkBuilder &);
3904++ flatbuffers::Offset<FBNetwork> Finish() {
3905++ const auto end = fbb_.EndTable(start_);
3906++ auto o = flatbuffers::Offset<FBNetwork>(end);
3907++ return o;
3908++ }
3909++};
3910++
3911++inline flatbuffers::Offset<FBNetwork> CreateFBNetwork(
3912++ flatbuffers::FlatBufferBuilder &_fbb,
3913++ uint16_t id = 0,
3914++ flatbuffers::Offset<flatbuffers::String> name = 0,
3915++ flatbuffers::Offset<flatbuffers::String> type = 0,
3916++ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBInputTensor>>> inputTensors = 0,
3917++ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBOutputTensor>>> outputTensors = 0) {
3918++ FBNetworkBuilder builder_(_fbb);
3919++ builder_.add_outputTensors(outputTensors);
3920++ builder_.add_inputTensors(inputTensors);
3921++ builder_.add_type(type);
3922++ builder_.add_name(name);
3923++ builder_.add_id(id);
3924++ return builder_.Finish();
3925++}
3926++
3927++inline flatbuffers::Offset<FBNetwork> CreateFBNetworkDirect(
3928++ flatbuffers::FlatBufferBuilder &_fbb,
3929++ uint16_t id = 0,
3930++ const char *name = nullptr,
3931++ const char *type = nullptr,
3932++ const std::vector<flatbuffers::Offset<FBInputTensor>> *inputTensors = nullptr,
3933++ const std::vector<flatbuffers::Offset<FBOutputTensor>> *outputTensors = nullptr) {
3934++ auto name__ = name ? _fbb.CreateString(name) : 0;
3935++ auto type__ = type ? _fbb.CreateString(type) : 0;
3936++ auto inputTensors__ = inputTensors ? _fbb.CreateVector<flatbuffers::Offset<FBInputTensor>>(*inputTensors) : 0;
3937++ auto outputTensors__ = outputTensors ? _fbb.CreateVector<flatbuffers::Offset<FBOutputTensor>>(*outputTensors) : 0;
3938++ return apParams::fb::CreateFBNetwork(
3939++ _fbb,
3940++ id,
3941++ name__,
3942++ type__,
3943++ inputTensors__,
3944++ outputTensors__);
3945++}
3946++
3947++struct FBApParams FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
3948++ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
3949++ VT_NETWORKS = 4
3950++ };
3951++ const flatbuffers::Vector<flatbuffers::Offset<FBNetwork>> *networks() const {
3952++ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<FBNetwork>> *>(VT_NETWORKS);
3953++ }
3954++ bool Verify(flatbuffers::Verifier &verifier) const {
3955++ return VerifyTableStart(verifier) &&
3956++ VerifyOffset(verifier, VT_NETWORKS) &&
3957++ verifier.VerifyVector(networks()) &&
3958++ verifier.VerifyVectorOfTables(networks()) &&
3959++ verifier.EndTable();
3960++ }
3961++};
3962++
3963++struct FBApParamsBuilder {
3964++ flatbuffers::FlatBufferBuilder &fbb_;
3965++ flatbuffers::uoffset_t start_;
3966++ void add_networks(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBNetwork>>> networks) {
3967++ fbb_.AddOffset(FBApParams::VT_NETWORKS, networks);
3968++ }
3969++ explicit FBApParamsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
3970++ : fbb_(_fbb) {
3971++ start_ = fbb_.StartTable();
3972++ }
3973++ FBApParamsBuilder &operator=(const FBApParamsBuilder &);
3974++ flatbuffers::Offset<FBApParams> Finish() {
3975++ const auto end = fbb_.EndTable(start_);
3976++ auto o = flatbuffers::Offset<FBApParams>(end);
3977++ return o;
3978++ }
3979++};
3980++
3981++inline flatbuffers::Offset<FBApParams> CreateFBApParams(
3982++ flatbuffers::FlatBufferBuilder &_fbb,
3983++ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FBNetwork>>> networks = 0) {
3984++ FBApParamsBuilder builder_(_fbb);
3985++ builder_.add_networks(networks);
3986++ return builder_.Finish();
3987++}
3988++
3989++inline flatbuffers::Offset<FBApParams> CreateFBApParamsDirect(
3990++ flatbuffers::FlatBufferBuilder &_fbb,
3991++ const std::vector<flatbuffers::Offset<FBNetwork>> *networks = nullptr) {
3992++ auto networks__ = networks ? _fbb.CreateVector<flatbuffers::Offset<FBNetwork>>(*networks) : 0;
3993++ return apParams::fb::CreateFBApParams(
3994++ _fbb,
3995++ networks__);
3996++}
3997++
3998++inline const apParams::fb::FBApParams *GetFBApParams(const void *buf) {
3999++ return flatbuffers::GetRoot<apParams::fb::FBApParams>(buf);
4000++}
4001++
4002++inline const apParams::fb::FBApParams *GetSizePrefixedFBApParams(const void *buf) {
4003++ return flatbuffers::GetSizePrefixedRoot<apParams::fb::FBApParams>(buf);
4004++}
4005++
4006++inline bool VerifyFBApParamsBuffer(
4007++ flatbuffers::Verifier &verifier) {
4008++ return verifier.VerifyBuffer<apParams::fb::FBApParams>(nullptr);
4009++}
4010++
4011++inline bool VerifySizePrefixedFBApParamsBuffer(
4012++ flatbuffers::Verifier &verifier) {
4013++ return verifier.VerifySizePrefixedBuffer<apParams::fb::FBApParams>(nullptr);
4014++}
4015++
4016++inline void FinishFBApParamsBuffer(
4017++ flatbuffers::FlatBufferBuilder &fbb,
4018++ flatbuffers::Offset<apParams::fb::FBApParams> root) {
4019++ fbb.Finish(root);
4020++}
4021++
4022++inline void FinishSizePrefixedFBApParamsBuffer(
4023++ flatbuffers::FlatBufferBuilder &fbb,
4024++ flatbuffers::Offset<apParams::fb::FBApParams> root) {
4025++ fbb.FinishSizePrefixed(root);
4026++}
4027++
4028++} // namespace fb
4029++} // namespace apParams
4030++
4031++#endif // FLATBUFFERS_GENERATED_APPARAMSFLATBUFFERS_APPARAMS_FB_H_
4032+\ No newline at end of file
4033+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4034++++ b/src/ipa/rpi/cam_helper/imx500_tensor_parser/flatbuffers/base.h 2025-05-08 00:06:16.055331334 +0530
4035+@@ -0,0 +1,379 @@
4036++#ifndef FLATBUFFERS_BASE_H_
4037++#define FLATBUFFERS_BASE_H_
4038++
4039++// clang-format off
4040++
4041++// If activate should be declared and included first.
4042++#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
4043++ defined(_MSC_VER) && defined(_DEBUG)
4044++ // The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace
4045++ // calloc/free (etc) to its debug version using #define directives.
4046++ #define _CRTDBG_MAP_ALLOC
4047++ #include <stdlib.h>
4048++ #include <crtdbg.h>
4049++ // Replace operator new by trace-enabled version.
4050++ #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
4051++ #define new DEBUG_NEW
4052++#endif
4053++
4054++#if !defined(FLATBUFFERS_ASSERT)
4055++#include <assert.h>
4056++#define FLATBUFFERS_ASSERT assert
4057++#elif defined(FLATBUFFERS_ASSERT_INCLUDE)
4058++// Include file with forward declaration
4059++#include FLATBUFFERS_ASSERT_INCLUDE
4060++#endif
4061++
4062++#ifndef ARDUINO
4063++#include <cstdint>
4064++#endif
4065++
4066++#include <cstddef>
4067++#include <cstdlib>
4068++#include <cstring>
4069++
4070++#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H)
4071++ #include <utility.h>
4072++#else
4073++ #include <utility>
4074++#endif
4075++
4076++#include <string>
4077++#include <type_traits>
4078++#include <vector>
4079++#include <set>
4080++#include <algorithm>
4081++#include <iterator>
4082++#include <memory>
4083++
4084++#ifdef _STLPORT_VERSION
4085++ #define FLATBUFFERS_CPP98_STL
4086++#endif
4087++#ifndef FLATBUFFERS_CPP98_STL
4088++ #include <functional>
4089++#endif
4090++
4091++#include "stl_emulation.h"
4092++
4093++// Note the __clang__ check is needed, because clang presents itself
4094++// as an older GNUC compiler (4.2).
4095++// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
4096++// Clang 3.4 and later implement all of the ISO C++ 2014 standard.
4097++// http://clang.llvm.org/cxx_status.html
4098++
4099++// Note the MSVC value '__cplusplus' may be incorrect:
4100++// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L,
4101++// indicating (erroneously!) that the compiler conformed to the C++98 Standard.
4102++// This value should be correct starting from MSVC2017-15.7-Preview-3.
4103++// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set.
4104++// Workaround (for details see MSDN):
4105++// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility.
4106++// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch.
4107++
4108++#if defined(__GNUC__) && !defined(__clang__)
4109++ #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
4110++#else
4111++ #define FLATBUFFERS_GCC 0
4112++#endif
4113++
4114++#if defined(__clang__)
4115++ #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
4116++#else
4117++ #define FLATBUFFERS_CLANG 0
4118++#endif
4119++
4120++/// @cond FLATBUFFERS_INTERNAL
4121++#if __cplusplus <= 199711L && \
4122++ (!defined(_MSC_VER) || _MSC_VER < 1600) && \
4123++ (!defined(__GNUC__) || \
4124++ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
4125++ #error A C++11 compatible compiler with support for the auto typing is \
4126++ required for FlatBuffers.
4127++ #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
4128++#endif
4129++
4130++#if !defined(__clang__) && \
4131++ defined(__GNUC__) && \
4132++ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
4133++ // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
4134++ // and constexpr keywords. Note the __clang__ check is needed, because clang
4135++ // presents itself as an older GNUC compiler.
4136++ #ifndef nullptr_t
4137++ const class nullptr_t {
4138++ public:
4139++ template<class T> inline operator T*() const { return 0; }
4140++ private:
4141++ void operator&() const;
4142++ } nullptr = {};
4143++ #endif
4144++ #ifndef constexpr
4145++ #define constexpr const
4146++ #endif
4147++#endif
4148++
4149++// The wire format uses a little endian encoding (since that's efficient for
4150++// the common platforms).
4151++#if defined(__s390x__)
4152++ #define FLATBUFFERS_LITTLEENDIAN 0
4153++#endif // __s390x__
4154++#if !defined(FLATBUFFERS_LITTLEENDIAN)
4155++ #if defined(__GNUC__) || defined(__clang__)
4156++ #if (defined(__BIG_ENDIAN__) || \
4157++ (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
4158++ #define FLATBUFFERS_LITTLEENDIAN 0
4159++ #else
4160++ #define FLATBUFFERS_LITTLEENDIAN 1
4161++ #endif // __BIG_ENDIAN__
4162++ #elif defined(_MSC_VER)
4163++ #if defined(_M_PPC)
4164++ #define FLATBUFFERS_LITTLEENDIAN 0
4165++ #else
4166++ #define FLATBUFFERS_LITTLEENDIAN 1
4167++ #endif
4168++ #else
4169++ #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
4170++ #endif
4171++#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
4172++
4173++#define FLATBUFFERS_VERSION_MAJOR 1
4174++#define FLATBUFFERS_VERSION_MINOR 11
4175++#define FLATBUFFERS_VERSION_REVISION 0
4176++#define FLATBUFFERS_STRING_EXPAND(X) #X
4177++#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
4178++
4179++#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
4180++ (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
4181++ defined(__clang__)
4182++ #define FLATBUFFERS_FINAL_CLASS final
4183++ #define FLATBUFFERS_OVERRIDE override
4184++ #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
4185++#else
4186++ #define FLATBUFFERS_FINAL_CLASS
4187++ #define FLATBUFFERS_OVERRIDE
4188++ #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE
4189++#endif
4190++
4191++#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
4192++ (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
4193++ (defined(__cpp_constexpr) && __cpp_constexpr >= 200704)
4194++ #define FLATBUFFERS_CONSTEXPR constexpr
4195++#else
4196++ #define FLATBUFFERS_CONSTEXPR const
4197++#endif
4198++
4199++#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
4200++ (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
4201++ #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR
4202++#else
4203++ #define FLATBUFFERS_CONSTEXPR_CPP14
4204++#endif
4205++
4206++#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
4207++ (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \
4208++ defined(__clang__)
4209++ #define FLATBUFFERS_NOEXCEPT noexcept
4210++#else
4211++ #define FLATBUFFERS_NOEXCEPT
4212++#endif
4213++
4214++// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
4215++// private, so be sure to put it at the end or reset access mode explicitly.
4216++#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
4217++ (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \
4218++ defined(__clang__)
4219++ #define FLATBUFFERS_DELETE_FUNC(func) func = delete;
4220++#else
4221++ #define FLATBUFFERS_DELETE_FUNC(func) private: func;
4222++#endif
4223++
4224++#ifndef FLATBUFFERS_HAS_STRING_VIEW
4225++ // Only provide flatbuffers::string_view if __has_include can be used
4226++ // to detect a header that provides an implementation
4227++ #if defined(__has_include)
4228++ // Check for std::string_view (in c++17)
4229++ #if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
4230++ #include <string_view>
4231++ namespace flatbuffers {
4232++ typedef std::string_view string_view;
4233++ }
4234++ #define FLATBUFFERS_HAS_STRING_VIEW 1
4235++ // Check for std::experimental::string_view (in c++14, compiler-dependent)
4236++ #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
4237++ #include <experimental/string_view>
4238++ namespace flatbuffers {
4239++ typedef std::experimental::string_view string_view;
4240++ }
4241++ #define FLATBUFFERS_HAS_STRING_VIEW 1
4242++ #endif
4243++ #endif // __has_include
4244++#endif // !FLATBUFFERS_HAS_STRING_VIEW
4245++
4246++#ifndef FLATBUFFERS_HAS_NEW_STRTOD
4247++ // Modern (C++11) strtod and strtof functions are available for use.
4248++ // 1) nan/inf strings as argument of strtod;
4249++ // 2) hex-float as argument of strtod/strtof.
4250++ #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
4251++ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \
4252++ (defined(__clang__))
4253++ #define FLATBUFFERS_HAS_NEW_STRTOD 1
4254++ #endif
4255++#endif // !FLATBUFFERS_HAS_NEW_STRTOD
4256++
4257++#ifndef FLATBUFFERS_LOCALE_INDEPENDENT
4258++ // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}.
4259++ // They are part of the POSIX-2008 but not part of the C/C++ standard.
4260++ // GCC/Clang have definition (_XOPEN_SOURCE>=700) if POSIX-2008.
4261++ #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \
4262++ (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE>=700)))
4263++ #define FLATBUFFERS_LOCALE_INDEPENDENT 1
4264++ #else
4265++ #define FLATBUFFERS_LOCALE_INDEPENDENT 0
4266++ #endif
4267++#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
4268++
4269++// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
4270++// - __supress_ubsan__("undefined")
4271++// - __supress_ubsan__("signed-integer-overflow")
4272++#if defined(__clang__)
4273++ #define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
4274++#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
4275++ #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
4276++#else
4277++ #define __supress_ubsan__(type)
4278++#endif
4279++
4280++// This is constexpr function used for checking compile-time constants.
4281++// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
4282++template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
4283++ return !!t;
4284++}
4285++
4286++// Enable C++ attribute [[]] if std:c++17 or higher.
4287++#if ((__cplusplus >= 201703L) \
4288++ || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))
4289++ // All attributes unknown to an implementation are ignored without causing an error.
4290++ #define FLATBUFFERS_ATTRIBUTE(attr) [[attr]]
4291++
4292++ #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]]
4293++#else
4294++ #define FLATBUFFERS_ATTRIBUTE(attr)
4295++
4296++ #if FLATBUFFERS_CLANG >= 30800
4297++ #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]]
4298++ #elif FLATBUFFERS_GCC >= 70300
4299++ #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]]
4300++ #else
4301++ #define FLATBUFFERS_FALLTHROUGH()
4302++ #endif
4303++#endif
4304++
4305++/// @endcond
4306++
4307++/// @file
4308++namespace flatbuffers {
4309++
4310++/// @cond FLATBUFFERS_INTERNAL
4311++// Our default offset / size type, 32bit on purpose on 64bit systems.
4312++// Also, using a consistent offset type maintains compatibility of serialized
4313++// offset values between 32bit and 64bit systems.
4314++typedef uint32_t uoffset_t;
4315++
4316++// Signed offsets for references that can go in both directions.
4317++typedef int32_t soffset_t;
4318++
4319++// Offset/index used in v-tables, can be changed to uint8_t in
4320++// format forks to save a bit of space if desired.
4321++typedef uint16_t voffset_t;
4322++
4323++typedef uintmax_t largest_scalar_t;
4324++
4325++// In 32bits, this evaluates to 2GB - 1
4326++#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
4327++
4328++// We support aligning the contents of buffers up to this size.
4329++#define FLATBUFFERS_MAX_ALIGNMENT 16
4330++
4331++#if defined(_MSC_VER)
4332++ #pragma warning(push)
4333++ #pragma warning(disable: 4127) // C4127: conditional expression is constant
4334++#endif
4335++
4336++template<typename T> T EndianSwap(T t) {
4337++ #if defined(_MSC_VER)
4338++ #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
4339++ #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
4340++ #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
4341++ #else
4342++ #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
4343++ // __builtin_bswap16 was missing prior to GCC 4.8.
4344++ #define FLATBUFFERS_BYTESWAP16(x) \
4345++ static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
4346++ #else
4347++ #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
4348++ #endif
4349++ #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
4350++ #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
4351++ #endif
4352++ if (sizeof(T) == 1) { // Compile-time if-then's.
4353++ return t;
4354++ } else if (sizeof(T) == 2) {
4355++ union { T t; uint16_t i; } u;
4356++ u.t = t;
4357++ u.i = FLATBUFFERS_BYTESWAP16(u.i);
4358++ return u.t;
4359++ } else if (sizeof(T) == 4) {
4360++ union { T t; uint32_t i; } u;
4361++ u.t = t;
4362++ u.i = FLATBUFFERS_BYTESWAP32(u.i);
4363++ return u.t;
4364++ } else if (sizeof(T) == 8) {
4365++ union { T t; uint64_t i; } u;
4366++ u.t = t;
4367++ u.i = FLATBUFFERS_BYTESWAP64(u.i);
4368++ return u.t;
4369++ } else {
4370++ FLATBUFFERS_ASSERT(0);
4371++ }
4372++}
4373++
4374++#if defined(_MSC_VER)
4375++ #pragma warning(pop)
4376++#endif
4377++
4378++
4379++template<typename T> T EndianScalar(T t) {
4380++ #if FLATBUFFERS_LITTLEENDIAN
4381++ return t;
4382++ #else
4383++ return EndianSwap(t);
4384++ #endif
4385++}
4386++
4387++template<typename T>
4388++// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
4389++__supress_ubsan__("alignment")
4390++T ReadScalar(const void *p) {
4391++ return EndianScalar(*reinterpret_cast<const T *>(p));
4392++}
4393++
4394++template<typename T>
4395++// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
4396++__supress_ubsan__("alignment")
4397++void WriteScalar(void *p, T t) {
4398++ *reinterpret_cast<T *>(p) = EndianScalar(t);
4399++}
4400++
4401++template<typename T> struct Offset;
4402++template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
4403++ *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
4404++}
4405++
4406++// Computes how many bytes you'd have to pad to be able to write an
4407++// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
4408++// memory).
4409++inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
4410++ return ((~buf_size) + 1) & (scalar_size - 1);
4411++}
4412++
4413++} // namespace flatbuffers
4414++#endif // FLATBUFFERS_BASE_H_
4415+\ No newline at end of file
4416+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4417++++ b/src/ipa/rpi/cam_helper/imx500_tensor_parser/flatbuffers/code_generators.h 2025-05-08 00:06:16.055331334 +0530
4418+@@ -0,0 +1,203 @@
4419++/*
4420++ * Copyright 2014 Google Inc. All rights reserved.
4421++ *
4422++ * Licensed under the Apache License, Version 2.0 (the "License");
4423++ * you may not use this file except in compliance with the License.
4424++ * You may obtain a copy of the License at
4425++ *
4426++ * http://www.apache.org/licenses/LICENSE-2.0
4427++ *
4428++ * Unless required by applicable law or agreed to in writing, software
4429++ * distributed under the License is distributed on an "AS IS" BASIS,
4430++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4431++ * See the License for the specific language governing permissions and
4432++ * limitations under the License.
4433++ */
4434++
4435++#ifndef FLATBUFFERS_CODE_GENERATORS_H_
4436++#define FLATBUFFERS_CODE_GENERATORS_H_
4437++
4438++#include <map>
4439++#include <sstream>
4440++#include "flatbuffers/idl.h"
4441++
4442++namespace flatbuffers {
4443++
4444++// Utility class to assist in generating code through use of text templates.
4445++//
4446++// Example code:
4447++// CodeWriter code;
4448++// code.SetValue("NAME", "Foo");
4449++// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
4450++// code.SetValue("NAME", "Bar");
4451++// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
4452++// std::cout << code.ToString() << std::endl;
4453++//
4454++// Output:
4455++// void Foo() { printf("%s", "Foo"); }
4456++// void Bar() { printf("%s", "Bar"); }
4457++class CodeWriter {
4458++ public:
4459++ CodeWriter() {}
4460++
4461++ // Clears the current "written" code.
4462++ void Clear() {
4463++ stream_.str("");
4464++ stream_.clear();
4465++ }
4466++
4467++ // Associates a key with a value. All subsequent calls to operator+=, where
4468++ // the specified key is contained in {{ and }} delimiters will be replaced by
4469++ // the given value.
4470++ void SetValue(const std::string &key, const std::string &value) {
4471++ value_map_[key] = value;
4472++ }
4473++
4474++ // Appends the given text to the generated code as well as a newline
4475++ // character. Any text within {{ and }} delimeters is replaced by values
4476++ // previously stored in the CodeWriter by calling SetValue above. The newline
4477++ // will be suppressed if the text ends with the \\ character.
4478++ void operator+=(std::string text);
4479++
4480++ // Returns the current contents of the CodeWriter as a std::string.
4481++ std::string ToString() const { return stream_.str(); }
4482++
4483++ private:
4484++ std::map<std::string, std::string> value_map_;
4485++ std::stringstream stream_;
4486++};
4487++
4488++class BaseGenerator {
4489++ public:
4490++ virtual bool generate() = 0;
4491++
4492++ static std::string NamespaceDir(const Parser &parser, const std::string &path,
4493++ const Namespace &ns);
4494++
4495++ protected:
4496++ BaseGenerator(const Parser &parser, const std::string &path,
4497++ const std::string &file_name,
4498++ const std::string qualifying_start,
4499++ const std::string qualifying_separator)
4500++ : parser_(parser),
4501++ path_(path),
4502++ file_name_(file_name),
4503++ qualifying_start_(qualifying_start),
4504++ qualifying_separator_(qualifying_separator) {}
4505++ virtual ~BaseGenerator() {}
4506++
4507++ // No copy/assign.
4508++ BaseGenerator &operator=(const BaseGenerator &);
4509++ BaseGenerator(const BaseGenerator &);
4510++
4511++ std::string NamespaceDir(const Namespace &ns) const;
4512++
4513++ static const char *FlatBuffersGeneratedWarning();
4514++
4515++ static std::string FullNamespace(const char *separator, const Namespace &ns);
4516++
4517++ static std::string LastNamespacePart(const Namespace &ns);
4518++
4519++ // tracks the current namespace for early exit in WrapInNameSpace
4520++ // c++, java and csharp returns a different namespace from
4521++ // the following default (no early exit, always fully qualify),
4522++ // which works for js and php
4523++ virtual const Namespace *CurrentNameSpace() const { return nullptr; }
4524++
4525++ // Ensure that a type is prefixed with its namespace whenever it is used
4526++ // outside of its namespace.
4527++ std::string WrapInNameSpace(const Namespace *ns,
4528++ const std::string &name) const;
4529++
4530++ std::string WrapInNameSpace(const Definition &def) const;
4531++
4532++ std::string GetNameSpace(const Definition &def) const;
4533++
4534++ const Parser &parser_;
4535++ const std::string &path_;
4536++ const std::string &file_name_;
4537++ const std::string qualifying_start_;
4538++ const std::string qualifying_separator_;
4539++};
4540++
4541++struct CommentConfig {
4542++ const char *first_line;
4543++ const char *content_line_prefix;
4544++ const char *last_line;
4545++};
4546++
4547++extern void GenComment(const std::vector<std::string> &dc,
4548++ std::string *code_ptr, const CommentConfig *config,
4549++ const char *prefix = "");
4550++
4551++class FloatConstantGenerator {
4552++ public:
4553++ virtual ~FloatConstantGenerator() {}
4554++ std::string GenFloatConstant(const FieldDef &field) const;
4555++
4556++ private:
4557++ virtual std::string Value(double v, const std::string &src) const = 0;
4558++ virtual std::string Inf(double v) const = 0;
4559++ virtual std::string NaN(double v) const = 0;
4560++
4561++ virtual std::string Value(float v, const std::string &src) const = 0;
4562++ virtual std::string Inf(float v) const = 0;
4563++ virtual std::string NaN(float v) const = 0;
4564++
4565++ template<typename T>
4566++ std::string GenFloatConstantImpl(const FieldDef &field) const;
4567++};
4568++
4569++class SimpleFloatConstantGenerator : public FloatConstantGenerator {
4570++ public:
4571++ SimpleFloatConstantGenerator(const char *nan_number,
4572++ const char *pos_inf_number,
4573++ const char *neg_inf_number);
4574++
4575++ private:
4576++ std::string Value(double v,
4577++ const std::string &src) const FLATBUFFERS_OVERRIDE;
4578++ std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
4579++ std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
4580++
4581++ std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
4582++ std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
4583++ std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
4584++
4585++ const std::string nan_number_;
4586++ const std::string pos_inf_number_;
4587++ const std::string neg_inf_number_;
4588++};
4589++
4590++// C++, C#, Java like generator.
4591++class TypedFloatConstantGenerator : public FloatConstantGenerator {
4592++ public:
4593++ TypedFloatConstantGenerator(const char *double_prefix,
4594++ const char *single_prefix, const char *nan_number,
4595++ const char *pos_inf_number,
4596++ const char *neg_inf_number = "");
4597++
4598++ private:
4599++ std::string Value(double v,
4600++ const std::string &src) const FLATBUFFERS_OVERRIDE;
4601++ std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
4602++
4603++ std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
4604++
4605++ std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
4606++ std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
4607++ std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
4608++
4609++ std::string MakeNaN(const std::string &prefix) const;
4610++ std::string MakeInf(bool neg, const std::string &prefix) const;
4611++
4612++ const std::string double_prefix_;
4613++ const std::string single_prefix_;
4614++ const std::string nan_number_;
4615++ const std::string pos_inf_number_;
4616++ const std::string neg_inf_number_;
4617++};
4618++
4619++} // namespace flatbuffers
4620++
4621++#endif // FLATBUFFERS_CODE_GENERATORS_H_
4622+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4623++++ b/src/ipa/rpi/cam_helper/imx500_tensor_parser/flatbuffers/flatbuffers.h 2025-05-08 00:06:16.056331319 +0530
4624+@@ -0,0 +1,2613 @@
4625++/*
4626++ * Copyright 2014 Google Inc. All rights reserved.
4627++ *
4628++ * Licensed under the Apache License, Version 2.0 (the "License");
4629++ * you may not use this file except in compliance with the License.
4630++ * You may obtain a copy of the License at
4631++ *
4632++ * http://www.apache.org/licenses/LICENSE-2.0
4633++ *
4634++ * Unless required by applicable law or agreed to in writing, software
4635++ * distributed under the License is distributed on an "AS IS" BASIS,
4636++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4637++ * See the License for the specific language governing permissions and
4638++ * limitations under the License.
4639++ */
4640++
4641++#ifndef FLATBUFFERS_H_
4642++#define FLATBUFFERS_H_
4643++
4644++#include "base.h"
4645++
4646++#if defined(FLATBUFFERS_NAN_DEFAULTS)
4647++#include <cmath>
4648++#endif
4649++
4650++namespace flatbuffers {
4651++// Generic 'operator==' with conditional specialisations.
4652++template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
4653++
4654++#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
4655++ (!defined(_MSC_VER) || _MSC_VER >= 1800)
4656++// Like `operator==(e, def)` with weak NaN if T=(float|double).
4657++template<> inline bool IsTheSameAs<float>(float e, float def) {
4658++ return (e == def) || (std::isnan(def) && std::isnan(e));
4659++}
4660++template<> inline bool IsTheSameAs<double>(double e, double def) {
4661++ return (e == def) || (std::isnan(def) && std::isnan(e));
4662++}
4663++#endif
4664++
4665++// Wrapper for uoffset_t to allow safe template specialization.
4666++// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
4667++template<typename T> struct Offset {
4668++ uoffset_t o;
4669++ Offset() : o(0) {}
4670++ Offset(uoffset_t _o) : o(_o) {}
4671++ Offset<void> Union() const { return Offset<void>(o); }
4672++ bool IsNull() const { return !o; }
4673++};
4674++
4675++inline void EndianCheck() {
4676++ int endiantest = 1;
4677++ // If this fails, see FLATBUFFERS_LITTLEENDIAN above.
4678++ FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
4679++ FLATBUFFERS_LITTLEENDIAN);
4680++ (void)endiantest;
4681++}
4682++
4683++template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
4684++ // clang-format off
4685++ #ifdef _MSC_VER
4686++ return __alignof(T);
4687++ #else
4688++ #ifndef alignof
4689++ return __alignof__(T);
4690++ #else
4691++ return alignof(T);
4692++ #endif
4693++ #endif
4694++ // clang-format on
4695++}
4696++
4697++// When we read serialized data from memory, in the case of most scalars,
4698++// we want to just read T, but in the case of Offset, we want to actually
4699++// perform the indirection and return a pointer.
4700++// The template specialization below does just that.
4701++// It is wrapped in a struct since function templates can't overload on the
4702++// return type like this.
4703++// The typedef is for the convenience of callers of this function
4704++// (avoiding the need for a trailing return decltype)
4705++template<typename T> struct IndirectHelper {
4706++ typedef T return_type;
4707++ typedef T mutable_return_type;
4708++ static const size_t element_stride = sizeof(T);
4709++ static return_type Read(const uint8_t *p, uoffset_t i) {
4710++ return EndianScalar((reinterpret_cast<const T *>(p))[i]);
4711++ }
4712++};
4713++template<typename T> struct IndirectHelper<Offset<T>> {
4714++ typedef const T *return_type;
4715++ typedef T *mutable_return_type;
4716++ static const size_t element_stride = sizeof(uoffset_t);
4717++ static return_type Read(const uint8_t *p, uoffset_t i) {
4718++ p += i * sizeof(uoffset_t);
4719++ return reinterpret_cast<return_type>(p + ReadScalar<uoffset_t>(p));
4720++ }
4721++};
4722++template<typename T> struct IndirectHelper<const T *> {
4723++ typedef const T *return_type;
4724++ typedef T *mutable_return_type;
4725++ static const size_t element_stride = sizeof(T);
4726++ static return_type Read(const uint8_t *p, uoffset_t i) {
4727++ return reinterpret_cast<const T *>(p + i * sizeof(T));
4728++ }
4729++};
4730++
4731++// An STL compatible iterator implementation for Vector below, effectively
4732++// calling Get() for every element.
4733++template<typename T, typename IT> struct VectorIterator {
4734++ typedef std::random_access_iterator_tag iterator_category;
4735++ typedef IT value_type;
4736++ typedef ptrdiff_t difference_type;
4737++ typedef IT *pointer;
4738++ typedef IT &reference;
4739++
4740++ VectorIterator(const uint8_t *data, uoffset_t i)
4741++ : data_(data + IndirectHelper<T>::element_stride * i) {}
4742++ VectorIterator(const VectorIterator &other) : data_(other.data_) {}
4743++ VectorIterator() : data_(nullptr) {}
4744++
4745++ VectorIterator &operator=(const VectorIterator &other) {
4746++ data_ = other.data_;
4747++ return *this;
4748++ }
4749++
4750++ // clang-format off
4751++ #if !defined(FLATBUFFERS_CPP98_STL)
4752++ VectorIterator &operator=(VectorIterator &&other) {
4753++ data_ = other.data_;
4754++ return *this;
4755++ }
4756++ #endif // !defined(FLATBUFFERS_CPP98_STL)
4757++ // clang-format on
4758++
4759++ bool operator==(const VectorIterator &other) const {
4760++ return data_ == other.data_;
4761++ }
4762++
4763++ bool operator<(const VectorIterator &other) const {
4764++ return data_ < other.data_;
4765++ }
4766++
4767++ bool operator!=(const VectorIterator &other) const {
4768++ return data_ != other.data_;
4769++ }
4770++
4771++ difference_type operator-(const VectorIterator &other) const {
4772++ return (data_ - other.data_) / IndirectHelper<T>::element_stride;
4773++ }
4774++
4775++ IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
4776++
4777++ IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
4778++
4779++ VectorIterator &operator++() {
4780++ data_ += IndirectHelper<T>::element_stride;
4781++ return *this;
4782++ }
4783++
4784++ VectorIterator operator++(int) {
4785++ VectorIterator temp(data_, 0);
4786++ data_ += IndirectHelper<T>::element_stride;
4787++ return temp;
4788++ }
4789++
4790++ VectorIterator operator+(const uoffset_t &offset) const {
4791++ return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
4792++ 0);
4793++ }
4794++
4795++ VectorIterator &operator+=(const uoffset_t &offset) {
4796++ data_ += offset * IndirectHelper<T>::element_stride;
4797++ return *this;
4798++ }
4799++
4800++ VectorIterator &operator--() {
4801++ data_ -= IndirectHelper<T>::element_stride;
4802++ return *this;
4803++ }
4804++
4805++ VectorIterator operator--(int) {
4806++ VectorIterator temp(data_, 0);
4807++ data_ -= IndirectHelper<T>::element_stride;
4808++ return temp;
4809++ }
4810++
4811++ VectorIterator operator-(const uoffset_t &offset) const {
4812++ return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
4813++ 0);
4814++ }
4815++
4816++ VectorIterator &operator-=(const uoffset_t &offset) {
4817++ data_ -= offset * IndirectHelper<T>::element_stride;
4818++ return *this;
4819++ }
4820++
4821++ private:
4822++ const uint8_t *data_;
4823++};
4824++
4825++template<typename Iterator> struct VectorReverseIterator :
4826++ public std::reverse_iterator<Iterator> {
4827++
4828++ explicit VectorReverseIterator(Iterator iter) : iter_(iter) {}
4829++
4830++ typename Iterator::value_type operator*() const { return *(iter_ - 1); }
4831++
4832++ typename Iterator::value_type operator->() const { return *(iter_ - 1); }
4833++
4834++ private:
4835++ Iterator iter_;
4836++};
4837++
4838++struct String;
4839++
4840++// This is used as a helper type for accessing vectors.
4841++// Vector::data() assumes the vector elements start after the length field.
4842++template<typename T> class Vector {
4843++ public:
4844++ typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
4845++ iterator;
4846++ typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
4847++ const_iterator;
4848++ typedef VectorReverseIterator<iterator> reverse_iterator;
4849++ typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
4850++
4851++ uoffset_t size() const { return EndianScalar(length_); }
4852++
4853++ // Deprecated: use size(). Here for backwards compatibility.
4854++ FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead"))
4855++ uoffset_t Length() const { return size(); }
4856++
4857++ typedef typename IndirectHelper<T>::return_type return_type;
4858++ typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
4859++
4860++ return_type Get(uoffset_t i) const {
4861++ FLATBUFFERS_ASSERT(i < size());
4862++ return IndirectHelper<T>::Read(Data(), i);
4863++ }
4864++
4865++ return_type operator[](uoffset_t i) const { return Get(i); }
4866++
4867++ // If this is a Vector of enums, T will be its storage type, not the enum
4868++ // type. This function makes it convenient to retrieve value with enum
4869++ // type E.
4870++ template<typename E> E GetEnum(uoffset_t i) const {
4871++ return static_cast<E>(Get(i));
4872++ }
4873++
4874++ // If this a vector of unions, this does the cast for you. There's no check
4875++ // to make sure this is the right type!
4876++ template<typename U> const U *GetAs(uoffset_t i) const {
4877++ return reinterpret_cast<const U *>(Get(i));
4878++ }
4879++
4880++ // If this a vector of unions, this does the cast for you. There's no check
4881++ // to make sure this is actually a string!
4882++ const String *GetAsString(uoffset_t i) const {
4883++ return reinterpret_cast<const String *>(Get(i));
4884++ }
4885++
4886++ const void *GetStructFromOffset(size_t o) const {
4887++ return reinterpret_cast<const void *>(Data() + o);
4888++ }
4889++
4890++ iterator begin() { return iterator(Data(), 0); }
4891++ const_iterator begin() const { return const_iterator(Data(), 0); }
4892++
4893++ iterator end() { return iterator(Data(), size()); }
4894++ const_iterator end() const { return const_iterator(Data(), size()); }
4895++
4896++ reverse_iterator rbegin() { return reverse_iterator(end()); }
4897++ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
4898++
4899++ reverse_iterator rend() { return reverse_iterator(end()); }
4900++ const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
4901++
4902++ const_iterator cbegin() const { return begin(); }
4903++
4904++ const_iterator cend() const { return end(); }
4905++
4906++ const_reverse_iterator crbegin() const { return rbegin(); }
4907++
4908++ const_reverse_iterator crend() const { return rend(); }
4909++
4910++ // Change elements if you have a non-const pointer to this object.
4911++ // Scalars only. See reflection.h, and the documentation.
4912++ void Mutate(uoffset_t i, const T &val) {
4913++ FLATBUFFERS_ASSERT(i < size());
4914++ WriteScalar(data() + i, val);
4915++ }
4916++
4917++ // Change an element of a vector of tables (or strings).
4918++ // "val" points to the new table/string, as you can obtain from
4919++ // e.g. reflection::AddFlatBuffer().
4920++ void MutateOffset(uoffset_t i, const uint8_t *val) {
4921++ FLATBUFFERS_ASSERT(i < size());
4922++ static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
4923++ WriteScalar(data() + i,
4924++ static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
4925++ }
4926++
4927++ // Get a mutable pointer to tables/strings inside this vector.
4928++ mutable_return_type GetMutableObject(uoffset_t i) const {
4929++ FLATBUFFERS_ASSERT(i < size());
4930++ return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
4931++ }
4932++
4933++ // The raw data in little endian format. Use with care.
4934++ const uint8_t *Data() const {
4935++ return reinterpret_cast<const uint8_t *>(&length_ + 1);
4936++ }
4937++
4938++ uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
4939++
4940++ // Similarly, but typed, much like std::vector::data
4941++ const T *data() const { return reinterpret_cast<const T *>(Data()); }
4942++ T *data() { return reinterpret_cast<T *>(Data()); }
4943++
4944++ template<typename K> return_type LookupByKey(K key) const {
4945++ void *search_result = std::bsearch(
4946++ &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
4947++
4948++ if (!search_result) {
4949++ return nullptr; // Key not found.
4950++ }
4951++
4952++ const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
4953++
4954++ return IndirectHelper<T>::Read(element, 0);
4955++ }
4956++
4957++ protected:
4958++ // This class is only used to access pre-existing data. Don't ever
4959++ // try to construct these manually.
4960++ Vector();
4961++
4962++ uoffset_t length_;
4963++
4964++ private:
4965++ // This class is a pointer. Copying will therefore create an invalid object.
4966++ // Private and unimplemented copy constructor.
4967++ Vector(const Vector &);
4968++
4969++ template<typename K> static int KeyCompare(const void *ap, const void *bp) {
4970++ const K *key = reinterpret_cast<const K *>(ap);
4971++ const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
4972++ auto table = IndirectHelper<T>::Read(data, 0);
4973++
4974++ // std::bsearch compares with the operands transposed, so we negate the
4975++ // result here.
4976++ return -table->KeyCompareWithValue(*key);
4977++ }
4978++};
4979++
4980++// Represent a vector much like the template above, but in this case we
4981++// don't know what the element types are (used with reflection.h).
4982++class VectorOfAny {
4983++ public:
4984++ uoffset_t size() const { return EndianScalar(length_); }
4985++
4986++ const uint8_t *Data() const {
4987++ return reinterpret_cast<const uint8_t *>(&length_ + 1);
4988++ }
4989++ uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
4990++
4991++ protected:
4992++ VectorOfAny();
4993++
4994++ uoffset_t length_;
4995++
4996++ private:
4997++ VectorOfAny(const VectorOfAny &);
4998++};
4999++
5000++#ifndef FLATBUFFERS_CPP98_STL
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches