mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
7 Commits
benzea/fix
...
wip/hadess
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d871751f6 | ||
|
|
4fdf0eae0f | ||
|
|
8632877b95 | ||
|
|
170d7c2cf7 | ||
|
|
e2d4b0d249 | ||
|
|
b0c546164e | ||
|
|
f2ae3fb8c5 |
@@ -48,11 +48,6 @@ build:
|
|||||||
<<: *build_one_driver
|
<<: *build_one_driver
|
||||||
<<: *build
|
<<: *build
|
||||||
# <<: *check_abi
|
# <<: *check_abi
|
||||||
artifacts:
|
|
||||||
expose_as: "HTML Documentation"
|
|
||||||
paths:
|
|
||||||
- _build/doc/html/
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
@@ -80,32 +75,13 @@ test_valgrind:
|
|||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
||||||
|
|
||||||
test_scan_build:
|
|
||||||
stage: test
|
|
||||||
except:
|
|
||||||
variables:
|
|
||||||
- $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
allow_failure: true
|
|
||||||
script:
|
|
||||||
- meson -Ddrivers=all . _build
|
|
||||||
# This is ugly, the wrapper disables the malloc checker
|
|
||||||
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build ninja -C _build scan-build
|
|
||||||
# Check that the directory is empty
|
|
||||||
- "! ls -A _build/meson-logs/scanbuild | grep -q ."
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- _build/meson-logs
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
test_indent:
|
test_indent:
|
||||||
stage: check-source
|
stage: check-source
|
||||||
except:
|
except:
|
||||||
variables:
|
variables:
|
||||||
- $CI_PIPELINE_SOURCE == "schedule"
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- scripts/uncrustify.sh
|
- scripts/uncrustify.sh --check
|
||||||
- git diff
|
|
||||||
- "! git status -s | grep -q ."
|
|
||||||
|
|
||||||
.flatpak_script_template: &flatpak_script
|
.flatpak_script_template: &flatpak_script
|
||||||
script:
|
script:
|
||||||
|
|||||||
@@ -24,4 +24,3 @@
|
|||||||
umockdev
|
umockdev
|
||||||
uncrustify
|
uncrustify
|
||||||
valgrind
|
valgrind
|
||||||
clang-analyzer
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This wrapper just disables the malloc checker
|
|
||||||
exec /usr/bin/scan-build -disable-checker unix.Malloc "$@"
|
|
||||||
13
MAINTAINERS
13
MAINTAINERS
@@ -1,13 +0,0 @@
|
|||||||
Current maintainers of libfprint are:
|
|
||||||
|
|
||||||
* Benjamin Berg <bberg@redhat.com>
|
|
||||||
* Marco Trevisan (Treviño) <mail@3v1n0.net>
|
|
||||||
|
|
||||||
Many drivers are not actively maintained and may not be fully functional.
|
|
||||||
We are happy to receive contributions, but the support we can give is
|
|
||||||
limitted unfortunately. For many drivers we may not even have test devices.
|
|
||||||
|
|
||||||
Maintained drivers are:
|
|
||||||
* synaptics:
|
|
||||||
Contributed and maintained by Synaptics Inc.
|
|
||||||
Contact: Vincent Huang <vincent.huang@tw.synaptics.com>
|
|
||||||
@@ -175,7 +175,7 @@ fpi_image_resize
|
|||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>fpi-image-device</FILE>
|
<FILE>fpi-image-device</FILE>
|
||||||
<TITLE>Internal FpImageDevice</TITLE>
|
<TITLE>FpImageDevice</TITLE>
|
||||||
FpiImageDeviceState
|
FpiImageDeviceState
|
||||||
FpImageDeviceClass
|
FpImageDeviceClass
|
||||||
fpi_image_device_session_error
|
fpi_image_device_session_error
|
||||||
53
examples/sendvirtcmd.py
Executable file
53
examples/sendvirtcmd.py
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# This script can be used together with the virtual_imgdev to simulate an
|
||||||
|
# image based fingerprint reader.
|
||||||
|
#
|
||||||
|
# To use, set the FP_VIRTUAL_IMAGE environment variable for both the
|
||||||
|
# libfprint using program (e.g. fprintd) and this script.
|
||||||
|
#
|
||||||
|
# Usually this would work by adding it into the systemd unit file. The
|
||||||
|
# best way of doing so is to create
|
||||||
|
# /etc/systemd/system/fprintd.service.d/fprintd-test.conf
|
||||||
|
#
|
||||||
|
# [Service]
|
||||||
|
# RuntimeDirectory=fprint
|
||||||
|
# Environment=FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock
|
||||||
|
# Environment=G_MESSAGES_DEBUG=all
|
||||||
|
# ReadWritePaths=$RUNTIME_DIR
|
||||||
|
#
|
||||||
|
# After that run:
|
||||||
|
#
|
||||||
|
# systemctl daemon-reload
|
||||||
|
# systemctl restart fprintd.service
|
||||||
|
#
|
||||||
|
# You may also need to disable selinux.
|
||||||
|
#
|
||||||
|
# Then run this script with e.g.
|
||||||
|
# FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock ./sendvirtimg.py "ADD <username> <finger> <success|failure>"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import cairo
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.stderr.write('You need to pass commands!\n')
|
||||||
|
sys.stderr.write('Usage: ./sendvirtimg.py "ADD <finger> <username> <success|failure>"\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
command = sys.argv[1]
|
||||||
|
|
||||||
|
# Send image through socket
|
||||||
|
sockaddr = os.environ['FP_VIRTUAL_DEVICE']
|
||||||
|
if not sockaddr:
|
||||||
|
sockaddr = os.environ['FP_VIRTUAL_DEVICE_IDENT']
|
||||||
|
|
||||||
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
sock.connect(sockaddr)
|
||||||
|
|
||||||
|
sock.sendall(command.encode('utf-8'))
|
||||||
|
|
||||||
@@ -614,7 +614,6 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
self->strips = g_slist_reverse (self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||||
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
|
|
||||||
g_slist_free_full (self->strips, g_free);
|
g_slist_free_full (self->strips, g_free);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
|
|||||||
@@ -458,7 +458,6 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
|
|||||||
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||||
img = fpi_assemble_frames (&assembling_ctx,
|
img = fpi_assemble_frames (&assembling_ctx,
|
||||||
self->strips);
|
self->strips);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
g_slist_free_full (self->strips, g_free);
|
g_slist_free_full (self->strips, g_free);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
|
|||||||
|
|
||||||
self->strips = g_slist_reverse (self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
g_slist_free_full (self->strips, g_free);
|
g_slist_free_full (self->strips, g_free);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
|
|||||||
@@ -331,7 +331,6 @@ capture_set_idle_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
|
|
||||||
priv->strips = g_slist_reverse (priv->strips);
|
priv->strips = g_slist_reverse (priv->strips);
|
||||||
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
|
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
|
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
|
||||||
g_slist_free (priv->strips);
|
g_slist_free (priv->strips);
|
||||||
priv->strips = NULL;
|
priv->strips = NULL;
|
||||||
|
|||||||
@@ -207,7 +207,6 @@ elan_save_img_frame (FpiDeviceElan *elandev)
|
|||||||
|
|
||||||
unsigned int frame_size = elandev->frame_width * elandev->frame_height;
|
unsigned int frame_size = elandev->frame_width * elandev->frame_height;
|
||||||
unsigned short *frame = g_malloc (frame_size * sizeof (short));
|
unsigned short *frame = g_malloc (frame_size * sizeof (short));
|
||||||
|
|
||||||
elan_save_frame (elandev, frame);
|
elan_save_frame (elandev, frame);
|
||||||
unsigned int sum = 0;
|
unsigned int sum = 0;
|
||||||
|
|
||||||
@@ -245,7 +244,6 @@ elan_process_frame_linear (unsigned short *raw_frame,
|
|||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
unsigned short min = 0xffff, max = 0;
|
unsigned short min = 0xffff, max = 0;
|
||||||
|
|
||||||
for (int i = 0; i < frame_size; i++)
|
for (int i = 0; i < frame_size; i++)
|
||||||
{
|
{
|
||||||
if (raw_frame[i] < min)
|
if (raw_frame[i] < min)
|
||||||
@@ -257,7 +255,6 @@ elan_process_frame_linear (unsigned short *raw_frame,
|
|||||||
g_assert (max != min);
|
g_assert (max != min);
|
||||||
|
|
||||||
unsigned short px;
|
unsigned short px;
|
||||||
|
|
||||||
for (int i = 0; i < frame_size; i++)
|
for (int i = 0; i < frame_size; i++)
|
||||||
{
|
{
|
||||||
px = raw_frame[i];
|
px = raw_frame[i];
|
||||||
@@ -281,7 +278,6 @@ elan_process_frame_thirds (unsigned short *raw_frame,
|
|||||||
|
|
||||||
unsigned short lvl0, lvl1, lvl2, lvl3;
|
unsigned short lvl0, lvl1, lvl2, lvl3;
|
||||||
unsigned short *sorted = g_malloc (frame_size * sizeof (short));
|
unsigned short *sorted = g_malloc (frame_size * sizeof (short));
|
||||||
|
|
||||||
memcpy (sorted, raw_frame, frame_size * sizeof (short));
|
memcpy (sorted, raw_frame, frame_size * sizeof (short));
|
||||||
qsort (sorted, frame_size, sizeof (short), cmp_short);
|
qsort (sorted, frame_size, sizeof (short), cmp_short);
|
||||||
lvl0 = sorted[0];
|
lvl0 = sorted[0];
|
||||||
@@ -291,7 +287,6 @@ elan_process_frame_thirds (unsigned short *raw_frame,
|
|||||||
g_free (sorted);
|
g_free (sorted);
|
||||||
|
|
||||||
unsigned short px;
|
unsigned short px;
|
||||||
|
|
||||||
for (int i = 0; i < frame_size; i++)
|
for (int i = 0; i < frame_size; i++)
|
||||||
{
|
{
|
||||||
px = raw_frame[i];
|
px = raw_frame[i];
|
||||||
@@ -325,7 +320,6 @@ elan_submit_image (FpImageDevice *dev)
|
|||||||
g_slist_foreach (raw_frames, (GFunc) self->process_frame, &frames);
|
g_slist_foreach (raw_frames, (GFunc) self->process_frame, &frames);
|
||||||
fpi_do_movement_estimation (&assembling_ctx, frames);
|
fpi_do_movement_estimation (&assembling_ctx, frames);
|
||||||
img = fpi_assemble_frames (&assembling_ctx, frames);
|
img = fpi_assemble_frames (&assembling_ctx, frames);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
|
|
||||||
g_slist_free_full (frames, g_free);
|
g_slist_free_full (frames, g_free);
|
||||||
|
|
||||||
@@ -515,7 +509,6 @@ elan_stop_capture (FpDevice *dev)
|
|||||||
|
|
||||||
FpiSsm *ssm =
|
FpiSsm *ssm =
|
||||||
fpi_ssm_new (dev, stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
|
fpi_ssm_new (dev, stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, stop_capture_complete);
|
fpi_ssm_start (ssm, stop_capture_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +619,6 @@ elan_capture (FpDevice *dev)
|
|||||||
elan_dev_reset_state (self);
|
elan_dev_reset_state (self);
|
||||||
FpiSsm *ssm =
|
FpiSsm *ssm =
|
||||||
fpi_ssm_new (dev, capture_run_state, CAPTURE_NUM_STATES);
|
fpi_ssm_new (dev, capture_run_state, CAPTURE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, capture_complete);
|
fpi_ssm_start (ssm, capture_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,7 +797,6 @@ elan_calibrate (FpDevice *dev)
|
|||||||
|
|
||||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
|
||||||
CALIBRATE_NUM_STATES);
|
CALIBRATE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, calibrate_complete);
|
fpi_ssm_start (ssm, calibrate_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +892,6 @@ elan_activate (FpImageDevice *dev)
|
|||||||
FpiSsm *ssm =
|
FpiSsm *ssm =
|
||||||
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES);
|
ACTIVATE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, activate_complete);
|
fpi_ssm_start (ssm, activate_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,7 +988,7 @@ static void
|
|||||||
elan_change_state_async (FpDevice *dev,
|
elan_change_state_async (FpDevice *dev,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
fp_dbg ("state change dev: %p", dev);
|
g_message ("state change dev: %p", dev);
|
||||||
elan_change_state (FP_IMAGE_DEVICE (dev));
|
elan_change_state (FP_IMAGE_DEVICE (dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *res
|
|||||||
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
|
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||||
{
|
{
|
||||||
if (offset >= msg_resp->payload_len)
|
if (offset >= msg_resp->payload_len)
|
||||||
|
|||||||
@@ -310,7 +310,6 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
fp_dbg ("Image size is %lu\n",
|
fp_dbg ("Image size is %lu\n",
|
||||||
self->image_size);
|
self->image_size);
|
||||||
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
|
||||||
memcpy (img->data, self->image_bits,
|
memcpy (img->data, self->image_bits,
|
||||||
IMAGE_SIZE);
|
IMAGE_SIZE);
|
||||||
fpi_image_device_image_captured (dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#define TIMEOUT 5000
|
#define TIMEOUT 5000
|
||||||
|
|
||||||
#define MSG_READ_BUF_SIZE 0x40
|
#define MSG_READ_BUF_SIZE 0x40
|
||||||
|
#define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
|
||||||
|
|
||||||
struct _FpiDeviceUpekts
|
struct _FpiDeviceUpekts
|
||||||
{
|
{
|
||||||
@@ -235,18 +236,12 @@ __handle_incoming_msg (FpDevice *device,
|
|||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
guint8 *buf = udata->buffer;
|
guint8 *buf = udata->buffer;
|
||||||
guint16 len;
|
guint16 len = ((buf[5] & 0xf) << 8) | buf[6];
|
||||||
guint16 computed_crc;
|
guint16 computed_crc = udf_crc (buf + 4, len + 3);
|
||||||
guint16 msg_crc;
|
guint16 msg_crc = (buf[len + 8] << 8) | buf[len + 7];
|
||||||
|
unsigned char *retdata = NULL;
|
||||||
unsigned char code_a, code_b;
|
unsigned char code_a, code_b;
|
||||||
|
|
||||||
g_assert (udata->buflen >= 6);
|
|
||||||
len = ((buf[5] & 0xf) << 8) | buf[6];
|
|
||||||
|
|
||||||
g_assert (udata->buflen >= len + 9);
|
|
||||||
computed_crc = udf_crc (buf + 4, len + 3);
|
|
||||||
msg_crc = (buf[len + 8] << 8) | buf[len + 7];
|
|
||||||
|
|
||||||
if (computed_crc != msg_crc)
|
if (computed_crc != msg_crc)
|
||||||
{
|
{
|
||||||
fp_err ("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
|
fp_err ("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
|
||||||
@@ -272,7 +267,12 @@ __handle_incoming_msg (FpDevice *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
udata->callback (device, READ_MSG_CMD, code_a, 0, buf + 7, len,
|
if (len > 0)
|
||||||
|
{
|
||||||
|
retdata = g_malloc (len);
|
||||||
|
memcpy (retdata, buf + 7, len);
|
||||||
|
}
|
||||||
|
udata->callback (device, READ_MSG_CMD, code_a, 0, retdata, len,
|
||||||
udata->user_data, NULL);
|
udata->user_data, NULL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -309,8 +309,14 @@ __handle_incoming_msg (FpDevice *device,
|
|||||||
innerlen = innerlen - 3;
|
innerlen = innerlen - 3;
|
||||||
_subcmd = innerbuf[5];
|
_subcmd = innerbuf[5];
|
||||||
fp_dbg ("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
|
fp_dbg ("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
|
||||||
|
if (innerlen > 0)
|
||||||
|
{
|
||||||
|
retdata = g_malloc (innerlen);
|
||||||
|
memcpy (retdata, innerbuf + 6, innerlen);
|
||||||
|
}
|
||||||
udata->callback (device, READ_MSG_RESPONSE, code_b, _subcmd,
|
udata->callback (device, READ_MSG_RESPONSE, code_b, _subcmd,
|
||||||
innerbuf + 6, innerlen, udata->user_data, NULL);
|
retdata, innerlen, udata->user_data, NULL);
|
||||||
|
g_free (retdata);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -352,8 +358,7 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct read_msg_data *udata = user_data;
|
struct read_msg_data *udata = user_data;
|
||||||
guint16 payload_len;
|
guint16 len;
|
||||||
gsize packet_len;
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@@ -378,15 +383,14 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
payload_len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
|
len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
|
||||||
packet_len = payload_len + 9;
|
|
||||||
if (transfer->actual_length != MSG_READ_BUF_SIZE &&
|
if (transfer->actual_length != MSG_READ_BUF_SIZE &&
|
||||||
packet_len > transfer->actual_length)
|
(len + 9) > transfer->actual_length)
|
||||||
{
|
{
|
||||||
/* Check that the length claimed inside the message is in line with
|
/* Check that the length claimed inside the message is in line with
|
||||||
* the amount of data that was transferred over USB. */
|
* the amount of data that was transferred over USB. */
|
||||||
fp_err ("msg didn't include enough data, expected=%d recv=%d",
|
fp_err ("msg didn't include enough data, expected=%d recv=%d",
|
||||||
(gint) packet_len, (gint) transfer->actual_length);
|
len + 9, (gint) transfer->actual_length);
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Packet from device didn't include data");
|
"Packet from device didn't include data");
|
||||||
goto err;
|
goto err;
|
||||||
@@ -395,14 +399,14 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
/* We use a 64 byte buffer for reading messages. However, sometimes
|
/* We use a 64 byte buffer for reading messages. However, sometimes
|
||||||
* messages are longer, in which case we have to do another USB bulk read
|
* messages are longer, in which case we have to do another USB bulk read
|
||||||
* to read the remainder. This is handled below. */
|
* to read the remainder. This is handled below. */
|
||||||
if (packet_len > MSG_READ_BUF_SIZE)
|
if (len > MAX_DATA_IN_READ_BUF)
|
||||||
{
|
{
|
||||||
int needed = packet_len - MSG_READ_BUF_SIZE;
|
int needed = len - MAX_DATA_IN_READ_BUF;
|
||||||
FpiUsbTransfer *etransfer = fpi_usb_transfer_new (device);
|
FpiUsbTransfer *etransfer = fpi_usb_transfer_new (device);
|
||||||
|
|
||||||
fp_dbg ("didn't fit in buffer, need to extend by %d bytes", needed);
|
fp_dbg ("didn't fit in buffer, need to extend by %d bytes", needed);
|
||||||
udata->buffer = g_realloc ((gpointer) udata->buffer, packet_len);
|
udata->buffer = g_realloc ((gpointer) udata->buffer, len);
|
||||||
udata->buflen = packet_len;
|
udata->buflen = len;
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full (etransfer, EP_IN,
|
fpi_usb_transfer_fill_bulk_full (etransfer, EP_IN,
|
||||||
udata->buffer + MSG_READ_BUF_SIZE,
|
udata->buffer + MSG_READ_BUF_SIZE,
|
||||||
@@ -696,7 +700,7 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SEND_RESP03:;
|
case SEND_RESP03:;
|
||||||
transfer = alloc_send_cmdresponse_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
|
transfer = alloc_send_cmd28_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
|
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
|
||||||
@@ -853,15 +857,22 @@ dev_init (FpDevice *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_exit (FpDevice *dev)
|
deinitsm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, NULL);
|
||||||
|
|
||||||
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, &error);
|
|
||||||
|
|
||||||
fpi_device_close_complete (dev, error);
|
fpi_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_exit (FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new (dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
|
||||||
|
fpi_ssm_start (ssm, deinitsm_done);
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned char enroll_init[] = {
|
static const unsigned char enroll_init[] = {
|
||||||
0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
|
0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
|
||||||
};
|
};
|
||||||
@@ -972,9 +983,7 @@ enroll_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
if (error)
|
if (error)
|
||||||
fp_warn ("Error deinitializing: %s", error->message);
|
fp_warn ("Error deinitializing: %s", error->message);
|
||||||
|
|
||||||
fpi_device_enroll_complete (dev,
|
fpi_device_enroll_complete (dev, data->print, data->error);
|
||||||
g_steal_pointer (&data->print),
|
|
||||||
g_steal_pointer (&data->error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -983,7 +992,7 @@ do_enroll_stop (FpDevice *dev, FpPrint *print, GError *error)
|
|||||||
EnrollStopData *data = g_new0 (EnrollStopData, 1);
|
EnrollStopData *data = g_new0 (EnrollStopData, 1);
|
||||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||||
|
|
||||||
data->print = print;
|
data->print = g_object_ref (print);
|
||||||
data->error = error;
|
data->error = error;
|
||||||
|
|
||||||
fpi_ssm_start (ssm, enroll_stop_deinit_cb);
|
fpi_ssm_start (ssm, enroll_stop_deinit_cb);
|
||||||
@@ -1118,7 +1127,6 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
|
|||||||
data_len - sizeof (scan_comp),
|
data_len - sizeof (scan_comp),
|
||||||
1);
|
1);
|
||||||
|
|
||||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
|
||||||
g_object_set (print, "fpi-data", fp_data, NULL);
|
g_object_set (print, "fpi-data", fp_data, NULL);
|
||||||
g_object_ref (print);
|
g_object_ref (print);
|
||||||
}
|
}
|
||||||
@@ -1237,11 +1245,11 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
fp_warn ("Error deinitializing: %s", error->message);
|
fp_warn ("Error deinitializing: %s", error->message);
|
||||||
|
|
||||||
if (data->error)
|
if (data->error)
|
||||||
fpi_device_verify_complete (dev, g_steal_pointer (&data->error));
|
fpi_device_verify_complete (dev, data->error);
|
||||||
else
|
else
|
||||||
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
||||||
|
|
||||||
g_clear_error (&error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1251,7 +1259,7 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
|
|||||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||||
|
|
||||||
/* Report the error immediately if possible, otherwise delay it. */
|
/* Report the error immediately if possible, otherwise delay it. */
|
||||||
if (error && error->domain == FP_DEVICE_RETRY)
|
if (!error && error->domain != FP_DEVICE_RETRY)
|
||||||
fpi_device_verify_report (dev, res, NULL, error);
|
fpi_device_verify_report (dev, res, NULL, error);
|
||||||
else
|
else
|
||||||
data->error = error;
|
data->error = error;
|
||||||
@@ -1293,7 +1301,7 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
|
|||||||
|
|
||||||
case VERIFY_INIT:
|
case VERIFY_INIT:
|
||||||
fpi_device_get_verify_data (dev, &print);
|
fpi_device_get_verify_data (dev, &print);
|
||||||
g_object_get (print, "fpi-data", &fp_data, NULL);
|
g_object_get (dev, "fpi-data", &fp_data, NULL);
|
||||||
|
|
||||||
data = g_variant_get_fixed_array (fp_data, &data_len, 1);
|
data = g_variant_get_fixed_array (fp_data, &data_len, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -156,8 +156,6 @@ async_abort (FpDevice *dev, FpiSsm *ssm, int ep)
|
|||||||
else
|
else
|
||||||
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
|
||||||
|
|
||||||
transfer->ssm = ssm;
|
|
||||||
|
|
||||||
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
|
||||||
async_abort_callback, NULL);
|
async_abort_callback, NULL);
|
||||||
}
|
}
|
||||||
@@ -242,7 +240,6 @@ prepare_image (FpDeviceVfs0050 *vdev)
|
|||||||
|
|
||||||
/* Building GSList */
|
/* Building GSList */
|
||||||
GSList *lines = NULL;
|
GSList *lines = NULL;
|
||||||
|
|
||||||
for (int i = height - 1; i >= 0; --i)
|
for (int i = height - 1; i >= 0; --i)
|
||||||
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
|
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
|
||||||
|
|
||||||
@@ -467,8 +464,8 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
if (error)
|
if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
|
||||||
/* Capture is done when there is no more data to transfer or device timed out */
|
/* Check if fingerprint data is over */
|
||||||
if (transfer->actual_length <= 0)
|
if (transfer->actual_length == 0)
|
||||||
{
|
{
|
||||||
fpi_ssm_next_state (transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
@@ -476,7 +473,7 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
{
|
{
|
||||||
self->bytes += transfer->actual_length;
|
self->bytes += transfer->actual_length;
|
||||||
|
|
||||||
/* Try reading more data */
|
/* We need more data */
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
fpi_ssm_get_cur_state (transfer->ssm));
|
fpi_ssm_get_cur_state (transfer->ssm));
|
||||||
}
|
}
|
||||||
@@ -598,7 +595,8 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
|||||||
/* Receive chunk of data */
|
/* Receive chunk of data */
|
||||||
transfer = fpi_usb_transfer_new (dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
|
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
|
||||||
(guint8 *) self->lines_buffer + self->bytes,
|
(guint8 *)
|
||||||
|
(self->lines_buffer + self->bytes),
|
||||||
VFS_USB_BUFFER_SIZE, NULL);
|
VFS_USB_BUFFER_SIZE, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
||||||
@@ -670,7 +668,6 @@ dev_activate (FpImageDevice *idev)
|
|||||||
self->ssm_active = 1;
|
self->ssm_active = 1;
|
||||||
|
|
||||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, dev_activate_callback);
|
fpi_ssm_start (ssm, dev_activate_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,7 +711,6 @@ dev_open (FpImageDevice *idev)
|
|||||||
|
|
||||||
/* Clearing previous device state */
|
/* Clearing previous device state */
|
||||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, dev_open_callback);
|
fpi_ssm_start (ssm, dev_open_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ translate_str (const char **srcL, gssize *len)
|
|||||||
src_len += tmp;
|
src_len += tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (src_len >= 2);
|
|
||||||
*len = src_len / 2;
|
*len = src_len / 2;
|
||||||
res = g_malloc0 (*len);
|
res = g_malloc0 (*len);
|
||||||
dst = res;
|
dst = res;
|
||||||
|
|||||||
@@ -381,8 +381,9 @@ submit_image (FpiSsm *ssm,
|
|||||||
{
|
{
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
if (self->lines_recorded < VFS5011_IMAGE_WIDTH)
|
if (self->lines_recorded == 0)
|
||||||
{
|
{
|
||||||
|
/* == FP_ENROLL_RETRY_TOO_SHORT */
|
||||||
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
|
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
456
libfprint/drivers/virtual-device.c
Normal file
456
libfprint/drivers/virtual-device.c
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
/*
|
||||||
|
* Virtual driver for "simple" device debugging
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||||
|
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a virtual driver to debug the non-image based drivers. A small
|
||||||
|
* python script is provided to connect to it via a socket, allowing
|
||||||
|
* prints to registered programmatically.
|
||||||
|
* Using this, it is possible to test libfprint and fprintd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "virtual_device"
|
||||||
|
|
||||||
|
#include "fpi-log.h"
|
||||||
|
|
||||||
|
#include "../fpi-device.h"
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <gio/gunixsocketaddress.h>
|
||||||
|
|
||||||
|
#define MAX_LINE_LEN 1024
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VIRTUAL_DEVICE,
|
||||||
|
VIRTUAL_DEVICE_IDENT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _FpDeviceVirtualDevice
|
||||||
|
{
|
||||||
|
FpDevice parent;
|
||||||
|
|
||||||
|
GSocketListener *listener;
|
||||||
|
GSocketConnection *connection;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
|
||||||
|
gint socket_fd;
|
||||||
|
gint client_fd;
|
||||||
|
guint line[MAX_LINE_LEN];
|
||||||
|
|
||||||
|
GHashTable *pending_prints; /* key: finger+username value: gboolean */
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP, DEVICE_VIRTUAL_DEVICE, FpDevice)
|
||||||
|
G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE)
|
||||||
|
|
||||||
|
static void start_listen (FpDeviceVirtualDevice *self);
|
||||||
|
|
||||||
|
#define ADD_CMD_PREFIX "ADD "
|
||||||
|
|
||||||
|
static FpFinger
|
||||||
|
str_to_finger (const char *str)
|
||||||
|
{
|
||||||
|
g_autoptr(GEnumClass) eclass;
|
||||||
|
GEnumValue *value;
|
||||||
|
|
||||||
|
eclass = g_type_class_ref (FP_TYPE_FINGER);
|
||||||
|
value = g_enum_get_value_by_nick (eclass, str);
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
return FP_FINGER_UNKNOWN;
|
||||||
|
|
||||||
|
return value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
finger_to_str (FpFinger finger)
|
||||||
|
{
|
||||||
|
GEnumClass *eclass;
|
||||||
|
GEnumValue *value;
|
||||||
|
|
||||||
|
eclass = g_type_class_ref (FP_TYPE_FINGER);
|
||||||
|
value = g_enum_get_value (eclass, finger);
|
||||||
|
g_type_class_unref (eclass);
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return value->value_nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_code (const char *str)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (str, "1") == 0 ||
|
||||||
|
g_strcmp0 (str, "success") == 0 ||
|
||||||
|
g_strcmp0 (str, "SUCCESS") == 0 ||
|
||||||
|
g_strcmp0 (str, "FPI_MATCH_SUCCESS") == 0)
|
||||||
|
return FPI_MATCH_SUCCESS;
|
||||||
|
|
||||||
|
return FPI_MATCH_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_command_line (FpDeviceVirtualDevice *self,
|
||||||
|
const char *line)
|
||||||
|
{
|
||||||
|
if (g_str_has_prefix (line, ADD_CMD_PREFIX))
|
||||||
|
{
|
||||||
|
g_auto(GStrv) elems;
|
||||||
|
FpPrint *print;
|
||||||
|
FpFinger finger;
|
||||||
|
gboolean success;
|
||||||
|
g_autofree char *description = NULL;
|
||||||
|
char *key;
|
||||||
|
|
||||||
|
/* Syntax: ADD <finger> <username> <error when used> */
|
||||||
|
elems = g_strsplit (line + strlen (ADD_CMD_PREFIX), " ", 3);
|
||||||
|
if (g_strv_length (elems) != 3)
|
||||||
|
{
|
||||||
|
g_warning ("Malformed command: %s", line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finger = str_to_finger (elems[0]);
|
||||||
|
if (finger == FP_FINGER_UNKNOWN)
|
||||||
|
{
|
||||||
|
g_warning ("Unknown finger '%s'", elems[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print = fp_print_new (FP_DEVICE (self));
|
||||||
|
fp_print_set_finger (print, finger);
|
||||||
|
fp_print_set_username (print, elems[1]);
|
||||||
|
description = g_strdup_printf ("Fingerprint finger '%s' for user '%s'",
|
||||||
|
elems[0], elems[1]);
|
||||||
|
fp_print_set_description (print, description);
|
||||||
|
success = parse_code (elems[2]);
|
||||||
|
|
||||||
|
key = g_strdup_printf ("%s-%s", elems[0], elems[1]);
|
||||||
|
g_hash_table_insert (self->pending_prints,
|
||||||
|
key, GINT_TO_POINTER (success));
|
||||||
|
|
||||||
|
fp_dbg ("Added pending print %s for user %s (code: %s)",
|
||||||
|
elems[0], elems[1], success ? "FPI_MATCH_SUCCESS" : "FPI_MATCH_FAIL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Unhandled command sent: '%s'", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_instruction_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
FpDeviceVirtualDevice *self;
|
||||||
|
gboolean success;
|
||||||
|
gsize bytes;
|
||||||
|
|
||||||
|
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
||||||
|
|
||||||
|
if (!success || bytes == 0)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
||||||
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
|
||||||
|
return;
|
||||||
|
g_warning ("Error receiving instruction data: %s", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||||
|
handle_command_line (self, (const char *) self->line);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||||
|
g_clear_object (&self->connection);
|
||||||
|
|
||||||
|
start_listen (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_instruction (FpDeviceVirtualDevice *self,
|
||||||
|
GInputStream *stream)
|
||||||
|
{
|
||||||
|
memset (&self->line, 0, sizeof (self->line));
|
||||||
|
g_input_stream_read_all_async (stream,
|
||||||
|
self->line,
|
||||||
|
sizeof (self->line),
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
self->cancellable,
|
||||||
|
recv_instruction_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
new_connection_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GSocketConnection) connection = NULL;
|
||||||
|
GInputStream *stream;
|
||||||
|
FpDeviceVirtualDevice *self = user_data;
|
||||||
|
|
||||||
|
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
||||||
|
res,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (!connection)
|
||||||
|
{
|
||||||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_warning ("Error accepting a new connection: %s", error->message);
|
||||||
|
start_listen (self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Always further connections (but we disconnect them immediately
|
||||||
|
* if we already have a connection). */
|
||||||
|
if (self->connection)
|
||||||
|
{
|
||||||
|
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||||
|
start_listen (self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->connection = g_steal_pointer (&connection);
|
||||||
|
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
|
||||||
|
|
||||||
|
recv_instruction (self, stream);
|
||||||
|
|
||||||
|
fp_dbg ("Got a new connection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_listen (FpDeviceVirtualDevice *self)
|
||||||
|
{
|
||||||
|
fp_dbg ("Starting a new listener");
|
||||||
|
g_socket_listener_accept_async (self->listener,
|
||||||
|
self->cancellable,
|
||||||
|
new_connection_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_init (FpDevice *dev)
|
||||||
|
{
|
||||||
|
fpi_device_open_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_verify (FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpPrint *print;
|
||||||
|
|
||||||
|
g_autoptr(GVariant) data = NULL;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
|
fpi_device_get_verify_data (dev, &print);
|
||||||
|
g_object_get (print, "fpi-data", &data, NULL);
|
||||||
|
success = g_variant_get_boolean (data);
|
||||||
|
|
||||||
|
fpi_device_verify_report (dev,
|
||||||
|
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
||||||
|
NULL, NULL);
|
||||||
|
fpi_device_verify_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_enroll (FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||||
|
gpointer success_ptr;
|
||||||
|
FpPrint *print = NULL;
|
||||||
|
g_autofree char *key = NULL;
|
||||||
|
|
||||||
|
fpi_device_get_enroll_data (dev, &print);
|
||||||
|
key = g_strdup_printf ("%s-%s",
|
||||||
|
finger_to_str (fp_print_get_finger (print)),
|
||||||
|
fp_print_get_username (print));
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended (self->pending_prints, key, NULL, &success_ptr))
|
||||||
|
{
|
||||||
|
gboolean success = GPOINTER_TO_INT (success_ptr);
|
||||||
|
GVariant *fp_data;
|
||||||
|
|
||||||
|
fp_data = g_variant_new_boolean (success);
|
||||||
|
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||||
|
if (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT)
|
||||||
|
fpi_print_set_device_stored (print, TRUE);
|
||||||
|
g_object_set (print, "fpi-data", fp_data, NULL);
|
||||||
|
fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_enroll_complete (dev, NULL,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
|
"No pending result for this username/finger combination"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_deinit (FpDevice *dev)
|
||||||
|
{
|
||||||
|
fpi_device_close_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dev_supports_identify (FpDevice *dev)
|
||||||
|
{
|
||||||
|
return fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_identify (FpDevice *dev)
|
||||||
|
{
|
||||||
|
GPtrArray *templates;
|
||||||
|
FpPrint *result = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_assert (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT);
|
||||||
|
|
||||||
|
fpi_device_get_identify_data (dev, &templates);
|
||||||
|
|
||||||
|
for (i = 0; i < templates->len; i++)
|
||||||
|
{
|
||||||
|
FpPrint *template = g_ptr_array_index (templates, i);
|
||||||
|
g_autoptr(GVariant) data = NULL;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
|
g_object_get (dev, "fpi-data", &template, NULL);
|
||||||
|
success = g_variant_get_boolean (data);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
result = template;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
fpi_device_identify_report (dev, result, NULL, NULL);
|
||||||
|
fpi_device_identify_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_device_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_cancellable_cancel (self->cancellable);
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
g_clear_object (&self->listener);
|
||||||
|
g_clear_object (&self->connection);
|
||||||
|
g_hash_table_destroy (self->pending_prints);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_device_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GSocketListener) listener = NULL;
|
||||||
|
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||||
|
const char *env;
|
||||||
|
g_autoptr(GSocketAddress) addr = NULL;
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
self->client_fd = -1;
|
||||||
|
|
||||||
|
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||||
|
|
||||||
|
listener = g_socket_listener_new ();
|
||||||
|
g_socket_listener_set_backlog (listener, 1);
|
||||||
|
|
||||||
|
/* Remove any left over socket. */
|
||||||
|
g_unlink (env);
|
||||||
|
|
||||||
|
addr = g_unix_socket_address_new (env);
|
||||||
|
|
||||||
|
if (!g_socket_listener_add_address (listener,
|
||||||
|
addr,
|
||||||
|
G_SOCKET_TYPE_STREAM,
|
||||||
|
G_SOCKET_PROTOCOL_DEFAULT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||||
|
|
||||||
|
fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->listener = g_steal_pointer (&listener);
|
||||||
|
self->cancellable = g_cancellable_new ();
|
||||||
|
self->pending_prints = g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed)
|
||||||
|
G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed (object);
|
||||||
|
|
||||||
|
start_listen (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_device_init (FpDeviceVirtualDevice *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FpIdEntry driver_ids[] = {
|
||||||
|
{ .virtual_envvar = "FP_VIRTUAL_DEVICE", .driver_data = VIRTUAL_DEVICE },
|
||||||
|
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_IDENT", .driver_data = VIRTUAL_DEVICE_IDENT },
|
||||||
|
{ .virtual_envvar = NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||||
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->constructed = fpi_device_virtual_device_constructed;
|
||||||
|
object_class->finalize = fpi_device_virtual_device_finalize;
|
||||||
|
|
||||||
|
dev_class->id = FP_COMPONENT;
|
||||||
|
dev_class->full_name = "Virtual device for debugging";
|
||||||
|
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||||
|
dev_class->id_table = driver_ids;
|
||||||
|
dev_class->nr_enroll_stages = 5;
|
||||||
|
|
||||||
|
dev_class->open = dev_init;
|
||||||
|
dev_class->close = dev_deinit;
|
||||||
|
dev_class->verify = dev_verify;
|
||||||
|
dev_class->enroll = dev_enroll;
|
||||||
|
|
||||||
|
dev_class->identify = dev_identify;
|
||||||
|
dev_class->supports_identify = dev_supports_identify;
|
||||||
|
}
|
||||||
@@ -215,6 +215,7 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
|
|||||||
|
|
||||||
g_warning ("Error accepting a new connection: %s", error->message);
|
g_warning ("Error accepting a new connection: %s", error->message);
|
||||||
start_listen (dev);
|
start_listen (dev);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always further connections (but we disconnect them immediately
|
/* Always further connections (but we disconnect them immediately
|
||||||
@@ -252,7 +253,6 @@ dev_init (FpImageDevice *dev)
|
|||||||
g_autoptr(GSocketListener) listener = NULL;
|
g_autoptr(GSocketListener) listener = NULL;
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||||
const char *env;
|
const char *env;
|
||||||
|
|
||||||
g_autoptr(GSocketAddress) addr = NULL;
|
g_autoptr(GSocketAddress) addr = NULL;
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ dev_init (FpImageDevice *dev)
|
|||||||
{
|
{
|
||||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||||
|
|
||||||
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
fpi_image_device_open_complete (dev, g_steal_pointer (&error));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,16 @@
|
|||||||
#include "fp-device-private.h"
|
#include "fp-device-private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION: fp-device
|
* SECTION: fpi-device
|
||||||
* @title: FpDevice
|
* @title: Internal FpDevice
|
||||||
* @short_description: Fingerpint device routines
|
* @short_description: Internal device routines
|
||||||
*
|
*
|
||||||
* These are the public #FpDevice routines.
|
* The methods that are available for drivers to manipulate a device. See
|
||||||
|
* #FpDeviceClass for more information. Also note that most of these are
|
||||||
|
* not relevant for image based devices, see #FpImageDeviceClass in that
|
||||||
|
* case.
|
||||||
|
*
|
||||||
|
* Also see the public #FpDevice routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void fp_device_async_initable_iface_init (GAsyncInitableIface *iface);
|
static void fp_device_async_initable_iface_init (GAsyncInitableIface *iface);
|
||||||
@@ -502,6 +507,9 @@ fp_device_supports_identify (FpDevice *device)
|
|||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
|
if (cls->supports_identify != NULL)
|
||||||
|
return cls->supports_identify (device);
|
||||||
|
|
||||||
return cls->identify != NULL;
|
return cls->identify != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,6 +949,13 @@ fp_device_identify (FpDevice *device,
|
|||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!fp_device_supports_identify (device))
|
||||||
|
{
|
||||||
|
g_task_return_error (task,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!priv->is_open)
|
if (!priv->is_open)
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
|
|||||||
@@ -281,7 +281,6 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
|||||||
gint map_w, map_h;
|
gint map_w, map_h;
|
||||||
gint bw, bh, bd;
|
gint bw, bh, bd;
|
||||||
gint r;
|
gint r;
|
||||||
g_autofree LFSPARMS *lfsparms;
|
|
||||||
|
|
||||||
/* Normalize the image first */
|
/* Normalize the image first */
|
||||||
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
||||||
@@ -295,15 +294,12 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
|||||||
|
|
||||||
data->flags &= ~(FPI_IMAGE_H_FLIPPED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_COLORS_INVERTED);
|
data->flags &= ~(FPI_IMAGE_H_FLIPPED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_COLORS_INVERTED);
|
||||||
|
|
||||||
lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS));
|
|
||||||
lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE;
|
|
||||||
|
|
||||||
timer = g_timer_new ();
|
timer = g_timer_new ();
|
||||||
r = get_minutiae (&minutiae, &quality_map, &direction_map,
|
r = get_minutiae (&minutiae, &quality_map, &direction_map,
|
||||||
&low_contrast_map, &low_flow_map, &high_curve_map,
|
&low_contrast_map, &low_flow_map, &high_curve_map,
|
||||||
&map_w, &map_h, &bdata, &bw, &bh, &bd,
|
&map_w, &map_h, &bdata, &bw, &bh, &bd,
|
||||||
data->image, data->width, data->height, 8,
|
data->image, data->width, data->height, 8,
|
||||||
data->ppmm, lfsparms);
|
data->ppmm, &g_lfsparms_V2);
|
||||||
g_timer_stop (timer);
|
g_timer_stop (timer);
|
||||||
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
|
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
|
||||||
|
|
||||||
|
|||||||
@@ -822,7 +822,7 @@ fp_print_deserialize (const guchar *data,
|
|||||||
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
||||||
for (i = 0; i < g_variant_n_children (prints); i++)
|
for (i = 0; i < g_variant_n_children (prints); i++)
|
||||||
{
|
{
|
||||||
g_autofree struct xyt_struct *xyt = NULL;
|
g_autofree struct xyt_struct *xyt = g_new0 (struct xyt_struct, 1);
|
||||||
const gint32 *xcol, *ycol, *thetacol;
|
const gint32 *xcol, *ycol, *thetacol;
|
||||||
gsize xlen, ylen, thetalen;
|
gsize xlen, ylen, thetalen;
|
||||||
g_autoptr(GVariant) xyt_data = NULL;
|
g_autoptr(GVariant) xyt_data = NULL;
|
||||||
@@ -848,7 +848,6 @@ fp_print_deserialize (const guchar *data,
|
|||||||
if (xlen > G_N_ELEMENTS (xyt->xcol))
|
if (xlen > G_N_ELEMENTS (xyt->xcol))
|
||||||
goto invalid_format;
|
goto invalid_format;
|
||||||
|
|
||||||
xyt = g_new0 (struct xyt_struct, 1);
|
|
||||||
xyt->nrows = xlen;
|
xyt->nrows = xlen;
|
||||||
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
|
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
|
||||||
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
|
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
|
||||||
|
|||||||
@@ -912,20 +912,6 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
|||||||
{
|
{
|
||||||
if (FP_IS_PRINT (print))
|
if (FP_IS_PRINT (print))
|
||||||
{
|
{
|
||||||
FpiPrintType print_type;
|
|
||||||
|
|
||||||
g_object_get (print, "fpi-type", &print_type, NULL);
|
|
||||||
if (print_type == FPI_PRINT_UNDEFINED)
|
|
||||||
{
|
|
||||||
g_warning ("Driver did not set the type on the returned print!");
|
|
||||||
g_clear_object (&print);
|
|
||||||
|
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"Driver provided incorrect print data!");
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ struct _FpIdEntry
|
|||||||
* @delete: Delete a print from the device
|
* @delete: Delete a print from the device
|
||||||
* @cancel: Called on cancellation, this is a convenience to not need to handle
|
* @cancel: Called on cancellation, this is a convenience to not need to handle
|
||||||
* the #GCancellable directly by using fpi_device_get_cancellable().
|
* the #GCancellable directly by using fpi_device_get_cancellable().
|
||||||
|
* @supports_identify: Whether identify operations are supported.
|
||||||
*
|
*
|
||||||
* NOTE: If your driver is image based, then you should subclass #FpImageDevice
|
* NOTE: If your driver is image based, then you should subclass #FpImageDevice
|
||||||
* instead. #FpImageDevice based drivers use a different way of interacting
|
* instead. #FpImageDevice based drivers use a different way of interacting
|
||||||
@@ -129,6 +130,8 @@ struct _FpDeviceClass
|
|||||||
void (*delete) (FpDevice * device);
|
void (*delete) (FpDevice * device);
|
||||||
|
|
||||||
void (*cancel) (FpDevice *device);
|
void (*cancel) (FpDevice *device);
|
||||||
|
|
||||||
|
gboolean (*supports_identify) (FpDevice *device);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,11 +24,12 @@
|
|||||||
#include "fp-image-device.h"
|
#include "fp-image-device.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION: fpi-image-device
|
* SECTION: fpi-image
|
||||||
* @title: Internal FpImageDevice
|
* @title: Internal FpImage
|
||||||
* @short_description: Internal image device functions
|
* @short_description: Internal image handling routines
|
||||||
*
|
*
|
||||||
* Internal image device functions. See #FpImageDevice for public routines.
|
* Internal image handling routines. Also see the public <ulink
|
||||||
|
* url="libfprint-FpImage.html">FpImage routines</ulink>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Manually redefine what G_DEFINE_* macro does */
|
/* Manually redefine what G_DEFINE_* macro does */
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
* @title: Internal FpImage
|
* @title: Internal FpImage
|
||||||
* @short_description: Internal image handling routines
|
* @short_description: Internal image handling routines
|
||||||
*
|
*
|
||||||
* Internal image handling routines. See #FpImage for public routines.
|
* Internal image handling routines. Also see the public <ulink
|
||||||
|
* url="libfprint-FpImage.html">FpImage routines</ulink>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ typedef enum {
|
|||||||
FPI_IMAGE_V_FLIPPED = 1 << 0,
|
FPI_IMAGE_V_FLIPPED = 1 << 0,
|
||||||
FPI_IMAGE_H_FLIPPED = 1 << 1,
|
FPI_IMAGE_H_FLIPPED = 1 << 1,
|
||||||
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
|
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
|
||||||
FPI_IMAGE_PARTIAL = 1 << 3,
|
|
||||||
} FpiImageFlags;
|
} FpiImageFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -155,6 +155,9 @@ foreach driver: drivers
|
|||||||
if driver == 'virtual_image'
|
if driver == 'virtual_image'
|
||||||
drivers_sources += [ 'drivers/virtual-image.c' ]
|
drivers_sources += [ 'drivers/virtual-image.c' ]
|
||||||
endif
|
endif
|
||||||
|
if driver == 'virtual_device'
|
||||||
|
drivers_sources += [ 'drivers/virtual-device.c' ]
|
||||||
|
endif
|
||||||
if driver == 'synaptics'
|
if driver == 'synaptics'
|
||||||
drivers_sources += [
|
drivers_sources += [
|
||||||
'drivers/synaptics/synaptics.c',
|
'drivers/synaptics/synaptics.c',
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
diff --git a/libfprint/nbis/mindtct/contour.c b/libfprint/nbis/mindtct/contour.c
|
|
||||||
index 3e9416c..31f32d0 100644
|
|
||||||
--- mindtct/contour.c
|
|
||||||
+++ mindtct/contour.c
|
|
||||||
@@ -440,6 +440,8 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
|
|
||||||
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
|
|
||||||
int i, j, ret;
|
|
||||||
|
|
||||||
+ g_assert (half_contour > 0);
|
|
||||||
+
|
|
||||||
/* Compute maximum length of complete contour */
|
|
||||||
/* (2 half contours + feature point). */
|
|
||||||
max_contour = (half_contour<<1) + 1;
|
|
||||||
diff --git a/libfprint/nbis/mindtct/minutia.c b/libfprint/nbis/mindtct/minutia.c
|
|
||||||
index 0b29aa0..77cf09d 100644
|
|
||||||
--- mindtct/minutia.c
|
|
||||||
+++ mindtct/minutia.c
|
|
||||||
@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
|
|
||||||
dmapval, bdata, iw, ih, lfsparms);
|
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
|
||||||
- if(ret == IGNORE)
|
|
||||||
+ if(ret != 0)
|
|
||||||
/* Deallocate the minutia. */
|
|
||||||
free_minutia(minutia);
|
|
||||||
|
|
||||||
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
|
|
||||||
dmapval, bdata, iw, ih, lfsparms);
|
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
|
||||||
- if(ret == IGNORE)
|
|
||||||
+ if(ret != 0)
|
|
||||||
/* Deallocate the minutia. */
|
|
||||||
free_minutia(minutia);
|
|
||||||
|
|
||||||
diff --git a/libfprint/nbis/mindtct/ridges.c b/libfprint/nbis/mindtct/ridges.c
|
|
||||||
index f0d9cd3..9902585 100644
|
|
||||||
--- mindtct/ridges.c
|
|
||||||
+++ mindtct/ridges.c
|
|
||||||
@@ -147,6 +147,8 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
|
||||||
{
|
|
||||||
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
|
||||||
|
|
||||||
+ g_assert (lfsparms->max_nbrs > 0);
|
|
||||||
+
|
|
||||||
/* Find up to the maximum number of qualifying neighbors. */
|
|
||||||
nbr_list = NULL;
|
|
||||||
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
|
||||||
@@ -407,6 +409,8 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
+ g_assert (pos >= 0);
|
|
||||||
+
|
|
||||||
/* If the desired insertion position is beyond one passed the last */
|
|
||||||
/* neighbor in the lists OR greater than equal to the maximum ... */
|
|
||||||
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
|
||||||
@@ -260,8 +260,6 @@ typedef struct g_lfsparms{
|
|||||||
int pores_steps_bwd;
|
int pores_steps_bwd;
|
||||||
double pores_min_dist2;
|
double pores_min_dist2;
|
||||||
double pores_max_ratio;
|
double pores_max_ratio;
|
||||||
int remove_perimeter_pts;
|
|
||||||
int min_pp_distance;
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
int max_nbrs;
|
int max_nbrs;
|
||||||
@@ -611,9 +609,6 @@ typedef struct g_lfsparms{
|
|||||||
/* contour points to be considered a pore. */
|
/* contour points to be considered a pore. */
|
||||||
#define PORES_MAX_RATIO 2.25
|
#define PORES_MAX_RATIO 2.25
|
||||||
|
|
||||||
/* Points which are closer than this distance to scan perimeter will be removed */
|
|
||||||
#define PERIMETER_PTS_DISTANCE 10
|
|
||||||
|
|
||||||
|
|
||||||
/***** RIDGE COUNTING CONSTANTS *****/
|
/***** RIDGE COUNTING CONSTANTS *****/
|
||||||
|
|
||||||
@@ -1128,9 +1123,6 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
|
|||||||
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
int *, const int, const int, const LFSPARMS *);
|
int *, const int, const int, const LFSPARMS *);
|
||||||
extern int remove_perimeter_pts(MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms);
|
|
||||||
|
|
||||||
/* results.c */
|
/* results.c */
|
||||||
extern int write_text_results(char *, const int, const int, const int,
|
extern int write_text_results(char *, const int, const int, const int,
|
||||||
|
|||||||
@@ -440,8 +440,6 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
|
|||||||
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
|
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
|
|
||||||
g_assert (half_contour > 0);
|
|
||||||
|
|
||||||
/* Compute maximum length of complete contour */
|
/* Compute maximum length of complete contour */
|
||||||
/* (2 half contours + feature point). */
|
/* (2 half contours + feature point). */
|
||||||
max_contour = (half_contour<<1) + 1;
|
max_contour = (half_contour<<1) + 1;
|
||||||
|
|||||||
@@ -150,8 +150,6 @@ LFSPARMS g_lfsparms = {
|
|||||||
PORES_STEPS_BWD,
|
PORES_STEPS_BWD,
|
||||||
PORES_MIN_DIST2,
|
PORES_MIN_DIST2,
|
||||||
PORES_MAX_RATIO,
|
PORES_MAX_RATIO,
|
||||||
FALSE, /* not removing perimeter points by default */
|
|
||||||
PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
MAX_NBRS,
|
MAX_NBRS,
|
||||||
@@ -236,8 +234,6 @@ LFSPARMS g_lfsparms_V2 = {
|
|||||||
PORES_STEPS_BWD,
|
PORES_STEPS_BWD,
|
||||||
PORES_MIN_DIST2,
|
PORES_MIN_DIST2,
|
||||||
PORES_MAX_RATIO,
|
PORES_MAX_RATIO,
|
||||||
FALSE, /* not removing perimeter points by default */
|
|
||||||
PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
MAX_NBRS,
|
MAX_NBRS,
|
||||||
|
|||||||
@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
|
|||||||
dmapval, bdata, iw, ih, lfsparms);
|
dmapval, bdata, iw, ih, lfsparms);
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||||
if(ret != 0)
|
if(ret == IGNORE)
|
||||||
/* Deallocate the minutia. */
|
/* Deallocate the minutia. */
|
||||||
free_minutia(minutia);
|
free_minutia(minutia);
|
||||||
|
|
||||||
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
|
|||||||
dmapval, bdata, iw, ih, lfsparms);
|
dmapval, bdata, iw, ih, lfsparms);
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||||
if(ret != 0)
|
if(ret == IGNORE)
|
||||||
/* Deallocate the minutia. */
|
/* Deallocate the minutia. */
|
||||||
free_minutia(minutia);
|
free_minutia(minutia);
|
||||||
|
|
||||||
|
|||||||
@@ -195,11 +195,6 @@ int remove_false_minutia_V2(MINUTIAE *minutiae,
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 11. Remove minutiae on image edge */
|
|
||||||
if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) {
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1334,159 +1329,6 @@ int remove_pointing_invblock_V2(MINUTIAE *minutiae,
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int i, dist;
|
|
||||||
for (i = 0; i < minutiae->num; i++) {
|
|
||||||
if (to_remove[i])
|
|
||||||
continue;
|
|
||||||
dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) +
|
|
||||||
(y - minutiae->list[i]->y) * (y - minutiae->list[i]->y));
|
|
||||||
if (dist < lfsparms->min_pp_distance) {
|
|
||||||
to_remove[i] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: remove_perimeter_pts - Takes a list of true and false minutiae and
|
|
||||||
#cat: attempts to detect and remove those false minutiae that
|
|
||||||
#cat: belong to image edge
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutiae - list of true and false minutiae
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Output:
|
|
||||||
minutiae - list of pruned minutiae
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
int remove_perimeter_pts(MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int i, j, ret, *to_remove;
|
|
||||||
int *left, *left_up, *left_down;
|
|
||||||
int *right, *right_up, *right_down;
|
|
||||||
int removed = 0;
|
|
||||||
int left_min, right_max;
|
|
||||||
|
|
||||||
if (!lfsparms->remove_perimeter_pts)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
to_remove = calloc(minutiae->num, sizeof(int));
|
|
||||||
left = calloc(ih, sizeof(int));
|
|
||||||
left_up = calloc(ih, sizeof(int));
|
|
||||||
left_down = calloc(ih, sizeof(int));
|
|
||||||
right = calloc(ih, sizeof(int));
|
|
||||||
right_up = calloc(ih, sizeof(int));
|
|
||||||
right_down = calloc(ih, sizeof(int));
|
|
||||||
|
|
||||||
/* Pass downwards */
|
|
||||||
left_min = iw - 1;
|
|
||||||
right_max = 0;
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
for (j = 0; j < left_min; j++) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
left_min = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left_min == (iw - 1))
|
|
||||||
left_down[i] = -1;
|
|
||||||
else
|
|
||||||
left_down[i] = left_min;
|
|
||||||
for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
right_max = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (right_max == 0)
|
|
||||||
right_down[i] = -1;
|
|
||||||
else
|
|
||||||
right_down[i] = right_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pass upwards */
|
|
||||||
left_min = iw - 1;
|
|
||||||
right_max = 0;
|
|
||||||
for (i = ih - 1; i >= 0; i--) {
|
|
||||||
for (j = 0; j < left_min; j++) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
left_min = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left_min == (iw - 1))
|
|
||||||
left_up[i] = -1;
|
|
||||||
else
|
|
||||||
left_up[i] = left_min;
|
|
||||||
for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
right_max = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (right_max == 0)
|
|
||||||
right_up[i] = -1;
|
|
||||||
else
|
|
||||||
right_up[i] = right_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge */
|
|
||||||
left_min = left_down[ih - 1];
|
|
||||||
right_max = right_down[ih - 1];
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
if (left_down[i] != left_min)
|
|
||||||
left[i] = left_down[i];
|
|
||||||
else
|
|
||||||
left[i] = left_up[i];
|
|
||||||
|
|
||||||
if (right_down[i] != right_max)
|
|
||||||
right[i] = right_down[i];
|
|
||||||
else
|
|
||||||
right[i] = right_up[i];
|
|
||||||
}
|
|
||||||
free(left_up);
|
|
||||||
free(left_down);
|
|
||||||
free(right_up);
|
|
||||||
free(right_down);
|
|
||||||
|
|
||||||
/* Mark minitiae close to the edge */
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
if (left[i] != -1)
|
|
||||||
mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms);
|
|
||||||
if (right[i] != -1)
|
|
||||||
mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(left);
|
|
||||||
free(right);
|
|
||||||
|
|
||||||
for (i = minutiae->num - 1; i >= 0; i--) {
|
|
||||||
/* If the current minutia index is flagged for removal ... */
|
|
||||||
if (to_remove[i]){
|
|
||||||
removed ++;
|
|
||||||
/* Remove the minutia from the minutiae list. */
|
|
||||||
if((ret = remove_minutia(i, minutiae))){
|
|
||||||
free(to_remove);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(to_remove);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_overlaps - Takes a list of true and false minutiae and
|
#cat: remove_overlaps - Takes a list of true and false minutiae and
|
||||||
|
|||||||
@@ -147,8 +147,6 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
|||||||
{
|
{
|
||||||
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
||||||
|
|
||||||
g_assert (lfsparms->max_nbrs > 0);
|
|
||||||
|
|
||||||
/* Find up to the maximum number of qualifying neighbors. */
|
/* Find up to the maximum number of qualifying neighbors. */
|
||||||
nbr_list = NULL;
|
nbr_list = NULL;
|
||||||
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
||||||
@@ -409,8 +407,6 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_assert (pos >= 0);
|
|
||||||
|
|
||||||
/* If the desired insertion position is beyond one passed the last */
|
/* If the desired insertion position is beyond one passed the last */
|
||||||
/* neighbor in the lists OR greater than equal to the maximum ... */
|
/* neighbor in the lists OR greater than equal to the maximum ... */
|
||||||
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
||||||
|
|||||||
@@ -1,231 +0,0 @@
|
|||||||
diff --git nbis/include/lfs.h nbis/include/lfs.h
|
|
||||||
index f4f38d7..8b12e73 100644
|
|
||||||
--- nbis/include/lfs.h
|
|
||||||
+++ nbis/include/lfs.h
|
|
||||||
@@ -260,6 +260,8 @@ typedef struct g_lfsparms{
|
|
||||||
int pores_steps_bwd;
|
|
||||||
double pores_min_dist2;
|
|
||||||
double pores_max_ratio;
|
|
||||||
+ int remove_perimeter_pts;
|
|
||||||
+ int min_pp_distance;
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
|
||||||
int max_nbrs;
|
|
||||||
@@ -609,6 +611,9 @@ typedef struct g_lfsparms{
|
|
||||||
/* contour points to be considered a pore. */
|
|
||||||
#define PORES_MAX_RATIO 2.25
|
|
||||||
|
|
||||||
+/* Points which are closer than this distance to scan perimeter will be removed */
|
|
||||||
+#define PERIMETER_PTS_DISTANCE 10
|
|
||||||
+
|
|
||||||
|
|
||||||
/***** RIDGE COUNTING CONSTANTS *****/
|
|
||||||
|
|
||||||
@@ -1123,6 +1128,9 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
|
|
||||||
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
|
||||||
unsigned char *, const int, const int,
|
|
||||||
int *, const int, const int, const LFSPARMS *);
|
|
||||||
+extern int remove_perimeter_pts(MINUTIAE *minutiae,
|
|
||||||
+ unsigned char *bdata, const int iw, const int ih,
|
|
||||||
+ const LFSPARMS *lfsparms);
|
|
||||||
|
|
||||||
/* results.c */
|
|
||||||
extern int write_text_results(char *, const int, const int, const int,
|
|
||||||
diff --git nbis/mindtct/globals.c nbis/mindtct/globals.c
|
|
||||||
index da10c15..79bc583 100644
|
|
||||||
--- nbis/mindtct/globals.c
|
|
||||||
+++ nbis/mindtct/globals.c
|
|
||||||
@@ -150,6 +150,8 @@ LFSPARMS g_lfsparms = {
|
|
||||||
PORES_STEPS_BWD,
|
|
||||||
PORES_MIN_DIST2,
|
|
||||||
PORES_MAX_RATIO,
|
|
||||||
+ FALSE, /* not removing perimeter points by default */
|
|
||||||
+ PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
|
||||||
MAX_NBRS,
|
|
||||||
@@ -234,6 +236,8 @@ LFSPARMS g_lfsparms_V2 = {
|
|
||||||
PORES_STEPS_BWD,
|
|
||||||
PORES_MIN_DIST2,
|
|
||||||
PORES_MAX_RATIO,
|
|
||||||
+ FALSE, /* not removing perimeter points by default */
|
|
||||||
+ PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
|
||||||
MAX_NBRS,
|
|
||||||
diff --git nbis/mindtct/remove.c nbis/mindtct/remove.c
|
|
||||||
index af5ab7d..7311f1c 100644
|
|
||||||
--- nbis/mindtct/remove.c
|
|
||||||
+++ nbis/mindtct/remove.c
|
|
||||||
@@ -195,6 +195,11 @@ int remove_false_minutia_V2(MINUTIAE *minutiae,
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* 11. Remove minutiae on image edge */
|
|
||||||
+ if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) {
|
|
||||||
+ return (ret);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1329,6 +1334,159 @@ int remove_pointing_invblock_V2(MINUTIAE *minutiae,
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y,
|
|
||||||
+ const LFSPARMS *lfsparms)
|
|
||||||
+{
|
|
||||||
+ int i, dist;
|
|
||||||
+ for (i = 0; i < minutiae->num; i++) {
|
|
||||||
+ if (to_remove[i])
|
|
||||||
+ continue;
|
|
||||||
+ dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) +
|
|
||||||
+ (y - minutiae->list[i]->y) * (y - minutiae->list[i]->y));
|
|
||||||
+ if (dist < lfsparms->min_pp_distance) {
|
|
||||||
+ to_remove[i] = 1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*************************************************************************
|
|
||||||
+**************************************************************************
|
|
||||||
+#cat: remove_perimeter_pts - Takes a list of true and false minutiae and
|
|
||||||
+#cat: attempts to detect and remove those false minutiae that
|
|
||||||
+#cat: belong to image edge
|
|
||||||
+
|
|
||||||
+ Input:
|
|
||||||
+ minutiae - list of true and false minutiae
|
|
||||||
+ bdata - binary image data (0==while & 1==black)
|
|
||||||
+ iw - width (in pixels) of image
|
|
||||||
+ ih - height (in pixels) of image
|
|
||||||
+ lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
+ Output:
|
|
||||||
+ minutiae - list of pruned minutiae
|
|
||||||
+ Return Code:
|
|
||||||
+ Zero - successful completion
|
|
||||||
+ Negative - system error
|
|
||||||
+**************************************************************************/
|
|
||||||
+int remove_perimeter_pts(MINUTIAE *minutiae,
|
|
||||||
+ unsigned char *bdata, const int iw, const int ih,
|
|
||||||
+ const LFSPARMS *lfsparms)
|
|
||||||
+{
|
|
||||||
+ int i, j, ret, *to_remove;
|
|
||||||
+ int *left, *left_up, *left_down;
|
|
||||||
+ int *right, *right_up, *right_down;
|
|
||||||
+ int removed = 0;
|
|
||||||
+ int left_min, right_max;
|
|
||||||
+
|
|
||||||
+ if (!lfsparms->remove_perimeter_pts)
|
|
||||||
+ return(0);
|
|
||||||
+
|
|
||||||
+ to_remove = calloc(minutiae->num, sizeof(int));
|
|
||||||
+ left = calloc(ih, sizeof(int));
|
|
||||||
+ left_up = calloc(ih, sizeof(int));
|
|
||||||
+ left_down = calloc(ih, sizeof(int));
|
|
||||||
+ right = calloc(ih, sizeof(int));
|
|
||||||
+ right_up = calloc(ih, sizeof(int));
|
|
||||||
+ right_down = calloc(ih, sizeof(int));
|
|
||||||
+
|
|
||||||
+ /* Pass downwards */
|
|
||||||
+ left_min = iw - 1;
|
|
||||||
+ right_max = 0;
|
|
||||||
+ for (i = 0; i < ih; i++) {
|
|
||||||
+ for (j = 0; j < left_min; j++) {
|
|
||||||
+ if ((bdata[i * iw + j] != 0)) {
|
|
||||||
+ left_min = j;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (left_min == (iw - 1))
|
|
||||||
+ left_down[i] = -1;
|
|
||||||
+ else
|
|
||||||
+ left_down[i] = left_min;
|
|
||||||
+ for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
+ if ((bdata[i * iw + j] != 0)) {
|
|
||||||
+ right_max = j;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (right_max == 0)
|
|
||||||
+ right_down[i] = -1;
|
|
||||||
+ else
|
|
||||||
+ right_down[i] = right_max;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Pass upwards */
|
|
||||||
+ left_min = iw - 1;
|
|
||||||
+ right_max = 0;
|
|
||||||
+ for (i = ih - 1; i >= 0; i--) {
|
|
||||||
+ for (j = 0; j < left_min; j++) {
|
|
||||||
+ if ((bdata[i * iw + j] != 0)) {
|
|
||||||
+ left_min = j;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (left_min == (iw - 1))
|
|
||||||
+ left_up[i] = -1;
|
|
||||||
+ else
|
|
||||||
+ left_up[i] = left_min;
|
|
||||||
+ for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
+ if ((bdata[i * iw + j] != 0)) {
|
|
||||||
+ right_max = j;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (right_max == 0)
|
|
||||||
+ right_up[i] = -1;
|
|
||||||
+ else
|
|
||||||
+ right_up[i] = right_max;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Merge */
|
|
||||||
+ left_min = left_down[ih - 1];
|
|
||||||
+ right_max = right_down[ih - 1];
|
|
||||||
+ for (i = 0; i < ih; i++) {
|
|
||||||
+ if (left_down[i] != left_min)
|
|
||||||
+ left[i] = left_down[i];
|
|
||||||
+ else
|
|
||||||
+ left[i] = left_up[i];
|
|
||||||
+
|
|
||||||
+ if (right_down[i] != right_max)
|
|
||||||
+ right[i] = right_down[i];
|
|
||||||
+ else
|
|
||||||
+ right[i] = right_up[i];
|
|
||||||
+ }
|
|
||||||
+ free(left_up);
|
|
||||||
+ free(left_down);
|
|
||||||
+ free(right_up);
|
|
||||||
+ free(right_down);
|
|
||||||
+
|
|
||||||
+ /* Mark minitiae close to the edge */
|
|
||||||
+ for (i = 0; i < ih; i++) {
|
|
||||||
+ if (left[i] != -1)
|
|
||||||
+ mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms);
|
|
||||||
+ if (right[i] != -1)
|
|
||||||
+ mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ free(left);
|
|
||||||
+ free(right);
|
|
||||||
+
|
|
||||||
+ for (i = minutiae->num - 1; i >= 0; i--) {
|
|
||||||
+ /* If the current minutia index is flagged for removal ... */
|
|
||||||
+ if (to_remove[i]){
|
|
||||||
+ removed ++;
|
|
||||||
+ /* Remove the minutia from the minutiae list. */
|
|
||||||
+ if((ret = remove_minutia(i, minutiae))){
|
|
||||||
+ free(to_remove);
|
|
||||||
+ return(ret);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ free(to_remove);
|
|
||||||
+
|
|
||||||
+ return (0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: remove_overlaps - Takes a list of true and false minutiae and
|
|
||||||
@@ -192,9 +192,3 @@ spatch --sp-file remove-global-y.cocci bozorth3/* include/bozorth.h --in-place
|
|||||||
# The above leaves an unused variable around, triggering a warning
|
# The above leaves an unused variable around, triggering a warning
|
||||||
# remove it.
|
# remove it.
|
||||||
patch -p0 < glib-mem-warning.patch
|
patch -p0 < glib-mem-warning.patch
|
||||||
|
|
||||||
# Also fix some scan-build warnings, mostly by adding assertions
|
|
||||||
patch -p0 < fix-scan-build-reports.patch
|
|
||||||
|
|
||||||
# Add pass to remove perimeter points
|
|
||||||
patch -p0 < remove-perimeter-pts.patch
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ cairo_dep = dependency('cairo', required: false)
|
|||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
drivers = get_option('drivers').split(',')
|
drivers = get_option('drivers').split(',')
|
||||||
virtual_drivers = [ 'virtual_image' ]
|
virtual_drivers = [ 'virtual_image', 'virtual_device' ]
|
||||||
default_drivers = [
|
default_drivers = [
|
||||||
'upektc_img',
|
'upektc_img',
|
||||||
'vfs5011',
|
'vfs5011',
|
||||||
|
|||||||
@@ -100,10 +100,7 @@ fpi_device_fake_enroll (FpDevice *device)
|
|||||||
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
|
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
|
||||||
|
|
||||||
if (!print && !fake_dev->ret_error)
|
if (!print && !fake_dev->ret_error)
|
||||||
{
|
|
||||||
fpi_device_get_enroll_data (device, &print);
|
fpi_device_get_enroll_data (device, &print);
|
||||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_device_enroll_complete (device,
|
fpi_device_enroll_complete (device,
|
||||||
print ? g_object_ref (print) : NULL,
|
print ? g_object_ref (print) : NULL,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ test_context_has_virtual_device (void)
|
|||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
fpt_setup_virtual_device_environment ();
|
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
context = fp_context_new ();
|
context = fp_context_new ();
|
||||||
devices = fp_context_get_devices (context);
|
devices = fp_context_get_devices (context);
|
||||||
@@ -70,7 +70,7 @@ test_context_has_virtual_device (void)
|
|||||||
|
|
||||||
g_assert_true (FP_IS_DEVICE (virtual_device));
|
g_assert_true (FP_IS_DEVICE (virtual_device));
|
||||||
|
|
||||||
fpt_teardown_virtual_device_environment ();
|
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -81,7 +81,7 @@ test_context_enumerates_new_devices (void)
|
|||||||
|
|
||||||
context = fp_context_new ();
|
context = fp_context_new ();
|
||||||
|
|
||||||
fpt_setup_virtual_device_environment ();
|
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_context_enumerate (context);
|
fp_context_enumerate (context);
|
||||||
devices = fp_context_get_devices (context);
|
devices = fp_context_get_devices (context);
|
||||||
@@ -89,7 +89,7 @@ test_context_enumerates_new_devices (void)
|
|||||||
g_assert_nonnull (devices);
|
g_assert_nonnull (devices);
|
||||||
g_assert_cmpuint (devices->len, ==, 1);
|
g_assert_cmpuint (devices->len, ==, 1);
|
||||||
|
|
||||||
fpt_teardown_virtual_device_environment ();
|
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
|||||||
static void
|
static void
|
||||||
test_device_open_async (void)
|
test_device_open_async (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
|||||||
static void
|
static void
|
||||||
test_device_close_async (void)
|
test_device_close_async (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||||
while (!tctx->user_data)
|
while (!tctx->user_data)
|
||||||
@@ -76,7 +76,7 @@ static void
|
|||||||
test_device_open_sync (void)
|
test_device_open_sync (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, &error);
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@@ -97,7 +97,7 @@ static void
|
|||||||
test_device_open_sync_notify (void)
|
test_device_open_sync_notify (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
||||||
fp_device_open_sync (tctx->device, NULL, &error);
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
@@ -109,7 +109,7 @@ static void
|
|||||||
test_device_close_sync (void)
|
test_device_close_sync (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
fp_device_close_sync (tctx->device, NULL, &error);
|
fp_device_close_sync (tctx->device, NULL, &error);
|
||||||
@@ -131,7 +131,7 @@ static void
|
|||||||
test_device_close_sync_notify (void)
|
test_device_close_sync_notify (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_driver (void)
|
test_device_get_driver (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
||||||
@@ -153,7 +153,7 @@ test_device_get_driver (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_device_id (void)
|
test_device_get_device_id (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
||||||
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_name (void)
|
test_device_get_name (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
||||||
@@ -172,7 +172,7 @@ test_device_get_name (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_scan_type (void)
|
test_device_get_scan_type (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
||||||
@@ -181,7 +181,7 @@ test_device_get_scan_type (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_nr_enroll_stages (void)
|
test_device_get_nr_enroll_stages (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
||||||
@@ -190,7 +190,7 @@ test_device_get_nr_enroll_stages (void)
|
|||||||
static void
|
static void
|
||||||
test_device_supports_identify (void)
|
test_device_supports_identify (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_true (fp_device_supports_identify (tctx->device));
|
g_assert_true (fp_device_supports_identify (tctx->device));
|
||||||
@@ -199,7 +199,7 @@ test_device_supports_identify (void)
|
|||||||
static void
|
static void
|
||||||
test_device_supports_capture (void)
|
test_device_supports_capture (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_true (fp_device_supports_capture (tctx->device));
|
g_assert_true (fp_device_supports_capture (tctx->device));
|
||||||
@@ -208,7 +208,7 @@ test_device_supports_capture (void)
|
|||||||
static void
|
static void
|
||||||
test_device_has_storage (void)
|
test_device_has_storage (void)
|
||||||
{
|
{
|
||||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_false (fp_device_has_storage (tctx->device));
|
g_assert_false (fp_device_has_storage (tctx->device));
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ test_frame_assembling (void)
|
|||||||
ctx.frame_height = 20;
|
ctx.frame_height = 20;
|
||||||
ctx.image_width = width;
|
ctx.image_width = width;
|
||||||
|
|
||||||
g_assert (height > ctx.frame_height);
|
|
||||||
|
|
||||||
offset = 10;
|
offset = 10;
|
||||||
test_height = height - (height - ctx.frame_height) % offset;
|
test_height = height - (height - ctx.frame_height) % offset;
|
||||||
|
|
||||||
|
|||||||
@@ -541,24 +541,6 @@ test_driver_enroll_error_no_print (void)
|
|||||||
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
|
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
|
||||||
g_assert_null (out_print);
|
g_assert_null (out_print);
|
||||||
g_assert_null (fake_dev->ret_print);
|
g_assert_null (fake_dev->ret_print);
|
||||||
g_clear_error (&error);
|
|
||||||
|
|
||||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
|
|
||||||
"*Driver did not set the type on the returned print*");
|
|
||||||
|
|
||||||
fake_dev->ret_error = NULL;
|
|
||||||
fake_dev->ret_print = fp_print_new (device); /* Type not set. */
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
|
|
||||||
(gpointer) (&fake_dev->ret_print));
|
|
||||||
out_print =
|
|
||||||
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
|
|
||||||
|
|
||||||
g_test_assert_expected_messages ();
|
|
||||||
g_assert (fake_dev->last_called_function == dev_class->enroll);
|
|
||||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
|
|
||||||
g_assert_null (out_print);
|
|
||||||
g_assert_null (fake_dev->ret_print);
|
|
||||||
g_clear_error (&error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -653,7 +635,7 @@ test_driver_enroll_progress (void)
|
|||||||
{
|
{
|
||||||
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
|
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
|
||||||
g_autoptr(FpAutoCloseDevice) device = NULL;
|
g_autoptr(FpAutoCloseDevice) device = NULL;
|
||||||
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
|
g_autoptr(FpPrint) enrolled_print = NULL;
|
||||||
ExpectedEnrollData expected_enroll_data = {0};
|
ExpectedEnrollData expected_enroll_data = {0};
|
||||||
FpiDeviceFake *fake_dev;
|
FpiDeviceFake *fake_dev;
|
||||||
|
|
||||||
@@ -1373,7 +1355,7 @@ test_driver_identify_report_no_callback (void)
|
|||||||
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
|
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
|
||||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
g_autoptr(FpAutoCloseDevice) device = NULL;
|
g_autoptr(FpAutoCloseDevice) device = NULL;
|
||||||
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
|
g_autoptr(FpPrint) enrolled_print = NULL;
|
||||||
g_autoptr(FpPrint) print = NULL;
|
g_autoptr(FpPrint) print = NULL;
|
||||||
g_autoptr(FpPrint) match = NULL;
|
g_autoptr(FpPrint) match = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
@@ -1511,7 +1493,6 @@ test_driver_list (void)
|
|||||||
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@@ -1534,7 +1515,6 @@ test_driver_list_error (void)
|
|||||||
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
g_autoptr(GPtrArray) prints = NULL;
|
g_autoptr(GPtrArray) prints = NULL;
|
||||||
|
|
||||||
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
|
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
|
||||||
@@ -1911,7 +1891,7 @@ test_driver_action_error_all (void)
|
|||||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
FpiDeviceFake *fake_dev;
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
fake_dev = FPI_DEVICE_FAKE (device);
|
fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
fake_dev->return_action_error = TRUE;
|
fake_dev->return_action_error = TRUE;
|
||||||
@@ -1982,7 +1962,7 @@ test_driver_action_error_fallback_all (void)
|
|||||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
FpiDeviceFake *fake_dev;
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
fake_dev = FPI_DEVICE_FAKE (device);
|
fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
fake_dev->return_action_error = TRUE;
|
fake_dev->return_action_error = TRUE;
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ test_ssm_new_full (void)
|
|||||||
static void
|
static void
|
||||||
test_ssm_new_no_handler (void)
|
test_ssm_new_no_handler (void)
|
||||||
{
|
{
|
||||||
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
|
g_autoptr(FpiSsm) ssm = NULL;
|
||||||
|
|
||||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
"*BUG:*handler*");
|
"*BUG:*handler*");
|
||||||
@@ -211,7 +211,7 @@ test_ssm_new_no_handler (void)
|
|||||||
static void
|
static void
|
||||||
test_ssm_new_wrong_states (void)
|
test_ssm_new_wrong_states (void)
|
||||||
{
|
{
|
||||||
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
|
g_autoptr(FpiSsm) ssm = NULL;
|
||||||
|
|
||||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
"*BUG:*nr_states*");
|
"*BUG:*nr_states*");
|
||||||
@@ -1172,7 +1172,6 @@ test_ssm_subssm_start (void)
|
|||||||
g_autoptr(FpiSsm) subssm =
|
g_autoptr(FpiSsm) subssm =
|
||||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||||
|
|
||||||
g_autoptr(FpiSsmTestData) subdata =
|
g_autoptr(FpiSsmTestData) subdata =
|
||||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||||
|
|
||||||
@@ -1263,7 +1262,6 @@ test_ssm_subssm_start_with_started (void)
|
|||||||
g_autoptr(FpiSsm) subssm =
|
g_autoptr(FpiSsm) subssm =
|
||||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||||
|
|
||||||
g_autoptr(FpiSsmTestData) subdata =
|
g_autoptr(FpiSsmTestData) subdata =
|
||||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||||
|
|
||||||
@@ -1307,7 +1305,6 @@ test_ssm_subssm_start_with_delayed (void)
|
|||||||
g_autoptr(FpiSsm) subssm =
|
g_autoptr(FpiSsm) subssm =
|
||||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||||
|
|
||||||
g_autoptr(FpiSsmTestData) subdata =
|
g_autoptr(FpiSsmTestData) subdata =
|
||||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||||
gpointer timeout_tracker = GUINT_TO_POINTER (TRUE);
|
gpointer timeout_tracker = GUINT_TO_POINTER (TRUE);
|
||||||
|
|||||||
@@ -22,41 +22,60 @@
|
|||||||
|
|
||||||
#include "test-utils.h"
|
#include "test-utils.h"
|
||||||
|
|
||||||
void
|
struct
|
||||||
fpt_teardown_virtual_device_environment (void)
|
|
||||||
{
|
{
|
||||||
const char *path = g_getenv ("FP_VIRTUAL_IMAGE");
|
const char *envvar;
|
||||||
|
const char *driver_id;
|
||||||
|
const char *device_id;
|
||||||
|
} devtype_vars[FPT_NUM_VIRTUAL_DEVICE_TYPES] = {
|
||||||
|
{ "FP_VIRTUAL_IMAGE", "virtual_image", "virtual_image" }, /* FPT_VIRTUAL_DEVICE_IMAGE */
|
||||||
|
{ "FP_VIRTUAL_DEVICE", "virtual_device", "virtual_device" }, /* FPT_VIRTUAL_DEVICE */
|
||||||
|
{ "FP_VIRTUAL_DEVICE_IDENT", "virtual_device", "virtual_device_ident" } /* FPT_VIRTUAL_DEVICE_IDENT */
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||||
|
{
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
path = g_getenv (devtype_vars[devtype].envvar);
|
||||||
|
|
||||||
if (path)
|
if (path)
|
||||||
{
|
{
|
||||||
g_autofree char *temp_dir = g_path_get_dirname (path);
|
g_autofree char *temp_dir = g_path_get_dirname (path);
|
||||||
|
|
||||||
g_unsetenv ("FP_VIRTUAL_IMAGE");
|
g_unsetenv (devtype_vars[devtype].envvar);
|
||||||
g_unlink (path);
|
g_unlink (path);
|
||||||
g_rmdir (temp_dir);
|
g_rmdir (temp_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FptVirtualDeviceType global_devtype;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_signal_event (int sig)
|
on_signal_event (int sig)
|
||||||
{
|
{
|
||||||
fpt_teardown_virtual_device_environment ();
|
fpt_teardown_virtual_device_environment (global_devtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fpt_setup_virtual_device_environment (void)
|
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autofree char *temp_dir = NULL;
|
g_autofree char *temp_dir = NULL;
|
||||||
g_autofree char *temp_path = NULL;
|
g_autofree char *temp_path = NULL;
|
||||||
|
g_autofree char *filename = NULL;
|
||||||
|
|
||||||
g_assert_null (g_getenv ("FP_VIRTUAL_IMAGE"));
|
g_assert_null (g_getenv (devtype_vars[devtype].envvar));
|
||||||
|
|
||||||
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
|
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
|
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id);
|
||||||
g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
|
temp_path = g_build_filename (temp_dir, filename, NULL);
|
||||||
|
g_setenv (devtype_vars[devtype].envvar, temp_path, TRUE);
|
||||||
|
|
||||||
|
global_devtype = devtype;
|
||||||
|
|
||||||
signal (SIGKILL, on_signal_event);
|
signal (SIGKILL, on_signal_event);
|
||||||
signal (SIGABRT, on_signal_event);
|
signal (SIGABRT, on_signal_event);
|
||||||
@@ -78,13 +97,16 @@ fpt_context_new (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FptContext *
|
FptContext *
|
||||||
fpt_context_new_with_virtual_imgdev (void)
|
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||||
{
|
{
|
||||||
FptContext *tctx;
|
FptContext *tctx;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
fpt_setup_virtual_device_environment ();
|
g_assert_true (devtype >= FPT_VIRTUAL_DEVICE_IMAGE &&
|
||||||
|
devtype < FPT_NUM_VIRTUAL_DEVICE_TYPES);
|
||||||
|
|
||||||
|
fpt_setup_virtual_device_environment (devtype);
|
||||||
|
|
||||||
tctx = fpt_context_new ();
|
tctx = fpt_context_new ();
|
||||||
devices = fp_context_get_devices (tctx->fp_context);
|
devices = fp_context_get_devices (tctx->fp_context);
|
||||||
@@ -96,7 +118,7 @@ fpt_context_new_with_virtual_imgdev (void)
|
|||||||
{
|
{
|
||||||
FpDevice *device = devices->pdata[i];
|
FpDevice *device = devices->pdata[i];
|
||||||
|
|
||||||
if (g_strcmp0 (fp_device_get_driver (device), "virtual_image") == 0)
|
if (g_strcmp0 (fp_device_get_driver (device), devtype_vars[devtype].driver_id) == 0)
|
||||||
{
|
{
|
||||||
tctx->device = device;
|
tctx->device = device;
|
||||||
break;
|
break;
|
||||||
@@ -105,6 +127,7 @@ fpt_context_new_with_virtual_imgdev (void)
|
|||||||
|
|
||||||
g_assert_true (FP_IS_DEVICE (tctx->device));
|
g_assert_true (FP_IS_DEVICE (tctx->device));
|
||||||
g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device);
|
g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device);
|
||||||
|
g_object_set_data (G_OBJECT (tctx->fp_context), "devtype", GUINT_TO_POINTER (devtype));
|
||||||
|
|
||||||
return tctx;
|
return tctx;
|
||||||
}
|
}
|
||||||
@@ -112,6 +135,10 @@ fpt_context_new_with_virtual_imgdev (void)
|
|||||||
void
|
void
|
||||||
fpt_context_free (FptContext *tctx)
|
fpt_context_free (FptContext *tctx)
|
||||||
{
|
{
|
||||||
|
FptVirtualDeviceType devtype;
|
||||||
|
|
||||||
|
devtype = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tctx->fp_context), "devtype"));
|
||||||
|
|
||||||
if (tctx->device && fp_device_is_open (tctx->device))
|
if (tctx->device && fp_device_is_open (tctx->device))
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
@@ -123,5 +150,5 @@ fpt_context_free (FptContext *tctx)
|
|||||||
g_clear_object (&tctx->fp_context);
|
g_clear_object (&tctx->fp_context);
|
||||||
g_free (tctx);
|
g_free (tctx);
|
||||||
|
|
||||||
fpt_teardown_virtual_device_environment ();
|
fpt_teardown_virtual_device_environment (devtype);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,15 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
void fpt_setup_virtual_device_environment (void);
|
typedef enum {
|
||||||
void fpt_teardown_virtual_device_environment (void);
|
FPT_VIRTUAL_DEVICE_IMAGE = 0,
|
||||||
|
FPT_VIRTUAL_DEVICE,
|
||||||
|
FPT_VIRTUAL_DEVICE_IDENTIFY,
|
||||||
|
FPT_NUM_VIRTUAL_DEVICE_TYPES
|
||||||
|
} FptVirtualDeviceType;
|
||||||
|
|
||||||
|
void fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype);
|
||||||
|
void fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype);
|
||||||
|
|
||||||
typedef struct _FptContext
|
typedef struct _FptContext
|
||||||
{
|
{
|
||||||
@@ -30,7 +37,7 @@ typedef struct _FptContext
|
|||||||
} FptContext;
|
} FptContext;
|
||||||
|
|
||||||
FptContext * fpt_context_new (void);
|
FptContext * fpt_context_new (void);
|
||||||
FptContext * fpt_context_new_with_virtual_imgdev (void);
|
FptContext * fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype);
|
||||||
|
|
||||||
void fpt_context_free (FptContext *test_context);
|
void fpt_context_free (FptContext *test_context);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user