mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
With this script it is possible to test libfprint/fprintd without any hardware device. The image needs to be provides as a PNG with the alpha channel storing the print data. See the comment in the file on how the script can be used.
112 lines
3.0 KiB
Python
Executable File
112 lines
3.0 KiB
Python
Executable File
#!/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_IMAGE=/run/fprint/virtimg_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_IMAGE=/run/fprint/virtimg_sock ./sendvirtimg.py prints/whorl.png
|
|
|
|
|
|
|
|
import cairo
|
|
import sys
|
|
import os
|
|
import socket
|
|
import struct
|
|
|
|
if len(sys.argv) != 2:
|
|
sys.stderr.write('You need to pass a PNG with an alpha channel!\n')
|
|
sys.exit(1)
|
|
|
|
# Just copied from the C file, we could also use the introspection data for
|
|
# this. Also, most of them do *not* make any sense.
|
|
commands = {
|
|
'retry' : struct.pack('ii', -1, 0),
|
|
'retry-too-short' : struct.pack('ii', -1, 1),
|
|
'retry-center-finger' : struct.pack('ii', -1, 2),
|
|
'retry-remove-finger' : struct.pack('ii', -1, 3),
|
|
|
|
'error' : struct.pack('ii', -2, 0),
|
|
'error-not-supported' : struct.pack('ii', -2, 1),
|
|
'error-not-open' : struct.pack('ii', -2, 2),
|
|
'error-already-open' : struct.pack('ii', -2, 3),
|
|
'error-busy' : struct.pack('ii', -2, 4),
|
|
'error-proto' : struct.pack('ii', -2, 5),
|
|
'error-data-invalid' : struct.pack('ii', -2, 6),
|
|
'error-data-not-found' : struct.pack('ii', -2, 7),
|
|
'error-data-full' : struct.pack('ii', -2, 8),
|
|
}
|
|
|
|
|
|
if sys.argv[1] in commands:
|
|
command = commands[sys.argv[1]]
|
|
else:
|
|
png = cairo.ImageSurface.create_from_png(sys.argv[1])
|
|
|
|
# Cairo wants 4 byte aligned rows, so just add a few pixel if necessary
|
|
w = png.get_width()
|
|
h = png.get_height()
|
|
w = (w + 3) // 4 * 4
|
|
h = (h + 3) // 4 * 4
|
|
img = cairo.ImageSurface(cairo.Format.A8, w, h)
|
|
cr = cairo.Context(img)
|
|
|
|
cr.set_source_rgba(1, 1, 1, 1)
|
|
cr.paint()
|
|
|
|
cr.set_source_rgba(0, 0, 0, 0)
|
|
cr.set_operator(cairo.OPERATOR_SOURCE)
|
|
|
|
cr.set_source_surface(png)
|
|
cr.paint()
|
|
|
|
mem = img.get_data()
|
|
mem = mem.tobytes()
|
|
assert len(mem) == img.get_width() * img.get_height()
|
|
|
|
command = struct.pack('ii', img.get_width(), img.get_height())
|
|
command += mem
|
|
|
|
|
|
|
|
def write_dbg_img():
|
|
dbg_img_rgb = cairo.ImageSurface(cairo.Format.RGB24, img.get_width(), img.get_height())
|
|
dbg_cr = cairo.Context(dbg_img_rgb)
|
|
dbg_cr.set_source_rgb(0, 0, 0)
|
|
dbg_cr.paint()
|
|
dbg_cr.set_source_rgb(1, 1, 1)
|
|
dbg_cr.mask_surface(img, 0, 0)
|
|
|
|
dbg_img_rgb.write_to_png('/tmp/test.png')
|
|
|
|
#write_dbg_img()
|
|
|
|
# Send image through socket
|
|
sockaddr = os.environ['FP_VIRTUAL_IMAGE']
|
|
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
sock.connect(sockaddr)
|
|
|
|
sock.sendall(command)
|
|
|