@photivra/engine 2.16.0 → 2.17.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +24 -0
  6. package/dist/camera/lens-projection.d.ts +5 -0
  7. package/dist/camera/lens-projection.js +10 -0
  8. package/dist/camera/lens-projection.js.map +1 -1
  9. package/dist/core/version.d.ts +1 -1
  10. package/dist/core/version.js +1 -1
  11. package/dist/core/version.js.map +1 -1
  12. package/dist/equipment/generic-lens-catalogue.d.ts +227 -0
  13. package/dist/equipment/generic-lens-catalogue.js +243 -0
  14. package/dist/equipment/generic-lens-catalogue.js.map +1 -0
  15. package/dist/facade/defocus-bokeh-zones.d.ts +33 -0
  16. package/dist/facade/defocus-bokeh-zones.js +53 -0
  17. package/dist/facade/defocus-bokeh-zones.js.map +1 -0
  18. package/dist/facade/defocus-image-space-provider.d.ts +9 -0
  19. package/dist/facade/defocus-image-space-provider.js +96 -7
  20. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  21. package/dist/facade/diffraction-provider.d.ts +29 -0
  22. package/dist/facade/diffraction-provider.js +117 -11
  23. package/dist/facade/diffraction-provider.js.map +1 -1
  24. package/dist/facade/display-view-gpu-session.js +4 -0
  25. package/dist/facade/display-view-gpu-session.js.map +1 -1
  26. package/dist/facade/display-view-gpu.d.ts +10 -0
  27. package/dist/facade/display-view-gpu.js.map +1 -1
  28. package/dist/facade/display-view-lens-signal.d.ts +30 -0
  29. package/dist/facade/display-view-lens-signal.js +427 -0
  30. package/dist/facade/display-view-lens-signal.js.map +1 -0
  31. package/dist/facade/expected-signal-setup.d.ts +7 -0
  32. package/dist/facade/expected-signal-setup.js +12 -2
  33. package/dist/facade/expected-signal-setup.js.map +1 -1
  34. package/dist/facade/expected-signal.d.ts +8 -0
  35. package/dist/facade/expected-signal.js +150 -0
  36. package/dist/facade/expected-signal.js.map +1 -1
  37. package/dist/facade/generic-lens-capture.d.ts +6 -0
  38. package/dist/facade/generic-lens-capture.js +8 -0
  39. package/dist/facade/generic-lens-capture.js.map +1 -0
  40. package/dist/facade/large-defocus-lattice.d.ts +39 -0
  41. package/dist/facade/large-defocus-lattice.js +64 -0
  42. package/dist/facade/large-defocus-lattice.js.map +1 -0
  43. package/dist/facade/scene-radiance.d.ts +5 -0
  44. package/dist/facade/scene-radiance.js +5 -2
  45. package/dist/facade/scene-radiance.js.map +1 -1
  46. package/dist/facade/simulate-capture.d.ts +38 -5
  47. package/dist/facade/simulate-capture.js +306 -49
  48. package/dist/facade/simulate-capture.js.map +1 -1
  49. package/dist/facade/simulate-display-view.js +22 -16
  50. package/dist/facade/simulate-display-view.js.map +1 -1
  51. package/dist/gpu/display-view-quality-gpu.d.ts +0 -9
  52. package/dist/gpu/display-view-quality-gpu.js +6 -0
  53. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  54. package/dist/gpu/display-view-speed-gpu.js +2 -0
  55. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  56. package/dist/index.d.ts +3 -0
  57. package/dist/index.js +3 -0
  58. package/dist/index.js.map +1 -1
  59. package/dist/optics/defocus-bokeh-kernel.d.ts +207 -0
  60. package/dist/optics/defocus-bokeh-kernel.js +380 -0
  61. package/dist/optics/defocus-bokeh-kernel.js.map +1 -0
  62. package/dist/optics/defocus-disc-kernel.d.ts +41 -19
  63. package/dist/optics/defocus-disc-kernel.js +44 -23
  64. package/dist/optics/defocus-disc-kernel.js.map +1 -1
  65. package/dist/optics/generic-lens-psf.d.ts +68 -0
  66. package/dist/optics/generic-lens-psf.js +337 -0
  67. package/dist/optics/generic-lens-psf.js.map +1 -0
  68. package/dist/optics/illumination-vignetting.d.ts +6 -0
  69. package/dist/optics/illumination-vignetting.js +24 -7
  70. package/dist/optics/illumination-vignetting.js.map +1 -1
  71. package/dist/optics/sensor-environment-query.d.ts +6 -0
  72. package/dist/optics/sensor-environment-query.js +13 -6
  73. package/dist/optics/sensor-environment-query.js.map +1 -1
  74. package/dist/optics/site-kernel-runs.d.ts +77 -0
  75. package/dist/optics/site-kernel-runs.js +200 -0
  76. package/dist/optics/site-kernel-runs.js.map +1 -0
  77. package/dist/output/generic-lens-corrections.d.ts +24 -0
  78. package/dist/output/generic-lens-corrections.js +51 -0
  79. package/dist/output/generic-lens-corrections.js.map +1 -0
  80. package/docs/AGENT_GUIDE.md +1 -0
  81. package/docs/API_REFERENCE.md +49 -1
  82. package/docs/QUICK_START.md +257 -17
  83. package/docs/USAGE.md +57 -5
  84. package/docs/api/core-version.md +1 -1
  85. package/docs/api/equipment-generic-lens-catalogue.md +281 -0
  86. package/docs/api/exports.json +137 -2
  87. package/docs/api/facade-simulate-capture.md +23 -2
  88. package/docs/api/optics-defocus-bokeh-kernel.md +145 -0
  89. package/docs/api/optics-defocus-disc-kernel.md +22 -15
  90. package/docs/api/optics-sensor-environment-query.md +6 -0
  91. package/docs/api/output-generic-lens-corrections.md +39 -0
  92. package/llms.txt +1 -0
  93. package/package.json +1 -1
@@ -6,14 +6,15 @@ The package and root API versions are recorded once in [Navigation](../API_REFER
6
6
 
7
7
  Checks, before rendering, whether `lens.defocus: { model: "geometric-disc" }` can render a request: the geometric
8
8
  defocus disc's diameter on the site lattice, the kernel radius it needs, and whether that radius is within
9
- {@link DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES} (#532). Pure and cheap: no kernel is built and nothing is rendered.
9
+ {@link DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES} (#532; 512 sites since 2.17.0, #564), and which convolution the renderers
10
+ would use. Pure and cheap: no kernel is built and nothing is rendered.
10
11
 
11
12
  It runs the same resolution and the same limit test as `simulateCapture`, `simulateDisplayView` and `prepareDisplayView`
12
13
  (the blur circle c = f²·|s − d| / (N·d·(s − f)) of `calculateDefocusCircle`, thin-lens model 1.1.0, divided by the pitch),
13
14
  so for the same focal length, f-number, distances and pitch a request they refuse for its defocus size has
14
15
  `withinLimit: false`, and one they accept has `withinLimit: true`. Pass the values the capture uses: in an automatic
15
- exposure mode that is the resolved f-number. The limit applies to the disc alone; with `lens.diffraction` the combined
16
- kernel (diffraction radius plus defocus radius, at most 32 + 64 sites) has no further limit. Other reasons a capture
16
+ exposure mode that is the resolved f-number. The limit applies to the disc alone; with `lens.diffraction` the diffraction
17
+ kernel (at most 32 sites) is applied with it and has no further limit. Other reasons a capture
17
18
  refuses `lens.defocus` out of focus (pupil sampling, a caller PSF, camera rotation with a rolling shutter, a vignetting or
18
19
  distortion profile that does not reach the kernel's radius beyond the frame, and in the display view a projection,
19
20
  distortion, vignetting or rotation) are not checked here.
@@ -49,18 +50,19 @@ export interface CalculateDefocusDiscKernelRadiusInput {
49
50
 
50
51
  ## DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES
51
52
 
52
- Largest kernel radius in sites of `lens.defocus: { model: "geometric-disc" }`, R ≤ 64: a disc of at most 129 sites
53
- across (a 129 × 129 window, 16 641 taps per site; the diffraction kernels stop at 32). `simulateCapture`,
54
- `simulateDisplayView` and `prepareDisplayView` refuse a request whose disc needs more, and never clip the disc; check a
55
- request first with {@link calculateDefocusDiscKernelRadius}.
53
+ Largest kernel radius in sites of `lens.defocus: { model: "geometric-disc" }`, R ≤ 512 (#564, 2.17.0; 64 before): a disc of
54
+ at most 1025 sites across (6.15 mm at 6 µm). `simulateCapture`, `simulateDisplayView` and `prepareDisplayView` refuse a
55
+ request whose disc needs more, and never clip the disc; check a request first with {@link calculateDefocusDiscKernelRadius}.
56
56
 
57
- Set from the cost measured in the capture (#492, step 2a; docs/QUICK_START.md, "Optics"): the capture's time grows with
58
- R² at every site the disc sees an edge from, and a 0.7 MP Siemens star took 0.37 s in focus, 2.9 s at R = 32, 4.7 s at
59
- R = 41 and 11.6 s at R = 64 (Node, one thread). 64 keeps the issue's 1.4 µm example (50 mm f/2.8, subject 2 m, focus
60
- 1.6 m: R = 41) with room for larger blurs, at a cost the caller chooses and the docs state; past it the call fails.
57
+ Up to 64 sites the disc is convolved directly ((2R + 1)² taps per site,
58
+ byte-identical to 2.16.0). Above it the renderers use the exact run convolution (`site-kernel-runs.ts`: one prefix-sum
59
+ difference per kernel row plus the cells the circle crosses, about 12·R reads per site), whose cost grows with R instead of
60
+ R². 512 bounds that cost (6,145 reads per site, below the 16,641 taps of the direct gather at 64), the kernel's own
61
+ memory ((2R + 1)² doubles, 8.4 MB) and each tile's source ((64 + 2R)² doubles per field, 9.5 MB): measured in
62
+ docs/QUICK_START.md, "Optics".
61
63
 
62
64
  ```ts
63
- DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES = 64
65
+ DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES = 512
64
66
  ```
65
67
 
66
68
  ## DefocusDiscKernelRadius
@@ -75,13 +77,18 @@ export interface DefocusDiscKernelRadius {
75
77
  diameterSites: number;
76
78
  /** Kernel radius R in sites the renderer needs for this disc, ⌈c / (2·pitch) − ½⌉ (0 for a disc inside one site, and in focus). */
77
79
  kernelRadiusSites: number;
78
- /** {@link DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES}, 64. */
80
+ /** {@link DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES}, 512 (64 before 2.17.0). */
79
81
  maximumKernelRadiusSites: number;
80
- /** Largest disc diameter in sites within the limit, 2·64 + 1 = 129: within the limit exactly when `diameterSites` ≤ 129. */
82
+ /** Largest disc diameter in sites within the limit, 2·512 + 1 = 1025: within the limit exactly when `diameterSites` ≤ 1025. */
81
83
  maximumDiameterSites: number;
82
84
  /** True when `kernelRadiusSites` ≤ `maximumKernelRadiusSites`: `lens.defocus` renders the request; false: it refuses it. */
83
85
  withinLimit: boolean;
84
- /** How far past the limit the kernel radius is, max(0, R − 64) sites; 0 when within the limit. */
86
+ /** How far past the limit the kernel radius is, max(0, R − 512) sites; 0 when within the limit. */
85
87
  excessKernelRadiusSites: number;
88
+ /**
89
+ * How the renderers convolve this disc (#564): `"direct"` for a kernel radius up to 64 sites (as in 2.16.0; also in focus),
90
+ * `"runs"` above it (the exact run convolution, cost about proportional to R per site), null past the limit.
91
+ */
92
+ convolution: "direct" | "runs" | null;
86
93
  }
87
94
  ```
@@ -57,6 +57,12 @@ export interface EnvironmentLensFieldMapping {
57
57
  | { kind: "radial"; profile: RadialDistortionProfile }
58
58
  | { kind: "brown-conrady"; profile: BrownConradyDistortionProfile };
59
59
  radiometricAreaCorrection: "inverse-distortion-jacobian";
60
+ /**
61
+ * #549, optional: what an ideal image point outside a radial projection's image circle (for example beyond r = 2f of the
62
+ * equisolid fisheye) does. Omitted: the query fails, as before. `"backward-ray"`: the query looks straight back (0, 0, −1),
63
+ * a direction no forward scene answers, so a provider that treats directions beyond 90° as empty gives it zero radiance.
64
+ */
65
+ outsideImageCircle?: "backward-ray";
60
66
  }
61
67
  ```
62
68
 
@@ -0,0 +1,39 @@
1
+ # output/generic-lens-corrections.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
+ ## createGenericLensCorrectionProfile
6
+
7
+ Builds the catalogue lens's generic correction profile for one camera state: a radial distortion map (the lens's own
8
+ r_d = r(1 + k1ρ²), read at each ideal destination point), per-channel lateral-colour scales 1 + L·D(λ_channel), and the
9
+ relative-illumination gain at the state's aperture (strength 1). The result passes `parseGenericLensCorrectionProfile`.
10
+
11
+ ```ts
12
+ export function createGenericLensCorrectionProfile(input: CreateGenericLensCorrectionProfileInput): GenericLensCorrectionProfile;
13
+ ```
14
+
15
+ This call is synchronous; any supplied provider must follow its explicit synchronous contract.
16
+
17
+ ## CreateGenericLensCorrectionProfileInput
18
+
19
+ The exact contract is declared below; use the domain guide for assumptions and staged integration.
20
+
21
+ ```ts
22
+ export interface CreateGenericLensCorrectionProfileInput {
23
+ /** A catalogue id (`GENERIC_LENS_IDS`); `state.lensId` must be the same id. */
24
+ lensId: string;
25
+ /** The sensor's active capture area, mm (the lens is scaled to it as in `resolveGenericLens`). */
26
+ activeImagingArea: { widthMm: number; heightMm: number };
27
+ /** The exact camera state the profile applies to: its focal length must be the lens's on this sensor, its aperture in range. */
28
+ state: OpticalProfileState;
29
+ }
30
+ ```
31
+
32
+ ## GENERIC_LENS_CORRECTION_CHANNEL_WAVELENGTHS_NM
33
+
34
+ Effective wavelengths of the red, green and blue channels for the lateral-colour map, nm: a generic approximation of where
35
+ a camera's channel responses peak, not a measured camera.
36
+
37
+ ```ts
38
+ GENERIC_LENS_CORRECTION_CHANNEL_WAVELENGTHS_NM: Readonly<Record<LensCorrectionChannel, number>> = Object.freeze({ red: 610, green: 540, blue: 465 })
39
+ ```
package/llms.txt CHANGED
@@ -21,6 +21,7 @@
21
21
  - [calculateDepthOfField()](https://github.com/Photivra/photivra/blob/main/docs/api/optics-depth-of-field.md#calculatedepthoffield): near and far limits and hyperfocal distance (thin lens)
22
22
  - [calculateDefocusCircle()](https://github.com/Photivra/photivra/blob/main/docs/api/optics-depth-of-field.md#calculatedefocuscircle): blur-circle size for an out-of-focus subject
23
23
  - [calculateDefocusDiscKernelRadius()](https://github.com/Photivra/photivra/blob/main/docs/api/optics-defocus-disc-kernel.md#calculatedefocusdisckernelradius): whether `lens.defocus` can render a blur before you render it (the 64-site limit)
24
+ - [resolveGenericLens()](https://github.com/Photivra/photivra/blob/main/docs/api/equipment-generic-lens-catalogue.md#resolvegenericlens): one of the 30 generic catalogue lenses ("PV 50 1.2 Pro") on a sensor, with its approximated optical character; `simulateCapture` renders it with `lens.catalogue`
24
25
  - [calculateFieldOfView()](https://github.com/Photivra/photivra/blob/main/docs/api/camera-field-of-view.md#calculatefieldofview): angle of view from focal length and sensor size
25
26
  - [calculateEquivalentFocalLength35Mm()](https://github.com/Photivra/photivra/blob/main/docs/api/camera-equivalent-focal-length.md#calculateequivalentfocallength35mm): crop factor and 35 mm-equivalent focal length
26
27
  - [calculateCenteredCrop()](https://github.com/Photivra/photivra/blob/main/docs/api/output-crop.md#calculatecenteredcrop): pixels left after a centred crop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@photivra/engine",
3
- "version": "2.16.0",
3
+ "version": "2.17.0",
4
4
  "private": false,
5
5
  "description": "Scientific TypeScript engine for camera optics, exposure, focus, motion, sensor sampling, diffraction, and digital imaging calculations.",
6
6
  "type": "module",