From 3f70d6f79410f483a9b34945dfe5b1cf5bfc23f6 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 20 Nov 2007 21:52:10 +0000 Subject: [PATCH] Identification infrastructure --- libfprint/core.c | 94 +++++++++++++++++++++++++++++++++++++++++ libfprint/fp_internal.h | 2 + libfprint/fprint.h | 60 +++++++++++++++++++------- 3 files changed, 141 insertions(+), 15 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index a018988..7db625a 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -747,6 +747,18 @@ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev) return dev->drv->type == DRIVER_IMAGING; } +/** \ingroup dev + * Determines if a device is capable of \ref identification "identification" + * through fp_identify_finger() and similar. Not all devices support this + * functionality. + * \param dev the fingerprint device + * \returns 1 if the device is capable of identification, 0 otherwise. + */ +API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev) +{ + return dev->drv->identify != NULL; +} + /** \ingroup dev * Captures an \ref img "image" from a device. The returned image is the raw * image provided by the device, you may wish to \ref img_std "standardize" it. @@ -1020,6 +1032,88 @@ API_EXPORTED int fp_verify_finger_img(struct fp_dev *dev, return r; } +/** \ingroup dev + * Performs a new scan and attempts to identify the scanned finger against + * a collection of previously enrolled fingerprints. + * If the device is an imaging device, it can also return the image from + * the scan, even when identification fails with a RETRY code. It is legal to + * call this function even on non-imaging devices, just don't expect them to + * provide images. + * + * This function returns codes from #fp_verify_result. The return code + * fp_verify_result#FP_VERIFY_MATCH indicates that the scanned fingerprint + * does appear in the print gallery, and the match_offset output parameter + * will indicate the index into the print gallery array of the matched print. + * + * This function will not necessarily examine the whole print gallery, it + * will return as soon as it finds a matching print. + * + * Not all devices support identification. -ENOTSUP will be returned when + * this is the case. + * + * \param dev the device to perform the scan. + * \param print_gallery NULL-terminated array of pointers to the prints to + * identify against. Each one must have been previously enrolled with a device + * compatible to the device selected to perform the scan. + * \param match_offset output location to store the array index of the matched + * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * returned. + * \param img location to store the scan image. accepts NULL for no image + * storage. If an image is returned, it must be freed with fp_img_free() after + * use. + * \return negative code on error, otherwise a code from #fp_verify_result + */ +API_EXPORTED int fp_identify_finger_img(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset, + struct fp_img **img) +{ + struct fp_driver *drv = dev->drv; + struct fp_img *_img; + int r; + + if (!drv->identify) { + fp_dbg("driver %s has no identify func", drv->name); + return -ENOTSUP; + } + fp_dbg("to be handled by %s", drv->name); + r = drv->identify(dev, print_gallery, match_offset, &_img); + if (r < 0) { + fp_dbg("identify error %d", r); + return r; + } + + if (img) + *img = _img; + else + fp_img_free(_img); + + switch (r) { + case FP_VERIFY_NO_MATCH: + fp_dbg("result: no match"); + break; + case FP_VERIFY_MATCH: + fp_dbg("result: match at offset %zd", match_offset); + break; + case FP_VERIFY_RETRY: + fp_dbg("verify should retry"); + break; + case FP_VERIFY_RETRY_TOO_SHORT: + fp_dbg("swipe was too short, verify should retry"); + break; + case FP_VERIFY_RETRY_CENTER_FINGER: + fp_dbg("finger was not centered, verify should retry"); + break; + case FP_VERIFY_RETRY_REMOVE_FINGER: + fp_dbg("scan failed, remove finger and retry"); + break; + default: + fp_err("unrecognised return code %d", r); + return -EINVAL; + } + + return r; +} + /** \ingroup core * Initialise libfprint. This function must be called before you attempt to * use the library in any way. diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 5e6f15f..7581c38 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -113,6 +113,8 @@ struct fp_driver { struct fp_print_data **print_data, struct fp_img **img); int (*verify)(struct fp_dev *dev, struct fp_print_data *data, struct fp_img **img); + int (*identify)(struct fp_dev *dev, struct fp_print_data **print_gallery, + size_t *match_offset, struct fp_img **img); }; enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv); diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 639c963..2b85584 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -150,30 +150,32 @@ static inline int fp_enroll_finger(struct fp_dev *dev, } /** \ingroup dev - * Verification result codes returned from fp_verify_finger(). + * Verification result codes returned from fp_verify_finger(). Return codes + * are also shared with fp_identify_finger(). * Result codes with RETRY in the name suggest that the scan failed due to * user error. Applications will generally want to inform the user of the * problem and then retry the verify operation. */ enum fp_verify_result { - /** The verification scan completed successfully, but the newly scanned - * fingerprint does not match the fingerprint being verified against. */ + /** The scan completed successfully, but the newly scanned fingerprint + * does not match the fingerprint being verified against. + * In the case of identification, this return code indicates that the + * scanned finger could not be found in the print gallery. */ FP_VERIFY_NO_MATCH = 0, - /** The verification scan completed successfully and the newly scanned - * fingerprint does match the fingerprint being verified. */ + /** The scan completed successfully and the newly scanned fingerprint does + * match the fingerprint being verified, or in the case of identification, + * the scanned fingerprint was found in the print gallery. */ FP_VERIFY_MATCH = 1, - /** The verification scan did not succeed due to poor scan quality or - * other general user scanning problem. */ + /** The scan did not succeed due to poor scan quality or other general + * user scanning problem. */ FP_VERIFY_RETRY = FP_ENROLL_RETRY, - /** The verification scan did not succeed because the finger swipe was - * too short. */ + /** The scan did not succeed because the finger swipe was too short. */ FP_VERIFY_RETRY_TOO_SHORT = FP_ENROLL_RETRY_TOO_SHORT, - /** The verification scan did not succeed because the finger was not - * centered on the scanner. */ + /** The scan did not succeed because the finger was not centered on the + * scanner. */ FP_VERIFY_RETRY_CENTER_FINGER = FP_ENROLL_RETRY_CENTER_FINGER, - /** The verification scan did not succeed due to quality or pressure - * problems; the user should remove their finger from the scanner before - * retrying. */ + /** The scan did not succeed due to quality or pressure problems; the user + * should remove their finger from the scanner before retrying. */ FP_VERIFY_RETRY_REMOVE_FINGER = FP_ENROLL_RETRY_REMOVE_FINGER, }; @@ -181,7 +183,9 @@ int fp_verify_finger_img(struct fp_dev *dev, struct fp_print_data *enrolled_print, struct fp_img **img); /** \ingroup dev - * Performs a new scan and verify it against a previously enrolled print. + * Performs a new scan and verify it against a previously enrolled print. This + * function is just a shortcut to calling fp_verify_finger_img() with a NULL + * image output parameter. * \param dev the device to perform the scan. * \param enrolled_print the print to verify against. Must have been previously * enrolled with a device compatible to the device selected to perform the scan. @@ -194,6 +198,32 @@ static inline int fp_verify_finger(struct fp_dev *dev, return fp_verify_finger_img(dev, enrolled_print, NULL); } +int fp_dev_supports_identification(struct fp_dev *dev); +int fp_identify_finger_img(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset, + struct fp_img **img); + +/** \ingroup dev + * Performs a new scan and attempts to identify the scanned finger against a + * collection of previously enrolled fingerprints. This function is just a + * shortcut to calling fp_identify_finger_img() with a NULL image output + * parameter. + * \param dev the device to perform the scan. + * \param print_gallery NULL-terminated array of pointers to the prints to + * identify against. Each one must have been previously enrolled with a device + * compatible to the device selected to perform the scan. + * \param match_offset output location to store the array index of the matched + * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * returned. + * \return negative code on error, otherwise a code from #fp_verify_result + * \sa fp_identify_finger_img() + */ +static inline int fp_identify_finger(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset) +{ + return fp_identify_finger_img(dev, print_gallery, match_offset, NULL); +} + /* Data handling */ int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data);