Initial implementation for image device access and capture
Also added new example: img_capture
This commit is contained in:
parent
0aac3706d7
commit
f3a838e856
9 changed files with 369 additions and 8 deletions
3
TODO
3
TODO
|
@ -1,9 +1,6 @@
|
||||||
LIBRARY
|
LIBRARY
|
||||||
=======
|
=======
|
||||||
fingerprint data classifcation by device or device type
|
fingerprint data classifcation by device or device type
|
||||||
storage mechanism
|
|
||||||
imaging support
|
|
||||||
external imaging APIs
|
|
||||||
identification
|
identification
|
||||||
external API documentation
|
external API documentation
|
||||||
test suite against NFIQ compliance set
|
test suite against NFIQ compliance set
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
INCLUDES = -I$(top_srcdir)
|
INCLUDES = -I$(top_srcdir)
|
||||||
noinst_PROGRAMS = verify_live enroll verify
|
noinst_PROGRAMS = verify_live enroll verify img_capture
|
||||||
|
|
||||||
verify_live_SOURCES = verify_live.c
|
verify_live_SOURCES = verify_live.c
|
||||||
verify_live_LDADD = ../libfprint/libfprint.la -lfprint
|
verify_live_LDADD = ../libfprint/libfprint.la -lfprint
|
||||||
|
@ -10,3 +10,6 @@ enroll_LDADD = ../libfprint/libfprint.la -lfprint
|
||||||
verify_SOURCES = verify.c
|
verify_SOURCES = verify.c
|
||||||
verify_LDADD = ../libfprint/libfprint.la -lfprint
|
verify_LDADD = ../libfprint/libfprint.la -lfprint
|
||||||
|
|
||||||
|
img_capture_SOURCES = img_capture.c
|
||||||
|
img_capture_LDADD = ../libfprint/libfprint.la -lfprint
|
||||||
|
|
||||||
|
|
100
examples/img_capture.c
Normal file
100
examples/img_capture.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Example libfprint image capture program
|
||||||
|
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <libfprint/fprint.h>
|
||||||
|
|
||||||
|
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||||
|
{
|
||||||
|
struct fp_dscv_dev *ddev = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; ddev = discovered_devs[i]; i++) {
|
||||||
|
struct fp_driver *drv = fp_dscv_dev_get_driver(ddev);
|
||||||
|
printf("Found device claimed by %s driver\n",
|
||||||
|
fp_driver_get_full_name(drv));
|
||||||
|
return ddev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ddev;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int r = 1;
|
||||||
|
struct fp_dscv_dev *ddev;
|
||||||
|
struct fp_dscv_dev **discovered_devs;
|
||||||
|
struct fp_dev *dev;
|
||||||
|
struct fp_img_dev *imgdev;
|
||||||
|
struct fp_img *img = NULL;
|
||||||
|
|
||||||
|
r = fp_init();
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
discovered_devs = fp_discover_devs();
|
||||||
|
if (!discovered_devs) {
|
||||||
|
fprintf(stderr, "Could not discover devices\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ddev = discover_device(discovered_devs);
|
||||||
|
if (!ddev) {
|
||||||
|
fprintf(stderr, "No devices detected.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = fp_dev_open(ddev);
|
||||||
|
fp_dscv_devs_free(discovered_devs);
|
||||||
|
if (!dev) {
|
||||||
|
fprintf(stderr, "Could not open device.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
imgdev = fp_dev_to_img_dev(dev);
|
||||||
|
if (!imgdev) {
|
||||||
|
fprintf(stderr, "could not get image dev, is this an imaging "
|
||||||
|
"device?\n");
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Opened device. It's now time to scan your finger.\n\n");
|
||||||
|
|
||||||
|
r = fp_imgdev_capture(imgdev, 0, &img);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "image capture failed, code %d\n", r);
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = fp_img_save_to_file(img, "finger.pgm");
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "img save failed, code %d\n", r);
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
out_close:
|
||||||
|
fp_dev_close(dev);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ libfprint_la_LIBADD = $(LIBUSB_LIBS) $(GLIB_LIBS)
|
||||||
libfprint_la_SOURCES = \
|
libfprint_la_SOURCES = \
|
||||||
core.c \
|
core.c \
|
||||||
data.c \
|
data.c \
|
||||||
|
img.c \
|
||||||
imgdev.c \
|
imgdev.c \
|
||||||
$(DRIVER_SRC)
|
$(DRIVER_SRC)
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev)
|
||||||
fp_err("usb_open failed");
|
fp_err("usb_open failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = g_malloc0(sizeof(*dev));
|
dev = g_malloc0(sizeof(*dev));
|
||||||
dev->drv = drv;
|
dev->drv = drv;
|
||||||
dev->udev = udevh;
|
dev->udev = udevh;
|
||||||
|
@ -242,6 +242,13 @@ API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
|
||||||
return drv->full_name;
|
return drv->full_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
API_EXPORTED struct fp_img_dev *fp_dev_to_img_dev(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
if (dev->drv->type != DRIVER_IMAGING)
|
||||||
|
return NULL;
|
||||||
|
return dev->priv;
|
||||||
|
}
|
||||||
|
|
||||||
API_EXPORTED int fp_enroll_finger(struct fp_dev *dev,
|
API_EXPORTED int fp_enroll_finger(struct fp_dev *dev,
|
||||||
struct fp_print_data **print_data)
|
struct fp_print_data **print_data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
|
||||||
|
|
||||||
|
#define container_of(ptr, type, member) ({ \
|
||||||
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
enum fpi_log_level {
|
enum fpi_log_level {
|
||||||
LOG_LEVEL_DEBUG,
|
LOG_LEVEL_DEBUG,
|
||||||
LOG_LEVEL_INFO,
|
LOG_LEVEL_INFO,
|
||||||
|
@ -82,6 +86,12 @@ struct fp_dev {
|
||||||
int __enroll_stage;
|
int __enroll_stage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fp_img_dev {
|
||||||
|
struct fp_dev *dev;
|
||||||
|
usb_dev_handle *udev;
|
||||||
|
void *priv;
|
||||||
|
};
|
||||||
|
|
||||||
struct usb_id {
|
struct usb_id {
|
||||||
uint16_t vendor;
|
uint16_t vendor;
|
||||||
uint16_t product;
|
uint16_t product;
|
||||||
|
@ -109,10 +119,20 @@ struct fp_driver {
|
||||||
int (*verify)(struct fp_dev *dev, struct fp_print_data *data);
|
int (*verify)(struct fp_dev *dev, struct fp_print_data *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* flags for fp_img_driver.flags */
|
||||||
|
#define FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE (1 << 0)
|
||||||
|
|
||||||
struct fp_img_driver {
|
struct fp_img_driver {
|
||||||
struct fp_driver driver;
|
struct fp_driver driver;
|
||||||
|
uint16_t flags;
|
||||||
|
|
||||||
/* Device operations */
|
/* Device operations */
|
||||||
|
int (*init)(struct fp_img_dev *dev, unsigned long driver_data);
|
||||||
|
void (*exit)(struct fp_img_dev *dev);
|
||||||
|
int (*await_finger_on)(struct fp_img_dev *dev);
|
||||||
|
int (*await_finger_off)(struct fp_img_dev *dev);
|
||||||
|
int (*capture)(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
|
struct fp_img **image);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct fp_driver upekts_driver;
|
extern struct fp_driver upekts_driver;
|
||||||
|
@ -133,9 +153,20 @@ struct fp_print_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length);
|
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length);
|
||||||
unsigned char *fpi_print_data_get_buffer(struct fp_print_data *data);
|
|
||||||
int fpi_print_data_compatible(struct fp_dev *dev, struct fp_print_data *data);
|
int fpi_print_data_compatible(struct fp_dev *dev, struct fp_print_data *data);
|
||||||
|
|
||||||
|
struct fp_img {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
size_t length;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_img *fpi_img_new(size_t length);
|
||||||
|
struct fp_img *fpi_img_new_dims(int width, int height);
|
||||||
|
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize);
|
||||||
|
gboolean fpi_img_is_sane(struct fp_img *img);
|
||||||
|
|
||||||
#define bswap16(x) (((x & 0xff) << 8) | (x >> 8))
|
#define bswap16(x) (((x & 0xff) << 8) | (x >> 8))
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
#define cpu_to_le16(x) (x)
|
#define cpu_to_le16(x) (x)
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct fp_dscv_dev;
|
||||||
struct fp_dev;
|
struct fp_dev;
|
||||||
struct fp_driver;
|
struct fp_driver;
|
||||||
struct fp_print_data;
|
struct fp_print_data;
|
||||||
|
struct fp_img;
|
||||||
|
|
||||||
/* misc/general stuff */
|
/* misc/general stuff */
|
||||||
enum fp_finger {
|
enum fp_finger {
|
||||||
|
@ -50,6 +51,7 @@ struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev);
|
||||||
void fp_dev_close(struct fp_dev *dev);
|
void fp_dev_close(struct fp_dev *dev);
|
||||||
struct fp_driver *fp_dev_get_driver(struct fp_dev *dev);
|
struct fp_driver *fp_dev_get_driver(struct fp_dev *dev);
|
||||||
int fp_dev_get_nr_enroll_stages(struct fp_dev *dev);
|
int fp_dev_get_nr_enroll_stages(struct fp_dev *dev);
|
||||||
|
struct fp_img_dev *fp_dev_to_img_dev(struct fp_dev *dev);
|
||||||
|
|
||||||
/* Drivers */
|
/* Drivers */
|
||||||
const char *fp_driver_get_name(struct fp_driver *drv);
|
const char *fp_driver_get_name(struct fp_driver *drv);
|
||||||
|
@ -86,6 +88,16 @@ int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger,
|
||||||
int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger);
|
int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger);
|
||||||
void fp_print_data_free(struct fp_print_data *data);
|
void fp_print_data_free(struct fp_print_data *data);
|
||||||
|
|
||||||
|
/* Imaging devices */
|
||||||
|
int fp_imgdev_capture(struct fp_img_dev *imgdev, int unconditional,
|
||||||
|
struct fp_img **image);
|
||||||
|
|
||||||
|
/* Image handling */
|
||||||
|
int fp_img_get_height(struct fp_img *img);
|
||||||
|
int fp_img_get_width(struct fp_img *img);
|
||||||
|
unsigned char *fp_img_get_data(struct fp_img *img);
|
||||||
|
int fp_img_save_to_file(struct fp_img *img, char *path);
|
||||||
|
|
||||||
/* Library */
|
/* Library */
|
||||||
int fp_init(void);
|
int fp_init(void);
|
||||||
|
|
||||||
|
|
106
libfprint/img.c
Normal file
106
libfprint/img.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Image management functions for libfprint
|
||||||
|
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||||
|
*
|
||||||
|
* 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 <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "fp_internal.h"
|
||||||
|
|
||||||
|
struct fp_img *fpi_img_new(size_t length)
|
||||||
|
{
|
||||||
|
struct fp_img *img = g_malloc(sizeof(*img) + length);
|
||||||
|
memset(img, 0, sizeof(*img));
|
||||||
|
fp_dbg("length=%zd", length);
|
||||||
|
img->length = length;
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fp_img *fpi_img_new_dims(int width, int height)
|
||||||
|
{
|
||||||
|
struct fp_img *img = fpi_img_new(width * height);
|
||||||
|
img->width = width;
|
||||||
|
img->height = height;
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean fpi_img_is_sane(struct fp_img *img)
|
||||||
|
{
|
||||||
|
/* basic checks */
|
||||||
|
if (!img->length || !img->width || !img->height)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* buffer is big enough? */
|
||||||
|
if ((img->length * img->height) < img->length)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize)
|
||||||
|
{
|
||||||
|
return g_realloc(img, sizeof(*img) + newsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
API_EXPORTED int fp_img_get_height(struct fp_img *img)
|
||||||
|
{
|
||||||
|
return img->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
API_EXPORTED int fp_img_get_width(struct fp_img *img)
|
||||||
|
{
|
||||||
|
return img->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
API_EXPORTED unsigned char *fp_img_get_data(struct fp_img *img)
|
||||||
|
{
|
||||||
|
return img->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
API_EXPORTED int fp_img_save_to_file(struct fp_img *img, char *path)
|
||||||
|
{
|
||||||
|
FILE *fd = fopen(path, "w");
|
||||||
|
size_t write_size = img->width * img->height;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!fd) {
|
||||||
|
fp_dbg("could not open '%s' for writing: %d", path, errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = fprintf(fd, "P5 %d %d 255\n", img->width, img->height);
|
||||||
|
if (r < 0) {
|
||||||
|
fp_err("pgm header write failed, error %d", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = fwrite(img->data, 1, write_size, fd);
|
||||||
|
if (r < write_size) {
|
||||||
|
fp_err("short write (%d)", r);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fd);
|
||||||
|
fp_dbg("written to '%s'", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Core imaging functions for libfprint
|
* Core imaging device functions for libfprint
|
||||||
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
@ -17,13 +17,117 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "fp_internal.h"
|
#include "fp_internal.h"
|
||||||
|
|
||||||
|
#define driver_to_img_driver(drv) \
|
||||||
|
container_of((drv), struct fp_img_driver, driver)
|
||||||
|
|
||||||
|
static int img_dev_init(struct fp_dev *dev, unsigned long driver_data)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *imgdev = g_malloc0(sizeof(*imgdev));
|
||||||
|
struct fp_img_driver *imgdrv = driver_to_img_driver(dev->drv);
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
imgdev->dev = dev;
|
||||||
|
dev->priv = imgdev;
|
||||||
|
dev->nr_enroll_stages = 1;
|
||||||
|
|
||||||
|
/* for consistency in driver code, allow udev access through imgdev */
|
||||||
|
imgdev->udev = dev->udev;
|
||||||
|
|
||||||
|
if (imgdrv->init) {
|
||||||
|
r = imgdrv->init(imgdev, driver_data);
|
||||||
|
if (r)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
g_free(imgdev);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void img_dev_exit(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
|
struct fp_img_driver *imgdrv = driver_to_img_driver(dev->drv);
|
||||||
|
|
||||||
|
if (imgdrv->exit)
|
||||||
|
imgdrv->exit(imgdev);
|
||||||
|
|
||||||
|
g_free(imgdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
API_EXPORTED int fp_imgdev_capture(struct fp_img_dev *imgdev,
|
||||||
|
int unconditional, struct fp_img **image)
|
||||||
|
{
|
||||||
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
|
struct fp_img_driver *imgdrv = driver_to_img_driver(drv);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
fp_err("no image pointer given");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imgdrv->capture) {
|
||||||
|
fp_err("img driver %s has no capture func", drv->name);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unconditional) {
|
||||||
|
if (!(imgdrv->flags & FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE)) {
|
||||||
|
fp_dbg("requested unconditional capture, but driver %s does not "
|
||||||
|
"support it", drv->name);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_dbg("%s will handle capture request", drv->name);
|
||||||
|
|
||||||
|
if (!unconditional && imgdrv->await_finger_on) {
|
||||||
|
r = imgdrv->await_finger_on(imgdev);
|
||||||
|
if (r) {
|
||||||
|
fp_err("await_finger_on failed with error %d", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = imgdrv->capture(imgdev, unconditional, image);
|
||||||
|
if (r) {
|
||||||
|
fp_err("capture failed with error %d", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unconditional && imgdrv->await_finger_off) {
|
||||||
|
r = imgdrv->await_finger_off(imgdev);
|
||||||
|
if (r) {
|
||||||
|
fp_err("await_finger_off failed with error %d", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 0) {
|
||||||
|
if (*image == NULL) {
|
||||||
|
fp_err("capture succeeded but no image returned?");
|
||||||
|
return -ENODATA;
|
||||||
|
}
|
||||||
|
if (!fpi_img_is_sane(*image)) {
|
||||||
|
fp_err("image is not sane!");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void fpi_img_driver_setup(struct fp_img_driver *idriver)
|
void fpi_img_driver_setup(struct fp_img_driver *idriver)
|
||||||
{
|
{
|
||||||
idriver->driver.type = DRIVER_IMAGING;
|
idriver->driver.type = DRIVER_IMAGING;
|
||||||
/* FIXME fill in primitive operations */
|
idriver->driver.init = img_dev_init;
|
||||||
|
idriver->driver.exit = img_dev_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue