Pārlūkot izejas kodu

Revert "Hello ducky (#1382)"

This reverts commit 271eb98ce5cdd9ec26c479607f8737d5cdd6694e, reversing
changes made to 7fadb7634d4b3b2a3dd8b615f345496b4f6b14cd.
Neeraj Gupta 1 gadu atpakaļ
vecāks
revīzija
a746206cae
98 mainītis faili ar 755 papildinājumiem un 711 dzēšanām
  1. 1 1
      android/app/src/main/AndroidManifest.xml
  2. BIN
      android/app/src/main/res/drawable-hdpi/android12splash.png
  3. BIN
      android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
  4. BIN
      android/app/src/main/res/drawable-hdpi/splash.png
  5. BIN
      android/app/src/main/res/drawable-mdpi/android12splash.png
  6. BIN
      android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
  7. BIN
      android/app/src/main/res/drawable-mdpi/splash.png
  8. BIN
      android/app/src/main/res/drawable-night-hdpi/android12splash.png
  9. BIN
      android/app/src/main/res/drawable-night-hdpi/splash.png
  10. BIN
      android/app/src/main/res/drawable-night-mdpi/android12splash.png
  11. BIN
      android/app/src/main/res/drawable-night-mdpi/splash.png
  12. BIN
      android/app/src/main/res/drawable-night-v21/background.png
  13. BIN
      android/app/src/main/res/drawable-night-xhdpi/android12splash.png
  14. BIN
      android/app/src/main/res/drawable-night-xhdpi/splash.png
  15. BIN
      android/app/src/main/res/drawable-night-xxhdpi/android12splash.png
  16. BIN
      android/app/src/main/res/drawable-night-xxhdpi/splash.png
  17. BIN
      android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png
  18. BIN
      android/app/src/main/res/drawable-night-xxxhdpi/splash.png
  19. BIN
      android/app/src/main/res/drawable-night/background.png
  20. BIN
      android/app/src/main/res/drawable-v21/background.png
  21. BIN
      android/app/src/main/res/drawable-xhdpi/android12splash.png
  22. BIN
      android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
  23. BIN
      android/app/src/main/res/drawable-xhdpi/splash.png
  24. BIN
      android/app/src/main/res/drawable-xxhdpi/android12splash.png
  25. BIN
      android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
  26. BIN
      android/app/src/main/res/drawable-xxhdpi/splash.png
  27. BIN
      android/app/src/main/res/drawable-xxxhdpi/android12splash.png
  28. BIN
      android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
  29. BIN
      android/app/src/main/res/drawable-xxxhdpi/splash.png
  30. BIN
      android/app/src/main/res/drawable/background.png
  31. 0 9
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  32. 1 0
      android/app/src/main/res/mipmap-anydpi-v26/launcher_icon.xml
  33. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  34. BIN
      android/app/src/main/res/mipmap-hdpi/launcher_icon.png
  35. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  36. BIN
      android/app/src/main/res/mipmap-mdpi/launcher_icon.png
  37. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  38. BIN
      android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
  39. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  40. BIN
      android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
  41. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  42. BIN
      android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
  43. 0 1
      android/app/src/main/res/values-night-v31/styles.xml
  44. 0 1
      android/app/src/main/res/values-night/styles.xml
  45. 0 1
      android/app/src/main/res/values-v31/styles.xml
  46. BIN
      assets/ente.png
  47. BIN
      assets/icon-light.png
  48. BIN
      assets/launcher_icon/adaptive_icon.png
  49. BIN
      assets/launcher_icon/ente-icon-foreground.png
  50. BIN
      assets/launcher_icon/icon.png
  51. BIN
      assets/splash-icon-dark.png
  52. BIN
      assets/splash-icon-light.png
  53. BIN
      assets/splash-screen-dark.png
  54. BIN
      assets/splash-screen-light.png
  55. 12 0
      ios/Podfile.lock
  56. 4 0
      ios/Runner.xcodeproj/project.pbxproj
  57. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  58. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  59. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  60. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  61. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  62. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  63. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  64. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  65. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  66. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  67. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
  68. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
  69. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
  70. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
  71. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  72. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  73. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
  74. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
  75. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  76. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  77. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  78. BIN
      ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
  79. BIN
      ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png
  80. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  81. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  82. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  83. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png
  84. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png
  85. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png
  86. 4 4
      ios/Runner/Info.plist
  87. 4 4
      lib/main.dart
  88. 157 157
      lib/services/object_detection/object_detection_service.dart
  89. 89 89
      lib/services/object_detection/tflite/classifier.dart
  90. 114 114
      lib/services/object_detection/tflite/cocossd_classifier.dart
  91. 68 68
      lib/services/object_detection/tflite/mobilenet_classifier.dart
  92. 73 73
      lib/services/object_detection/tflite/scene_classifier.dart
  93. 76 76
      lib/services/object_detection/utils/isolate_utils.dart
  94. 9 10
      lib/ui/viewer/file/file_details_widget.dart
  95. 62 62
      lib/ui/viewer/file_details/objects_item_widget.dart
  96. 1 0
      lib/utils/delete_file_util.dart
  97. 64 23
      pubspec.lock
  98. 16 18
      pubspec.yaml

+ 1 - 1
android/app/src/main/AndroidManifest.xml

@@ -3,7 +3,7 @@
     package="io.ente.photos">
     package="io.ente.photos">
     <application android:name="${applicationName}"
     <application android:name="${applicationName}"
         android:label="@string/app_name"
         android:label="@string/app_name"
-        android:icon="@mipmap/ic_launcher"
+        android:icon="@mipmap/launcher_icon"
         android:usesCleartextTraffic="true"
         android:usesCleartextTraffic="true"
         android:requestLegacyExternalStorage="true"
         android:requestLegacyExternalStorage="true"
         android:allowBackup="false"
         android:allowBackup="false"

BIN
android/app/src/main/res/drawable-hdpi/android12splash.png


BIN
android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png


BIN
android/app/src/main/res/drawable-hdpi/splash.png


BIN
android/app/src/main/res/drawable-mdpi/android12splash.png


BIN
android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png


BIN
android/app/src/main/res/drawable-mdpi/splash.png


BIN
android/app/src/main/res/drawable-night-hdpi/android12splash.png


BIN
android/app/src/main/res/drawable-night-hdpi/splash.png


BIN
android/app/src/main/res/drawable-night-mdpi/android12splash.png


BIN
android/app/src/main/res/drawable-night-mdpi/splash.png


BIN
android/app/src/main/res/drawable-night-v21/background.png


BIN
android/app/src/main/res/drawable-night-xhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-night-xhdpi/splash.png


BIN
android/app/src/main/res/drawable-night-xxhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-night-xxhdpi/splash.png


BIN
android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-night-xxxhdpi/splash.png


BIN
android/app/src/main/res/drawable-night/background.png


BIN
android/app/src/main/res/drawable-v21/background.png


BIN
android/app/src/main/res/drawable-xhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png


BIN
android/app/src/main/res/drawable-xhdpi/splash.png


BIN
android/app/src/main/res/drawable-xxhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png


BIN
android/app/src/main/res/drawable-xxhdpi/splash.png


BIN
android/app/src/main/res/drawable-xxxhdpi/android12splash.png


BIN
android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png


BIN
android/app/src/main/res/drawable-xxxhdpi/splash.png


BIN
android/app/src/main/res/drawable/background.png


+ 0 - 9
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-  <background android:drawable="@color/ic_launcher_background"/>
-  <foreground>
-    <inset
-        android:drawable="@drawable/ic_launcher_foreground"
-        android:inset="26%" />
-  </foreground>
-</adaptive-icon>

+ 1 - 0
android/app/src/main/res/mipmap-anydpi-v26/launcher_icon.xml

@@ -2,4 +2,5 @@
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
   <background android:drawable="@color/ic_launcher_background"/>
   <background android:drawable="@color/ic_launcher_background"/>
   <foreground android:drawable="@drawable/ic_launcher_foreground"/>
   <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+  <monochrome android:drawable="@drawable/ic_launcher_foreground"/>
 </adaptive-icon>
 </adaptive-icon>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png


+ 0 - 1
android/app/src/main/res/values-night-v31/styles.xml

@@ -4,7 +4,6 @@
     <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
     <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:windowFullscreen">false</item>
         <item name="android:windowFullscreen">false</item>
-        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowSplashScreenBackground">#000000</item>
         <item name="android:windowSplashScreenBackground">#000000</item>
         <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
         <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>

+ 0 - 1
android/app/src/main/res/values-night/styles.xml

@@ -7,7 +7,6 @@
         <item name="android:windowBackground">@drawable/launch_background</item>
         <item name="android:windowBackground">@drawable/launch_background</item>
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:windowFullscreen">false</item>
         <item name="android:windowFullscreen">false</item>
-        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
     </style>
     </style>
     <!-- Theme applied to the Android Window as soon as the process has started.
     <!-- Theme applied to the Android Window as soon as the process has started.

+ 0 - 1
android/app/src/main/res/values-v31/styles.xml

@@ -4,7 +4,6 @@
     <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
     <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:forceDarkAllowed">false</item>
         <item name="android:windowFullscreen">false</item>
         <item name="android:windowFullscreen">false</item>
-        <item name="android:windowDrawsSystemBarBackgrounds">false</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowSplashScreenBackground">#ffffff</item>
         <item name="android:windowSplashScreenBackground">#ffffff</item>
         <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
         <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>

BIN
assets/ente.png


BIN
assets/icon-light.png


BIN
assets/launcher_icon/adaptive_icon.png


BIN
assets/launcher_icon/ente-icon-foreground.png


BIN
assets/launcher_icon/icon.png


BIN
assets/splash-icon-dark.png


BIN
assets/splash-icon-light.png


BIN
assets/splash-screen-dark.png


BIN
assets/splash-screen-light.png


+ 12 - 0
ios/Podfile.lock

@@ -1,6 +1,8 @@
 PODS:
 PODS:
   - background_fetch (1.1.6):
   - background_fetch (1.1.6):
     - Flutter
     - Flutter
+  - camera_avfoundation (0.0.1):
+    - Flutter
   - connectivity_plus (0.0.1):
   - connectivity_plus (0.0.1):
     - Flutter
     - Flutter
     - ReachabilitySwift
     - ReachabilitySwift
@@ -163,6 +165,8 @@ PODS:
     - FMDB (>= 2.7.5)
     - FMDB (>= 2.7.5)
   - tflite_flutter (0.1.0):
   - tflite_flutter (0.1.0):
     - Flutter
     - Flutter
+  - tflite_flutter_helper (0.0.1):
+    - Flutter
   - Toast (4.0.0)
   - Toast (4.0.0)
   - uni_links (0.0.1):
   - uni_links (0.0.1):
     - Flutter
     - Flutter
@@ -178,6 +182,7 @@ PODS:
 
 
 DEPENDENCIES:
 DEPENDENCIES:
   - background_fetch (from `.symlinks/plugins/background_fetch/ios`)
   - background_fetch (from `.symlinks/plugins/background_fetch/ios`)
+  - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
   - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
   - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
   - device_info (from `.symlinks/plugins/device_info/ios`)
   - device_info (from `.symlinks/plugins/device_info/ios`)
   - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
   - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@@ -209,6 +214,7 @@ DEPENDENCIES:
   - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
   - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
   - sqflite (from `.symlinks/plugins/sqflite/ios`)
   - sqflite (from `.symlinks/plugins/sqflite/ios`)
   - tflite_flutter (from `.symlinks/plugins/tflite_flutter/ios`)
   - tflite_flutter (from `.symlinks/plugins/tflite_flutter/ios`)
+  - tflite_flutter_helper (from `.symlinks/plugins/tflite_flutter_helper/ios`)
   - uni_links (from `.symlinks/plugins/uni_links/ios`)
   - uni_links (from `.symlinks/plugins/uni_links/ios`)
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
   - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
   - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
@@ -240,6 +246,8 @@ SPEC REPOS:
 EXTERNAL SOURCES:
 EXTERNAL SOURCES:
   background_fetch:
   background_fetch:
     :path: ".symlinks/plugins/background_fetch/ios"
     :path: ".symlinks/plugins/background_fetch/ios"
+  camera_avfoundation:
+    :path: ".symlinks/plugins/camera_avfoundation/ios"
   connectivity_plus:
   connectivity_plus:
     :path: ".symlinks/plugins/connectivity_plus/ios"
     :path: ".symlinks/plugins/connectivity_plus/ios"
   device_info:
   device_info:
@@ -302,6 +310,8 @@ EXTERNAL SOURCES:
     :path: ".symlinks/plugins/sqflite/ios"
     :path: ".symlinks/plugins/sqflite/ios"
   tflite_flutter:
   tflite_flutter:
     :path: ".symlinks/plugins/tflite_flutter/ios"
     :path: ".symlinks/plugins/tflite_flutter/ios"
+  tflite_flutter_helper:
+    :path: ".symlinks/plugins/tflite_flutter_helper/ios"
   uni_links:
   uni_links:
     :path: ".symlinks/plugins/uni_links/ios"
     :path: ".symlinks/plugins/uni_links/ios"
   url_launcher_ios:
   url_launcher_ios:
@@ -315,6 +325,7 @@ EXTERNAL SOURCES:
 
 
 SPEC CHECKSUMS:
 SPEC CHECKSUMS:
   background_fetch: bc9b44b0bf8b434e282a2ac9be8662800a0296ed
   background_fetch: bc9b44b0bf8b434e282a2ac9be8662800a0296ed
+  camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
   connectivity_plus: 53efb943fc2882c8512d84c45707bcabc4c36076
   connectivity_plus: 53efb943fc2882c8512d84c45707bcabc4c36076
   device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
   device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
   Firebase: bd152f0f3d278c4060c5c71359db08ebcfd5a3e2
   Firebase: bd152f0f3d278c4060c5c71359db08ebcfd5a3e2
@@ -364,6 +375,7 @@ SPEC CHECKSUMS:
   shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
   shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
   sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
   sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
   tflite_flutter: 9157a660578930a99728974f247369af1c3595d5
   tflite_flutter: 9157a660578930a99728974f247369af1c3595d5
+  tflite_flutter_helper: 543b46b6bd064b21c92ea6e54bc0b29f1ce74cb5
   Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
   Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
   uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
   uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
   url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
   url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4

+ 4 - 0
ios/Runner.xcodeproj/project.pbxproj

@@ -276,6 +276,7 @@
 				"${BUILT_PRODUCTS_DIR}/SentryPrivate/SentryPrivate.framework",
 				"${BUILT_PRODUCTS_DIR}/SentryPrivate/SentryPrivate.framework",
 				"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
 				"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
 				"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
 				"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
+				"${BUILT_PRODUCTS_DIR}/camera_avfoundation/camera_avfoundation.framework",
 				"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
 				"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
 				"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
 				"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
@@ -306,6 +307,7 @@
 				"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
 				"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
 				"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
 				"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
 				"${BUILT_PRODUCTS_DIR}/tflite_flutter/tflite_flutter.framework",
 				"${BUILT_PRODUCTS_DIR}/tflite_flutter/tflite_flutter.framework",
+				"${BUILT_PRODUCTS_DIR}/tflite_flutter_helper/tflite_flutter_helper.framework",
 				"${BUILT_PRODUCTS_DIR}/uni_links/uni_links.framework",
 				"${BUILT_PRODUCTS_DIR}/uni_links/uni_links.framework",
 				"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
 				"${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework",
 				"${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework",
@@ -331,6 +333,7 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SentryPrivate.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SentryPrivate.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/camera_avfoundation.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",
@@ -361,6 +364,7 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tflite_flutter.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tflite_flutter.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tflite_flutter_helper.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/uni_links.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/uni_links.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework",

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png


BIN
ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png


+ 4 - 4
ios/Runner/Info.plist

@@ -64,10 +64,10 @@
 		</dict>
 		</dict>
 		<key>ITSAppUsesNonExemptEncryption</key>
 		<key>ITSAppUsesNonExemptEncryption</key>
 		<false/>
 		<false/>
-		<key>FLTEnableImpeller</key>
-		<false/>
-		<key>FLTEnableWideGamut</key>
-		<false/>
+		 <key>FLTEnableImpeller</key>
+         <false />
+         <key>FLTEnableWideGamut</key>
+         <false/>
 		<key>NSFaceIDUsageDescription</key>
 		<key>NSFaceIDUsageDescription</key>
 		<string>Please allow ente to lock itself with FaceID or TouchID</string>
 		<string>Please allow ente to lock itself with FaceID or TouchID</string>
 		<key>NSCameraUsageDescription</key>
 		<key>NSCameraUsageDescription</key>

+ 4 - 4
lib/main.dart

@@ -29,7 +29,7 @@ import 'package:photos/services/local_file_update_service.dart';
 import 'package:photos/services/local_sync_service.dart';
 import 'package:photos/services/local_sync_service.dart';
 import "package:photos/services/location_service.dart";
 import "package:photos/services/location_service.dart";
 import 'package:photos/services/memories_service.dart';
 import 'package:photos/services/memories_service.dart';
-// import "package:photos/services/object_detection/object_detection_service.dart";
+import "package:photos/services/object_detection/object_detection_service.dart";
 import 'package:photos/services/push_service.dart';
 import 'package:photos/services/push_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/services/remote_sync_service.dart';
 import 'package:photos/services/search_service.dart';
 import 'package:photos/services/search_service.dart';
@@ -190,9 +190,9 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
   // Can not including existing tf/ml binaries as they are not being built
   // Can not including existing tf/ml binaries as they are not being built
   // from source.
   // from source.
   // See https://gitlab.com/fdroid/fdroiddata/-/merge_requests/12671#note_1294346819
   // See https://gitlab.com/fdroid/fdroiddata/-/merge_requests/12671#note_1294346819
-  // if (!UpdateService.instance.isFdroidFlavor()) {
-  //   unawaited(ObjectDetectionService.instance.init());
-  // }
+  if (!UpdateService.instance.isFdroidFlavor()) {
+    unawaited(ObjectDetectionService.instance.init());
+  }
 
 
   _logger.info("Initialization done");
   _logger.info("Initialization done");
 }
 }

+ 157 - 157
lib/services/object_detection/object_detection_service.dart

@@ -1,157 +1,157 @@
-// import "dart:isolate";
-// import "dart:math";
-// import "dart:typed_data";
-
-// import "package:logging/logging.dart";
-// import "package:photos/services/object_detection/models/predictions.dart";
-// import 'package:photos/services/object_detection/models/recognition.dart';
-// import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
-// import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
-// import "package:photos/services/object_detection/tflite/scene_classifier.dart";
-// import "package:photos/services/object_detection/utils/isolate_utils.dart";
-
-// class ObjectDetectionService {
-//   static const scoreThreshold = 0.35;
-
-//   final _logger = Logger("ObjectDetectionService");
-
-//   late CocoSSDClassifier _objectClassifier;
-//   late MobileNetClassifier _mobileNetClassifier;
-//   late SceneClassifier _sceneClassifier;
-
-//   late IsolateUtils _isolateUtils;
-
-//   ObjectDetectionService._privateConstructor();
-//   bool inInitiated = false;
-
-//   Future<void> init() async {
-//     _isolateUtils = IsolateUtils();
-//     await _isolateUtils.start();
-//     try {
-//       _objectClassifier = CocoSSDClassifier();
-//     } catch (e, s) {
-//       _logger.severe("Could not initialize cocossd", e, s);
-//     }
-//     try {
-//       _mobileNetClassifier = MobileNetClassifier();
-//     } catch (e, s) {
-//       _logger.severe("Could not initialize mobilenet", e, s);
-//     }
-//     try {
-//       _sceneClassifier = SceneClassifier();
-//     } catch (e, s) {
-//       _logger.severe("Could not initialize sceneclassifier", e, s);
-//     }
-//     inInitiated = true;
-//   }
-
-//   static ObjectDetectionService instance =
-//       ObjectDetectionService._privateConstructor();
-
-//   Future<Map<String, double>> predict(Uint8List bytes) async {
-//     try {
-//       if (!inInitiated) {
-//         return Future.error("ObjectDetectionService init is not completed");
-//       }
-//       final results = <String, double>{};
-//       final methods = [_getObjects, _getMobileNetResults, _getSceneResults];
-
-//       for (var method in methods) {
-//         final methodResults = await method(bytes);
-//         methodResults.forEach((key, value) {
-//           results.update(
-//             key,
-//             (existingValue) => max(existingValue, value),
-//             ifAbsent: () => value,
-//           );
-//         });
-//       }
-//       return results;
-//     } catch (e, s) {
-//       _logger.severe(e, s);
-//       rethrow;
-//     }
-//   }
-
-//   Future<Map<String, double>> _getObjects(Uint8List bytes) async {
-//     try {
-//       final isolateData = IsolateData(
-//         bytes,
-//         _objectClassifier.interpreter.address,
-//         _objectClassifier.labels,
-//         ClassifierType.cocossd,
-//       );
-//       return _getPredictions(isolateData);
-//     } catch (e, s) {
-//       _logger.severe("Could not run cocossd", e, s);
-//     }
-//     return {};
-//   }
-
-//   Future<Map<String, double>> _getMobileNetResults(Uint8List bytes) async {
-//     try {
-//       final isolateData = IsolateData(
-//         bytes,
-//         _mobileNetClassifier.interpreter.address,
-//         _mobileNetClassifier.labels,
-//         ClassifierType.mobilenet,
-//       );
-//       return _getPredictions(isolateData);
-//     } catch (e, s) {
-//       _logger.severe("Could not run mobilenet", e, s);
-//     }
-//     return {};
-//   }
-
-//   Future<Map<String, double>> _getSceneResults(Uint8List bytes) async {
-//     try {
-//       final isolateData = IsolateData(
-//         bytes,
-//         _sceneClassifier.interpreter.address,
-//         _sceneClassifier.labels,
-//         ClassifierType.scenes,
-//       );
-//       return _getPredictions(isolateData);
-//     } catch (e, s) {
-//       _logger.severe("Could not run scene detection", e, s);
-//     }
-//     return {};
-//   }
-
-//   Future<Map<String, double>> _getPredictions(IsolateData isolateData) async {
-//     final predictions = await _inference(isolateData);
-//     final Map<String, double> results = {};
-
-//     if (predictions.error == null) {
-//       for (final Recognition result in predictions.recognitions!) {
-//         if (result.score > scoreThreshold) {
-//           // Update the result score only if it's higher than the current score
-//           if (!results.containsKey(result.label) ||
-//               results[result.label]! < result.score) {
-//             results[result.label] = result.score;
-//           }
-//         }
-//       }
-
-//       _logger.info(
-//         "Time taken for ${isolateData.type}: ${predictions.stats!.totalElapsedTime}ms",
-//       );
-//     } else {
-//       _logger.severe(
-//         "Error while fetching predictions for ${isolateData.type}",
-//         predictions.error,
-//       );
-//     }
-
-//     return results;
-//   }
-
-//   /// Runs inference in another isolate
-//   Future<Predictions> _inference(IsolateData isolateData) async {
-//     final responsePort = ReceivePort();
-//     _isolateUtils.sendPort.send(
-//       isolateData..responsePort = responsePort.sendPort,
-//     );
-//     return await responsePort.first;
-//   }
-// }
+import "dart:isolate";
+import "dart:math";
+import "dart:typed_data";
+
+import "package:logging/logging.dart";
+import "package:photos/services/object_detection/models/predictions.dart";
+import 'package:photos/services/object_detection/models/recognition.dart';
+import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
+import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
+import "package:photos/services/object_detection/tflite/scene_classifier.dart";
+import "package:photos/services/object_detection/utils/isolate_utils.dart";
+
+class ObjectDetectionService {
+  static const scoreThreshold = 0.35;
+
+  final _logger = Logger("ObjectDetectionService");
+
+  late CocoSSDClassifier _objectClassifier;
+  late MobileNetClassifier _mobileNetClassifier;
+  late SceneClassifier _sceneClassifier;
+
+  late IsolateUtils _isolateUtils;
+
+  ObjectDetectionService._privateConstructor();
+  bool inInitiated = false;
+
+  Future<void> init() async {
+    _isolateUtils = IsolateUtils();
+    await _isolateUtils.start();
+    try {
+      _objectClassifier = CocoSSDClassifier();
+    } catch (e, s) {
+      _logger.severe("Could not initialize cocossd", e, s);
+    }
+    try {
+      _mobileNetClassifier = MobileNetClassifier();
+    } catch (e, s) {
+      _logger.severe("Could not initialize mobilenet", e, s);
+    }
+    try {
+      _sceneClassifier = SceneClassifier();
+    } catch (e, s) {
+      _logger.severe("Could not initialize sceneclassifier", e, s);
+    }
+    inInitiated = true;
+  }
+
+  static ObjectDetectionService instance =
+      ObjectDetectionService._privateConstructor();
+
+  Future<Map<String, double>> predict(Uint8List bytes) async {
+    try {
+      if (!inInitiated) {
+        return Future.error("ObjectDetectionService init is not completed");
+      }
+      final results = <String, double>{};
+      final methods = [_getObjects, _getMobileNetResults, _getSceneResults];
+
+      for (var method in methods) {
+        final methodResults = await method(bytes);
+        methodResults.forEach((key, value) {
+          results.update(
+            key,
+            (existingValue) => max(existingValue, value),
+            ifAbsent: () => value,
+          );
+        });
+      }
+      return results;
+    } catch (e, s) {
+      _logger.severe(e, s);
+      rethrow;
+    }
+  }
+
+  Future<Map<String, double>> _getObjects(Uint8List bytes) async {
+    try {
+      final isolateData = IsolateData(
+        bytes,
+        _objectClassifier.interpreter.address,
+        _objectClassifier.labels,
+        ClassifierType.cocossd,
+      );
+      return _getPredictions(isolateData);
+    } catch (e, s) {
+      _logger.severe("Could not run cocossd", e, s);
+    }
+    return {};
+  }
+
+  Future<Map<String, double>> _getMobileNetResults(Uint8List bytes) async {
+    try {
+      final isolateData = IsolateData(
+        bytes,
+        _mobileNetClassifier.interpreter.address,
+        _mobileNetClassifier.labels,
+        ClassifierType.mobilenet,
+      );
+      return _getPredictions(isolateData);
+    } catch (e, s) {
+      _logger.severe("Could not run mobilenet", e, s);
+    }
+    return {};
+  }
+
+  Future<Map<String, double>> _getSceneResults(Uint8List bytes) async {
+    try {
+      final isolateData = IsolateData(
+        bytes,
+        _sceneClassifier.interpreter.address,
+        _sceneClassifier.labels,
+        ClassifierType.scenes,
+      );
+      return _getPredictions(isolateData);
+    } catch (e, s) {
+      _logger.severe("Could not run scene detection", e, s);
+    }
+    return {};
+  }
+
+  Future<Map<String, double>> _getPredictions(IsolateData isolateData) async {
+    final predictions = await _inference(isolateData);
+    final Map<String, double> results = {};
+
+    if (predictions.error == null) {
+      for (final Recognition result in predictions.recognitions!) {
+        if (result.score > scoreThreshold) {
+          // Update the result score only if it's higher than the current score
+          if (!results.containsKey(result.label) ||
+              results[result.label]! < result.score) {
+            results[result.label] = result.score;
+          }
+        }
+      }
+
+      _logger.info(
+        "Time taken for ${isolateData.type}: ${predictions.stats!.totalElapsedTime}ms",
+      );
+    } else {
+      _logger.severe(
+        "Error while fetching predictions for ${isolateData.type}",
+        predictions.error,
+      );
+    }
+
+    return results;
+  }
+
+  /// Runs inference in another isolate
+  Future<Predictions> _inference(IsolateData isolateData) async {
+    final responsePort = ReceivePort();
+    _isolateUtils.sendPort.send(
+      isolateData..responsePort = responsePort.sendPort,
+    );
+    return await responsePort.first;
+  }
+}

+ 89 - 89
lib/services/object_detection/tflite/classifier.dart

@@ -1,89 +1,89 @@
-// import "dart:math";
-
-// import 'package:image/image.dart' as image_lib;
-// import "package:logging/logging.dart";
-// import "package:photos/services/object_detection/models/predictions.dart";
-// import "package:tflite_flutter/tflite_flutter.dart";
-// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
-
-// abstract class Classifier {
-//   // Path to the model
-//   String get modelPath;
-
-//   // Path to the labels
-//   String get labelPath;
-
-//   // Input size expected by the model (for eg. width = height = 224)
-//   int get inputSize;
-
-//   // Logger implementation for the specific classifier
-//   Logger get logger;
-
-//   Predictions? predict(image_lib.Image image);
-
-//   /// Instance of Interpreter
-//   late Interpreter _interpreter;
-
-//   /// Labels file loaded as list
-//   late List<String> _labels;
-
-//   /// Shapes of output tensors
-//   late List<List<int>> _outputShapes;
-
-//   /// Types of output tensors
-//   late List<TfLiteType> _outputTypes;
-
-//   /// Gets the interpreter instance
-//   Interpreter get interpreter => _interpreter;
-
-//   /// Gets the loaded labels
-//   List<String> get labels => _labels;
-
-//   /// Gets the output shapes
-//   List<List<int>> get outputShapes => _outputShapes;
-
-//   /// Gets the output types
-//   List<TfLiteType> get outputTypes => _outputTypes;
-
-//   /// Loads interpreter from asset
-//   void loadModel(Interpreter? interpreter) async {
-//     try {
-//       _interpreter = interpreter ??
-//           await Interpreter.fromAsset(
-//             modelPath,
-//             options: InterpreterOptions()..threads = 4,
-//           );
-//       final outputTensors = _interpreter.getOutputTensors();
-//       _outputShapes = [];
-//       _outputTypes = [];
-//       for (var tensor in outputTensors) {
-//         _outputShapes.add(tensor.shape);
-//         _outputTypes.add(tensor.type);
-//       }
-//       logger.info("Interpreter initialized");
-//     } catch (e, s) {
-//       logger.severe("Error while creating interpreter", e, s);
-//     }
-//   }
-
-//   /// Loads labels from assets
-//   void loadLabels(List<String>? labels) async {
-//     try {
-//       _labels = labels ?? await FileUtil.loadLabels(labelPath);
-//       logger.info("Labels initialized");
-//     } catch (e, s) {
-//       logger.severe("Error while loading labels", e, s);
-//     }
-//   }
-
-//   /// Pre-process the image
-//   TensorImage getProcessedImage(TensorImage inputImage) {
-//     final padSize = max(inputImage.height, inputImage.width);
-//     final imageProcessor = ImageProcessorBuilder()
-//         .add(ResizeWithCropOrPadOp(padSize, padSize))
-//         .add(ResizeOp(inputSize, inputSize, ResizeMethod.BILINEAR))
-//         .build();
-//     inputImage = imageProcessor.process(inputImage);
-//     return inputImage;
-//   }
-// }
+import "dart:math";
+
+import 'package:image/image.dart' as image_lib;
+import "package:logging/logging.dart";
+import "package:photos/services/object_detection/models/predictions.dart";
+import "package:tflite_flutter/tflite_flutter.dart";
+import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
+
+abstract class Classifier {
+  // Path to the model
+  String get modelPath;
+
+  // Path to the labels
+  String get labelPath;
+
+  // Input size expected by the model (for eg. width = height = 224)
+  int get inputSize;
+
+  // Logger implementation for the specific classifier
+  Logger get logger;
+
+  Predictions? predict(image_lib.Image image);
+
+  /// Instance of Interpreter
+  late Interpreter _interpreter;
+
+  /// Labels file loaded as list
+  late List<String> _labels;
+
+  /// Shapes of output tensors
+  late List<List<int>> _outputShapes;
+
+  /// Types of output tensors
+  late List<TfLiteType> _outputTypes;
+
+  /// Gets the interpreter instance
+  Interpreter get interpreter => _interpreter;
+
+  /// Gets the loaded labels
+  List<String> get labels => _labels;
+
+  /// Gets the output shapes
+  List<List<int>> get outputShapes => _outputShapes;
+
+  /// Gets the output types
+  List<TfLiteType> get outputTypes => _outputTypes;
+
+  /// Loads interpreter from asset
+  void loadModel(Interpreter? interpreter) async {
+    try {
+      _interpreter = interpreter ??
+          await Interpreter.fromAsset(
+            modelPath,
+            options: InterpreterOptions()..threads = 4,
+          );
+      final outputTensors = _interpreter.getOutputTensors();
+      _outputShapes = [];
+      _outputTypes = [];
+      for (var tensor in outputTensors) {
+        _outputShapes.add(tensor.shape);
+        _outputTypes.add(tensor.type);
+      }
+      logger.info("Interpreter initialized");
+    } catch (e, s) {
+      logger.severe("Error while creating interpreter", e, s);
+    }
+  }
+
+  /// Loads labels from assets
+  void loadLabels(List<String>? labels) async {
+    try {
+      _labels = labels ?? await FileUtil.loadLabels(labelPath);
+      logger.info("Labels initialized");
+    } catch (e, s) {
+      logger.severe("Error while loading labels", e, s);
+    }
+  }
+
+  /// Pre-process the image
+  TensorImage getProcessedImage(TensorImage inputImage) {
+    final padSize = max(inputImage.height, inputImage.width);
+    final imageProcessor = ImageProcessorBuilder()
+        .add(ResizeWithCropOrPadOp(padSize, padSize))
+        .add(ResizeOp(inputSize, inputSize, ResizeMethod.BILINEAR))
+        .build();
+    inputImage = imageProcessor.process(inputImage);
+    return inputImage;
+  }
+}

+ 114 - 114
lib/services/object_detection/tflite/cocossd_classifier.dart

@@ -1,115 +1,115 @@
-// import 'dart:math';
+import 'dart:math';
 
 
-// import 'package:image/image.dart' as image_lib;
-// import "package:logging/logging.dart";
-// import 'package:photos/services/object_detection/models/predictions.dart';
-// import 'package:photos/services/object_detection/models/recognition.dart';
-// import "package:photos/services/object_detection/models/stats.dart";
-// import "package:photos/services/object_detection/tflite/classifier.dart";
-// import "package:tflite_flutter/tflite_flutter.dart";
-// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
-
-// /// Classifier
-// class CocoSSDClassifier extends Classifier {
-//   static final _logger = Logger("CocoSSDClassifier");
-//   static const double threshold = 0.4;
-
-//   @override
-//   String get modelPath => "models/cocossd/model.tflite";
-
-//   @override
-//   String get labelPath => "assets/models/cocossd/labels.txt";
-
-//   @override
-//   int get inputSize => 300;
-
-//   @override
-//   Logger get logger => _logger;
-
-//   static const int numResults = 10;
-
-//   CocoSSDClassifier({
-//     Interpreter? interpreter,
-//     List<String>? labels,
-//   }) {
-//     loadModel(interpreter);
-//     loadLabels(labels);
-//   }
-
-//   @override
-//   Predictions? predict(image_lib.Image image) {
-//     final predictStartTime = DateTime.now().millisecondsSinceEpoch;
-
-//     final preProcessStart = DateTime.now().millisecondsSinceEpoch;
-
-//     // Create TensorImage from image
-//     TensorImage inputImage = TensorImage.fromImage(image);
-
-//     // Pre-process TensorImage
-//     inputImage = getProcessedImage(inputImage);
-
-//     final preProcessElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - preProcessStart;
-
-//     // TensorBuffers for output tensors
-//     final outputLocations = TensorBufferFloat(outputShapes[0]);
-//     final outputClasses = TensorBufferFloat(outputShapes[1]);
-//     final outputScores = TensorBufferFloat(outputShapes[2]);
-//     final numLocations = TensorBufferFloat(outputShapes[3]);
-
-//     // Inputs object for runForMultipleInputs
-//     // Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
-//     final inputs = [inputImage.buffer];
-
-//     // Outputs map
-//     final outputs = {
-//       0: outputLocations.buffer,
-//       1: outputClasses.buffer,
-//       2: outputScores.buffer,
-//       3: numLocations.buffer,
-//     };
-
-//     final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
-
-//     // run inference
-//     interpreter.runForMultipleInputs(inputs, outputs);
-
-//     final inferenceTimeElapsed =
-//         DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
-
-//     // Maximum number of results to show
-//     final resultsCount = min(numResults, numLocations.getIntValue(0));
-
-//     // Using labelOffset = 1 as ??? at index 0
-//     const labelOffset = 1;
-
-//     final recognitions = <Recognition>[];
-
-//     for (int i = 0; i < resultsCount; i++) {
-//       // Prediction score
-//       final score = outputScores.getDoubleValue(i);
-
-//       // Label string
-//       final labelIndex = outputClasses.getIntValue(i) + labelOffset;
-//       final label = labels.elementAt(labelIndex);
-
-//       if (score > threshold) {
-//         recognitions.add(
-//           Recognition(i, label, score),
-//         );
-//       }
-//     }
-
-//     final predictElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - predictStartTime;
-//     return Predictions(
-//       recognitions,
-//       Stats(
-//         predictElapsedTime,
-//         predictElapsedTime,
-//         inferenceTimeElapsed,
-//         preProcessElapsedTime,
-//       ),
-//     );
-//   }
-// }
+import 'package:image/image.dart' as image_lib;
+import "package:logging/logging.dart";
+import 'package:photos/services/object_detection/models/predictions.dart';
+import 'package:photos/services/object_detection/models/recognition.dart';
+import "package:photos/services/object_detection/models/stats.dart";
+import "package:photos/services/object_detection/tflite/classifier.dart";
+import "package:tflite_flutter/tflite_flutter.dart";
+import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
+
+/// Classifier
+class CocoSSDClassifier extends Classifier {
+  static final _logger = Logger("CocoSSDClassifier");
+  static const double threshold = 0.4;
+
+  @override
+  String get modelPath => "models/cocossd/model.tflite";
+
+  @override
+  String get labelPath => "assets/models/cocossd/labels.txt";
+
+  @override
+  int get inputSize => 300;
+
+  @override
+  Logger get logger => _logger;
+
+  static const int numResults = 10;
+
+  CocoSSDClassifier({
+    Interpreter? interpreter,
+    List<String>? labels,
+  }) {
+    loadModel(interpreter);
+    loadLabels(labels);
+  }
+
+  @override
+  Predictions? predict(image_lib.Image image) {
+    final predictStartTime = DateTime.now().millisecondsSinceEpoch;
+
+    final preProcessStart = DateTime.now().millisecondsSinceEpoch;
+
+    // Create TensorImage from image
+    TensorImage inputImage = TensorImage.fromImage(image);
+
+    // Pre-process TensorImage
+    inputImage = getProcessedImage(inputImage);
+
+    final preProcessElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - preProcessStart;
+
+    // TensorBuffers for output tensors
+    final outputLocations = TensorBufferFloat(outputShapes[0]);
+    final outputClasses = TensorBufferFloat(outputShapes[1]);
+    final outputScores = TensorBufferFloat(outputShapes[2]);
+    final numLocations = TensorBufferFloat(outputShapes[3]);
+
+    // Inputs object for runForMultipleInputs
+    // Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
+    final inputs = [inputImage.buffer];
+
+    // Outputs map
+    final outputs = {
+      0: outputLocations.buffer,
+      1: outputClasses.buffer,
+      2: outputScores.buffer,
+      3: numLocations.buffer,
+    };
+
+    final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
+
+    // run inference
+    interpreter.runForMultipleInputs(inputs, outputs);
+
+    final inferenceTimeElapsed =
+        DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
+
+    // Maximum number of results to show
+    final resultsCount = min(numResults, numLocations.getIntValue(0));
+
+    // Using labelOffset = 1 as ??? at index 0
+    const labelOffset = 1;
+
+    final recognitions = <Recognition>[];
+
+    for (int i = 0; i < resultsCount; i++) {
+      // Prediction score
+      final score = outputScores.getDoubleValue(i);
+
+      // Label string
+      final labelIndex = outputClasses.getIntValue(i) + labelOffset;
+      final label = labels.elementAt(labelIndex);
+
+      if (score > threshold) {
+        recognitions.add(
+          Recognition(i, label, score),
+        );
+      }
+    }
+
+    final predictElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - predictStartTime;
+    return Predictions(
+      recognitions,
+      Stats(
+        predictElapsedTime,
+        predictElapsedTime,
+        inferenceTimeElapsed,
+        preProcessElapsedTime,
+      ),
+    );
+  }
+}

+ 68 - 68
lib/services/object_detection/tflite/mobilenet_classifier.dart

@@ -1,83 +1,83 @@
-// import 'package:image/image.dart' as image_lib;
-// import "package:logging/logging.dart";
-// import 'package:photos/services/object_detection/models/predictions.dart';
-// import 'package:photos/services/object_detection/models/recognition.dart';
-// import "package:photos/services/object_detection/models/stats.dart";
-// import "package:photos/services/object_detection/tflite/classifier.dart";
-// import "package:tflite_flutter/tflite_flutter.dart";
-// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
+import 'package:image/image.dart' as image_lib;
+import "package:logging/logging.dart";
+import 'package:photos/services/object_detection/models/predictions.dart';
+import 'package:photos/services/object_detection/models/recognition.dart';
+import "package:photos/services/object_detection/models/stats.dart";
+import "package:photos/services/object_detection/tflite/classifier.dart";
+import "package:tflite_flutter/tflite_flutter.dart";
+import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
 
 
-// // Source: https://tfhub.dev/tensorflow/lite-model/mobilenet_v1_1.0_224/1/default/1
-// class MobileNetClassifier extends Classifier {
-//   static final _logger = Logger("MobileNetClassifier");
-//   static const double threshold = 0.4;
+// Source: https://tfhub.dev/tensorflow/lite-model/mobilenet_v1_1.0_224/1/default/1
+class MobileNetClassifier extends Classifier {
+  static final _logger = Logger("MobileNetClassifier");
+  static const double threshold = 0.4;
 
 
-//   @override
-//   String get modelPath => "models/mobilenet/mobilenet_v1_1.0_224_quant.tflite";
+  @override
+  String get modelPath => "models/mobilenet/mobilenet_v1_1.0_224_quant.tflite";
 
 
-//   @override
-//   String get labelPath =>
-//       "assets/models/mobilenet/labels_mobilenet_quant_v1_224.txt";
+  @override
+  String get labelPath =>
+      "assets/models/mobilenet/labels_mobilenet_quant_v1_224.txt";
 
 
-//   @override
-//   int get inputSize => 224;
+  @override
+  int get inputSize => 224;
 
 
-//   @override
-//   Logger get logger => _logger;
+  @override
+  Logger get logger => _logger;
 
 
-//   MobileNetClassifier({
-//     Interpreter? interpreter,
-//     List<String>? labels,
-//   }) {
-//     loadModel(interpreter);
-//     loadLabels(labels);
-//   }
+  MobileNetClassifier({
+    Interpreter? interpreter,
+    List<String>? labels,
+  }) {
+    loadModel(interpreter);
+    loadLabels(labels);
+  }
 
 
-//   @override
-//   Predictions? predict(image_lib.Image image) {
-//     final predictStartTime = DateTime.now().millisecondsSinceEpoch;
+  @override
+  Predictions? predict(image_lib.Image image) {
+    final predictStartTime = DateTime.now().millisecondsSinceEpoch;
 
 
-//     final preProcessStart = DateTime.now().millisecondsSinceEpoch;
+    final preProcessStart = DateTime.now().millisecondsSinceEpoch;
 
 
-//     // Create TensorImage from image
-//     TensorImage inputImage = TensorImage.fromImage(image);
+    // Create TensorImage from image
+    TensorImage inputImage = TensorImage.fromImage(image);
 
 
-//     // Pre-process TensorImage
-//     inputImage = getProcessedImage(inputImage);
+    // Pre-process TensorImage
+    inputImage = getProcessedImage(inputImage);
 
 
-//     final preProcessElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - preProcessStart;
+    final preProcessElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - preProcessStart;
 
 
-//     // TensorBuffers for output tensors
-//     final output = TensorBufferUint8(outputShapes[0]);
-//     final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
-//     // run inference
-//     interpreter.run(inputImage.buffer, output.buffer);
+    // TensorBuffers for output tensors
+    final output = TensorBufferUint8(outputShapes[0]);
+    final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
+    // run inference
+    interpreter.run(inputImage.buffer, output.buffer);
 
 
-//     final inferenceTimeElapsed =
-//         DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
+    final inferenceTimeElapsed =
+        DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
 
 
-//     final recognitions = <Recognition>[];
-//     for (int i = 0; i < labels.length; i++) {
-//       final score = output.getDoubleValue(i) / 255;
-//       final label = labels.elementAt(i);
-//       if (score >= threshold) {
-//         recognitions.add(
-//           Recognition(i, label, score),
-//         );
-//       }
-//     }
+    final recognitions = <Recognition>[];
+    for (int i = 0; i < labels.length; i++) {
+      final score = output.getDoubleValue(i) / 255;
+      final label = labels.elementAt(i);
+      if (score >= threshold) {
+        recognitions.add(
+          Recognition(i, label, score),
+        );
+      }
+    }
 
 
-//     final predictElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - predictStartTime;
-//     return Predictions(
-//       recognitions,
-//       Stats(
-//         predictElapsedTime,
-//         predictElapsedTime,
-//         inferenceTimeElapsed,
-//         preProcessElapsedTime,
-//       ),
-//     );
-//   }
-// }
+    final predictElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - predictStartTime;
+    return Predictions(
+      recognitions,
+      Stats(
+        predictElapsedTime,
+        predictElapsedTime,
+        inferenceTimeElapsed,
+        preProcessElapsedTime,
+      ),
+    );
+  }
+}

+ 73 - 73
lib/services/object_detection/tflite/scene_classifier.dart

@@ -1,88 +1,88 @@
-// import "package:flutter/foundation.dart";
-// import 'package:image/image.dart' as image_lib;
-// import "package:logging/logging.dart";
-// import 'package:photos/services/object_detection/models/predictions.dart';
-// import 'package:photos/services/object_detection/models/recognition.dart';
-// import "package:photos/services/object_detection/models/stats.dart";
-// import "package:photos/services/object_detection/tflite/classifier.dart";
-// import "package:tflite_flutter/tflite_flutter.dart";
-// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
+import "package:flutter/foundation.dart";
+import 'package:image/image.dart' as image_lib;
+import "package:logging/logging.dart";
+import 'package:photos/services/object_detection/models/predictions.dart';
+import 'package:photos/services/object_detection/models/recognition.dart';
+import "package:photos/services/object_detection/models/stats.dart";
+import "package:photos/services/object_detection/tflite/classifier.dart";
+import "package:tflite_flutter/tflite_flutter.dart";
+import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
 
 
-// // Source: https://tfhub.dev/sayannath/lite-model/image-scene/1
-// class SceneClassifier extends Classifier {
-//   static final _logger = Logger("SceneClassifier");
-//   static const double threshold = 0.35;
+// Source: https://tfhub.dev/sayannath/lite-model/image-scene/1
+class SceneClassifier extends Classifier {
+  static final _logger = Logger("SceneClassifier");
+  static const double threshold = 0.35;
 
 
-//   @override
-//   String get modelPath => "models/scenes/model.tflite";
+  @override
+  String get modelPath => "models/scenes/model.tflite";
 
 
-//   @override
-//   String get labelPath => "assets/models/scenes/labels.txt";
+  @override
+  String get labelPath => "assets/models/scenes/labels.txt";
 
 
-//   @override
-//   int get inputSize => 224;
+  @override
+  int get inputSize => 224;
 
 
-//   @override
-//   Logger get logger => _logger;
+  @override
+  Logger get logger => _logger;
 
 
-//   SceneClassifier({
-//     Interpreter? interpreter,
-//     List<String>? labels,
-//   }) {
-//     loadModel(interpreter);
-//     loadLabels(labels);
-//   }
+  SceneClassifier({
+    Interpreter? interpreter,
+    List<String>? labels,
+  }) {
+    loadModel(interpreter);
+    loadLabels(labels);
+  }
 
 
-//   @override
-//   Predictions? predict(image_lib.Image image) {
-//     final predictStartTime = DateTime.now().millisecondsSinceEpoch;
+  @override
+  Predictions? predict(image_lib.Image image) {
+    final predictStartTime = DateTime.now().millisecondsSinceEpoch;
 
 
-//     final preProcessStart = DateTime.now().millisecondsSinceEpoch;
+    final preProcessStart = DateTime.now().millisecondsSinceEpoch;
 
 
-//     // Create TensorImage from image
-//     TensorImage inputImage = TensorImage.fromImage(image);
+    // Create TensorImage from image
+    TensorImage inputImage = TensorImage.fromImage(image);
 
 
-//     // Pre-process TensorImage
-//     inputImage = getProcessedImage(inputImage);
-//     final list = inputImage.getTensorBuffer().getDoubleList();
-//     final input = list.reshape([1, inputSize, inputSize, 3]);
+    // Pre-process TensorImage
+    inputImage = getProcessedImage(inputImage);
+    final list = inputImage.getTensorBuffer().getDoubleList();
+    final input = list.reshape([1, inputSize, inputSize, 3]);
 
 
-//     final preProcessElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - preProcessStart;
+    final preProcessElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - preProcessStart;
 
 
-//     final output = TensorBufferFloat(outputShapes[0]);
+    final output = TensorBufferFloat(outputShapes[0]);
 
 
-//     final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
-//     interpreter.run(input, output.buffer);
-//     final inferenceTimeElapsed =
-//         DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
+    final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
+    interpreter.run(input, output.buffer);
+    final inferenceTimeElapsed =
+        DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
 
 
-//     final recognitions = <Recognition>[];
-//     for (int i = 0; i < labels.length; i++) {
-//       final score = output.getDoubleValue(i);
-//       final label = labels.elementAt(i);
-//       if (score >= threshold) {
-//         recognitions.add(
-//           Recognition(i, label, score),
-//         );
-//       } else if (kDebugMode && score > 0.2) {
-//         debugPrint("scenePrediction score $label is below threshold: $score");
-//       }
-//     }
-//     debugPrint(
-//       "Total lables ${labels.length} + reccg ${recognitions.map((e) => e.label).toSet()}",
-//     );
+    final recognitions = <Recognition>[];
+    for (int i = 0; i < labels.length; i++) {
+      final score = output.getDoubleValue(i);
+      final label = labels.elementAt(i);
+      if (score >= threshold) {
+        recognitions.add(
+          Recognition(i, label, score),
+        );
+      } else if (kDebugMode && score > 0.2) {
+        debugPrint("scenePrediction score $label is below threshold: $score");
+      }
+    }
+    debugPrint(
+      "Total lables ${labels.length} + reccg ${recognitions.map((e) => e.label).toSet()}",
+    );
 
 
-//     final predictElapsedTime =
-//         DateTime.now().millisecondsSinceEpoch - predictStartTime;
-//     return Predictions(
-//       recognitions,
-//       Stats(
-//         predictElapsedTime,
-//         predictElapsedTime,
-//         inferenceTimeElapsed,
-//         preProcessElapsedTime,
-//       ),
-//     );
-//   }
-// }
+    final predictElapsedTime =
+        DateTime.now().millisecondsSinceEpoch - predictStartTime;
+    return Predictions(
+      recognitions,
+      Stats(
+        predictElapsedTime,
+        predictElapsedTime,
+        inferenceTimeElapsed,
+        preProcessElapsedTime,
+      ),
+    );
+  }
+}

+ 76 - 76
lib/services/object_detection/utils/isolate_utils.dart

@@ -1,88 +1,88 @@
-// import 'dart:isolate';
-// import "dart:typed_data";
+import 'dart:isolate';
+import "dart:typed_data";
 
 
-// import 'package:image/image.dart' as imgLib;
-// import "package:photos/services/object_detection/models/predictions.dart";
-// import "package:photos/services/object_detection/tflite/classifier.dart";
-// import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
-// import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
-// import "package:photos/services/object_detection/tflite/scene_classifier.dart";
-// import 'package:tflite_flutter/tflite_flutter.dart';
+import 'package:image/image.dart' as imgLib;
+import "package:photos/services/object_detection/models/predictions.dart";
+import "package:photos/services/object_detection/tflite/classifier.dart";
+import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
+import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
+import "package:photos/services/object_detection/tflite/scene_classifier.dart";
+import 'package:tflite_flutter/tflite_flutter.dart';
 
 
-// /// Manages separate Isolate instance for inference
-// class IsolateUtils {
-//   static const String debugName = "InferenceIsolate";
+/// Manages separate Isolate instance for inference
+class IsolateUtils {
+  static const String debugName = "InferenceIsolate";
 
 
-//   late SendPort _sendPort;
-//   final _receivePort = ReceivePort();
+  late SendPort _sendPort;
+  final _receivePort = ReceivePort();
 
 
-//   SendPort get sendPort => _sendPort;
+  SendPort get sendPort => _sendPort;
 
 
-//   Future<void> start() async {
-//     await Isolate.spawn<SendPort>(
-//       entryPoint,
-//       _receivePort.sendPort,
-//       debugName: debugName,
-//     );
+  Future<void> start() async {
+    await Isolate.spawn<SendPort>(
+      entryPoint,
+      _receivePort.sendPort,
+      debugName: debugName,
+    );
 
 
-//     _sendPort = await _receivePort.first;
-//   }
+    _sendPort = await _receivePort.first;
+  }
 
 
-//   static void entryPoint(SendPort sendPort) async {
-//     final port = ReceivePort();
-//     sendPort.send(port.sendPort);
+  static void entryPoint(SendPort sendPort) async {
+    final port = ReceivePort();
+    sendPort.send(port.sendPort);
 
 
-//     await for (final IsolateData isolateData in port) {
-//       final classifier = _getClassifier(isolateData);
-//       final image = imgLib.decodeImage(isolateData.input);
-//       try {
-//         final results = classifier.predict(image!);
-//         isolateData.responsePort.send(results);
-//       } catch (e) {
-//         isolateData.responsePort.send(Predictions(null, null, error: e));
-//       }
-//     }
-//   }
+    await for (final IsolateData isolateData in port) {
+      final classifier = _getClassifier(isolateData);
+      final image = imgLib.decodeImage(isolateData.input);
+      try {
+        final results = classifier.predict(image!);
+        isolateData.responsePort.send(results);
+      } catch (e) {
+        isolateData.responsePort.send(Predictions(null, null, error: e));
+      }
+    }
+  }
 
 
-//   static Classifier _getClassifier(IsolateData isolateData) {
-//     final interpreter = Interpreter.fromAddress(isolateData.interpreterAddress);
-//     if (isolateData.type == ClassifierType.cocossd) {
-//       return CocoSSDClassifier(
-//         interpreter: interpreter,
-//         labels: isolateData.labels,
-//       );
-//     } else if (isolateData.type == ClassifierType.mobilenet) {
-//       return MobileNetClassifier(
-//         interpreter: interpreter,
-//         labels: isolateData.labels,
-//       );
-//     } else {
-//       return SceneClassifier(
-//         interpreter: interpreter,
-//         labels: isolateData.labels,
-//       );
-//     }
-//   }
-// }
+  static Classifier _getClassifier(IsolateData isolateData) {
+    final interpreter = Interpreter.fromAddress(isolateData.interpreterAddress);
+    if (isolateData.type == ClassifierType.cocossd) {
+      return CocoSSDClassifier(
+        interpreter: interpreter,
+        labels: isolateData.labels,
+      );
+    } else if (isolateData.type == ClassifierType.mobilenet) {
+      return MobileNetClassifier(
+        interpreter: interpreter,
+        labels: isolateData.labels,
+      );
+    } else {
+      return SceneClassifier(
+        interpreter: interpreter,
+        labels: isolateData.labels,
+      );
+    }
+  }
+}
 
 
-// /// Bundles data to pass between Isolate
-// class IsolateData {
-//   Uint8List input;
-//   int interpreterAddress;
-//   List<String> labels;
-//   ClassifierType type;
-//   late SendPort responsePort;
+/// Bundles data to pass between Isolate
+class IsolateData {
+  Uint8List input;
+  int interpreterAddress;
+  List<String> labels;
+  ClassifierType type;
+  late SendPort responsePort;
 
 
-//   IsolateData(
-//     this.input,
-//     this.interpreterAddress,
-//     this.labels,
-//     this.type,
-//   );
-// }
+  IsolateData(
+    this.input,
+    this.interpreterAddress,
+    this.labels,
+    this.type,
+  );
+}
 
 
-// enum ClassifierType {
-//   cocossd,
-//   mobilenet,
-//   scenes,
-// }
+enum ClassifierType {
+  cocossd,
+  mobilenet,
+  scenes,
+}

+ 9 - 10
lib/ui/viewer/file/file_details_widget.dart

@@ -7,7 +7,7 @@ import 'package:photos/models/file/file.dart';
 import 'package:photos/models/file/file_type.dart';
 import 'package:photos/models/file/file_type.dart';
 import "package:photos/models/metadata/file_magic.dart";
 import "package:photos/models/metadata/file_magic.dart";
 import "package:photos/services/file_magic_service.dart";
 import "package:photos/services/file_magic_service.dart";
-// import "package:photos/services/update_service.dart";
+import "package:photos/services/update_service.dart";
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/components/buttons/icon_button_widget.dart';
 import 'package:photos/ui/components/buttons/icon_button_widget.dart';
 import "package:photos/ui/components/divider_widget.dart";
 import "package:photos/ui/components/divider_widget.dart";
@@ -20,7 +20,7 @@ import "package:photos/ui/viewer/file_details/creation_time_item_widget.dart";
 import 'package:photos/ui/viewer/file_details/exif_item_widgets.dart';
 import 'package:photos/ui/viewer/file_details/exif_item_widgets.dart';
 import "package:photos/ui/viewer/file_details/file_properties_item_widget.dart";
 import "package:photos/ui/viewer/file_details/file_properties_item_widget.dart";
 import "package:photos/ui/viewer/file_details/location_tags_widget.dart";
 import "package:photos/ui/viewer/file_details/location_tags_widget.dart";
-// import "package:photos/ui/viewer/file_details/objects_item_widget.dart";
+import "package:photos/ui/viewer/file_details/objects_item_widget.dart";
 import "package:photos/utils/exif_util.dart";
 import "package:photos/utils/exif_util.dart";
 
 
 class FileDetailsWidget extends StatefulWidget {
 class FileDetailsWidget extends StatefulWidget {
@@ -177,12 +177,12 @@ class _FileDetailsWidgetState extends State<FileDetailsWidget> {
       ]);
       ]);
     }
     }
 
 
-    // if (!UpdateService.instance.isFdroidFlavor()) {
-    //   fileDetailsTiles.addAll([
-    //     ObjectsItemWidget(file),
-    //     const FileDetailsDivider(),
-    //   ]);
-    // }
+    if (!UpdateService.instance.isFdroidFlavor()) {
+      fileDetailsTiles.addAll([
+        ObjectsItemWidget(file),
+        const FileDetailsDivider(),
+      ]);
+    }
 
 
     if (file.uploadedFileID != null && file.updationTime != null) {
     if (file.uploadedFileID != null && file.updationTime != null) {
       fileDetailsTiles.addAll(
       fileDetailsTiles.addAll(
@@ -280,8 +280,7 @@ class _FileDetailsWidgetState extends State<FileDetailsWidget> {
     if (imageWidth != null && imageLength != null) {
     if (imageWidth != null && imageLength != null) {
       _exifData["resolution"] = '$imageWidth x $imageLength';
       _exifData["resolution"] = '$imageWidth x $imageLength';
       final double megaPixels =
       final double megaPixels =
-          (imageWidth.values.firstAsInt() * imageLength.values.firstAsInt()) /
-              1000000;
+          (imageWidth.values.firstAsInt() * imageLength.values.firstAsInt()) / 1000000;
       final double roundedMegaPixels = (megaPixels * 10).round() / 10.0;
       final double roundedMegaPixels = (megaPixels * 10).round() / 10.0;
       _exifData['megaPixels'] = roundedMegaPixels..toStringAsFixed(1);
       _exifData['megaPixels'] = roundedMegaPixels..toStringAsFixed(1);
     } else {
     } else {

+ 62 - 62
lib/ui/viewer/file_details/objects_item_widget.dart

@@ -1,67 +1,67 @@
-// import "package:flutter/foundation.dart";
-// import "package:flutter/material.dart";
-// import "package:logging/logging.dart";
-// import "package:photos/generated/l10n.dart";
-// import 'package:photos/models/file/file.dart';
-// import "package:photos/services/object_detection/object_detection_service.dart";
-// import "package:photos/ui/components/buttons/chip_button_widget.dart";
-// import "package:photos/ui/components/info_item_widget.dart";
-// import "package:photos/utils/thumbnail_util.dart";
+import "package:flutter/foundation.dart";
+import "package:flutter/material.dart";
+import "package:logging/logging.dart";
+import "package:photos/generated/l10n.dart";
+import 'package:photos/models/file/file.dart';
+import "package:photos/services/object_detection/object_detection_service.dart";
+import "package:photos/ui/components/buttons/chip_button_widget.dart";
+import "package:photos/ui/components/info_item_widget.dart";
+import "package:photos/utils/thumbnail_util.dart";
 
 
-// class ObjectsItemWidget extends StatelessWidget {
-//   final EnteFile file;
-//   const ObjectsItemWidget(this.file, {super.key});
+class ObjectsItemWidget extends StatelessWidget {
+  final EnteFile file;
+  const ObjectsItemWidget(this.file, {super.key});
 
 
-//   @override
-//   Widget build(BuildContext context) {
-//     return InfoItemWidget(
-//       key: const ValueKey("Objects"),
-//       leadingIcon: Icons.image_search_outlined,
-//       subtitleSection: _objectTags(context, file),
-//       hasChipButtons: true,
-//     );
-//   }
+  @override
+  Widget build(BuildContext context) {
+    return InfoItemWidget(
+      key: const ValueKey("Objects"),
+      leadingIcon: Icons.image_search_outlined,
+      subtitleSection: _objectTags(context, file),
+      hasChipButtons: true,
+    );
+  }
 
 
-//   Future<List<ChipButtonWidget>> _objectTags(
-//     BuildContext context,
-//     EnteFile file,
-//   ) async {
-//     try {
-//       final chipButtons = <ChipButtonWidget>[];
-//       var objectTags = <String, double>{};
-//       final thumbnail = await getThumbnail(file);
-//       if (thumbnail != null) {
-//         objectTags = await ObjectDetectionService.instance.predict(thumbnail);
-//       }
-//       if (objectTags.isEmpty) {
-//         return [
-//           ChipButtonWidget(
-//             S.of(context).noResults,
-//             noChips: true,
-//           ),
-//         ];
-//       }
-//       // sort by values
-//       objectTags = Map.fromEntries(
-//         objectTags.entries.toList()
-//           ..sort((e1, e2) => e2.value.compareTo(e1.value)),
-//       );
+  Future<List<ChipButtonWidget>> _objectTags(
+    BuildContext context,
+    EnteFile file,
+  ) async {
+    try {
+      final chipButtons = <ChipButtonWidget>[];
+      var objectTags = <String, double>{};
+      final thumbnail = await getThumbnail(file);
+      if (thumbnail != null) {
+        objectTags = await ObjectDetectionService.instance.predict(thumbnail);
+      }
+      if (objectTags.isEmpty) {
+        return [
+          ChipButtonWidget(
+            S.of(context).noResults,
+            noChips: true,
+          ),
+        ];
+      }
+      // sort by values
+      objectTags = Map.fromEntries(
+        objectTags.entries.toList()
+          ..sort((e1, e2) => e2.value.compareTo(e1.value)),
+      );
 
 
-//       for (MapEntry<String, double> entry in objectTags.entries) {
-//         chipButtons.add(
-//           ChipButtonWidget(
-//             entry.key +
-//                 (kDebugMode
-//                     ? "-" + (entry.value * 100).round().toString()
-//                     : ""),
-//           ),
-//         );
-//       }
+      for (MapEntry<String, double> entry in objectTags.entries) {
+        chipButtons.add(
+          ChipButtonWidget(
+            entry.key +
+                (kDebugMode
+                    ? "-" + (entry.value * 100).round().toString()
+                    : ""),
+          ),
+        );
+      }
 
 
-//       return chipButtons;
-//     } catch (e, s) {
-//       Logger("ObjctsItemWidget").info(e, s);
-//       return [];
-//     }
-//   }
-// }
+      return chipButtons;
+    } catch (e, s) {
+      Logger("ObjctsItemWidget").info(e, s);
+      return [];
+    }
+  }
+}

+ 1 - 0
lib/utils/delete_file_util.dart

@@ -4,6 +4,7 @@ import 'dart:math';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
+import "package:path/path.dart";
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';

+ 64 - 23
pubspec.lock

@@ -193,6 +193,46 @@ packages:
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.0.2"
     version: "1.0.2"
+  camera:
+    dependency: transitive
+    description:
+      name: camera
+      sha256: "3ad71371b8168a4c8012c0b40a53c05afc75d46cc688b0f37b4611a841d47b25"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.8+1"
+  camera_android:
+    dependency: transitive
+    description:
+      name: camera_android
+      sha256: "665d62c1f334722c7519ca5d3b94ad68ecaa801691870602da5638a42c1fff67"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.8+3"
+  camera_avfoundation:
+    dependency: transitive
+    description:
+      name: camera_avfoundation
+      sha256: "1a416e452b30955b392f4efbf23291d3f2ba3660a85e1628859eb62d2a2bab26"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.13+2"
+  camera_platform_interface:
+    dependency: transitive
+    description:
+      name: camera_platform_interface
+      sha256: "60fa0bb62a4f3bf3a7c413e31e4cd01b69c779ccc8e4668904a24581b86c316b"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.5.1"
+  camera_web:
+    dependency: transitive
+    description:
+      name: camera_web
+      sha256: "18cdbee5441e9a6fb129fdd9b68a06d1b8c5236932ba97d5faeaefe80db2e5bd"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.2.1+6"
   characters:
   characters:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -218,14 +258,6 @@ packages:
       url: "https://github.com/ente-io/chewie.git"
       url: "https://github.com/ente-io/chewie.git"
     source: git
     source: git
     version: "1.7.0"
     version: "1.7.0"
-  cli_util:
-    dependency: transitive
-    description:
-      name: cli_util
-      sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.4.0"
   clock:
   clock:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -631,13 +663,13 @@ packages:
     source: hosted
     source: hosted
     version: "5.7.2+3"
     version: "5.7.2+3"
   flutter_launcher_icons:
   flutter_launcher_icons:
-    dependency: "direct dev"
+    dependency: "direct main"
     description:
     description:
       name: flutter_launcher_icons
       name: flutter_launcher_icons
-      sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
+      sha256: "559c600f056e7c704bd843723c21e01b5fba47e8824bd02422165bcc02a5de1d"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "0.13.1"
+    version: "0.9.3"
   flutter_lints:
   flutter_lints:
     dependency: "direct dev"
     dependency: "direct dev"
     description:
     description:
@@ -703,10 +735,10 @@ packages:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
       name: flutter_native_splash
       name: flutter_native_splash
-      sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698
+      sha256: "6777a3abb974021a39b5fdd2d46a03ca390e03903b6351f21d10e7ecc969f12d"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "2.3.2"
+    version: "2.2.16"
   flutter_password_strength:
   flutter_password_strength:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -878,10 +910,10 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: html
       name: html
-      sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
+      sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "0.15.4"
+    version: "0.15.3"
   http:
   http:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -918,10 +950,10 @@ packages:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
       name: image
       name: image
-      sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
+      sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "4.0.17"
+    version: "3.3.0"
   image_editor:
   image_editor:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -1365,10 +1397,10 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: petitparser
       name: petitparser
-      sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
+      sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "5.4.0"
+    version: "5.1.0"
   photo_manager:
   photo_manager:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -1854,6 +1886,15 @@ packages:
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "0.9.1"
     version: "0.9.1"
+  tflite_flutter_helper:
+    dependency: "direct main"
+    description:
+      path: "."
+      ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
+      resolved-ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
+      url: "https://github.com/elephantum/tflite_flutter_helper.git"
+    source: git
+    version: "0.3.0"
   timezone:
   timezone:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1922,10 +1963,10 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: universal_io
       name: universal_io
-      sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
+      sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "2.2.2"
+    version: "2.2.0"
   url_launcher:
   url_launcher:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -2171,10 +2212,10 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: xml
       name: xml
-      sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
+      sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "6.3.0"
+    version: "6.2.2"
   xmlstream:
   xmlstream:
     dependency: transitive
     dependency: transitive
     description:
     description:

+ 16 - 18
pubspec.yaml

@@ -65,12 +65,13 @@ dependencies:
   flutter_email_sender: ^5.2.0
   flutter_email_sender: ^5.2.0
   flutter_image_compress: ^1.1.0
   flutter_image_compress: ^1.1.0
   flutter_inappwebview: ^5.5.0+2
   flutter_inappwebview: ^5.5.0+2
+  flutter_launcher_icons: ^0.9.3
   flutter_local_notifications: ^12.0.4
   flutter_local_notifications: ^12.0.4
   flutter_localizations:
   flutter_localizations:
     sdk: flutter
     sdk: flutter
   flutter_map: ^4.0.0
   flutter_map: ^4.0.0
   flutter_map_marker_cluster: ^1.1.1
   flutter_map_marker_cluster: ^1.1.1
-  flutter_native_splash: ^2.3.1
+  flutter_native_splash: ^2.2.0+1
   flutter_password_strength: ^0.1.6
   flutter_password_strength: ^0.1.6
   flutter_secure_storage: ^8.0.0
   flutter_secure_storage: ^8.0.0
   flutter_sodium: ^0.2.0
   flutter_sodium: ^0.2.0
@@ -79,7 +80,7 @@ dependencies:
   freezed_annotation: ^2.2.0
   freezed_annotation: ^2.2.0
   google_nav_bar: ^5.0.5
   google_nav_bar: ^5.0.5
   http: ^0.13.4
   http: ^0.13.4
-  image: ^4.0.17
+  image: ^3.0.2
   image_editor: ^1.3.0
   image_editor: ^1.3.0
   in_app_purchase: ^3.0.7
   in_app_purchase: ^3.0.7
   intl: ^0.18.0
   intl: ^0.18.0
@@ -127,10 +128,10 @@ dependencies:
   syncfusion_flutter_core: ^19.2.49
   syncfusion_flutter_core: ^19.2.49
   syncfusion_flutter_sliders: ^19.2.49
   syncfusion_flutter_sliders: ^19.2.49
   tflite_flutter: ^0.9.0
   tflite_flutter: ^0.9.0
-  # tflite_flutter_helper:
-  #   git:
-  #     url: https://github.com/elephantum/tflite_flutter_helper.git  # Fixes https://github.com/am15h/tflite_flutter_helper/issues/57
-  #     ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
+  tflite_flutter_helper:
+    git:
+      url: https://github.com/elephantum/tflite_flutter_helper.git  # Fixes https://github.com/am15h/tflite_flutter_helper/issues/57
+      ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
   tuple: ^2.0.0
   tuple: ^2.0.0
   uni_links: ^0.5.1
   uni_links: ^0.5.1
   url_launcher: ^6.0.3
   url_launcher: ^6.0.3
@@ -167,7 +168,6 @@ dev_dependencies:
   build_runner: ^2.3.3
   build_runner: ^2.3.3
   flutter_driver:
   flutter_driver:
     sdk: flutter
     sdk: flutter
-  flutter_launcher_icons: ^0.13.1
   flutter_lints: ^2.0.1
   flutter_lints: ^2.0.1
   flutter_test:
   flutter_test:
     sdk: flutter
     sdk: flutter
@@ -177,20 +177,18 @@ dev_dependencies:
   json_serializable: ^6.6.1
   json_serializable: ^6.6.1
   test: ^1.22.0
   test: ^1.22.0
 
 
-flutter_launcher_icons:
-  android: true
-  ios: true
-  image_path: "assets/launcher_icon/icon.png"
-  adaptive_icon_foreground: "assets/launcher_icon/adaptive_icon.png"
+flutter_icons:
+  android: "launcher_icon"
+  adaptive_icon_foreground: "assets/launcher_icon/ente-icon-foreground.png"
   adaptive_icon_background: "#ffffff"
   adaptive_icon_background: "#ffffff"
-  remove_alpha_ios: true
-  min_sdk_android: 21
+  ios: true
+  image_path: "assets/icon-light.png"
 
 
 flutter_native_splash:
 flutter_native_splash:
   color: "#ffffff"
   color: "#ffffff"
   color_dark: "#000000"
   color_dark: "#000000"
-  image: assets/splash-icon-light.png
-  image_dark: assets/splash-icon-dark.png
+  image: assets/splash-screen-light.png
+  image_dark: assets/splash-screen-dark.png
   android_fullscreen: true
   android_fullscreen: true
   android_gravity: center
   android_gravity: center
   ios_content_mode: center
   ios_content_mode: center
@@ -200,8 +198,8 @@ flutter_native_splash:
     # Please note that the splash screen will be clipped to a circle on the center of the screen.
     # Please note that the splash screen will be clipped to a circle on the center of the screen.
     # App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
     # App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
     # 768 pixels in diameter.
     # 768 pixels in diameter.
-    image: assets/splash-icon-light.png
-    image_dark: assets/splash-icon-dark.png
+    image: assets/splash-screen-light.png
+    image_dark: assets/splash-screen-dark.png
 
 
 # For information on the generic Dart part of this file, see the
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
 # following page: https://dart.dev/tools/pub/pubspec