react-native-vision-camera-spoof-detector 1.1.22 → 1.1.24

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 (201) hide show
  1. package/android/CMakeLists.txt +12 -0
  2. package/android/build.gradle +10 -9
  3. package/android/src/main/cpp/cpp-adapter.cpp +6 -3
  4. package/android/src/main/java/com/faceantispoof/FaceAntiSpoofingAdvanced.kt +83 -0
  5. package/android/src/main/java/com/margelo/nitro/camera/spoofdetector/HybridSpoofDetectorOutput.kt +26 -11
  6. package/package.json +1 -1
  7. package/android/src/main/cpp/CMakeLists.txt +0 -33
  8. package/android/src/main/cpp/FaceAntiSpoofJSI.cpp +0 -142
  9. package/android/src/main/cpp/FastYuvJni.cpp +0 -111
  10. package/android/src/main/cpp/fast_yuv.cpp +0 -342
  11. package/android/src/main/cpp/fast_yuv.h +0 -23
  12. package/android/src/main/cpp/libyuv/.clang-format +0 -6
  13. package/android/src/main/cpp/libyuv/.gn +0 -40
  14. package/android/src/main/cpp/libyuv/.vpython3 +0 -410
  15. package/android/src/main/cpp/libyuv/AUTHORS +0 -7
  16. package/android/src/main/cpp/libyuv/Android.bp +0 -202
  17. package/android/src/main/cpp/libyuv/Android.mk +0 -106
  18. package/android/src/main/cpp/libyuv/BUILD.gn +0 -490
  19. package/android/src/main/cpp/libyuv/CM_linux_packages.cmake +0 -70
  20. package/android/src/main/cpp/libyuv/CMakeLists.txt +0 -259
  21. package/android/src/main/cpp/libyuv/DEPS +0 -935
  22. package/android/src/main/cpp/libyuv/DIR_METADATA +0 -3
  23. package/android/src/main/cpp/libyuv/LICENSE +0 -29
  24. package/android/src/main/cpp/libyuv/OWNERS +0 -11
  25. package/android/src/main/cpp/libyuv/PATENTS +0 -24
  26. package/android/src/main/cpp/libyuv/PRESUBMIT.py +0 -65
  27. package/android/src/main/cpp/libyuv/README.chromium +0 -11
  28. package/android/src/main/cpp/libyuv/README.md +0 -19
  29. package/android/src/main/cpp/libyuv/build_overrides/build.gni +0 -60
  30. package/android/src/main/cpp/libyuv/build_overrides/gtest.gni +0 -19
  31. package/android/src/main/cpp/libyuv/build_overrides/partition_alloc.gni +0 -17
  32. package/android/src/main/cpp/libyuv/codereview.settings +0 -5
  33. package/android/src/main/cpp/libyuv/docs/deprecated_builds.md +0 -409
  34. package/android/src/main/cpp/libyuv/docs/environment_variables.md +0 -64
  35. package/android/src/main/cpp/libyuv/docs/feature_detection.md +0 -108
  36. package/android/src/main/cpp/libyuv/docs/filtering.md +0 -196
  37. package/android/src/main/cpp/libyuv/docs/formats.md +0 -208
  38. package/android/src/main/cpp/libyuv/docs/getting_started.md +0 -296
  39. package/android/src/main/cpp/libyuv/docs/rotation.md +0 -107
  40. package/android/src/main/cpp/libyuv/download_vs_toolchain.py +0 -29
  41. package/android/src/main/cpp/libyuv/include/libyuv/basic_types.h +0 -68
  42. package/android/src/main/cpp/libyuv/include/libyuv/compare.h +0 -111
  43. package/android/src/main/cpp/libyuv/include/libyuv/compare_row.h +0 -112
  44. package/android/src/main/cpp/libyuv/include/libyuv/convert.h +0 -1117
  45. package/android/src/main/cpp/libyuv/include/libyuv/convert_argb.h +0 -2335
  46. package/android/src/main/cpp/libyuv/include/libyuv/convert_from.h +0 -203
  47. package/android/src/main/cpp/libyuv/include/libyuv/convert_from_argb.h +0 -394
  48. package/android/src/main/cpp/libyuv/include/libyuv/cpu_id.h +0 -147
  49. package/android/src/main/cpp/libyuv/include/libyuv/cpu_support.h +0 -99
  50. package/android/src/main/cpp/libyuv/include/libyuv/loongson_intrinsics.h +0 -1949
  51. package/android/src/main/cpp/libyuv/include/libyuv/mjpeg_decoder.h +0 -195
  52. package/android/src/main/cpp/libyuv/include/libyuv/planar_functions.h +0 -1131
  53. package/android/src/main/cpp/libyuv/include/libyuv/rotate.h +0 -296
  54. package/android/src/main/cpp/libyuv/include/libyuv/rotate_argb.h +0 -37
  55. package/android/src/main/cpp/libyuv/include/libyuv/rotate_row.h +0 -265
  56. package/android/src/main/cpp/libyuv/include/libyuv/row.h +0 -6738
  57. package/android/src/main/cpp/libyuv/include/libyuv/row_sve.h +0 -2154
  58. package/android/src/main/cpp/libyuv/include/libyuv/scale.h +0 -336
  59. package/android/src/main/cpp/libyuv/include/libyuv/scale_argb.h +0 -76
  60. package/android/src/main/cpp/libyuv/include/libyuv/scale_rgb.h +0 -42
  61. package/android/src/main/cpp/libyuv/include/libyuv/scale_row.h +0 -1726
  62. package/android/src/main/cpp/libyuv/include/libyuv/scale_uv.h +0 -51
  63. package/android/src/main/cpp/libyuv/include/libyuv/version.h +0 -16
  64. package/android/src/main/cpp/libyuv/include/libyuv/video_common.h +0 -222
  65. package/android/src/main/cpp/libyuv/include/libyuv.h +0 -33
  66. package/android/src/main/cpp/libyuv/infra/config/OWNERS +0 -3
  67. package/android/src/main/cpp/libyuv/infra/config/PRESUBMIT.py +0 -17
  68. package/android/src/main/cpp/libyuv/infra/config/README.md +0 -2
  69. package/android/src/main/cpp/libyuv/infra/config/codereview.settings +0 -6
  70. package/android/src/main/cpp/libyuv/infra/config/commit-queue.cfg +0 -144
  71. package/android/src/main/cpp/libyuv/infra/config/cr-buildbucket.cfg +0 -1185
  72. package/android/src/main/cpp/libyuv/infra/config/luci-logdog.cfg +0 -9
  73. package/android/src/main/cpp/libyuv/infra/config/luci-milo.cfg +0 -246
  74. package/android/src/main/cpp/libyuv/infra/config/luci-scheduler.cfg +0 -385
  75. package/android/src/main/cpp/libyuv/infra/config/main.star +0 -402
  76. package/android/src/main/cpp/libyuv/infra/config/project.cfg +0 -16
  77. package/android/src/main/cpp/libyuv/infra/config/realms.cfg +0 -111
  78. package/android/src/main/cpp/libyuv/libyuv.gni +0 -34
  79. package/android/src/main/cpp/libyuv/libyuv.gyp +0 -149
  80. package/android/src/main/cpp/libyuv/libyuv.gypi +0 -87
  81. package/android/src/main/cpp/libyuv/linux.mk +0 -96
  82. package/android/src/main/cpp/libyuv/public.mk +0 -13
  83. package/android/src/main/cpp/libyuv/pylintrc +0 -49
  84. package/android/src/main/cpp/libyuv/riscv_script/prepare_toolchain_qemu.sh +0 -74
  85. package/android/src/main/cpp/libyuv/riscv_script/riscv-clang.cmake +0 -56
  86. package/android/src/main/cpp/libyuv/riscv_script/run_qemu.sh +0 -15
  87. package/android/src/main/cpp/libyuv/source/compare.cc +0 -435
  88. package/android/src/main/cpp/libyuv/source/compare_common.cc +0 -74
  89. package/android/src/main/cpp/libyuv/source/compare_gcc.cc +0 -362
  90. package/android/src/main/cpp/libyuv/source/compare_neon.cc +0 -96
  91. package/android/src/main/cpp/libyuv/source/compare_neon64.cc +0 -223
  92. package/android/src/main/cpp/libyuv/source/compare_win.cc +0 -241
  93. package/android/src/main/cpp/libyuv/source/convert.cc +0 -4746
  94. package/android/src/main/cpp/libyuv/source/convert_argb.cc +0 -9179
  95. package/android/src/main/cpp/libyuv/source/convert_from.cc +0 -866
  96. package/android/src/main/cpp/libyuv/source/convert_from_argb.cc +0 -3671
  97. package/android/src/main/cpp/libyuv/source/convert_jpeg.cc +0 -602
  98. package/android/src/main/cpp/libyuv/source/convert_to_argb.cc +0 -391
  99. package/android/src/main/cpp/libyuv/source/convert_to_i420.cc +0 -288
  100. package/android/src/main/cpp/libyuv/source/cpu_id.cc +0 -496
  101. package/android/src/main/cpp/libyuv/source/mjpeg_decoder.cc +0 -580
  102. package/android/src/main/cpp/libyuv/source/mjpeg_validate.cc +0 -71
  103. package/android/src/main/cpp/libyuv/source/planar_functions.cc +0 -5663
  104. package/android/src/main/cpp/libyuv/source/rotate.cc +0 -1241
  105. package/android/src/main/cpp/libyuv/source/rotate_any.cc +0 -76
  106. package/android/src/main/cpp/libyuv/source/rotate_argb.cc +0 -259
  107. package/android/src/main/cpp/libyuv/source/rotate_common.cc +0 -208
  108. package/android/src/main/cpp/libyuv/source/rotate_gcc.cc +0 -505
  109. package/android/src/main/cpp/libyuv/source/rotate_lsx.cc +0 -233
  110. package/android/src/main/cpp/libyuv/source/rotate_neon.cc +0 -219
  111. package/android/src/main/cpp/libyuv/source/rotate_neon64.cc +0 -273
  112. package/android/src/main/cpp/libyuv/source/rotate_sme.cc +0 -174
  113. package/android/src/main/cpp/libyuv/source/rotate_win.cc +0 -253
  114. package/android/src/main/cpp/libyuv/source/row_any.cc +0 -2519
  115. package/android/src/main/cpp/libyuv/source/row_common.cc +0 -4461
  116. package/android/src/main/cpp/libyuv/source/row_gcc.cc +0 -9570
  117. package/android/src/main/cpp/libyuv/source/row_lasx.cc +0 -2343
  118. package/android/src/main/cpp/libyuv/source/row_lsx.cc +0 -3030
  119. package/android/src/main/cpp/libyuv/source/row_neon.cc +0 -4026
  120. package/android/src/main/cpp/libyuv/source/row_neon64.cc +0 -5617
  121. package/android/src/main/cpp/libyuv/source/row_rvv.cc +0 -2599
  122. package/android/src/main/cpp/libyuv/source/row_sme.cc +0 -1183
  123. package/android/src/main/cpp/libyuv/source/row_sve.cc +0 -1088
  124. package/android/src/main/cpp/libyuv/source/row_win.cc +0 -6453
  125. package/android/src/main/cpp/libyuv/source/scale.cc +0 -2710
  126. package/android/src/main/cpp/libyuv/source/scale_any.cc +0 -991
  127. package/android/src/main/cpp/libyuv/source/scale_argb.cc +0 -1158
  128. package/android/src/main/cpp/libyuv/source/scale_common.cc +0 -1977
  129. package/android/src/main/cpp/libyuv/source/scale_gcc.cc +0 -2947
  130. package/android/src/main/cpp/libyuv/source/scale_lsx.cc +0 -739
  131. package/android/src/main/cpp/libyuv/source/scale_neon.cc +0 -1449
  132. package/android/src/main/cpp/libyuv/source/scale_neon64.cc +0 -1552
  133. package/android/src/main/cpp/libyuv/source/scale_rgb.cc +0 -82
  134. package/android/src/main/cpp/libyuv/source/scale_rvv.cc +0 -1971
  135. package/android/src/main/cpp/libyuv/source/scale_sme.cc +0 -555
  136. package/android/src/main/cpp/libyuv/source/scale_uv.cc +0 -1159
  137. package/android/src/main/cpp/libyuv/source/scale_win.cc +0 -1392
  138. package/android/src/main/cpp/libyuv/source/test.sh +0 -35
  139. package/android/src/main/cpp/libyuv/source/video_common.cc +0 -62
  140. package/android/src/main/cpp/libyuv/tools_libyuv/OWNERS +0 -4
  141. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/roll_deps.py +0 -931
  142. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py +0 -164
  143. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS +0 -21
  144. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.new +0 -13
  145. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old +0 -13
  146. package/android/src/main/cpp/libyuv/tools_libyuv/get_landmines.py +0 -38
  147. package/android/src/main/cpp/libyuv/tools_libyuv/msan/OWNERS +0 -3
  148. package/android/src/main/cpp/libyuv/tools_libyuv/msan/blacklist.txt +0 -9
  149. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/OWNERS +0 -3
  150. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/blacklist.txt +0 -15
  151. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/vptr_blacklist.txt +0 -25
  152. package/android/src/main/cpp/libyuv/unit_test/basictypes_test.cc +0 -43
  153. package/android/src/main/cpp/libyuv/unit_test/color_test.cc +0 -848
  154. package/android/src/main/cpp/libyuv/unit_test/compare_test.cc +0 -739
  155. package/android/src/main/cpp/libyuv/unit_test/convert_argb_test.cc +0 -2867
  156. package/android/src/main/cpp/libyuv/unit_test/convert_test.cc +0 -2133
  157. package/android/src/main/cpp/libyuv/unit_test/cpu_test.cc +0 -427
  158. package/android/src/main/cpp/libyuv/unit_test/cpu_thread_test.cc +0 -63
  159. package/android/src/main/cpp/libyuv/unit_test/math_test.cc +0 -160
  160. package/android/src/main/cpp/libyuv/unit_test/planar_test.cc +0 -4731
  161. package/android/src/main/cpp/libyuv/unit_test/rotate_argb_test.cc +0 -334
  162. package/android/src/main/cpp/libyuv/unit_test/rotate_test.cc +0 -962
  163. package/android/src/main/cpp/libyuv/unit_test/scale_argb_test.cc +0 -590
  164. package/android/src/main/cpp/libyuv/unit_test/scale_plane_test.cc +0 -465
  165. package/android/src/main/cpp/libyuv/unit_test/scale_rgb_test.cc +0 -280
  166. package/android/src/main/cpp/libyuv/unit_test/scale_test.cc +0 -1135
  167. package/android/src/main/cpp/libyuv/unit_test/scale_uv_test.cc +0 -249
  168. package/android/src/main/cpp/libyuv/unit_test/testdata/arm_v7.txt +0 -12
  169. package/android/src/main/cpp/libyuv/unit_test/testdata/mips.txt +0 -7
  170. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson2k.txt +0 -5
  171. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson3.txt +0 -10
  172. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson_mmi.txt +0 -7
  173. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64.txt +0 -4
  174. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64_rvv.txt +0 -4
  175. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64_rvv_zvfh.txt +0 -4
  176. package/android/src/main/cpp/libyuv/unit_test/testdata/tegra3.txt +0 -23
  177. package/android/src/main/cpp/libyuv/unit_test/testdata/test0.jpg +0 -0
  178. package/android/src/main/cpp/libyuv/unit_test/testdata/test1.jpg +0 -0
  179. package/android/src/main/cpp/libyuv/unit_test/testdata/test2.jpg +0 -0
  180. package/android/src/main/cpp/libyuv/unit_test/testdata/test3.jpg +0 -0
  181. package/android/src/main/cpp/libyuv/unit_test/testdata/test4.jpg +0 -0
  182. package/android/src/main/cpp/libyuv/unit_test/unit_test.cc +0 -581
  183. package/android/src/main/cpp/libyuv/unit_test/unit_test.h +0 -232
  184. package/android/src/main/cpp/libyuv/unit_test/video_common_test.cc +0 -112
  185. package/android/src/main/cpp/libyuv/util/Makefile +0 -9
  186. package/android/src/main/cpp/libyuv/util/color.cc +0 -120
  187. package/android/src/main/cpp/libyuv/util/compare.cc +0 -67
  188. package/android/src/main/cpp/libyuv/util/cpuid.c +0 -211
  189. package/android/src/main/cpp/libyuv/util/i444tonv12_eg.cc +0 -28
  190. package/android/src/main/cpp/libyuv/util/psnr.cc +0 -291
  191. package/android/src/main/cpp/libyuv/util/psnr.h +0 -47
  192. package/android/src/main/cpp/libyuv/util/psnr_main.cc +0 -620
  193. package/android/src/main/cpp/libyuv/util/ssim.cc +0 -364
  194. package/android/src/main/cpp/libyuv/util/ssim.h +0 -38
  195. package/android/src/main/cpp/libyuv/util/yuvconstants.c +0 -114
  196. package/android/src/main/cpp/libyuv/util/yuvconvert.cc +0 -367
  197. package/android/src/main/cpp/libyuv/winarm.mk +0 -47
  198. package/android/src/main/java/com/faceantispoof/ByteBufferPool.kt +0 -68
  199. package/android/src/main/java/com/faceantispoof/FastYuv.kt +0 -51
  200. package/android/src/main/java/com/faceantispoof/YuvToFloatArrayConverter.kt +0 -584
  201. package/android/src/main/java/com/faceantispoof/YuvToRgbConverter.kt +0 -73
@@ -18,6 +18,9 @@ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/VisionCameraSpoofDetec
18
18
 
19
19
  find_library(LOG_LIB log)
20
20
  find_package(react-native-vision-camera REQUIRED)
21
+ find_package(ReactAndroid REQUIRED)
22
+ find_package(fbjni REQUIRED)
23
+ find_package(react-native-nitro-modules REQUIRED)
21
24
 
22
25
  target_link_options(${PACKAGE_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
23
26
 
@@ -25,5 +28,14 @@ target_link_libraries(
25
28
  ${PACKAGE_NAME}
26
29
  ${LOG_LIB}
27
30
  android
31
+ fbjni::fbjni
32
+ ReactAndroid::jsi
33
+ react-native-nitro-modules::NitroModules
28
34
  react-native-vision-camera::VisionCamera
29
35
  )
36
+
37
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
38
+ target_link_libraries(${PACKAGE_NAME} ReactAndroid::reactnative)
39
+ else()
40
+ target_link_libraries(${PACKAGE_NAME} ReactAndroid::react_nativemodule_core)
41
+ endif()
@@ -38,15 +38,6 @@ android {
38
38
 
39
39
  buildConfigField "String", "MODEL_FILE", "\"FaceAntiSpoofing.tflite\""
40
40
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
41
-
42
- // Needed for JSI / C++ build
43
- externalNativeBuild {
44
- cmake {
45
- cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
46
- arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
47
- abiFilters (*reactNativeArchitectures())
48
- }
49
- }
50
41
  }
51
42
 
52
43
  buildTypes {
@@ -98,6 +89,16 @@ android {
98
89
  }
99
90
  }
100
91
 
92
+ defaultConfig {
93
+ externalNativeBuild {
94
+ cmake {
95
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
96
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
97
+ abiFilters(*reactNativeArchitectures())
98
+ }
99
+ }
100
+ }
101
+
101
102
  externalNativeBuild {
102
103
  cmake {
103
104
  path "CMakeLists.txt"
@@ -1,9 +1,12 @@
1
- #include "VisionCameraSpoofDetectorOnLoad.hpp"
2
- #include <fbjni/fbjni.h>
3
1
  #include <jni.h>
2
+ #include <fbjni/fbjni.h>
3
+
4
+ #include "VisionCameraSpoofDetectorOnLoad.hpp"
4
5
 
6
+ extern "C" {
5
7
  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
6
8
  return facebook::jni::initialize(vm, []() {
7
9
  margelo::nitro::camera::spoofdetector::registerAllNatives();
8
10
  });
9
- }
11
+ }
12
+ }
@@ -260,6 +260,50 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
260
260
  }
261
261
  }
262
262
 
263
+ fun advancedAntiSpoofingRGBA(buffer: ByteBuffer, width: Int, height: Int, rowStride: Int, pixelStride: Int): AntiSpoofingResult {
264
+ if (!isInitialized) {
265
+ return AntiSpoofingResult(
266
+ neuralNetworkScore = 0f,
267
+ laplacianScore = 0,
268
+ textureComplexity = 0,
269
+ temporalConsistency = 0f,
270
+ colorSaturation = 0f,
271
+ combinedScore = 0f,
272
+ confidence = 0f
273
+ )
274
+ }
275
+
276
+ return try {
277
+ val sampled = sampleRgbaBufferToModelAndGray(buffer, width, height, rowStride, pixelStride)
278
+ val nnResult = neuralNetworkAntiSpoofingSampled(sampled.rgbBuffer)
279
+ val nnScore = nnResult.getOrNull() ?: throw IllegalStateException(nnResult.exceptionOrNull()?.message ?: "NN inference failed")
280
+ val laplacianScore = calculateLaplacianFromGray(sampled.grayBuffer)
281
+ val combinedScore = calculateCombinedScore(nnScore, laplacianScore)
282
+ val confidence = calculateConfidence(nnScore, laplacianScore)
283
+
284
+ AntiSpoofingResult(
285
+ neuralNetworkScore = nnScore,
286
+ laplacianScore = laplacianScore,
287
+ textureComplexity = 0,
288
+ temporalConsistency = 0f,
289
+ colorSaturation = 0f,
290
+ combinedScore = combinedScore,
291
+ confidence = confidence
292
+ )
293
+ } catch (e: Exception) {
294
+ Log.e(TAG, "Error in advancedAntiSpoofingRGBA buffer path", e)
295
+ AntiSpoofingResult(
296
+ neuralNetworkScore = 0f,
297
+ laplacianScore = 0,
298
+ textureComplexity = 0,
299
+ temporalConsistency = 0f,
300
+ colorSaturation = 0f,
301
+ combinedScore = 0f,
302
+ confidence = 0f
303
+ )
304
+ }
305
+ }
306
+
263
307
  // FROM WORKING VERSION: neuralNetworkAntiSpoofing with Bitmap
264
308
  private fun neuralNetworkAntiSpoofing(bitmap: Bitmap): Result<Float> {
265
309
  return try {
@@ -381,6 +425,45 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
381
425
  return SampledFrame(modelInputBuffer, grayBuffer)
382
426
  }
383
427
 
428
+ private fun sampleRgbaBufferToModelAndGray(
429
+ buffer: ByteBuffer,
430
+ srcWidth: Int,
431
+ srcHeight: Int,
432
+ rowStride: Int,
433
+ pixelStride: Int
434
+ ): SampledFrame {
435
+ val targetWidth = INPUT_IMAGE_SIZE
436
+ val targetHeight = INPUT_IMAGE_SIZE
437
+ val scaleX = srcWidth.toFloat() / targetWidth
438
+ val scaleY = srcHeight.toFloat() / targetHeight
439
+ val duplicated = buffer.duplicate()
440
+ duplicated.order(ByteOrder.nativeOrder())
441
+
442
+ for (targetY in 0 until targetHeight) {
443
+ val srcY = (targetY * scaleY).toInt().coerceIn(0, srcHeight - 1)
444
+ val rowOffset = srcY * rowStride
445
+ for (targetX in 0 until targetWidth) {
446
+ val srcX = (targetX * scaleX).toInt().coerceIn(0, srcWidth - 1)
447
+ val pixelIndex = rowOffset + srcX * pixelStride
448
+
449
+ val r = duplicated.get(pixelIndex).toInt() and 0xFF
450
+ val g = duplicated.get(pixelIndex + 1).toInt() and 0xFF
451
+ val b = duplicated.get(pixelIndex + 2).toInt() and 0xFF
452
+
453
+ modelInputBuffer[targetY][targetX][0] = r / 255f
454
+ modelInputBuffer[targetY][targetX][1] = g / 255f
455
+ modelInputBuffer[targetY][targetX][2] = b / 255f
456
+ grayBuffer[targetY][targetX] = (
457
+ 0.299f * r +
458
+ 0.587f * g +
459
+ 0.114f * b
460
+ ).toInt()
461
+ }
462
+ }
463
+
464
+ return SampledFrame(modelInputBuffer, grayBuffer)
465
+ }
466
+
384
467
  // FROM WORKING VERSION: laplacian with Bitmap
385
468
  private fun laplacian(bitmap: Bitmap): Result<Int> {
386
469
  return try {
@@ -83,12 +83,21 @@ class HybridSpoofDetectorOutput(
83
83
  return
84
84
  }
85
85
  try {
86
- val rgba = extractRgbaBytes(image)
87
- if (!shouldProcessFrame(rgba, image.width, image.height)) {
86
+ val plane = image.planes.firstOrNull() ?: throw IllegalStateException("RGBA image has no planes")
87
+ val rgba = plane.buffer.duplicate()
88
+ rgba.order(java.nio.ByteOrder.nativeOrder())
89
+
90
+ if (!shouldProcessFrameFromPlane(rgba, image.width, image.height, plane.rowStride, plane.pixelStride)) {
88
91
  return
89
92
  }
90
93
 
91
- val result = detector.advancedAntiSpoofingRGBA(rgba, image.width, image.height)
94
+ val result = detector.advancedAntiSpoofingRGBA(
95
+ rgba,
96
+ image.width,
97
+ image.height,
98
+ plane.rowStride,
99
+ plane.pixelStride,
100
+ )
92
101
  val isLive = result.neuralNetworkScore < FaceAntiSpoofingAdvanced.BASE_THRESHOLD &&
93
102
  result.laplacianScore > FaceAntiSpoofingAdvanced.LAPLACIAN_THRESHOLD
94
103
  options.onResult.invoke(
@@ -109,7 +118,13 @@ class HybridSpoofDetectorOutput(
109
118
  }
110
119
  }
111
120
 
112
- private fun shouldProcessFrame(rgba: ByteArray, width: Int, height: Int): Boolean {
121
+ private fun shouldProcessFrameFromPlane(
122
+ buffer: java.nio.ByteBuffer,
123
+ width: Int,
124
+ height: Int,
125
+ rowStride: Int,
126
+ pixelStride: Int,
127
+ ): Boolean {
113
128
  val frameIndex = frameCounter.incrementAndGet()
114
129
  if (frameIndex % FRAME_EVALUATION_INTERVAL != 0) {
115
130
  return false
@@ -121,14 +136,14 @@ class HybridSpoofDetectorOutput(
121
136
  var sampleCount = 0
122
137
 
123
138
  for (y in 0 until height step sampleStep) {
124
- val rowOffset = y * width * 4
139
+ val rowOffset = y * rowStride
125
140
  for (x in 0 until width step sampleStep) {
126
- val index = rowOffset + x * 4
127
- if (index + 2 >= rgba.size) continue
141
+ val index = rowOffset + x * pixelStride
142
+ if (index + 2 >= buffer.capacity()) continue
128
143
 
129
- val r = rgba[index].toInt() and 0xFF
130
- val g = rgba[index + 1].toInt() and 0xFF
131
- val b = rgba[index + 2].toInt() and 0xFF
144
+ val r = buffer.get(index).toInt() and 0xFF
145
+ val g = buffer.get(index + 1).toInt() and 0xFF
146
+ val b = buffer.get(index + 2).toInt() and 0xFF
132
147
  val luma = (0.299 * r + 0.587 * g + 0.114 * b).toInt()
133
148
 
134
149
  brightnessSum += luma.toLong()
@@ -143,7 +158,7 @@ class HybridSpoofDetectorOutput(
143
158
 
144
159
  val avgBrightness = brightnessSum.toFloat() / sampleCount
145
160
  val variance = (brightnessSquaredSum.toFloat() / sampleCount) - (avgBrightness * avgBrightness)
146
- val brightnessDelta = kotlin.math.abs(avgBrightness - lastFrameBrightness)
161
+ val brightnessDelta = abs(avgBrightness - lastFrameBrightness)
147
162
  lastFrameBrightness = avgBrightness
148
163
 
149
164
  val brightnessOk = avgBrightness in MIN_FRAME_BRIGHTNESS..MAX_FRAME_BRIGHTNESS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-vision-camera-spoof-detector",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "High-performance face anti-spoofing and liveness detection module for React Native Vision Camera. Uses TensorFlow Lite with GPU acceleration and optimized YUV processing.",
5
5
  "homepage": "https://github.com/dpraful/react-native-vision-camera-spoof-detector",
6
6
  "repository": {
@@ -1,33 +0,0 @@
1
- cmake_minimum_required(VERSION 3.18)
2
- project(VisionCameraSpoofDetector)
3
-
4
- set(CMAKE_CXX_STANDARD 17)
5
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
- set(CMAKE_SUPPRESS_REGENERATION ON)
7
- set(CMAKE_POSITION_INDEPENDENT_CODE ON)
8
- set(CMAKE_ANDROID_STL_TYPE c++_shared)
9
-
10
- set(PACKAGE_NAME VisionCameraSpoofDetector)
11
- set(CMAKE_VERBOSE_MAKEFILE ON)
12
-
13
- add_library(${PACKAGE_NAME} SHARED
14
- cpp-adapter.cpp
15
- )
16
-
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)
22
-
23
- # Android 15+ 16KB page support
24
- target_link_options(${PACKAGE_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
25
-
26
- target_link_libraries(
27
- ${PACKAGE_NAME}
28
- ${LOG_LIB}
29
- android
30
- react-native-vision-camera::VisionCamera
31
- )
32
-
33
-
@@ -1,142 +0,0 @@
1
- #include <jni.h>
2
- #include <jsi/jsi.h>
3
- #include <string>
4
- #include <vector>
5
- #include <algorithm>
6
- #include <android/log.h>
7
-
8
- using namespace facebook;
9
-
10
- // Logging macro
11
- #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "FaceAntiSpoofJSI", __VA_ARGS__))
12
-
13
- static JavaVM *javaVm = nullptr;
14
-
15
- jsi::Value faceAntiSpoof(jsi::Runtime &runtime, const jsi::Value &frame) {
16
- if (!frame.isObject()) {
17
- throw jsi::JSError(runtime, "FaceAntiSpoof expected a Frame object");
18
- }
19
-
20
- auto frameObject = frame.asObject(runtime);
21
- auto planesValue = frameObject.getProperty(runtime, "getPlanes").asObject(runtime)
22
- .asFunction(runtime).call(runtime, frameObject);
23
- auto planes = planesValue.asObject(runtime);
24
- auto length = static_cast<size_t>(planes.getProperty(runtime, "length").asNumber());
25
- if (length < 3) {
26
- throw jsi::JSError(runtime, "FaceAntiSpoof expected Y, U and V planes");
27
- }
28
-
29
- std::vector<std::vector<uint8_t>> planeData(3);
30
- jint rowStrides[3] = {};
31
- jint pixelStrides[3] = {};
32
- for (size_t index = 0; index < 3; index++) {
33
- auto plane = planes.getProperty(runtime, jsi::Value(static_cast<double>(index))).asObject(runtime);
34
- auto buffer = plane.getProperty(runtime, "getPixelBuffer").asObject(runtime)
35
- .asFunction(runtime).call(runtime, plane).asObject(runtime);
36
- auto arrayBuffer = std::move(buffer).getArrayBuffer(runtime);
37
- auto *data = static_cast<const uint8_t *>(arrayBuffer.data(runtime));
38
- planeData[index].assign(data, data + arrayBuffer.size(runtime));
39
- rowStrides[index] = static_cast<jint>(plane.getProperty(runtime, "bytesPerRow").asNumber());
40
- auto planeWidth = plane.getProperty(runtime, "width").asNumber();
41
- pixelStrides[index] = std::max(1, static_cast<jint>(rowStrides[index] / planeWidth));
42
- }
43
-
44
- JNIEnv *env = nullptr;
45
- bool attached = false;
46
- if (javaVm == nullptr) {
47
- throw jsi::JSError(runtime, "FaceAntiSpoof Android runtime is unavailable");
48
- }
49
- if (javaVm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) == JNI_EDETACHED) {
50
- if (javaVm->AttachCurrentThread(&env, nullptr) != JNI_OK) {
51
- throw jsi::JSError(runtime, "FaceAntiSpoof could not attach to Android runtime");
52
- }
53
- attached = true;
54
- }
55
- auto moduleClass = env->FindClass("com/faceantispoof/FaceAntiSpoofModule");
56
- auto process = env->GetStaticMethodID(moduleClass, "processFrameFromJSI", "([[BII[I[I)[D");
57
- auto javaPlanes = env->NewObjectArray(3, env->FindClass("[B"), nullptr);
58
- auto javaRowStrides = env->NewIntArray(3);
59
- auto javaPixelStrides = env->NewIntArray(3);
60
- env->SetIntArrayRegion(javaRowStrides, 0, 3, rowStrides);
61
- env->SetIntArrayRegion(javaPixelStrides, 0, 3, pixelStrides);
62
- for (int index = 0; index < 3; index++) {
63
- auto bytes = env->NewByteArray(static_cast<jsize>(planeData[index].size()));
64
- env->SetByteArrayRegion(bytes, 0, static_cast<jsize>(planeData[index].size()),
65
- reinterpret_cast<const jbyte *>(planeData[index].data()));
66
- env->SetObjectArrayElement(javaPlanes, index, bytes);
67
- env->DeleteLocalRef(bytes);
68
- }
69
- auto values = static_cast<jdoubleArray>(env->CallStaticObjectMethod(
70
- moduleClass, process, javaPlanes, static_cast<jint>(frameObject.getProperty(runtime, "width").asNumber()),
71
- static_cast<jint>(frameObject.getProperty(runtime, "height").asNumber()),
72
- javaRowStrides, javaPixelStrides));
73
- jdouble output[5] = {};
74
- if (values != nullptr) env->GetDoubleArrayRegion(values, 0, 5, output);
75
- env->DeleteLocalRef(values);
76
- env->DeleteLocalRef(javaPixelStrides);
77
- env->DeleteLocalRef(javaRowStrides);
78
- env->DeleteLocalRef(javaPlanes);
79
- env->DeleteLocalRef(moduleClass);
80
- if (attached) javaVm->DetachCurrentThread();
81
-
82
- jsi::Object result(runtime);
83
- result.setProperty(runtime, "isLive", output[0] != 0.0);
84
- result.setProperty(runtime, "label", output[0] != 0.0 ? "Live Face" : "Spoof Face");
85
- result.setProperty(runtime, "neuralNetworkScore", output[1]);
86
- result.setProperty(runtime, "laplacianScore", output[2]);
87
- result.setProperty(runtime, "combinedScore", output[3]);
88
- result.setProperty(runtime, "confidence", output[4]);
89
- return result;
90
- }
91
-
92
- extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) {
93
- javaVm = vm;
94
- return JNI_VERSION_1_6;
95
- }
96
-
97
- // JSI registration function
98
- extern "C"
99
- JNIEXPORT void JNICALL
100
- Java_com_faceantispoof_FaceAntiSpoofModule_registerJSIFunction(JNIEnv *env, jobject thiz, jlong jsContextPtr) {
101
- LOGI("registerJSIFunction called with jsContextPtr = %ld", (long)jsContextPtr);
102
-
103
- if (jsContextPtr == 0) {
104
- LOGI("FaceAntiSpoofJSI: JS runtime pointer is 0 (null)!");
105
- return;
106
- }
107
-
108
- auto *runtime = reinterpret_cast<jsi::Runtime *>(jsContextPtr);
109
- if (!runtime) {
110
- LOGI("FaceAntiSpoofJSI: Runtime reinterpret_cast resulted in null pointer!");
111
- return;
112
- }
113
-
114
- try {
115
- LOGI("FaceAntiSpoofJSI: Creating JSI function...");
116
-
117
- jsi::Function func = jsi::Function::createFromHostFunction(
118
- *runtime,
119
- jsi::PropNameID::forAscii(*runtime, "__faceAntiSpoof"),
120
- 1,
121
- [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
122
- LOGI("FaceAntiSpoofJSI: __faceAntiSpoof function called");
123
- if (count < 1) {
124
- jsi::Object error(rt);
125
- error.setProperty(rt, "isLive", false);
126
- error.setProperty(rt, "label", "No frame provided");
127
- error.setProperty(rt, "confidence", 0.0);
128
- return error;
129
- }
130
- return faceAntiSpoof(rt, args[0]);
131
- }
132
- );
133
-
134
- LOGI("FaceAntiSpoofJSI: Setting __faceAntiSpoof on global object...");
135
- runtime->global().setProperty(*runtime, "__faceAntiSpoof", std::move(func));
136
- LOGI("FaceAntiSpoofJSI: __faceAntiSpoof registered successfully!");
137
- } catch (const std::exception &e) {
138
- LOGI("FaceAntiSpoofJSI: Exception during JSI registration: %s", e.what());
139
- } catch (...) {
140
- LOGI("FaceAntiSpoofJSI: Unknown exception during JSI registration!");
141
- }
142
- }
@@ -1,111 +0,0 @@
1
- #include <jni.h>
2
- #include <android/log.h>
3
- #include <string.h>
4
- #include "fast_yuv.h"
5
-
6
- #define LOG_TAG "FastYuvJNI"
7
- #define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
8
-
9
- extern "C" {
10
-
11
- JNIEXPORT jboolean JNICALL Java_com_visioncamera_fastyuv_FastYuv_nativeNV21ToARGB(JNIEnv* env, jclass clazz,
12
- jbyteArray nv21Array,
13
- jint width, jint height,
14
- jbyteArray outArgbArray) {
15
- if (!nv21Array || !outArgbArray) return JNI_FALSE;
16
- jsize in_len = env->GetArrayLength(nv21Array);
17
- jsize out_len = env->GetArrayLength(outArgbArray);
18
- int expected_in = width * height + (width * height) / 2;
19
- int expected_out = width * height * 4;
20
- if (in_len < expected_in || out_len < expected_out) return JNI_FALSE;
21
-
22
- jbyte* in_bytes = env->GetByteArrayElements(nv21Array, nullptr);
23
- jbyte* out_bytes = env->GetByteArrayElements(outArgbArray, nullptr);
24
- bool ok = fastyuv::NV21ToARGB((const uint8_t*)in_bytes, width, height, (uint8_t*)out_bytes);
25
- env->ReleaseByteArrayElements(nv21Array, in_bytes, JNI_ABORT);
26
- env->ReleaseByteArrayElements(outArgbArray, out_bytes, 0);
27
- return ok ? JNI_TRUE : JNI_FALSE;
28
- }
29
-
30
- JNIEXPORT jboolean JNICALL Java_com_visioncamera_fastyuv_FastYuv_nativeNV21ToRGB(JNIEnv* env, jclass clazz,
31
- jbyteArray nv21Array,
32
- jint width, jint height,
33
- jbyteArray outRgbArray) {
34
- if (!nv21Array || !outRgbArray) return JNI_FALSE;
35
- jsize in_len = env->GetArrayLength(nv21Array);
36
- jsize out_len = env->GetArrayLength(outRgbArray);
37
- int expected_in = width * height + (width * height) / 2;
38
- int expected_out = width * height * 3;
39
- if (in_len < expected_in || out_len < expected_out) return JNI_FALSE;
40
-
41
- jbyte* in_bytes = env->GetByteArrayElements(nv21Array, nullptr);
42
- jbyte* out_bytes = env->GetByteArrayElements(outRgbArray, nullptr);
43
- bool ok = fastyuv::NV21ToRGB24((const uint8_t*)in_bytes, width, height, (uint8_t*)out_bytes);
44
- env->ReleaseByteArrayElements(nv21Array, in_bytes, JNI_ABORT);
45
- env->ReleaseByteArrayElements(outRgbArray, out_bytes, 0);
46
- return ok ? JNI_TRUE : JNI_FALSE;
47
- }
48
-
49
- JNIEXPORT jboolean JNICALL Java_com_visioncamera_fastyuv_FastYuv_nativeNV21ToBGR(JNIEnv* env, jclass clazz,
50
- jbyteArray nv21Array,
51
- jint width, jint height,
52
- jbyteArray outBgrArray) {
53
- if (!nv21Array || !outBgrArray) return JNI_FALSE;
54
- jsize in_len = env->GetArrayLength(nv21Array);
55
- jsize out_len = env->GetArrayLength(outBgrArray);
56
- int expected_in = width * height + (width * height) / 2;
57
- int expected_out = width * height * 3;
58
- if (in_len < expected_in || out_len < expected_out) return JNI_FALSE;
59
-
60
- jbyte* in_bytes = env->GetByteArrayElements(nv21Array, nullptr);
61
- jbyte* out_bytes = env->GetByteArrayElements(outBgrArray, nullptr);
62
- bool ok = fastyuv::NV21ToBGR24((const uint8_t*)in_bytes, width, height, (uint8_t*)out_bytes);
63
- env->ReleaseByteArrayElements(nv21Array, in_bytes, JNI_ABORT);
64
- env->ReleaseByteArrayElements(outBgrArray, out_bytes, 0);
65
- return ok ? JNI_TRUE : JNI_FALSE;
66
- }
67
-
68
- JNIEXPORT jboolean JNICALL Java_com_visioncamera_fastyuv_FastYuv_nativeNV21ToARGBResize(JNIEnv* env, jclass clazz,
69
- jbyteArray nv21Array,
70
- jint src_w, jint src_h,
71
- jbyteArray outArgbArray,
72
- jint dst_w, jint dst_h) {
73
- if (!nv21Array || !outArgbArray) return JNI_FALSE;
74
- jsize in_len = env->GetArrayLength(nv21Array);
75
- jsize out_len = env->GetArrayLength(outArgbArray);
76
- int expected_in = src_w * src_h + (src_w * src_h) / 2;
77
- int expected_out = dst_w * dst_h * 4;
78
- if (in_len < expected_in || out_len < expected_out) return JNI_FALSE;
79
-
80
- jbyte* in_bytes = env->GetByteArrayElements(nv21Array, nullptr);
81
- jbyte* out_bytes = env->GetByteArrayElements(outArgbArray, nullptr);
82
- bool ok = fastyuv::NV21ToARGBResize((const uint8_t*)in_bytes, src_w, src_h, (uint8_t*)out_bytes, dst_w, dst_h);
83
- env->ReleaseByteArrayElements(nv21Array, in_bytes, JNI_ABORT);
84
- env->ReleaseByteArrayElements(outArgbArray, out_bytes, 0);
85
- return ok ? JNI_TRUE : JNI_FALSE;
86
- }
87
-
88
- JNIEXPORT jboolean JNICALL Java_com_visioncamera_fastyuv_FastYuv_nativeNV21ToARGBRotate(JNIEnv* env, jclass clazz,
89
- jbyteArray nv21Array,
90
- jint src_w, jint src_h,
91
- jbyteArray outArgbArray,
92
- jint rotation) {
93
- if (!nv21Array || !outArgbArray) return JNI_FALSE;
94
- jsize in_len = env->GetArrayLength(nv21Array);
95
- jsize out_len = env->GetArrayLength(outArgbArray);
96
- int expected_in = src_w * src_h + (src_w * src_h) / 2;
97
- // rotation may swap dims; allocate expected_out conservatively using max dims
98
- int dst_w = (rotation % 180 == 0) ? src_w : src_h;
99
- int dst_h = (rotation % 180 == 0) ? src_h : src_w;
100
- int expected_out = dst_w * dst_h * 4;
101
- if (in_len < expected_in || out_len < expected_out) return JNI_FALSE;
102
-
103
- jbyte* in_bytes = env->GetByteArrayElements(nv21Array, nullptr);
104
- jbyte* out_bytes = env->GetByteArrayElements(outArgbArray, nullptr);
105
- bool ok = fastyuv::NV21ToARGBRotate((const uint8_t*)in_bytes, src_w, src_h, (uint8_t*)out_bytes, rotation);
106
- env->ReleaseByteArrayElements(nv21Array, in_bytes, JNI_ABORT);
107
- env->ReleaseByteArrayElements(outArgbArray, out_bytes, 0);
108
- return ok ? JNI_TRUE : JNI_FALSE;
109
- }
110
-
111
- } // extern "C"