@pixerate/editor 0.21.0 → 0.23.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 (114) hide show
  1. package/README.md +100 -13
  2. package/THIRD_PARTY_NOTICES.md +88 -0
  3. package/dist/agent/index.cjs +86 -111
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +69 -211
  6. package/dist/agent/index.d.ts +69 -211
  7. package/dist/agent/index.js +77 -102
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/arrangeShortcuts-B8O3f8-P.d.cts +184 -0
  10. package/dist/arrangeShortcuts-sLlD2rSX.d.ts +184 -0
  11. package/dist/canvas/index.cjs +2112 -60
  12. package/dist/canvas/index.cjs.map +1 -1
  13. package/dist/canvas/index.d.cts +712 -181
  14. package/dist/canvas/index.d.ts +712 -181
  15. package/dist/canvas/index.js +2105 -53
  16. package/dist/canvas/index.js.map +1 -1
  17. package/dist/chunk-26BVFKHU.cjs +453 -0
  18. package/dist/chunk-26BVFKHU.cjs.map +1 -0
  19. package/dist/chunk-2H7ZHPEJ.js +762 -0
  20. package/dist/chunk-2H7ZHPEJ.js.map +1 -0
  21. package/dist/chunk-7DWMJCAT.js +453 -0
  22. package/dist/chunk-7DWMJCAT.js.map +1 -0
  23. package/dist/{chunk-TVRC4KVT.cjs → chunk-AA4ZEVCC.cjs} +845 -90
  24. package/dist/chunk-AA4ZEVCC.cjs.map +1 -0
  25. package/dist/chunk-ARRTP33I.js +101 -0
  26. package/dist/chunk-ARRTP33I.js.map +1 -0
  27. package/dist/{chunk-LA7PEGU3.cjs → chunk-CL37JGFW.cjs} +4 -4
  28. package/dist/{chunk-LA7PEGU3.cjs.map → chunk-CL37JGFW.cjs.map} +1 -1
  29. package/dist/chunk-CPOKFNBG.cjs +101 -0
  30. package/dist/chunk-CPOKFNBG.cjs.map +1 -0
  31. package/dist/chunk-G2I4QJOT.cjs +762 -0
  32. package/dist/chunk-G2I4QJOT.cjs.map +1 -0
  33. package/dist/{chunk-4QPLEUL2.cjs → chunk-GVSMRPHB.cjs} +1046 -54
  34. package/dist/chunk-GVSMRPHB.cjs.map +1 -0
  35. package/dist/{chunk-KYRZDWM4.js → chunk-JJDLPEWL.js} +2 -2
  36. package/dist/{chunk-GVW4P7BG.js → chunk-K3R5NG2D.js} +448 -54
  37. package/dist/chunk-K3R5NG2D.js.map +1 -0
  38. package/dist/{chunk-3TYMNULT.js → chunk-MJZBNWG7.js} +807 -52
  39. package/dist/chunk-MJZBNWG7.js.map +1 -0
  40. package/dist/{chunk-A7DKIA72.js → chunk-QBJ22YZR.js} +1059 -93
  41. package/dist/chunk-QBJ22YZR.js.map +1 -0
  42. package/dist/{chunk-CYFJCKC4.js → chunk-QGHGJ56O.js} +997 -5
  43. package/dist/chunk-QGHGJ56O.js.map +1 -0
  44. package/dist/{chunk-JYRIOFEN.cjs → chunk-RIKBJLS2.cjs} +1064 -98
  45. package/dist/chunk-RIKBJLS2.cjs.map +1 -0
  46. package/dist/{chunk-U6NDQFOK.cjs → chunk-XDMXXC4Z.cjs} +569 -175
  47. package/dist/chunk-XDMXXC4Z.cjs.map +1 -0
  48. package/dist/commands/index.cjs +860 -0
  49. package/dist/commands/index.cjs.map +1 -0
  50. package/dist/commands/index.d.cts +592 -0
  51. package/dist/commands/index.d.ts +592 -0
  52. package/dist/commands/index.js +860 -0
  53. package/dist/commands/index.js.map +1 -0
  54. package/dist/{controller-OUdxPY-X.d.ts → controller-pePCJLT1.d.cts} +216 -11
  55. package/dist/{controller-OUdxPY-X.d.cts → controller-pePCJLT1.d.ts} +216 -11
  56. package/dist/extensions/index.cjs +14 -4
  57. package/dist/extensions/index.cjs.map +1 -1
  58. package/dist/extensions/index.d.cts +3 -3
  59. package/dist/extensions/index.d.ts +3 -3
  60. package/dist/extensions/index.js +13 -3
  61. package/dist/history/index.cjs +12 -2
  62. package/dist/history/index.cjs.map +1 -1
  63. package/dist/history/index.d.cts +211 -7
  64. package/dist/history/index.d.ts +211 -7
  65. package/dist/history/index.js +13 -3
  66. package/dist/image-editor/index.cjs +418 -13
  67. package/dist/image-editor/index.cjs.map +1 -1
  68. package/dist/image-editor/index.d.cts +154 -3
  69. package/dist/image-editor/index.d.ts +154 -3
  70. package/dist/image-editor/index.js +417 -12
  71. package/dist/image-editor/index.js.map +1 -1
  72. package/dist/{index-k3mFbPx_.d.cts → index-CCr_z9kF.d.cts} +3 -3
  73. package/dist/{index-Ng1pG7JE.d.ts → index-Ck6ajwXh.d.ts} +3 -3
  74. package/dist/index.cjs +275 -83
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.cts +296 -47
  77. package/dist/index.d.ts +296 -47
  78. package/dist/index.js +266 -74
  79. package/dist/index.js.map +1 -1
  80. package/dist/registry-D5-R90p0.d.cts +209 -0
  81. package/dist/registry-D5-R90p0.d.ts +209 -0
  82. package/dist/{registry-iAHbqkYt.d.cts → registry-GJI4gToU.d.cts} +15 -4
  83. package/dist/{registry-iAHbqkYt.d.ts → registry-GJI4gToU.d.ts} +15 -4
  84. package/dist/serializers/index.cjs +3 -3
  85. package/dist/serializers/index.d.cts +1 -1
  86. package/dist/serializers/index.d.ts +1 -1
  87. package/dist/serializers/index.js +2 -2
  88. package/dist/spreadsheet/index.cjs +23 -3
  89. package/dist/spreadsheet/index.cjs.map +1 -1
  90. package/dist/spreadsheet/index.d.cts +97 -10
  91. package/dist/spreadsheet/index.d.ts +97 -10
  92. package/dist/spreadsheet/index.js +22 -2
  93. package/dist/{track-changes-G8JcWB8b.d.cts → track-changes-BSF58RK0.d.cts} +92 -9
  94. package/dist/{track-changes-G8JcWB8b.d.ts → track-changes-BSF58RK0.d.ts} +92 -9
  95. package/dist/{types-DMe0vFB1.d.cts → types-DX4Mh4SL.d.cts} +1 -1
  96. package/dist/{types-DMe0vFB1.d.ts → types-DX4Mh4SL.d.ts} +1 -1
  97. package/dist/types-GT5a5YAX.d.cts +86 -0
  98. package/dist/types-GT5a5YAX.d.ts +86 -0
  99. package/package.json +8 -2
  100. package/dist/chunk-2TWGLC5K.cjs +0 -262
  101. package/dist/chunk-2TWGLC5K.cjs.map +0 -1
  102. package/dist/chunk-3TYMNULT.js.map +0 -1
  103. package/dist/chunk-4QPLEUL2.cjs.map +0 -1
  104. package/dist/chunk-A7DKIA72.js.map +0 -1
  105. package/dist/chunk-CYFJCKC4.js.map +0 -1
  106. package/dist/chunk-GVW4P7BG.js.map +0 -1
  107. package/dist/chunk-JYRIOFEN.cjs.map +0 -1
  108. package/dist/chunk-KAADNAPF.js +0 -262
  109. package/dist/chunk-KAADNAPF.js.map +0 -1
  110. package/dist/chunk-TVRC4KVT.cjs.map +0 -1
  111. package/dist/chunk-U6NDQFOK.cjs.map +0 -1
  112. package/dist/types-BZgcDsC5.d.cts +0 -42
  113. package/dist/types-BZgcDsC5.d.ts +0 -42
  114. /package/dist/{chunk-KYRZDWM4.js.map → chunk-JJDLPEWL.js.map} +0 -0
@@ -24,8 +24,20 @@ interface ImageAdjustments {
24
24
  saturation: number;
25
25
  exposure: number;
26
26
  temperature: number;
27
+ /**
28
+ * -100 (green) to 100 (magenta), 0 is default. White-balance tint correction in Duv × 3000
29
+ * (process 2 only; the legacy process ignores it).
30
+ */
31
+ tint?: number;
27
32
  blur: number;
28
33
  opacity: number;
34
+ /**
35
+ * Rendering process the values are interpreted by. `2` (the latest; new edits and Reset get
36
+ * it): linear-light exposure, Bradford white balance, LUT tone curve without intermediate
37
+ * clipping. `1` or missing: the legacy 8-bit rendering, so edits saved before process
38
+ * versions existed look exactly as they did. See `normalizeProcessVersion`.
39
+ */
40
+ process?: 1 | 2;
29
41
  }
30
42
  interface DepthMaskOptions {
31
43
  enabled: boolean;
@@ -150,10 +162,27 @@ interface ImageEditorAIHooks {
150
162
  }
151
163
 
152
164
  /**
153
- * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, opacity, blur)
154
- * directly to the pixel data of an ImageData buffer.
165
+ * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,
166
+ * opacity, blur) directly to the pixel data of an ImageData buffer.
167
+ *
168
+ * `adjustments.process` selects the rendering: `2` is the linear-light pipeline
169
+ * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved
170
+ * before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).
155
171
  */
156
172
  declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
173
+ /**
174
+ * Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so
175
+ * that edits saved without a `process` look exactly as they always have. `tint` is ignored.
176
+ */
177
+ declare function applyLegacyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
178
+ /**
179
+ * Process 2: decode sRGB to linear float once; apply exposure (gain) and white balance (a
180
+ * Bradford matrix relative to as-shot) in linear light; a per-channel tone LUT for the
181
+ * highlight shoulder, contrast and brightness; luminance-preserving saturation in linear light;
182
+ * then encode back to sRGB through a LUT. Nothing is clamped between stages, only at the final
183
+ * encode. Neutral settings are the identity.
184
+ */
185
+ declare function applyProcess2Adjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
157
186
  /**
158
187
  * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.
159
188
  * Supports threshold range with softness gradation, brightness mode, and optional inversion.
@@ -165,6 +194,116 @@ declare function applyDepthMask(mainImageData: ImageData, maskImageData: ImageDa
165
194
  */
166
195
  declare function removeAlpha(imageData: ImageData): void;
167
196
 
197
+ /**
198
+ * Colour science for the image editor's process 2 rendering: sRGB transfer functions,
199
+ * correlated colour temperature / tint (Kim et al. Planckian locus, tint as Duv), Bradford
200
+ * white-balance adaptation relative to "as shot", and the display-referred tone curve.
201
+ */
202
+ /** A CIE 1931 chromaticity. */
203
+ interface Chromaticity {
204
+ x: number;
205
+ y: number;
206
+ }
207
+ /** A row-major 3×3 matrix (`[m00, m01, m02, m10, …, m22]`). */
208
+ type Matrix3 = [number, number, number, number, number, number, number, number, number];
209
+ /** The rendering of adjustments from before process versions existed. Frozen. */
210
+ declare const LEGACY_PROCESS_VERSION: 1;
211
+ /** The process new edits and Reset get. */
212
+ declare const LATEST_PROCESS_VERSION: 2;
213
+ type ImageProcessVersion = 1 | 2;
214
+ /**
215
+ * Reads a stored process number leniently: a missing or damaged value (not a whole number) is
216
+ * the legacy process, so a saved edit from before process versions renders exactly as it did. A
217
+ * whole number newer than this build knows renders with the latest process.
218
+ */
219
+ declare function normalizeProcessVersion(value: unknown): ImageProcessVersion;
220
+ declare function srgbToLinear(v: number): number;
221
+ declare function linearToSrgb(v: number): number;
222
+ /** Rec.709 / sRGB luminance weights (linear light). */
223
+ declare const LUMA_709: readonly [number, number, number];
224
+ declare const IDENTITY_MATRIX3: Matrix3;
225
+ declare function mulMatrix3(a: Matrix3, b: Matrix3): Matrix3;
226
+ declare function applyMatrix3(m: Matrix3, v: readonly [number, number, number]): [number, number, number];
227
+ declare function invertMatrix3(m: Matrix3): Matrix3 | null;
228
+ declare const D65: Chromaticity;
229
+ /** Bradford chromatic adaptation (XYZ → XYZ) from white `src` to white `dst`. */
230
+ declare function bradfordAdaptation(src: Chromaticity, dst: Chromaticity): Matrix3;
231
+ /**
232
+ * Matrix (linear sRGB → linear sRGB) that white-balances a scene lit by `src` so that it
233
+ * renders as if lit by D65.
234
+ */
235
+ declare function wbMatrix(src: Chromaticity): Matrix3;
236
+ /** The chromaticity of a linear sRGB colour. */
237
+ declare function linearSrgbToXy(rgb: readonly [number, number, number]): Chromaticity;
238
+ /** Tint units per unit of Duv. */
239
+ declare const TINT_SCALE = 3000;
240
+ declare const MIN_KELVIN = 1667;
241
+ declare const MAX_KELVIN = 25000;
242
+ /** CIE 1931 xy → CIE 1960 uv. */
243
+ declare function xyToUv(p: Chromaticity): [number, number];
244
+ /** CIE 1960 uv → CIE 1931 xy. */
245
+ declare function uvToXy(u: number, v: number): Chromaticity;
246
+ /**
247
+ * Source illuminant chromaticity for temperature `kelvin` and correction `tint`.
248
+ * Positive tint means a green source white, whose correction adds magenta to the image.
249
+ */
250
+ declare function tempTintToXy(kelvin: number, tint: number): Chromaticity;
251
+ /** Inverse of {@link tempTintToXy}: nearest locus temperature (searched in mired space) and tint. */
252
+ declare function xyToTempTint(p: Chromaticity): {
253
+ kelvin: number;
254
+ tint: number;
255
+ };
256
+ /** Rendered images carry no as-shot white: "as shot" is 6500 K / tint 0 and maps to the identity. */
257
+ declare const AS_SHOT_KELVIN = 6500;
258
+ /** Mireds per unit of the `temperature` slider (−100…100). */
259
+ declare const MIRED_PER_TEMPERATURE_UNIT = 1;
260
+ /**
261
+ * Maps the `temperature` slider (−100 cool … +100 warm) to the Kelvin white-balance setting:
262
+ * one mired per unit around 6500 K, so 0 → 6500 K, +100 → ~18 570 K (a strong warming
263
+ * correction), −100 → ~3 940 K (a strong cooling correction). Mireds are perceptually even,
264
+ * so equal slider steps look like equal changes.
265
+ */
266
+ declare function temperatureToKelvin(temperature: number): number;
267
+ /** Inverse of {@link temperatureToKelvin}. */
268
+ declare function kelvinToTemperature(kelvin: number): number;
269
+ /**
270
+ * White-balance matrix (linear sRGB) for the `temperature` / `tint` sliders, relative to
271
+ * "as shot": the identity at 0 / 0. Normalised so neutral luminance is preserved (white
272
+ * balance doesn't change exposure).
273
+ */
274
+ declare function whiteBalanceMatrix(temperature: number, tint?: number): Matrix3;
275
+ /**
276
+ * Neutral-point eyedropper: the `temperature` / `tint` that render the sampled sRGB colour
277
+ * (0–255 per channel, as it appears in the unadjusted image) neutral. Results are clamped to
278
+ * the slider range −100…100.
279
+ */
280
+ declare function whiteBalanceFromSample(rgb: readonly [number, number, number] | {
281
+ r: number;
282
+ g: number;
283
+ b: number;
284
+ }): {
285
+ temperature: number;
286
+ tint: number;
287
+ };
288
+ /** Number of intervals in a tone LUT (the table has `TONE_LUT_SIZE + 1` entries). */
289
+ declare const TONE_LUT_SIZE = 4096;
290
+ /**
291
+ * The process 2 tone curve for one linear input value in `[0, headroom]`:
292
+ *
293
+ * 1. A highlight shoulder (extended Reinhard with white point `headroom`) above a knee of 0.6
294
+ * rolls values above 1 (after exposure / white balance) back into range instead of clipping.
295
+ * With no headroom (`headroom = 1`) it is exactly the identity.
296
+ * 2. In a gamma-2.2 perceptual domain, contrast is an S-curve anchored at 0, middle grey and 1
297
+ * (as `ToneMap::display`), and brightness a midtone lift anchored at 0 and 1.
298
+ *
299
+ * `contrast` and `brightness` are −100…100; both 0 with `headroom = 1` is the identity.
300
+ */
301
+ declare function toneCurve(y: number, contrast: number, brightness: number, headroom?: number): number;
302
+ /** Tabulates {@link toneCurve} over `[0, headroom]` in {@link TONE_LUT_SIZE} steps. */
303
+ declare function buildToneLut(contrast: number, brightness: number, headroom?: number): Float32Array;
304
+ /** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */
305
+ declare function sampleToneLut(lut: Float32Array, headroom: number, y: number): number;
306
+
168
307
  interface RenderOptions {
169
308
  viewportWidth?: number;
170
309
  viewportHeight?: number;
@@ -246,6 +385,11 @@ declare class ImageEditorRenderer {
246
385
  }
247
386
 
248
387
  declare const DEFAULT_ADJUSTMENTS: ImageAdjustments;
388
+ /**
389
+ * Fills in defaults for stored adjustments. A stored object without `process` was saved before
390
+ * process versions existed and keeps the legacy rendering.
391
+ */
392
+ declare function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments;
249
393
  declare const DEFAULT_TRANSFORM: ImageTransform;
250
394
  declare const DEFAULT_DEPTH_MASK: DepthMaskOptions;
251
395
  /**
@@ -292,6 +436,13 @@ declare class ImageEditorController {
292
436
  flipHorizontal(): void;
293
437
  flipVertical(): void;
294
438
  setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory?: boolean): void;
439
+ /** True when the adjustments use an older rendering process than {@link LATEST_PROCESS_VERSION}. */
440
+ get isProcessOutdated(): boolean;
441
+ /**
442
+ * Update to Current Process: re-interprets the current adjustment values with the latest
443
+ * rendering process (one undo step). Returns false when already current.
444
+ */
445
+ upgradeProcess(): boolean;
295
446
  resetAdjustments(): void;
296
447
  setDepthMask(partial: Partial<DepthMaskOptions>): void;
297
448
  resetDepthMask(): void;
@@ -465,4 +616,4 @@ declare function getAnnotationBounds(ann: Annotation): {
465
616
  */
466
617
  declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
467
618
 
468
- export { type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, type LineAnnotation, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, isQuarterTurnSwapped, mapCropHandle, normalizeAngle, projectImagePoint, projectImageRect, removeAlpha, unprojectCanvasPoint };
619
+ export { AS_SHOT_KELVIN, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type Chromaticity, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, IDENTITY_MATRIX3, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type Matrix3, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, TINT_SCALE, TONE_LUT_SIZE, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, bradfordAdaptation, buildToneLut, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, invertMatrix3, isQuarterTurnSwapped, kelvinToTemperature, linearSrgbToXy, linearToSrgb, mapCropHandle, mulMatrix3, normalizeAngle, normalizeProcessVersion, normalizeStoredAdjustments, projectImagePoint, projectImageRect, removeAlpha, sampleToneLut, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, unprojectCanvasPoint, uvToXy, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };
@@ -24,8 +24,20 @@ interface ImageAdjustments {
24
24
  saturation: number;
25
25
  exposure: number;
26
26
  temperature: number;
27
+ /**
28
+ * -100 (green) to 100 (magenta), 0 is default. White-balance tint correction in Duv × 3000
29
+ * (process 2 only; the legacy process ignores it).
30
+ */
31
+ tint?: number;
27
32
  blur: number;
28
33
  opacity: number;
34
+ /**
35
+ * Rendering process the values are interpreted by. `2` (the latest; new edits and Reset get
36
+ * it): linear-light exposure, Bradford white balance, LUT tone curve without intermediate
37
+ * clipping. `1` or missing: the legacy 8-bit rendering, so edits saved before process
38
+ * versions existed look exactly as they did. See `normalizeProcessVersion`.
39
+ */
40
+ process?: 1 | 2;
29
41
  }
30
42
  interface DepthMaskOptions {
31
43
  enabled: boolean;
@@ -150,10 +162,27 @@ interface ImageEditorAIHooks {
150
162
  }
151
163
 
152
164
  /**
153
- * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, opacity, blur)
154
- * directly to the pixel data of an ImageData buffer.
165
+ * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,
166
+ * opacity, blur) directly to the pixel data of an ImageData buffer.
167
+ *
168
+ * `adjustments.process` selects the rendering: `2` is the linear-light pipeline
169
+ * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved
170
+ * before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).
155
171
  */
156
172
  declare function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
173
+ /**
174
+ * Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so
175
+ * that edits saved without a `process` look exactly as they always have. `tint` is ignored.
176
+ */
177
+ declare function applyLegacyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
178
+ /**
179
+ * Process 2: decode sRGB to linear float once; apply exposure (gain) and white balance (a
180
+ * Bradford matrix relative to as-shot) in linear light; a per-channel tone LUT for the
181
+ * highlight shoulder, contrast and brightness; luminance-preserving saturation in linear light;
182
+ * then encode back to sRGB through a LUT. Nothing is clamped between stages, only at the final
183
+ * encode. Neutral settings are the identity.
184
+ */
185
+ declare function applyProcess2Adjustments(imageData: ImageData, adjustments: ImageAdjustments): void;
157
186
  /**
158
187
  * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.
159
188
  * Supports threshold range with softness gradation, brightness mode, and optional inversion.
@@ -165,6 +194,116 @@ declare function applyDepthMask(mainImageData: ImageData, maskImageData: ImageDa
165
194
  */
166
195
  declare function removeAlpha(imageData: ImageData): void;
167
196
 
197
+ /**
198
+ * Colour science for the image editor's process 2 rendering: sRGB transfer functions,
199
+ * correlated colour temperature / tint (Kim et al. Planckian locus, tint as Duv), Bradford
200
+ * white-balance adaptation relative to "as shot", and the display-referred tone curve.
201
+ */
202
+ /** A CIE 1931 chromaticity. */
203
+ interface Chromaticity {
204
+ x: number;
205
+ y: number;
206
+ }
207
+ /** A row-major 3×3 matrix (`[m00, m01, m02, m10, …, m22]`). */
208
+ type Matrix3 = [number, number, number, number, number, number, number, number, number];
209
+ /** The rendering of adjustments from before process versions existed. Frozen. */
210
+ declare const LEGACY_PROCESS_VERSION: 1;
211
+ /** The process new edits and Reset get. */
212
+ declare const LATEST_PROCESS_VERSION: 2;
213
+ type ImageProcessVersion = 1 | 2;
214
+ /**
215
+ * Reads a stored process number leniently: a missing or damaged value (not a whole number) is
216
+ * the legacy process, so a saved edit from before process versions renders exactly as it did. A
217
+ * whole number newer than this build knows renders with the latest process.
218
+ */
219
+ declare function normalizeProcessVersion(value: unknown): ImageProcessVersion;
220
+ declare function srgbToLinear(v: number): number;
221
+ declare function linearToSrgb(v: number): number;
222
+ /** Rec.709 / sRGB luminance weights (linear light). */
223
+ declare const LUMA_709: readonly [number, number, number];
224
+ declare const IDENTITY_MATRIX3: Matrix3;
225
+ declare function mulMatrix3(a: Matrix3, b: Matrix3): Matrix3;
226
+ declare function applyMatrix3(m: Matrix3, v: readonly [number, number, number]): [number, number, number];
227
+ declare function invertMatrix3(m: Matrix3): Matrix3 | null;
228
+ declare const D65: Chromaticity;
229
+ /** Bradford chromatic adaptation (XYZ → XYZ) from white `src` to white `dst`. */
230
+ declare function bradfordAdaptation(src: Chromaticity, dst: Chromaticity): Matrix3;
231
+ /**
232
+ * Matrix (linear sRGB → linear sRGB) that white-balances a scene lit by `src` so that it
233
+ * renders as if lit by D65.
234
+ */
235
+ declare function wbMatrix(src: Chromaticity): Matrix3;
236
+ /** The chromaticity of a linear sRGB colour. */
237
+ declare function linearSrgbToXy(rgb: readonly [number, number, number]): Chromaticity;
238
+ /** Tint units per unit of Duv. */
239
+ declare const TINT_SCALE = 3000;
240
+ declare const MIN_KELVIN = 1667;
241
+ declare const MAX_KELVIN = 25000;
242
+ /** CIE 1931 xy → CIE 1960 uv. */
243
+ declare function xyToUv(p: Chromaticity): [number, number];
244
+ /** CIE 1960 uv → CIE 1931 xy. */
245
+ declare function uvToXy(u: number, v: number): Chromaticity;
246
+ /**
247
+ * Source illuminant chromaticity for temperature `kelvin` and correction `tint`.
248
+ * Positive tint means a green source white, whose correction adds magenta to the image.
249
+ */
250
+ declare function tempTintToXy(kelvin: number, tint: number): Chromaticity;
251
+ /** Inverse of {@link tempTintToXy}: nearest locus temperature (searched in mired space) and tint. */
252
+ declare function xyToTempTint(p: Chromaticity): {
253
+ kelvin: number;
254
+ tint: number;
255
+ };
256
+ /** Rendered images carry no as-shot white: "as shot" is 6500 K / tint 0 and maps to the identity. */
257
+ declare const AS_SHOT_KELVIN = 6500;
258
+ /** Mireds per unit of the `temperature` slider (−100…100). */
259
+ declare const MIRED_PER_TEMPERATURE_UNIT = 1;
260
+ /**
261
+ * Maps the `temperature` slider (−100 cool … +100 warm) to the Kelvin white-balance setting:
262
+ * one mired per unit around 6500 K, so 0 → 6500 K, +100 → ~18 570 K (a strong warming
263
+ * correction), −100 → ~3 940 K (a strong cooling correction). Mireds are perceptually even,
264
+ * so equal slider steps look like equal changes.
265
+ */
266
+ declare function temperatureToKelvin(temperature: number): number;
267
+ /** Inverse of {@link temperatureToKelvin}. */
268
+ declare function kelvinToTemperature(kelvin: number): number;
269
+ /**
270
+ * White-balance matrix (linear sRGB) for the `temperature` / `tint` sliders, relative to
271
+ * "as shot": the identity at 0 / 0. Normalised so neutral luminance is preserved (white
272
+ * balance doesn't change exposure).
273
+ */
274
+ declare function whiteBalanceMatrix(temperature: number, tint?: number): Matrix3;
275
+ /**
276
+ * Neutral-point eyedropper: the `temperature` / `tint` that render the sampled sRGB colour
277
+ * (0–255 per channel, as it appears in the unadjusted image) neutral. Results are clamped to
278
+ * the slider range −100…100.
279
+ */
280
+ declare function whiteBalanceFromSample(rgb: readonly [number, number, number] | {
281
+ r: number;
282
+ g: number;
283
+ b: number;
284
+ }): {
285
+ temperature: number;
286
+ tint: number;
287
+ };
288
+ /** Number of intervals in a tone LUT (the table has `TONE_LUT_SIZE + 1` entries). */
289
+ declare const TONE_LUT_SIZE = 4096;
290
+ /**
291
+ * The process 2 tone curve for one linear input value in `[0, headroom]`:
292
+ *
293
+ * 1. A highlight shoulder (extended Reinhard with white point `headroom`) above a knee of 0.6
294
+ * rolls values above 1 (after exposure / white balance) back into range instead of clipping.
295
+ * With no headroom (`headroom = 1`) it is exactly the identity.
296
+ * 2. In a gamma-2.2 perceptual domain, contrast is an S-curve anchored at 0, middle grey and 1
297
+ * (as `ToneMap::display`), and brightness a midtone lift anchored at 0 and 1.
298
+ *
299
+ * `contrast` and `brightness` are −100…100; both 0 with `headroom = 1` is the identity.
300
+ */
301
+ declare function toneCurve(y: number, contrast: number, brightness: number, headroom?: number): number;
302
+ /** Tabulates {@link toneCurve} over `[0, headroom]` in {@link TONE_LUT_SIZE} steps. */
303
+ declare function buildToneLut(contrast: number, brightness: number, headroom?: number): Float32Array;
304
+ /** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */
305
+ declare function sampleToneLut(lut: Float32Array, headroom: number, y: number): number;
306
+
168
307
  interface RenderOptions {
169
308
  viewportWidth?: number;
170
309
  viewportHeight?: number;
@@ -246,6 +385,11 @@ declare class ImageEditorRenderer {
246
385
  }
247
386
 
248
387
  declare const DEFAULT_ADJUSTMENTS: ImageAdjustments;
388
+ /**
389
+ * Fills in defaults for stored adjustments. A stored object without `process` was saved before
390
+ * process versions existed and keeps the legacy rendering.
391
+ */
392
+ declare function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments;
249
393
  declare const DEFAULT_TRANSFORM: ImageTransform;
250
394
  declare const DEFAULT_DEPTH_MASK: DepthMaskOptions;
251
395
  /**
@@ -292,6 +436,13 @@ declare class ImageEditorController {
292
436
  flipHorizontal(): void;
293
437
  flipVertical(): void;
294
438
  setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory?: boolean): void;
439
+ /** True when the adjustments use an older rendering process than {@link LATEST_PROCESS_VERSION}. */
440
+ get isProcessOutdated(): boolean;
441
+ /**
442
+ * Update to Current Process: re-interprets the current adjustment values with the latest
443
+ * rendering process (one undo step). Returns false when already current.
444
+ */
445
+ upgradeProcess(): boolean;
295
446
  resetAdjustments(): void;
296
447
  setDepthMask(partial: Partial<DepthMaskOptions>): void;
297
448
  resetDepthMask(): void;
@@ -465,4 +616,4 @@ declare function getAnnotationBounds(ann: Annotation): {
465
616
  */
466
617
  declare function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding?: number): boolean;
467
618
 
468
- export { type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, type LineAnnotation, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, isQuarterTurnSwapped, mapCropHandle, normalizeAngle, projectImagePoint, projectImageRect, removeAlpha, unprojectCanvasPoint };
619
+ export { AS_SHOT_KELVIN, type Annotation, type AnnotationType, type ArrowAnnotation, type AspectRatio, type BaseAnnotation, type Chromaticity, type CircleAnnotation, type CreateAnnotationPayload, type CropBox, type CropHandle, D65, DEFAULT_ADJUSTMENTS, DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, type DepthMaskOptions, type ExportOptions, IDENTITY_MATRIX3, type ImageAdjustments, type ImageAnnotation, type ImageDimensions, type ImageEditorAIHooks, ImageEditorController, type ImageEditorOptions, ImageEditorRenderer, type ImageEditorState, type ImageEditorTool, type ImagePoint, type ImageProcessVersion, type ImageProjection, type ImageTransform, type InpaintHook, type InpaintOptions, LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, LUMA_709, type LineAnnotation, MAX_KELVIN, MIN_KELVIN, MIRED_PER_TEMPERATURE_UNIT, type Matrix3, type PenAnnotation, type RectAnnotation, type RemoveBackgroundHook, type RemoveBackgroundOptions, type RenderOptions, type SerializedImageEditorState, TINT_SCALE, TONE_LUT_SIZE, type TextAnnotation, type ViewportMetrics, applyAdjustments, applyDepthMask, applyImageProjectionToContext, applyLegacyAdjustments, applyMatrix3, applyProcess2Adjustments, bradfordAdaptation, buildToneLut, calculateCropDrag, canvasToImagePoint, clampCropToImage, getAnnotationBounds, getCropCursor, getRotatedSize, getViewportMetrics, getViewportProjection, globalImageCache, hitTestAnnotation, hitTestCrop, imageToCanvasPoint, invertMatrix3, isQuarterTurnSwapped, kelvinToTemperature, linearSrgbToXy, linearToSrgb, mapCropHandle, mulMatrix3, normalizeAngle, normalizeProcessVersion, normalizeStoredAdjustments, projectImagePoint, projectImageRect, removeAlpha, sampleToneLut, srgbToLinear, tempTintToXy, temperatureToKelvin, toneCurve, unprojectCanvasPoint, uvToXy, wbMatrix, whiteBalanceFromSample, whiteBalanceMatrix, xyToTempTint, xyToUv };