react-native-image-stitcher 0.14.2 → 0.15.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 (116) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +35 -0
  3. package/RNImageStitcher.podspec +8 -7
  4. package/android/build.gradle +0 -16
  5. package/android/src/main/cpp/CMakeLists.txt +2 -63
  6. package/android/src/main/cpp/image_stitcher_jni.cpp +14 -0
  7. package/android/src/main/cpp/keyframe_gate_jni.cpp +13 -0
  8. package/android/src/main/java/io/imagestitcher/rn/BatchStitcher.kt +285 -3
  9. package/android/src/main/java/io/imagestitcher/rn/IncrementalStitcher.kt +180 -1162
  10. package/android/src/main/java/io/imagestitcher/rn/KeyframeGate.kt +29 -0
  11. package/android/src/main/java/io/imagestitcher/rn/RNImageStitcherPackage.kt +0 -4
  12. package/android/src/main/java/io/imagestitcher/rn/RNSARCameraView.kt +13 -64
  13. package/cpp/keyframe_gate.cpp +82 -23
  14. package/cpp/keyframe_gate.hpp +31 -2
  15. package/cpp/stitcher.cpp +208 -28
  16. package/cpp/tests/CMakeLists.txt +18 -12
  17. package/cpp/tests/keyframe_timebudget_test.cpp +65 -0
  18. package/cpp/tests/warp_guard_test.cpp +48 -0
  19. package/cpp/warp_guard.hpp +41 -0
  20. package/dist/camera/Camera.d.ts +31 -16
  21. package/dist/camera/Camera.js +10 -2
  22. package/dist/camera/CaptureStitchStatsToast.d.ts +15 -2
  23. package/dist/camera/CaptureStitchStatsToast.js +27 -7
  24. package/dist/camera/PanoramaSettings.d.ts +10 -223
  25. package/dist/camera/PanoramaSettings.js +6 -28
  26. package/dist/camera/PanoramaSettingsBridge.d.ts +1 -24
  27. package/dist/camera/PanoramaSettingsBridge.js +3 -102
  28. package/dist/camera/PanoramaSettingsModal.js +7 -1
  29. package/dist/camera/buildPanoramaInitialSettings.d.ts +11 -0
  30. package/dist/camera/buildPanoramaInitialSettings.js +4 -0
  31. package/dist/camera/cameraErrorMessages.d.ts +32 -0
  32. package/dist/camera/cameraErrorMessages.js +53 -0
  33. package/dist/camera/selectCaptureDevice.d.ts +5 -1
  34. package/dist/camera/selectCaptureDevice.js +22 -2
  35. package/dist/camera/useCapture.js +38 -0
  36. package/dist/index.d.ts +5 -8
  37. package/dist/index.js +11 -34
  38. package/dist/stitching/incremental.d.ts +1 -117
  39. package/dist/stitching/stitchVideo.d.ts +0 -35
  40. package/dist/types.d.ts +0 -87
  41. package/ios/Sources/RNImageStitcher/IncrementalStitcher.swift +96 -674
  42. package/ios/Sources/RNImageStitcher/IncrementalStitcherBridge.swift +9 -12
  43. package/ios/Sources/RNImageStitcher/KeyframeGate.swift +14 -0
  44. package/ios/Sources/RNImageStitcher/KeyframeGateBridge.h +7 -0
  45. package/ios/Sources/RNImageStitcher/KeyframeGateBridge.mm +6 -0
  46. package/ios/Sources/RNImageStitcher/OpenCVKeyframeCollector.h +2 -2
  47. package/ios/Sources/RNImageStitcher/OpenCVKeyframeCollector.mm +3 -3
  48. package/ios/Sources/RNImageStitcher/OpenCVStitcher.h +28 -60
  49. package/ios/Sources/RNImageStitcher/OpenCVStitcher.mm +180 -921
  50. package/ios/Sources/RNImageStitcher/RNSARSession.swift +10 -35
  51. package/ios/Sources/RNImageStitcher/Stitcher.swift +84 -35
  52. package/ios/Sources/RNImageStitcher/StitcherBridge.m +13 -0
  53. package/ios/Sources/RNImageStitcher/StitcherBridge.swift +132 -5
  54. package/package.json +3 -2
  55. package/src/camera/Camera.tsx +43 -22
  56. package/src/camera/CaptureStitchStatsToast.tsx +58 -14
  57. package/src/camera/PanoramaSettings.ts +16 -289
  58. package/src/camera/PanoramaSettingsBridge.ts +3 -114
  59. package/src/camera/PanoramaSettingsModal.tsx +14 -1
  60. package/src/camera/__tests__/PanoramaSettingsBridge.test.ts +3 -188
  61. package/src/camera/__tests__/buildPanoramaInitialSettings.test.ts +41 -0
  62. package/src/camera/__tests__/cameraErrorMessages.test.ts +76 -0
  63. package/src/camera/__tests__/selectCaptureDevice.test.ts +33 -0
  64. package/src/camera/buildPanoramaInitialSettings.ts +17 -0
  65. package/src/camera/cameraErrorMessages.ts +84 -0
  66. package/src/camera/selectCaptureDevice.ts +28 -3
  67. package/src/camera/useCapture.ts +44 -1
  68. package/src/index.ts +11 -40
  69. package/src/stitching/incremental.ts +3 -140
  70. package/src/stitching/stitchVideo.ts +0 -26
  71. package/src/types.ts +0 -95
  72. package/android/src/main/cpp/stitcher_jsi_install_jni.cpp +0 -227
  73. package/android/src/main/java/io/imagestitcher/rn/IncrementalFirstwinsEngine.kt +0 -1081
  74. package/android/src/main/java/io/imagestitcher/rn/StitcherJsiInstallerModule.kt +0 -103
  75. package/android/src/main/java/io/imagestitcher/rn/StitcherWorkletRuntime.kt +0 -256
  76. package/cpp/stitcher_frame_jsi.cpp +0 -214
  77. package/cpp/stitcher_frame_jsi.hpp +0 -108
  78. package/cpp/stitcher_proxy_jsi.cpp +0 -109
  79. package/cpp/stitcher_proxy_jsi.hpp +0 -46
  80. package/cpp/stitcher_worklet_dispatch.cpp +0 -103
  81. package/cpp/stitcher_worklet_dispatch.hpp +0 -71
  82. package/cpp/stitcher_worklet_registry.cpp +0 -91
  83. package/cpp/stitcher_worklet_registry.hpp +0 -146
  84. package/cpp/tests/stitcher_worklet_registry_test.cpp +0 -195
  85. package/dist/stitching/IncrementalStitcherView.d.ts +0 -41
  86. package/dist/stitching/IncrementalStitcherView.js +0 -157
  87. package/dist/stitching/StitcherWorkletRegistry.d.ts +0 -117
  88. package/dist/stitching/StitcherWorkletRegistry.js +0 -78
  89. package/dist/stitching/ensureStitcherProxyInstalled.d.ts +0 -8
  90. package/dist/stitching/ensureStitcherProxyInstalled.js +0 -81
  91. package/dist/stitching/useFrameProcessor.d.ts +0 -119
  92. package/dist/stitching/useFrameProcessor.js +0 -196
  93. package/dist/stitching/useFrameStream.d.ts +0 -34
  94. package/dist/stitching/useFrameStream.js +0 -234
  95. package/dist/stitching/useThrottledFrameProcessor.d.ts +0 -33
  96. package/dist/stitching/useThrottledFrameProcessor.js +0 -132
  97. package/ios/Sources/RNImageStitcher/OpenCVIncrementalStitcher.h +0 -474
  98. package/ios/Sources/RNImageStitcher/OpenCVIncrementalStitcher.mm +0 -1328
  99. package/ios/Sources/RNImageStitcher/OpenCVSlitScanStitcher.h +0 -103
  100. package/ios/Sources/RNImageStitcher/OpenCVSlitScanStitcher.mm +0 -3285
  101. package/ios/Sources/RNImageStitcher/RNSARWorkletRuntime.h +0 -128
  102. package/ios/Sources/RNImageStitcher/RNSARWorkletRuntime.mm +0 -313
  103. package/ios/Sources/RNImageStitcher/SaveFrameAsJpegPlugin.mm +0 -185
  104. package/ios/Sources/RNImageStitcher/StitcherFrameHostObject.h +0 -60
  105. package/ios/Sources/RNImageStitcher/StitcherFrameHostObject.mm +0 -214
  106. package/ios/Sources/RNImageStitcher/StitcherJsiInstaller.h +0 -42
  107. package/ios/Sources/RNImageStitcher/StitcherJsiInstaller.mm +0 -160
  108. package/src/stitching/IncrementalStitcherView.tsx +0 -198
  109. package/src/stitching/StitcherWorkletRegistry.ts +0 -156
  110. package/src/stitching/__tests__/StitcherWorkletRegistry.test.ts +0 -176
  111. package/src/stitching/__tests__/ensureStitcherProxyInstalled.test.ts +0 -94
  112. package/src/stitching/__tests__/useThrottledFrameProcessor.test.ts +0 -178
  113. package/src/stitching/ensureStitcherProxyInstalled.ts +0 -141
  114. package/src/stitching/useFrameProcessor.ts +0 -226
  115. package/src/stitching/useFrameStream.ts +0 -271
  116. package/src/stitching/useThrottledFrameProcessor.ts +0 -145
@@ -1,145 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- //
3
- // v0.9.0 Layer 2 — throttle gate over v0.8.0's `useFrameProcessor`.
4
- //
5
- // ## What this is
6
- //
7
- // A thin wrapper around `useFrameProcessor` that enforces a maximum
8
- // invocation rate (`sampleHz`) at the worklet layer. The host's
9
- // worklet fires up to `sampleHz` times per second; ticks too close
10
- // together are dropped via a `useSharedValue<number>` monotonic-time
11
- // gate inside the worklet body.
12
- //
13
- // ## When to use this (vs alternatives)
14
- //
15
- // - **`useFrameProcessor` directly** — every camera frame (~30-60 Hz).
16
- // Use for true-realtime processing that wants to see every frame.
17
- // - **`useThrottledFrameProcessor`** (this hook) — sub-frame-rate
18
- // worklet-native processing. The worklet runtime has direct
19
- // access to `frame.toArrayBuffer()`, `frame.arDepth`,
20
- // `frame.arAnchors`, and can call other vc Frame Processor plugins
21
- // (native OCR libraries, TFLite ML inference, etc.). Results
22
- // bridged to JS via `runOnJS`.
23
- // - **`useFrameStream`** (Layer 3, also in this directory) —
24
- // sub-frame-rate JS-thread consumer. The lib JPEG-encodes each
25
- // sample on the producer thread and delivers a `SampledFrame`
26
- // (file path + pose + dims) to a JS-thread callback. Use for
27
- // file-path OCR libraries (RN modules wrapping ML Kit etc.),
28
- // cloud upload, thumbnail UI.
29
- //
30
- // ## Use-case mapping (canonical)
31
- //
32
- // | Use case | Layer | Why |
33
- // |---------------------------------------|-------|----------------------------------|
34
- // | OCR via Vision.framework / ML Kit | **2** | native libs, bbox in frame coords|
35
- // | TFLite ML detection (via vc plugin) | **2** | same shape as OCR |
36
- // | LiDAR depth → 3D reconstruction | **2** | depth too large to bridge |
37
- // | Pose-only telemetry | **2** | tiny payload, no encoding needed |
38
- // | File-path OCR (RN module) | 3 | host wants a JPEG, not pixels |
39
- // | Cloud upload (sampled JPEG feed) | 3 | JPEG IS the payload |
40
- // | Live thumbnail preview UI | 3 | `<Image source={{uri: ...}}>` |
41
- //
42
- // See `docs/host-app-integration.md` § "Tier 2 + 3" for recipes.
43
- //
44
- // ## Threading
45
- //
46
- // The wrapped worklet fires on whatever runtime `useFrameProcessor`
47
- // dispatches on:
48
- // - **Non-AR mode**: vision-camera's Frame Processor runtime
49
- // (producer thread).
50
- // - **AR mode**: the lib's `RNSARWorkletRuntime` (iOS) /
51
- // worklets-core default context (Android) — fired by the AR
52
- // session's per-frame dispatch. See v0.8.0 Phase 4b.i / 4b.iii.
53
- //
54
- // Either way, the worklet MUST NOT block — the next frame's
55
- // processing is gated on this one returning. Long work belongs
56
- // behind `runOnJS` / a separate worklet runtime.
57
- //
58
- // ## Behaviour at the throttle boundary
59
- //
60
- // The hook tracks a monotonic-time shared value of "last sample time".
61
- // Each tick checks if `frame.timestamp - lastSampleMs.value >=
62
- // (1000 / sampleHz)`. If yes, the worklet body runs and the value
63
- // updates; if no, the worklet returns silently.
64
- //
65
- // Edge cases:
66
- // - First-ever tick: `lastSampleMs.value` starts at 0; first frame's
67
- // timestamp will be >> 0 → first tick always fires. Subsequent
68
- // ticks throttle as expected.
69
- // - vc v4 timestamp semantics: per the project's worklet-throttle
70
- // gotcha note, `frame.timestamp` is NOT reliably nanoseconds in
71
- // vc v4. The hook treats `frame.timestamp` as ALREADY in
72
- // milliseconds (which is what vc v4 actually delivers; the
73
- // v0.8.0 StitcherFrame contract documents this). If a future
74
- // vc version changes the unit, the throttle math here needs
75
- // re-checking.
76
-
77
- import type { DependencyList } from 'react';
78
- import { useSharedValue } from 'react-native-worklets-core';
79
-
80
- import { useFrameProcessor } from './useFrameProcessor';
81
- import type {
82
- StitcherFrame,
83
- StitcherFrameProcessor,
84
- } from './StitcherFrame';
85
- import type { ThrottledFrameProcessorOptions } from '../types';
86
-
87
- /**
88
- * Throttled variant of `useFrameProcessor`. See the module
89
- * docstring for the full use-case mapping; quick version:
90
- *
91
- * ```tsx
92
- * const fp = useThrottledFrameProcessor(
93
- * (frame) => {
94
- * 'worklet';
95
- * // worklet-native OCR / ML / depth processing here
96
- * },
97
- * { sampleHz: 2 },
98
- * [],
99
- * );
100
- * return <Camera frameProcessor={fp} ... />;
101
- * ```
102
- *
103
- * @param worklet Host's frame-processor worklet. Must be
104
- * `'worklet'`-prefixed. Runs at most `sampleHz`
105
- * times per second.
106
- * @param options `{ sampleHz }` — clamped to `[0.5, 30]`.
107
- * @param deps Standard React deps array. Treated the same as
108
- * `useFrameProcessor`'s deps — when they change the
109
- * inner worklet is re-bound.
110
- *
111
- * @returns A `useFrameProcessor`-shaped processor object, pass it
112
- * to `<Camera frameProcessor={...}>`.
113
- */
114
- export function useThrottledFrameProcessor(
115
- worklet: StitcherFrameProcessor,
116
- options: ThrottledFrameProcessorOptions,
117
- deps: DependencyList,
118
- ): ReturnType<typeof useFrameProcessor> {
119
- // Clamp + derive interval. Done outside the worklet so the
120
- // useSharedValue / useFrameProcessor hooks see stable values.
121
- const sampleHz = Math.max(0.5, Math.min(30, options.sampleHz));
122
- const minIntervalMs = 1000 / sampleHz;
123
-
124
- // Monotonic-time gate. Initialised to 0 → first tick always
125
- // fires (frame.timestamp >> 0).
126
- const lastSampleMs = useSharedValue(0);
127
-
128
- // eslint-disable-next-line react-hooks/exhaustive-deps
129
- return useFrameProcessor(
130
- (frame: StitcherFrame) => {
131
- 'worklet';
132
- const now = frame.timestamp;
133
- if (now - lastSampleMs.value < minIntervalMs) {
134
- return;
135
- }
136
- lastSampleMs.value = now;
137
- worklet(frame);
138
- },
139
- // The throttle interval is captured in the worklet closure; if
140
- // it changes we need to re-bind the worklet so the new
141
- // `minIntervalMs` takes effect. Same for the host's worklet
142
- // identity (so deps changes on the host side re-bind too).
143
- [minIntervalMs, worklet, ...deps],
144
- );
145
- }