summaryrefslogtreecommitdiff
path: root/src/faces/FaceDetect.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/faces/FaceDetect.vala')
-rw-r--r--src/faces/FaceDetect.vala146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/faces/FaceDetect.vala b/src/faces/FaceDetect.vala
new file mode 100644
index 0000000..83caa4d
--- /dev/null
+++ b/src/faces/FaceDetect.vala
@@ -0,0 +1,146 @@
+/**
+ * Face detection and recognition functions
+ * Copyright 2018 Narendra A (narendra_m_a(at)yahoo(dot)com)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// DBus face_detect_proxy definition
+public struct FaceRect {
+ public double x;
+ public double y;
+ public double width;
+ public double height;
+ public double[] vec;
+}
+
+[DBus (name = "org.gnome.Shotwell.Faces1")]
+public interface FaceDetectInterface : DBusProxy {
+ public abstract FaceRect[] detect_faces(string inputName, string cascadeName, double scale, bool infer)
+ throws IOError, DBusError;
+ public abstract bool load_net(string netFile)
+ throws IOError, DBusError;
+ public abstract void terminate() throws IOError, DBusError;
+}
+
+// Class to communicate with facedetect process over DBus
+public class FaceDetect {
+ public const string DBUS_NAME = "org.gnome.Shotwell.Faces1";
+ public const string DBUS_PATH = "/org/gnome/shotwell/faces";
+ public static bool connected = false;
+ public static string net_file;
+ public const string ERROR_MESSAGE = "Unable to connect to facedetect service";
+
+ public static FaceDetectInterface face_detect_proxy;
+
+#if FACEDETECT_BUS_PRIVATE
+ private static GLib.DBusServer dbus_server;
+ private static Subprocess process;
+#endif
+
+ public static void create_face_detect_proxy(DBusConnection connection, string bus_name, string owner) {
+ if (bus_name == DBUS_NAME) {
+ message("Dbus name %s available", bus_name);
+
+ try {
+ // Service file should automatically run the facedetect binary
+ face_detect_proxy = Bus.get_proxy_sync (BusType.SESSION, DBUS_NAME, DBUS_PATH);
+ face_detect_proxy.load_net(net_file);
+ connected = true;
+ } catch(IOError e) {
+ AppWindow.error_message(ERROR_MESSAGE);
+ } catch(DBusError e) {
+ AppWindow.error_message(ERROR_MESSAGE);
+ }
+ }
+ }
+
+ public static void interface_gone(DBusConnection connection, string bus_name) {
+ message("Dbus name %s gone", bus_name);
+ connected = false;
+ face_detect_proxy = null;
+ }
+
+#if FACEDETECT_BUS_PRIVATE
+ private static bool on_new_connection(DBusServer server, DBusConnection connection) {
+ try {
+ face_detect_proxy = connection.get_proxy_sync(null, DBUS_PATH,
+ DBusProxyFlags.DO_NOT_LOAD_PROPERTIES
+ | DBusProxyFlags.DO_NOT_CONNECT_SIGNALS,
+ null);
+ Idle.add(() => {
+ try {
+ face_detect_proxy.load_net(net_file);
+ connected = true;
+ } catch (Error error) {
+ critical("Failed to call load_net: %s", error.message);
+ AppWindow.error_message(ERROR_MESSAGE);
+ }
+ return false;
+ });
+
+ return true;
+ } catch (Error error) {
+ critical("Failed to create face_detect_proxy for face detect: %s", error.message);
+ AppWindow.error_message(ERROR_MESSAGE);
+
+ return false;
+ }
+ }
+#endif
+
+ public static void init(string net_file) {
+ FaceDetect.net_file = net_file;
+#if FACEDETECT_BUS_PRIVATE
+ var address = "unix:tmpdir=%s".printf(Environment.get_tmp_dir());
+ var observer = new DBusAuthObserver();
+ observer.authorize_authenticated_peer.connect((stream, credentials) => {
+ debug("Observer trying to authorize for %s", credentials.to_string());
+ if (credentials == null)
+ return false;
+
+ try {
+ if (!credentials.is_same_user(new Credentials()))
+ return false;
+ return true;
+ } catch (Error error) {
+ return false;
+ }
+ });
+
+ try {
+ dbus_server = new GLib.DBusServer.sync(address, DBusServerFlags.NONE, DBus.generate_guid(), observer, null);
+ dbus_server.new_connection.connect(on_new_connection);
+ dbus_server.start();
+ process = new Subprocess(SubprocessFlags.NONE, AppDirs.get_facedetect_bin().get_path(),
+ "--address=" + dbus_server.get_client_address());
+
+ } catch (Error error) {
+ warning("Failed to create private DBus server: %s", error.message);
+ AppWindow.error_message(ERROR_MESSAGE);
+ }
+#else
+ Bus.watch_name(BusType.SESSION, DBUS_NAME, BusNameWatcherFlags.NONE,
+ create_face_detect_proxy, interface_gone);
+#endif
+ }
+
+}