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
- } catch (e: Exception) {
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
- val sdkPalettes = PaletteManager.getDefaultPalettes()
457
- val paletteNames = sdkPalettes.map { it.name }
458
- Log.d(TAG, "True FLIR Palettes: $paletteNames")
459
-
460
- val maxEff = sdkPalettes.size
461
- val paletteIdx = rawIdx % maxEff
462
- val safeIdx = if (paletteIdx < 0) paletteIdx + maxEff else paletteIdx
463
-
464
- val targetPaletteName = paletteNames[safeIdx]
465
- Log.d(TAG, "Applying true FLIR palette: $targetPaletteName (index: $safeIdx, max: $maxEff)")
466
-
467
- sdkManager?.setPalette(targetPaletteName)
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: Exception) {
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
- val palettes = PaletteManager.getDefaultPalettes()
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 (e: Exception) {
514
- Log.e(TAG, "Palette icon generation error", e)
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: Exception) {
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: Exception) {
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: Exception) {
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: Exception) {
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 = "iron";
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
- Palette palette =
360
- PaletteManager.getDefaultPalettes().stream()
361
- .filter(p -> p.name.equalsIgnoreCase(paletteToApply))
362
- .findFirst()
363
- .orElse(null);
364
- if (palette != null) {
365
- thermalImage.setPalette(palette);
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 = "iron"
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
- names = img.paletteManager.getDefaultPalettes().map { $0.name }
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 ["iron", "rainbow", "grayscale", "arctic", "lava", "contrast", "hotcold", "medical"]
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
- let palettes = thermalImage.paletteManager.getDefaultPalettes()
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilabs-flir",
3
- "version": "2.3.3",
3
+ "version": "2.3.5",
4
4
  "description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",