@photivra/engine 2.2.1 → 2.3.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 (44) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/dist/capture/native-environment-raw.d.ts +18 -0
  6. package/dist/capture/native-environment-raw.js +17 -1
  7. package/dist/capture/native-environment-raw.js.map +1 -1
  8. package/dist/capture/native-raw.d.ts +3 -0
  9. package/dist/capture/native-raw.js +8 -5
  10. package/dist/capture/native-raw.js.map +1 -1
  11. package/dist/core/version.d.ts +1 -1
  12. package/dist/core/version.js +1 -1
  13. package/dist/core/version.js.map +1 -1
  14. package/dist/equipment/generic-prime-lenses.d.ts +46 -0
  15. package/dist/equipment/generic-prime-lenses.js +59 -0
  16. package/dist/equipment/generic-prime-lenses.js.map +1 -0
  17. package/dist/facade/chart-scenes.d.ts +270 -1
  18. package/dist/facade/chart-scenes.js +443 -17
  19. package/dist/facade/chart-scenes.js.map +1 -1
  20. package/dist/facade/scene-radiance.d.ts +47 -0
  21. package/dist/facade/scene-radiance.js +65 -5
  22. package/dist/facade/scene-radiance.js.map +1 -1
  23. package/dist/facade/simulate-capture.d.ts +151 -4
  24. package/dist/facade/simulate-capture.js +296 -55
  25. package/dist/facade/simulate-capture.js.map +1 -1
  26. package/dist/facade/subject-framing.d.ts +55 -0
  27. package/dist/facade/subject-framing.js +66 -0
  28. package/dist/facade/subject-framing.js.map +1 -0
  29. package/dist/gpu/chart-radiance-gpu.d.ts +8 -0
  30. package/dist/gpu/chart-radiance-gpu.js +20 -1
  31. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  32. package/dist/index.d.ts +5 -3
  33. package/dist/index.js +5 -3
  34. package/dist/index.js.map +1 -1
  35. package/docs/API_REFERENCE.md +48 -1
  36. package/docs/QUICK_START.md +264 -3
  37. package/docs/api/core-version.md +1 -1
  38. package/docs/api/equipment-generic-prime-lenses.md +85 -0
  39. package/docs/api/exports.json +167 -2
  40. package/docs/api/facade-chart-scenes.md +280 -4
  41. package/docs/api/facade-scene-radiance.md +42 -0
  42. package/docs/api/facade-simulate-capture.md +107 -2
  43. package/docs/api/facade-subject-framing.md +72 -0
  44. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chart-scenes.js","sourceRoot":"","sources":["../../src/facade/chart-scenes.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Procedural test charts for the capture facade, written for this engine. Every chart is a flat,\n * Lambertian (matte) reflectance pattern, defined by formulas in normalized frame coordinates. No\n * third-party chart data (for example ColorChecker reflectances) is bundled. Coloured patches use\n * spectra that the caller supplies.\n *\n * Frame coordinates: `u` runs from -1 (left edge of the framed chart) to +1 (right edge); `v` points up\n * and has the same scale, so it runs from -aspect to +aspect where aspect = height/width of the frame.\n * The facade places the chart perpendicular to the optical axis at the subject distance and sizes it so\n * that this rectangle exactly fills the active capture (see `SimulateCaptureResult.assumptions`).\n *\n * The slanted edge follows the geometry described by P. D. Burns, \"Slanted-Edge MTF for Digital Camera\n * and Scanner Analysis\", IS&T PICS 2000 (free from imaging.org; also ISO 12233). It is a near-vertical\n * edge rotated by a few degrees (5 degrees by default), with a 4:1 light/dark reflectance ratio by\n * default. This is only a geometric description. No measured chart or ISO test procedure is copied.\n * @see docs/QUICK_START.md for the chart catalogue and their analytic definitions.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { prepareColorimetricSpectrum, type ColorimetricSpectrum, type PreparedColorimetricSpectrum } from \"../color/color-matching-functions.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\n\n/** A neutral (spectrally flat) reflectance in [0, 1], or a caller reflectance spectrum (values in [0, 1]). */\nexport type ChartReflectance = number | ColorimetricSpectrum;\n\nexport interface UniformChartScene { preset: \"uniform\"; reflectance?: ChartReflectance }\nexport interface SlantedEdgeChartScene {\n preset: \"slanted-edge\";\n /** Clockwise tilt of the edge from vertical, degrees, in (-45, 45). Default 5. */\n angleDegrees?: number;\n /** Left (dark) side reflectance. Default 0.15. */\n darkReflectance?: number;\n /** Right (light) side reflectance. Default 0.6 (4:1 with the default dark side). */\n lightReflectance?: number;\n}\nexport interface SiemensStarChartScene {\n preset: \"siemens-star\";\n /** Light/dark sector pairs around the star, 2..360. Default 36. */\n cycles?: number;\n /** Star radius as a fraction of the frame half-height, (0, 1]. Default 0.9. */\n radiusFraction?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n /** Reflectance outside the star. Default 0.18. */\n backgroundReflectance?: number;\n}\nexport interface StepWedgeChartScene {\n preset: \"step-wedge\";\n /** Number of equal-width vertical steps from left (minimum) to right (maximum), 2..64. Default 11. */\n steps?: number;\n minimumReflectance?: number;\n maximumReflectance?: number;\n /** `equal-density` (geometric, default) or `linear` reflectance spacing. */\n spacing?: \"equal-density\" | \"linear\";\n}\nexport interface GreyRampChartScene {\n preset: \"grey-ramp\";\n /** Continuous ramp, linear in reflectance from left (minimum) to right (maximum). */\n minimumReflectance?: number;\n maximumReflectance?: number;\n}\nexport interface CheckerboardChartScene {\n preset: \"checkerboard\";\n /** Squares across the frame width, 2..256. Default 8. */\n squaresAcross?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n}\nexport interface PointGridChartScene {\n preset: \"point-grid\";\n /** Grid columns and rows of small disks centred in equal cells. Defaults 5 × 3. */\n columns?: number;\n rows?: number;\n /** Disk radius in frame units (fraction of the frame half-width). Default 0.01. */\n radius?: number;\n pointReflectance?: number;\n backgroundReflectance?: number;\n}\nexport interface PatchChartScene {\n preset: \"patches\";\n /** Caller reflectance per patch, row-major; the facade bundles no colour-chart data. 1..1024 patches. */\n patches: readonly { patchId: string; reflectance: ChartReflectance }[];\n /** Patches per row. Default ceil(sqrt(patch count)). */\n columns?: number;\n /** Gap between patches as a fraction of the cell size, [0, 0.5). Default 0.1. */\n gapFraction?: number;\n backgroundReflectance?: number;\n}\nexport type ChartScene = UniformChartScene | SlantedEdgeChartScene | SiemensStarChartScene | StepWedgeChartScene |\n GreyRampChartScene | CheckerboardChartScene | PointGridChartScene | PatchChartScene;\nexport type ChartScenePresetId = ChartScene[\"preset\"];\nexport const CHART_SCENE_PRESETS: readonly ChartScenePresetId[] = Object.freeze([\"uniform\", \"slanted-edge\", \"siemens-star\",\n \"step-wedge\", \"grey-ramp\", \"checkerboard\", \"point-grid\", \"patches\"] as const);\n\n/** Engine-chosen chart parameters, each reported when the caller omitted it. */\nexport const CHART_SCENE_DEFAULTS = Object.freeze({\n uniform: Object.freeze({ reflectance: 0.18 }),\n \"slanted-edge\": Object.freeze({ angleDegrees: 5, darkReflectance: 0.15, lightReflectance: 0.6 }),\n \"siemens-star\": Object.freeze({ cycles: 36, radiusFraction: 0.9, darkReflectance: 0.05, lightReflectance: 0.8, backgroundReflectance: 0.18 }),\n \"step-wedge\": Object.freeze({ steps: 11, minimumReflectance: 0.03, maximumReflectance: 0.9, spacing: \"equal-density\" as const }),\n \"grey-ramp\": Object.freeze({ minimumReflectance: 0.03, maximumReflectance: 0.9 }),\n checkerboard: Object.freeze({ squaresAcross: 8, darkReflectance: 0.05, lightReflectance: 0.8 }),\n \"point-grid\": Object.freeze({ columns: 5, rows: 3, radius: 0.01, pointReflectance: 0.9, backgroundReflectance: 0.02 }),\n patches: Object.freeze({ gapFraction: 0.1, backgroundReflectance: 0.18 })\n});\n\n/** A validated chart: every parameter resolved, plus which ones came from {@link CHART_SCENE_DEFAULTS}. */\nexport interface ResolvedChartScene {\n preset: ChartScenePresetId;\n /** Fully resolved parameters (spectra are reported as `\"caller-spectrum\"`). */\n parameters: Readonly<Record<string, unknown>>;\n /** Names of parameters filled from defaults. */\n defaultedParameters: readonly string[];\n /** Frame aspect (height / width) the chart was resolved for. */\n aspect: number;\n /**\n * Material index at a frame point (u right, v up). The index points into `materials`, starting at 0.\n * Points outside the framed rectangle still evaluate (the pattern continues as defined), so blur and\n * small framing differences stay well defined.\n */\n materialAt(u: number, v: number): number;\n /** Reflectance materials: a neutral number or a prepared caller spectrum. */\n materials: readonly ({ kind: \"neutral\"; reflectance: number } | { kind: \"spectrum\"; spectrum: PreparedColorimetricSpectrum })[];\n /** Reflectance in [0, 1] at a frame point and wavelength (nm). */\n reflectanceAt(u: number, v: number, wavelengthNanometers: number): number;\n}\n\nfunction reflectance(value: unknown, name: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1) throw new InvalidConfigurationError(name + \" must be a reflectance in [0, 1].\");\n return value;\n}\nfunction integerIn(value: unknown, name: string, minimum: number, maximum: number): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < minimum || value > maximum) throw new InvalidConfigurationError(name + \" must be an integer from \" + minimum + \" to \" + maximum + \".\");\n return value;\n}\nfunction finiteIn(value: unknown, name: string, minimum: number, maximum: number, open = false): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < minimum || value > maximum || (open && (value === minimum || value === maximum)))\n throw new InvalidConfigurationError(name + \" is outside its supported range.\");\n return value;\n}\n/** Wavelength range every chart spectrum must cover (the facade's sensor quadrature range). */\nexport const CHART_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });\nfunction material(value: unknown, name: string): ResolvedChartScene[\"materials\"][number] {\n if (typeof value === \"number\") return { kind: \"neutral\", reflectance: reflectance(value, name) };\n let spectrum: PreparedColorimetricSpectrum;\n try { spectrum = prepareColorimetricSpectrum(value as ColorimetricSpectrum, name); } catch (error) {\n throw new InvalidConfigurationError(name + \" must be a neutral reflectance or a valid reflectance spectrum: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n const range = spectrum.wavelengthRangeNanometers;\n if (range.minimum > CHART_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < CHART_SPECTRAL_RANGE_NANOMETERS.maximum)\n throw new InvalidConfigurationError(name + \" must cover 380-780 nm.\");\n for (let nm = CHART_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= CHART_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 5) reflectance(spectrum.evaluate(nm), name + \" values\");\n return { kind: \"spectrum\", spectrum };\n}\n\n/**\n * Validates a chart description and resolves every default. `aspect` is the frame height/width. Unknown\n * fields are rejected so that a mistyped parameter never silently falls back to a default.\n */\nexport function resolveChartScene(input: { scene: ChartScene; aspect: number }): ResolvedChartScene {\n requireInputObject(input, \"resolveChartScene input\");\n for (const key of Object.keys(input)) if (key !== \"scene\" && key !== \"aspect\") throw new InvalidConfigurationError(\"resolveChartScene input has unknown field \\\"\" + key + \"\\\".\");\n const { scene, aspect } = input;\n requireInputObject(scene, \"chart scene\");\n if (typeof aspect !== \"number\" || !Number.isFinite(aspect) || aspect <= 0) throw new InvalidConfigurationError(\"Chart aspect must be positive.\");\n const preset = (scene as { preset?: unknown }).preset;\n if (typeof preset !== \"string\" || !(CHART_SCENE_PRESETS as readonly string[]).includes(preset)) throw new InvalidConfigurationError(\"Unknown chart preset.\");\n const record = scene as unknown as Record<string, unknown>;\n const defaults = CHART_SCENE_DEFAULTS[preset as ChartScenePresetId] as Record<string, unknown>;\n const allowed = [\"preset\", ...Object.keys(defaults), ...(preset === \"patches\" ? [\"patches\", \"columns\"] : [])];\n for (const key of Object.keys(record)) if (!allowed.includes(key)) throw new InvalidConfigurationError(\"Unknown chart parameter: \" + key + \".\");\n const defaulted: string[] = [];\n const get = (key: string): unknown => { if (record[key] === undefined) { if (key in defaults) defaulted.push(key); return defaults[key]; } return record[key]; };\n const neutral = (key: string): number => reflectance(get(key), key);\n const done = (parameters: Record<string, unknown>, materials: ResolvedChartScene[\"materials\"], materialAt: (u: number, v: number) => number): ResolvedChartScene =>\n Object.freeze({ preset: preset as ChartScenePresetId, parameters: Object.freeze(parameters), defaultedParameters: Object.freeze(defaulted), aspect, materials: Object.freeze(materials), materialAt,\n reflectanceAt(u: number, v: number, nm: number): number {\n const m = materials[materialAt(u, v)]!;\n if (m.kind === \"neutral\") return m.reflectance;\n const value = m.spectrum.evaluate(nm);\n if (!(value >= 0 && value <= 1)) throw new InvalidConfigurationError(\"Chart reflectance spectrum left [0, 1].\");\n return value;\n } });\n switch (preset as ChartScenePresetId) {\n case \"uniform\": {\n const raw = get(\"reflectance\"), m = material(raw, \"reflectance\");\n return done({ reflectance: typeof raw === \"number\" ? raw : \"caller-spectrum\" }, [m], () => 0);\n }\n case \"slanted-edge\": {\n const angle = finiteIn(get(\"angleDegrees\"), \"angleDegrees\", -45, 45, true), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\");\n const t = angle * Math.PI / 180, c = Math.cos(t), s = Math.sin(t);\n // Edge through the frame centre along (sin t, cos t); the light side is to the right.\n return done({ angleDegrees: angle, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }], (u, v) => (u * c - v * s >= 0 ? 1 : 0));\n }\n case \"siemens-star\": {\n const cycles = integerIn(get(\"cycles\"), \"cycles\", 2, 360), radius = finiteIn(get(\"radiusFraction\"), \"radiusFraction\", 0, 1, false);\n if (radius === 0) throw new InvalidConfigurationError(\"radiusFraction must be positive.\");\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), background = neutral(\"backgroundReflectance\"), r = radius * aspect;\n return done({ cycles, radiusFraction: radius, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }, { kind: \"neutral\", reflectance: background }], (u, v) => {\n if (u * u + v * v > r * r) return 2;\n const phase = Math.atan2(v, u) / (2 * Math.PI) + 0.5; // [0, 1]\n return Math.floor(phase * 2 * cycles) % 2 === 0 ? 1 : 0;\n });\n }\n case \"step-wedge\": {\n const steps = integerIn(get(\"steps\"), \"steps\", 2, 64), lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\"), spacing = get(\"spacing\");\n if (spacing !== \"equal-density\" && spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n const values = calculateStepWedgeReflectances({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing });\n return done({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing, stepReflectances: values },\n values.map((reflectanceValue) => ({ kind: \"neutral\" as const, reflectance: reflectanceValue })),\n (u) => Math.min(steps - 1, Math.max(0, Math.floor((u + 1) / 2 * steps))));\n }\n case \"grey-ramp\": {\n const lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\");\n if (!(hi > lo)) throw new InvalidConfigurationError(\"Grey ramp needs minimum < maximum reflectance.\");\n // A continuous ramp is stored as 1024 neutral levels. The step size (< 0.1 % of the range) is far below sensor noise.\n const levels = 1024, materials = Array.from({ length: levels }, (_, i) => ({ kind: \"neutral\" as const, reflectance: lo + (hi - lo) * (i + 0.5) / levels }));\n return done({ minimumReflectance: lo, maximumReflectance: hi, representation: \"1024 equal neutral levels\" }, materials,\n (u) => Math.min(levels - 1, Math.max(0, Math.floor((u + 1) / 2 * levels))));\n }\n case \"checkerboard\": {\n const across = integerIn(get(\"squaresAcross\"), \"squaresAcross\", 2, 256), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), size = 2 / across;\n return done({ squaresAcross: across, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }],\n (u, v) => ((Math.floor((u + 1) / size) + Math.floor((aspect - v) / size)) % 2 === 0 ? 1 : 0));\n }\n case \"point-grid\": {\n const columns = integerIn(get(\"columns\"), \"columns\", 1, 256), rows = integerIn(get(\"rows\"), \"rows\", 1, 256);\n const radius = finiteIn(get(\"radius\"), \"radius\", 0, 1, true), point = neutral(\"pointReflectance\"), background = neutral(\"backgroundReflectance\");\n const centers = calculatePointGridCenters({ columns, rows, aspect });\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ columns, rows, radius, pointReflectance: point, backgroundReflectance: background },\n [{ kind: \"neutral\", reflectance: background }, { kind: \"neutral\", reflectance: point }], (u, v) => {\n const i = Math.min(columns - 1, Math.max(0, Math.floor((u + 1) / cellW))), j = Math.min(rows - 1, Math.max(0, Math.floor((aspect - v) / cellH)));\n const c = centers[j * columns + i]!;\n return (u - c.u) ** 2 + (v - c.v) ** 2 <= radius * radius ? 1 : 0;\n });\n }\n case \"patches\": {\n const list = record.patches;\n if (!Array.isArray(list) || list.length < 1 || list.length > 1024) throw new InvalidConfigurationError(\"patches must list 1 to 1024 caller reflectances.\");\n const ids = new Set<string>();\n const materials: ResolvedChartScene[\"materials\"][number][] = [];\n for (const [index, patch] of list.entries()) {\n requireInputObject(patch, \"patches[\" + index + \"]\");\n const p = patch as Record<string, unknown>;\n for (const key of Object.keys(p)) if (key !== \"patchId\" && key !== \"reflectance\") throw new InvalidConfigurationError(\"Unknown patch field: \" + key + \".\");\n if (typeof p.patchId !== \"string\" || p.patchId.trim() === \"\" || ids.has(p.patchId)) throw new InvalidConfigurationError(\"Each patch needs a unique non-empty patchId.\");\n ids.add(p.patchId);\n materials.push(material(p.reflectance, \"patches[\" + index + \"].reflectance\"));\n }\n const columnsRaw = record.columns === undefined ? Math.ceil(Math.sqrt(list.length)) : record.columns;\n if (record.columns === undefined) defaulted.push(\"columns\");\n const columns = integerIn(columnsRaw, \"columns\", 1, list.length), rows = Math.ceil(list.length / columns);\n const gap = finiteIn(get(\"gapFraction\"), \"gapFraction\", 0, 0.5), background = neutral(\"backgroundReflectance\");\n if (gap >= 0.5) throw new InvalidConfigurationError(\"gapFraction must be below 0.5.\");\n const backgroundIndex = materials.length;\n materials.push({ kind: \"neutral\", reflectance: background });\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ patchIds: list.map((p: { patchId: string }) => p.patchId), columns, rows, gapFraction: gap, backgroundReflectance: background }, materials, (u, v) => {\n const fx = (u + 1) / cellW, fy = (aspect - v) / cellH, i = Math.floor(fx), j = Math.floor(fy);\n if (i < 0 || j < 0 || i >= columns || j >= rows) return backgroundIndex;\n const index = j * columns + i, x = fx - i, y = fy - j;\n if (index >= list.length || x < gap / 2 || x > 1 - gap / 2 || y < gap / 2 || y > 1 - gap / 2) return backgroundIndex;\n return index;\n });\n }\n }\n}\n\n/**\n * Step reflectances of a step wedge. `equal-density` spaces optical density D = -log10(R) evenly, which\n * gives geometric reflectance steps, as on a photographic step tablet. `linear` spaces reflectance evenly.\n */\nexport function calculateStepWedgeReflectances(input: { steps: number; minimumReflectance: number; maximumReflectance: number;\n spacing: \"equal-density\" | \"linear\" }): number[] {\n requireInputKeys(input, \"calculateStepWedgeReflectances\", [\"steps\", \"minimumReflectance\", \"maximumReflectance\", \"spacing\"]);\n const steps = integerIn(input.steps, \"steps\", 2, 64), lo = reflectance(input.minimumReflectance, \"minimumReflectance\"), hi = reflectance(input.maximumReflectance, \"maximumReflectance\");\n if (input.spacing !== \"equal-density\" && input.spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (input.spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n return Array.from({ length: steps }, (_, k) => {\n if (k === steps - 1) return hi;\n const t = k / (steps - 1);\n return input.spacing === \"linear\" ? lo + (hi - lo) * t : lo * (hi / lo) ** t;\n });\n}\n\n/** Centres (frame units) of a point grid: one disk centred in each of columns × rows equal cells, row-major from the top-left. */\nexport function calculatePointGridCenters(input: { columns: number; rows: number; aspect: number }): { u: number; v: number }[] {\n requireInputKeys(input, \"calculatePointGridCenters\", [\"columns\", \"rows\", \"aspect\"]);\n const columns = integerIn(input.columns, \"columns\", 1, 256), rows = integerIn(input.rows, \"rows\", 1, 256);\n if (typeof input.aspect !== \"number\" || !Number.isFinite(input.aspect) || input.aspect <= 0) throw new InvalidConfigurationError(\"aspect must be positive.\");\n const out: { u: number; v: number }[] = [];\n for (let j = 0; j < rows; j++) for (let i = 0; i < columns; i++) out.push({ u: -1 + (i + 0.5) * 2 / columns, v: input.aspect - (j + 0.5) * 2 * input.aspect / rows });\n return out;\n}\n"]}
1
+ {"version":3,"file":"chart-scenes.js","sourceRoot":"","sources":["../../src/facade/chart-scenes.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Procedural test charts for the capture facade, written for this engine. Every chart is a flat,\n * Lambertian (matte) reflectance pattern, defined by formulas in normalized frame coordinates. No\n * third-party chart data (for example ColorChecker reflectances) is bundled. Coloured patches use\n * spectra that the caller supplies.\n *\n * Frame coordinates: `u` runs from -1 (left edge of the framed chart) to +1 (right edge); `v` points up\n * and has the same scale, so it runs from -aspect to +aspect where aspect = height/width of the frame.\n * The facade places the chart perpendicular to the optical axis at the subject distance and sizes it so\n * that this rectangle exactly fills the active capture (see `SimulateCaptureResult.assumptions`), or, with\n * `simulateCapture({ chartSize })` (2.3), at its physical size.\n *\n * The slanted edge follows the geometry described by P. D. Burns, \"Slanted-Edge MTF for Digital Camera\n * and Scanner Analysis\", IS&T PICS 2000 (free from imaging.org; also ISO 12233). It is a near-vertical\n * edge rotated by a few degrees (5 degrees by default), with a 4:1 light/dark reflectance ratio by\n * default. This is only a geometric description. No measured chart or ISO test procedure is copied.\n *\n * Chart elements (2.3) are generic, unbranded test-pattern primitives; each element's definition and\n * source is given at its preset below. A `composite` chart lays out any of them in placement rectangles\n * over a background, so an application can build its own layout from engine parts. Continuous patterns\n * (sine star, zone plate, dead-leaves greys) are quantized to {@link CHART_CONTINUOUS_LEVELS} equal neutral\n * levels, like the grey ramp: the step (below 0.1 % of the range) is far below sensor noise.\n * @see docs/QUICK_START.md for the chart catalogue and their analytic definitions.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { prepareColorimetricSpectrum, type ColorimetricSpectrum, type PreparedColorimetricSpectrum } from \"../color/color-matching-functions.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport { createDeterministicUniformStream } from \"../sensor/stochastic-seed.js\";\n\n/** A neutral (spectrally flat) reflectance in [0, 1], or a caller reflectance spectrum (values in [0, 1]). */\nexport type ChartReflectance = number | ColorimetricSpectrum;\n\nexport interface UniformChartScene { preset: \"uniform\"; reflectance?: ChartReflectance }\nexport interface SlantedEdgeChartScene {\n preset: \"slanted-edge\";\n /** Clockwise tilt of the edge from vertical, degrees, in (-45, 45). Default 5. */\n angleDegrees?: number;\n /** Left (dark) side reflectance. Default 0.15. */\n darkReflectance?: number;\n /** Right (light) side reflectance. Default 0.6 (4:1 with the default dark side). */\n lightReflectance?: number;\n}\nexport interface SiemensStarChartScene {\n preset: \"siemens-star\";\n /** Light/dark sector pairs around the star, 2..360. Default 36. */\n cycles?: number;\n /** Star radius as a fraction of the frame half-height, (0, 1]. Default 0.9. */\n radiusFraction?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n /** Reflectance outside the star. Default 0.18. */\n backgroundReflectance?: number;\n /**\n * 2.3: angular reflectance profile. `bar` (default): square-wave sectors. `sine`: a sinusoidal star,\n * R(θ) = mid + amp·sin(2π·cycles·(θ/2π + ½)) between the dark and light reflectances, zero crossings at\n * the bar star's sector edges, quantized to {@link CHART_CONTINUOUS_LEVELS} levels. Reported in the\n * parameters only when given, so 2.2 scene digests are unchanged.\n */\n profile?: \"bar\" | \"sine\";\n}\nexport interface StepWedgeChartScene {\n preset: \"step-wedge\";\n /** Number of equal-width vertical steps from left (minimum) to right (maximum), 2..64. Default 11. */\n steps?: number;\n minimumReflectance?: number;\n maximumReflectance?: number;\n /** `equal-density` (geometric, default) or `linear` reflectance spacing. */\n spacing?: \"equal-density\" | \"linear\";\n}\nexport interface GreyRampChartScene {\n preset: \"grey-ramp\";\n /** Continuous ramp, linear in reflectance from left (minimum) to right (maximum). */\n minimumReflectance?: number;\n maximumReflectance?: number;\n}\nexport interface CheckerboardChartScene {\n preset: \"checkerboard\";\n /** Squares across the frame width, 2..256. Default 8. */\n squaresAcross?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n}\nexport interface PointGridChartScene {\n preset: \"point-grid\";\n /** Grid columns and rows of small disks centred in equal cells. Defaults 5 × 3. */\n columns?: number;\n rows?: number;\n /** Disk radius in frame units (fraction of the frame half-width). Default 0.01. */\n radius?: number;\n pointReflectance?: number;\n backgroundReflectance?: number;\n}\nexport interface PatchChartScene {\n preset: \"patches\";\n /** Caller reflectance per patch, row-major; the facade bundles no colour-chart data. 1..1024 patches. */\n patches: readonly { patchId: string; reflectance: ChartReflectance }[];\n /** Patches per row. Default ceil(sqrt(patch count)). */\n columns?: number;\n /** Gap between patches as a fraction of the cell size, [0, 0.5). Default 0.1. */\n gapFraction?: number;\n backgroundReflectance?: number;\n}\n/**\n * 2.3: seeded dead-leaves texture (Matheron's random closed set model, in the scale-invariant form used for\n * camera texture measurement by Cao, Guichard and Hornung): opaque disks with Poisson-distributed centres,\n * radius density ∝ r⁻³ on [radiusMinimum, radiusMaximum] and a grey drawn uniformly in [minimum, maximum]\n * reflectance. Disks are drawn in order with earlier disks on top until every point of the chart (plus 0.1\n * frame units around it) is covered, which samples the stationary dead-leaves image exactly (Kendall and\n * Thönnes' backward \"perfect simulation\"). Radii are in frame units (fraction of the frame half-width).\n */\nexport interface DeadLeavesChartScene {\n preset: \"dead-leaves\";\n /** Smallest disk radius, frame units, [0.002, radiusMaximum). Default 0.01. */\n radiusMinimum?: number;\n /** Largest disk radius, frame units, (radiusMinimum, 2]. Default 0.5. */\n radiusMaximum?: number;\n /** Grey range (neutral reflectances). Defaults 0.2 and 0.6. */\n minimumReflectance?: number;\n maximumReflectance?: number;\n /** Random seed (uint32); the same seed gives the same disks on every platform. Default 1. */\n seed?: number;\n}\n/**\n * 2.3: groups of three dark bars on a light plate (the three-bar concept of the US Air Force 1951 target,\n * a US-government publication, in the engine's own arrangement): one group per frequency, vertical bars (horizontal resolution)\n * in the upper row and horizontal bars (vertical resolution) below, optionally labelled with engine-drawn\n * seven-segment numerals. Frequencies are line widths per picture height (LW/PH, as in ISO 12233), where\n * the picture height is the chart's height: one bar is PH/LW wide.\n */\nexport interface BarGroupsChartScene {\n preset: \"bar-groups\";\n /** One group per entry, left to right: integers 1..100000. Default [100, 200, 400, 800]. 1..32 entries. */\n lineWidthsPerPictureHeight?: readonly number[];\n /** Draw each group's LW/PH value below it. Default true. */\n numerals?: boolean;\n darkReflectance?: number;\n lightReflectance?: number;\n}\n/**\n * 2.3: hyperbolic wedge: `lineCount` dark lines separated by light gaps of the same width, whose width\n * shrinks along the wedge axis so that the frequency rises linearly from the minimum to the maximum LW/PH.\n * The line edges are hyperbolas. `horizontal`: the axis runs left to right and the lines are nearly\n * horizontal (vertical resolution); `vertical`: the axis runs bottom to top (horizontal resolution).\n */\nexport interface HyperbolicWedgeChartScene {\n preset: \"hyperbolic-wedge\";\n orientation?: \"horizontal\" | \"vertical\";\n /** Dark lines, 1..50. Default 5. */\n lineCount?: number;\n /** LW/PH at the start and end of the axis. Defaults 100 and 1000. */\n minimumLineWidthsPerPictureHeight?: number;\n maximumLineWidthsPerPictureHeight?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n}\n/**\n * 2.3: circular zone plate R(r) = mid + amp·cos(π·k·r²): the local frequency k·r rises linearly from 0 at\n * the centre to `maximumCyclesPerPictureHeight` at the rim (the quadratic-phase chirp of a Fresnel zone\n * plate). Quantized to {@link CHART_CONTINUOUS_LEVELS} levels.\n */\nexport interface ZonePlateChartScene {\n preset: \"zone-plate\";\n /** Plate radius as a fraction of the frame half-height, (0, 1]. Default 0.9. */\n radiusFraction?: number;\n /** Frequency at the rim, cycles per picture height. Default 200. */\n maximumCyclesPerPictureHeight?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n backgroundReflectance?: number;\n}\n/**\n * 2.3: a field of dark squares rotated clockwise by `angleDegrees` on a light background, one centred in\n * each of columns × rows equal cells: every square gives two near-vertical and two near-horizontal slanted\n * edges (Burns, PICS 2000). See {@link calculateSlantedSquareEdges}.\n */\nexport interface SlantedSquaresChartScene {\n preset: \"slanted-squares\";\n columns?: number;\n rows?: number;\n /** Square side as a fraction of the smaller cell side, (0, 1); the rotated square must stay in its cell. Default 0.5. */\n sizeFraction?: number;\n /** Clockwise rotation, degrees, in (-45, 45). Default 5. */\n angleDegrees?: number;\n /** Square (dark) and background (light) reflectances. Defaults 0.15 and 0.6 (4:1). */\n darkReflectance?: number;\n lightReflectance?: number;\n}\n/** 2.3: straight lines at every multiple of `spacing` from the centre in u and v (a distortion and registration grid). */\nexport interface LineGridChartScene {\n preset: \"line-grid\";\n /** Distance between lines, frame units, (0, 2]. Default 1/3 (six cells across). */\n spacing?: number;\n /** Line width, frame units, (0, spacing). Default 0.01. */\n lineWidth?: number;\n lineReflectance?: number;\n backgroundReflectance?: number;\n}\n/** 2.3: registration fiducial: a 2 × 2 checker disk inside a dark ring; `inverted` swaps the checker phase (an orientation cue). */\nexport interface FiducialChartScene {\n preset: \"fiducial\";\n /** Disk radius as a fraction of the frame half-height, (0, 1]. Default 0.8. */\n radiusFraction?: number;\n /** Ring width as a fraction of the radius, (0, 1). Default 0.18. */\n ringFraction?: number;\n /** Default false: the upper-right and lower-left quadrants are dark. */\n inverted?: boolean;\n darkReflectance?: number;\n lightReflectance?: number;\n backgroundReflectance?: number;\n}\n/** Any chart preset except `composite`: a composite's background or element. */\nexport type ChartElementScene = UniformChartScene | SlantedEdgeChartScene | SiemensStarChartScene | StepWedgeChartScene | GreyRampChartScene |\n CheckerboardChartScene | PointGridChartScene | PatchChartScene | DeadLeavesChartScene | BarGroupsChartScene | HyperbolicWedgeChartScene |\n ZonePlateChartScene | SlantedSquaresChartScene | LineGridChartScene | FiducialChartScene;\n/**\n * One element of a composite chart: a preset drawn inside its placement rectangle (frame units of the\n * composite). The element sees its own frame: u = ±1 at the rectangle's left and right edges, aspect =\n * height / width, and LW/PH frequencies still refer to the composite's picture height.\n */\nexport interface CompositeChartElement {\n scene: ChartElementScene;\n centerU: number;\n centerV: number;\n width: number;\n height: number;\n /** `rectangle` (default) or `ellipse` inscribed in the rectangle; outside it, earlier elements or the background show. */\n mask?: \"rectangle\" | \"ellipse\";\n}\n/**\n * 2.3: an ordered list of elements over a background. Later elements cover earlier ones. The engine\n * provides only the generic parts; a branded or product-specific layout stays in the application.\n */\nexport interface CompositeChartScene {\n preset: \"composite\";\n /** Fills the whole composite frame. Default `{ preset: \"uniform\", reflectance: 0.18 }`. */\n background?: ChartElementScene;\n /** 1..256 elements, drawn in order. */\n elements: readonly CompositeChartElement[];\n}\nexport type ChartScene = ChartElementScene | CompositeChartScene;\nexport type ChartScenePresetId = ChartScene[\"preset\"];\nexport const CHART_SCENE_PRESETS: readonly ChartScenePresetId[] = Object.freeze([\"uniform\", \"slanted-edge\", \"siemens-star\",\n \"step-wedge\", \"grey-ramp\", \"checkerboard\", \"point-grid\", \"patches\", \"dead-leaves\", \"bar-groups\", \"hyperbolic-wedge\", \"zone-plate\",\n \"slanted-squares\", \"line-grid\", \"fiducial\", \"composite\"] as const);\n/** Neutral levels that represent a continuous pattern (grey ramp; 2.3 sine star, zone plate and dead-leaves greys). */\nexport const CHART_CONTINUOUS_LEVELS = 1024;\n\n/** Engine-chosen chart parameters, each reported when the caller omitted it. */\nexport const CHART_SCENE_DEFAULTS = Object.freeze({\n uniform: Object.freeze({ reflectance: 0.18 }),\n \"slanted-edge\": Object.freeze({ angleDegrees: 5, darkReflectance: 0.15, lightReflectance: 0.6 }),\n \"siemens-star\": Object.freeze({ cycles: 36, radiusFraction: 0.9, darkReflectance: 0.05, lightReflectance: 0.8, backgroundReflectance: 0.18 }),\n \"step-wedge\": Object.freeze({ steps: 11, minimumReflectance: 0.03, maximumReflectance: 0.9, spacing: \"equal-density\" as const }),\n \"grey-ramp\": Object.freeze({ minimumReflectance: 0.03, maximumReflectance: 0.9 }),\n checkerboard: Object.freeze({ squaresAcross: 8, darkReflectance: 0.05, lightReflectance: 0.8 }),\n \"point-grid\": Object.freeze({ columns: 5, rows: 3, radius: 0.01, pointReflectance: 0.9, backgroundReflectance: 0.02 }),\n patches: Object.freeze({ gapFraction: 0.1, backgroundReflectance: 0.18 }),\n \"dead-leaves\": Object.freeze({ radiusMinimum: 0.01, radiusMaximum: 0.5, minimumReflectance: 0.2, maximumReflectance: 0.6, seed: 1 }),\n \"bar-groups\": Object.freeze({ lineWidthsPerPictureHeight: Object.freeze([100, 200, 400, 800]), numerals: true, darkReflectance: 0.05, lightReflectance: 0.8 }),\n \"hyperbolic-wedge\": Object.freeze({ orientation: \"horizontal\" as const, lineCount: 5, minimumLineWidthsPerPictureHeight: 100,\n maximumLineWidthsPerPictureHeight: 1000, darkReflectance: 0.05, lightReflectance: 0.8 }),\n \"zone-plate\": Object.freeze({ radiusFraction: 0.9, maximumCyclesPerPictureHeight: 200, darkReflectance: 0.1, lightReflectance: 0.7, backgroundReflectance: 0.18 }),\n \"slanted-squares\": Object.freeze({ columns: 3, rows: 2, sizeFraction: 0.5, angleDegrees: 5, darkReflectance: 0.15, lightReflectance: 0.6 }),\n \"line-grid\": Object.freeze({ spacing: 1 / 3, lineWidth: 0.01, lineReflectance: 0.42, backgroundReflectance: 0.6 }),\n fiducial: Object.freeze({ radiusFraction: 0.8, ringFraction: 0.18, inverted: false, darkReflectance: 0.05, lightReflectance: 0.8, backgroundReflectance: 0.18 }),\n composite: Object.freeze({ background: Object.freeze({ preset: \"uniform\" as const, reflectance: 0.18 }) })\n});\n\n/** A validated chart: every parameter resolved, plus which ones came from {@link CHART_SCENE_DEFAULTS}. */\nexport interface ResolvedChartScene {\n preset: ChartScenePresetId;\n /** Fully resolved parameters (spectra are reported as `\"caller-spectrum\"`). */\n parameters: Readonly<Record<string, unknown>>;\n /** Names of parameters filled from defaults. */\n defaultedParameters: readonly string[];\n /** Frame aspect (height / width) the chart was resolved for. */\n aspect: number;\n /**\n * Material index at a frame point (u right, v up). The index points into `materials`, starting at 0.\n * Points outside the framed rectangle still evaluate (the pattern continues as defined), so blur and\n * small framing differences stay well defined.\n */\n materialAt(u: number, v: number): number;\n /** Reflectance materials: a neutral number or a prepared caller spectrum. */\n materials: readonly ({ kind: \"neutral\"; reflectance: number } | { kind: \"spectrum\"; spectrum: PreparedColorimetricSpectrum })[];\n /** Reflectance in [0, 1] at a frame point and wavelength (nm). */\n reflectanceAt(u: number, v: number, wavelengthNanometers: number): number;\n}\n\nfunction reflectance(value: unknown, name: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1) throw new InvalidConfigurationError(name + \" must be a reflectance in [0, 1].\");\n return value;\n}\nfunction integerIn(value: unknown, name: string, minimum: number, maximum: number): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < minimum || value > maximum) throw new InvalidConfigurationError(name + \" must be an integer from \" + minimum + \" to \" + maximum + \".\");\n return value;\n}\nfunction finiteIn(value: unknown, name: string, minimum: number, maximum: number, open = false): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < minimum || value > maximum || (open && (value === minimum || value === maximum)))\n throw new InvalidConfigurationError(name + \" is outside its supported range.\");\n return value;\n}\n/** Wavelength range every chart spectrum must cover (the facade's sensor quadrature range). */\nexport const CHART_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });\nfunction material(value: unknown, name: string): ResolvedChartScene[\"materials\"][number] {\n if (typeof value === \"number\") return { kind: \"neutral\", reflectance: reflectance(value, name) };\n let spectrum: PreparedColorimetricSpectrum;\n try { spectrum = prepareColorimetricSpectrum(value as ColorimetricSpectrum, name); } catch (error) {\n throw new InvalidConfigurationError(name + \" must be a neutral reflectance or a valid reflectance spectrum: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n const range = spectrum.wavelengthRangeNanometers;\n if (range.minimum > CHART_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < CHART_SPECTRAL_RANGE_NANOMETERS.maximum)\n throw new InvalidConfigurationError(name + \" must cover 380-780 nm.\");\n for (let nm = CHART_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= CHART_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 5) reflectance(spectrum.evaluate(nm), name + \" values\");\n return { kind: \"spectrum\", spectrum };\n}\n\n/** Raw caller spectrum inputs per material (undefined for neutral materials), for the facade's scene digest. */\nconst MATERIAL_INPUTS = new WeakMap<ResolvedChartScene, readonly unknown[]>();\n/**\n * Internal (not exported from the package): the caller input behind each material of a resolved chart, in\n * material order (`undefined` for an engine neutral). The facade hashes caller spectra from these inputs.\n */\nexport function chartMaterialInputs(chart: ResolvedChartScene): readonly unknown[] {\n return MATERIAL_INPUTS.get(chart) ?? chart.materials.map(() => undefined);\n}\n/** Frame context of a chart being resolved: the picture height (in its own frame units) its LW/PH frequencies refer to. */\ninterface ChartContext { pictureHeight: number; nested: boolean }\ntype Materials = ResolvedChartScene[\"materials\"][number][];\nconst neutralMaterials = (values: readonly number[]): Materials => values.map((reflectanceValue) => ({ kind: \"neutral\" as const, reflectance: reflectanceValue }));\n/** CHART_CONTINUOUS_LEVELS equal neutral levels between `from` and `to` (level i at from + (to − from)(i + ½)/levels). */\nfunction continuousMaterials(from: number, to: number): Materials {\n return Array.from({ length: CHART_CONTINUOUS_LEVELS }, (_, i) => ({ kind: \"neutral\" as const, reflectance: from + (to - from) * (i + 0.5) / CHART_CONTINUOUS_LEVELS }));\n}\n/** The level index of a continuous value between `from` and `to`. */\nfunction continuousLevel(value: number, from: number, to: number): number {\n return Math.min(CHART_CONTINUOUS_LEVELS - 1, Math.max(0, Math.floor((value - from) / (to - from) * CHART_CONTINUOUS_LEVELS)));\n}\nfunction booleanParameter(value: unknown, name: string): boolean {\n if (typeof value !== \"boolean\") throw new InvalidConfigurationError(name + \" must be true or false.\");\n return value;\n}\n\n/**\n * Validates a chart description and resolves every default. `aspect` is the frame height/width. Unknown\n * fields are rejected so that a mistyped parameter never silently falls back to a default.\n */\nexport function resolveChartScene(input: { scene: ChartScene; aspect: number }): ResolvedChartScene {\n requireInputObject(input, \"resolveChartScene input\");\n for (const key of Object.keys(input)) if (key !== \"scene\" && key !== \"aspect\") throw new InvalidConfigurationError(\"resolveChartScene input has unknown field \\\"\" + key + \"\\\".\");\n const { scene, aspect } = input;\n requireInputObject(scene, \"chart scene\");\n if (typeof aspect !== \"number\" || !Number.isFinite(aspect) || aspect <= 0) throw new InvalidConfigurationError(\"Chart aspect must be positive.\");\n return resolveScene(scene, aspect, { pictureHeight: 2 * aspect, nested: false });\n}\n\nfunction resolveScene(scene: unknown, aspect: number, context: ChartContext): ResolvedChartScene {\n requireInputObject(scene, \"chart scene\");\n const preset = (scene as { preset?: unknown }).preset;\n if (typeof preset !== \"string\" || !(CHART_SCENE_PRESETS as readonly string[]).includes(preset)) throw new InvalidConfigurationError(\"Unknown chart preset.\");\n if (preset === \"composite\" && context.nested) throw new InvalidConfigurationError(\"A composite chart cannot contain another composite.\");\n const record = scene as Record<string, unknown>;\n const defaults = CHART_SCENE_DEFAULTS[preset as ChartScenePresetId] as Record<string, unknown>;\n const extra = preset === \"patches\" ? [\"patches\", \"columns\"] : preset === \"composite\" ? [\"elements\"] : preset === \"siemens-star\" ? [\"profile\"] : [];\n const allowed = [\"preset\", ...Object.keys(defaults), ...extra];\n for (const key of Object.keys(record)) if (!allowed.includes(key)) throw new InvalidConfigurationError(\"Unknown chart parameter: \" + key + \".\");\n const defaulted: string[] = [];\n const get = (key: string): unknown => { if (record[key] === undefined) { if (key in defaults) defaulted.push(key); return defaults[key]; } return record[key]; };\n const neutral = (key: string): number => reflectance(get(key), key);\n const done = (parameters: Record<string, unknown>, materials: ResolvedChartScene[\"materials\"], materialAt: (u: number, v: number) => number,\n inputs?: readonly unknown[]): ResolvedChartScene => {\n const chart: ResolvedChartScene = Object.freeze({ preset: preset as ChartScenePresetId, parameters: Object.freeze(parameters), defaultedParameters: Object.freeze(defaulted), aspect,\n materials: Object.freeze(materials), materialAt,\n reflectanceAt(u: number, v: number, nm: number): number {\n const m = materials[materialAt(u, v)]!;\n if (m.kind === \"neutral\") return m.reflectance;\n const value = m.spectrum.evaluate(nm);\n if (!(value >= 0 && value <= 1)) throw new InvalidConfigurationError(\"Chart reflectance spectrum left [0, 1].\");\n return value;\n } });\n if (inputs) MATERIAL_INPUTS.set(chart, Object.freeze([...inputs]));\n return chart;\n };\n switch (preset as ChartScenePresetId) {\n case \"uniform\": {\n const raw = get(\"reflectance\"), m = material(raw, \"reflectance\");\n return done({ reflectance: typeof raw === \"number\" ? raw : \"caller-spectrum\" }, [m], () => 0, [typeof raw === \"number\" ? undefined : raw]);\n }\n case \"slanted-edge\": {\n const angle = finiteIn(get(\"angleDegrees\"), \"angleDegrees\", -45, 45, true), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\");\n const t = angle * Math.PI / 180, c = Math.cos(t), s = Math.sin(t);\n // Edge through the frame centre along (sin t, cos t); the light side is to the right.\n return done({ angleDegrees: angle, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }], (u, v) => (u * c - v * s >= 0 ? 1 : 0));\n }\n case \"siemens-star\": {\n const cycles = integerIn(get(\"cycles\"), \"cycles\", 2, 360), radius = finiteIn(get(\"radiusFraction\"), \"radiusFraction\", 0, 1, false);\n if (radius === 0) throw new InvalidConfigurationError(\"radiusFraction must be positive.\");\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), background = neutral(\"backgroundReflectance\"), r = radius * aspect;\n const profile = record.profile;\n if (profile !== undefined && profile !== \"bar\" && profile !== \"sine\") throw new InvalidConfigurationError(\"profile must be bar or sine.\");\n const parameters: Record<string, unknown> = { cycles, radiusFraction: radius, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background };\n if (profile === \"sine\") {\n // Sinusoidal star (2.3): zero crossings at the bar star's sector edges, light where the bar star is light.\n if (dark === light) throw new InvalidConfigurationError(\"A sine star needs different dark and light reflectances.\");\n const mid = (dark + light) / 2, amp = (light - dark) / 2, materials = continuousMaterials(dark, light);\n materials.push({ kind: \"neutral\", reflectance: background });\n return done({ ...parameters, profile, representation: CHART_CONTINUOUS_LEVELS + \" equal neutral levels\" }, materials, (u, v) => {\n if (u * u + v * v > r * r) return CHART_CONTINUOUS_LEVELS;\n const phase = Math.atan2(v, u) / (2 * Math.PI) + 0.5;\n return continuousLevel(mid + amp * Math.sin(2 * Math.PI * cycles * phase), dark, light);\n });\n }\n if (profile === \"bar\") parameters.profile = profile;\n return done(parameters,\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }, { kind: \"neutral\", reflectance: background }], (u, v) => {\n if (u * u + v * v > r * r) return 2;\n const phase = Math.atan2(v, u) / (2 * Math.PI) + 0.5; // [0, 1]\n return Math.floor(phase * 2 * cycles) % 2 === 0 ? 1 : 0;\n });\n }\n case \"step-wedge\": {\n const steps = integerIn(get(\"steps\"), \"steps\", 2, 64), lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\"), spacing = get(\"spacing\");\n if (spacing !== \"equal-density\" && spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n const values = calculateStepWedgeReflectances({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing });\n return done({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing, stepReflectances: values },\n values.map((reflectanceValue) => ({ kind: \"neutral\" as const, reflectance: reflectanceValue })),\n (u) => Math.min(steps - 1, Math.max(0, Math.floor((u + 1) / 2 * steps))));\n }\n case \"grey-ramp\": {\n const lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\");\n if (!(hi > lo)) throw new InvalidConfigurationError(\"Grey ramp needs minimum < maximum reflectance.\");\n // A continuous ramp is stored as 1024 neutral levels. The step size (< 0.1 % of the range) is far below sensor noise.\n const levels = 1024, materials = Array.from({ length: levels }, (_, i) => ({ kind: \"neutral\" as const, reflectance: lo + (hi - lo) * (i + 0.5) / levels }));\n return done({ minimumReflectance: lo, maximumReflectance: hi, representation: \"1024 equal neutral levels\" }, materials,\n (u) => Math.min(levels - 1, Math.max(0, Math.floor((u + 1) / 2 * levels))));\n }\n case \"checkerboard\": {\n const across = integerIn(get(\"squaresAcross\"), \"squaresAcross\", 2, 256), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), size = 2 / across;\n return done({ squaresAcross: across, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }],\n (u, v) => ((Math.floor((u + 1) / size) + Math.floor((aspect - v) / size)) % 2 === 0 ? 1 : 0));\n }\n case \"point-grid\": {\n const columns = integerIn(get(\"columns\"), \"columns\", 1, 256), rows = integerIn(get(\"rows\"), \"rows\", 1, 256);\n const radius = finiteIn(get(\"radius\"), \"radius\", 0, 1, true), point = neutral(\"pointReflectance\"), background = neutral(\"backgroundReflectance\");\n const centers = calculatePointGridCenters({ columns, rows, aspect });\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ columns, rows, radius, pointReflectance: point, backgroundReflectance: background },\n [{ kind: \"neutral\", reflectance: background }, { kind: \"neutral\", reflectance: point }], (u, v) => {\n const i = Math.min(columns - 1, Math.max(0, Math.floor((u + 1) / cellW))), j = Math.min(rows - 1, Math.max(0, Math.floor((aspect - v) / cellH)));\n const c = centers[j * columns + i]!;\n return (u - c.u) ** 2 + (v - c.v) ** 2 <= radius * radius ? 1 : 0;\n });\n }\n case \"patches\": {\n const list = record.patches;\n if (!Array.isArray(list) || list.length < 1 || list.length > 1024) throw new InvalidConfigurationError(\"patches must list 1 to 1024 caller reflectances.\");\n const ids = new Set<string>();\n const materials: ResolvedChartScene[\"materials\"][number][] = [], inputs: unknown[] = [];\n for (const [index, patch] of list.entries()) {\n requireInputObject(patch, \"patches[\" + index + \"]\");\n const p = patch as Record<string, unknown>;\n for (const key of Object.keys(p)) if (key !== \"patchId\" && key !== \"reflectance\") throw new InvalidConfigurationError(\"Unknown patch field: \" + key + \".\");\n if (typeof p.patchId !== \"string\" || p.patchId.trim() === \"\" || ids.has(p.patchId)) throw new InvalidConfigurationError(\"Each patch needs a unique non-empty patchId.\");\n ids.add(p.patchId);\n materials.push(material(p.reflectance, \"patches[\" + index + \"].reflectance\"));\n inputs.push(typeof p.reflectance === \"number\" ? undefined : p.reflectance);\n }\n const columnsRaw = record.columns === undefined ? Math.ceil(Math.sqrt(list.length)) : record.columns;\n if (record.columns === undefined) defaulted.push(\"columns\");\n const columns = integerIn(columnsRaw, \"columns\", 1, list.length), rows = Math.ceil(list.length / columns);\n const gap = finiteIn(get(\"gapFraction\"), \"gapFraction\", 0, 0.5), background = neutral(\"backgroundReflectance\");\n if (gap >= 0.5) throw new InvalidConfigurationError(\"gapFraction must be below 0.5.\");\n const backgroundIndex = materials.length;\n materials.push({ kind: \"neutral\", reflectance: background });\n inputs.push(undefined);\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ patchIds: list.map((p: { patchId: string }) => p.patchId), columns, rows, gapFraction: gap, backgroundReflectance: background }, materials, (u, v) => {\n const fx = (u + 1) / cellW, fy = (aspect - v) / cellH, i = Math.floor(fx), j = Math.floor(fy);\n if (i < 0 || j < 0 || i >= columns || j >= rows) return backgroundIndex;\n const index = j * columns + i, x = fx - i, y = fy - j;\n if (index >= list.length || x < gap / 2 || x > 1 - gap / 2 || y < gap / 2 || y > 1 - gap / 2) return backgroundIndex;\n return index;\n }, inputs);\n }\n case \"dead-leaves\": {\n const rMin = finiteIn(get(\"radiusMinimum\"), \"radiusMinimum\", DEAD_LEAVES_MINIMUM_RADIUS, 2), rMax = finiteIn(get(\"radiusMaximum\"), \"radiusMaximum\", 0, 2, true);\n if (!(rMax > rMin)) throw new InvalidConfigurationError(\"radiusMaximum must exceed radiusMinimum.\");\n const lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\"), seed = integerIn(get(\"seed\"), \"seed\", 0, 0xffffffff);\n if (hi < lo) throw new InvalidConfigurationError(\"Dead leaves need minimum ≤ maximum reflectance.\");\n const leaves = generateDeadLeaves(rMin, rMax, seed, aspect);\n return done({ radiusMinimum: rMin, radiusMaximum: rMax, minimumReflectance: lo, maximumReflectance: hi, seed, diskCount: leaves.diskCount,\n radiusDensity: \"proportional-to-r^-3\", representation: CHART_CONTINUOUS_LEVELS + \" equal neutral levels\" }, continuousMaterials(lo, hi), leaves.levelAt);\n }\n case \"bar-groups\": {\n const lws = get(\"lineWidthsPerPictureHeight\");\n if (!Array.isArray(lws) || lws.length < 1 || lws.length > 32) throw new InvalidConfigurationError(\"lineWidthsPerPictureHeight must list 1 to 32 frequencies.\");\n const list = lws.map((lw, i) => integerIn(lw, \"lineWidthsPerPictureHeight[\" + i + \"]\", 1, 100_000));\n const numerals = booleanParameter(get(\"numerals\"), \"numerals\"), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\");\n const layout = barGroupLayout(list, numerals, aspect, context.pictureHeight);\n return done({ lineWidthsPerPictureHeight: list, numerals, darkReflectance: dark, lightReflectance: light }, neutralMaterials([dark, light]), (u, v) => {\n for (const g of layout) {\n if (u < g.cell.u0 || u > g.cell.u1) continue;\n const b = g.verticalBars, h = g.horizontalBars;\n if (u >= b.u0 && u < b.u1 && v >= b.v0 && v <= b.v1) return Math.floor((u - b.u0) / g.lineWidth) % 2 === 0 ? 0 : 1;\n if (u >= h.u0 && u <= h.u1 && v > h.v0 && v <= h.v1) return Math.floor((h.v1 - v) / g.lineWidth) % 2 === 0 ? 0 : 1;\n if (g.label && numeralInk(g.label, u, v)) return 0;\n return 1;\n }\n return 1;\n });\n }\n case \"hyperbolic-wedge\": {\n const orientation = get(\"orientation\");\n if (orientation !== \"horizontal\" && orientation !== \"vertical\") throw new InvalidConfigurationError(\"orientation must be horizontal or vertical.\");\n const lines = integerIn(get(\"lineCount\"), \"lineCount\", 1, 50);\n const lw0 = finiteIn(get(\"minimumLineWidthsPerPictureHeight\"), \"minimumLineWidthsPerPictureHeight\", 0, 1e6, true);\n const lw1 = finiteIn(get(\"maximumLineWidthsPerPictureHeight\"), \"maximumLineWidthsPerPictureHeight\", 0, 1e6, true);\n if (!(lw1 > lw0)) throw new InvalidConfigurationError(\"maximumLineWidthsPerPictureHeight must exceed minimumLineWidthsPerPictureHeight.\");\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), ph = context.pictureHeight;\n const across = orientation === \"horizontal\" ? 2 * aspect : 2;\n if ((2 * lines - 1) * ph / lw0 > across) throw new InvalidConfigurationError(\"The wedge's \" + (2 * lines - 1) + \" line widths at \" + lw0 + \" LW/PH do not fit across the chart.\");\n return done({ orientation, lineCount: lines, minimumLineWidthsPerPictureHeight: lw0, maximumLineWidthsPerPictureHeight: lw1, darkReflectance: dark, lightReflectance: light },\n neutralMaterials([dark, light]), (u, v) => {\n const s = orientation === \"horizontal\" ? (u + 1) / 2 : (v + aspect) / (2 * aspect), y = orientation === \"horizontal\" ? v : u;\n if (s < 0 || s > 1) return 1;\n const w = ph / (lw0 + (lw1 - lw0) * s), half = (2 * lines - 1) * w / 2;\n if (y < -half || y >= half) return 1;\n return Math.floor((y + half) / w) % 2 === 0 ? 0 : 1;\n });\n }\n case \"zone-plate\": {\n const radius = finiteIn(get(\"radiusFraction\"), \"radiusFraction\", 0, 1, false);\n if (radius === 0) throw new InvalidConfigurationError(\"radiusFraction must be positive.\");\n const fMax = finiteIn(get(\"maximumCyclesPerPictureHeight\"), \"maximumCyclesPerPictureHeight\", 0, 1e6, true);\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), background = neutral(\"backgroundReflectance\");\n if (dark === light) throw new InvalidConfigurationError(\"A zone plate needs different dark and light reflectances.\");\n // Local frequency of cos(π·k·r²) is k·r cycles per frame unit: k·R = fMax / PH at the rim.\n const r = radius * aspect, k = fMax / context.pictureHeight / r, mid = (dark + light) / 2, amp = (light - dark) / 2;\n const materials = continuousMaterials(dark, light);\n materials.push({ kind: \"neutral\", reflectance: background });\n return done({ radiusFraction: radius, maximumCyclesPerPictureHeight: fMax, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background,\n representation: CHART_CONTINUOUS_LEVELS + \" equal neutral levels\" }, materials, (u, v) => {\n const r2 = u * u + v * v;\n if (r2 > r * r) return CHART_CONTINUOUS_LEVELS;\n return continuousLevel(mid + amp * Math.cos(Math.PI * k * r2), dark, light);\n });\n }\n case \"slanted-squares\": {\n const columns = integerIn(get(\"columns\"), \"columns\", 1, 64), rows = integerIn(get(\"rows\"), \"rows\", 1, 64);\n const size = finiteIn(get(\"sizeFraction\"), \"sizeFraction\", 0, 1, true), angle = finiteIn(get(\"angleDegrees\"), \"angleDegrees\", -45, 45, true);\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\");\n const t = angle * Math.PI / 180, c = Math.cos(t), s = Math.sin(t);\n if (size * (Math.abs(c) + Math.abs(s)) > 1) throw new InvalidConfigurationError(\"The rotated squares must stay inside their cells: sizeFraction·(|cos θ| + |sin θ|) ≤ 1.\");\n const cellW = 2 / columns, cellH = 2 * aspect / rows, half = size * Math.min(cellW, cellH) / 2;\n return done({ columns, rows, sizeFraction: size, angleDegrees: angle, darkReflectance: dark, lightReflectance: light }, neutralMaterials([dark, light]), (u, v) => {\n const i = Math.min(columns - 1, Math.max(0, Math.floor((u + 1) / cellW))), j = Math.min(rows - 1, Math.max(0, Math.floor((aspect - v) / cellH)));\n const du = u - (-1 + (i + 0.5) * cellW), dv = v - (aspect - (j + 0.5) * cellH);\n const x = du * c - dv * s, y = du * s + dv * c;\n return Math.abs(x) <= half && Math.abs(y) <= half ? 0 : 1;\n });\n }\n case \"line-grid\": {\n const spacing = finiteIn(get(\"spacing\"), \"spacing\", 0, 2, true), width = finiteIn(get(\"lineWidth\"), \"lineWidth\", 0, spacing, true);\n const line = neutral(\"lineReflectance\"), background = neutral(\"backgroundReflectance\"), half = width / 2;\n return done({ spacing, lineWidth: width, lineReflectance: line, backgroundReflectance: background }, neutralMaterials([background, line]),\n (u, v) => (Math.abs(u - spacing * Math.round(u / spacing)) <= half || Math.abs(v - spacing * Math.round(v / spacing)) <= half ? 1 : 0));\n }\n case \"fiducial\": {\n const radius = finiteIn(get(\"radiusFraction\"), \"radiusFraction\", 0, 1, false), ring = finiteIn(get(\"ringFraction\"), \"ringFraction\", 0, 1, true);\n if (radius === 0) throw new InvalidConfigurationError(\"radiusFraction must be positive.\");\n const inverted = booleanParameter(get(\"inverted\"), \"inverted\"), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), background = neutral(\"backgroundReflectance\");\n const r = radius * aspect, inner = r * (1 - ring);\n return done({ radiusFraction: radius, ringFraction: ring, inverted, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background },\n neutralMaterials([dark, light, background]), (u, v) => {\n const r2 = u * u + v * v;\n if (r2 > r * r) return 2;\n if (r2 > inner * inner) return 0;\n return ((u >= 0) === (v >= 0)) !== inverted ? 0 : 1;\n });\n }\n case \"composite\": {\n const list = record.elements;\n if (!Array.isArray(list) || list.length < 1 || list.length > 256) throw new InvalidConfigurationError(\"elements must list 1 to 256 chart elements.\");\n const nested: ChartContext = { pictureHeight: context.pictureHeight, nested: true };\n const background = resolveScene(get(\"background\"), aspect, nested);\n const materials: Materials = [...background.materials], inputs: unknown[] = [...chartMaterialInputs(background)];\n for (const key of background.defaultedParameters) defaulted.push(\"background.parameters.\" + key);\n const elements = list.map((value: unknown, index: number) => {\n const name = \"elements[\" + index + \"]\";\n requireInputObject(value, name);\n const e = value as Record<string, unknown>;\n for (const key of Object.keys(e)) if (![\"scene\", \"centerU\", \"centerV\", \"width\", \"height\", \"mask\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + name + \" field: \" + key + \".\");\n const cu = finiteIn(e.centerU, name + \".centerU\", -1e6, 1e6), cv = finiteIn(e.centerV, name + \".centerV\", -1e6, 1e6);\n const width = finiteIn(e.width, name + \".width\", 0, 1e6, true), height = finiteIn(e.height, name + \".height\", 0, 1e6, true);\n const mask = e.mask === undefined ? \"rectangle\" : e.mask;\n if (mask !== \"rectangle\" && mask !== \"ellipse\") throw new InvalidConfigurationError(name + \".mask must be rectangle or ellipse.\");\n if (e.mask === undefined) defaulted.push(\"elements.\" + index + \".placement.mask\");\n // The element's own frame: u = ±1 across its width; frequencies keep the composite's picture height.\n const chart = resolveScene(e.scene, height / width, { pictureHeight: context.pictureHeight * 2 / width, nested: true });\n for (const key of chart.defaultedParameters) defaulted.push(\"elements.\" + index + \".parameters.\" + key);\n const offset = materials.length;\n materials.push(...chart.materials);\n inputs.push(...chartMaterialInputs(chart));\n return { chart, offset, cu, cv, hw: width / 2, hh: height / 2, scale: 2 / width, ellipse: mask === \"ellipse\",\n report: { preset: chart.preset, placement: { centerU: cu, centerV: cv, width, height, mask }, parameters: chart.parameters } };\n });\n return done({ background: { preset: background.preset, parameters: background.parameters }, elements: elements.map((e) => e.report) }, materials, (u, v) => {\n for (let i = elements.length - 1; i >= 0; i--) {\n const e = elements[i]!, du = u - e.cu, dv = v - e.cv;\n if (du < -e.hw || du > e.hw || dv < -e.hh || dv > e.hh) continue;\n if (e.ellipse && (du / e.hw) ** 2 + (dv / e.hh) ** 2 > 1) continue;\n return e.offset + e.chart.materialAt(du * e.scale, dv * e.scale);\n }\n return background.materialAt(u, v);\n }, inputs);\n }\n }\n}\n\n/** Smallest dead-leaves disk radius, frame units: bounds the lookup grid and the disk count. */\nconst DEAD_LEAVES_MINIMUM_RADIUS = 0.002;\n/** Dead-leaves work limits: lookup cells and disks. */\nconst DEAD_LEAVES_MAXIMUM_CELLS = 4_194_304, DEAD_LEAVES_MAXIMUM_DISKS = 4_000_000;\n/** The covered margin around the chart, frame units; beyond it the texture is its mean grey. */\nconst DEAD_LEAVES_MARGIN = 0.1;\n/**\n * Dead-leaves disks, drawn front to back: disk n lies under disks 0..n−1. Each disk is listed in the lookup\n * cells it overlaps that are not yet covered; a cell is closed as soon as one disk covers it entirely, so no\n * later disk can show in it. Drawing stops when every cell is closed (the domain is fully covered), which is\n * the backward perfect simulation of the stationary model (Kendall and Thönnes 1999). Deterministic: the\n * engine's xorshift32 stream, and only correctly rounded operations (+ − × ÷ and √) on the drawn values.\n */\nfunction generateDeadLeaves(rMin: number, rMax: number, seed: number, aspect: number): { diskCount: number; levelAt(u: number, v: number): number } {\n const u0 = -1 - DEAD_LEAVES_MARGIN, v0 = -aspect - DEAD_LEAVES_MARGIN, width = 2 + 2 * DEAD_LEAVES_MARGIN, height = 2 * aspect + 2 * DEAD_LEAVES_MARGIN;\n const cell = Math.max(rMin, Math.sqrt(width * height / DEAD_LEAVES_MAXIMUM_CELLS));\n const nx = Math.ceil(width / cell), ny = Math.ceil(height / cell), cells = nx * ny;\n if (!(cells <= DEAD_LEAVES_MAXIMUM_CELLS)) throw new InvalidConfigurationError(\"Dead leaves: the chart aspect is too extreme for the lookup grid.\");\n const closed = new Uint8Array(cells), head = new Int32Array(cells).fill(-1), tail = new Int32Array(cells).fill(-1);\n let next = new Int32Array(1 << 16), entryDisk = new Int32Array(1 << 16), entries = 0;\n let X = new Float64Array(1 << 14), Y = new Float64Array(1 << 14), R2 = new Float64Array(1 << 14), level = new Uint16Array(1 << 14);\n const a = 1 / (rMin * rMin), b = 1 / (rMax * rMax), random = createDeterministicUniformStream(seed);\n let open = cells, n = 0;\n while (open > 0) {\n if (n >= DEAD_LEAVES_MAXIMUM_DISKS) throw new InvalidConfigurationError(\"Dead leaves need more than \" + DEAD_LEAVES_MAXIMUM_DISKS + \" disks; raise radiusMinimum.\");\n // Inverse CDF of the density ∝ r⁻³ on [rMin, rMax]: r = (rMin⁻² − U·(rMin⁻² − rMax⁻²))^(−1/2).\n const r = 1 / Math.sqrt(a - random.next() * (a - b));\n const x = u0 - rMax + random.next() * (width + 2 * rMax), y = v0 - rMax + random.next() * (height + 2 * rMax);\n const grey = Math.min(CHART_CONTINUOUS_LEVELS - 1, Math.floor(random.next() * CHART_CONTINUOUS_LEVELS));\n if (n === X.length) {\n const grow = <T extends Float64Array | Uint16Array>(old: T, make: (length: number) => T): T => { const out = make(old.length * 2); out.set(old); return out; };\n X = grow(X, (l) => new Float64Array(l)); Y = grow(Y, (l) => new Float64Array(l)); R2 = grow(R2, (l) => new Float64Array(l)); level = grow(level, (l) => new Uint16Array(l));\n }\n X[n] = x; Y[n] = y; R2[n] = r * r; level[n] = grey;\n const i0 = Math.max(0, Math.floor((x - r - u0) / cell)), i1 = Math.min(nx - 1, Math.floor((x + r - u0) / cell));\n const j0 = Math.max(0, Math.floor((y - r - v0) / cell)), j1 = Math.min(ny - 1, Math.floor((y + r - v0) / cell));\n for (let j = j0; j <= j1; j++) {\n const cy0 = v0 + j * cell, cy1 = cy0 + cell, ny0 = Math.max(cy0, Math.min(y, cy1)) - y;\n for (let i = i0; i <= i1; i++) {\n const c = j * nx + i;\n if (closed[c]) continue;\n const cx0 = u0 + i * cell, cx1 = cx0 + cell, nx0 = Math.max(cx0, Math.min(x, cx1)) - x;\n if (nx0 * nx0 + ny0 * ny0 > r * r) continue;\n if (entries === next.length) {\n const grownNext = new Int32Array(entries * 2), grownDisk = new Int32Array(entries * 2);\n grownNext.set(next); grownDisk.set(entryDisk); next = grownNext; entryDisk = grownDisk;\n }\n entryDisk[entries] = n; next[entries] = -1;\n if (tail[c]! < 0) head[c] = entries; else next[tail[c]!] = entries;\n tail[c] = entries++;\n const fx = Math.max(Math.abs(cx0 - x), Math.abs(cx1 - x)), fy = Math.max(Math.abs(cy0 - y), Math.abs(cy1 - y));\n if (fx * fx + fy * fy <= r * r) { closed[c] = 1; open--; }\n }\n }\n n++;\n }\n const mean = CHART_CONTINUOUS_LEVELS / 2;\n return { diskCount: n, levelAt(u: number, v: number): number {\n const i = Math.floor((u - u0) / cell), j = Math.floor((v - v0) / cell);\n if (i < 0 || j < 0 || i >= nx || j >= ny) return mean;\n for (let e = head[j * nx + i]!; e >= 0; e = next[e]!) {\n const d = entryDisk[e]!, dx = u - X[d]!, dy = v - Y[d]!;\n if (dx * dx + dy * dy <= R2[d]!) return level[d]!;\n }\n return mean;\n } };\n}\n\n/** An axis-aligned rectangle in chart frame units: u0 ≤ u ≤ u1, v0 ≤ v ≤ v1. */\nexport interface ChartRectangle { u0: number; v0: number; u1: number; v1: number }\ninterface NumeralLabel { text: string; u0: number; v0: number; height: number }\ninterface BarGroup { lineWidthsPerPictureHeight: number; lineWidth: number; cell: { u0: number; u1: number }; verticalBars: ChartRectangle; horizontalBars: ChartRectangle; label?: NumeralLabel }\n/**\n * Bar-group layout in the chart's own frame: G equal columns (80 % group, 20 % gap), rows from the top\n * 40 % vertical bars, 40 % horizontal bars, 20 % numerals (50 %/50 % without numerals), each row inset by\n * 5 % of its height. A group is five line widths (three dark bars, two light gaps) centred in its cell.\n */\nfunction barGroupLayout(list: readonly number[], numerals: boolean, aspect: number, pictureHeight: number): BarGroup[] {\n const H = 2 * aspect, weights = numerals ? [0.4, 0.4, 0.2] : [0.5, 0.5], column = 2 / list.length;\n const rows: { v0: number; v1: number }[] = [];\n let top = aspect;\n for (const w of weights) { const h = H * w; rows.push({ v0: top - h + 0.05 * h, v1: top - 0.05 * h }); top -= h; }\n return list.map((lw, i) => {\n const w = pictureHeight / lw, u0 = -1 + i * column + 0.1 * column, u1 = u0 + 0.8 * column, uc = (u0 + u1) / 2;\n const r0 = rows[0]!, r1 = rows[1]!, vc = (r1.v0 + r1.v1) / 2;\n if (5 * w > u1 - u0 || 5 * w > r1.v1 - r1.v0) throw new InvalidConfigurationError(\"The bar group at \" + lw + \" LW/PH (five line widths) does not fit its cell; use fewer groups or higher frequencies.\");\n const group: BarGroup = { lineWidthsPerPictureHeight: lw, lineWidth: w, cell: { u0, u1 },\n verticalBars: { u0: uc - 2.5 * w, v0: r0.v0, u1: uc + 2.5 * w, v1: r0.v1 }, horizontalBars: { u0, v0: vc - 2.5 * w, u1, v1: vc + 2.5 * w } };\n if (numerals) {\n const r2 = rows[2]!, text = String(lw), units = text.length * NUMERAL_ADVANCE - (NUMERAL_ADVANCE - NUMERAL_WIDTH);\n const height = Math.min(r2.v1 - r2.v0, (u1 - u0) / units);\n group.label = { text, u0: uc - units * height / 2, v0: (r2.v0 + r2.v1) / 2 - height / 2, height };\n }\n return group;\n });\n}\n/** Engine-drawn seven-segment numerals: a 0.6 × 1 cell per digit (baseline at 0, y up), stroke 0.16, advance 0.82. */\nconst NUMERAL_WIDTH = 0.6, NUMERAL_ADVANCE = 0.82;\nconst SEGMENTS: Readonly<Record<string, readonly [number, number, number, number]>> = Object.freeze({\n a: [0.08, 0.84, 0.52, 1], b: [0.44, 0.5, 0.6, 1], c: [0.44, 0, 0.6, 0.5], d: [0.08, 0, 0.52, 0.16], e: [0, 0, 0.16, 0.5], f: [0, 0.5, 0.16, 1], g: [0.08, 0.42, 0.52, 0.58] });\nconst DIGIT_SEGMENTS = [\"abcdef\", \"bc\", \"abged\", \"abgcd\", \"fgbc\", \"afgcd\", \"afgedc\", \"abc\", \"abcdefg\", \"abcdfg\"];\nfunction numeralInk(label: NumeralLabel, u: number, v: number): boolean {\n const x = (u - label.u0) / label.height, y = (v - label.v0) / label.height;\n if (y < 0 || y > 1 || x < 0) return false;\n const k = Math.floor(x / NUMERAL_ADVANCE);\n if (k >= label.text.length) return false;\n const cx = x - k * NUMERAL_ADVANCE;\n for (const s of DIGIT_SEGMENTS[label.text.charCodeAt(k) - 48]!) {\n const [x0, y0, x1, y1] = SEGMENTS[s]!;\n if (cx >= x0 && cx <= x1 && y >= y0 && y <= y1) return true;\n }\n return false;\n}\n\n/** Element placements of a resolved chart with a frame map to the chart's frame units (one identity entry for a plain preset). */\nfunction chartElements(chart: ResolvedChartScene): { index: number | null; preset: string; parameters: Record<string, unknown>; aspect: number; pictureHeight: number;\n toFrame(u: number, v: number): { u: number; v: number }; scale: number }[] {\n if (chart.preset !== \"composite\") return [{ index: null, preset: chart.preset, parameters: chart.parameters as Record<string, unknown>, aspect: chart.aspect,\n pictureHeight: 2 * chart.aspect, toFrame: (u, v) => ({ u, v }), scale: 1 }];\n const elements = (chart.parameters.elements as readonly { preset: string; placement: { centerU: number; centerV: number; width: number; height: number }; parameters: Record<string, unknown> }[]);\n return elements.map((e, index) => {\n const p = e.placement, s = p.width / 2;\n return { index, preset: e.preset, parameters: e.parameters, aspect: p.height / p.width, pictureHeight: 2 * chart.aspect / s,\n toFrame: (u: number, v: number) => ({ u: p.centerU + u * s, v: p.centerV + v * s }), scale: s };\n });\n}\nconst mapRectangle = (r: ChartRectangle, toFrame: (u: number, v: number) => { u: number; v: number }): ChartRectangle => {\n const a = toFrame(r.u0, r.v0), b = toFrame(r.u1, r.v1);\n return { u0: a.u, v0: a.v, u1: b.u, v1: b.v };\n};\n\n/** One bar group of a `bar-groups` chart or composite element, in the chart's frame units. */\nexport interface ChartBarGroupTarget {\n /** Composite element index, or null for a plain `bar-groups` chart. */\n elementIndex: number | null;\n lineWidthsPerPictureHeight: number;\n /** Line pairs (cycles) per picture height: LW/PH ÷ 2. */\n cyclesPerPictureHeight: number;\n /** Width of one bar, frame units. */\n lineWidth: number;\n /** The three vertical bars (horizontal resolution) and the three horizontal bars (vertical resolution). */\n verticalBars: ChartRectangle;\n horizontalBars: ChartRectangle;\n}\n/**\n * The bar groups of a `bar-groups` chart, or of every `bar-groups` element of a composite, in the chart's\n * frame units (2.3). `aspect` is the chart's height / width, as for {@link resolveChartScene}.\n */\nexport function calculateBarGroupTargets(input: { scene: ChartScene; aspect: number }): ChartBarGroupTarget[] {\n requireInputKeys(input, \"calculateBarGroupTargets\", [\"scene\", \"aspect\"]);\n const chart = resolveChartScene({ scene: input.scene, aspect: input.aspect });\n return chartElements(chart).filter((e) => e.preset === \"bar-groups\").flatMap((e) =>\n barGroupLayout(e.parameters.lineWidthsPerPictureHeight as number[], e.parameters.numerals as boolean, e.aspect, e.pictureHeight).map((g) => ({\n elementIndex: e.index, lineWidthsPerPictureHeight: g.lineWidthsPerPictureHeight, cyclesPerPictureHeight: g.lineWidthsPerPictureHeight / 2,\n lineWidth: g.lineWidth * e.scale, verticalBars: mapRectangle(g.verticalBars, e.toFrame), horizontalBars: mapRectangle(g.horizontalBars, e.toFrame) })));\n}\n\n/** One square of a `slanted-squares` chart and its four edges, in the chart's frame units. */\nexport interface ChartSlantedSquare {\n elementIndex: number | null;\n center: { u: number; v: number };\n /** Side length, frame units. */\n side: number;\n /** Clockwise rotation, degrees. */\n angleDegrees: number;\n darkReflectance: number;\n lightReflectance: number;\n /** `left`/`right` edges are near-vertical (horizontal MTF), `top`/`bottom` near-horizontal (vertical MTF). */\n edges: { side: \"left\" | \"right\" | \"top\" | \"bottom\"; midpoint: { u: number; v: number }; direction: { u: number; v: number }; length: number }[];\n}\n/**\n * Squares and edges of a `slanted-squares` chart, or of every `slanted-squares` element of a composite, in\n * the chart's frame units (2.3), for slanted-edge regions of interest (Burns, PICS 2000). Directions are unit\n * vectors along each edge (u right, v up).\n */\nexport function calculateSlantedSquareEdges(input: { scene: ChartScene; aspect: number }): ChartSlantedSquare[] {\n requireInputKeys(input, \"calculateSlantedSquareEdges\", [\"scene\", \"aspect\"]);\n const chart = resolveChartScene({ scene: input.scene, aspect: input.aspect });\n return chartElements(chart).filter((e) => e.preset === \"slanted-squares\").flatMap((e) => {\n const p = e.parameters as { columns: number; rows: number; sizeFraction: number; angleDegrees: number; darkReflectance: number; lightReflectance: number };\n const t = p.angleDegrees * Math.PI / 180, c = Math.cos(t), s = Math.sin(t), cellW = 2 / p.columns, cellH = 2 * e.aspect / p.rows;\n const half = p.sizeFraction * Math.min(cellW, cellH) / 2, out: ChartSlantedSquare[] = [];\n // Local square axes rotated clockwise by t: x̂ = (cos t, −sin t), ŷ = (sin t, cos t) in (u, v).\n const xAxis = { u: c, v: -s }, yAxis = { u: s, v: c };\n for (let j = 0; j < p.rows; j++) for (let i = 0; i < p.columns; i++) {\n const cu = -1 + (i + 0.5) * cellW, cv = e.aspect - (j + 0.5) * cellH, at = (x: number, y: number): { u: number; v: number } => e.toFrame(cu + x * xAxis.u + y * yAxis.u, cv + x * xAxis.v + y * yAxis.v);\n const length = 2 * half * e.scale;\n out.push({ elementIndex: e.index, center: e.toFrame(cu, cv), side: length, angleDegrees: p.angleDegrees, darkReflectance: p.darkReflectance, lightReflectance: p.lightReflectance,\n edges: [{ side: \"left\", midpoint: at(-half, 0), direction: yAxis, length }, { side: \"right\", midpoint: at(half, 0), direction: yAxis, length },\n { side: \"top\", midpoint: at(0, half), direction: xAxis, length }, { side: \"bottom\", midpoint: at(0, -half), direction: xAxis, length }] });\n }\n return out;\n });\n}\n\n/**\n * Step reflectances of a step wedge. `equal-density` spaces optical density D = -log10(R) evenly, which\n * gives geometric reflectance steps, as on a photographic step tablet. `linear` spaces reflectance evenly.\n */\nexport function calculateStepWedgeReflectances(input: { steps: number; minimumReflectance: number; maximumReflectance: number;\n spacing: \"equal-density\" | \"linear\" }): number[] {\n requireInputKeys(input, \"calculateStepWedgeReflectances\", [\"steps\", \"minimumReflectance\", \"maximumReflectance\", \"spacing\"]);\n const steps = integerIn(input.steps, \"steps\", 2, 64), lo = reflectance(input.minimumReflectance, \"minimumReflectance\"), hi = reflectance(input.maximumReflectance, \"maximumReflectance\");\n if (input.spacing !== \"equal-density\" && input.spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (input.spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n return Array.from({ length: steps }, (_, k) => {\n if (k === steps - 1) return hi;\n const t = k / (steps - 1);\n return input.spacing === \"linear\" ? lo + (hi - lo) * t : lo * (hi / lo) ** t;\n });\n}\n\n/** Centres (frame units) of a point grid: one disk centred in each of columns × rows equal cells, row-major from the top-left. */\nexport function calculatePointGridCenters(input: { columns: number; rows: number; aspect: number }): { u: number; v: number }[] {\n requireInputKeys(input, \"calculatePointGridCenters\", [\"columns\", \"rows\", \"aspect\"]);\n const columns = integerIn(input.columns, \"columns\", 1, 256), rows = integerIn(input.rows, \"rows\", 1, 256);\n if (typeof input.aspect !== \"number\" || !Number.isFinite(input.aspect) || input.aspect <= 0) throw new InvalidConfigurationError(\"aspect must be positive.\");\n const out: { u: number; v: number }[] = [];\n for (let j = 0; j < rows; j++) for (let i = 0; i < columns; i++) out.push({ u: -1 + (i + 0.5) * 2 / columns, v: input.aspect - (j + 0.5) * 2 * input.aspect / rows });\n return out;\n}\n"]}
@@ -53,6 +53,13 @@ export interface ScenePlanePoint {
53
53
  u: number;
54
54
  v: number;
55
55
  wavelengthNanometers: number;
56
+ /**
57
+ * 2.3, only with a fixed-size chart (`chartSize`): the point in chart-local frame units (±1 at the chart's
58
+ * left/right edges, v up on the same scale, ±chart height/width at its top/bottom). The function is then
59
+ * called only for points on the chart; the surround is the placement's surround reflectance.
60
+ */
61
+ chartU?: number;
62
+ chartV?: number;
56
63
  }
57
64
  /** Caller Lambertian reflectance (in [0, 1]) lit by the facade illuminant. */
58
65
  export interface CallerReflectanceScene {
@@ -70,6 +77,16 @@ export interface PlanarSceneGeometry {
70
77
  distanceM: number;
71
78
  /** Metres per frame unit on the plane (half the framed width). */
72
79
  metresPerFrameUnit: number;
80
+ /**
81
+ * 2.3, opt-in fixed-size chart: the chart is `widthM` × `heightM` on the plane, centred on the optical axis;
82
+ * outside it the plane is a neutral Lambertian surround of `surroundReflectance`, lit by the same illuminant.
83
+ * A chart preset is then resolved in its own frame (aspect heightM / widthM). Without it the chart fills the frame.
84
+ */
85
+ chart?: {
86
+ widthM: number;
87
+ heightM: number;
88
+ surroundReflectance: number;
89
+ };
73
90
  }
74
91
  export interface PlanarSceneRadianceProvider {
75
92
  sceneId: string;
@@ -78,6 +95,13 @@ export interface PlanarSceneRadianceProvider {
78
95
  evaluateApertureRadiance(request: Readonly<SceneRadianceEvaluationRequest>, ray: Readonly<SensorApertureRay>): SceneRadianceEvaluationResult;
79
96
  /** Spectral radiance at a plane point (frame units), the same value the callbacks return. */
80
97
  radianceAt(u: number, v: number, wavelengthNanometers: number): number;
98
+ /**
99
+ * 2.3, chart scenes only: the chart material at a plane point (frame units), or `materials.length` for the
100
+ * surround of a fixed-size chart; `materialRadiance` gives that material's spectral radiance, the same value
101
+ * `radianceAt` returns at its points.
102
+ */
103
+ chartMaterialAt?(u: number, v: number): number;
104
+ materialRadiance?(material: number, wavelengthNanometers: number): number;
81
105
  }
82
106
  /**
83
107
  * Wraps a chart or caller scene as a provider for the native environment RAW task. `irradianceScale` is
@@ -93,6 +117,24 @@ export declare function buildPlanarSceneRadianceProvider(input: {
93
117
  evidence: readonly EvidenceProvenance[];
94
118
  limitations: readonly string[];
95
119
  }): PlanarSceneRadianceProvider;
120
+ /** 2.3: a chart's physical size on the scene plane (`simulateCapture` `chartSize`, `createPlanarSceneRadianceProvider` `chartSize`). */
121
+ export interface ChartSizeOption {
122
+ /** Chart width in metres, (0, 10 000]. */
123
+ widthM: number;
124
+ /** Chart height in metres. Default: widthM × the frame aspect (height / width), so the chart has the frame's shape. */
125
+ heightM?: number;
126
+ /** Neutral reflectance of the plane around the chart, lit by the same illuminant. Default 0.18. */
127
+ surroundReflectance?: number;
128
+ }
129
+ /** Default surround of a fixed-size chart: an 18 % grey plane. */
130
+ export declare const CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE = 0.18;
131
+ /** Internal: validates a chart size and fills its defaults; `defaulted` names the fields taken from defaults. */
132
+ export declare function resolveChartSizeOption(value: unknown, frameAspect: number): {
133
+ widthM: number;
134
+ heightM: number;
135
+ surroundReflectance: number;
136
+ defaulted: ("heightM" | "surroundReflectance")[];
137
+ };
96
138
  /**
97
139
  * Public scene-preset provider. Places an engine chart (or a caller reflectance or radiance function) on
98
140
  * a plane `distanceM` in front of the camera and `framedWidthM` wide (frame units u = ±1 at its edges),
@@ -110,6 +152,11 @@ export declare function createPlanarSceneRadianceProvider(input: {
110
152
  aspect: number;
111
153
  sceneId: string;
112
154
  providerProfileId: string;
155
+ /**
156
+ * 2.3, opt-in: place the chart at this physical size, centred, instead of filling the frame; the chart preset
157
+ * is resolved with aspect heightM / widthM and the rest of the plane is the surround.
158
+ */
159
+ chartSize?: ChartSizeOption;
113
160
  }): PlanarSceneRadianceProvider & {
114
161
  chart: ResolvedChartScene | null;
115
162
  };
@@ -118,10 +118,22 @@ export function buildPlanarSceneRadianceProvider(input) {
118
118
  const scale = geometry.metresPerFrameUnit, distance = geometry.distanceM, sceneId = input.sceneId, providerProfileId = input.providerProfileId;
119
119
  const evidence = input.evidence, limitations = input.limitations;
120
120
  const caller = "kind" in scene ? scene : undefined, chart = caller ? undefined : scene;
121
+ const placed = geometry.chart, half = placed ? placed.widthM / 2 : 0, chartAspect = placed ? placed.heightM / placed.widthM : 0;
121
122
  function radianceAt(u, v, nm) {
123
+ if (placed) {
124
+ // Fixed-size chart (2.3): chart-local frame units from the plane point in metres.
125
+ const xM = u * scale, yM = v * scale, cu = xM / half, cv = yM / half;
126
+ if (!(Math.abs(cu) <= 1 && Math.abs(cv) <= chartAspect))
127
+ return placed.surroundReflectance * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;
128
+ if (chart)
129
+ return chart.reflectanceAt(cu, cv, nm) * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;
130
+ return callerValue(Object.freeze({ xM, yM, u, v, wavelengthNanometers: nm, chartU: cu, chartV: cv }), nm);
131
+ }
122
132
  if (chart)
123
133
  return chart.reflectanceAt(u, v, nm) * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;
124
- const point = Object.freeze({ xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm });
134
+ return callerValue(Object.freeze({ xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm }), nm);
135
+ }
136
+ function callerValue(point, nm) {
125
137
  const value = caller.evaluate(point);
126
138
  if (caller.kind === "reflectance-function") {
127
139
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1)
@@ -137,8 +149,32 @@ export function buildPlanarSceneRadianceProvider(input) {
137
149
  wavelengthBasis: request.wavelengthBasis, quantity: "outgoing-spectral-radiance", unit: "W/m^2/sr/nm",
138
150
  spectralRadianceWattsPerSquareMeterSteradianNanometer: radiance, scientificStatus: "approximation", uncertainty: UNCERTAINTY, evidence, limitations };
139
151
  }
152
+ const chartAccess = chart ? {
153
+ chartMaterialAt(u, v) {
154
+ if (!placed)
155
+ return chart.materialAt(u, v);
156
+ const cu = u * scale / half, cv = v * scale / half;
157
+ return Math.abs(cu) <= 1 && Math.abs(cv) <= chartAspect ? chart.materialAt(cu, cv) : chart.materials.length;
158
+ },
159
+ materialRadiance(material, nm) {
160
+ const m = chart.materials[material];
161
+ let value;
162
+ if (m === undefined)
163
+ value = placed ? placed.surroundReflectance : NaN;
164
+ else if (m.kind === "neutral")
165
+ value = m.reflectance;
166
+ else {
167
+ value = m.spectrum.evaluate(nm);
168
+ if (!(value >= 0 && value <= 1))
169
+ throw new InvalidConfigurationError("Chart reflectance spectrum left [0, 1].");
170
+ }
171
+ if (!(value >= 0))
172
+ throw new InvalidConfigurationError("Unknown chart material.");
173
+ return value * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;
174
+ }
175
+ } : {};
140
176
  return {
141
- sceneId, providerProfileId, radianceAt,
177
+ sceneId, providerProfileId, radianceAt, ...chartAccess,
142
178
  evaluateRadiance(request) {
143
179
  const target = request.target;
144
180
  if (target.kind !== "environment-direction")
@@ -158,6 +194,28 @@ export function buildPlanarSceneRadianceProvider(input) {
158
194
  }
159
195
  };
160
196
  }
197
+ /** Default surround of a fixed-size chart: an 18 % grey plane. */
198
+ export const CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE = 0.18;
199
+ /** Internal: validates a chart size and fills its defaults; `defaulted` names the fields taken from defaults. */
200
+ export function resolveChartSizeOption(value, frameAspect) {
201
+ requireInputObject(value, "chartSize");
202
+ const record = value;
203
+ for (const key of Object.keys(record))
204
+ if (!["widthM", "heightM", "surroundReflectance"].includes(key))
205
+ throw new InvalidConfigurationError("Unknown chartSize field: " + key + ".");
206
+ const size = (x, name) => {
207
+ if (typeof x !== "number" || !Number.isFinite(x) || x <= 0 || x > 10_000)
208
+ throw new InvalidConfigurationError("chartSize." + name + " must be a positive number of metres up to 10000.");
209
+ return x;
210
+ };
211
+ const defaulted = [];
212
+ const widthM = size(record.widthM, "widthM");
213
+ const heightM = record.heightM === undefined ? (defaulted.push("heightM"), widthM * frameAspect) : size(record.heightM, "heightM");
214
+ const surround = record.surroundReflectance === undefined ? (defaulted.push("surroundReflectance"), CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE) : record.surroundReflectance;
215
+ if (typeof surround !== "number" || !Number.isFinite(surround) || surround < 0 || surround > 1)
216
+ throw new InvalidConfigurationError("chartSize.surroundReflectance must be a reflectance in [0, 1].");
217
+ return { widthM, heightM, surroundReflectance: surround, defaulted };
218
+ }
161
219
  /**
162
220
  * Public scene-preset provider. Places an engine chart (or a caller reflectance or radiance function) on
163
221
  * a plane `distanceM` in front of the camera and `framedWidthM` wide (frame units u = ±1 at its edges),
@@ -167,7 +225,7 @@ export function buildPlanarSceneRadianceProvider(input) {
167
225
  */
168
226
  export function createPlanarSceneRadianceProvider(input) {
169
227
  requireInputObject(input, "createPlanarSceneRadianceProvider input");
170
- const keys = ["scene", "illuminant", "illuminanceLux", "distanceM", "framedWidthM", "aspect", "sceneId", "providerProfileId"];
228
+ const keys = ["scene", "illuminant", "illuminanceLux", "distanceM", "framedWidthM", "aspect", "sceneId", "providerProfileId", "chartSize"];
171
229
  for (const key of Object.keys(input))
172
230
  if (!keys.includes(key))
173
231
  throw new InvalidConfigurationError("createPlanarSceneRadianceProvider input has unknown field \"" + key + "\".");
@@ -181,11 +239,13 @@ export function createPlanarSceneRadianceProvider(input) {
181
239
  throw new InvalidConfigurationError(key + " must be a public opaque ID.");
182
240
  requireInputObject(input.scene, "scene");
183
241
  const caller = "kind" in input.scene ? requireCallerScene(input.scene) : undefined;
184
- const chart = caller ? null : resolveChartScene({ scene: input.scene, aspect: input.aspect });
242
+ const size = input.chartSize === undefined ? undefined : resolveChartSizeOption(input.chartSize, input.aspect);
243
+ const chart = caller ? null : resolveChartScene({ scene: input.scene, aspect: size ? size.heightM / size.widthM : input.aspect });
185
244
  const illuminant = resolveCaptureIlluminant(input.illuminant);
186
245
  const provider = buildPlanarSceneRadianceProvider({ scene: chart ?? caller, sceneId: input.sceneId, providerProfileId: input.providerProfileId, illuminant,
187
246
  irradianceScale: calculateIlluminantIrradianceScale(illuminant.shape, input.illuminanceLux),
188
- geometry: { distanceM: input.distanceM, metresPerFrameUnit: input.framedWidthM / 2 },
247
+ geometry: { distanceM: input.distanceM, metresPerFrameUnit: input.framedWidthM / 2,
248
+ ...(size ? { chart: { widthM: size.widthM, heightM: size.heightM, surroundReflectance: size.surroundReflectance } } : {}) },
189
249
  evidence: [{ sourceOrigin: "photivra", sourceReference: "photivra:planar-scene-provider", reuseStatus: "photivra-owned" }],
190
250
  limitations: ["Planar Lambertian scene under uniform illumination; no shadows, inter-reflection, gloss or fluorescence."] });
191
251
  return { ...provider, chart };