diff options
Diffstat (limited to 'src/faces/FaceDetect.vala')
-rw-r--r-- | src/faces/FaceDetect.vala | 146 |
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 + } + +} |