ilabs-flir 2.0.4 → 2.0.5

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 (35) hide show
  1. package/Flir.podspec +139 -139
  2. package/README.md +1066 -1066
  3. package/android/Flir/build.gradle.kts +72 -72
  4. package/android/Flir/src/main/AndroidManifest.xml +45 -45
  5. package/android/Flir/src/main/java/flir/android/FlirCommands.java +136 -136
  6. package/android/Flir/src/main/java/flir/android/FlirFrameCache.kt +6 -6
  7. package/android/Flir/src/main/java/flir/android/FlirManager.kt +476 -476
  8. package/android/Flir/src/main/java/flir/android/FlirModule.kt +257 -257
  9. package/android/Flir/src/main/java/flir/android/FlirPackage.kt +18 -18
  10. package/android/Flir/src/main/java/flir/android/FlirSDKLoader.kt +74 -74
  11. package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +583 -583
  12. package/android/Flir/src/main/java/flir/android/FlirStatus.kt +12 -12
  13. package/android/Flir/src/main/java/flir/android/FlirView.kt +48 -48
  14. package/android/Flir/src/main/java/flir/android/FlirViewManager.kt +13 -13
  15. package/app.plugin.js +381 -381
  16. package/expo-module.config.json +5 -5
  17. package/ios/Flir/src/Flir-Bridging-Header.h +34 -34
  18. package/ios/Flir/src/FlirEventEmitter.h +25 -25
  19. package/ios/Flir/src/FlirEventEmitter.m +63 -63
  20. package/ios/Flir/src/FlirManager.swift +599 -599
  21. package/ios/Flir/src/FlirModule.h +17 -17
  22. package/ios/Flir/src/FlirModule.m +713 -713
  23. package/ios/Flir/src/FlirPreviewView.h +13 -13
  24. package/ios/Flir/src/FlirPreviewView.m +171 -171
  25. package/ios/Flir/src/FlirState.h +68 -68
  26. package/ios/Flir/src/FlirState.m +135 -135
  27. package/ios/Flir/src/FlirViewManager.h +16 -16
  28. package/ios/Flir/src/FlirViewManager.m +27 -27
  29. package/package.json +72 -71
  30. package/react-native.config.js +14 -14
  31. package/scripts/fetch-binaries.js +47 -5
  32. package/sdk-manifest.json +50 -50
  33. package/src/index.d.ts +63 -63
  34. package/src/index.js +7 -7
  35. package/src/index.ts +6 -6
@@ -1,135 +1,135 @@
1
- //
2
- // FlirState.m
3
- // Flir
4
- //
5
- // Shared state singleton for FLIR frame and temperature data
6
- //
7
-
8
- #import "FlirState.h"
9
-
10
- static FlirState *_sharedState = nil;
11
-
12
- @implementation FlirState {
13
- NSArray<NSNumber *> *_temperatureData;
14
- int _imageWidth;
15
- int _imageHeight;
16
- dispatch_queue_t _accessQueue;
17
- }
18
-
19
- + (instancetype)shared {
20
- static dispatch_once_t onceToken;
21
- dispatch_once(&onceToken, ^{
22
- _sharedState = [[FlirState alloc] init];
23
- });
24
- return _sharedState;
25
- }
26
-
27
- - (instancetype)init {
28
- if (self = [super init]) {
29
- _lastTemperature = NAN;
30
- _latestImage = nil;
31
- _temperatureData = nil;
32
- _imageWidth = 0;
33
- _imageHeight = 0;
34
- _accessQueue =
35
- dispatch_queue_create("com.flir.state.access", DISPATCH_QUEUE_SERIAL);
36
- }
37
- return self;
38
- }
39
-
40
- - (int)imageWidth {
41
- return _imageWidth;
42
- }
43
-
44
- - (int)imageHeight {
45
- return _imageHeight;
46
- }
47
-
48
- - (double)getTemperatureAt:(int)x y:(int)y {
49
- // First try the temperature data array if available
50
- double t = [self queryTemperatureAtPoint:x y:y];
51
- if (!isnan(t)) {
52
- return t;
53
- }
54
- // Fall back to last sampled temperature
55
- return self.lastTemperature;
56
- }
57
-
58
- - (double)queryTemperatureAtPoint:(int)x y:(int)y {
59
- __block double result = NAN;
60
-
61
- dispatch_sync(_accessQueue, ^{
62
- if (_temperatureData == nil || _imageWidth == 0 || _imageHeight == 0) {
63
- return;
64
- }
65
-
66
- // Bounds check
67
- if (x < 0 || x >= _imageWidth || y < 0 || y >= _imageHeight) {
68
- return;
69
- }
70
-
71
- // Access flattened array: index = y * width + x
72
- NSInteger index = y * _imageWidth + x;
73
- if (index < 0 || index >= (NSInteger)[_temperatureData count]) {
74
- return;
75
- }
76
-
77
- result = [_temperatureData[index] doubleValue];
78
- });
79
-
80
- return result;
81
- }
82
-
83
- - (void)updateFrame:(UIImage *)image {
84
- [self updateFrame:image withTemperatureData:nil];
85
- }
86
-
87
- - (void)updateFrame:(UIImage *)image
88
- withTemperatureData:(NSArray<NSNumber *> *)tempData {
89
- if (!image)
90
- return;
91
-
92
- dispatch_async(_accessQueue, ^{
93
- self.latestImage = image;
94
-
95
- if (tempData != nil) {
96
- self->_temperatureData = [tempData copy];
97
- self->_imageWidth = (int)image.size.width;
98
- self->_imageHeight = (int)image.size.height;
99
- }
100
- });
101
-
102
- // Invoke texture callback on main thread (for Metal filters, texture unit 7)
103
- if (self.onTextureUpdate) {
104
- dispatch_async(dispatch_get_main_queue(), ^{
105
- if (self.onTextureUpdate) {
106
- self.onTextureUpdate(image, 7);
107
- }
108
- });
109
- }
110
-
111
- // Sample temperature at center point and invoke callback
112
- if (self.onTemperatureUpdate) {
113
- int centerX = (int)(image.size.width / 2);
114
- int centerY = (int)(image.size.height / 2);
115
- double temp = [self getTemperatureAt:centerX y:centerY];
116
-
117
- dispatch_async(dispatch_get_main_queue(), ^{
118
- if (self.onTemperatureUpdate) {
119
- self.onTemperatureUpdate(temp, centerX, centerY);
120
- }
121
- });
122
- }
123
- }
124
-
125
- - (void)reset {
126
- dispatch_async(_accessQueue, ^{
127
- self.latestImage = nil;
128
- self.lastTemperature = NAN;
129
- self->_temperatureData = nil;
130
- self->_imageWidth = 0;
131
- self->_imageHeight = 0;
132
- });
133
- }
134
-
135
- @end
1
+ //
2
+ // FlirState.m
3
+ // Flir
4
+ //
5
+ // Shared state singleton for FLIR frame and temperature data
6
+ //
7
+
8
+ #import "FlirState.h"
9
+
10
+ static FlirState *_sharedState = nil;
11
+
12
+ @implementation FlirState {
13
+ NSArray<NSNumber *> *_temperatureData;
14
+ int _imageWidth;
15
+ int _imageHeight;
16
+ dispatch_queue_t _accessQueue;
17
+ }
18
+
19
+ + (instancetype)shared {
20
+ static dispatch_once_t onceToken;
21
+ dispatch_once(&onceToken, ^{
22
+ _sharedState = [[FlirState alloc] init];
23
+ });
24
+ return _sharedState;
25
+ }
26
+
27
+ - (instancetype)init {
28
+ if (self = [super init]) {
29
+ _lastTemperature = NAN;
30
+ _latestImage = nil;
31
+ _temperatureData = nil;
32
+ _imageWidth = 0;
33
+ _imageHeight = 0;
34
+ _accessQueue =
35
+ dispatch_queue_create("com.flir.state.access", DISPATCH_QUEUE_SERIAL);
36
+ }
37
+ return self;
38
+ }
39
+
40
+ - (int)imageWidth {
41
+ return _imageWidth;
42
+ }
43
+
44
+ - (int)imageHeight {
45
+ return _imageHeight;
46
+ }
47
+
48
+ - (double)getTemperatureAt:(int)x y:(int)y {
49
+ // First try the temperature data array if available
50
+ double t = [self queryTemperatureAtPoint:x y:y];
51
+ if (!isnan(t)) {
52
+ return t;
53
+ }
54
+ // Fall back to last sampled temperature
55
+ return self.lastTemperature;
56
+ }
57
+
58
+ - (double)queryTemperatureAtPoint:(int)x y:(int)y {
59
+ __block double result = NAN;
60
+
61
+ dispatch_sync(_accessQueue, ^{
62
+ if (_temperatureData == nil || _imageWidth == 0 || _imageHeight == 0) {
63
+ return;
64
+ }
65
+
66
+ // Bounds check
67
+ if (x < 0 || x >= _imageWidth || y < 0 || y >= _imageHeight) {
68
+ return;
69
+ }
70
+
71
+ // Access flattened array: index = y * width + x
72
+ NSInteger index = y * _imageWidth + x;
73
+ if (index < 0 || index >= (NSInteger)[_temperatureData count]) {
74
+ return;
75
+ }
76
+
77
+ result = [_temperatureData[index] doubleValue];
78
+ });
79
+
80
+ return result;
81
+ }
82
+
83
+ - (void)updateFrame:(UIImage *)image {
84
+ [self updateFrame:image withTemperatureData:nil];
85
+ }
86
+
87
+ - (void)updateFrame:(UIImage *)image
88
+ withTemperatureData:(NSArray<NSNumber *> *)tempData {
89
+ if (!image)
90
+ return;
91
+
92
+ dispatch_async(_accessQueue, ^{
93
+ self.latestImage = image;
94
+
95
+ if (tempData != nil) {
96
+ self->_temperatureData = [tempData copy];
97
+ self->_imageWidth = (int)image.size.width;
98
+ self->_imageHeight = (int)image.size.height;
99
+ }
100
+ });
101
+
102
+ // Invoke texture callback on main thread (for Metal filters, texture unit 7)
103
+ if (self.onTextureUpdate) {
104
+ dispatch_async(dispatch_get_main_queue(), ^{
105
+ if (self.onTextureUpdate) {
106
+ self.onTextureUpdate(image, 7);
107
+ }
108
+ });
109
+ }
110
+
111
+ // Sample temperature at center point and invoke callback
112
+ if (self.onTemperatureUpdate) {
113
+ int centerX = (int)(image.size.width / 2);
114
+ int centerY = (int)(image.size.height / 2);
115
+ double temp = [self getTemperatureAt:centerX y:centerY];
116
+
117
+ dispatch_async(dispatch_get_main_queue(), ^{
118
+ if (self.onTemperatureUpdate) {
119
+ self.onTemperatureUpdate(temp, centerX, centerY);
120
+ }
121
+ });
122
+ }
123
+ }
124
+
125
+ - (void)reset {
126
+ dispatch_async(_accessQueue, ^{
127
+ self.latestImage = nil;
128
+ self.lastTemperature = NAN;
129
+ self->_temperatureData = nil;
130
+ self->_imageWidth = 0;
131
+ self->_imageHeight = 0;
132
+ });
133
+ }
134
+
135
+ @end
@@ -1,16 +1,16 @@
1
- //
2
- // FlirViewManager.h
3
- // Flir
4
- //
5
- // React Native view manager for FLIR preview
6
- //
7
-
8
- #import <React/RCTViewManager.h>
9
-
10
- NS_ASSUME_NONNULL_BEGIN
11
-
12
- @interface FlirViewManager : RCTViewManager
13
-
14
- @end
15
-
16
- NS_ASSUME_NONNULL_END
1
+ //
2
+ // FlirViewManager.h
3
+ // Flir
4
+ //
5
+ // React Native view manager for FLIR preview
6
+ //
7
+
8
+ #import <React/RCTViewManager.h>
9
+
10
+ NS_ASSUME_NONNULL_BEGIN
11
+
12
+ @interface FlirViewManager : RCTViewManager
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -1,27 +1,27 @@
1
- //
2
- // FlirViewManager.m
3
- // Flir
4
- //
5
- // React Native view manager for FLIR preview
6
- //
7
-
8
- #import "FlirViewManager.h"
9
- #import "FlirPreviewView.h"
10
- #import <React/RCTUIManager.h>
11
-
12
- @implementation FlirViewManager
13
-
14
- RCT_EXPORT_MODULE(FlirPreviewView)
15
-
16
- + (BOOL)requiresMainQueueSetup {
17
- return YES;
18
- }
19
-
20
- - (UIView *)view {
21
- return [[FlirPreviewView alloc] init];
22
- }
23
-
24
- RCT_EXPORT_VIEW_PROPERTY(showTemperature, BOOL)
25
- RCT_EXPORT_VIEW_PROPERTY(showFallback, BOOL)
26
-
27
- @end
1
+ //
2
+ // FlirViewManager.m
3
+ // Flir
4
+ //
5
+ // React Native view manager for FLIR preview
6
+ //
7
+
8
+ #import "FlirViewManager.h"
9
+ #import "FlirPreviewView.h"
10
+ #import <React/RCTUIManager.h>
11
+
12
+ @implementation FlirViewManager
13
+
14
+ RCT_EXPORT_MODULE(FlirPreviewView)
15
+
16
+ + (BOOL)requiresMainQueueSetup {
17
+ return YES;
18
+ }
19
+
20
+ - (UIView *)view {
21
+ return [[FlirPreviewView alloc] init];
22
+ }
23
+
24
+ RCT_EXPORT_VIEW_PROPERTY(showTemperature, BOOL)
25
+ RCT_EXPORT_VIEW_PROPERTY(showFallback, BOOL)
26
+
27
+ @end
package/package.json CHANGED
@@ -1,72 +1,73 @@
1
- {
2
- "name": "ilabs-flir",
3
- "version": "2.0.4",
4
- "description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
5
- "main": "src/index.js",
6
- "types": "src/index.d.ts",
7
- "scripts": {
8
- "postinstall": "node scripts/fetch-binaries.js",
9
- "fetch-binaries": "node scripts/fetch-binaries.js",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "files": [
13
- "src/",
14
- "android/Flir/src/",
15
- "android/Flir/build.gradle.kts",
16
- "android/Flir/libs/",
17
- "ios/Flir/src/",
18
- "ios/Flir/SDKLoader/",
19
- "ios/Flir/Framework/",
20
- "ios/Flir/Frameworks/",
21
- "app.plugin.js",
22
- "Flir.podspec",
23
- "sdk-manifest.json",
24
- "scripts/",
25
- "expo-module.config.json",
26
- "react-native.config.js"
27
- ],
28
- "keywords": [
29
- "flir",
30
- "thermal",
31
- "thermal-camera",
32
- "react-native",
33
- "expo",
34
- "expo-plugin",
35
- "config-plugin",
36
- "flir-one",
37
- "thermal-imaging",
38
- "infrared",
39
- "ios",
40
- "android"
41
- ],
42
- "repository": {
43
- "type": "git",
44
- "url": "https://github.com/PraveenOjha/flir.git"
45
- },
46
- "homepage": "https://github.com/PraveenOjha/flir#readme",
47
- "bugs": {
48
- "url": "https://github.com/PraveenOjha/flir/issues"
49
- },
50
- "author": "Praveen Ojha",
51
- "license": "MIT",
52
- "peerDependencies": {
53
- "react": "*",
54
- "react-native": ">=0.60.0"
55
- },
56
- "dependencies": {
57
- "@expo/config-plugins": "^7.0.0"
58
- },
59
- "devDependencies": {
60
- "typescript": "^5.0.0",
61
- "@types/react": "*",
62
- "@types/react-native": "*"
63
- },
64
- "react-native": {
65
- "ios": {
66
- "podspec": "./Flir.podspec"
67
- },
68
- "android": {
69
- "sourceDir": "./android/Flir"
70
- }
71
- }
1
+ {
2
+ "name": "ilabs-flir",
3
+ "version": "2.0.5",
4
+ "description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
5
+ "main": "src/index.js",
6
+ "types": "src/index.d.ts",
7
+ "scripts": {
8
+ "postinstall": "node scripts/fetch-binaries.js",
9
+ "fetch-binaries": "node scripts/fetch-binaries.js",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "files": [
13
+ "src/",
14
+ "android/Flir/src/",
15
+ "android/Flir/build.gradle.kts",
16
+ "android/Flir/libs/",
17
+ "ios/Flir/src/",
18
+ "ios/Flir/SDKLoader/",
19
+ "ios/Flir/Framework/",
20
+ "ios/Flir/Frameworks/",
21
+ "app.plugin.js",
22
+ "Flir.podspec",
23
+ "sdk-manifest.json",
24
+ "scripts/",
25
+ "expo-module.config.json",
26
+ "react-native.config.js"
27
+ ],
28
+ "keywords": [
29
+ "flir",
30
+ "thermal",
31
+ "thermal-camera",
32
+ "react-native",
33
+ "expo",
34
+ "expo-plugin",
35
+ "config-plugin",
36
+ "flir-one",
37
+ "thermal-imaging",
38
+ "infrared",
39
+ "ios",
40
+ "android"
41
+ ],
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/PraveenOjha/flir.git"
45
+ },
46
+ "homepage": "https://github.com/PraveenOjha/flir#readme",
47
+ "bugs": {
48
+ "url": "https://github.com/PraveenOjha/flir/issues"
49
+ },
50
+ "author": "Praveen Ojha",
51
+ "license": "MIT",
52
+ "peerDependencies": {
53
+ "react": "*",
54
+ "react-native": ">=0.60.0"
55
+ },
56
+ "dependencies": {
57
+ "@expo/config-plugins": "^7.0.0",
58
+ "adm-zip": "^0.5.10"
59
+ },
60
+ "devDependencies": {
61
+ "typescript": "^5.0.0",
62
+ "@types/react": "*",
63
+ "@types/react-native": "*"
64
+ },
65
+ "react-native": {
66
+ "ios": {
67
+ "podspec": "./Flir.podspec"
68
+ },
69
+ "android": {
70
+ "sourceDir": "./android/Flir"
71
+ }
72
+ }
72
73
  }
@@ -1,14 +1,14 @@
1
- module.exports = {
2
- dependency: {
3
- platforms: {
4
- android: {
5
- sourceDir: './android/Flir',
6
- packageImportPath: 'import flir.android.FlirPackage;',
7
- packageInstance: 'new FlirPackage()',
8
- },
9
- ios: {
10
- podspecPath: './Flir.podspec',
11
- },
12
- },
13
- },
14
- };
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ sourceDir: './android/Flir',
6
+ packageImportPath: 'import flir.android.FlirPackage;',
7
+ packageInstance: 'new FlirPackage()',
8
+ },
9
+ ios: {
10
+ podspecPath: './Flir.podspec',
11
+ },
12
+ },
13
+ },
14
+ };
@@ -69,12 +69,51 @@ function extractZip(zipPath, dest) {
69
69
  if (!fs.existsSync(dest)) {
70
70
  throw new Error(`Destination folder ${dest} does not exist. Please create it and re-run installation.`);
71
71
  }
72
- if (process.platform === 'win32') {
73
- // Use PowerShell Expand-Archive
74
- execSync(`powershell -NoProfile -Command "Expand-Archive -Force -LiteralPath '${zipPath}' -DestinationPath '${TMP_DIR}'"`, { stdio: 'inherit' });
75
- } else {
76
- execSync(`unzip -o '${zipPath}' -d '${TMP_DIR}'`, { stdio: 'inherit' });
72
+ // Preferred: use a pure-Node extractor (adm-zip) so the script is platform-independent.
73
+ try {
74
+ const AdmZip = require('adm-zip');
75
+ const zip = new AdmZip(zipPath);
76
+ zip.extractAllTo(TMP_DIR, true);
77
+ return;
78
+ } catch (e) {
79
+ // If adm-zip isn't available, fall back to system tools.
80
+ console.log('adm-zip not available, falling back to system extraction tools');
77
81
  }
82
+ // Next preference: system `unzip` (macOS, Linux, and many developer environments). If `unzip` is not available,
83
+ // try `tar -xf` (some platforms provide bsdtar which can extract zip files), otherwise fail with a helpful message.
84
+ const cmdExists = (cmd) => {
85
+ try {
86
+ if (process.platform === 'win32') {
87
+ execSync(`where ${cmd}`, { stdio: 'ignore' });
88
+ } else {
89
+ execSync(`which ${cmd}`, { stdio: 'ignore' });
90
+ }
91
+ return true;
92
+ } catch (_err) {
93
+ return false;
94
+ }
95
+ };
96
+
97
+ if (cmdExists('unzip')) {
98
+ try {
99
+ execSync(`unzip -o '${zipPath}' -d '${TMP_DIR}'`, { stdio: 'inherit' });
100
+ return;
101
+ } catch (err) {
102
+ throw new Error(`Failed to extract zip using 'unzip'. Consider installing 'unzip' or adding 'adm-zip' package. Original error: ${err.message}`);
103
+ }
104
+ }
105
+
106
+ // 'tar' can sometimes extract zip files (via bsdtar). Try it as a last resort.
107
+ if (cmdExists('tar')) {
108
+ try {
109
+ execSync(`tar -xf '${zipPath}' -C '${TMP_DIR}'`, { stdio: 'inherit' });
110
+ return;
111
+ } catch (err) {
112
+ throw new Error(`Failed to extract zip using 'tar'. Consider installing 'unzip' or add 'adm-zip' package. Original error: ${err.message}`);
113
+ }
114
+ }
115
+
116
+ throw new Error(`No extractor found: please install 'unzip' or add the 'adm-zip' dependency in your project so the fetch script can extract SDK binaries.`);
78
117
  }
79
118
 
80
119
  function copyIosExtractedFiles(tmpFolder, destFolder) {
@@ -193,6 +232,9 @@ async function run() {
193
232
  } catch (err) {
194
233
  console.error('Failed to fetch binaries:', err.message);
195
234
  process.exit(1);
235
+ } finally {
236
+ // Always attempt to remove temporary folder to avoid leaving cruft
237
+ try { fs.rmSync(TMP_DIR, { recursive: true, force: true }); } catch (e) {}
196
238
  }
197
239
  }
198
240