ilabs-flir 2.3.3 → 2.3.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.
|
@@ -85,8 +85,18 @@ object FlirManager {
|
|
|
85
85
|
}
|
|
86
86
|
fun getAvailablePalettes(): List<String> {
|
|
87
87
|
return try {
|
|
88
|
-
PaletteManager.getDefaultPalettes().map { it.name }
|
|
89
|
-
|
|
88
|
+
val palettes = PaletteManager.getDefaultPalettes().map { it.name }.toMutableList()
|
|
89
|
+
// Move WhiteHot/Gray to the front
|
|
90
|
+
val grayIdx = palettes.indexOfFirst {
|
|
91
|
+
it.equals("WhiteHot", ignoreCase = true) || it.equals("Gray", ignoreCase = true) || it.contains("gray", ignoreCase = true)
|
|
92
|
+
}
|
|
93
|
+
if (grayIdx > 0) {
|
|
94
|
+
val gray = palettes.removeAt(grayIdx)
|
|
95
|
+
palettes.add(0, gray)
|
|
96
|
+
}
|
|
97
|
+
palettes
|
|
98
|
+
} catch (t: Throwable) {
|
|
99
|
+
Log.e(TAG, "Failed to get available palettes from SDK", t)
|
|
90
100
|
listOf("grayscale", "iron", "rainbow", "arctic", "lava", "contrast", "hotcold", "medical")
|
|
91
101
|
}
|
|
92
102
|
}
|
|
@@ -453,20 +463,34 @@ object FlirManager {
|
|
|
453
463
|
Log.d(TAG, "Updated Var.cool to $shaderIdx via reflection (raw=$rawIdx)")
|
|
454
464
|
|
|
455
465
|
// If we are in FLIR mode, also notify the SDK palette using the official SDK palette list
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
466
|
+
var sdkPalettes: List<Palette>? = null
|
|
467
|
+
try {
|
|
468
|
+
sdkPalettes = PaletteManager.getDefaultPalettes()
|
|
469
|
+
} catch (t: Throwable) {
|
|
470
|
+
try {
|
|
471
|
+
val altClazz = Class.forName("com.flir.thermalsdk.image.palettes.PaletteManager")
|
|
472
|
+
val method = altClazz.getMethod("getDefaultPalettes")
|
|
473
|
+
sdkPalettes = method.invoke(null) as? List<Palette>
|
|
474
|
+
} catch (t2: Throwable) {
|
|
475
|
+
Log.w(TAG, "Palette discovery failed in updateAcol", t2)
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (sdkPalettes != null) {
|
|
480
|
+
val paletteNames = sdkPalettes.map { it.name }
|
|
481
|
+
Log.d(TAG, "True FLIR Palettes: $paletteNames")
|
|
482
|
+
|
|
483
|
+
val maxEff = sdkPalettes.size
|
|
484
|
+
val paletteIdx = rawIdx % maxEff
|
|
485
|
+
val safeIdx = if (paletteIdx < 0) paletteIdx + maxEff else paletteIdx
|
|
486
|
+
|
|
487
|
+
val targetPaletteName = paletteNames[safeIdx]
|
|
488
|
+
Log.d(TAG, "Applying true FLIR palette: $targetPaletteName (index: $safeIdx, max: $maxEff)")
|
|
489
|
+
|
|
490
|
+
sdkManager?.setPalette(targetPaletteName)
|
|
491
|
+
}
|
|
468
492
|
|
|
469
|
-
} catch (e:
|
|
493
|
+
} catch (e: Throwable) {
|
|
470
494
|
Log.w(TAG, "Could not update Var.cool via reflection: ${e.message}")
|
|
471
495
|
}
|
|
472
496
|
}
|
|
@@ -477,7 +501,36 @@ object FlirManager {
|
|
|
477
501
|
fun generatePaletteIcons(context: Context): List<Map<String, String>> {
|
|
478
502
|
val results = mutableListOf<Map<String, String>>()
|
|
479
503
|
try {
|
|
480
|
-
|
|
504
|
+
var rawPalettes: List<Palette>? = null
|
|
505
|
+
try {
|
|
506
|
+
rawPalettes = PaletteManager.getDefaultPalettes()
|
|
507
|
+
} catch (t: Throwable) {
|
|
508
|
+
Log.e(TAG, "PaletteManager.getDefaultPalettes() failed in icon generation", t)
|
|
509
|
+
try {
|
|
510
|
+
val altClazz = Class.forName("com.flir.thermalsdk.image.palettes.PaletteManager")
|
|
511
|
+
val method = altClazz.getMethod("getDefaultPalettes")
|
|
512
|
+
rawPalettes = method.invoke(null) as? List<Palette>
|
|
513
|
+
} catch (t2: Throwable) {
|
|
514
|
+
Log.e(TAG, "Alternative package search also failed in icon generation", t2)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (rawPalettes == null) {
|
|
519
|
+
Log.e(TAG, "Failed to retrieve any palettes from SDK")
|
|
520
|
+
return emptyList()
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
val palettes = rawPalettes.toMutableList()
|
|
524
|
+
|
|
525
|
+
// Reorder: Move WhiteHot/Gray to the front
|
|
526
|
+
val grayIdx = palettes.indexOfFirst {
|
|
527
|
+
it.name.equals("WhiteHot", ignoreCase = true) || it.name.equals("Gray", ignoreCase = true) || it.name.contains("gray", ignoreCase = true)
|
|
528
|
+
}
|
|
529
|
+
if (grayIdx > 0) {
|
|
530
|
+
val gray = palettes.removeAt(grayIdx)
|
|
531
|
+
palettes.add(0, gray)
|
|
532
|
+
}
|
|
533
|
+
|
|
481
534
|
val dir = File(context.cacheDir, "flir_palettes")
|
|
482
535
|
if (!dir.exists()) dir.mkdirs()
|
|
483
536
|
|
|
@@ -510,8 +563,8 @@ object FlirManager {
|
|
|
510
563
|
"uri" to if (iconFile.exists()) "file://${iconFile.absolutePath}" else ""
|
|
511
564
|
))
|
|
512
565
|
}
|
|
513
|
-
} catch (
|
|
514
|
-
Log.e(TAG, "Palette icon generation error",
|
|
566
|
+
} catch (t: Throwable) {
|
|
567
|
+
Log.e(TAG, "Palette icon generation error", t)
|
|
515
568
|
}
|
|
516
569
|
return results
|
|
517
570
|
}
|
|
@@ -144,7 +144,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
144
144
|
val result = com.facebook.react.bridge.Arguments.createArray()
|
|
145
145
|
palettes.forEach { result.pushString(it) }
|
|
146
146
|
promise?.resolve(result)
|
|
147
|
-
} catch (e:
|
|
147
|
+
} catch (e: Throwable) {
|
|
148
148
|
promise?.reject("ERR_FLIR_PALETTES", e)
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -162,7 +162,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
162
162
|
result.pushMap(map)
|
|
163
163
|
}
|
|
164
164
|
promise?.resolve(result)
|
|
165
|
-
} catch (e:
|
|
165
|
+
} catch (e: Throwable) {
|
|
166
166
|
promise?.reject("ERR_FLIR_PALETTE_ICONS", e)
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -306,7 +306,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
306
306
|
try {
|
|
307
307
|
FlirManager.updateAcol(value)
|
|
308
308
|
promise?.resolve(true)
|
|
309
|
-
} catch (e:
|
|
309
|
+
} catch (e: Throwable) {
|
|
310
310
|
promise?.reject("ERR_FLIR_ACOL", e)
|
|
311
311
|
}
|
|
312
312
|
}
|
|
@@ -318,7 +318,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
318
318
|
FlirManager.setPalette(name)
|
|
319
319
|
}
|
|
320
320
|
promise?.resolve(true)
|
|
321
|
-
} catch (e:
|
|
321
|
+
} catch (e: Throwable) {
|
|
322
322
|
promise?.reject("ERR_FLIR_PALETTE", e)
|
|
323
323
|
}
|
|
324
324
|
}
|
|
@@ -51,7 +51,7 @@ public class FlirSdkManager {
|
|
|
51
51
|
private Stream activeStream;
|
|
52
52
|
private final List<Identity> discoveredDevices = Collections.synchronizedList(new ArrayList<>());
|
|
53
53
|
private volatile Bitmap latestBitmap;
|
|
54
|
-
private volatile String currentPaletteName = "
|
|
54
|
+
private volatile String currentPaletteName = "WhiteHot";
|
|
55
55
|
private final AtomicBoolean isProcessingFrame = new AtomicBoolean(false);
|
|
56
56
|
private boolean useHalfScale = false;
|
|
57
57
|
private String pendingSnapshotPath = null;
|
|
@@ -101,8 +101,25 @@ public class FlirSdkManager {
|
|
|
101
101
|
if (isInitialized)
|
|
102
102
|
return;
|
|
103
103
|
try {
|
|
104
|
+
try {
|
|
105
|
+
// Explicitly load the native library to ensure JNI methods are linked
|
|
106
|
+
try {
|
|
107
|
+
System.loadLibrary("atlas_native");
|
|
108
|
+
Log.i(TAG, "Successfully loaded atlas_native library manually");
|
|
109
|
+
} catch (UnsatisfiedLinkError e) {
|
|
110
|
+
Log.w(TAG, "System.loadLibrary(atlas_native) failed (might be loaded by SDK): " + e.getMessage());
|
|
111
|
+
}
|
|
112
|
+
|
|
104
113
|
ThermalSdkAndroid.init(context);
|
|
114
|
+
|
|
115
|
+
// Small delay to ensure JNI linkage is stable
|
|
116
|
+
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
|
|
117
|
+
|
|
105
118
|
isInitialized = true;
|
|
119
|
+
Log.i(TAG, "FLIR SDK initialized successfully. Arch: " + System.getProperty("os.arch"));
|
|
120
|
+
} catch (Throwable e) {
|
|
121
|
+
Log.e(TAG, "Critical failure during FLIR SDK initialization", e);
|
|
122
|
+
}
|
|
106
123
|
Log.d(TAG, "SDK initialized");
|
|
107
124
|
} catch (Exception e) {
|
|
108
125
|
Log.e(TAG, "SDK init failed", e);
|
|
@@ -356,13 +373,39 @@ public class FlirSdkManager {
|
|
|
356
373
|
streamer.withThermalImage(thermalImage -> {
|
|
357
374
|
// 1. Apply Palette
|
|
358
375
|
if (paletteToApply != null) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
376
|
+
try {
|
|
377
|
+
Palette palette = null;
|
|
378
|
+
// 1. Try to get default palettes list safely
|
|
379
|
+
List<Palette> sdkPalettes = null;
|
|
380
|
+
try {
|
|
381
|
+
sdkPalettes = PaletteManager.getDefaultPalettes();
|
|
382
|
+
} catch (Throwable t) {
|
|
383
|
+
Log.e(TAG, "PaletteManager.getDefaultPalettes() failed (Linkage Error?)", t);
|
|
384
|
+
// Fallback: Try to use reflection for alternative package if suggested
|
|
385
|
+
try {
|
|
386
|
+
Class<?> altClazz = Class.forName("com.flir.thermalsdk.image.palettes.PaletteManager");
|
|
387
|
+
java.lang.reflect.Method method = altClazz.getMethod("getDefaultPalettes");
|
|
388
|
+
sdkPalettes = (List<Palette>) method.invoke(null);
|
|
389
|
+
Log.i(TAG, "Successfully retrieved palettes using alternative package");
|
|
390
|
+
} catch (Throwable t2) {
|
|
391
|
+
Log.e(TAG, "Alternative PaletteManager search also failed", t2);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (sdkPalettes != null) {
|
|
396
|
+
for (Palette p : sdkPalettes) {
|
|
397
|
+
if (p.name.equalsIgnoreCase(paletteToApply)) {
|
|
398
|
+
palette = p;
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (palette != null) {
|
|
405
|
+
thermalImage.setPalette(palette);
|
|
406
|
+
}
|
|
407
|
+
} catch (Throwable t) {
|
|
408
|
+
Log.e(TAG, "Failed to apply palette: " + paletteToApply, t);
|
|
366
409
|
}
|
|
367
410
|
}
|
|
368
411
|
|
|
@@ -67,7 +67,7 @@ import ThermalSDK
|
|
|
67
67
|
private let stateLock = NSObject()
|
|
68
68
|
|
|
69
69
|
// Palette and Snapshot state
|
|
70
|
-
private var currentPaletteName: String = "
|
|
70
|
+
private var currentPaletteName: String = "WhiteHot"
|
|
71
71
|
private var pendingSnapshotPath: String?
|
|
72
72
|
|
|
73
73
|
// Dedicated render queue for frame processing (matches sample app pattern)
|
|
@@ -530,22 +530,21 @@ import ThermalSDK
|
|
|
530
530
|
|
|
531
531
|
@objc public func getAvailablePalettes() -> [String] {
|
|
532
532
|
#if FLIR_ENABLED
|
|
533
|
-
// We use a dummy thermal image to access palette manager if no streamer exists,
|
|
534
|
-
// but typically PaletteManager.getDefaultPalettes() might be static or available via streamer
|
|
535
533
|
if let streamer = streamer {
|
|
536
534
|
var names: [String] = []
|
|
537
535
|
streamer.withThermalImage { img in
|
|
538
|
-
|
|
536
|
+
var palettes = img.paletteManager.getDefaultPalettes().map { $0.name }
|
|
537
|
+
// Reorder: Move WhiteHot/Gray to the front
|
|
538
|
+
if let grayIdx = palettes.firstIndex(where: { $0.lowercased() == "whitehot" || $0.lowercased() == "gray" }) {
|
|
539
|
+
let gray = palettes.remove(at: grayIdx)
|
|
540
|
+
palettes.insert(gray, at: 0)
|
|
541
|
+
}
|
|
542
|
+
names = palettes
|
|
539
543
|
}
|
|
540
544
|
if !names.isEmpty { return names }
|
|
541
545
|
}
|
|
542
|
-
|
|
543
|
-
// Fallback: Try to get from a temporary thermal image if possible,
|
|
544
|
-
// but FLIR SDK often requires a valid image.
|
|
545
|
-
// For now, return a standard list if we can't get it dynamically,
|
|
546
|
-
// or try to find a static way.
|
|
547
546
|
#endif
|
|
548
|
-
return ["
|
|
547
|
+
return ["WhiteHot", "iron", "rainbow", "arctic", "lava", "contrast", "hotcold", "medical"]
|
|
549
548
|
}
|
|
550
549
|
|
|
551
550
|
@objc public func generatePaletteIcons() -> [[String: String]] {
|
|
@@ -562,7 +561,14 @@ import ThermalSDK
|
|
|
562
561
|
}
|
|
563
562
|
|
|
564
563
|
streamer.withThermalImage { thermalImage in
|
|
565
|
-
|
|
564
|
+
var palettes = thermalImage.paletteManager.getDefaultPalettes()
|
|
565
|
+
|
|
566
|
+
// Reorder: Move WhiteHot/Gray to the front
|
|
567
|
+
if let grayIdx = palettes.firstIndex(where: { $0.name.lowercased() == "whitehot" || $0.name.lowercased() == "gray" }) {
|
|
568
|
+
let gray = palettes.remove(at: grayIdx)
|
|
569
|
+
palettes.insert(gray, at: 0)
|
|
570
|
+
}
|
|
571
|
+
|
|
566
572
|
for palette in palettes {
|
|
567
573
|
let iconURL = paletteDir.appendingPathComponent("\(palette.name.lowercased()).png")
|
|
568
574
|
if !fileManager.fileExists(atPath: iconURL.path) {
|