From d7100e41df96d3f6f4929296a2c30503d648e0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 11 Dec 2019 19:55:47 +0100 Subject: [PATCH] fp-image, fp-print: Move private methods to own code units --- libfprint/fp-image.c | 128 +----------------- libfprint/fp-print-private.h | 46 +++++++ libfprint/fp-print.c | 247 +--------------------------------- libfprint/fpi-image.c | 150 +++++++++++++++++++++ libfprint/fpi-print.c | 249 +++++++++++++++++++++++++++++++++++ libfprint/meson.build | 2 + 6 files changed, 452 insertions(+), 370 deletions(-) create mode 100644 libfprint/fp-print-private.h create mode 100644 libfprint/fpi-image.c create mode 100644 libfprint/fpi-print.c diff --git a/libfprint/fp-image.c b/libfprint/fp-image.c index 16837a8..ac70d68 100644 --- a/libfprint/fp-image.c +++ b/libfprint/fp-image.c @@ -18,15 +18,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define FP_COMPONENT "image" + #include "fpi-image.h" #include "fpi-log.h" #include -#if HAVE_PIXMAN -#include -#endif - /** * SECTION: fp-image * @title: FpImage @@ -36,15 +34,6 @@ * this object allows accessing this data. */ -/** - * SECTION: fpi-image - * @title: Internal FpImage - * @short_description: Internal image handling routines - * - * Internal image handling routines. Also see the public FpImage routines. - */ - G_DEFINE_TYPE (FpImage, fp_image, G_TYPE_OBJECT) enum { @@ -479,78 +468,6 @@ fp_image_detect_minutiae_finish (FpImage *self, return g_task_propagate_boolean (G_TASK (result), error); } - - -/** - * fpi_std_sq_dev: - * @buf: buffer (usually bitmap, one byte per pixel) - * @size: size of @buffer - * - * Calculates the squared standard deviation of the individual - * pixels in the buffer, as per the following formula: - * |[ - * mean = sum (buf[0..size]) / size - * sq_dev = sum ((buf[0.size] - mean) ^ 2) - * ]| - * This function is usually used to determine whether image - * is empty. - * - * Returns: the squared standard deviation for @buffer - */ -gint -fpi_std_sq_dev (const guint8 *buf, - gint size) -{ - guint64 res = 0, mean = 0; - gint i; - - for (i = 0; i < size; i++) - mean += buf[i]; - - mean /= size; - - for (i = 0; i < size; i++) - { - int dev = (int) buf[i] - mean; - res += dev * dev; - } - - return res / size; -} - -/** - * fpi_mean_sq_diff_norm: - * @buf1: buffer (usually bitmap, one byte per pixel) - * @buf2: buffer (usually bitmap, one byte per pixel) - * @size: buffer size of smallest buffer - * - * This function calculates the normalized mean square difference of - * two buffers, usually two lines, as per the following formula: - * |[ - * sq_diff = sum ((buf1[0..size] - buf2[0..size]) ^ 2) / size - * ]| - * - * This functions is usually used to get numerical difference - * between two images. - * - * Returns: the normalized mean squared difference between @buf1 and @buf2 - */ -gint -fpi_mean_sq_diff_norm (const guint8 *buf1, - const guint8 *buf2, - gint size) -{ - int res = 0, i; - - for (i = 0; i < size; i++) - { - int dev = (int) buf1[i] - (int) buf2[i]; - res += dev * dev; - } - - return res / size; -} - /** * fp_minutia_get_coords: * @min: A #FpMinutia @@ -568,44 +485,3 @@ fp_minutia_get_coords (FpMinutia *min, gint *x, gint *y) if (y) *y = min->y; } - -#if HAVE_PIXMAN -FpImage * -fpi_image_resize (FpImage *orig_img, - guint w_factor, - guint h_factor) -{ - int new_width = orig_img->width * w_factor; - int new_height = orig_img->height * h_factor; - pixman_image_t *orig, *resized; - pixman_transform_t transform; - FpImage *newimg; - - orig = pixman_image_create_bits (PIXMAN_a8, orig_img->width, orig_img->height, (uint32_t *) orig_img->data, orig_img->width); - resized = pixman_image_create_bits (PIXMAN_a8, new_width, new_height, NULL, new_width); - - pixman_transform_init_identity (&transform); - pixman_transform_scale (NULL, &transform, pixman_int_to_fixed (w_factor), pixman_int_to_fixed (h_factor)); - pixman_image_set_transform (orig, &transform); - pixman_image_set_filter (orig, PIXMAN_FILTER_BILINEAR, NULL, 0); - pixman_image_composite32 (PIXMAN_OP_SRC, - orig, /* src */ - NULL, /* mask */ - resized, /* dst */ - 0, 0, /* src x y */ - 0, 0, /* mask x y */ - 0, 0, /* dst x y */ - new_width, new_height /* width height */ - ); - - newimg = fp_image_new (new_width, new_height); - newimg->flags = orig_img->flags; - - memcpy (newimg->data, pixman_image_get_data (resized), new_width * new_height); - - pixman_image_unref (orig); - pixman_image_unref (resized); - - return newimg; -} -#endif diff --git a/libfprint/fp-print-private.h b/libfprint/fp-print-private.h new file mode 100644 index 0000000..f5822b3 --- /dev/null +++ b/libfprint/fp-print-private.h @@ -0,0 +1,46 @@ +/* + * FPrint Print handling + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2019 Benjamin Berg + * + * 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 + */ + +#include "fpi-print.h" +#include "fpi-image.h" + +#include + +struct _FpPrint +{ + GInitiallyUnowned parent_instance; + + FpPrintType type; + + gchar *driver; + gchar *device_id; + gboolean device_stored; + + FpImage *image; + + /* Metadata */ + FpFinger finger; + gchar *username; + gchar *description; + GDate *enroll_date; + + GVariant *data; + GPtrArray *prints; +}; diff --git a/libfprint/fp-print.c b/libfprint/fp-print.c index f724c77..30fdf1a 100644 --- a/libfprint/fp-print.c +++ b/libfprint/fp-print.c @@ -18,12 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "fpi-print.h" -#include "fpi-image.h" -#include "fpi-log.h" -#include "fpi-device.h" +#define FP_COMPONENT "print" -#include +#include "fp-print-private.h" +#include "fpi-log.h" /** * SECTION: fp-print @@ -42,28 +40,6 @@ * #FpPrint routines. */ -struct _FpPrint -{ - GInitiallyUnowned parent_instance; - - FpPrintType type; - - gchar *driver; - gchar *device_id; - gboolean device_stored; - - FpImage *image; - - /* Metadata */ - FpFinger finger; - gchar *username; - gchar *description; - GDate *enroll_date; - - GVariant *data; - GPtrArray *prints; -}; - G_DEFINE_TYPE (FpPrint, fp_print, G_TYPE_INITIALLY_UNOWNED) enum { @@ -540,223 +516,6 @@ fp_print_set_enroll_date (FpPrint *print, g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_ENROLL_DATE]); } - - -/** - * fpi_print_add_print: - * @print: A #FpPrint - * @add: Print to append to @print - * - * Appends the single #FP_PRINT_NBIS print from @add to the collection of - * prints in @print. Both print objects need to be of type #FP_PRINT_NBIS - * for this to work. - */ -void -fpi_print_add_print (FpPrint *print, FpPrint *add) -{ - g_return_if_fail (print->type == FP_PRINT_NBIS); - g_return_if_fail (add->type == FP_PRINT_NBIS); - - g_assert (add->prints->len == 1); - g_ptr_array_add (print->prints, g_memdup (add->prints->pdata[0], sizeof (struct xyt_struct))); -} - -/** - * fpi_print_set_type: - * @print: A #FpPrint - * @type: The newly type of the print data - * - * This function can only be called exactly once. Drivers should - * call it after creating a new print, or to initialize the template - * print passed during enrollment. - */ -void -fpi_print_set_type (FpPrint *print, - FpPrintType type) -{ - g_return_if_fail (FP_IS_PRINT (print)); - /* We only allow setting this once! */ - g_return_if_fail (print->type == FP_PRINT_UNDEFINED); - - print->type = type; - if (print->type == FP_PRINT_NBIS) - { - g_assert_null (print->prints); - print->prints = g_ptr_array_new_with_free_func (g_free); - } - g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_FPI_TYPE]); -} - -/** - * fpi_print_set_device_stored: - * @print: A #FpPrint - * @device_stored: Whether the print is stored on the device or not - * - * Drivers must set this to %TRUE for any print that is really a handle - * for data that is stored on the device itself. - */ -void -fpi_print_set_device_stored (FpPrint *print, - gboolean device_stored) -{ - g_return_if_fail (FP_IS_PRINT (print)); - - print->device_stored = device_stored; - g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_DEVICE_STORED]); -} - -/* XXX: This is the old version, but wouldn't it be smarter to instead - * use the highest quality mintutiae? Possibly just using bz_prune from - * upstream? */ -static void -minutiae_to_xyt (struct fp_minutiae *minutiae, - int bwidth, - int bheight, - struct xyt_struct *xyt) -{ - int i; - struct fp_minutia *minutia; - struct minutiae_struct c[MAX_FILE_MINUTIAE]; - - /* struct xyt_struct uses arrays of MAX_BOZORTH_MINUTIAE (200) */ - int nmin = min (minutiae->num, MAX_BOZORTH_MINUTIAE); - - for (i = 0; i < nmin; i++) - { - minutia = minutiae->list[i]; - - lfs2nist_minutia_XYT (&c[i].col[0], &c[i].col[1], &c[i].col[2], - minutia, bwidth, bheight); - c[i].col[3] = sround (minutia->reliability * 100.0); - - if (c[i].col[2] > 180) - c[i].col[2] -= 360; - } - - qsort ((void *) &c, (size_t) nmin, sizeof (struct minutiae_struct), - sort_x_y); - - for (i = 0; i < nmin; i++) - { - xyt->xcol[i] = c[i].col[0]; - xyt->ycol[i] = c[i].col[1]; - xyt->thetacol[i] = c[i].col[2]; - } - xyt->nrows = nmin; -} - -/** - * fpi_print_add_from_image: - * @print: A #FpPrint - * @image: A #FpImage - * @error: Return location for error - * - * Extracts the minutiae from the given image and adds it to @print of - * type #FP_PRINT_NBIS. - * - * The @image will be kept so that API users can get retrieve it e.g. - * for debugging purposes. - * - * Returns: %TRUE on success - */ -gboolean -fpi_print_add_from_image (FpPrint *print, - FpImage *image, - GError **error) -{ - GPtrArray *minutiae; - struct fp_minutiae _minutiae; - struct xyt_struct *xyt; - - if (print->type != FP_PRINT_NBIS || !image) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_DATA, - "Cannot add print data from image!"); - return FALSE; - } - - minutiae = fp_image_get_minutiae (image); - if (!minutiae || minutiae->len == 0) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_DATA, - "No minutiae found in image or not yet detected!"); - return FALSE; - } - - _minutiae.num = minutiae->len; - _minutiae.list = (struct fp_minutia **) minutiae->pdata; - _minutiae.alloc = minutiae->len; - - xyt = g_new0 (struct xyt_struct, 1); - minutiae_to_xyt (&_minutiae, image->width, image->height, xyt); - g_ptr_array_add (print->prints, xyt); - - g_clear_object (&print->image); - print->image = g_object_ref (image); - g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_IMAGE]); - - return TRUE; -} - -/** - * fpi_print_bz3_match: - * @template: A #FpPrint containing one or more prints - * @print: A newly scanned #FpPrint to test - * @bz3_threshold: The BZ3 match threshold - * @error: Return location for error - * - * Match the newly scanned @print (containing exactly one print) against the - * prints contained in @template which will have been stored during enrollment. - * - * Both @template and @print need to be of type #FP_PRINT_NBIS for this to - * work. - * - * Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned - */ -FpiMatchResult -fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GError **error) -{ - struct xyt_struct *pstruct; - gint probe_len; - gint i; - - /* XXX: Use a different error type? */ - if (template->type != FP_PRINT_NBIS || print->type != FP_PRINT_NBIS) - { - *error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED, - "It is only possible to match NBIS type print data"); - return FPI_MATCH_ERROR; - } - - if (print->prints->len != 1) - { - *error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, - "New print contains more than one print!"); - return FPI_MATCH_ERROR; - } - - pstruct = g_ptr_array_index (print->prints, 0); - probe_len = bozorth_probe_init (pstruct); - - for (i = 0; i < template->prints->len; i++) - { - struct xyt_struct *gstruct; - gint score; - gstruct = g_ptr_array_index (template->prints, i); - score = bozorth_to_gallery (probe_len, pstruct, gstruct); - fp_dbg ("score %d", score); - - if (score >= bz3_threshold) - return FPI_MATCH_SUCCESS; - } - - return FPI_MATCH_FAIL; -} - /** * fp_print_compatible: * @self: A #FpPrint diff --git a/libfprint/fpi-image.c b/libfprint/fpi-image.c new file mode 100644 index 0000000..8344037 --- /dev/null +++ b/libfprint/fpi-image.c @@ -0,0 +1,150 @@ +/* + * FPrint Image - Private APIs + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2019 Benjamin Berg + * + * 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 "image" + +#include "fpi-image.h" +#include "fpi-log.h" + +#include + +#if HAVE_PIXMAN +#include +#endif + +/** + * SECTION: fpi-image + * @title: Internal FpImage + * @short_description: Internal image handling routines + * + * Internal image handling routines. Also see the public FpImage routines. + */ + +/** + * fpi_std_sq_dev: + * @buf: buffer (usually bitmap, one byte per pixel) + * @size: size of @buffer + * + * Calculates the squared standard deviation of the individual + * pixels in the buffer, as per the following formula: + * |[ + * mean = sum (buf[0..size]) / size + * sq_dev = sum ((buf[0.size] - mean) ^ 2) + * ]| + * This function is usually used to determine whether image + * is empty. + * + * Returns: the squared standard deviation for @buffer + */ +gint +fpi_std_sq_dev (const guint8 *buf, + gint size) +{ + guint64 res = 0, mean = 0; + gint i; + + for (i = 0; i < size; i++) + mean += buf[i]; + + mean /= size; + + for (i = 0; i < size; i++) + { + int dev = (int) buf[i] - mean; + res += dev * dev; + } + + return res / size; +} + +/** + * fpi_mean_sq_diff_norm: + * @buf1: buffer (usually bitmap, one byte per pixel) + * @buf2: buffer (usually bitmap, one byte per pixel) + * @size: buffer size of smallest buffer + * + * This function calculates the normalized mean square difference of + * two buffers, usually two lines, as per the following formula: + * |[ + * sq_diff = sum ((buf1[0..size] - buf2[0..size]) ^ 2) / size + * ]| + * + * This functions is usually used to get numerical difference + * between two images. + * + * Returns: the normalized mean squared difference between @buf1 and @buf2 + */ +gint +fpi_mean_sq_diff_norm (const guint8 *buf1, + const guint8 *buf2, + gint size) +{ + int res = 0, i; + + for (i = 0; i < size; i++) + { + int dev = (int) buf1[i] - (int) buf2[i]; + res += dev * dev; + } + + return res / size; +} + +#if HAVE_PIXMAN +FpImage * +fpi_image_resize (FpImage *orig_img, + guint w_factor, + guint h_factor) +{ + int new_width = orig_img->width * w_factor; + int new_height = orig_img->height * h_factor; + pixman_image_t *orig, *resized; + pixman_transform_t transform; + FpImage *newimg; + + orig = pixman_image_create_bits (PIXMAN_a8, orig_img->width, orig_img->height, (uint32_t *) orig_img->data, orig_img->width); + resized = pixman_image_create_bits (PIXMAN_a8, new_width, new_height, NULL, new_width); + + pixman_transform_init_identity (&transform); + pixman_transform_scale (NULL, &transform, pixman_int_to_fixed (w_factor), pixman_int_to_fixed (h_factor)); + pixman_image_set_transform (orig, &transform); + pixman_image_set_filter (orig, PIXMAN_FILTER_BILINEAR, NULL, 0); + pixman_image_composite32 (PIXMAN_OP_SRC, + orig, /* src */ + NULL, /* mask */ + resized, /* dst */ + 0, 0, /* src x y */ + 0, 0, /* mask x y */ + 0, 0, /* dst x y */ + new_width, new_height /* width height */ + ); + + newimg = fp_image_new (new_width, new_height); + newimg->flags = orig_img->flags; + + memcpy (newimg->data, pixman_image_get_data (resized), new_width * new_height); + + pixman_image_unref (orig); + pixman_image_unref (resized); + + return newimg; +} +#endif diff --git a/libfprint/fpi-print.c b/libfprint/fpi-print.c new file mode 100644 index 0000000..a407dd9 --- /dev/null +++ b/libfprint/fpi-print.c @@ -0,0 +1,249 @@ +/* + * FPrint Print handling - Private APIs + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2019 Benjamin Berg + * + * 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 "print" +#include "fpi-log.h" + +#include "fp-print-private.h" +#include "fpi-device.h" + +/** + * SECTION: fpi-print + * @title: Internal FpPrint + * @short_description: Internal fingerprint handling routines + * + * Interaction with prints and their storage. See also the public + * #FpPrint routines. + */ + +/** + * fpi_print_add_print: + * @print: A #FpPrint + * @add: Print to append to @print + * + * Appends the single #FP_PRINT_NBIS print from @add to the collection of + * prints in @print. Both print objects need to be of type #FP_PRINT_NBIS + * for this to work. + */ +void +fpi_print_add_print (FpPrint *print, FpPrint *add) +{ + g_return_if_fail (print->type == FP_PRINT_NBIS); + g_return_if_fail (add->type == FP_PRINT_NBIS); + + g_assert (add->prints->len == 1); + g_ptr_array_add (print->prints, g_memdup (add->prints->pdata[0], sizeof (struct xyt_struct))); +} + +/** + * fpi_print_set_type: + * @print: A #FpPrint + * @type: The newly type of the print data + * + * This function can only be called exactly once. Drivers should + * call it after creating a new print, or to initialize the template + * print passed during enrollment. + */ +void +fpi_print_set_type (FpPrint *print, + FpPrintType type) +{ + g_return_if_fail (FP_IS_PRINT (print)); + /* We only allow setting this once! */ + g_return_if_fail (print->type == FP_PRINT_UNDEFINED); + + print->type = type; + if (print->type == FP_PRINT_NBIS) + { + g_assert_null (print->prints); + print->prints = g_ptr_array_new_with_free_func (g_free); + } + g_object_notify (G_OBJECT (print), "fp-type"); +} + +/** + * fpi_print_set_device_stored: + * @print: A #FpPrint + * @device_stored: Whether the print is stored on the device or not + * + * Drivers must set this to %TRUE for any print that is really a handle + * for data that is stored on the device itself. + */ +void +fpi_print_set_device_stored (FpPrint *print, + gboolean device_stored) +{ + g_return_if_fail (FP_IS_PRINT (print)); + + print->device_stored = device_stored; + g_object_notify (G_OBJECT (print), "device-stored"); +} + +/* XXX: This is the old version, but wouldn't it be smarter to instead + * use the highest quality mintutiae? Possibly just using bz_prune from + * upstream? */ +static void +minutiae_to_xyt (struct fp_minutiae *minutiae, + int bwidth, + int bheight, + struct xyt_struct *xyt) +{ + int i; + struct fp_minutia *minutia; + struct minutiae_struct c[MAX_FILE_MINUTIAE]; + + /* struct xyt_struct uses arrays of MAX_BOZORTH_MINUTIAE (200) */ + int nmin = min (minutiae->num, MAX_BOZORTH_MINUTIAE); + + for (i = 0; i < nmin; i++) + { + minutia = minutiae->list[i]; + + lfs2nist_minutia_XYT (&c[i].col[0], &c[i].col[1], &c[i].col[2], + minutia, bwidth, bheight); + c[i].col[3] = sround (minutia->reliability * 100.0); + + if (c[i].col[2] > 180) + c[i].col[2] -= 360; + } + + qsort ((void *) &c, (size_t) nmin, sizeof (struct minutiae_struct), + sort_x_y); + + for (i = 0; i < nmin; i++) + { + xyt->xcol[i] = c[i].col[0]; + xyt->ycol[i] = c[i].col[1]; + xyt->thetacol[i] = c[i].col[2]; + } + xyt->nrows = nmin; +} + +/** + * fpi_print_add_from_image: + * @print: A #FpPrint + * @image: A #FpImage + * @error: Return location for error + * + * Extracts the minutiae from the given image and adds it to @print of + * type #FP_PRINT_NBIS. + * + * The @image will be kept so that API users can get retrieve it e.g. + * for debugging purposes. + * + * Returns: %TRUE on success + */ +gboolean +fpi_print_add_from_image (FpPrint *print, + FpImage *image, + GError **error) +{ + GPtrArray *minutiae; + struct fp_minutiae _minutiae; + struct xyt_struct *xyt; + + if (print->type != FP_PRINT_NBIS || !image) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "Cannot add print data from image!"); + return FALSE; + } + + minutiae = fp_image_get_minutiae (image); + if (!minutiae || minutiae->len == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "No minutiae found in image or not yet detected!"); + return FALSE; + } + + _minutiae.num = minutiae->len; + _minutiae.list = (struct fp_minutia **) minutiae->pdata; + _minutiae.alloc = minutiae->len; + + xyt = g_new0 (struct xyt_struct, 1); + minutiae_to_xyt (&_minutiae, image->width, image->height, xyt); + g_ptr_array_add (print->prints, xyt); + + g_clear_object (&print->image); + print->image = g_object_ref (image); + g_object_notify (G_OBJECT (print), "image"); + + return TRUE; +} + +/** + * fpi_print_bz3_match: + * @template: A #FpPrint containing one or more prints + * @print: A newly scanned #FpPrint to test + * @bz3_threshold: The BZ3 match threshold + * @error: Return location for error + * + * Match the newly scanned @print (containing exactly one print) against the + * prints contained in @template which will have been stored during enrollment. + * + * Both @template and @print need to be of type #FP_PRINT_NBIS for this to + * work. + * + * Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned + */ +FpiMatchResult +fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GError **error) +{ + struct xyt_struct *pstruct; + gint probe_len; + gint i; + + /* XXX: Use a different error type? */ + if (template->type != FP_PRINT_NBIS || print->type != FP_PRINT_NBIS) + { + *error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED, + "It is only possible to match NBIS type print data"); + return FPI_MATCH_ERROR; + } + + if (print->prints->len != 1) + { + *error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "New print contains more than one print!"); + return FPI_MATCH_ERROR; + } + + pstruct = g_ptr_array_index (print->prints, 0); + probe_len = bozorth_probe_init (pstruct); + + for (i = 0; i < template->prints->len; i++) + { + struct xyt_struct *gstruct; + gint score; + gstruct = g_ptr_array_index (template->prints, i); + score = bozorth_to_gallery (probe_len, pstruct, gstruct); + fp_dbg ("score %d", score); + + if (score >= bz3_threshold) + return FPI_MATCH_SUCCESS; + } + + return FPI_MATCH_FAIL; +} diff --git a/libfprint/meson.build b/libfprint/meson.build index 9eb4849..8cb8609 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -9,7 +9,9 @@ libfprint_sources = [ libfprint_private_sources = [ 'fpi-assembling.c', 'fpi-device.c', + 'fpi-image.c', 'fpi-image-device.c', + 'fpi-print.c', 'fpi-ssm.c', 'fpi-usb-transfer.c', 'fpi-byte-reader.c',