react-native-vision-camera-spoof-detector 1.1.0 โ†’ 1.1.11

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/.npmignore +16 -0
  2. package/README.md +103 -186
  3. package/android/CMakeLists.txt +29 -0
  4. package/android/build.gradle +26 -10
  5. package/android/fix-prefab.gradle +4 -0
  6. package/android/src/main/AndroidManifest.xml +1 -1
  7. package/android/src/main/cpp/CMakeLists.txt +18 -86
  8. package/android/src/main/cpp/FaceAntiSpoofJSI.cpp +80 -6
  9. package/android/src/main/cpp/cpp-adapter.cpp +9 -0
  10. package/android/src/main/java/com/faceantispoof/FaceAntiSpoofModule.kt +55 -103
  11. package/android/src/main/java/com/faceantispoof/FaceAntiSpoofPackage.kt +15 -8
  12. package/android/src/main/java/com/margelo/nitro/camera/spoofdetector/HybridSpoofDetectorFactory.kt +15 -0
  13. package/android/src/main/java/com/margelo/nitro/camera/spoofdetector/HybridSpoofDetectorOutput.kt +111 -0
  14. package/index.js +22 -43
  15. package/nitro.json +20 -0
  16. package/nitrogen/generated/.gitattributes +1 -0
  17. package/nitrogen/generated/android/VisionCameraSpoofDetector+autolinking.cmake +81 -0
  18. package/nitrogen/generated/android/VisionCameraSpoofDetector+autolinking.gradle +27 -0
  19. package/nitrogen/generated/android/VisionCameraSpoofDetectorOnLoad.cpp +58 -0
  20. package/nitrogen/generated/android/VisionCameraSpoofDetectorOnLoad.hpp +34 -0
  21. package/nitrogen/generated/android/c++/JAntiSpoofingResult.hpp +77 -0
  22. package/nitrogen/generated/android/c++/JFunc_void_AntiSpoofingResult.hpp +78 -0
  23. package/nitrogen/generated/android/c++/JFunc_void_std__exception_ptr.hpp +76 -0
  24. package/nitrogen/generated/android/c++/JHybridSpoofDetectorFactorySpec.cpp +75 -0
  25. package/nitrogen/generated/android/c++/JHybridSpoofDetectorFactorySpec.hpp +63 -0
  26. package/nitrogen/generated/android/c++/JSize.hpp +61 -0
  27. package/nitrogen/generated/android/c++/JSpoofDetectorOutputOptions.hpp +91 -0
  28. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/AntiSpoofingResult.kt +76 -0
  29. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/Func_void_AntiSpoofingResult.kt +78 -0
  30. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/Func_void_std__exception_ptr.kt +78 -0
  31. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/HybridSpoofDetectorFactorySpec.kt +57 -0
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/Size.kt +56 -0
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/SpoofDetectorOutputOptions.kt +65 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/spoofdetector/VisionCameraSpoofDetectorOnLoad.kt +35 -0
  35. package/nitrogen/generated/shared/c++/AntiSpoofingResult.hpp +103 -0
  36. package/nitrogen/generated/shared/c++/HybridSpoofDetectorFactorySpec.cpp +21 -0
  37. package/nitrogen/generated/shared/c++/HybridSpoofDetectorFactorySpec.hpp +67 -0
  38. package/nitrogen/generated/shared/c++/Size.hpp +87 -0
  39. package/nitrogen/generated/shared/c++/SpoofDetectorOutputOptions.hpp +98 -0
  40. package/package.json +10 -8
  41. package/src/specs/SpoofDetectorFactory.nitro.ts +23 -0
  42. package/android/src/main/assets/spoof_model_scale_2_7.tflite +0 -0
  43. package/android/src/main/assets/spoof_model_scale_4_0.tflite +0 -0
  44. /package/{android/src/main โ†’ lib}/assets/FaceAntiSpoofing.tflite +0 -0
package/.npmignore ADDED
@@ -0,0 +1,16 @@
1
+ **/build/
2
+ **/.cxx/
3
+ **/.gradle/
4
+ **/node_modules/
5
+ **/Pods/
6
+ **/.swiftpm/
7
+ **/DerivedData/
8
+ **/xcuserdata/
9
+ **/.idea/
10
+ **/coverage/
11
+ **/dist/
12
+ **/tmp/
13
+ **/.DS_Store
14
+ **/local.properties
15
+ **/*.iml
16
+ *.log
package/README.md CHANGED
@@ -19,13 +19,11 @@ High-performance face anti-spoofing and liveness detection module for React Nati
19
19
 
20
20
  ## ๐Ÿ“‹ Requirements
21
21
 
22
- - React Native >= 0.60.0
23
- - React Native Vision Camera `^4.6.4` or `^5.0.0`
24
- - `react-native-reanimated` `^3.0.0`
25
- - `react-native-worklets` `^0.12.0`
22
+ - React Native >= 0.76.0
23
+ - React Native Vision Camera `^5.0.0`
26
24
  - `react-native-vision-camera-worklets` `^5.0.0`
27
25
  - iOS 11.0 or later
28
- - react-native-vision-camera-face-detector (optional, for enhanced features)
26
+ - `react-native-vision-camera-face-detector` (required for the face-gated example below)
29
27
 
30
28
  ## ๐Ÿ“ฆ Installation
31
29
 
@@ -40,9 +38,9 @@ yarn add react-native-vision-camera-spoof-detector
40
38
  ### Step 2: Install peer dependencies
41
39
 
42
40
  ```bash
43
- npm install react-native-vision-camera react-native-reanimated react-native-worklets react-native-vision-camera-worklets
41
+ npm install react-native-vision-camera react-native-reanimated react-native-worklets react-native-vision-camera-worklets react-native-vision-camera-face-detector
44
42
  # or
45
- yarn add react-native-vision-camera react-native-reanimated react-native-worklets react-native-vision-camera-worklets
43
+ yarn add react-native-vision-camera react-native-reanimated react-native-worklets react-native-vision-camera-worklets react-native-vision-camera-face-detector
46
44
  ```
47
45
 
48
46
  ### Step 3: Configure iOS
@@ -82,213 +80,144 @@ react-native link react-native-vision-camera-spoof-detector
82
80
 
83
81
  ## ๐Ÿš€ Quick Start
84
82
 
85
- > **Important:** Request camera permission before rendering `Camera`, and call `initializeFaceAntiSpoof()` once before the frame processor starts. The frame processor returns `null` until native initialization or a result is available. Native inference is throttled and may return the most recent result while another frame is being processed.
86
-
87
- ### Simple Usage
83
+ Vision Camera 5 uses camera outputs for this package. The anti-spoof output can be combined with the face detector output and enabled only while a face is visible.
88
84
 
89
85
  ```javascript
90
86
  import React, { useEffect, useState } from 'react';
91
- import { StyleSheet, Text, View } from 'react-native';
92
- import { Camera, useCameraDevices, useCameraPermission, useFrameProcessor } from 'react-native-vision-camera';
93
- import { faceAntiSpoofFrameProcessor, initializeFaceAntiSpoof } from 'react-native-vision-camera-spoof-detector';
94
- import { runOnJS } from 'react-native-reanimated';
95
-
96
- export default function App() {
97
- const devices = useCameraDevices();
98
- const device = devices.front;
87
+ import { StyleSheet, Text, useWindowDimensions, View } from 'react-native';
88
+ import {
89
+ Camera,
90
+ useCameraDevice,
91
+ useCameraPermission,
92
+ } from 'react-native-vision-camera';
93
+ import { useFaceDetectorOutput } from 'react-native-vision-camera-face-detector';
94
+ import { useFaceAntiSpoofFrameOutput } from 'react-native-vision-camera-spoof-detector';
95
+
96
+ const CameraScreen = () => {
97
+ const device = useCameraDevice('front');
99
98
  const { hasPermission, requestPermission } = useCameraPermission();
99
+ const { width: windowWidth, height: windowHeight } = useWindowDimensions();
100
+ const [faces, setFaces] = useState([]);
101
+ const [detectionError, setDetectionError] = useState(null);
100
102
  const [spoofResult, setSpoofResult] = useState(null);
101
103
 
102
104
  useEffect(() => {
103
105
  if (!hasPermission) requestPermission();
104
106
  }, [hasPermission, requestPermission]);
105
107
 
106
- useEffect(() => {
107
- initializeFaceAntiSpoof()
108
- .then((success) => console.log('FaceAntiSpoof initialized:', success))
109
- .catch((error) => console.error('FaceAntiSpoof initialization failed:', error));
110
- }, []);
108
+ const faceDetectorOutput = useFaceDetectorOutput({
109
+ cameraFacing: 'front',
110
+ autoMode: true,
111
+ windowWidth,
112
+ windowHeight,
113
+ performanceMode: 'fast',
114
+ trackingEnabled: true,
115
+ onFacesDetected(detectedFaces) {
116
+ setDetectionError(null);
117
+ setFaces(detectedFaces);
118
+ if (detectedFaces.length === 0) setSpoofResult(null);
119
+ },
120
+ onError(error) {
121
+ setDetectionError(error.message);
122
+ },
123
+ });
111
124
 
112
- const frameProcessor = useFrameProcessor((frame) => {
113
- 'worklet';
114
- const result = faceAntiSpoofFrameProcessor(frame);
115
- if (result) {
116
- runOnJS(setSpoofResult)(result);
117
- }
118
- }, []);
125
+ const antiSpoofOutput = useFaceAntiSpoofFrameOutput({
126
+ onResult(result) {
127
+ setSpoofResult(result);
128
+ },
129
+ });
119
130
 
120
- if (!hasPermission || device == null) return <Text>Waiting for camera permission...</Text>;
131
+ const outputs = faces.length > 0
132
+ ? [faceDetectorOutput, antiSpoofOutput]
133
+ : [faceDetectorOutput];
134
+
135
+ if (!hasPermission) return <Message text="Camera permission is required." />;
136
+ if (!device) return <Message text="No front camera is available." />;
121
137
 
122
138
  return (
123
139
  <View style={styles.container}>
124
140
  <Camera
125
141
  style={StyleSheet.absoluteFill}
126
142
  device={device}
127
- isActive={true}
128
- frameProcessor={frameProcessor}
129
- frameProcessorFps={5}
143
+ isActive
144
+ outputs={outputs}
130
145
  />
131
- {spoofResult && (
132
- <View style={styles.resultContainer}>
133
- <Text style={styles.resultText}>
134
- Is Live: {spoofResult.isLive ? 'Yes' : 'No'}
135
- </Text>
136
- <Text style={styles.resultText}>
137
- Score: {spoofResult.neuralNetworkScore?.toFixed(2)}
138
- </Text>
139
- <Text style={styles.resultText}>
140
- Label: {spoofResult.label}
141
- </Text>
142
- </View>
143
- )}
146
+
147
+ <View style={styles.statusContainer}>
148
+ <Text style={styles.statusText}>
149
+ {detectionError ?? `${faces.length} face${faces.length === 1 ? '' : 's'} detected`}
150
+ </Text>
151
+ <Text style={styles.statusText}>
152
+ {faces.length === 0
153
+ ? 'Waiting for face...'
154
+ : spoofResult
155
+ ? JSON.stringify(spoofResult)
156
+ : 'Anti-spoof processing...'}
157
+ </Text>
158
+ </View>
144
159
  </View>
145
160
  );
146
- }
161
+ };
162
+
163
+ const Message = ({ text }) => (
164
+ <View style={styles.messageContainer}>
165
+ <Text style={styles.messageText}>{text}</Text>
166
+ </View>
167
+ );
147
168
 
148
169
  const styles = StyleSheet.create({
149
170
  container: { flex: 1 },
150
- resultContainer: {
151
- position: 'absolute',
152
- bottom: 50,
153
- left: 0,
154
- right: 0,
171
+ messageContainer: {
172
+ flex: 1,
155
173
  alignItems: 'center',
156
- backgroundColor: 'rgba(0,0,0,0.5)',
157
- padding: 10,
174
+ justifyContent: 'center',
175
+ paddingHorizontal: 24,
158
176
  },
159
- resultText: {
160
- color: 'white',
161
- fontSize: 20,
162
- fontWeight: 'bold',
177
+ messageText: { fontSize: 16, textAlign: 'center' },
178
+ statusContainer: {
179
+ position: 'absolute',
180
+ top: 56,
181
+ alignSelf: 'center',
182
+ paddingHorizontal: 14,
183
+ paddingVertical: 8,
184
+ borderRadius: 16,
185
+ backgroundColor: 'rgba(0, 0, 0, 0.65)',
163
186
  },
187
+ statusText: { color: '#ffffff', fontSize: 14, marginVertical: 2 },
164
188
  });
189
+
190
+ export default CameraScreen;
165
191
  ```
166
192
 
167
- ### Advanced Usage with Full Feature Set
193
+ The anti-spoof output callback receives a result after native inference. No manual `runOnJS`, frame processor, or explicit initialization call is required for this output API. The output may be omitted until a face is detected, as shown above.
168
194
 
169
- ```javascript
170
- import { useCallback, useMemo, useEffect, useRef } from 'react';
171
- import { scheduleOnRN } from 'react-native-worklets';
172
- import { useFrameProcessor } from 'react-native-vision-camera';
173
- import { useFaceDetector } from 'react-native-vision-camera-face-detector';
174
- import {
175
- faceAntiSpoofFrameProcessor,
176
- initializeFaceAntiSpoof,
177
- isFaceAntiSpoofAvailable,
178
- } from 'react-native-vision-camera-spoof-detector';
179
-
180
- const useFaceDetectionFrameProcessor = ({
181
- onStableFaceDetected = () => { },
182
- onFacesUpdate = () => { },
183
- onLivenessUpdate = () => { },
184
- onAntiSpoofUpdate = () => { },
185
- showCodeScanner = false,
186
- isLoading = false,
187
- isActive = true,
188
- livenessLevel = 0,
189
- antispooflevel = 0.35,
190
- }) => {
191
- const { detectFaces } = useFaceDetector({
192
- performanceMode: 'fast',
193
- landmarkMode: 'none',
194
- contourMode: 'none',
195
- classificationMode: livenessLevel === 1 ? 'all' : 'none',
196
- minFaceSize: 0.2,
197
- });
195
+ ## ๐Ÿ“š API Reference
198
196
 
199
- const isMounted = useRef(true);
200
- const antiSpoofInitialized = useRef(false);
201
-
202
- const initializeAntiSpoof = useCallback(async () => {
203
- if (antiSpoofInitialized.current) return true;
204
- try {
205
- const available = isFaceAntiSpoofAvailable?.();
206
- if (!available) return false;
207
- await initializeFaceAntiSpoof();
208
- antiSpoofInitialized.current = true;
209
- return true;
210
- } catch (err) {
211
- console.error('Anti-spoof initialization error:', err);
212
- return false;
213
- }
214
- }, []);
197
+ ### `useFaceAntiSpoofFrameOutput(options?)`
215
198
 
216
- useEffect(() => {
217
- initializeAntiSpoof();
218
- }, [initializeAntiSpoof]);
219
-
220
- // Shared state for face tracking
221
- const sharedState = useMemo(
222
- () =>
223
- Worklets.createSharedValue({
224
- flags: {
225
- captured: false,
226
- showCodeScanner: showCodeScanner,
227
- isActive: isActive,
228
- hasSingleFace: false,
229
- isFaceCentered: false,
230
- },
231
- antiSpoof: {
232
- isLive: false,
233
- confidence: 0,
234
- consecutiveLiveFrames: 0,
235
- },
236
- }),
237
- []
238
- );
199
+ Creates a Vision Camera 5 camera output for native anti-spoofing inference.
239
200
 
240
- const frameProcessor = useFrameProcessor(
241
- (frame) => {
242
- 'worklet';
243
-
244
- try {
245
- const detected = detectFaces?.(frame);
246
-
247
- if (!detected || detected.length === 0) {
248
- onFacesUpdate?.({ count: 0, progress: 0 });
249
- return;
250
- }
251
-
252
- if (detected.length === 1 && !sharedState.value.flags.captured) {
253
- const antiSpoofResult = faceAntiSpoofFrameProcessor?.(frame);
254
-
255
- if (antiSpoofResult?.isLive) {
256
- sharedState.value.antiSpoof.isLive = true;
257
- sharedState.value.antiSpoof.confidence = antiSpoofResult.combinedScore;
258
- onAntiSpoofUpdate?.({
259
- isLive: true,
260
- confidence: antiSpoofResult.combinedScore,
261
- });
262
- }
263
-
264
- onFacesUpdate?.({ count: 1, progress: 50 });
265
- } else {
266
- onFacesUpdate?.({ count: detected.length, progress: 0 });
267
- }
268
- } catch (err) {
269
- console.error('Frame processing error:', err);
270
- } finally {
271
- frame.release?.();
272
- }
273
- },
274
- [detectFaces, isLoading]
275
- );
201
+ ```javascript
202
+ const antiSpoofOutput = useFaceAntiSpoofFrameOutput({
203
+ onResult(result) {
204
+ console.log(result);
205
+ },
206
+ onError(error) {
207
+ console.error(error);
208
+ },
209
+ });
210
+ ```
276
211
 
277
- return {
278
- frameProcessor,
279
- sharedState,
280
- initializeAntiSpoof,
281
- };
282
- };
212
+ Pass the returned output in the `Camera` component's `outputs` array. The callback runs on the React Native runtime after native inference.
283
213
 
284
- export default useFaceDetectionFrameProcessor;
285
- ```
214
+ **Options**: `onResult(result)` and optional `onError(error)`.
286
215
 
287
- ## ๐Ÿ“š API Reference
216
+ ---
288
217
 
289
218
  ### `initializeFaceAntiSpoof()`
290
219
 
291
- Initializes the face anti-spoofing module. Must be called before using the frame processor.
220
+ Initializes the native module when an application needs an explicit startup check or model-loading diagnostics. It is not required when using `useFaceAntiSpoofFrameOutput()`.
292
221
 
293
222
  ```javascript
294
223
  const success = await initializeFaceAntiSpoof();
@@ -310,18 +239,6 @@ const available = isFaceAntiSpoofAvailable();
310
239
 
311
240
  ---
312
241
 
313
- ### `faceAntiSpoofFrameProcessor(frame)`
314
-
315
- Process frame and get anti-spoofing result.
316
-
317
- ```javascript
318
- const result = faceAntiSpoofFrameProcessor(frame);
319
- ```
320
-
321
- **Parameters**: `frame` (Vision Camera Frame)
322
-
323
- **Returns**: `FaceAntiSpoofingResult | null`. On iOS, inference runs off the frame callback and the returned object can be the latest completed result.
324
-
325
242
  ### `FaceAntiSpoofingResult`
326
243
 
327
244
  ```typescript
@@ -0,0 +1,29 @@
1
+ project(VisionCameraSpoofDetector)
2
+ cmake_minimum_required(VERSION 3.9.0)
3
+
4
+ set(PACKAGE_NAME VisionCameraSpoofDetector)
5
+ set(CMAKE_SUPPRESS_REGENERATION ON)
6
+ set(CMAKE_VERBOSE_MAKEFILE ON)
7
+ set(CMAKE_CXX_STANDARD 20)
8
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
9
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
10
+ set(CMAKE_ANDROID_STL_TYPE c++_shared)
11
+
12
+ add_library(${PACKAGE_NAME} SHARED
13
+ src/main/cpp/cpp-adapter.cpp
14
+ )
15
+
16
+ # Nitrogen-generated specs: this path is valid because the project root is android/
17
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/VisionCameraSpoofDetector+autolinking.cmake)
18
+
19
+ find_library(LOG_LIB log)
20
+ find_package(react-native-vision-camera REQUIRED)
21
+
22
+ target_link_options(${PACKAGE_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
23
+
24
+ target_link_libraries(
25
+ ${PACKAGE_NAME}
26
+ ${LOG_LIB}
27
+ android
28
+ react-native-vision-camera::VisionCamera
29
+ )
@@ -19,8 +19,15 @@ buildscript {
19
19
 
20
20
  apply plugin: 'com.android.library'
21
21
  apply plugin: 'kotlin-android'
22
+ apply from: '../nitrogen/generated/android/VisionCameraSpoofDetector+autolinking.gradle'
23
+
24
+ def reactNativeArchitectures() {
25
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
26
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
27
+ }
22
28
 
23
29
  android {
30
+ namespace "com.margelo.nitro.camera.spoofdetector"
24
31
  compileSdkVersion rootProject.ext.compileSdkVersion
25
32
 
26
33
  defaultConfig {
@@ -35,7 +42,9 @@ android {
35
42
  // Needed for JSI / C++ build
36
43
  externalNativeBuild {
37
44
  cmake {
38
- cppFlags "-std=c++17"
45
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
46
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
47
+ abiFilters (*reactNativeArchitectures())
39
48
  }
40
49
  }
41
50
  }
@@ -61,7 +70,7 @@ android {
61
70
 
62
71
  sourceSets {
63
72
  main {
64
- assets.srcDirs = ['src/main/assets']
73
+ assets.srcDirs = ['../lib/assets']
65
74
  }
66
75
  }
67
76
 
@@ -91,10 +100,14 @@ android {
91
100
 
92
101
  externalNativeBuild {
93
102
  cmake {
94
- path "src/main/cpp/CMakeLists.txt"
95
- version "3.22.1" // Optional: matches your installed CMake
103
+ path "CMakeLists.txt"
104
+ version "3.22.1"
96
105
  }
97
106
  }
107
+
108
+ buildFeatures {
109
+ prefab true
110
+ }
98
111
  }
99
112
 
100
113
  def isNewArchitectureEnabled() {
@@ -109,8 +122,10 @@ repositories {
109
122
  }
110
123
 
111
124
  dependencies {
112
- // React Native
113
- implementation "com.facebook.react:react-native:+"
125
+ implementation "androidx.camera:camera-core:1.7.0-alpha03"
126
+
127
+ // React Native and VisionCamera provide their native Prefab libraries.
128
+ compileOnly "com.facebook.react:react-android"
114
129
 
115
130
  // Kotlin
116
131
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
@@ -130,8 +145,9 @@ dependencies {
130
145
  // AndroidX - EXIF Support for image orientation
131
146
  implementation "androidx.exifinterface:exifinterface:1.3.6"
132
147
 
133
- // VisionCamera 5 uses Nitro frame outputs backed by react-native-worklets.
134
- implementation project(':react-native-vision-camera')
135
- implementation project(':react-native-vision-camera-worklets')
136
- implementation project(':react-native-worklets')
148
+ // VisionCamera 5 and Nitro provide these native libraries to the consuming app.
149
+ compileOnly project(':react-native-vision-camera')
150
+ compileOnly project(':react-native-vision-camera-worklets')
151
+ compileOnly project(':react-native-worklets')
152
+ compileOnly project(':react-native-nitro-modules')
137
153
  }
@@ -0,0 +1,4 @@
1
+ // This package does not need the forced prefab reconfigure workaround.
2
+ // Leaving the task outputs as a normal Gradle up-to-date state prevents the
3
+ // infinite CMake regeneration loop that was triggering
4
+ // "ninja: error: manifest 'build.ninja' still dirty after 100 tries".
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
- package="com.faceantispoof">
3
+ >
4
4
  <application>
5
5
  <meta-data
6
6
  android:name="com.google.mlkit.vision.DEPENDENCIES"
@@ -1,101 +1,33 @@
1
- cmake_minimum_required(VERSION 3.4.1)
2
-
3
- project(fastyuv)
4
-
5
- set(SOURCE_FILES
6
- FastYuvJni.cpp
7
- fast_yuv.cpp
8
- )
9
-
10
- add_library(fastyuv SHARED ${SOURCE_FILES})
11
-
12
- # Enable NEON SIMD optimizations for ARM architectures
13
- if(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
14
- # ARM NEON optimization flags
15
- target_compile_options(fastyuv PRIVATE
16
- -fPIC
17
- -O3
18
- )
19
-
20
- # ARM-specific NEON enablement (clang doesn't support -march=native for cross-compilation)
21
- if(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7")
22
- # ARMv7 with NEON (32-bit ARM)
23
- target_compile_options(fastyuv PRIVATE -march=armv7-a -mfpu=neon -mfloat-abi=softfp)
24
- elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
25
- # ARMv8 with full SIMD support (64-bit ARM)
26
- target_compile_options(fastyuv PRIVATE -march=armv8-a)
27
- endif()
28
- endif()
29
-
30
- # Always add libyuv include dir so headers like libyuv/convert.h are found.
31
- target_include_directories(fastyuv PRIVATE ${CMAKE_SOURCE_DIR}/libyuv/include)
32
-
33
- # Prefer using libyuv subproject if available.
34
- if (EXISTS ${CMAKE_SOURCE_DIR}/libyuv/CMakeLists.txt)
35
- add_subdirectory(libyuv)
36
- # Link against the libyuv target produced by that CMake. The lib creates
37
- # targets named 'yuv' (static) and 'yuv_shared' (shared) whose output
38
- # library name is 'libyuv'. Prefer the shared target when available.
39
- if (TARGET yuv_shared)
40
- target_link_libraries(fastyuv PRIVATE yuv_shared)
41
- elseif (TARGET yuv)
42
- target_link_libraries(fastyuv PRIVATE yuv)
43
- endif()
44
- endif()
45
-
46
- # ๆ”ฏๆŒ Android 15+ ็š„ 16KB ้กต้ขๅคงๅฐ
47
- # https://developer.android.com/guide/practices/page-sizes
48
- target_link_options(fastyuv PRIVATE "-Wl,-z,max-page-size=16384")
49
-
50
- # Android log
51
- find_library(log-lib log)
52
- target_link_libraries(fastyuv PRIVATE ${log-lib})
53
1
  cmake_minimum_required(VERSION 3.18)
54
- project(faceantispoof)
2
+ project(VisionCameraSpoofDetector)
55
3
 
56
4
  set(CMAKE_CXX_STANDARD 17)
57
5
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+ set(CMAKE_SUPPRESS_REGENERATION ON)
58
7
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
8
+ set(CMAKE_ANDROID_STL_TYPE c++_shared)
59
9
 
60
- get_filename_component(CMAKE_SOURCE_ABS "${CMAKE_SOURCE_DIR}" ABSOLUTE)
61
- # .../react-native-vision-camera-spoof-detector/android/src/main/cpp -> ../../../.. = .../node_modules
62
- get_filename_component(PARENT_1 "${CMAKE_SOURCE_ABS}/.." ABSOLUTE) # main
63
- get_filename_component(PARENT_2 "${PARENT_1}/.." ABSOLUTE) # src
64
- get_filename_component(PARENT_3 "${PARENT_2}/.." ABSOLUTE) # android
65
- get_filename_component(PARENT_4 "${PARENT_3}/.." ABSOLUTE) # react-native-vision-camera-spoof-detector
66
- get_filename_component(NODE_MODULES_ABS "${PARENT_4}/.." ABSOLUTE) # node_modules
67
-
68
- set(REACT_NATIVE_DIR "${NODE_MODULES_ABS}/react-native")
69
- set(REACT_COMMON_DIR "${REACT_NATIVE_DIR}/ReactCommon")
70
-
71
- message(STATUS "NODE_MODULES_ABS: ${NODE_MODULES_ABS}")
72
- message(STATUS "REACT_NATIVE_DIR: ${REACT_NATIVE_DIR}")
73
- message(STATUS "REACT_COMMON_DIR: ${REACT_COMMON_DIR}")
10
+ set(PACKAGE_NAME VisionCameraSpoofDetector)
11
+ set(CMAKE_VERBOSE_MAKEFILE ON)
74
12
 
75
- # Compile JSI implementation
76
- file(GLOB JSI_CPP "${REACT_COMMON_DIR}/jsi/jsi/jsi.cpp")
77
-
78
- add_library(faceantispoof SHARED FaceAntiSpoofJSI.cpp ${JSI_CPP})
79
-
80
- target_include_directories(faceantispoof PRIVATE
81
- "${REACT_COMMON_DIR}/jsi"
82
- "${REACT_COMMON_DIR}/cxxreact"
83
- "${REACT_COMMON_DIR}/callinvoker/ReactCommon"
84
- "${REACT_COMMON_DIR}/runtimeexecutor/ReactCommon"
85
- "${REACT_COMMON_DIR}"
13
+ add_library(${PACKAGE_NAME} SHARED
14
+ cpp-adapter.cpp
86
15
  )
87
16
 
88
- find_library(log-lib log)
17
+ # Nitrogen-generated hybrid bindings
18
+ include(${CMAKE_SOURCE_DIR}/../../../../nitrogen/generated/android/VisionCameraSpoofDetector+autolinking.cmake)
19
+
20
+ find_library(LOG_LIB log)
21
+ find_package(react-native-vision-camera REQUIRED)
89
22
 
90
- # ๆ”ฏๆŒ Android 15+ ็š„ 16KB ้กต้ขๅคงๅฐ
91
- target_link_options(faceantispoof PRIVATE "-Wl,-z,max-page-size=16384")
23
+ # Android 15+ 16KB page support
24
+ target_link_options(${PACKAGE_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
92
25
 
93
26
  target_link_libraries(
94
- faceantispoof
95
- "${log-lib}"
96
- c++_shared
97
- atomic
98
- m
27
+ ${PACKAGE_NAME}
28
+ ${LOG_LIB}
29
+ android
30
+ react-native-vision-camera::VisionCamera
99
31
  )
100
32
 
101
33