From fd2875aa3ea340a554b36d6abfb4764c29c5655a Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 6 Jun 2020 23:04:26 -0700 Subject: [PATCH] examples: add img-capture example This one can be useful in scripts, e.g. for building fingerprint dataset. --- examples/img-capture.c | 185 +++++++++++++++++++++++++++++++++++++++++ examples/meson.build | 2 +- examples/storage.c | 2 +- examples/storage.h | 2 + 4 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 examples/img-capture.c diff --git a/examples/img-capture.c b/examples/img-capture.c new file mode 100644 index 0000000..780c5d7 --- /dev/null +++ b/examples/img-capture.c @@ -0,0 +1,185 @@ +/* + * Example fingerprint verification program, which verifies the + * finger which has been previously enrolled to disk. + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2019 Marco Trevisan + * Copyright (C) 2020 Vasily Khoruzhick + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FP_COMPONENT "example-capture" + +#include +#include +#include + +#include "storage.h" +#include "utilities.h" + +typedef struct CaptureData +{ + GMainLoop *loop; + GCancellable *cancellable; + unsigned int sigint_handler; + int ret_value; + const char *filename; +} CaptureData; + +static void +capture_data_free (CaptureData *capture_data) +{ + g_clear_handle_id (&capture_data->sigint_handler, g_source_remove); + g_clear_object (&capture_data->cancellable); + g_main_loop_unref (capture_data->loop); + g_free (capture_data); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC (CaptureData, capture_data_free) + +static void +on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) +{ + CaptureData *capture_data = user_data; + + g_autoptr(GError) error = NULL; + + fp_device_close_finish (dev, res, &error); + + if (error) + g_warning ("Failed closing device %s\n", error->message); + + g_main_loop_quit (capture_data->loop); +} + +static void +capture_quit (FpDevice *dev, + CaptureData *capture_data) +{ + if (!fp_device_is_open (dev)) + { + g_main_loop_quit (capture_data->loop); + return; + } + + fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, capture_data); +} + +static void +dev_capture_cb (FpDevice *dev, + GAsyncResult *res, + void *user_data) +{ + g_autoptr(GError) error = NULL; + CaptureData *capture_data = user_data; + FpImage *image = NULL; + + g_clear_object (&capture_data->cancellable); + + image = fp_device_capture_finish (dev, res, &error); + if (!image) + { + g_warning ("Error capturing data: %s", error->message); + capture_quit (dev, capture_data); + return; + } + + save_image_to_pgm (image, capture_data->filename); + + capture_quit (dev, capture_data); +} + +static void +start_capture (FpDevice *dev, CaptureData *capture_data) +{ + fp_device_capture (dev, TRUE, capture_data->cancellable, (GAsyncReadyCallback) dev_capture_cb, capture_data); +} + +static void +on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data) +{ + CaptureData *capture_data = user_data; + + g_autoptr(GError) error = NULL; + + if (!fp_device_open_finish (dev, res, &error)) + { + g_warning ("Failed to open device: %s", error->message); + capture_quit (dev, capture_data); + return; + } + + g_print ("Opened device. "); + + start_capture (dev, capture_data); +} + +static gboolean +sigint_cb (void *user_data) +{ + CaptureData *capture_data = user_data; + + g_cancellable_cancel (capture_data->cancellable); + + return G_SOURCE_CONTINUE; +} + +int +main (int argc, const char *argv[]) +{ + g_autoptr(FpContext) ctx = NULL; + g_autoptr(CaptureData) capture_data = NULL; + GPtrArray *devices; + FpDevice *dev; + + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + + ctx = fp_context_new (); + + devices = fp_context_get_devices (ctx); + if (!devices) + { + g_warning ("Impossible to get devices"); + return EXIT_FAILURE; + } + + dev = discover_device (devices); + if (!dev) + { + g_warning ("No devices detected."); + return EXIT_FAILURE; + } + + capture_data = g_new0 (CaptureData, 1); + capture_data->ret_value = EXIT_FAILURE; + capture_data->loop = g_main_loop_new (NULL, FALSE); + capture_data->cancellable = g_cancellable_new (); + capture_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH, + SIGINT, + sigint_cb, + capture_data, + NULL); + if (argc == 2) + capture_data->filename = argv[1]; + else + capture_data->filename = "finger.pgm"; + fp_device_open (dev, capture_data->cancellable, + (GAsyncReadyCallback) on_device_opened, + capture_data); + + g_main_loop_run (capture_data->loop); + + return capture_data->ret_value; +} diff --git a/examples/meson.build b/examples/meson.build index 90a1178..a0ea9ec 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,5 +1,5 @@ -examples = [ 'enroll', 'verify', 'manage-prints' ] +examples = [ 'enroll', 'verify', 'manage-prints', 'img-capture' ] foreach example: examples executable(example, [ example + '.c', 'storage.c', 'utilities.c' ], diff --git a/examples/storage.c b/examples/storage.c index ebffb33..4cccea2 100644 --- a/examples/storage.c +++ b/examples/storage.c @@ -180,7 +180,7 @@ print_create_template (FpDevice *dev, FpFinger finger) } -static gboolean +gboolean save_image_to_pgm (FpImage *img, const char *path) { FILE *fd = fopen (path, "w"); diff --git a/examples/storage.h b/examples/storage.h index 6c6c220..0cc8269 100644 --- a/examples/storage.h +++ b/examples/storage.h @@ -28,3 +28,5 @@ FpPrint * print_create_template (FpDevice *dev, FpFinger finger); gboolean print_image_save (FpPrint *print, const char *path); +gboolean save_image_to_pgm (FpImage *img, + const char *path);