react-native-parity-blur 0.1.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 (109) hide show
  1. package/LICENSE +20 -0
  2. package/ParityBlur.podspec +20 -0
  3. package/README.md +198 -0
  4. package/android/build.gradle +57 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/parityblur/AndroidBlurCalibration.kt +82 -0
  7. package/android/src/main/java/com/parityblur/BlurEngine.kt +132 -0
  8. package/android/src/main/java/com/parityblur/ParityBlurDebug.kt +24 -0
  9. package/android/src/main/java/com/parityblur/ParityBlurPackage.kt +17 -0
  10. package/android/src/main/java/com/parityblur/ParityBlurView.kt +542 -0
  11. package/android/src/main/java/com/parityblur/ParityBlurViewManager.kt +161 -0
  12. package/android/src/main/java/com/parityblur/PipelineMath.kt +202 -0
  13. package/android/src/main/java/com/parityblur/PixelCopySnapshotProvider.kt +108 -0
  14. package/android/src/main/java/com/parityblur/SoftwareSnapshotProvider.kt +173 -0
  15. package/android/src/main/java/com/parityblur/WindowBlurContext.kt +116 -0
  16. package/android/src/test/java/com/parityblur/MiniJson.kt +179 -0
  17. package/android/src/test/java/com/parityblur/PipelineFixturesTest.kt +222 -0
  18. package/ios/BlurEngine.swift +106 -0
  19. package/ios/ColorPipeline.swift +72 -0
  20. package/ios/MetalPresentationSurface.swift +51 -0
  21. package/ios/ParityBlurCoreView.swift +382 -0
  22. package/ios/ParityBlurDebug.swift +18 -0
  23. package/ios/ParityBlurView.h +14 -0
  24. package/ios/ParityBlurView.mm +135 -0
  25. package/ios/PipelineMath.swift +177 -0
  26. package/ios/SnapshotProvider.swift +128 -0
  27. package/ios/WindowBlurContext.swift +111 -0
  28. package/lib/module/BlurView.js +124 -0
  29. package/lib/module/BlurView.js.map +1 -0
  30. package/lib/module/ParityBlurViewNativeComponent.ts +82 -0
  31. package/lib/module/defaults.js +13 -0
  32. package/lib/module/defaults.js.map +1 -0
  33. package/lib/module/index.js +5 -0
  34. package/lib/module/index.js.map +1 -0
  35. package/lib/module/package.json +1 -0
  36. package/lib/module/pipeline/androidCalibration.js +55 -0
  37. package/lib/module/pipeline/androidCalibration.js.map +1 -0
  38. package/lib/module/pipeline/captureRect.js +151 -0
  39. package/lib/module/pipeline/captureRect.js.map +1 -0
  40. package/lib/module/pipeline/color.js +82 -0
  41. package/lib/module/pipeline/color.js.map +1 -0
  42. package/lib/module/pipeline/constants.js +65 -0
  43. package/lib/module/pipeline/constants.js.map +1 -0
  44. package/lib/module/pipeline/downsample.js +61 -0
  45. package/lib/module/pipeline/downsample.js.map +1 -0
  46. package/lib/module/pipeline/index.js +23 -0
  47. package/lib/module/pipeline/index.js.map +1 -0
  48. package/lib/module/pipeline/overlay.js +56 -0
  49. package/lib/module/pipeline/overlay.js.map +1 -0
  50. package/lib/module/pipeline/saturation.js +52 -0
  51. package/lib/module/pipeline/saturation.js.map +1 -0
  52. package/lib/module/pipeline/types.js +23 -0
  53. package/lib/module/pipeline/types.js.map +1 -0
  54. package/lib/module/pipeline/units.js +33 -0
  55. package/lib/module/pipeline/units.js.map +1 -0
  56. package/lib/module/presets.js +96 -0
  57. package/lib/module/presets.js.map +1 -0
  58. package/lib/module/types.js +4 -0
  59. package/lib/module/types.js.map +1 -0
  60. package/lib/typescript/package.json +1 -0
  61. package/lib/typescript/src/BlurView.d.ts +16 -0
  62. package/lib/typescript/src/BlurView.d.ts.map +1 -0
  63. package/lib/typescript/src/ParityBlurViewNativeComponent.d.ts +63 -0
  64. package/lib/typescript/src/ParityBlurViewNativeComponent.d.ts.map +1 -0
  65. package/lib/typescript/src/defaults.d.ts +12 -0
  66. package/lib/typescript/src/defaults.d.ts.map +1 -0
  67. package/lib/typescript/src/index.d.ts +5 -0
  68. package/lib/typescript/src/index.d.ts.map +1 -0
  69. package/lib/typescript/src/pipeline/androidCalibration.d.ts +42 -0
  70. package/lib/typescript/src/pipeline/androidCalibration.d.ts.map +1 -0
  71. package/lib/typescript/src/pipeline/captureRect.d.ts +84 -0
  72. package/lib/typescript/src/pipeline/captureRect.d.ts.map +1 -0
  73. package/lib/typescript/src/pipeline/color.d.ts +19 -0
  74. package/lib/typescript/src/pipeline/color.d.ts.map +1 -0
  75. package/lib/typescript/src/pipeline/constants.d.ts +52 -0
  76. package/lib/typescript/src/pipeline/constants.d.ts.map +1 -0
  77. package/lib/typescript/src/pipeline/downsample.d.ts +31 -0
  78. package/lib/typescript/src/pipeline/downsample.d.ts.map +1 -0
  79. package/lib/typescript/src/pipeline/index.d.ts +20 -0
  80. package/lib/typescript/src/pipeline/index.d.ts.map +1 -0
  81. package/lib/typescript/src/pipeline/overlay.d.ts +31 -0
  82. package/lib/typescript/src/pipeline/overlay.d.ts.map +1 -0
  83. package/lib/typescript/src/pipeline/saturation.d.ts +38 -0
  84. package/lib/typescript/src/pipeline/saturation.d.ts.map +1 -0
  85. package/lib/typescript/src/pipeline/types.d.ts +32 -0
  86. package/lib/typescript/src/pipeline/types.d.ts.map +1 -0
  87. package/lib/typescript/src/pipeline/units.d.ts +23 -0
  88. package/lib/typescript/src/pipeline/units.d.ts.map +1 -0
  89. package/lib/typescript/src/presets.d.ts +57 -0
  90. package/lib/typescript/src/presets.d.ts.map +1 -0
  91. package/lib/typescript/src/types.d.ts +116 -0
  92. package/lib/typescript/src/types.d.ts.map +1 -0
  93. package/package.json +167 -0
  94. package/src/BlurView.tsx +195 -0
  95. package/src/ParityBlurViewNativeComponent.ts +82 -0
  96. package/src/defaults.ts +20 -0
  97. package/src/index.ts +10 -0
  98. package/src/pipeline/androidCalibration.ts +64 -0
  99. package/src/pipeline/captureRect.ts +172 -0
  100. package/src/pipeline/color.ts +66 -0
  101. package/src/pipeline/constants.ts +65 -0
  102. package/src/pipeline/downsample.ts +74 -0
  103. package/src/pipeline/index.ts +20 -0
  104. package/src/pipeline/overlay.ts +46 -0
  105. package/src/pipeline/saturation.ts +65 -0
  106. package/src/pipeline/types.ts +37 -0
  107. package/src/pipeline/units.ts +32 -0
  108. package/src/presets.ts +103 -0
  109. package/src/types.ts +132 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["sigmaPxFromDp","blurRadiusDp","displayScale","Number","isFinite","sigmaSnapshotFromPx","sigmaPx","downsample"],"sourceRoot":"../../../src","sources":["pipeline/units.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAACC,YAAoB,EAAEC,YAAoB,EAAU;EAChF,IAAI,CAACC,MAAM,CAACC,QAAQ,CAACH,YAAY,CAAC,IAAIA,YAAY,IAAI,CAAC,EAAE,OAAO,CAAC;EACjE,IAAI,CAACE,MAAM,CAACC,QAAQ,CAACF,YAAY,CAAC,IAAIA,YAAY,IAAI,CAAC,EAAE,OAAO,CAAC;EACjE,OAAOD,YAAY,GAAGC,YAAY;AACpC;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASG,mBAAmBA,CAACC,OAAe,EAAEC,UAAsB,EAAU;EACnF,IAAI,CAACJ,MAAM,CAACC,QAAQ,CAACE,OAAO,CAAC,IAAIA,OAAO,IAAI,CAAC,EAAE,OAAO,CAAC;EACvD,OAAOA,OAAO,GAAGC,UAAU;AAC7B","ignoreList":[]}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Material-like presets (plan §11, plan §41 / Milestone 8).
5
+ *
6
+ * A preset is nothing more than a fixed, explicit
7
+ * `{ blurRadius, saturation, overlayColor }` prop bundle. There is no
8
+ * hidden or platform-specific behavior: applying `BlurPresets.dark` is
9
+ * exactly equivalent to spreading that plain object onto `<BlurView>`
10
+ * yourself, and the resulting three numbers/strings go through the same
11
+ * calibrated pipeline as any other explicit props (docs/PIPELINE_SPEC.md).
12
+ * Because blurRadius/saturation/overlayColor are calibrated to match
13
+ * cross-platform (docs/CALIBRATION_REPORT.md — worst measured ΔE76 0.90,
14
+ * SSIM ≥ 0.983), a given preset renders the same on iOS and Android.
15
+ *
16
+ * These are *approximations* of the visual weight of iOS system materials
17
+ * (UIBlurEffect styles), chosen by eye against reasonable blurRadius /
18
+ * saturation / overlayColor values — they are not derived from, measured
19
+ * against, or guaranteed to match `UIVisualEffectView` output, and Android
20
+ * has no equivalent native material to match at all. Treat the names as a
21
+ * starting point, not a parity claim (plan §43 — nested/material stacking
22
+ * is deterministic, not an Apple material emulation).
23
+ *
24
+ * Usage:
25
+ * ```tsx
26
+ * <BlurView {...BlurPresets.dark} style={styles.sheet}>
27
+ * {children}
28
+ * </BlurView>
29
+ * ```
30
+ *
31
+ * Every field is a plain public prop, so you can still override any one of
32
+ * them by spreading the preset first and your own prop second:
33
+ * ```tsx
34
+ * <BlurView {...BlurPresets.dark} blurRadius={30} />
35
+ * ```
36
+ *
37
+ * Or, for the same effect without spreading, pass the `preset` prop
38
+ * directly to `<BlurView>` (`src/BlurView.tsx`) — it resolves to this same
39
+ * object client-side before any explicit blurRadius/saturation/overlayColor
40
+ * prop is applied on top of it. Both forms are pure JS convenience; neither
41
+ * adds a native prop.
42
+ */
43
+
44
+ /** One named preset: an explicit bundle of public BlurView props. */
45
+
46
+ /** Keys of {@link BlurPresets}. */
47
+
48
+ /**
49
+ * Named material-like preset table. See the module doc comment above for
50
+ * semantics and the "not a parity claim" caveat.
51
+ */
52
+ export const BlurPresets = {
53
+ /** Barely-there frosted glass: minimal blur, faint light tint. */
54
+ ultraThin: {
55
+ blurRadius: 10,
56
+ saturation: 1.3,
57
+ overlayColor: 'rgba(255,255,255,0.15)'
58
+ },
59
+ /** Light frosted glass, subtle. */
60
+ thin: {
61
+ blurRadius: 14,
62
+ saturation: 1.4,
63
+ overlayColor: 'rgba(255,255,255,0.25)'
64
+ },
65
+ /** Neutral, medium-weight — a reasonable default over photos/color. */
66
+ regular: {
67
+ blurRadius: 20,
68
+ saturation: 1.2,
69
+ overlayColor: 'rgba(128,128,128,0.16)'
70
+ },
71
+ /** Heavier blur, more opaque neutral-dark tint. */
72
+ thick: {
73
+ blurRadius: 28,
74
+ saturation: 1.3,
75
+ overlayColor: 'rgba(20,20,20,0.35)'
76
+ },
77
+ /** Near-opaque, low-saturation — for toolbar/nav-bar-like surfaces. */
78
+ chrome: {
79
+ blurRadius: 24,
80
+ saturation: 1.1,
81
+ overlayColor: 'rgba(230,230,230,0.55)'
82
+ },
83
+ /** Classic light material: strong blur, warm-white tint, boosted saturation. */
84
+ light: {
85
+ blurRadius: 20,
86
+ saturation: 1.8,
87
+ overlayColor: 'rgba(255,255,255,0.4)'
88
+ },
89
+ /** Classic dark material: strong blur, near-black tint, boosted saturation. */
90
+ dark: {
91
+ blurRadius: 20,
92
+ saturation: 1.5,
93
+ overlayColor: 'rgba(16,16,16,0.45)'
94
+ }
95
+ };
96
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BlurPresets","ultraThin","blurRadius","saturation","overlayColor","thin","regular","thick","chrome","light","dark"],"sourceRoot":"../../src","sources":["presets.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAUA;;AAIA;AACA;AACA;AACA;AACA,OAAO,MAAMA,WAAyD,GAAG;EACvE;EACAC,SAAS,EAAE;IACTC,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAC,IAAI,EAAE;IACJH,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAE,OAAO,EAAE;IACPJ,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAG,KAAK,EAAE;IACLL,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAI,MAAM,EAAE;IACNN,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAK,KAAK,EAAE;IACLP,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB,CAAC;EACD;EACAM,IAAI,EAAE;IACJR,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE,GAAG;IACfC,YAAY,EAAE;EAChB;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import type { BlurViewProps, BlurViewRef } from './types.js';
3
+ /**
4
+ * Public backdrop blur component (plan §28/§29/§30).
5
+ *
6
+ * Renders the native ParityBlurView host view backed by a real blur on both
7
+ * platforms: Android API 31+ real-time `RenderEffect` Gaussian blur (older
8
+ * Android renders `fallbackColor` instead — real CPU blur is intentionally
9
+ * out of scope, plan §44), iOS `MPSImageGaussianBlur`. `refresh()` is fully
10
+ * wired to a native coalesced recapture (plan §29). See
11
+ * docs/PIPELINE_SPEC.md for the canonical pipeline both backends implement
12
+ * and docs/CALIBRATION_REPORT.md for measured cross-platform parity.
13
+ */
14
+ export declare const BlurView: React.ForwardRefExoticComponent<BlurViewProps & React.RefAttributes<BlurViewRef>>;
15
+ export default BlurView;
16
+ //# sourceMappingURL=BlurView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,OAAO,KAAK,EAAkB,aAAa,EAAE,WAAW,EAAE,MAAM,YAAS,CAAC;AAsD1E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,mFA8GpB,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Fabric codegen spec for the ParityBlurView native host view.
3
+ *
4
+ * Every public prop from plan §28 is plumbed through to native, and the
5
+ * `refresh()` Fabric command is wired end-to-end to a real coalesced
6
+ * recapture. Both native backends (Android Kotlin, iOS Swift) implement the
7
+ * real capture/blur/saturate/overlay pipeline defined in
8
+ * docs/PIPELINE_SPEC.md — this file only declares the codegen shape, not
9
+ * the behavior.
10
+ *
11
+ * Deviation from plan §28 (documented in the Milestone 1 report): the public
12
+ * `downsample` prop is `'auto' | 1 | 2 | 4 | 8` (see src/types.ts). Fabric
13
+ * codegen's TypeScript parser rejects a union that mixes string and numeric
14
+ * literals for one prop ("Mixed types are not supported"), and a plain
15
+ * string enum with numeric-looking values ('1', '2', ...) is also unsafe
16
+ * because the iOS/C++ generator turns each enum option into a bare
17
+ * identifier (`ParityBlurViewDownsample::1` is not valid C++). Instead this
18
+ * native prop is a plain Int32 where `0` is a sentinel for `'auto'` and
19
+ * `1 | 2 | 4 | 8` pass through unchanged. `src/BlurView.tsx` performs the
20
+ * 'auto' <-> 0 translation; native code treats 0 as "auto".
21
+ *
22
+ * Note: this file deliberately imports everything from the 'react-native'
23
+ * package root rather than deep 'react-native/Libraries/...' paths. This
24
+ * project's tsconfig opts into the `react-native-strict-api` custom
25
+ * condition, and react-native's package.json `exports` map explicitly
26
+ * blocks deep `Libraries/*` subpath imports under that condition -- so
27
+ * `codegenNativeCommands`, `codegenNativeComponent`, and the CodegenTypes
28
+ * (Double/Int32/WithDefault) must come from the root barrel, which
29
+ * re-exports all three for exactly this reason.
30
+ *
31
+ * Also note: do NOT re-export `CodegenTypes.WithDefault`/`Double`/`Int32` as
32
+ * local generic type aliases (an earlier draft of this file did, to shorten
33
+ * the qualified names). @react-native/codegen's alias resolution does plain
34
+ * textual substitution with no generic instantiation, so a chain like
35
+ * `NativeBlurMode -> WithDefault<'static'|'live','static'> -> (local
36
+ * `WithDefault<Type,Value>` alias) -> CodegenTypes.WithDefault<Type,Value>`
37
+ * loses the real type arguments and fails with "The default value in
38
+ * WithDefault must be string, number, boolean or null." Referencing
39
+ * `CodegenTypes.WithDefault<...>` directly (qualified) avoids the extra
40
+ * alias hop and keeps the real arguments intact.
41
+ */
42
+ import { type CodegenTypes, type ColorValue, type HostComponent, type ViewProps } from 'react-native';
43
+ import type * as React from 'react';
44
+ type NativeBlurMode = CodegenTypes.WithDefault<'static' | 'live', 'static'>;
45
+ type NativeBlurQuality = CodegenTypes.WithDefault<'high' | 'balanced' | 'performance', 'balanced'>;
46
+ export interface NativeProps extends ViewProps {
47
+ blurRadius?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
48
+ mode?: NativeBlurMode;
49
+ overlayColor?: ColorValue;
50
+ saturation?: CodegenTypes.WithDefault<CodegenTypes.Double, 1>;
51
+ quality?: NativeBlurQuality;
52
+ downsample?: CodegenTypes.WithDefault<CodegenTypes.Int32, 0>;
53
+ maxFps?: CodegenTypes.WithDefault<CodegenTypes.Int32, 30>;
54
+ fallbackColor?: ColorValue;
55
+ }
56
+ type ComponentType = HostComponent<NativeProps>;
57
+ interface NativeCommands {
58
+ refresh: (viewRef: React.ComponentRef<ComponentType>) => void;
59
+ }
60
+ export declare const Commands: NativeCommands;
61
+ declare const _default: ComponentType;
62
+ export default _default;
63
+ //# sourceMappingURL=ParityBlurViewNativeComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParityBlurViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ParityBlurViewNativeComponent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,KAAK,cAAc,GAAG,YAAY,CAAC,WAAW,CAAC,QAAQ,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC5E,KAAK,iBAAiB,GAAG,YAAY,CAAC,WAAW,CAC/C,MAAM,GAAG,UAAU,GAAG,aAAa,EACnC,UAAU,CACX,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,UAAU,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,UAAU,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B,UAAU,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,EAAE,UAAU,CAAC;CAC5B;AAED,KAAK,aAAa,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;AAEhD,UAAU,cAAc;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,QAAQ,EAAE,cAErB,CAAC;wBAIE,aAAa;AAFlB,wBAEmB"}
@@ -0,0 +1,12 @@
1
+ import type { BlurDownsample, BlurMode, BlurQuality } from './types.js';
2
+ export declare const DEFAULT_BLUR_RADIUS = 0;
3
+ export declare const DEFAULT_MODE: BlurMode;
4
+ export declare const DEFAULT_OVERLAY_COLOR = "transparent";
5
+ export declare const DEFAULT_SATURATION = 1;
6
+ export declare const DEFAULT_QUALITY: BlurQuality;
7
+ export declare const DEFAULT_DOWNSAMPLE: BlurDownsample;
8
+ export declare const DEFAULT_MAX_FPS = 30;
9
+ export declare const MIN_MAX_FPS = 1;
10
+ export declare const MAX_MAX_FPS = 120;
11
+ export declare const ALLOWED_DOWNSAMPLE_VALUES: ReadonlyArray<BlurDownsample>;
12
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAS,CAAC;AAErE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,YAAY,EAAE,QAAmB,CAAC;AAC/C,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,eAAe,EAAE,WAAwB,CAAC;AACvD,eAAO,MAAM,kBAAkB,EAAE,cAAuB,CAAC;AACzD,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,cAAc,CAMnE,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { BlurView, default } from './BlurView.js';
2
+ export type { BlurDownsample, BlurMode, BlurQuality, BlurViewProps, BlurViewRef, } from './types.js';
3
+ export { BlurPresets } from './presets.js';
4
+ export type { BlurPreset, BlurPresetName } from './presets.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAY,CAAC;AAC/C,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,YAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAW,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAW,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Android RenderEffect calibration (plan §5.2).
3
+ *
4
+ * INTERNAL MODULE. The single place the HWUI sigma<->radius relation lives on
5
+ * the TypeScript side; the Kotlin `AndroidBlurCalibration` must mirror it
6
+ * exactly. Verified on a Pixel 6a (API 36) in M0: radiusForSigma(10) exactly
7
+ * equals 16.454486... (matching the on-device measurement 16.45449).
8
+ *
9
+ * Relation (HWUI): sigma = SLOPE * radiusPlatform + INTERCEPT
10
+ * Inverse: radiusPlatform = (sigma - INTERCEPT) / SLOPE
11
+ *
12
+ * When sigmaSnapshot <= INTERCEPT (0.5) the inverse is non-positive, so we
13
+ * clamp to a no-blur passthrough rather than feeding a bogus radius to
14
+ * RenderEffect.createBlurEffect (plan §5.2 "no-op blur" for very small sigma).
15
+ */
16
+ export interface AndroidBlurParam {
17
+ /** True when the requested blur collapses to a no-op passthrough. */
18
+ noBlur: boolean;
19
+ /**
20
+ * Platform radius to pass to RenderEffect.createBlurEffect. 0 when noBlur.
21
+ * Always >= 0.
22
+ */
23
+ radiusPlatform: number;
24
+ }
25
+ /**
26
+ * Forward relation, exposed for tests/verification: the sigma that HWUI
27
+ * produces for a given platform radius.
28
+ */
29
+ export declare function sigmaForRadius(radiusPlatform: number): number;
30
+ /**
31
+ * Inverse relation: the platform radius required to achieve a target
32
+ * snapshot-domain sigma. Below the intercept this returns a no-blur result.
33
+ * Monotonically non-decreasing in sigmaSnapshot.
34
+ */
35
+ export declare function radiusForSigma(sigmaSnapshot: number): AndroidBlurParam;
36
+ /**
37
+ * iOS MPSImageGaussianBlur takes the snapshot-domain sigma directly (plan §5.3).
38
+ * Provided here for symmetry so both platform mappings live in the reference.
39
+ * Sigma at or below 0 means no blur.
40
+ */
41
+ export declare function iosSigmaForSigma(sigmaSnapshot: number): number;
42
+ //# sourceMappingURL=androidCalibration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"androidCalibration.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/androidCalibration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,gBAAgB,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAG9D"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Capture-rect math (plan §7, §12).
3
+ *
4
+ * INTERNAL MODULE. All rectangles here are in TARGET-LOCAL DEVICE PIXELS unless
5
+ * a field/return is explicitly documented as snapshot pixels.
6
+ *
7
+ * Pipeline of this module:
8
+ * 1. supportMarginPx — Gaussian support margin = ceil(K * sigmaPx)
9
+ * 2. expandCaptureRect — expand visible rect by margin, clamp to target bounds
10
+ * 3. snapshotRectFor — map the clamped device-px rect into integer snapshot
11
+ * pixels (floor origin, ceil far edge = conservative
12
+ * cover)
13
+ * 4. cropRectFor — the sub-region of the snapshot that maps back to the
14
+ * visible rect (fractional, snapshot px)
15
+ * 5. cropRectToViewPx — inverse mapping used to prove round-tripping
16
+ *
17
+ * Rounding rule (LOCKED): in the snapshot domain the origin FLOORS and the far
18
+ * edge CEILS, so `size = ceil(farEdge/D) - floor(origin/D)`. This is the
19
+ * conservative reading of "floor for origin, ceil for size": it guarantees
20
+ * every device pixel of the clamped capture rect is covered by the snapshot
21
+ * rect, at the cost of at most one extra snapshot pixel per side. A naive
22
+ * `floor(origin), ceil(width)` would fail to cover the far edge and is NOT used.
23
+ */
24
+ import type { Downsample, Rect } from './types.js';
25
+ /** Gaussian support margin in device px (plan §7): ceil(K * sigmaPx). */
26
+ export declare function supportMarginPx(sigmaPx: number, k?: number): number;
27
+ /** Intersection of two rects; empty (zero-size) rect if they do not overlap. */
28
+ export declare function intersectRect(a: Rect, b: Rect): Rect;
29
+ /**
30
+ * Expand the visible blur rect by the Gaussian support margin and clamp to the
31
+ * target bounds. Returns a float device-px rect (plan §7). The margin only
32
+ * covers content that exists inside the target; CLAMP handles the outer edge
33
+ * where the margin was cut off (plan §8).
34
+ */
35
+ export declare function expandCaptureRect(visibleRect: Rect, targetBounds: Rect, sigmaPx: number, k?: number): Rect;
36
+ /** Area of a rect in device px^2 (helper for downsample selection). */
37
+ export declare function rectArea(r: Rect): number;
38
+ /**
39
+ * Map a clamped device-px capture rect into integer snapshot pixels for
40
+ * downsample factor D. Floor the origin, ceil the far edge (conservative
41
+ * cover). The returned rect is in SNAPSHOT PIXELS (indices), so its device-px
42
+ * footprint is `snapshotRect * D`.
43
+ */
44
+ export declare function snapshotRectFor(captureRectPx: Rect, downsample: Downsample): Rect;
45
+ /**
46
+ * The fractional crop rect, in SNAPSHOT PIXELS, that selects the visible region
47
+ * out of the (larger) snapshot rect after blur. Because the snapshot origin was
48
+ * floored, the crop origin carries a fractional remainder in [0, 1) snapshot px
49
+ * which the upsample step resolves with bilinear sampling (plan §12).
50
+ *
51
+ * cropX = visibleRect.x / D - snapshotRect.x
52
+ * cropW = visibleRect.width / D
53
+ */
54
+ export declare function cropRectFor(visibleRect: Rect, snapshotRect: Rect, downsample: Downsample): Rect;
55
+ /**
56
+ * Inverse of {@link cropRectFor}: map a snapshot-px crop rect back to
57
+ * target-local device px. Used to verify round-tripping (should recover the
58
+ * original visible rect within half a snapshot pixel = D/2 device px).
59
+ */
60
+ export declare function cropRectToViewPx(cropRect: Rect, snapshotRect: Rect, downsample: Downsample): Rect;
61
+ export interface CapturePlan {
62
+ /** Input visible blur rect (target-local device px). */
63
+ visibleRect: Rect;
64
+ /** Gaussian support margin (device px). */
65
+ marginPx: number;
66
+ /** Expanded + clamped capture rect (target-local device px, float). */
67
+ captureRectPx: Rect;
68
+ /** Capture area used for downsample selection (device px^2). */
69
+ captureAreaPx: number;
70
+ /** Selected downsample factor. */
71
+ downsample: Downsample;
72
+ /** Integer snapshot-pixel rect to allocate/blur. */
73
+ snapshotRect: Rect;
74
+ /** Fractional snapshot-px crop rect selecting the visible region. */
75
+ cropRect: Rect;
76
+ }
77
+ /**
78
+ * Assemble the full capture plan for a given visible rect, target bounds,
79
+ * sigmaPx and pre-resolved downsample factor. Downsample resolution lives in
80
+ * downsample.ts and takes `captureAreaPx` from this same computation, so the
81
+ * caller sequences: expand -> area -> resolveDownsample -> buildCapturePlan.
82
+ */
83
+ export declare function buildCapturePlan(visibleRect: Rect, targetBounds: Rect, sigmaPx: number, downsample: Downsample, k?: number): CapturePlan;
84
+ //# sourceMappingURL=captureRect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureRect.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/captureRect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAS,CAAC;AAEhD,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAE,MAA0B,GAAG,MAAM,CAGtF;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAWpD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,IAAI,EAClB,OAAO,EAAE,MAAM,EACf,CAAC,GAAE,MAA0B,GAC5B,IAAI,CASN;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAMjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,IAAI,EAClB,UAAU,EAAE,UAAU,GACrB,IAAI,CAON;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,IAAI,EACd,YAAY,EAAE,IAAI,EAClB,UAAU,EAAE,UAAU,GACrB,IAAI,CAON;AAED,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,WAAW,EAAE,IAAI,CAAC;IAClB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,aAAa,EAAE,IAAI,CAAC;IACpB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,UAAU,EAAE,UAAU,CAAC;IACvB,oDAAoD;IACpD,YAAY,EAAE,IAAI,CAAC;IACnB,qEAAqE;IACrE,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,IAAI,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,EACtB,CAAC,GAAE,MAA0B,GAC5B,WAAW,CAcb"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Color parsing for the overlay prop.
3
+ *
4
+ * INTERNAL MODULE. Parses the subset of CSS color syntaxes React Native
5
+ * accepts for a string color prop into straight-alpha RGBA in [0,1]:
6
+ * - 'transparent'
7
+ * - #rgb / #rgba / #rrggbb / #rrggbbaa
8
+ * - rgb(r,g,b) / rgba(r,g,b,a) (r,g,b integer 0-255, a float 0-1)
9
+ *
10
+ * Any unrecognised value returns a fully-transparent color (no overlay), which
11
+ * is the documented default (plan §11). The native backends parse the same
12
+ * prop with their platform color parsers; this reference fixes the expected
13
+ * numeric result for parity fixtures.
14
+ */
15
+ import type { RGBA } from './types.js';
16
+ export declare const TRANSPARENT: RGBA;
17
+ /** Parse a color string into straight-alpha RGBA. Unrecognised -> transparent. */
18
+ export declare function parseColor(input: string | null | undefined): RGBA;
19
+ //# sourceMappingURL=color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/color.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAS,CAAC;AAEpC,eAAO,MAAM,WAAW,EAAE,IAAiC,CAAC;AAU5D,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAqCjE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Locked calibration constants for the canonical pipeline.
3
+ *
4
+ * INTERNAL MODULE. These are the single source of truth for the reference
5
+ * implementation. Native backends must mirror these exact values. Per the
6
+ * plan (§5.2, §38) constants remain provisional until the parity milestone,
7
+ * but M0 device verification already confirmed the HWUI relation on API 36.
8
+ */
9
+ /**
10
+ * HWUI RenderEffect Gaussian relation, verified exact on a Pixel 6a (API 36)
11
+ * in M0: `sigma = HWUI_SIGMA_SLOPE * radiusPlatform + HWUI_SIGMA_INTERCEPT`.
12
+ * Isolated here so a future version-aware calibration can override it in one
13
+ * place (plan §5.2). Do NOT inline these anywhere else.
14
+ */
15
+ export declare const HWUI_SIGMA_SLOPE = 0.57735;
16
+ export declare const HWUI_SIGMA_INTERCEPT = 0.5;
17
+ /**
18
+ * Below this snapshot-domain sigma the Android RenderEffect relation inverts
19
+ * to a non-positive radius, so we emit a no-blur passthrough instead. Equal to
20
+ * HWUI_SIGMA_INTERCEPT by construction (radius 0 <=> sigma 0.5).
21
+ */
22
+ export declare const ANDROID_MIN_BLUR_SIGMA = 0.5;
23
+ /** Gaussian support multiplier for capture expansion (plan §7). */
24
+ export declare const CAPTURE_SUPPORT_K = 3;
25
+ /**
26
+ * Auto-downsample: target lower bound on snapshot-domain sigma. Keeping
27
+ * sigmaSnapshot at or above this prevents over-downsampling that would make
28
+ * the kernel degenerate (plan §12). 1 snapshot px.
29
+ */
30
+ export declare const MIN_SIGMA_SNAPSHOT = 1;
31
+ /**
32
+ * Auto-downsample: captures with area (device px^2) below this are considered
33
+ * "small" and are never downsampled beyond 2x — aggressive reduction of a tiny
34
+ * region buys no meaningful performance while degrading quality.
35
+ * 256 * 256 device px.
36
+ */
37
+ export declare const SMALL_CAPTURE_AREA_PX: number;
38
+ /**
39
+ * Auto-downsample: per-quality ceiling on the downsample factor (plan §13).
40
+ * high -> prefer 1x or 2x
41
+ * balanced -> prefer 2x or 4x
42
+ * performance -> prefer 4x or 8x
43
+ */
44
+ export declare const QUALITY_MAX_DOWNSAMPLE: Record<'high' | 'balanced' | 'performance', 1 | 2 | 4 | 8>;
45
+ /**
46
+ * Rec. 709 luminance coefficients (plan §10). Sum to 1.0. Used for the
47
+ * saturation matrix on both platforms.
48
+ */
49
+ export declare const LUMA_R = 0.2126;
50
+ export declare const LUMA_G = 0.7152;
51
+ export declare const LUMA_B = 0.0722;
52
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,UAAU,CAAC;AACxC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,MAAuB,CAAC;AAE3D,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,IAAM,CAAC;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,MAAM,GAAG,UAAU,GAAG,aAAa,EACnC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAKd,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,eAAO,MAAM,MAAM,SAAS,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Auto downsample selection (plan §12, §13).
3
+ *
4
+ * INTERNAL MODULE. Deterministic function of (sigmaPx, captureAreaPx, quality)
5
+ * -> D in {1,2,4,8}. Both backends must select identically for identical input.
6
+ *
7
+ * The chosen factor is the largest allowed value that satisfies ALL of three
8
+ * independent ceilings, then snapped down to a real factor in {1,2,4,8}:
9
+ *
10
+ * 1. quality ceiling — QUALITY_MAX_DOWNSAMPLE[quality]
11
+ * 2. sigma floor — keep sigmaSnapshot = sigmaPx / D >= MIN_SIGMA_SNAPSHOT,
12
+ * i.e. D <= floor(sigmaPx / MIN_SIGMA_SNAPSHOT)
13
+ * 3. area ceiling — tiny captures (< SMALL_CAPTURE_AREA_PX) never exceed 2x
14
+ *
15
+ * See docs/PIPELINE_SPEC.md for the locked decision table.
16
+ */
17
+ import type { BlurDownsample, BlurQuality, Downsample } from './types.js';
18
+ /**
19
+ * Resolve the auto-selected downsample factor.
20
+ *
21
+ * @param sigmaPx device-pixel sigma (blurRadius * displayScale)
22
+ * @param captureAreaPx expanded capture area in device px^2
23
+ * @param quality quality tier
24
+ */
25
+ export declare function autoDownsample(sigmaPx: number, captureAreaPx: number, quality: BlurQuality): Downsample;
26
+ /**
27
+ * Resolve a public `downsample` prop to a concrete factor. An explicit numeric
28
+ * value is honoured verbatim; 'auto' delegates to {@link autoDownsample}.
29
+ */
30
+ export declare function resolveDownsample(prop: BlurDownsample, sigmaPx: number, captureAreaPx: number, quality: BlurQuality): Downsample;
31
+ //# sourceMappingURL=downsample.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downsample.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/downsample.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAS,CAAC;AAWvE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,WAAW,GACnB,UAAU,CAeZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,WAAW,GACnB,UAAU,CAGZ"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Canonical pipeline reference implementation — INTERNAL barrel.
3
+ *
4
+ * This module is the executable form of docs/PIPELINE_SPEC.md: pure TypeScript,
5
+ * no react-native imports, no side effects. Native backends (Kotlin / Swift)
6
+ * must reproduce these exact rules.
7
+ *
8
+ * IMPORTANT: this barrel is intentionally NOT re-exported from src/index.ts.
9
+ * It is a spec/testing artifact, not part of the package's public API.
10
+ */
11
+ export * from './types.js';
12
+ export * from './constants.js';
13
+ export * from './units.js';
14
+ export * from './androidCalibration.js';
15
+ export * from './downsample.js';
16
+ export * from './captureRect.js';
17
+ export * from './saturation.js';
18
+ export * from './color.js';
19
+ export * from './overlay.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,YAAS,CAAC;AACxB,cAAc,gBAAa,CAAC;AAC5B,cAAc,YAAS,CAAC;AACxB,cAAc,yBAAsB,CAAC;AACrC,cAAc,iBAAc,CAAC;AAC7B,cAAc,kBAAe,CAAC;AAC9B,cAAc,iBAAc,CAAC;AAC7B,cAAc,YAAS,CAAC;AACxB,cAAc,cAAW,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Overlay source-over compositing (plan §11).
3
+ *
4
+ * INTERNAL MODULE. The overlay color (straight alpha, parsed from the prop) is
5
+ * the SOURCE; the saturated blur result is the DESTINATION. Applied AFTER
6
+ * saturation, BEFORE final clipping (plan §6 step 10). This is the only tint in
7
+ * the pipeline — no hidden platform tint is permitted.
8
+ *
9
+ * Straight-alpha (non-premultiplied) source-over, per channel:
10
+ *
11
+ * outA = srcA + dstA * (1 - srcA)
12
+ * outC = (srcC*srcA + dstC*dstA*(1 - srcA)) / outA (outA > 0)
13
+ * 0 (outA = 0)
14
+ *
15
+ * In v1 the capture surface is an opaque backdrop, so dstA = 1 and this reduces
16
+ * to the familiar linear blend outC = srcC*srcA + dstC*(1 - srcA), outA = 1.
17
+ * The general form is implemented so the reference stays correct if a future
18
+ * version captures translucent backdrops.
19
+ */
20
+ import type { RGBA } from './types.js';
21
+ /**
22
+ * Source-over composite of a straight-alpha source over a straight-alpha
23
+ * destination. Returns straight-alpha RGBA.
24
+ */
25
+ export declare function sourceOver(src: RGBA, dst: RGBA): RGBA;
26
+ /**
27
+ * Convenience: composite an overlay color over an opaque (alpha=1) blurred
28
+ * pixel — the v1 case. Equivalent to sourceOver(overlay, {..dst, a:1}).
29
+ */
30
+ export declare function overlayOnOpaque(overlay: RGBA, dst: RGBA): RGBA;
31
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAS,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAWrD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAE9D"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Saturation color matrix (plan §10).
3
+ *
4
+ * INTERNAL MODULE. One canonical 4x5 color matrix (Android ColorMatrix layout:
5
+ * 4 output rows R,G,B,A; 5 columns R,G,B,A,offset) using Rec.709 luminance
6
+ * coefficients. Applied AFTER blur, BEFORE overlay (plan §6 step 9).
7
+ *
8
+ * For saturation s and luma coefficients (lr,lg,lb) with t = 1 - s:
9
+ *
10
+ * R' = (t*lr + s)*R + t*lg*G + t*lb*B
11
+ * G' = t*lr*R + (t*lg + s)*G + t*lb*B
12
+ * B' = t*lr*R + t*lg*G + (t*lb + s)*B
13
+ * A' = A
14
+ *
15
+ * s = 1 -> identity; s = 0 -> luminance grayscale; s > 1 -> more saturated.
16
+ *
17
+ * The alpha row is untouched and there is no offset column (all offsets 0).
18
+ * The matrix operates on the same channel representation the backend blurs in
19
+ * (gamma-space, straight color for the opaque v1 backdrop). It does NOT itself
20
+ * premultiply — see docs/PIPELINE_SPEC.md §Color.
21
+ */
22
+ /**
23
+ * Row-major 4x5 saturation matrix (20 numbers), matching Android's
24
+ * ColorMatrix and directly transcribable to a Metal 4x4 + bias.
25
+ */
26
+ export declare function saturationMatrix(s: number, lr?: number, lg?: number, lb?: number): number[];
27
+ /**
28
+ * Apply a 4x5 saturation matrix to a straight-alpha RGBA tuple (channels in
29
+ * [0,1]). Returned RGB is clamped to [0,1]; alpha is passed through untouched.
30
+ * Reference for backend parity tests.
31
+ */
32
+ export declare function applySaturation(matrix: number[], r: number, g: number, b: number, a: number): {
33
+ r: number;
34
+ g: number;
35
+ b: number;
36
+ a: number;
37
+ };
38
+ //# sourceMappingURL=saturation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saturation.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/saturation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,EAAE,MAAM,EACT,EAAE,GAAE,MAAe,EACnB,EAAE,GAAE,MAAe,EACnB,EAAE,GAAE,MAAe,GAClB,MAAM,EAAE,CAQV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EAAE,EAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAUhD"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared value types for the canonical pipeline reference implementation.
3
+ *
4
+ * INTERNAL MODULE. Nothing here is re-exported from src/index.ts. These types
5
+ * describe the language-neutral contract that both native backends implement;
6
+ * they are the executable form of docs/PIPELINE_SPEC.md.
7
+ */
8
+ import type { BlurDownsample, BlurQuality } from '../types.js';
9
+ /** Integer downsample factor actually used by the pipeline (never 'auto'). */
10
+ export type Downsample = 1 | 2 | 4 | 8;
11
+ /** The four concrete downsample factors, largest first (selection order). */
12
+ export declare const DOWNSAMPLE_FACTORS: readonly Downsample[];
13
+ /**
14
+ * Axis-aligned rectangle. Units are documented per-field by the producing
15
+ * function (device px in target-local space, or snapshot px). Origin is the
16
+ * top-left corner; width/height grow right/down.
17
+ */
18
+ export interface Rect {
19
+ x: number;
20
+ y: number;
21
+ width: number;
22
+ height: number;
23
+ }
24
+ /** Straight-alpha RGBA colour, all channels normalised to [0, 1]. */
25
+ export interface RGBA {
26
+ r: number;
27
+ g: number;
28
+ b: number;
29
+ a: number;
30
+ }
31
+ export type { BlurDownsample, BlurQuality };
32
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAE5D,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEvC,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,EAAE,SAAS,UAAU,EAAiB,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}