@photivra/engine 2.20.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +295 -1
- package/CITATION.cff +1 -1
- package/README.md +7 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +18 -0
- package/dist/capture/c2pa-embed.d.ts +116 -0
- package/dist/capture/c2pa-embed.js +493 -0
- package/dist/capture/c2pa-embed.js.map +1 -0
- package/dist/capture/dng-import.d.ts +73 -8
- package/dist/capture/dng-import.js +315 -80
- package/dist/capture/dng-import.js.map +1 -1
- package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
- package/dist/capture/dng-opcodes.d.ts +96 -0
- package/dist/capture/dng-opcodes.js +391 -0
- package/dist/capture/dng-opcodes.js.map +1 -0
- package/dist/capture/dng-profile-maps.d.ts +99 -0
- package/dist/capture/dng-profile-maps.js +381 -0
- package/dist/capture/dng-profile-maps.js.map +1 -0
- package/dist/capture/dng-stage-image.d.ts +23 -0
- package/dist/capture/dng-stage-image.js +65 -0
- package/dist/capture/dng-stage-image.js.map +1 -0
- package/dist/capture/exposure-build-up-stage.d.ts +16 -0
- package/dist/capture/exposure-build-up-stage.js +4 -0
- package/dist/capture/exposure-build-up-stage.js.map +1 -0
- package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
- package/dist/capture/jpeg-xl-tiles.js +151 -0
- package/dist/capture/jpeg-xl-tiles.js.map +1 -0
- package/dist/capture/lossy-jpeg.d.ts +17 -0
- package/dist/capture/lossy-jpeg.js +369 -0
- package/dist/capture/lossy-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +2 -1
- package/dist/capture/native-environment-lean.js +41 -73
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.js +4 -3
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +2 -1
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw.d.ts +3 -2
- package/dist/capture/native-raw.js +5 -4
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +4 -1
- package/dist/capture/sensor-raw-producer.js +12 -3
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/neighbor-highlight-reconstruction.d.ts +66 -0
- package/dist/color/neighbor-highlight-reconstruction.js +234 -0
- package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +5 -0
- package/dist/color/sensor-color-development.js +7 -1
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/spectral-spikiness.d.ts +11 -0
- package/dist/color/spectral-spikiness.js +23 -0
- package/dist/color/spectral-spikiness.js.map +1 -0
- package/dist/core/execution-error.d.ts +21 -0
- package/dist/core/execution-error.js +12 -0
- package/dist/core/execution-error.js.map +1 -0
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +3 -2
- package/dist/equipment/generic-lens-catalogue.js +18 -5
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +32 -0
- package/dist/equipment/generic-tier-assets.js +16 -11
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/sensor-profile-body.d.ts +78 -0
- package/dist/equipment/sensor-profile-body.js +77 -0
- package/dist/equipment/sensor-profile-body.js.map +1 -0
- package/dist/equipment/sensor-profiles.d.ts +8 -0
- package/dist/equipment/sensor-profiles.js +82 -0
- package/dist/equipment/sensor-profiles.js.map +1 -0
- package/dist/facade/catalogue-lens-signal.d.ts +28 -3
- package/dist/facade/catalogue-lens-signal.js +83 -78
- package/dist/facade/catalogue-lens-signal.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +2 -1
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/defocus-image-space-provider.d.ts +7 -0
- package/dist/facade/defocus-image-space-provider.js +64 -76
- package/dist/facade/defocus-image-space-provider.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +1 -1
- package/dist/facade/diffraction-provider.js +4 -4
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +39 -5
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +19 -6
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.js +25 -23
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view-normal.d.ts +15 -0
- package/dist/facade/display-view-normal.js +44 -0
- package/dist/facade/display-view-normal.js.map +1 -0
- package/dist/facade/display-view-rendering.d.ts +97 -0
- package/dist/facade/display-view-rendering.js +598 -0
- package/dist/facade/display-view-rendering.js.map +1 -0
- package/dist/facade/display-view.d.ts +37 -65
- package/dist/facade/display-view.js +152 -499
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +3 -1
- package/dist/facade/expected-signal-setup.js +3 -3
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +47 -14
- package/dist/facade/expected-signal.js +117 -112
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/exposure-build-up.d.ts +70 -0
- package/dist/facade/exposure-build-up.js +164 -0
- package/dist/facade/exposure-build-up.js.map +1 -0
- package/dist/facade/fast-methods.d.ts +1 -1
- package/dist/facade/fast-methods.js +46 -9
- package/dist/facade/fast-methods.js.map +1 -1
- package/dist/facade/generic-lens-capture.d.ts +3 -3
- package/dist/facade/generic-lens-capture.js +3 -3
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/image-plane-enable.d.ts +7 -0
- package/dist/facade/image-plane-enable.js +17 -0
- package/dist/facade/image-plane-enable.js.map +1 -0
- package/dist/facade/image-plane-lattice-data.d.ts +6 -0
- package/dist/facade/image-plane-lattice-data.js +10 -0
- package/dist/facade/image-plane-lattice-data.js.map +1 -0
- package/dist/facade/image-plane-support.d.ts +33 -0
- package/dist/facade/image-plane-support.js +11 -0
- package/dist/facade/image-plane-support.js.map +1 -0
- package/dist/facade/image-plane.d.ts +36 -0
- package/dist/facade/image-plane.js +384 -0
- package/dist/facade/image-plane.js.map +1 -0
- package/dist/facade/mixed-illumination.d.ts +108 -0
- package/dist/facade/mixed-illumination.js +174 -0
- package/dist/facade/mixed-illumination.js.map +1 -0
- package/dist/facade/on-demand-kits.d.ts +14 -0
- package/dist/facade/on-demand-kits.js +36 -0
- package/dist/facade/on-demand-kits.js.map +1 -0
- package/dist/facade/opt-in-kit.d.ts +9 -0
- package/dist/facade/opt-in-kit.js +11 -0
- package/dist/facade/opt-in-kit.js.map +1 -0
- package/dist/facade/quality-kit.d.ts +21 -0
- package/dist/facade/quality-kit.js +23 -0
- package/dist/facade/quality-kit.js.map +1 -0
- package/dist/facade/quality-paths.d.ts +22 -0
- package/dist/facade/quality-paths.js +44 -0
- package/dist/facade/quality-paths.js.map +1 -0
- package/dist/facade/representative-light-sources.d.ts +72 -0
- package/dist/facade/representative-light-sources.js +124 -0
- package/dist/facade/representative-light-sources.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +145 -4
- package/dist/facade/scene-radiance.js +50 -13
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +68 -20
- package/dist/facade/simulate-capture.js +399 -146
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +10 -12
- package/dist/facade/simulate-display-view.js +70 -53
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +13 -1
- package/dist/gpu/chart-composite-gpu.js +48 -9
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +4 -30
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
- package/dist/gpu/display-view-composite-material-module.js +39 -13
- package/dist/gpu/display-view-composite-material-module.js.map +1 -1
- package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
- package/dist/gpu/display-view-gpu-renderer.js +134 -0
- package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
- package/dist/gpu/display-view-image-material-module.d.ts +87 -0
- package/dist/gpu/display-view-image-material-module.js +361 -0
- package/dist/gpu/display-view-image-material-module.js.map +1 -0
- package/dist/gpu/display-view-image-quality.d.ts +87 -0
- package/dist/gpu/display-view-image-quality.js +625 -0
- package/dist/gpu/display-view-image-quality.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +80 -65
- package/dist/gpu/display-view-quality-gpu.js +187 -445
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.d.ts +67 -19
- package/dist/gpu/display-view-speed-gpu.js +181 -105
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/image-kernel-accelerator.js +3 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +2 -13
- package/dist/gpu/image-kernel-execution.js +2 -10
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +8 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js +21 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
- package/dist/gpu/wgsl-display-view-coupled.d.ts +88 -0
- package/dist/gpu/wgsl-display-view-coupled.js +353 -0
- package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +33 -24
- package/dist/gpu/wgsl-display-view-quality-kernel.js +166 -146
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +19 -44
- package/dist/gpu/wgsl-display-view-speed-kernel.js +116 -18
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
- package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
- package/dist/gpu/wgsl-exact-sum.js +42 -0
- package/dist/gpu/wgsl-exact-sum.js.map +1 -0
- package/dist/index.d.ts +22 -6
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/motion/subject-motion.d.ts +66 -0
- package/dist/motion/subject-motion.js +52 -0
- package/dist/motion/subject-motion.js.map +1 -0
- package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
- package/dist/optics/generic-lens-lateral-color.js +77 -0
- package/dist/optics/generic-lens-lateral-color.js.map +1 -0
- package/dist/optics/generic-lens-psf.js +54 -46
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +7 -0
- package/dist/optics/lens-psf-profile.js +2 -1
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/output/camera-channel-response.d.ts +50 -0
- package/dist/output/camera-channel-response.js +69 -0
- package/dist/output/camera-channel-response.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +19 -5
- package/dist/output/developed-lens-corrections.js +28 -9
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +41 -5
- package/dist/output/generic-lens-corrections.js +52 -8
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.js +5 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/print-plan.d.ts +41 -5
- package/dist/output/print-plan.js +59 -14
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/sdr-rendering.d.ts +18 -1
- package/dist/output/sdr-rendering.js +39 -2
- package/dist/output/sdr-rendering.js.map +1 -1
- package/dist/sensor/binomial-sample.d.ts +3 -0
- package/dist/sensor/binomial-sample.js +86 -0
- package/dist/sensor/binomial-sample.js.map +1 -0
- package/dist/sensor/native-sensor-report.d.ts +10 -0
- package/dist/sensor/native-sensor-report.js +16 -0
- package/dist/sensor/native-sensor-report.js.map +1 -0
- package/dist/sensor/sensor-characteristics.d.ts +91 -13
- package/dist/sensor/sensor-characteristics.js +30 -15
- package/dist/sensor/sensor-characteristics.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +214 -4
- package/docs/QUICK_START.md +162 -8
- package/docs/USAGE.md +195 -22
- package/docs/api/capture-c2pa-embed.md +177 -0
- package/docs/api/capture-dng-import.md +86 -10
- package/docs/api/capture-dng-opcodes.md +93 -0
- package/docs/api/capture-dng-profile-maps.md +141 -0
- package/docs/api/capture-dng-stage-image.md +43 -0
- package/docs/api/capture-jpeg-xl-tiles.md +33 -0
- package/docs/api/capture-lossy-jpeg.md +41 -0
- package/docs/api/capture-native-raw-development.md +2 -1
- package/docs/api/core-execution-error.md +43 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +10 -5
- package/docs/api/equipment-sensor-profile-body.md +64 -0
- package/docs/api/equipment-sensor-profiles.md +86 -0
- package/docs/api/exports.json +460 -5
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-display-view.md +11 -15
- package/docs/api/facade-exposure-build-up.md +105 -0
- package/docs/api/facade-fast-methods.md +47 -10
- package/docs/api/facade-image-plane-enable.md +16 -0
- package/docs/api/facade-mixed-illumination.md +67 -0
- package/docs/api/facade-quality-paths.md +24 -0
- package/docs/api/facade-representative-light-sources.md +131 -0
- package/docs/api/facade-scene-radiance.md +54 -3
- package/docs/api/facade-simulate-capture.md +48 -11
- package/docs/api/facade-simulate-display-view.md +10 -12
- package/docs/api/gpu-image-kernel-execution.md +0 -36
- package/docs/api/motion-subject-motion.md +23 -0
- package/docs/api/optics-generic-lens-lateral-color.md +79 -0
- package/docs/api/output-camera-channel-response.md +55 -0
- package/docs/api/output-developed-lens-corrections.md +10 -1
- package/docs/api/output-generic-lens-corrections.md +40 -4
- package/docs/api/output-print-plan.md +35 -1
- package/docs/api/output-sdr-rendering.md +6 -1
- package/docs/api/sensor-sensor-characteristics.md +54 -2
- package/llms.txt +3 -0
- package/package.json +6 -5
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# capture/dng-opcodes.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## applyDngOpcodes
|
|
6
|
+
|
|
7
|
+
Applies an opcode list to a stage image in place (WarpRectilinear returns a new buffer in `image.data`). Returns one assumption
|
|
8
|
+
per opcode: what was applied, or why it was not.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
export function applyDngOpcodes(image: DngStageImage, opcodes: readonly DngOpcode[], options: ApplyDngOpcodesOptions): string[];
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
15
|
+
|
|
16
|
+
## ApplyDngOpcodesOptions
|
|
17
|
+
|
|
18
|
+
Options of {@link applyDngOpcodes}.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
export interface ApplyDngOpcodesOptions {
|
|
22
|
+
/** 1, 2 or 3: the list's stage (for the report). */
|
|
23
|
+
stage: 1 | 2 | 3;
|
|
24
|
+
/**
|
|
25
|
+
* WarpRectilinear resampling: false (full quality) uses cubic convolution (Keys, a = −0.75, the DNG SDK's kernel); true uses
|
|
26
|
+
* bilinear interpolation (fast). Registered as "dngImport.warpRectilinear" in SIMULATE_CAPTURE_FAST_METHODS.
|
|
27
|
+
*/
|
|
28
|
+
fast: boolean;
|
|
29
|
+
/** 1, or 0.5 for a half-size image: pixel-coordinate parameters are scaled; pitched areas and bad pixels are then not applied. */
|
|
30
|
+
scale?: 1 | 0.5;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## DngOpcode
|
|
35
|
+
|
|
36
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
export interface DngOpcode {
|
|
40
|
+
id: number;
|
|
41
|
+
/** The specification's name, or "Unknown". */
|
|
42
|
+
name: string;
|
|
43
|
+
dngVersion: [number, number, number, number];
|
|
44
|
+
/** Flag bit 0: a reader may skip it. */
|
|
45
|
+
optional: boolean;
|
|
46
|
+
/** Flag bit 1: may be skipped for preview-quality rendering. */
|
|
47
|
+
previewSkip: boolean;
|
|
48
|
+
/** Decoded parameters of an applied opcode; null for one this reader does not apply. */
|
|
49
|
+
parameters: DngOpcodeParameters | null;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## DngOpcodeArea
|
|
54
|
+
|
|
55
|
+
The rectangle, plane range and pitch an area-based opcode acts on (stage pixel coordinates, bottom and right exclusive).
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
export interface DngOpcodeArea { top: number; left: number; bottom: number; right: number; plane: number; planes: number; rowPitch: number; colPitch: number }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## DngOpcodeParameters
|
|
62
|
+
|
|
63
|
+
Opcode parameters, by opcode.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
export type DngOpcodeParameters =
|
|
67
|
+
| { opcode: "WarpRectilinear"; planes: { radial: [number, number, number, number]; tangential: [number, number] }[]; centerX: number; centerY: number }
|
|
68
|
+
| { opcode: "FixVignetteRadial"; coefficients: [number, number, number, number, number]; centerX: number; centerY: number }
|
|
69
|
+
| { opcode: "FixBadPixelsConstant"; constant: number; bayerPhase: number }
|
|
70
|
+
| { opcode: "FixBadPixelsList"; bayerPhase: number; points: [number, number][]; rects: [number, number, number, number][] }
|
|
71
|
+
| { opcode: "MapTable"; area: DngOpcodeArea; table: Uint16Array }
|
|
72
|
+
| { opcode: "MapPolynomial"; area: DngOpcodeArea; coefficients: number[] }
|
|
73
|
+
| { opcode: "GainMap"; area: DngOpcodeArea; pointsV: number; pointsH: number; spacingV: number; spacingH: number; originV: number; originH: number; mapPlanes: number; gains: Float32Array }
|
|
74
|
+
| { opcode: "DeltaPerRow" | "DeltaPerColumn" | "ScalePerRow" | "ScalePerColumn"; area: DngOpcodeArea; values: Float32Array };
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## DngStageImage
|
|
78
|
+
|
|
79
|
+
A stage image: interleaved (row, column, plane), normalized values.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
export interface DngStageImage { width: number; height: number; planes: number; data: Float32Array }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## parseDngOpcodeList
|
|
86
|
+
|
|
87
|
+
Parses an opcode list (the tag's bytes). Every count and length is checked against the bytes before allocation.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
export function parseDngOpcodeList(bytes: Uint8Array): DngOpcode[];
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# capture/dng-profile-maps.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## applyDngProfileGainTableMap
|
|
6
|
+
|
|
7
|
+
Applies ProfileGainTableMap(2): at each pixel the weight t = clamp(w·(R, G, B, min, max)·2^BaselineExposure, 0, 1)^γ selects a
|
|
8
|
+
gain by linear interpolation at t·N in the table (index clamped to N − 1, SDK), bilinear between map points at the pixel centre's
|
|
9
|
+
relative position (held at the map's edges); R, G and B are multiplied by it.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
export function applyDngProfileGainTableMap(input: ApplyDngProfileGainTableMapInput): void;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
16
|
+
|
|
17
|
+
## ApplyDngProfileGainTableMapInput
|
|
18
|
+
|
|
19
|
+
Options of {@link applyDngProfileGainTableMap}.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
export interface ApplyDngProfileGainTableMapInput {
|
|
23
|
+
/** Linear ProPhoto (RIMM, D50) RGB, white-balanced, 1 = clipping white; changed in place. */
|
|
24
|
+
image: DngRgbImage;
|
|
25
|
+
map: DngProfileGainTableMap;
|
|
26
|
+
/** BaselineExposure (stops) not yet applied to `image`: the weight is scaled by 2^stops, as the SDK does. Default 0. */
|
|
27
|
+
baselineExposureStops?: number;
|
|
28
|
+
/** Where `image` sits in the stage-3 (ActiveArea) image the map spans. Default: `image` is the whole stage-3 image. */
|
|
29
|
+
region?: { x: number; y: number; stageWidth: number; stageHeight: number };
|
|
30
|
+
/** Keep values above 1 (true) or clip to 0..1 (false, the SDR default). */
|
|
31
|
+
overrange?: boolean;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## applyDngRgbTables
|
|
36
|
+
|
|
37
|
+
Applies RGBTables: each table maps ProPhoto RGB into its own primaries (clipped to 0..1, the clipped-off part kept and added back
|
|
38
|
+
when GamutExtension is "extend"), encodes it with the table's gamma, interpolates tetrahedrally in the 3D table, decodes and maps
|
|
39
|
+
back (SDK `RefRGBtoRGBTable3D`). The background table (empty name) applies to the whole image. Weighted sum: each masked table's
|
|
40
|
+
result weighted by its mask, the background (the background table's result, or the input) by 1 − min(1, Σ masks), normalized.
|
|
41
|
+
Sequential: each table in file order, blended into the running image by its mask (the background table by 1 − min(1, Σ other masks)).
|
|
42
|
+
A table whose mask is not supplied is skipped (as the SDK skips a name with no SemanticMask); the returned notes say so.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
export function applyDngRgbTables(input: ApplyDngRgbTablesInput): string[];
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
49
|
+
|
|
50
|
+
## ApplyDngRgbTablesInput
|
|
51
|
+
|
|
52
|
+
Options of {@link applyDngRgbTables}.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
export interface ApplyDngRgbTablesInput {
|
|
56
|
+
/** ProPhoto-primaries RGB after the tone curve, 0..1; changed in place. */
|
|
57
|
+
image: DngRgbImage;
|
|
58
|
+
tables: DngRgbTables;
|
|
59
|
+
/** Semantic masks by name (values 0..1, any size; stretched over the image with bilinear interpolation). */
|
|
60
|
+
masks?: readonly { name: string; width: number; height: number; data: Float32Array }[];
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## DngProfileGainTableMap
|
|
65
|
+
|
|
66
|
+
A parsed ProfileGainTableMap(2): N gains at each of V × H map points, decoded to 32-bit floats.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
export interface DngProfileGainTableMap {
|
|
70
|
+
/** 1 for ProfileGainTableMap (52525), 2 for ProfileGainTableMap2 (52544). */
|
|
71
|
+
version: 1 | 2;
|
|
72
|
+
pointsV: number; pointsH: number; spacingV: number; spacingH: number; originV: number; originH: number;
|
|
73
|
+
/** MapPointsN: the table length at each map point. */
|
|
74
|
+
tablePoints: number;
|
|
75
|
+
/** MapInputWeights for red, green, blue, min(R,G,B) and max(R,G,B). */
|
|
76
|
+
inputWeights: [number, number, number, number, number];
|
|
77
|
+
/** PGTM2: the weight's gamma (1 for version 1). */
|
|
78
|
+
gamma: number;
|
|
79
|
+
/** Gains, row-major (v, h, table point). */
|
|
80
|
+
gains: Float32Array;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## DngRgbImage
|
|
85
|
+
|
|
86
|
+
An RGB image, interleaved (row, column, channel).
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
export interface DngRgbImage { width: number; height: number; data: Float32Array }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## DngRgbTable
|
|
93
|
+
|
|
94
|
+
One table of RGBTables: a 3D table of `divisions`³ RGB samples (16-bit, 65535 = 1).
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
export interface DngRgbTable {
|
|
98
|
+
/** TableSemanticName: the semantic mask it applies within; "" for the background table (the whole image). */
|
|
99
|
+
semanticName: string;
|
|
100
|
+
divisions: number;
|
|
101
|
+
gamma: "linear" | "srgb" | "1.8" | "2.2" | "rec2020";
|
|
102
|
+
primaries: "srgb" | "adobe-rgb" | "display-p3" | "rec2020" | "prophoto";
|
|
103
|
+
gamut: "clip" | "extend";
|
|
104
|
+
/** RGB per node, red slowest then green then blue, length divisions³ × 3. */
|
|
105
|
+
samples: Uint16Array;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## DngRgbTables
|
|
110
|
+
|
|
111
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
export interface DngRgbTables { compositeMethod: "weighted-sum" | "sequential"; tables: DngRgbTable[] }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## parseDngProfileGainTableMap
|
|
118
|
+
|
|
119
|
+
Parses ProfileGainTableMap (version 1) or ProfileGainTableMap2 (version 2). Layout: MapPointsV, MapPointsH (LONG), MapSpacingV,
|
|
120
|
+
MapSpacingH, MapOriginV, MapOriginH (DOUBLE), MapPointsN (LONG), MapInputWeights (5 FLOAT); version 2 adds DataType (LONG: 0 uint8,
|
|
121
|
+
1 uint16, 2 float16, 3 float32), Gamma, GainMin, GainMax (FLOAT); then the gains. Integer gains are GainMin + (x/max)·(GainMax −
|
|
122
|
+
GainMin). A single map point on an axis has spacing 1 and origin 0 (SDK).
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
export function parseDngProfileGainTableMap(bytes: Uint8Array, littleEndian: boolean, version: 1 | 2): DngProfileGainTableMap;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
129
|
+
|
|
130
|
+
## parseDngRgbTables
|
|
131
|
+
|
|
132
|
+
Parses RGBTables (52543): table count (LONG, at most 20; 0 means none), CompositeMethod (LONG: 0 weighted sum, 1 sequential), then
|
|
133
|
+
per table LengthTableSemanticName (SHORT), the name's bytes, Divisions, PixelType (0 uint8, 1 uint16, 2 float32), GammaEncoding
|
|
134
|
+
(0 linear, 1 sRGB, 2 γ 1.8, 3 γ 2.2, 4 Rec. 2020), ColorPrimaries (0 sRGB, 1 Adobe RGB, 2 P3, 3 Rec. 2020, 4 ProPhoto) and
|
|
135
|
+
GamutExtension (0 clip, 1 extend), each a BYTE, then Divisions³ RGB samples (uint8 scaled by 256, float scaled by 65535).
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
export function parseDngRgbTables(bytes: Uint8Array, littleEndian: boolean): DngRgbTables | null;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# capture/dng-stage-image.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## developDngStageImage
|
|
6
|
+
|
|
7
|
+
Builds the stage-2 (CFA) or stage-3 (LinearRaw) image of an imported DNG, normalized 0..1, interleaved by sample.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
export function developDngStageImage(raw: ImportedDngRaw, options: DevelopDngStageImageOptions = {}): DngStageImageResult;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
14
|
+
|
|
15
|
+
## DevelopDngStageImageOptions
|
|
16
|
+
|
|
17
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
export interface DevelopDngStageImageOptions {
|
|
21
|
+
/** The output the development is for ("srgb-8" or "srgb-16" on screen; "dng", "jpeg" or "png" exports). Default "srgb-8" (fast; owner, 2026-11-11). */
|
|
22
|
+
format?: "srgb-8" | "srgb-16" | "dng" | "jpeg" | "png";
|
|
23
|
+
/** The speed-versus-accuracy choice (WarpRectilinear resampling); default from `format` (fast on screen, full for exports). */
|
|
24
|
+
fast?: boolean;
|
|
25
|
+
/** Apply the opcode lists (default true). */
|
|
26
|
+
opcodes?: boolean;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## DngStageImageResult
|
|
31
|
+
|
|
32
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
export interface DngStageImageResult extends DngStageImage {
|
|
36
|
+
/** 3 for LinearRaw (every opcode list applied), 2 for a CFA mosaic (OpcodeList3 left to the caller). */
|
|
37
|
+
stage: 2 | 3;
|
|
38
|
+
/** The resolved `fast` and where it came from. */
|
|
39
|
+
fast: { requested: boolean; defaultedFrom: "request" | "format" };
|
|
40
|
+
/** What was applied and what was not. */
|
|
41
|
+
assumptions: string[];
|
|
42
|
+
}
|
|
43
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# capture/jpeg-xl-tiles.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## createJxlOxideDngDecoder
|
|
6
|
+
|
|
7
|
+
A {@link DngJpegXlDecoder} over jxl-oxide-wasm: `forceSrgb` off (the samples stay in the codestream's encoding), one render per
|
|
8
|
+
tile, and the image object freed after it. Usage: `import init, * as jxl from "jxl-oxide-wasm"; await init();
|
|
9
|
+
createJxlOxideDngDecoder(jxl)`.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
export function createJxlOxideDngDecoder(module: JxlOxideModule): DngJpegXlDecoder;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
16
|
+
|
|
17
|
+
## DngJpegXlDecoder
|
|
18
|
+
|
|
19
|
+
Decodes one JPEG XL codestream (a DNG strip or tile) to PNG bytes in the codestream's own colour encoding (no colour conversion).
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
export type DngJpegXlDecoder = (codestream: Uint8Array) => Uint8Array | Promise<Uint8Array>;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## JxlOxideModule
|
|
26
|
+
|
|
27
|
+
The part of the jxl-oxide-wasm module the adapter uses (its `JxlImage` class, after the module's `init`).
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
export interface JxlOxideModule {
|
|
31
|
+
JxlImage: new () => { feedBytes(bytes: Uint8Array): unknown; tryInit(): boolean; render(): { encodeToPng(): Uint8Array }; forceSrgb: boolean; free(): void };
|
|
32
|
+
}
|
|
33
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# capture/lossy-jpeg.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## LossyJpegImage
|
|
6
|
+
|
|
7
|
+
Decoded samples, interleaved by component within each line (line, x, component), 0..255.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
export interface LossyJpegImage {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
components: number;
|
|
14
|
+
/** "ycbcr-to-rgb" when three YCbCr components were converted to RGB; "none" otherwise. */
|
|
15
|
+
colorTransform: "ycbcr-to-rgb" | "none";
|
|
16
|
+
samples: Uint8Array;
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## LossyJpegLimits
|
|
21
|
+
|
|
22
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
export interface LossyJpegLimits {
|
|
26
|
+
/** Largest width x height x components accepted, checked before any sample buffer is allocated. */
|
|
27
|
+
maximumSamples: number;
|
|
28
|
+
/** An abbreviated table-specification stream (SOI, DQT/DHT, EOI) read before `bytes`, as DNG's JPEGTables tag (347) supplies. */
|
|
29
|
+
tables?: Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## parseLossyJpeg
|
|
34
|
+
|
|
35
|
+
Decodes one DCT JPEG stream (see the module notes). Every length, count and table index is checked against the buffer.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
export function parseLossyJpeg(bytes: Uint8Array, limits: LossyJpegLimits): LossyJpegImage;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
@@ -136,7 +136,8 @@ RAW saturation handled before white balance. Counts are pixels or samples of the
|
|
|
136
136
|
|
|
137
137
|
```ts
|
|
138
138
|
export interface RawHighlightDiagnostics {
|
|
139
|
-
|
|
139
|
+
/** #602: "reconstruct-neighbors" from `simulateCapture`'s whole-image neighbor reconstruction. */
|
|
140
|
+
mode: RawHighlightMode | "reconstruct-neighbors";
|
|
140
141
|
/** Output pixels with at least one contributing site at or above its white level, or flagged as saturated. */
|
|
141
142
|
saturatedPixelCount: number;
|
|
142
143
|
/** `clip`: WB-scaled samples clipped at the smallest gain. Always 0 for `reconstruct`. */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# core/execution-error.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## ImageKernelExecutionError
|
|
6
|
+
|
|
7
|
+
Domain error for getting and running a backend. Input validation still throws the engine's existing errors.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
export class ImageKernelExecutionError extends Error {
|
|
11
|
+
readonly code = "IMAGE_KERNEL_EXECUTION";
|
|
12
|
+
readonly reason: ImageKernelFailureReason;
|
|
13
|
+
|
|
14
|
+
constructor(reason: ImageKernelFailureReason, message: string) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "ImageKernelExecutionError";
|
|
17
|
+
this.reason = reason;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ImageKernelFailureReason
|
|
23
|
+
|
|
24
|
+
Failure classes reported by {@link ImageKernelExecutionError}. `conformance-failed` (#481): a device failed the display view's
|
|
25
|
+
run-time self-check with `gpu: "require"`. `quality-code-unavailable` (2.22.0, #594): on-demand full-quality code could not be
|
|
26
|
+
loaded (for example a failed chunk download); `prepareQualityPaths()` rejects with it, a display-view render with `gpu: "require"`
|
|
27
|
+
fails with it (with `gpu: "auto"` it runs the CPU reference), and a CPU request whose full-quality or opt-in code does not load
|
|
28
|
+
fails with it (nothing is remembered: the next request tries again).
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
export type ImageKernelFailureReason = ImageKernelFallbackReason | "device-lost" | "out-of-memory" | "gpu-validation" |
|
|
32
|
+
"aborted" | "disposed" | "busy" | "unsupported-on-backend" | "unsupported-float32-domain" | "indeterminate-float32-classification" | "conformance-failed" |
|
|
33
|
+
"quality-code-unavailable";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## ImageKernelFallbackReason
|
|
37
|
+
|
|
38
|
+
Why a requested `webgpu-f32` backend ran the CPU reference instead. `webgpu-disabled`: `setWebGpuEnabled(false)` in this realm.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
export type ImageKernelFallbackReason = "webgpu-unavailable" | "webgpu-disabled" | "adapter-unavailable" | "device-request-failed" |
|
|
42
|
+
"insufficient-limits" | "unsupported-platform-endianness";
|
|
43
|
+
```
|
package/docs/api/core-version.md
CHANGED
|
@@ -11,5 +11,5 @@ version they were made with. Proof-of-concept (POC), schema and model contracts
|
|
|
11
11
|
own versions. Release checks confirm it matches package.json and the packed package.
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
ENGINE_API_VERSION = "2.
|
|
14
|
+
ENGINE_API_VERSION = "2.22.0" as const
|
|
15
15
|
```
|
|
@@ -4,11 +4,11 @@ The package and root API versions are recorded once in [Navigation](../API_REFER
|
|
|
4
4
|
|
|
5
5
|
## GENERIC_LENS_CATALOGUE
|
|
6
6
|
|
|
7
|
-
The
|
|
7
|
+
The 33 lenses: 17 professional, 13 consumer and (#554) 3 phone lenses, each set by focal length.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
GENERIC_LENS_CATALOGUE: readonly GenericLensCatalogueEntry[] = Object.freeze([...PRO.map((row) => entry("professional", row)),
|
|
11
|
-
...CONSUMER.map((row) => entry("consumer", row))])
|
|
11
|
+
...CONSUMER.map((row) => entry("consumer", row)), ...PHONE.map((row) => entry("phone", row))])
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## GENERIC_LENS_IDS
|
|
@@ -30,7 +30,12 @@ GENERIC_LENS_SET_BASELINES: Readonly<Record<GenericLensSet, Readonly<GenericLens
|
|
|
30
30
|
breathingFraction: -0.03, focusScatterDepthOfFocusFraction: 0.1, closeFocusFactor: 0.15 }),
|
|
31
31
|
consumer: Object.freeze({ sphericalWaves: 0.5, comaWaves: 1.0, astigmatismWaves: 0.8, fieldCurvatureWaves: 0.45, axialColorWaves: 0.4,
|
|
32
32
|
lateralColorFraction: 0.0003, distortionMagnitude: 0.03, naturalVignettingStops: 0.7, opticalVignettingStops: 1.1, veilingGlareFraction: 0.02, ghostFraction: 0.008,
|
|
33
|
-
breathingFraction: -0.08, focusScatterDepthOfFocusFraction: 0.3, closeFocusFactor: 0.5 })
|
|
33
|
+
breathingFraction: -0.08, focusScatterDepthOfFocusFraction: 0.3, closeFocusFactor: 0.5 }),
|
|
34
|
+
// #554: design values (docs/LENS_CATALOGUE.md, "Phone lenses"): the consumer baseline with the stronger fall-off, flare and distortion
|
|
35
|
+
// (corrected in software on phones) of small fixed-aperture phone lenses, and no optical-vignetting change (the aperture is fixed).
|
|
36
|
+
phone: Object.freeze({ sphericalWaves: 0.5, comaWaves: 1.0, astigmatismWaves: 0.8, fieldCurvatureWaves: 0.5, axialColorWaves: 0.3,
|
|
37
|
+
lateralColorFraction: 0.0004, distortionMagnitude: 0.03, naturalVignettingStops: 1.2, opticalVignettingStops: 0.5, veilingGlareFraction: 0.03, ghostFraction: 0.01,
|
|
38
|
+
breathingFraction: -0.05, focusScatterDepthOfFocusFraction: 0.3, closeFocusFactor: 0.5 })
|
|
34
39
|
})
|
|
35
40
|
```
|
|
36
41
|
|
|
@@ -179,10 +184,10 @@ export type GenericLensKind = "standard" | "macro" | "fisheye";
|
|
|
179
184
|
|
|
180
185
|
## GenericLensSet
|
|
181
186
|
|
|
182
|
-
|
|
187
|
+
#554: "phone", the three fixed lenses of a phone sensor profile (`sensor.profile` with `fixedLenses: "phone"`).
|
|
183
188
|
|
|
184
189
|
```ts
|
|
185
|
-
export type GenericLensSet = "professional" | "consumer";
|
|
190
|
+
export type GenericLensSet = "professional" | "consumer" | "phone";
|
|
186
191
|
```
|
|
187
192
|
|
|
188
193
|
## ResolvedGenericLens
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# equipment/sensor-profile-body.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## SENSOR_PROFILE_ISO_ANCHOR
|
|
6
|
+
|
|
7
|
+
The engine's ISO anchor (see the module comment): white charge 60 000 e⁻ at ISO 100, 36 µm², QE 0.5.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
SENSOR_PROFILE_ISO_ANCHOR = Object.freeze({ iso: 100, fullWellElectrons: 60000, pixelAreaSquareMicrometers: 36, peakQuantumEfficiency: .5 })
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## SensorProfile
|
|
14
|
+
|
|
15
|
+
One sensor profile. Every number is per photosite unless stated; see `provenance` for each value's kind.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
export interface SensorProfile {
|
|
19
|
+
id: string;
|
|
20
|
+
/** Format, resolution, architecture and era; no maker or product name. */
|
|
21
|
+
name: string;
|
|
22
|
+
/** A market category, not a specification: it is a label and changes nothing. */
|
|
23
|
+
marketTag: "consumer" | "professional";
|
|
24
|
+
architecture: "front-illuminated" | "back-illuminated" | "stacked";
|
|
25
|
+
sensorWidthMm: number; sensorHeightMm: number;
|
|
26
|
+
pixelsWide: number; pixelsHigh: number;
|
|
27
|
+
pixelPitchMicrometers: number;
|
|
28
|
+
/** The green channel's peak EQE (#555 `peakQuantumEfficiency`). */
|
|
29
|
+
peakQuantumEfficiency: number;
|
|
30
|
+
/** Full-well capacity, e⁻: the charge at the RAW white level at base ISO. */
|
|
31
|
+
fullWellElectrons: number;
|
|
32
|
+
/** Read noise, RMS e⁻; `highGainFromIso` null for one conversion gain throughout. */
|
|
33
|
+
readNoise: { lowGainElectrons: number; highGainElectrons: number; highGainFromIso: number | null };
|
|
34
|
+
/** Charge storage limit of the high conversion gain, e⁻ (null without one): full well × base ISO / switch ISO. */
|
|
35
|
+
highGainFullWellElectrons: number | null;
|
|
36
|
+
adcBitDepth: 12 | 14 | 16;
|
|
37
|
+
/** Re-rated base ISO (see the module comment) and the highest ISO setting. */
|
|
38
|
+
baseIso: number; maximumIso: number;
|
|
39
|
+
/** Largest analog gain relative to base ISO; above it the gain is digital. */
|
|
40
|
+
maximumAnalogGain: number;
|
|
41
|
+
/** Rolling readout, s: the top-to-bottom skew with `motion.shutter: "rolling"`. */
|
|
42
|
+
readoutSeconds: number;
|
|
43
|
+
/** Fixed-pattern noise used with `sensor.fixedPatternNoise` (EMVA 1288 Release 4.0 non-uniformities). */
|
|
44
|
+
fixedPattern: { prnu: number; dsnu: number; hotPixelFraction: number; hotPixelMultiplier: number; rowElectrons: number; columnElectrons: number };
|
|
45
|
+
/** What the profile is good for (text only). */
|
|
46
|
+
goodFor: readonly string[];
|
|
47
|
+
description: string;
|
|
48
|
+
/** "phone": the profile takes only the catalogue's phone lenses (`lens.catalogue`), which need it. */
|
|
49
|
+
fixedLenses: "phone" | null;
|
|
50
|
+
/**
|
|
51
|
+
* Each value's kind and source key (S1–S10, docs/SENSOR_PROFILES.md "Sources"); a value not listed is a design value.
|
|
52
|
+
* For example `fullWellElectrons: "published S1"` or `baseIso: "derived"`.
|
|
53
|
+
*/
|
|
54
|
+
provenance: Readonly<Partial<Record<keyof SensorProfile | "sensorSize" | "pixels" | "highGainFromIso", string>>>;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## SensorProfileValueKind
|
|
59
|
+
|
|
60
|
+
How a profile value was obtained: copied from a source, calculated from sourced values, or Photivra's design value.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
export type SensorProfileValueKind = "published" | "derived" | "design";
|
|
64
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# equipment/sensor-profiles.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## resolveSensorProfile
|
|
6
|
+
|
|
7
|
+
The profile record with this id (for `sensor.profile`); a clear error listing the ids otherwise.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
export function resolveSensorProfile(id: unknown): SensorProfile;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
14
|
+
|
|
15
|
+
## SENSOR_PROFILE_IDS
|
|
16
|
+
|
|
17
|
+
The profile ids, in catalogue order.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
SENSOR_PROFILE_IDS: readonly string[] = Object.freeze(SENSOR_PROFILES.map((p) => p.id))
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## SENSOR_PROFILES
|
|
24
|
+
|
|
25
|
+
The catalogue, in the issue's order. Frozen.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
SENSOR_PROFILES: readonly SensorProfile[] = Object.freeze(([
|
|
29
|
+
{ id: "full-frame-24mp-bsi-2020s", name: "Full frame 24 MP BSI, 2020s", marketTag: "consumer", architecture: "back-illuminated",
|
|
30
|
+
sensorWidthMm: 36.07, sensorHeightMm: 24.01, pixelsWide: 6072, pixelsHigh: 4042, pixelPitchMicrometers: 5.94, peakQuantumEfficiency: .8,
|
|
31
|
+
fullWellElectrons: 100000, readNoise: { lowGainElectrons: 6.4, highGainElectrons: 1.1, highGainFromIso: 500 }, highGainFullWellElectrons: 20000,
|
|
32
|
+
adcBitDepth: 14, baseIso: 100, maximumIso: 51200, maximumAnalogGain: 64, readoutSeconds: .05, fixedPattern: BSI,
|
|
33
|
+
goodFor: ["landscape", "portrait", "travel"], description: "Large pixels and a deep full well for wide dynamic range at base ISO; a moderate readout shows some rolling-shutter skew.",
|
|
34
|
+
fixedLenses: null, provenance: { ...sourced("S1", "pixels", "pixelPitchMicrometers", "peakQuantumEfficiency", "fullWellElectrons", "readNoise", "adcBitDepth"),
|
|
35
|
+
sensorSize: "derived", architecture: "published S1", highGainFromIso: "derived S1", highGainFullWellElectrons: "derived", baseIso: "derived" } },
|
|
36
|
+
{ id: "full-frame-45mp-stacked-2020s", name: "Full frame 45 MP stacked, 2020s", marketTag: "professional", architecture: "stacked",
|
|
37
|
+
sensorWidthMm: 36, sensorHeightMm: 24, pixelsWide: 8256, pixelsHigh: 5504, pixelPitchMicrometers: 4.36, peakQuantumEfficiency: .8,
|
|
38
|
+
fullWellElectrons: 69000, readNoise: { lowGainElectrons: 3.5, highGainElectrons: 1.5, highGainFromIso: 250 }, highGainFullWellElectrons: 22080,
|
|
39
|
+
adcBitDepth: 14, baseIso: 80, maximumIso: 25600, maximumAnalogGain: 64, readoutSeconds: .005, fixedPattern: BSI,
|
|
40
|
+
goodFor: ["landscape", "studio", "wildlife"], description: "High resolution with a fast stacked readout: fine detail for landscape and studio work, little rolling-shutter skew for action.",
|
|
41
|
+
fixedLenses: null, provenance: { pixelPitchMicrometers: "derived", fullWellElectrons: "design (S2 scaled by pixel area)", readNoise: "design (S2)", highGainFromIso: "design (S2)",
|
|
42
|
+
highGainFullWellElectrons: "derived", baseIso: "derived" } },
|
|
43
|
+
{ id: "full-frame-24mp-stacked-sports-2020s", name: "Full frame 24 MP stacked (sports), 2020s", marketTag: "professional", architecture: "stacked",
|
|
44
|
+
sensorWidthMm: 36, sensorHeightMm: 24, pixelsWide: 6000, pixelsHigh: 4000, pixelPitchMicrometers: 6, peakQuantumEfficiency: .8,
|
|
45
|
+
fullWellElectrons: 80000, readNoise: { lowGainElectrons: 3, highGainElectrons: 1, highGainFromIso: 400 }, highGainFullWellElectrons: 25000,
|
|
46
|
+
adcBitDepth: 14, baseIso: 125, maximumIso: 102400, maximumAnalogGain: 64, readoutSeconds: .0025, fixedPattern: BSI,
|
|
47
|
+
goodFor: ["sports", "wildlife", "journalism"], description: "The fastest readout and low high-gain read noise: almost no rolling-shutter skew and clean high ISO, at a moderate resolution.",
|
|
48
|
+
fixedLenses: null, provenance: { pixelPitchMicrometers: "derived", highGainFullWellElectrons: "derived", baseIso: "derived" } },
|
|
49
|
+
{ id: "full-frame-24mp-fsi-2010s", name: "Full frame 24 MP front-illuminated, 2010s", marketTag: "professional", architecture: "front-illuminated",
|
|
50
|
+
sensorWidthMm: 36.01, sensorHeightMm: 24.07, pixelsWide: 6032, pixelsHigh: 4032, pixelPitchMicrometers: 5.97, peakQuantumEfficiency: .53,
|
|
51
|
+
fullWellElectrons: 76000, readNoise: { lowGainElectrons: 4, highGainElectrons: 4, highGainFromIso: null }, highGainFullWellElectrons: null,
|
|
52
|
+
adcBitDepth: 14, baseIso: 80, maximumIso: 25600, maximumAnalogGain: 64, readoutSeconds: .08, fixedPattern: FSI,
|
|
53
|
+
goodFor: ["portrait", "landscape", "journalism"], description: "An older professional sensor: lower QE and one conversion gain, so a modern consumer BSI sensor beats it at high ISO; slow readout.",
|
|
54
|
+
fixedLenses: null, provenance: { ...sourced("S3", "pixels", "pixelPitchMicrometers", "peakQuantumEfficiency", "fullWellElectrons", "adcBitDepth"),
|
|
55
|
+
sensorSize: "derived", architecture: "derived S4", baseIso: "derived" } },
|
|
56
|
+
{ id: "aps-c-24mp-fsi-2020s", name: "APS-C 24 MP front-illuminated, 2020s", marketTag: "consumer", architecture: "front-illuminated",
|
|
57
|
+
sensorWidthMm: 23.55, sensorHeightMm: 15.73, pixelsWide: 6024, pixelsHigh: 4024, pixelPitchMicrometers: 3.91, peakQuantumEfficiency: .55,
|
|
58
|
+
fullWellElectrons: 36000, readNoise: { lowGainElectrons: 2.7, highGainElectrons: 2.7, highGainFromIso: null }, highGainFullWellElectrons: null,
|
|
59
|
+
adcBitDepth: 14, baseIso: 80, maximumIso: 25600, maximumAnalogGain: 64, readoutSeconds: .06, fixedPattern: FSI,
|
|
60
|
+
goodFor: ["travel", "family", "learning"], description: "A smaller, front-illuminated sensor: less light per pixel, a slower readout and more rolling-shutter skew.",
|
|
61
|
+
fixedLenses: null, provenance: { ...sourced("S5", "pixels", "pixelPitchMicrometers", "architecture", "fullWellElectrons", "readNoise", "adcBitDepth"), sensorSize: "derived", baseIso: "derived" } },
|
|
62
|
+
{ id: "aps-c-26mp-bsi-2020s", name: "APS-C 26 MP BSI, 2020s", marketTag: "professional", architecture: "back-illuminated",
|
|
63
|
+
sensorWidthMm: 23.49, sensorHeightMm: 15.7, pixelsWide: 6248, pixelsHigh: 4176, pixelPitchMicrometers: 3.76, peakQuantumEfficiency: .8,
|
|
64
|
+
fullWellElectrons: 50000, readNoise: { lowGainElectrons: 3.3, highGainElectrons: 1, highGainFromIso: 250 }, highGainFullWellElectrons: 16000,
|
|
65
|
+
adcBitDepth: 14, baseIso: 80, maximumIso: 25600, maximumAnalogGain: 64, readoutSeconds: .025, fixedPattern: BSI,
|
|
66
|
+
goodFor: ["wildlife", "sports", "travel"], description: "A BSI APS-C sensor with dual conversion gain whose readout beats the consumer full-frame profile's.",
|
|
67
|
+
fixedLenses: null, provenance: { ...sourced("S6", "pixels", "pixelPitchMicrometers", "peakQuantumEfficiency", "fullWellElectrons", "readNoise"), sensorSize: "derived",
|
|
68
|
+
architecture: "published S6", highGainFromIso: "design (S7)", highGainFullWellElectrons: "derived", baseIso: "derived" } },
|
|
69
|
+
{ id: "medium-format-100mp-bsi-16bit", name: "Medium format 100 MP BSI, 16-bit", marketTag: "professional", architecture: "back-illuminated",
|
|
70
|
+
sensorWidthMm: 43.856, sensorHeightMm: 32.9, pixelsWide: 11656, pixelsHigh: 8750, pixelPitchMicrometers: 3.76, peakQuantumEfficiency: .8,
|
|
71
|
+
fullWellElectrons: 50300, readNoise: { lowGainElectrons: 3.3, highGainElectrons: 1, highGainFromIso: 250 }, highGainFullWellElectrons: 16096,
|
|
72
|
+
adcBitDepth: 16, baseIso: 80, maximumIso: 12800, maximumAnalogGain: 64, readoutSeconds: .25, fixedPattern: BSI,
|
|
73
|
+
goodFor: ["studio", "landscape", "portrait"], description: "A large sensor with 100 MP and a 16-bit RAW; a slow readout makes its electronic shutter unsuited to motion.",
|
|
74
|
+
fixedLenses: null, provenance: { ...sourced("S7", "pixels", "pixelPitchMicrometers", "sensorSize", "fullWellElectrons", "readNoise", "adcBitDepth"), architecture: "published S8",
|
|
75
|
+
highGainFromIso: "derived S7", highGainFullWellElectrons: "derived", baseIso: "derived" } },
|
|
76
|
+
{ id: "phone-50mp-stacked", name: "Phone, large, 50 MP stacked", marketTag: "consumer", architecture: "stacked",
|
|
77
|
+
sensorWidthMm: 9.844, sensorHeightMm: 7.431, pixelsWide: 8192, pixelsHigh: 6144, pixelPitchMicrometers: 1.197, peakQuantumEfficiency: .75,
|
|
78
|
+
fullWellElectrons: 8600, readNoise: { lowGainElectrons: 3, highGainElectrons: 1.4, highGainFromIso: 160 }, highGainFullWellElectrons: 2150,
|
|
79
|
+
adcBitDepth: 12, baseIso: 40, maximumIso: 6400, maximumAnalogGain: 64, readoutSeconds: 1 / 30,
|
|
80
|
+
fixedPattern: { prnu: .008, dsnu: .3, hotPixelFraction: 2e-4, hotPixelMultiplier: 50, rowElectrons: .2, columnElectrons: .2 },
|
|
81
|
+
goodFor: ["everyday", "travel", "family"], description: "A large phone sensor: tiny pixels with a small full well, so less dynamic range and more noise per pixel; simulated as a single frame (no multi-frame stacking).",
|
|
82
|
+
fixedLenses: "phone", provenance: { ...sourced("S9", "pixels", "pixelPitchMicrometers", "sensorSize", "architecture", "adcBitDepth"), fullWellElectrons: "design (S10 scaled by pixel area)",
|
|
83
|
+
readNoise: "high gain published S10, low gain design", highGainFullWellElectrons: "derived", readoutSeconds: "derived S9 (1 / full-resolution frame rate)",
|
|
84
|
+
fixedPattern: "PRNU, row and column published S10; the rest design", baseIso: "derived" } }
|
|
85
|
+
] satisfies SensorProfile[]).map((p) => Object.freeze(p)))
|
|
86
|
+
```
|