mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
242 Commits
v_0_3_0
...
wip/hadess
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e8deba37 | ||
|
|
bb4d888661 | ||
|
|
ff77cfc9b5 | ||
|
|
80f91ecb7b | ||
|
|
6cb77465ab | ||
|
|
6f6127cbb6 | ||
|
|
e1d85fb636 | ||
|
|
74b5c92787 | ||
|
|
ac1f97e2eb | ||
|
|
40f486b108 | ||
|
|
b62e67401c | ||
|
|
dd0a0134a6 | ||
|
|
5e24000799 | ||
|
|
c5cdfcb120 | ||
|
|
549a6694d2 | ||
|
|
14e34e1d15 | ||
|
|
e5393bf46a | ||
|
|
878a201bb1 | ||
|
|
b0e4619e0a | ||
|
|
aec65777a7 | ||
|
|
31bad8ddd2 | ||
|
|
79d65c907f | ||
|
|
92231d984f | ||
|
|
2fbc77955e | ||
|
|
c91819f551 | ||
|
|
b3f6ff5a36 | ||
|
|
52f84bee3c | ||
|
|
dda6857fee | ||
|
|
0215483fb3 | ||
|
|
37bb59df13 | ||
|
|
db34837d2d | ||
|
|
ba49677794 | ||
|
|
1a376c1bfa | ||
|
|
ef807d9d0e | ||
|
|
2a4893d946 | ||
|
|
cee061b363 | ||
|
|
1bbdf304ab | ||
|
|
6155068f9e | ||
|
|
0c4e3bb1c4 | ||
|
|
4547ff0c19 | ||
|
|
b7cce4d91d | ||
|
|
475250ce71 | ||
|
|
f40f231a63 | ||
|
|
d83d92adf2 | ||
|
|
d15282bff1 | ||
|
|
00637c4f0b | ||
|
|
2e035a7f45 | ||
|
|
17577175f8 | ||
|
|
933fab6ed4 | ||
|
|
7e5661caff | ||
|
|
19dfb138a6 | ||
|
|
0930f2614c | ||
|
|
1b20521e5c | ||
|
|
0e351db91a | ||
|
|
9cca501650 | ||
|
|
2481cbe4ab | ||
|
|
bc3959d1e0 | ||
|
|
1ac815e457 | ||
|
|
55b83062d0 | ||
|
|
391f77ce5e | ||
|
|
bc30a3d2e5 | ||
|
|
ff5de4ff03 | ||
|
|
f433a4d67c | ||
|
|
994061af44 | ||
|
|
501020921e | ||
|
|
53c09405b2 | ||
|
|
1f0079a274 | ||
|
|
15afe43cf0 | ||
|
|
eb8f7ba3b2 | ||
|
|
901a6f7fed | ||
|
|
fc92f62136 | ||
|
|
ff09456cf5 | ||
|
|
32fcfde86b | ||
|
|
363a1b3371 | ||
|
|
c376c6fb02 | ||
|
|
8e6e23b8d0 | ||
|
|
63e5d56441 | ||
|
|
e9bfd943fc | ||
|
|
614e2286c2 | ||
|
|
768a74c4bf | ||
|
|
612e9e11de | ||
|
|
06c72d54be | ||
|
|
be68bacc94 | ||
|
|
317d7bc988 | ||
|
|
b44e417bca | ||
|
|
9d67ce484d | ||
|
|
78b8602cf6 | ||
|
|
83a0a7681b | ||
|
|
c5e0e41ce7 | ||
|
|
b3fe4a1e91 | ||
|
|
f59bf389d9 | ||
|
|
231b8f9f92 | ||
|
|
dac153d24a | ||
|
|
3661d146a7 | ||
|
|
3bf55a3e07 | ||
|
|
5226467fc2 | ||
|
|
54deaa1b24 | ||
|
|
7ff667f58d | ||
|
|
58ba9b02ed | ||
|
|
d35da0ce99 | ||
|
|
041e6a1078 | ||
|
|
1c73c36ed7 | ||
|
|
69de32f700 | ||
|
|
4bfee76ead | ||
|
|
4d7afd9b4f | ||
|
|
cfe60c0640 | ||
|
|
d82847a6b4 | ||
|
|
5a7e6e07ff | ||
|
|
2162aa9f48 | ||
|
|
a1f36c71c9 | ||
|
|
e4eedef27e | ||
|
|
5e29695969 | ||
|
|
49a46668ad | ||
|
|
76269decdd | ||
|
|
8454a25ecf | ||
|
|
a0bbbd7d32 | ||
|
|
12f6dae8cd | ||
|
|
9570c36fd4 | ||
|
|
487dae0d2f | ||
|
|
d71018bd8f | ||
|
|
61fa57b05d | ||
|
|
fc1781e317 | ||
|
|
ffef6c2bcc | ||
|
|
67d29f7936 | ||
|
|
9437c98d54 | ||
|
|
f7d00a828d | ||
|
|
0f0a4b2da6 | ||
|
|
c9cdbaf880 | ||
|
|
83f29dad9f | ||
|
|
c2a11c5918 | ||
|
|
3746b2ad5c | ||
|
|
b51fa446e3 | ||
|
|
6fc5293e83 | ||
|
|
aab3daa28b | ||
|
|
e40f7bd1f7 | ||
|
|
6664f87d8f | ||
|
|
6e8d5cd6a1 | ||
|
|
9f7e1ecf40 | ||
|
|
d9567002e4 | ||
|
|
a656a4a9f3 | ||
|
|
2944a35e74 | ||
|
|
391373fb0c | ||
|
|
985e8c4577 | ||
|
|
bd0d4258e4 | ||
|
|
9bbd9b208a | ||
|
|
59fe0fb699 | ||
|
|
f1fdd71613 | ||
|
|
bb66780cb5 | ||
|
|
45fb6d7908 | ||
|
|
9f408bf51b | ||
|
|
ee32166267 | ||
|
|
a3c90f2b24 | ||
|
|
dc537ef2c9 | ||
|
|
061a457658 | ||
|
|
82ae7c1c09 | ||
|
|
79d79c3c87 | ||
|
|
35e356f625 | ||
|
|
948ab02d1a | ||
|
|
a6101026d2 | ||
|
|
e0966cb20f | ||
|
|
e278e8321c | ||
|
|
e1728e7c25 | ||
|
|
e215b05094 | ||
|
|
fe3fdd1f50 | ||
|
|
5ff45658c0 | ||
|
|
d12b294783 | ||
|
|
2bba4fb073 | ||
|
|
aeca32fc12 | ||
|
|
12c1088777 | ||
|
|
9e2f8b5e75 | ||
|
|
c14ebd8b63 | ||
|
|
a6339a30ef | ||
|
|
f3dd55815e | ||
|
|
6d65bfcf80 | ||
|
|
1acd647b29 | ||
|
|
0e843ad6b3 | ||
|
|
7eafca7bab | ||
|
|
3b3679c900 | ||
|
|
43eca622cd | ||
|
|
02509e1073 | ||
|
|
0b2d33c712 | ||
|
|
7751fcb375 | ||
|
|
8a87ba448c | ||
|
|
7e1646c382 | ||
|
|
a5ec0b30e1 | ||
|
|
29cf86a02e | ||
|
|
7892c943e6 | ||
|
|
a7d6b7c30a | ||
|
|
258ac2d4da | ||
|
|
31cf7a9383 | ||
|
|
f335256cbe | ||
|
|
c02cb3083d | ||
|
|
2084724115 | ||
|
|
59925d2027 | ||
|
|
118c610e29 | ||
|
|
313bfede77 | ||
|
|
c1da647aed | ||
|
|
22d204cc68 | ||
|
|
bc497f1b26 | ||
|
|
8c5f2e6434 | ||
|
|
5b20892dd4 | ||
|
|
b2a53a459c | ||
|
|
45ac0eefb0 | ||
|
|
ea6d5ba6d6 | ||
|
|
ed2c75842a | ||
|
|
b307dd1a6a | ||
|
|
39902374ce | ||
|
|
9e92d4cf2c | ||
|
|
6b84c6664f | ||
|
|
f569d0bf44 | ||
|
|
1cfd14b7fe | ||
|
|
5d32102efe | ||
|
|
9e10edd422 | ||
|
|
fecf6d6fe5 | ||
|
|
e32fa8cc38 | ||
|
|
d8aae30a67 | ||
|
|
84b97ea15b | ||
|
|
8f98743857 | ||
|
|
be29f27e25 | ||
|
|
d003f08855 | ||
|
|
0f7ad00fc4 | ||
|
|
83333bce3f | ||
|
|
132b178304 | ||
|
|
c3689665db | ||
|
|
3d222ddda7 | ||
|
|
080c414ce9 | ||
|
|
ff02115b0f | ||
|
|
3b409c767c | ||
|
|
d05c69698c | ||
|
|
2d09b10a27 | ||
|
|
bc03d56186 | ||
|
|
96e7224a23 | ||
|
|
0f4a75ff61 | ||
|
|
dfff16f3e3 | ||
|
|
3d2e545264 | ||
|
|
c96fa32da4 | ||
|
|
48ec64f683 | ||
|
|
f8aa82a554 | ||
|
|
1451a2dde2 | ||
|
|
d2e957683f | ||
|
|
a3ae96c214 | ||
|
|
3dd905d4e9 |
20
.gitlab-ci.yml
Normal file
20
.gitlab-ci.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
image: fedora:rawhide
|
||||
stages:
|
||||
- build
|
||||
|
||||
variables:
|
||||
DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
|
||||
gcc gcc-c++ glibc-devel libX11-devel libXv-devel
|
||||
|
||||
|
||||
before_script:
|
||||
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
|
||||
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- meson . _build
|
||||
- ninja -C _build
|
||||
- ninja -C _build install
|
||||
|
||||
3
AUTHORS
3
AUTHORS
@@ -4,7 +4,8 @@ Copyright (C) 2006 Pavel Machek <pavel@suse.cz>
|
||||
Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
|
||||
Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
Copyright (C) 2007 Cyrille Bagard
|
||||
Copyright (C) 2007 Vasily Khoruzhick
|
||||
Copyright (C) 2007-2008,2012 Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Copyright (C) 2007 Jan-Michael Brummer <buzz2@gmx.de>
|
||||
Copyright (C) 2007 Anthony Bretaudeau <wxcover@users.sourceforge.net>
|
||||
Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com>
|
||||
Copyright (C) 2012 Timo Teräs <timo.teras@iki.fi>
|
||||
|
||||
96
HACKING
96
HACKING
@@ -1,96 +0,0 @@
|
||||
Copyright notices
|
||||
=================
|
||||
|
||||
If you make a contribution substantial enough to add or update a copyright
|
||||
notice on a file, such notice must be mirrored in the AUTHORS file. This is
|
||||
to make it easy for people to comply to section 6 of the LGPL, which states
|
||||
that a "work that uses the Library" must include copyright notices from
|
||||
this library. By providing them all in one place, hopefully we save such
|
||||
users some time.
|
||||
|
||||
|
||||
USB
|
||||
===
|
||||
|
||||
At the time of development, there are no known consumer fingerprint readers
|
||||
which do not operate over the USB bus. Therefore the library is designed around
|
||||
the fact that each driver drivers USB devices, and each device is a USB device.
|
||||
If we were to ever support a non-USB device, some rearchitecting would be
|
||||
needed, but this would not be a substantial task.
|
||||
|
||||
|
||||
GLib
|
||||
====
|
||||
|
||||
Although the library uses GLib internally, libfprint is designed to provide
|
||||
a completely neutral interface to it's application users. So, the public
|
||||
APIs should never return GLib data types or anything like that.
|
||||
|
||||
|
||||
Two-faced-ness
|
||||
==============
|
||||
|
||||
Like any decent library, this one is designed to provide a stable and
|
||||
documented API to it's users: applications. Clear distinction is made between
|
||||
data available internally in the library, and data/functions available to
|
||||
the applications.
|
||||
|
||||
This library is confused a little by the fact that there is another 'interface'
|
||||
at hand: the internal interface provided to drivers. So, we effectively end
|
||||
up with 2 APIs:
|
||||
|
||||
1. The external-facing API for applications
|
||||
2. The internal API for fingerprint drivers
|
||||
|
||||
Non-static functions which are intended for internal use only are prepended
|
||||
with the "fpi_" prefix.
|
||||
|
||||
|
||||
API stability
|
||||
=============
|
||||
|
||||
No API stability has been promised to anyone: go wild, there's no issue with
|
||||
breaking APIs at this point in time.
|
||||
|
||||
|
||||
Portability
|
||||
===========
|
||||
|
||||
libfprint is primarily written for Linux. However, I'm interested in
|
||||
supporting efforts to port this to other operating systems too.
|
||||
|
||||
You should ensure code is portable wherever possible. Try and use GLib rather
|
||||
than OS-specific features.
|
||||
|
||||
Endianness must be considered in all code. libfprint must support both big-
|
||||
and little-endian systems.
|
||||
|
||||
|
||||
Coding Style
|
||||
============
|
||||
|
||||
This project follows Linux kernel coding style but with a tab width of 4.
|
||||
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
All additions of public API functions must be accompanied with doxygen
|
||||
comments.
|
||||
|
||||
All changes which potentially change the behaviour of the public API must
|
||||
be reflected by updating the appropriate doxygen comments.
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Patches should be sent to the fprint mailing list detailed on the website.
|
||||
A subscription is required.
|
||||
|
||||
Information about libfprint development repositories can be found here:
|
||||
http://www.reactivated.net/fprint/Libfprint_development
|
||||
|
||||
If you're looking for ideas for things to work on, look at the TODO file or
|
||||
grep the source code for FIXMEs.
|
||||
|
||||
52
HACKING.md
Normal file
52
HACKING.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Contributing to libfprint
|
||||
|
||||
## GLib
|
||||
|
||||
Although the library uses GLib internally, libfprint is designed to provide
|
||||
a completely neutral interface to it's application users. So, the public
|
||||
APIs should never return GLib data types or anything like that.
|
||||
|
||||
## Two-faced-ness
|
||||
|
||||
Like any decent library, this one is designed to provide a stable and
|
||||
documented API to its users: applications. Clear distinction is made between
|
||||
data available internally in the library, and data/functions available to
|
||||
the applications.
|
||||
|
||||
This library is confused a little by the fact that there is another 'interface'
|
||||
at hand: the internal interface provided to drivers. So, we effectively end
|
||||
up with 2 APIs:
|
||||
|
||||
1. The [external-facing API for applications](libfprint/fprint.h)
|
||||
2. The [internal API for fingerprint drivers](libfprint/drivers_api.h)
|
||||
|
||||
Non-static functions which are intended for internal use only are prepended
|
||||
with the "fpi_" prefix.
|
||||
|
||||
## Documentation
|
||||
|
||||
All additions of public API functions must be accompanied with gtk-doc
|
||||
comments.
|
||||
|
||||
All changes which potentially change the behaviour of the public API must
|
||||
be reflected by updating the appropriate gtk-doc comments.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Patches should be sent as merge requests to the gitlab page:
|
||||
https://gitlab.freedesktop.org/libfprint/libfprint/merge_requests
|
||||
|
||||
Drivers are not usually written by libfprint developers, but when they
|
||||
are, we require:
|
||||
- 3 stand-alone devices. Not in a laptop or another embedded device, as
|
||||
space is scarce, unless the device has special integration with that
|
||||
hardware.
|
||||
- specifications of the protocol.
|
||||
|
||||
If you are an end-user, you can file a feature request with the "Driver Request"
|
||||
tag on [libfprint's issue page](https://gitlab.freedesktop.org/libfprint/libfprint/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=Driver%20Request),
|
||||
or subscribe to an existing feature request there.
|
||||
|
||||
If you are an enterprising hacker, please file a new merge request with
|
||||
the driver patches integrated.
|
||||
238
INSTALL
238
INSTALL
@@ -1,234 +1,6 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
libfprint uses the Meson build system. See
|
||||
http://mesonbuild.com/Quick-guide.html for details on how to
|
||||
compile libfprint.
|
||||
|
||||
The "meson configure" command will give you a list of available
|
||||
command-line options.
|
||||
|
||||
22
Makefile.am
22
Makefile.am
@@ -1,22 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = dist-bzip2
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
EXTRA_DIST = THANKS TODO HACKING libfprint.pc.in
|
||||
DISTCLEANFILES = ChangeLog libfprint.pc
|
||||
|
||||
SUBDIRS = libfprint doc
|
||||
|
||||
if BUILD_EXAMPLES
|
||||
SUBDIRS += examples
|
||||
endif
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfig_DATA=libfprint.pc
|
||||
|
||||
.PHONY: ChangeLog dist-up
|
||||
ChangeLog:
|
||||
git --git-dir $(top_srcdir)/.git log > ChangeLog || touch ChangeLog
|
||||
|
||||
dist-hook: ChangeLog
|
||||
|
||||
dist-up: dist
|
||||
rsync $(distdir).tar.bz2 frs.sourceforge.net:uploads/
|
||||
109
NEWS
109
NEWS
@@ -1,6 +1,115 @@
|
||||
This file lists notable changes in each release. For the full history of all
|
||||
changes, see ChangeLog.
|
||||
|
||||
2018-06-12: v0.8.1 release
|
||||
- Brown paperbag release to install the udev rules file in the correct
|
||||
directory if the udev pkg-config file doesn't have a trailing slash
|
||||
|
||||
2018-06-12: v0.8.0 release
|
||||
- Port to meson as the build system
|
||||
- Port documentation to gtk-doc
|
||||
|
||||
* Drivers:
|
||||
- Add Elan driver
|
||||
- Increase threshold to detect encryption on URU4000 devices
|
||||
- Remove already replaced UPEKE2 driver
|
||||
- Fix possible crash caused by vfs5011 when no lines were captured
|
||||
|
||||
* Library:
|
||||
- Fix a number of memory and file descriptor leaks and warnings
|
||||
- Make NSS (and URU4000) driver optional
|
||||
- Fix assembling of frames for non-reverse and non reverse stripes
|
||||
- Split internal private header to clarify drivers API
|
||||
- Simplify logging system, now all the builds can be used to output
|
||||
debug information
|
||||
- Mark fp_dscv_print functions as deprecated
|
||||
|
||||
* Udev rules:
|
||||
- Add some unsupported devices to the whitelist
|
||||
|
||||
2017-05-14: v0.7.0 release
|
||||
* Drivers:
|
||||
- Add VFS0050 driver
|
||||
- Fix possible crash in AES3500 and AES4000
|
||||
- Fix broken enrollment in VFS101
|
||||
- Better verification with small sensor scanners
|
||||
- Plenty of fixes in VFS5011
|
||||
- Fix memory corruption in AES1610
|
||||
- Improve calibration settings for AES1610
|
||||
- Improve image assembling in upeksonly driver
|
||||
- Autodetect whether image is encrypted in uru4k
|
||||
|
||||
* Library:
|
||||
- NBIS: Remove false minutia at the edge of partial image
|
||||
- Introduce routines to assemble image from lines (used in VFS5011 and upeksonly)
|
||||
- Fix a bug that can cause driver state machine to enter into endless loop.
|
||||
|
||||
* Udev rules:
|
||||
- Add driver name to the USB properties
|
||||
|
||||
* Plenty of build fixes
|
||||
|
||||
2015-02-03: v0.6.0 release
|
||||
|
||||
* Drivers:
|
||||
- Reduce duplication between AES3500 and AES4000 drivers and
|
||||
add support for AES3500 device
|
||||
- Add support for UPEK 147e:2020 and Upek Eikon 2 devices
|
||||
- Add EgisTec ES603 driver
|
||||
- Add VFS5011 driver
|
||||
- Always perform 5 scans for image enrollment
|
||||
- Better verification with AES1660 driver
|
||||
- Better verification for a number of AES drivers
|
||||
|
||||
* Library:
|
||||
- Always use Pixman for image manipulation, gdk-pixbuf and ImageMagick
|
||||
are not supported any more.
|
||||
|
||||
* Udev rules:
|
||||
- Fix warning when USB hub or system does not support power management
|
||||
|
||||
2013-08-11: v0.5.1 release
|
||||
|
||||
* Drivers
|
||||
- Add support for 147e:2020 to upeke2 driver
|
||||
- Fix possible race condition, and cancellation in uru4000 driver
|
||||
|
||||
* Udev rules:
|
||||
- Add Microsoft keyboard to the suspend blacklist
|
||||
|
||||
* Plenty of build fixes
|
||||
|
||||
2012-12-03: v0.5.0 release
|
||||
|
||||
* Drivers:
|
||||
- New VFS300/VFS301 driver
|
||||
- New AES2550/AES2810 drivers
|
||||
- New AES1660 driver
|
||||
- New AES2660 driver
|
||||
- New DigitalPersona URU4500 driver
|
||||
- Avoid empty capture and improve image contrast in the
|
||||
AES2501 and AES2550 drivers
|
||||
- Update upektc driver, add support for Eikon Touch 300
|
||||
- Fix UrU4000 image capture on ARM
|
||||
|
||||
* Library:
|
||||
- Fix global variable collisions with libusb and other system headers
|
||||
- Fix possible crash in NBIS image processing with some fingerprints
|
||||
|
||||
* Udev rules:
|
||||
- Fix power control path for newer kernels
|
||||
- Move udev rules to the correct directory
|
||||
- Don't print duplicated udev rules
|
||||
- Include udev rules in the tarball
|
||||
- Allow disabling of udev rules for cross-compiling
|
||||
- Add driver names in the generated rules
|
||||
|
||||
2011-04-18: v0.4.0 release
|
||||
* Add support for Validity VFS101 (USB ID 138a:0001)
|
||||
* Fix crasher when resizing a fingerprint image
|
||||
* Fix wrong timeout being returned when either of
|
||||
libusb or libfprint doesn't have a timeout
|
||||
|
||||
2010-09-08: v0.3.0 release
|
||||
* Add support for UPEK TCS4C (USB ID 147e:1000)
|
||||
* Use NSS instead of OpenSSL for GPL compliance
|
||||
|
||||
6
README
6
README
@@ -2,7 +2,7 @@ libfprint
|
||||
=========
|
||||
|
||||
libfprint is part of the fprint project:
|
||||
http://www.reactivated.net/fprint
|
||||
https://fprint.freedesktop.org/
|
||||
|
||||
libfprint was originally developed as part of an academic project at the
|
||||
University of Manchester with the aim of hiding differences between different
|
||||
@@ -22,7 +22,7 @@ university computers and the project is not hosted at the university either.
|
||||
|
||||
For more information on libfprint, supported devices, API documentation, etc.,
|
||||
see the homepage:
|
||||
http://www.reactivated.net/fprint/Libfprint
|
||||
https://fprint.freedesktop.org/
|
||||
|
||||
libfprint is licensed under the GNU LGPL version 2.1. See the COPYING file
|
||||
for the license text.
|
||||
@@ -37,5 +37,5 @@ libfprint includes code from NIST's NBIS software distribution:
|
||||
http://fingerprint.nist.gov/NBIS/index.html
|
||||
We include bozorth3 from the US export controlled distribution. We have
|
||||
determined that it is fine to ship bozorth3 in an open source project,
|
||||
see http://reactivated.net/fprint/wiki/US_export_control
|
||||
see https://fprint.freedesktop.org/us-export-control.html
|
||||
|
||||
|
||||
1
THANKS
1
THANKS
@@ -8,3 +8,4 @@ Toby Howard (University of Manchester)
|
||||
Seemant Kulleen
|
||||
Pavel Herrman
|
||||
Bastien Nocera
|
||||
Greg Kerr and Martin Konecny from AuthenTec Inc - hardware donations (AES2550 device), datasheets for AES2550 and AES2810
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
libtoolize --copy --force || exit 1
|
||||
aclocal || exit 1
|
||||
autoheader || exit 1
|
||||
autoconf || exit 1
|
||||
automake -a -c || exit 1
|
||||
./configure --enable-maintainer-mode --enable-examples-build \
|
||||
--enable-x11-examples-build --enable-debug-log $*
|
||||
274
configure.ac
274
configure.ac
@@ -1,274 +0,0 @@
|
||||
AC_INIT([libfprint], [0.3.0])
|
||||
AM_INIT_AUTOMAKE([1.11 dist-bzip2 no-dist-gzip check-news])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_SRCDIR([libfprint/core.c])
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
|
||||
AC_PREREQ([2.50])
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
AC_C_INLINE
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
|
||||
|
||||
# Library versioning
|
||||
lt_major="0"
|
||||
lt_revision="0"
|
||||
lt_age="0"
|
||||
AC_SUBST(lt_major)
|
||||
AC_SUBST(lt_revision)
|
||||
AC_SUBST(lt_age)
|
||||
|
||||
all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000"
|
||||
|
||||
require_imaging='no'
|
||||
require_aeslib='no'
|
||||
enable_upeke2='no'
|
||||
enable_upekts='no'
|
||||
enable_upektc='no'
|
||||
enable_upeksonly='no'
|
||||
enable_vcom5s='no'
|
||||
enable_uru4000='no'
|
||||
enable_fdu2000='no'
|
||||
enable_aes1610='no'
|
||||
enable_aes2501='no'
|
||||
enable_aes4000='no'
|
||||
|
||||
AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers],
|
||||
[List of drivers to enable])],
|
||||
[drivers="$withval"],
|
||||
[drivers="$all_drivers"])
|
||||
|
||||
for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do
|
||||
case ${driver} in
|
||||
upekts)
|
||||
AC_DEFINE([ENABLE_UPEKTS], [], [Build UPEK TouchStrip driver])
|
||||
enable_upekts="yes"
|
||||
;;
|
||||
upeke2)
|
||||
AC_DEFINE([ENABLE_UPEKE2], [], [Build UPEK Eikon 2])
|
||||
enable_upeke2="yes"
|
||||
;;
|
||||
upektc)
|
||||
AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver])
|
||||
enable_upektc="no"
|
||||
# Driver not ported
|
||||
;;
|
||||
upeksonly)
|
||||
AC_DEFINE([ENABLE_UPEKSONLY], [], [Build UPEK TouchStrip sensor-only driver])
|
||||
enable_upeksonly="yes"
|
||||
;;
|
||||
uru4000)
|
||||
AC_DEFINE([ENABLE_URU4000], [], [Build Digital Persona U.are.U 4000 driver])
|
||||
enable_uru4000="yes"
|
||||
;;
|
||||
fdu2000)
|
||||
AC_DEFINE([ENABLE_FDU2000], [], [Build Secugen FDU 2000 driver])
|
||||
enable_fdu2000="no"
|
||||
# Driver not ported
|
||||
;;
|
||||
vcom5s)
|
||||
AC_DEFINE([ENABLE_VCOM5S], [], [Build Veridicom 5thSense driver])
|
||||
enable_vcom5s="yes"
|
||||
;;
|
||||
aes2501)
|
||||
AC_DEFINE([ENABLE_AES2501], [], [Build AuthenTec AES2501 driver])
|
||||
require_aeslib="yes"
|
||||
enable_aes2501="yes"
|
||||
;;
|
||||
aes1610)
|
||||
AC_DEFINE([ENABLE_AES1610], [], [Build AuthenTec AES1610 driver])
|
||||
require_aeslib="yes"
|
||||
enable_aes1610="yes"
|
||||
;;
|
||||
aes4000)
|
||||
AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver])
|
||||
require_aeslib="yes"
|
||||
require_imaging="yes"
|
||||
enable_aes4000="yes"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_UPEKE2], [test "$enable_upeke2" = "yes"])
|
||||
#AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"])
|
||||
AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"])
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1])
|
||||
AC_SUBST(LIBUSB_CFLAGS)
|
||||
AC_SUBST(LIBUSB_LIBS)
|
||||
|
||||
# check for OpenSSL's libcrypto
|
||||
PKG_CHECK_MODULES(CRYPTO, nss)
|
||||
AC_SUBST(CRYPTO_CFLAGS)
|
||||
AC_SUBST(CRYPTO_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(GLIB, "glib-2.0")
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
|
||||
imagemagick_found=no
|
||||
gdkpixbuf_found=no
|
||||
|
||||
if test "$require_imaging" = "yes"; then
|
||||
PKG_CHECK_MODULES(IMAGING, gthread-2.0 gdk-pixbuf-2.0, [gdkpixbuf_found=yes], [gdkpixbuf_found=no])
|
||||
if test "$gdkpixbuf_found" != "yes"; then
|
||||
PKG_CHECK_MODULES(IMAGING, ImageMagick, [imagemagick_found=yes], [imagemagick_found=no])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$require_imaging" = "yes"; then
|
||||
if test "$gdkpixbuf_found" != "yes" && test "$imagemagick_found" != "yes"; then
|
||||
AC_MSG_ERROR([gdk-pixbuf or ImageMagick is required for imaging support])
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([REQUIRE_GDKPIXBUF], [test "$gdkpixbuf_found" = "yes"])
|
||||
AM_CONDITIONAL([REQUIRE_IMAGEMAGICK], [test "$imagemagick_found" = "yes"])
|
||||
AC_SUBST(IMAGING_CFLAGS)
|
||||
AC_SUBST(IMAGING_LIBS)
|
||||
|
||||
# Examples build
|
||||
AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build],
|
||||
[build example applications (default n)])],
|
||||
[build_examples=$enableval],
|
||||
[build_examples='no'])
|
||||
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
|
||||
|
||||
# Examples build
|
||||
AC_ARG_ENABLE([x11-examples-build], [AS_HELP_STRING([--enable-x11-examples-build],
|
||||
[build X11 example applications (default n)])],
|
||||
[build_x11_examples=$enableval],
|
||||
[build_x11_examples='no'])
|
||||
AM_CONDITIONAL([BUILD_X11_EXAMPLES], [test "x$build_x11_examples" != "xno"])
|
||||
|
||||
|
||||
if test "x$build_x11_examples" != "xno"; then
|
||||
# check for Xv extensions
|
||||
# imported from Coriander
|
||||
AC_DEFUN([AC_CHECK_XV],[
|
||||
AC_SUBST(XV_CFLAGS)
|
||||
AC_SUBST(XV_LIBS)
|
||||
AC_MSG_CHECKING(for Xv extensions)
|
||||
AC_TRY_COMPILE([
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xvlib.h>],[
|
||||
int main(void) { (void) XvGetPortAttribute(0, 0, 0, 0); return 0; }
|
||||
],xv=yes,xv=no);
|
||||
AC_MSG_RESULT($xv)
|
||||
if test x$xv = xyes; then
|
||||
XV_LIBS="-lXv -lXext"
|
||||
XV_CFLAGS=""
|
||||
AC_DEFINE(HAVE_XV,1,[defined if XV video overlay is available])
|
||||
else
|
||||
AC_MSG_ERROR([XV is required for X11 examples])
|
||||
fi
|
||||
])
|
||||
AC_CHECK_XV
|
||||
fi
|
||||
|
||||
# Message logging
|
||||
AC_ARG_ENABLE([log], [AS_HELP_STRING([--disable-log], [disable all logging])],
|
||||
[log_enabled=$enableval],
|
||||
[log_enabled='yes'])
|
||||
if test "x$log_enabled" != "xno"; then
|
||||
AC_DEFINE([ENABLE_LOGGING], 1, [Message logging])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log],
|
||||
[enable debug logging (default n)])],
|
||||
[debug_log_enabled=$enableval],
|
||||
[debug_log_enabled='no'])
|
||||
if test "x$debug_log_enabled" != "xno"; then
|
||||
AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Debug message logging])
|
||||
fi
|
||||
|
||||
# Restore gnu89 inline semantics on gcc 4.3 and newer
|
||||
saved_cflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fgnu89-inline"
|
||||
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="")
|
||||
CFLAGS="$saved_cflags"
|
||||
|
||||
AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility])
|
||||
AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow"
|
||||
AC_SUBST(AM_CFLAGS)
|
||||
|
||||
if test "$require_imaging" = "yes"; then
|
||||
if test x$gdkpixbuf_found != no; then
|
||||
AC_MSG_NOTICE([** Using gdk-pixbuf for imaging])
|
||||
else
|
||||
AC_MSG_NOTICE([** Using ImageMagick for imaging])
|
||||
fi
|
||||
else
|
||||
AC_MSG_NOTICE([ Imaging support disabled])
|
||||
fi
|
||||
|
||||
if test x$enable_upekts != xno ; then
|
||||
AC_MSG_NOTICE([** upekts driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ upekts driver disabled])
|
||||
fi
|
||||
if test x$enable_upeke2 != xno ; then
|
||||
AC_MSG_NOTICE([** upeke2 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ upeke2 driver disabled])
|
||||
fi
|
||||
if test x$enable_upektc != xno ; then
|
||||
AC_MSG_NOTICE([** upektc driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ upektc driver disabled])
|
||||
fi
|
||||
if test x$enable_upeksonly != xno ; then
|
||||
AC_MSG_NOTICE([** upeksonly driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ upeksonly driver disabled])
|
||||
fi
|
||||
if test x$enable_vcom5s != xno ; then
|
||||
AC_MSG_NOTICE([** vcom5s driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ vcom5s driver disabled])
|
||||
fi
|
||||
if test x$enable_uru4000 != xno ; then
|
||||
AC_MSG_NOTICE([** uru4000 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ uru4000 driver disabled])
|
||||
fi
|
||||
if test x$enable_fdu2000 != xno ; then
|
||||
AC_MSG_NOTICE([** fdu2000 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ fdu2000 driver disabled])
|
||||
fi
|
||||
if test x$enable_aes1610 != xno ; then
|
||||
AC_MSG_NOTICE([** aes1610 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ aes1610 driver disabled])
|
||||
fi
|
||||
if test x$enable_aes2501 != xno ; then
|
||||
AC_MSG_NOTICE([** aes2501 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ aes2501 driver disabled])
|
||||
fi
|
||||
if test x$enable_aes4000 != xno ; then
|
||||
AC_MSG_NOTICE([** aes4000 driver enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ aes4000 driver disabled])
|
||||
fi
|
||||
if test x$require_aeslib != xno ; then
|
||||
AC_MSG_NOTICE([** aeslib helper functions enabled])
|
||||
else
|
||||
AC_MSG_NOTICE([ aeslib helper functions disabled])
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] [examples/Makefile] [doc/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
EXTRA_DIST = doxygen.cfg
|
||||
|
||||
docs: doxygen.cfg
|
||||
doxygen $^
|
||||
|
||||
docs-upload: docs
|
||||
ln -s html api
|
||||
ncftpput -f ~/.ncftp/reactivated -m -R httpdocs/fprint api/
|
||||
rm -f api
|
||||
|
||||
115
doc/advanced-topics.xml
Normal file
115
doc/advanced-topics.xml
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="advanced-topics" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<title>Advanced Topics</title>
|
||||
|
||||
<refsect2 id="compatibility">
|
||||
<title>Device and print compatibility</title>
|
||||
|
||||
<para>
|
||||
Moving off generic conceptual ideas and onto libfprint-specific
|
||||
implementation details, here are some introductory notes regarding how
|
||||
libfprint copes with compatibility of fingerprints.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
libfprint deals with a whole variety of different fingerprint readers and
|
||||
the design includes considerations of compatibility and interoperability
|
||||
between multiple devices. Your application should also be prepared to
|
||||
work with more than one type of fingerprint reader and should consider that
|
||||
enrolled fingerprint X may not be compatible with the device the user has
|
||||
plugged in today.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
libfprint implements the principle that fingerprints from different devices
|
||||
are not necessarily compatible. For example, different devices may see
|
||||
significantly different areas of fingerprint surface, and comparing images
|
||||
between the devices would be unreliable. Also, devices can stretch and
|
||||
distort images in different ways.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
libfprint also implements the principle that in some cases, fingerprints
|
||||
<emphasis>are</emphasis> compatible between different devices. If you go and buy two
|
||||
identical fingerprint readers, it seems logical that you should be able
|
||||
to enroll on one and verify on another without problems.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
libfprint takes a fairly simplistic approach to these issues. Internally,
|
||||
fingerprint hardware is driven by individual drivers. libfprint enforces
|
||||
that a fingerprint that came from a device backed by driver X is never
|
||||
compared to a fingerprint that came from a device backed by driver Y.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally, libfprint is designed for the situation where a single driver
|
||||
may support a range of devices which differ in imaging or scanning
|
||||
properties. For example, a driver may support two ranges of devices which
|
||||
even though are programmed over the same interface, one device sees
|
||||
substantially less of the finger flesh, therefore images from the two
|
||||
device types should be incompatible despite being from the same driver. To
|
||||
implement this, each driver assigns a <emphasis>device type</emphasis> to each device
|
||||
that it detects based on its imaging characteristics. libfprint ensures that
|
||||
two prints being compared have the same device type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In summary, libfprint represents fingerprints in several internal structures
|
||||
and each representation will offer you a way of determining the
|
||||
<ulink url="#driver_id">driver ID</ulink> and <ulink url="#device-types">devtype</ulink> of the print in
|
||||
question. Prints are only compatible if the driver ID <emphasis role="strong">and</emphasis> devtypes
|
||||
match. libfprint does offer you some "is this print compatible?" helper
|
||||
functions, so you don't have to worry about these details too much.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="driver_id">
|
||||
<title>Driver IDs</title>
|
||||
|
||||
<para>
|
||||
Each driver is assigned a unique ID by the project maintainer. These
|
||||
assignments are
|
||||
<ulink url="https://gitlab.freedesktop.org/libfprint/libfprint/blob/master/libfprint/drivers/driver_ids.h">
|
||||
documented in the sources</ulink> and will never change.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The only reason you may be interested in retrieving the driver ID for a
|
||||
driver is for the purpose of checking if some print data is compatible
|
||||
with a device. libfprint uses the driver ID as one way of checking that
|
||||
the print you are trying to verify is compatible with the device in
|
||||
question - it ensures that enrollment data from one driver is never fed to
|
||||
another. Note that libfprint does provide you with helper functions to
|
||||
determine whether a print is compatible with a device, so under most
|
||||
circumstances, you don't have to worry about driver IDs at all.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="device-types">
|
||||
<title>Device types</title>
|
||||
|
||||
<para>
|
||||
Internally, the <ulink url="libfprint-Driver-operations.html#libfprint-Driver-operations.description">driver</ulink> behind a device assigns a 32-bit
|
||||
<emphasis>devtype</emphasis> identifier to the device. This cannot be used as a unique
|
||||
ID for a specific device as many devices under the same range may share
|
||||
the same devtype. The devtype may even be 0 in all cases.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The only reason you may be interested in retrieving the devtype for a
|
||||
device is for the purpose of checking if some print data is compatible
|
||||
with a device. libfprint uses the devtype as one way of checking that the
|
||||
print you are verifying is compatible with the device in question - the
|
||||
devtypes must be equal. This effectively allows drivers to support more
|
||||
than one type of device where the data from each one is not compatible with
|
||||
the other. Note that libfprint does provide you with helper functions to
|
||||
determine whether a print is compatible with a device, so under most
|
||||
circumstances, you don't have to worry about devtypes at all.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
</chapter>
|
||||
1294
doc/doxygen.cfg
1294
doc/doxygen.cfg
File diff suppressed because it is too large
Load Diff
30
doc/getting-started.xml
Normal file
30
doc/getting-started.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<title>Getting Started</title>
|
||||
|
||||
<para>
|
||||
libfprint includes several simple functional examples under the <computeroutput>examples/</computeroutput>
|
||||
directory in the libfprint source distribution. Those are good starting
|
||||
points.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Usually the first thing you want to do is determine which fingerprint
|
||||
devices are present. This is done through <ulink url="libfprint-Device-discovery.html">device discovery</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once you have found a device you would like to operate, you should open it.
|
||||
Refer to <ulink url="libfprint-Devices-operations.html">device operations</ulink>. This section also details enrollment,
|
||||
image capture, and verification.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
That should be enough to get you started, but do remember there are
|
||||
documentation pages on other aspects of libfprint's API (see the modules
|
||||
page).
|
||||
</para>
|
||||
</chapter>
|
||||
106
doc/intro.xml
Normal file
106
doc/intro.xml
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
||||
]>
|
||||
<chapter id="intro" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
libfprint is an open source library to provide access to fingerprint
|
||||
scanning devices. For more info, see the
|
||||
<ulink url="https://fprint.freedesktop.org/">libfprint project homepage</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This documentation is aimed at application developers who wish to integrate
|
||||
fingerprint-related functionality into their software. libfprint has been
|
||||
designed so that you only have to do this once – by integrating your
|
||||
software with libfprint, you'll be supporting all the fingerprint readers
|
||||
that we have got our hands on. As such, the API is rather general (and
|
||||
therefore hopefully easy to comprehend!), and does its best to hide the
|
||||
technical details that required to operate the hardware.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This documentation is not aimed at developers wishing to develop and
|
||||
contribute fingerprint device drivers to libfprint.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Feedback on this API and its associated documentation is appreciated. Was
|
||||
anything unclear? Does anything seem unreasonably complicated? Is anything
|
||||
missing? Let us know on the
|
||||
<ulink url="https://lists.freedesktop.org/mailman/listinfo/fprint">mailing list</ulink>.
|
||||
</para>
|
||||
|
||||
<refsect2 id="enrollment">
|
||||
<title>Enrollment</title>
|
||||
|
||||
<para>
|
||||
Before you dive into the API, it's worth introducing a couple of concepts.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The process of enrolling a finger is where you effectively scan your
|
||||
finger for the purposes of teaching the system what your finger looks like.
|
||||
This means that you scan your fingerprint, then the system processes it and
|
||||
stores some data about your fingerprint to refer to later.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="verification">
|
||||
<title>Verification</title>
|
||||
|
||||
<para>
|
||||
Verification is what most people think of when they think about fingerprint
|
||||
scanning. The process of verification is effectively performing a fresh
|
||||
fingerprint scan, and then comparing that scan to a finger that was
|
||||
previously enrolled.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As an example scenario, verification can be used to implement what people
|
||||
would picture as fingerprint login (i.e. fingerprint replaces password).
|
||||
For example:
|
||||
</para>
|
||||
<itemizedlist mark='dot'>
|
||||
<listitem>
|
||||
I enroll my fingerprint through some software that trusts I am who I say
|
||||
I am. This is a prerequisite before I can perform fingerprint-based
|
||||
login for my account.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Some time later, I want to login to my computer. I enter my username,
|
||||
but instead of prompting me for a password, it asks me to scan my finger.
|
||||
I scan my finger.
|
||||
</listitem>
|
||||
<listitem>
|
||||
The system compares the finger I just scanned to the one that was
|
||||
enrolled earlier. If the system decides that the fingerprints match,
|
||||
I am successfully logged in. Otherwise, the system informs me that I am
|
||||
not authorised to login as that user.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="identification">
|
||||
<title>Identification</title>
|
||||
|
||||
<para>
|
||||
Identification is the process of comparing a freshly scanned fingerprint
|
||||
to a <emphasis>collection</emphasis> of previously enrolled fingerprints. For example,
|
||||
imagine there are 100 people in an organisation, and they all have enrolled
|
||||
their fingerprints. One user walks up to a fingerprint scanner and scans
|
||||
their finger. With <emphasis>no other knowledge</emphasis> of who that user might be,
|
||||
the system examines their fingerprint, looks in the database, and determines
|
||||
that the user is user number #61.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In other words, verification might be seen as a one-to-one fingerprint
|
||||
comparison where you know the identity of the user that you wish to
|
||||
authenticate, whereas identification is a one-to-many comparison where you
|
||||
do not know the identity of the user that you wish to authenticate.
|
||||
</para>
|
||||
</refsect2>
|
||||
</chapter>
|
||||
53
doc/libfprint-docs.xml
Normal file
53
doc/libfprint-docs.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||
]>
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>libfprint Reference Manual</title>
|
||||
<releaseinfo>
|
||||
<para>This document is the API reference for the libfprint library.</para>
|
||||
<para>
|
||||
The latest version of libfprint, as well as the latest version of
|
||||
this API reference, is <ulink role="online-location" url="https://fprint.freedesktop.org/libfprint-dev/">available online</ulink>.
|
||||
</para>
|
||||
</releaseinfo>
|
||||
</bookinfo>
|
||||
|
||||
<part>
|
||||
<title>Library Overview</title>
|
||||
<xi:include href="intro.xml"/>
|
||||
<xi:include href="advanced-topics.xml"/>
|
||||
<xi:include href="getting-started.xml"/>
|
||||
</part>
|
||||
|
||||
<part>
|
||||
<title>API Documentation</title>
|
||||
<xi:include href="xml/events.xml"/>
|
||||
<xi:include href="xml/discovery.xml"/>
|
||||
|
||||
<xi:include href="xml/drv.xml"/>
|
||||
<xi:include href="xml/dev.xml"/>
|
||||
<xi:include href="xml/print_data.xml"/>
|
||||
<!-- FIXME https://bugs.freedesktop.org/show_bug.cgi?id=106550 -->
|
||||
<xi:include href="xml/dscv_print.xml"/>
|
||||
<xi:include href="xml/img.xml"/>
|
||||
</part>
|
||||
|
||||
<!--
|
||||
<part>
|
||||
<title>Writing Drivers</title>
|
||||
</part>
|
||||
-->
|
||||
|
||||
<index id="api-index">
|
||||
<title>API Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
<index id="deprecated-api-index" role="deprecated">
|
||||
<title>Index of deprecated API</title>
|
||||
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
</book>
|
||||
136
doc/libfprint-sections.txt
Normal file
136
doc/libfprint-sections.txt
Normal file
@@ -0,0 +1,136 @@
|
||||
<INCLUDE>fprint.h</INCLUDE>
|
||||
|
||||
<SECTION>
|
||||
<FILE>events</FILE>
|
||||
<TITLE>Initialisation and events handling</TITLE>
|
||||
fp_set_debug
|
||||
fp_init
|
||||
fp_exit
|
||||
fp_pollfd
|
||||
fp_handle_events_timeout
|
||||
fp_handle_events
|
||||
fp_get_next_timeout
|
||||
fp_get_pollfds
|
||||
fp_pollfd_added_cb
|
||||
fp_pollfd_removed_cb
|
||||
fp_set_pollfd_notifiers
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>discovery</FILE>
|
||||
<TITLE>Device discovery</TITLE>
|
||||
fp_dscv_dev
|
||||
fp_discover_devs
|
||||
fp_dscv_devs_free
|
||||
fp_dscv_dev_get_driver
|
||||
fp_dscv_dev_get_devtype
|
||||
fp_dscv_dev_get_driver_id
|
||||
fp_dscv_dev_supports_print_data
|
||||
fp_dscv_dev_supports_dscv_print
|
||||
fp_dscv_dev_for_print_data
|
||||
fp_dscv_dev_for_dscv_print
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>drv</FILE>
|
||||
fp_driver
|
||||
fp_driver_get_name
|
||||
fp_driver_get_full_name
|
||||
fp_driver_get_driver_id
|
||||
fp_driver_get_scan_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>dev</FILE>
|
||||
fp_dev
|
||||
fp_scan_type
|
||||
fp_capture_result
|
||||
fp_enroll_result
|
||||
fp_verify_result
|
||||
|
||||
fp_dev_get_driver
|
||||
fp_dev_get_nr_enroll_stages
|
||||
fp_dev_get_devtype
|
||||
fp_dev_supports_print_data
|
||||
fp_dev_supports_imaging
|
||||
fp_dev_supports_identification
|
||||
fp_dev_supports_dscv_print
|
||||
fp_dev_get_img_width
|
||||
fp_dev_get_img_height
|
||||
|
||||
fp_operation_stop_cb
|
||||
fp_img_operation_cb
|
||||
fp_dev_open_cb
|
||||
fp_enroll_stage_cb
|
||||
fp_identify_cb
|
||||
|
||||
fp_dev_open
|
||||
fp_async_dev_open
|
||||
|
||||
fp_dev_close
|
||||
fp_async_dev_close
|
||||
|
||||
fp_enroll_finger
|
||||
fp_enroll_finger_img
|
||||
fp_async_enroll_start
|
||||
fp_async_enroll_stop
|
||||
|
||||
fp_verify_finger
|
||||
fp_verify_finger_img
|
||||
fp_async_verify_start
|
||||
fp_async_verify_stop
|
||||
|
||||
fp_identify_finger
|
||||
fp_identify_finger_img
|
||||
fp_async_identify_start
|
||||
fp_async_identify_stop
|
||||
|
||||
fp_dev_img_capture
|
||||
fp_async_capture_start
|
||||
fp_async_capture_stop
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>print_data</FILE>
|
||||
fp_finger
|
||||
fp_print_data
|
||||
fp_print_data
|
||||
fp_print_data_get_data
|
||||
fp_print_data_from_data
|
||||
fp_print_data_save
|
||||
fp_print_data_load
|
||||
fp_print_data_delete
|
||||
fp_print_data_from_dscv_print
|
||||
fp_print_data_free
|
||||
fp_print_data_get_driver_id
|
||||
fp_print_data_get_devtype
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>dscv_print</FILE>
|
||||
fp_dscv_print
|
||||
fp_discover_prints
|
||||
fp_dscv_prints_free
|
||||
fp_dscv_print_get_driver_id
|
||||
fp_dscv_print_get_devtype
|
||||
fp_dscv_print_get_finger
|
||||
fp_dscv_print_delete
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>img</FILE>
|
||||
fp_img
|
||||
fp_minutia
|
||||
fp_img_free
|
||||
fp_img_get_height
|
||||
fp_img_get_width
|
||||
fp_img_get_data
|
||||
fp_img_save_to_file
|
||||
fp_img_standardize
|
||||
fp_img_binarize
|
||||
fp_img_get_minutiae
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>poll</FILE>
|
||||
</SECTION>
|
||||
67
doc/meson.build
Normal file
67
doc/meson.build
Normal file
@@ -0,0 +1,67 @@
|
||||
subdir('xml')
|
||||
|
||||
private_headers = [
|
||||
'config.h',
|
||||
|
||||
'aeslib.h',
|
||||
'assembling.h',
|
||||
'fp_internal.h',
|
||||
|
||||
# Drivers
|
||||
'aes1660.h',
|
||||
'aes2501.h',
|
||||
'aes2550.h',
|
||||
'aes2660.h',
|
||||
'aes3k.h',
|
||||
'aesx660.h',
|
||||
'driver_ids.h',
|
||||
'elan.h',
|
||||
'upeksonly.h',
|
||||
'upektc.h',
|
||||
'upektc_img.h',
|
||||
'vfs0050.h',
|
||||
'vfs301_proto_fragments.h',
|
||||
'vfs301_proto.h',
|
||||
'vfs5011_proto.h',
|
||||
|
||||
# NBIS
|
||||
'morph.h',
|
||||
'sunrast.h',
|
||||
'bozorth.h',
|
||||
'defs.h',
|
||||
'log.h',
|
||||
'bz_array.h',
|
||||
'lfs.h',
|
||||
]
|
||||
|
||||
html_images = [
|
||||
]
|
||||
|
||||
content_files = [
|
||||
'intro.xml'
|
||||
]
|
||||
|
||||
expand_content_files = content_files
|
||||
|
||||
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
|
||||
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
||||
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
|
||||
|
||||
gnome.gtkdoc('libfprint',
|
||||
main_xml: 'libfprint-docs.xml',
|
||||
src_dir: join_paths(meson.source_root(), 'libfprint'),
|
||||
dependencies: libfprint_dep,
|
||||
content_files: content_files,
|
||||
expand_content_files: expand_content_files,
|
||||
scan_args: [
|
||||
'--rebuild-types',
|
||||
'--ignore-decorators=API_EXPORTED',
|
||||
'--ignore-headers=' + ' '.join(private_headers),
|
||||
],
|
||||
fixxref_args: [
|
||||
'--html-dir=@0@'.format(docpath),
|
||||
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
|
||||
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')),
|
||||
],
|
||||
html_assets: html_images,
|
||||
install: true)
|
||||
8
doc/xml/gtkdocentities.ent.in
Normal file
8
doc/xml/gtkdocentities.ent.in
Normal file
@@ -0,0 +1,8 @@
|
||||
<!ENTITY package "@PACKAGE@">
|
||||
<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
|
||||
<!ENTITY package_name "@PACKAGE_NAME@">
|
||||
<!ENTITY package_string "@PACKAGE_STRING@">
|
||||
<!ENTITY package_tarname "@PACKAGE_TARNAME@">
|
||||
<!ENTITY package_url "@PACKAGE_URL@">
|
||||
<!ENTITY package_version "@PACKAGE_VERSION@">
|
||||
<!ENTITY package_api_version "@PACKAGE_API_VERSION@">
|
||||
10
doc/xml/meson.build
Normal file
10
doc/xml/meson.build
Normal file
@@ -0,0 +1,10 @@
|
||||
ent_conf = configuration_data()
|
||||
ent_conf.set('PACKAGE', 'libfprint')
|
||||
ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/libfprint/libfprint/issues')
|
||||
ent_conf.set('PACKAGE_NAME', 'libfprint')
|
||||
ent_conf.set('PACKAGE_STRING', 'libfprint')
|
||||
ent_conf.set('PACKAGE_TARNAME', 'libfprint-' + meson.project_version())
|
||||
ent_conf.set('PACKAGE_URL', 'https://fprint.freedesktop.org/')
|
||||
ent_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||
ent_conf.set('PACKAGE_API_VERSION', '1.0')
|
||||
configure_file(input: 'gtkdocentities.ent.in', output: 'gtkdocentities.ent', configuration: ent_conf)
|
||||
@@ -1,26 +0,0 @@
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
noinst_PROGRAMS = verify_live enroll verify img_capture cpp-test
|
||||
|
||||
verify_live_SOURCES = verify_live.c
|
||||
verify_live_LDADD = ../libfprint/libfprint.la
|
||||
|
||||
enroll_SOURCES = enroll.c
|
||||
enroll_LDADD = ../libfprint/libfprint.la
|
||||
|
||||
verify_SOURCES = verify.c
|
||||
verify_LDADD = ../libfprint/libfprint.la
|
||||
|
||||
img_capture_SOURCES = img_capture.c
|
||||
img_capture_LDADD = ../libfprint/libfprint.la
|
||||
|
||||
cpp_test_SOURCES = cpp-test.cpp
|
||||
cpp_test_LDADD = ../libfprint/libfprint.la
|
||||
|
||||
if BUILD_X11_EXAMPLES
|
||||
noinst_PROGRAMS += img_capture_continuous
|
||||
|
||||
img_capture_continuous_CFLAGS = $(X_CFLAGS) $(XV_CFLAGS)
|
||||
img_capture_continuous_SOURCES = img_capture_continuous.c
|
||||
img_capture_continuous_LDADD = ../libfprint/libfprint.la $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS);
|
||||
endif
|
||||
|
||||
@@ -110,12 +110,14 @@ int main(void)
|
||||
"Ctrl+C\n");
|
||||
getchar();
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
fp_set_debug(3);
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
|
||||
@@ -42,12 +42,14 @@ int main(void)
|
||||
struct fp_dev *dev;
|
||||
struct fp_img *img = NULL;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
fp_set_debug(3);
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
@@ -57,6 +59,7 @@ int main(void)
|
||||
|
||||
ddev = discover_device(discovered_devs);
|
||||
if (!ddev) {
|
||||
fp_dscv_devs_free(discovered_devs);
|
||||
fprintf(stderr, "No devices detected.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define FORMAT 0x32595559
|
||||
|
||||
static int adaptor = -1;
|
||||
static unsigned char *framebuffer = NULL;
|
||||
static char *framebuffer = NULL;
|
||||
|
||||
static Display *display = NULL;
|
||||
static Window window=(Window)NULL;
|
||||
@@ -50,10 +50,10 @@ static int connection = -1;
|
||||
u = u > 255 ? 255 : u;\
|
||||
v = v > 255 ? 255 : v
|
||||
|
||||
static void grey2yuy2 (unsigned char *grey, unsigned char *YUV, int num) {
|
||||
static void grey2yuy2 (unsigned char *grey, char *YUV, int num) {
|
||||
int i, j;
|
||||
int y0, y1, u0, u1, v0, v1;
|
||||
int gval;
|
||||
uint64_t gval;
|
||||
|
||||
for (i = 0, j = 0; i < num; i += 2, j += 4)
|
||||
{
|
||||
@@ -84,9 +84,9 @@ static void display_frame(struct fp_img *img)
|
||||
0, 0, width, height, 0, 0, width, height);
|
||||
}
|
||||
|
||||
static void QueryXv()
|
||||
static void QueryXv(void)
|
||||
{
|
||||
int num_adaptors;
|
||||
unsigned int num_adaptors;
|
||||
int num_formats;
|
||||
XvImageFormatValues *formats = NULL;
|
||||
int i,j;
|
||||
@@ -141,12 +141,14 @@ int main(void)
|
||||
int img_height;
|
||||
int standardize = 0;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
fp_set_debug(3);
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
|
||||
29
examples/meson.build
Normal file
29
examples/meson.build
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ]
|
||||
foreach example: examples
|
||||
executable(example,
|
||||
example + '.c',
|
||||
dependencies: libfprint_dep,
|
||||
include_directories: [
|
||||
root_inc,
|
||||
],
|
||||
c_args: common_cflags)
|
||||
endforeach
|
||||
|
||||
executable('cpp-test',
|
||||
'cpp-test.cpp',
|
||||
dependencies: libfprint_dep,
|
||||
include_directories: [
|
||||
root_inc,
|
||||
],
|
||||
c_args: common_cflags)
|
||||
|
||||
if get_option('x11-examples')
|
||||
executable('img_capture_continuous',
|
||||
'img_capture_continuous.c',
|
||||
dependencies: [ libfprint_dep, xv_dep, x11_dep ],
|
||||
include_directories: [
|
||||
root_inc,
|
||||
],
|
||||
c_args: common_cflags)
|
||||
endif
|
||||
@@ -86,12 +86,14 @@ int main(void)
|
||||
struct fp_dev *dev;
|
||||
struct fp_print_data *data;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
fp_set_debug(3);
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
|
||||
@@ -129,12 +129,14 @@ int main(void)
|
||||
struct fp_dev *dev;
|
||||
struct fp_print_data *data;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
fp_set_debug(3);
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libfprint
|
||||
Description: Generic C API for fingerprint reader access
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lfprint
|
||||
Cflags: -I${includedir}/libfprint
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
lib_LTLIBRARIES = libfprint.la
|
||||
noinst_PROGRAMS = fprint-list-udev-rules
|
||||
MOSTLYCLEANFILES = $(udev_rules_DATA)
|
||||
|
||||
UPEKE2_SRC = drivers/upeke2.c
|
||||
UPEKTS_SRC = drivers/upekts.c
|
||||
UPEKTC_SRC = drivers/upektc.c
|
||||
UPEKSONLY_SRC = drivers/upeksonly.c
|
||||
URU4000_SRC = drivers/uru4000.c
|
||||
AES1610_SRC = drivers/aes1610.c
|
||||
AES2501_SRC = drivers/aes2501.c drivers/aes2501.h
|
||||
AES4000_SRC = drivers/aes4000.c
|
||||
FDU2000_SRC = drivers/fdu2000.c
|
||||
VCOM5S_SRC = drivers/vcom5s.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(UPEKE2_SRC) \
|
||||
$(UPEKTS_SRC) \
|
||||
$(UPEKTC_SRC) \
|
||||
$(UPEKSONLY_SRC) \
|
||||
$(URU4000_SRC) \
|
||||
$(AES1610_SRC) \
|
||||
$(AES2501_SRC) \
|
||||
$(AES4000_SRC) \
|
||||
$(FDU2000_SRC) \
|
||||
$(VCOM5S_SRC) \
|
||||
aeslib.c aeslib.h \
|
||||
imagemagick.c \
|
||||
gdkpixbuf.c
|
||||
|
||||
DRIVER_SRC =
|
||||
OTHER_SRC =
|
||||
|
||||
NBIS_SRC = \
|
||||
nbis/include/bozorth.h \
|
||||
nbis/include/bz_array.h \
|
||||
nbis/include/defs.h \
|
||||
nbis/include/lfs.h \
|
||||
nbis/include/log.h \
|
||||
nbis/include/morph.h \
|
||||
nbis/include/sunrast.h \
|
||||
nbis/bozorth3/bozorth3.c \
|
||||
nbis/bozorth3/bz_alloc.c \
|
||||
nbis/bozorth3/bz_drvrs.c \
|
||||
nbis/bozorth3/bz_gbls.c \
|
||||
nbis/bozorth3/bz_io.c \
|
||||
nbis/bozorth3/bz_sort.c \
|
||||
nbis/mindtct/binar.c \
|
||||
nbis/mindtct/block.c \
|
||||
nbis/mindtct/contour.c \
|
||||
nbis/mindtct/detect.c \
|
||||
nbis/mindtct/dft.c \
|
||||
nbis/mindtct/free.c \
|
||||
nbis/mindtct/globals.c \
|
||||
nbis/mindtct/imgutil.c \
|
||||
nbis/mindtct/init.c \
|
||||
nbis/mindtct/line.c \
|
||||
nbis/mindtct/log.c \
|
||||
nbis/mindtct/loop.c \
|
||||
nbis/mindtct/maps.c \
|
||||
nbis/mindtct/matchpat.c \
|
||||
nbis/mindtct/minutia.c \
|
||||
nbis/mindtct/morph.c \
|
||||
nbis/mindtct/quality.c \
|
||||
nbis/mindtct/remove.c \
|
||||
nbis/mindtct/ridges.c \
|
||||
nbis/mindtct/shape.c \
|
||||
nbis/mindtct/sort.c \
|
||||
nbis/mindtct/util.c
|
||||
|
||||
libfprint_la_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS)
|
||||
libfprint_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@
|
||||
libfprint_la_LIBADD = -lm $(LIBUSB_LIBS) $(GLIB_LIBS) $(CRYPTO_LIBS)
|
||||
|
||||
fprint_list_udev_rules_SOURCES = fprint-list-udev-rules.c
|
||||
fprint_list_udev_rules_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(IMAGEMAGICK_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS)
|
||||
fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la
|
||||
|
||||
udev_rules_DATA = 60-fprint-autosuspend.rules
|
||||
udev_rulesdir = $(sysconfdir)/udev/rules.d/
|
||||
|
||||
$(udev_rules_DATA): fprint-list-udev-rules
|
||||
$(builddir)/fprint-list-udev-rules > $@
|
||||
|
||||
if ENABLE_UPEKE2
|
||||
DRIVER_SRC += $(UPEKE2_SRC)
|
||||
endif
|
||||
|
||||
if ENABLE_UPEKTS
|
||||
DRIVER_SRC += $(UPEKTS_SRC)
|
||||
endif
|
||||
|
||||
if ENABLE_UPEKSONLY
|
||||
DRIVER_SRC += $(UPEKSONLY_SRC)
|
||||
endif
|
||||
|
||||
#if ENABLE_UPEKTC
|
||||
#DRIVER_SRC += $(UPEKTC_SRC)
|
||||
#endif
|
||||
|
||||
if ENABLE_URU4000
|
||||
DRIVER_SRC += $(URU4000_SRC)
|
||||
endif
|
||||
|
||||
if ENABLE_VCOM5S
|
||||
DRIVER_SRC += $(VCOM5S_SRC)
|
||||
endif
|
||||
|
||||
#if ENABLE_FDU2000
|
||||
#DRIVER_SRC += $(FDU2000_SRC)
|
||||
#endif
|
||||
|
||||
if ENABLE_AES1610
|
||||
DRIVER_SRC += $(AES1610_SRC)
|
||||
endif
|
||||
|
||||
if ENABLE_AES2501
|
||||
DRIVER_SRC += $(AES2501_SRC)
|
||||
endif
|
||||
|
||||
if ENABLE_AES4000
|
||||
DRIVER_SRC += $(AES4000_SRC)
|
||||
endif
|
||||
|
||||
if REQUIRE_IMAGEMAGICK
|
||||
OTHER_SRC += imagemagick.c
|
||||
libfprint_la_CFLAGS += $(IMAGING_CFLAGS)
|
||||
libfprint_la_LIBADD += $(IMAGING_LIBS)
|
||||
endif
|
||||
|
||||
if REQUIRE_GDKPIXBUF
|
||||
OTHER_SRC += gdkpixbuf.c
|
||||
libfprint_la_CFLAGS += $(IMAGING_CFLAGS)
|
||||
libfprint_la_LIBADD += $(IMAGING_LIBS)
|
||||
endif
|
||||
|
||||
if REQUIRE_AESLIB
|
||||
OTHER_SRC += aeslib.c aeslib.h
|
||||
endif
|
||||
|
||||
libfprint_la_SOURCES = \
|
||||
fp_internal.h \
|
||||
async.c \
|
||||
core.c \
|
||||
data.c \
|
||||
drv.c \
|
||||
img.c \
|
||||
imgdev.c \
|
||||
poll.c \
|
||||
sync.c \
|
||||
$(DRIVER_SRC) \
|
||||
$(OTHER_SRC) \
|
||||
$(NBIS_SRC)
|
||||
|
||||
pkginclude_HEADERS = fprint.h
|
||||
@@ -19,12 +19,15 @@
|
||||
|
||||
#define FP_COMPONENT "aeslib"
|
||||
|
||||
#include "fp_internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "fp_internal.h"
|
||||
#include "assembling.h"
|
||||
#include "aeslib.h"
|
||||
|
||||
#define MAX_REGWRITES_PER_REQUEST 16
|
||||
@@ -157,17 +160,16 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
||||
continue_write_regv(wdata);
|
||||
}
|
||||
|
||||
void aes_assemble_image(unsigned char *input, size_t width, size_t height,
|
||||
unsigned char *output)
|
||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fpi_frame *frame,
|
||||
unsigned int x,
|
||||
unsigned int y)
|
||||
{
|
||||
size_t row, column;
|
||||
unsigned char ret;
|
||||
|
||||
for (column = 0; column < width; column++) {
|
||||
for (row = 0; row < height; row += 2) {
|
||||
output[width * row + column] = (*input & 0x07) * 36;
|
||||
output[width * (row + 1) + column] = ((*input & 0x70) >> 4) * 36;
|
||||
input++;
|
||||
}
|
||||
}
|
||||
ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)];
|
||||
ret = y % 2 ? ret >> 4 : ret & 0xf;
|
||||
ret *= 17;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,21 +20,26 @@
|
||||
#ifndef __AESLIB_H__
|
||||
#define __AESLIB_H__
|
||||
|
||||
#include <fp_internal.h>
|
||||
#include <fprint.h>
|
||||
|
||||
struct aes_regwrite {
|
||||
unsigned char reg;
|
||||
unsigned char value;
|
||||
};
|
||||
|
||||
struct fpi_frame;
|
||||
struct fpi_frame_asmbl_ctx;
|
||||
|
||||
typedef void (*aes_write_regv_cb)(struct fp_img_dev *dev, int result,
|
||||
void *user_data);
|
||||
|
||||
void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
||||
unsigned int num_regs, aes_write_regv_cb callback, void *user_data);
|
||||
|
||||
void aes_assemble_image(unsigned char *input, size_t width, size_t height,
|
||||
unsigned char *output);
|
||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fpi_frame *frame,
|
||||
unsigned int x,
|
||||
unsigned int y);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
434
libfprint/assembling.c
Normal file
434
libfprint/assembling.c
Normal file
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Image assembling routines
|
||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright (C) 2013 Arseniy Lartsev <arseniy@chalmers.se>
|
||||
* Copyright (C) 2015 Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "assembling"
|
||||
|
||||
#include "fp_internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "assembling.h"
|
||||
|
||||
static unsigned int calc_error(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fpi_frame *first_frame,
|
||||
struct fpi_frame *second_frame,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
unsigned int width, height;
|
||||
unsigned int x1, y1, x2, y2, err, i, j;
|
||||
|
||||
width = ctx->frame_width - (dx > 0 ? dx : -dx);
|
||||
height = ctx->frame_height - dy;
|
||||
|
||||
y1 = 0;
|
||||
y2 = dy;
|
||||
i = 0;
|
||||
err = 0;
|
||||
do {
|
||||
x1 = dx < 0 ? 0 : dx;
|
||||
x2 = dx < 0 ? -dx : 0;
|
||||
j = 0;
|
||||
|
||||
do {
|
||||
unsigned char v1, v2;
|
||||
|
||||
|
||||
v1 = ctx->get_pixel(ctx, first_frame, x1, y1);
|
||||
v2 = ctx->get_pixel(ctx, second_frame, x2, y2);
|
||||
err += v1 > v2 ? v1 - v2 : v2 - v1;
|
||||
j++;
|
||||
x1++;
|
||||
x2++;
|
||||
|
||||
} while (j < width);
|
||||
i++;
|
||||
y1++;
|
||||
y2++;
|
||||
} while (i < height);
|
||||
|
||||
/* Normalize error */
|
||||
err *= (ctx->frame_height * ctx->frame_width);
|
||||
err /= (height * width);
|
||||
|
||||
if (err == 0)
|
||||
return INT_MAX;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* This function is rather CPU-intensive. It's better to use hardware
|
||||
* to detect movement direction when possible.
|
||||
*/
|
||||
static void find_overlap(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fpi_frame *first_frame,
|
||||
struct fpi_frame *second_frame,
|
||||
unsigned int *min_error)
|
||||
{
|
||||
int dx, dy;
|
||||
unsigned int err;
|
||||
*min_error = 255 * ctx->frame_height * ctx->frame_width;
|
||||
|
||||
/* Seeking in horizontal and vertical dimensions,
|
||||
* for horizontal dimension we'll check only 8 pixels
|
||||
* in both directions. For vertical direction diff is
|
||||
* rarely less than 2, so start with it.
|
||||
*/
|
||||
for (dy = 2; dy < ctx->frame_height; dy++) {
|
||||
for (dx = -8; dx < 8; dx++) {
|
||||
err = calc_error(ctx, first_frame, second_frame,
|
||||
dx, dy);
|
||||
if (err < *min_error) {
|
||||
*min_error = err;
|
||||
second_frame->delta_x = -dx;
|
||||
second_frame->delta_y = dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
||||
GSList *stripes, size_t num_stripes,
|
||||
gboolean reverse)
|
||||
{
|
||||
GSList *list_entry = stripes;
|
||||
GTimer *timer;
|
||||
int frame = 1;
|
||||
struct fpi_frame *prev_stripe = list_entry->data;
|
||||
unsigned int min_error;
|
||||
/* Max error is width * height * 255, for AES2501 which has the largest
|
||||
* sensor its 192*16*255 = 783360. So for 32bit value it's ~5482 frame before
|
||||
* we might get int overflow. Use 64bit value here to prevent integer overflow
|
||||
*/
|
||||
unsigned long long total_error = 0;
|
||||
|
||||
list_entry = g_slist_next(list_entry);
|
||||
|
||||
timer = g_timer_new();
|
||||
do {
|
||||
struct fpi_frame *cur_stripe = list_entry->data;
|
||||
|
||||
if (reverse) {
|
||||
find_overlap(ctx, prev_stripe, cur_stripe, &min_error);
|
||||
cur_stripe->delta_y = -cur_stripe->delta_y;
|
||||
cur_stripe->delta_x = -cur_stripe->delta_x;
|
||||
}
|
||||
else
|
||||
find_overlap(ctx, cur_stripe, prev_stripe, &min_error);
|
||||
total_error += min_error;
|
||||
|
||||
frame++;
|
||||
prev_stripe = cur_stripe;
|
||||
list_entry = g_slist_next(list_entry);
|
||||
|
||||
} while (frame < num_stripes);
|
||||
|
||||
g_timer_stop(timer);
|
||||
fp_dbg("calc delta completed in %f secs", g_timer_elapsed(timer, NULL));
|
||||
g_timer_destroy(timer);
|
||||
|
||||
return total_error / num_stripes;
|
||||
}
|
||||
|
||||
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
||||
GSList *stripes, size_t num_stripes)
|
||||
{
|
||||
int err, rev_err;
|
||||
err = do_movement_estimation(ctx, stripes, num_stripes, FALSE);
|
||||
rev_err = do_movement_estimation(ctx, stripes, num_stripes, TRUE);
|
||||
fp_dbg("errors: %d rev: %d", err, rev_err);
|
||||
if (err < rev_err) {
|
||||
do_movement_estimation(ctx, stripes, num_stripes, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void aes_blit_stripe(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fp_img *img,
|
||||
struct fpi_frame *stripe,
|
||||
int x, int y)
|
||||
{
|
||||
unsigned int ix, iy;
|
||||
unsigned int fx, fy;
|
||||
unsigned int width, height;
|
||||
|
||||
/* Find intersection */
|
||||
if (x < 0) {
|
||||
width = ctx->frame_width + x;
|
||||
ix = 0;
|
||||
fx = -x;
|
||||
} else {
|
||||
ix = x;
|
||||
fx = 0;
|
||||
width = ctx->frame_width;
|
||||
}
|
||||
if ((ix + width) > img->width)
|
||||
width = img->width - ix;
|
||||
|
||||
if (y < 0) {
|
||||
iy = 0;
|
||||
fy = -y;
|
||||
height = ctx->frame_height + y;
|
||||
} else {
|
||||
iy = y;
|
||||
fy = 0;
|
||||
height = ctx->frame_height;
|
||||
}
|
||||
|
||||
if (fx > ctx->frame_width)
|
||||
return;
|
||||
|
||||
if (fy > ctx->frame_height)
|
||||
return;
|
||||
|
||||
if (ix > img->width)
|
||||
return;
|
||||
|
||||
if (iy > img->height)
|
||||
return;
|
||||
|
||||
if ((iy + height) > img->height)
|
||||
height = img->height - iy;
|
||||
|
||||
for (; fy < height; fy++, iy++) {
|
||||
if (x < 0) {
|
||||
ix = 0;
|
||||
fx = -x;
|
||||
} else {
|
||||
ix = x;
|
||||
fx = 0;
|
||||
}
|
||||
for (; fx < width; fx++, ix++) {
|
||||
img->data[ix + (iy * img->width)] = ctx->get_pixel(ctx, stripe, fx, fy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
||||
GSList *stripes, size_t stripes_len)
|
||||
{
|
||||
GSList *stripe;
|
||||
struct fp_img *img;
|
||||
int height = 0;
|
||||
int i, y, x;
|
||||
gboolean reverse = FALSE;
|
||||
struct fpi_frame *fpi_frame;
|
||||
|
||||
BUG_ON(stripes_len == 0);
|
||||
BUG_ON(ctx->image_width < ctx->frame_width);
|
||||
|
||||
/* Calculate height */
|
||||
i = 0;
|
||||
stripe = stripes;
|
||||
|
||||
/* No offset for 1st image */
|
||||
fpi_frame = stripe->data;
|
||||
fpi_frame->delta_x = 0;
|
||||
fpi_frame->delta_y = 0;
|
||||
do {
|
||||
fpi_frame = stripe->data;
|
||||
|
||||
height += fpi_frame->delta_y;
|
||||
i++;
|
||||
stripe = g_slist_next(stripe);
|
||||
} while (i < stripes_len);
|
||||
|
||||
fp_dbg("height is %d", height);
|
||||
|
||||
if (height < 0) {
|
||||
reverse = TRUE;
|
||||
height = -height;
|
||||
}
|
||||
|
||||
/* For last frame */
|
||||
height += ctx->frame_height;
|
||||
|
||||
/* Create buffer big enough for max image */
|
||||
img = fpi_img_new(ctx->image_width * height);
|
||||
img->flags = FP_IMG_COLORS_INVERTED;
|
||||
img->flags |= reverse ? 0 : FP_IMG_H_FLIPPED | FP_IMG_V_FLIPPED;
|
||||
img->width = ctx->image_width;
|
||||
img->height = height;
|
||||
|
||||
/* Assemble stripes */
|
||||
i = 0;
|
||||
stripe = stripes;
|
||||
y = reverse ? (height - ctx->frame_height) : 0;
|
||||
x = (ctx->image_width - ctx->frame_width) / 2;
|
||||
|
||||
do {
|
||||
fpi_frame = stripe->data;
|
||||
|
||||
if(reverse) {
|
||||
y += fpi_frame->delta_y;
|
||||
x += fpi_frame->delta_x;
|
||||
}
|
||||
|
||||
aes_blit_stripe(ctx, img, fpi_frame, x, y);
|
||||
|
||||
if(!reverse) {
|
||||
y += fpi_frame->delta_y;
|
||||
x += fpi_frame->delta_x;
|
||||
}
|
||||
|
||||
stripe = g_slist_next(stripe);
|
||||
i++;
|
||||
} while (i < stripes_len);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
static int cmpint(const void *p1, const void *p2, gpointer data)
|
||||
{
|
||||
int a = *((int *)p1);
|
||||
int b = *((int *)p2);
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (a == b)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void median_filter(int *data, int size, int filtersize)
|
||||
{
|
||||
int i;
|
||||
int *result = (int *)g_malloc0(size*sizeof(int));
|
||||
int *sortbuf = (int *)g_malloc0(filtersize*sizeof(int));
|
||||
for (i = 0; i < size; i++) {
|
||||
int i1 = i - (filtersize-1)/2;
|
||||
int i2 = i + (filtersize-1)/2;
|
||||
if (i1 < 0)
|
||||
i1 = 0;
|
||||
if (i2 >= size)
|
||||
i2 = size-1;
|
||||
g_memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));
|
||||
g_qsort_with_data(sortbuf, i2-i1+1, sizeof(int), cmpint, NULL);
|
||||
result[i] = sortbuf[(i2-i1+1)/2];
|
||||
}
|
||||
memmove(data, result, size*sizeof(int));
|
||||
g_free(result);
|
||||
g_free(sortbuf);
|
||||
}
|
||||
|
||||
static void interpolate_lines(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *line1, float y1, GSList *line2,
|
||||
float y2, unsigned char *output, float yi, int size)
|
||||
{
|
||||
int i;
|
||||
unsigned char p1, p2;
|
||||
|
||||
if (!line1 || !line2)
|
||||
return;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
p1 = ctx->get_pixel(ctx, line1, i);
|
||||
p2 = ctx->get_pixel(ctx, line2, i);
|
||||
output[i] = (float)p1
|
||||
+ (yi - y1)/(y2 - y1)*(p2 - p1);
|
||||
}
|
||||
}
|
||||
|
||||
static int min(int a, int b) {return (a < b) ? a : b; }
|
||||
|
||||
/* Rescale image to account for variable swiping speed */
|
||||
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *lines, size_t lines_len)
|
||||
{
|
||||
/* Number of output lines per distance between two scanners */
|
||||
int i;
|
||||
GSList *row1, *row2;
|
||||
float y = 0.0;
|
||||
int line_ind = 0;
|
||||
int *offsets = (int *)g_malloc0((lines_len / 2) * sizeof(int));
|
||||
unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height);
|
||||
struct fp_img *img;
|
||||
|
||||
g_return_val_if_fail (lines != NULL, NULL);
|
||||
g_return_val_if_fail (lines_len > 0, NULL);
|
||||
|
||||
fp_dbg("%"G_GINT64_FORMAT, g_get_real_time());
|
||||
|
||||
row1 = lines;
|
||||
for (i = 0; (i < lines_len - 1) && row1; i += 2) {
|
||||
int bestmatch = i;
|
||||
int bestdiff = 0;
|
||||
int j, firstrow, lastrow;
|
||||
|
||||
firstrow = i + 1;
|
||||
lastrow = min(i + ctx->max_search_offset, lines_len - 1);
|
||||
|
||||
row2 = g_slist_next(row1);
|
||||
for (j = firstrow; j <= lastrow; j++) {
|
||||
int diff = ctx->get_deviation(ctx,
|
||||
row1,
|
||||
row2);
|
||||
if ((j == firstrow) || (diff < bestdiff)) {
|
||||
bestdiff = diff;
|
||||
bestmatch = j;
|
||||
}
|
||||
row2 = g_slist_next(row2);
|
||||
}
|
||||
offsets[i / 2] = bestmatch - i;
|
||||
fp_dbg("%d", offsets[i / 2]);
|
||||
row1 = g_slist_next(row1);
|
||||
if (row1)
|
||||
row1 = g_slist_next(row1);
|
||||
}
|
||||
|
||||
median_filter(offsets, (lines_len / 2) - 1, ctx->median_filter_size);
|
||||
|
||||
fp_dbg("offsets_filtered: %"G_GINT64_FORMAT, g_get_real_time());
|
||||
for (i = 0; i <= (lines_len / 2) - 1; i++)
|
||||
fp_dbg("%d", offsets[i]);
|
||||
row1 = lines;
|
||||
for (i = 0; i < lines_len - 1; i++, row1 = g_slist_next(row1)) {
|
||||
int offset = offsets[i/2];
|
||||
if (offset > 0) {
|
||||
float ynext = y + (float)ctx->resolution / offset;
|
||||
while (line_ind < ynext) {
|
||||
if (line_ind > ctx->max_height - 1)
|
||||
goto out;
|
||||
interpolate_lines(ctx,
|
||||
row1, y,
|
||||
g_slist_next(row1),
|
||||
ynext,
|
||||
output + line_ind * ctx->line_width,
|
||||
line_ind,
|
||||
ctx->line_width);
|
||||
line_ind++;
|
||||
}
|
||||
y = ynext;
|
||||
}
|
||||
}
|
||||
out:
|
||||
img = fpi_img_new(ctx->line_width * line_ind);
|
||||
img->height = line_ind;
|
||||
img->width = ctx->line_width;
|
||||
img->flags = FP_IMG_V_FLIPPED;
|
||||
g_memmove(img->data, output, ctx->line_width * line_ind);
|
||||
g_free(offsets);
|
||||
g_free(output);
|
||||
return img;
|
||||
}
|
||||
65
libfprint/assembling.h
Normal file
65
libfprint/assembling.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Image assembling routines
|
||||
* Shared functions between libfprint Authentec drivers
|
||||
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright (C) 2015 Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLING_H__
|
||||
#define __ASSEMBLING_H__
|
||||
|
||||
#include <fprint.h>
|
||||
|
||||
struct fpi_frame {
|
||||
int delta_x;
|
||||
int delta_y;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
struct fpi_frame_asmbl_ctx {
|
||||
unsigned frame_width;
|
||||
unsigned frame_height;
|
||||
unsigned image_width;
|
||||
unsigned char (*get_pixel)(struct fpi_frame_asmbl_ctx *ctx,
|
||||
struct fpi_frame *frame,
|
||||
unsigned x,
|
||||
unsigned y);
|
||||
};
|
||||
|
||||
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
||||
GSList *stripes, size_t stripes_len);
|
||||
|
||||
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
||||
GSList *stripes, size_t stripes_len);
|
||||
|
||||
struct fpi_line_asmbl_ctx {
|
||||
unsigned line_width;
|
||||
unsigned max_height;
|
||||
unsigned resolution;
|
||||
unsigned median_filter_size;
|
||||
unsigned max_search_offset;
|
||||
int (*get_deviation)(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *line1, GSList *line2);
|
||||
unsigned char (*get_pixel)(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *line,
|
||||
unsigned x);
|
||||
};
|
||||
|
||||
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *lines, size_t lines_len);
|
||||
|
||||
#endif
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
#define FP_COMPONENT "async"
|
||||
|
||||
#include "fp_internal.h"
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "fp_internal.h"
|
||||
|
||||
/* Drivers call this when device initialisation has completed */
|
||||
void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
|
||||
{
|
||||
@@ -36,15 +36,27 @@ void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
|
||||
dev->open_cb(dev, status, dev->open_cb_data);
|
||||
}
|
||||
|
||||
API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb,
|
||||
/**
|
||||
* fp_async_dev_open:
|
||||
* @ddev:
|
||||
* @callback:
|
||||
* @user_data
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback,
|
||||
void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = ddev->drv;
|
||||
struct fp_driver *drv;
|
||||
struct fp_dev *dev;
|
||||
libusb_device_handle *udevh;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(ddev != NULL, -ENODEV);
|
||||
|
||||
drv = ddev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
r = libusb_open(ddev->udev, &udevh);
|
||||
if (r < 0) {
|
||||
fp_err("usb_open failed, error %d", r);
|
||||
@@ -56,7 +68,7 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb,
|
||||
dev->udev = udevh;
|
||||
dev->__enroll_stage = -1;
|
||||
dev->state = DEV_STATE_INITIALIZING;
|
||||
dev->open_cb = cb;
|
||||
dev->open_cb = callback;
|
||||
dev->open_cb_data = user_data;
|
||||
|
||||
if (!drv->open) {
|
||||
@@ -78,7 +90,7 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb,
|
||||
/* Drivers call this when device deinitialisation has completed */
|
||||
void fpi_drvcb_close_complete(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
|
||||
dev->state = DEV_STATE_DEINITIALIZED;
|
||||
libusb_close(dev->udev);
|
||||
@@ -87,10 +99,22 @@ void fpi_drvcb_close_complete(struct fp_dev *dev)
|
||||
g_free(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_dev_close:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data
|
||||
*/
|
||||
API_EXPORTED void fp_async_dev_close(struct fp_dev *dev,
|
||||
fp_dev_close_cb callback, void *user_data)
|
||||
fp_operation_stop_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
g_return_if_fail (drv->close != NULL);
|
||||
|
||||
if (g_slist_index(opened_devices, (gconstpointer) dev) == -1)
|
||||
fp_err("device %p not in opened list!", dev);
|
||||
@@ -98,12 +122,6 @@ API_EXPORTED void fp_async_dev_close(struct fp_dev *dev,
|
||||
|
||||
dev->close_cb = callback;
|
||||
dev->close_cb_data = user_data;
|
||||
|
||||
if (!drv->close) {
|
||||
fpi_drvcb_close_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->state = DEV_STATE_DEINITIALIZING;
|
||||
drv->close(dev);
|
||||
}
|
||||
@@ -127,12 +145,24 @@ void fpi_drvcb_enroll_started(struct fp_dev *dev, int status)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_enroll_start:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev,
|
||||
fp_enroll_stage_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
if (!dev->nr_enroll_stages || !drv->enroll_start) {
|
||||
fp_err("driver %s has 0 enroll stages or no enroll func",
|
||||
drv->name);
|
||||
@@ -174,20 +204,32 @@ void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
|
||||
/* Drivers call this when enrollment has stopped */
|
||||
void fpi_drvcb_enroll_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_ENROLL_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
if (dev->enroll_stop_cb)
|
||||
dev->enroll_stop_cb(dev, dev->enroll_stop_cb_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_enroll_stop:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
|
||||
fp_enroll_stop_cb callback, void *user_data)
|
||||
fp_operation_stop_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
if (!drv->enroll_start)
|
||||
return -ENOTSUP;
|
||||
|
||||
@@ -210,13 +252,26 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_verify_start:
|
||||
* @dev:
|
||||
* @data:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
|
||||
struct fp_print_data *data, fp_verify_cb callback, void *user_data)
|
||||
struct fp_print_data *data, fp_img_operation_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
if (!drv->verify_start)
|
||||
return -ENOTSUP;
|
||||
|
||||
@@ -237,7 +292,7 @@ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
|
||||
/* Drivers call this when verification has started */
|
||||
void fpi_drvcb_verify_started(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_VERIFY_STARTING);
|
||||
if (status) {
|
||||
if (status > 0) {
|
||||
@@ -271,21 +326,33 @@ void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result,
|
||||
/* Drivers call this when verification has stopped */
|
||||
void fpi_drvcb_verify_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_VERIFY_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
if (dev->verify_stop_cb)
|
||||
dev->verify_stop_cb(dev, dev->verify_stop_cb_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_verify_stop:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
||||
fp_verify_stop_cb callback, void *user_data)
|
||||
fp_operation_stop_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
gboolean iterating = (dev->state == DEV_STATE_VERIFYING);
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_ERROR
|
||||
&& dev->state != DEV_STATE_VERIFYING
|
||||
&& dev->state != DEV_STATE_VERIFY_DONE);
|
||||
@@ -311,13 +378,26 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_identify_start:
|
||||
* @dev:
|
||||
* @gallery:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_identify_start(struct fp_dev *dev,
|
||||
struct fp_print_data **gallery, fp_identify_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
if (!drv->identify_start)
|
||||
return -ENOTSUP;
|
||||
dev->state = DEV_STATE_IDENTIFY_STARTING;
|
||||
@@ -369,14 +449,26 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
||||
fp_dbg("ignoring verify result as no callback is subscribed");
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_identify_stop:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
|
||||
fp_identify_stop_cb callback, void *user_data)
|
||||
fp_operation_stop_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
struct fp_driver *drv;
|
||||
gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING);
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
|
||||
&& dev->state != DEV_STATE_IDENTIFY_DONE);
|
||||
|
||||
@@ -405,10 +497,133 @@ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
|
||||
/* Drivers call this when identification has stopped */
|
||||
void fpi_drvcb_identify_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFY_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
if (dev->identify_stop_cb)
|
||||
dev->identify_stop_cb(dev, dev->identify_stop_cb_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_capture_start:
|
||||
* @dev:
|
||||
* @unconditional:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional,
|
||||
fp_img_operation_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
if (!drv->capture_start)
|
||||
return -ENOTSUP;
|
||||
|
||||
dev->state = DEV_STATE_CAPTURE_STARTING;
|
||||
dev->capture_cb = callback;
|
||||
dev->capture_cb_data = user_data;
|
||||
dev->unconditional_capture = unconditional;
|
||||
|
||||
r = drv->capture_start(dev);
|
||||
if (r < 0) {
|
||||
dev->capture_cb = NULL;
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
fp_err("failed to start verification, error %d", r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Drivers call this when capture has started */
|
||||
void fpi_drvcb_capture_started(struct fp_dev *dev, int status)
|
||||
{
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_CAPTURE_STARTING);
|
||||
if (status) {
|
||||
if (status > 0) {
|
||||
status = -status;
|
||||
fp_dbg("adjusted to %d", status);
|
||||
}
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
if (dev->capture_cb)
|
||||
dev->capture_cb(dev, status, NULL, dev->capture_cb_data);
|
||||
} else {
|
||||
dev->state = DEV_STATE_CAPTURING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Drivers call this to report a capture result (which might mark completion) */
|
||||
void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result,
|
||||
struct fp_img *img)
|
||||
{
|
||||
fp_dbg("result %d", result);
|
||||
BUG_ON(dev->state != DEV_STATE_CAPTURING);
|
||||
if (result < 0 || result == FP_CAPTURE_COMPLETE)
|
||||
dev->state = DEV_STATE_CAPTURE_DONE;
|
||||
|
||||
if (dev->capture_cb)
|
||||
dev->capture_cb(dev, result, img, dev->capture_cb_data);
|
||||
else
|
||||
fp_dbg("ignoring capture result as no callback is subscribed");
|
||||
}
|
||||
|
||||
/* Drivers call this when capture has stopped */
|
||||
void fpi_drvcb_capture_stopped(struct fp_dev *dev)
|
||||
{
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_CAPTURE_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
if (dev->capture_stop_cb)
|
||||
dev->capture_stop_cb(dev, dev->capture_stop_cb_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_capture_stop:
|
||||
* @dev:
|
||||
* @callback:
|
||||
* @user_data:
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev,
|
||||
fp_operation_stop_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_ERROR
|
||||
&& dev->state != DEV_STATE_CAPTURING
|
||||
&& dev->state != DEV_STATE_CAPTURE_DONE);
|
||||
|
||||
dev->capture_cb = NULL;
|
||||
dev->capture_stop_cb = callback;
|
||||
dev->capture_stop_cb_data = user_data;
|
||||
dev->state = DEV_STATE_CAPTURE_STOPPING;
|
||||
|
||||
if (!drv->capture_start)
|
||||
return -ENOTSUP;
|
||||
if (!drv->capture_stop) {
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
fpi_drvcb_capture_stopped(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = drv->capture_stop(dev);
|
||||
if (r < 0) {
|
||||
fp_err("failed to stop verification");
|
||||
dev->capture_stop_cb = NULL;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
781
libfprint/core.c
781
libfprint/core.c
File diff suppressed because it is too large
Load Diff
359
libfprint/data.c
359
libfprint/data.c
@@ -32,8 +32,11 @@
|
||||
|
||||
#define DIR_PERMS 0700
|
||||
|
||||
/** @defgroup print_data Stored prints
|
||||
* Stored prints are represented by a structure named <tt>fp_print_data</tt>.
|
||||
/**
|
||||
* SECTION: print_data
|
||||
* @title: Stored prints
|
||||
*
|
||||
* Stored prints are represented by a structure named #fp_print_data.
|
||||
* Stored prints are originally obtained from an enrollment function such as
|
||||
* fp_enroll_finger().
|
||||
*
|
||||
@@ -73,7 +76,6 @@ void fpi_data_exit(void)
|
||||
((finger) >= LEFT_THUMB && (finger) <= RIGHT_LITTLE)
|
||||
|
||||
/* for debug messages only */
|
||||
#ifdef ENABLE_DEBUG_LOGGING
|
||||
static const char *finger_num_to_str(enum fp_finger finger)
|
||||
{
|
||||
const char *names[] = {
|
||||
@@ -92,90 +94,191 @@ static const char *finger_num_to_str(enum fp_finger finger)
|
||||
return "UNKNOWN";
|
||||
return names[finger];
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct fp_print_data *print_data_new(uint16_t driver_id,
|
||||
uint32_t devtype, enum fp_print_data_type type, size_t length)
|
||||
uint32_t devtype, enum fp_print_data_type type)
|
||||
{
|
||||
struct fp_print_data *data = g_malloc(sizeof(*data) + length);
|
||||
fp_dbg("length=%zd driver=%02x devtype=%04x", length, driver_id, devtype);
|
||||
memset(data, 0, sizeof(*data));
|
||||
struct fp_print_data *data = g_malloc0(sizeof(*data));
|
||||
fp_dbg("driver=%02x devtype=%04x", driver_id, devtype);
|
||||
data->driver_id = driver_id;
|
||||
data->devtype = devtype;
|
||||
data->type = type;
|
||||
data->length = length;
|
||||
return data;
|
||||
}
|
||||
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
|
||||
void fpi_print_data_item_free(struct fp_print_data_item *item)
|
||||
{
|
||||
return print_data_new(dev->drv->id, dev->devtype,
|
||||
fpi_driver_get_data_type(dev->drv), length);
|
||||
g_free(item);
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
struct fp_print_data_item *fpi_print_data_item_new(size_t length)
|
||||
{
|
||||
struct fp_print_data_item *item = g_malloc0(sizeof(*item) + length);
|
||||
item->length = length;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev)
|
||||
{
|
||||
return print_data_new(dev->drv->id, dev->devtype,
|
||||
fpi_driver_get_data_type(dev->drv));
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_print_data_get_data:
|
||||
* @data: the stored print
|
||||
* @ret: output location for the data buffer. Must be freed with free()
|
||||
* after use.
|
||||
|
||||
* Convert a stored print into a unified representation inside a data buffer.
|
||||
* You can then store this data buffer in any way that suits you, and load
|
||||
* it back at some later time using fp_print_data_from_data().
|
||||
* \param data the stored print
|
||||
* \param ret output location for the data buffer. Must be freed with free()
|
||||
* after use.
|
||||
* \returns the size of the freshly allocated buffer, or 0 on error.
|
||||
*
|
||||
* Returns: the size of the freshly allocated buffer, or 0 on error.
|
||||
*/
|
||||
API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
|
||||
unsigned char **ret)
|
||||
{
|
||||
struct fpi_print_data_fp1 *buf;
|
||||
size_t buflen;
|
||||
struct fpi_print_data_fp2 *out_data;
|
||||
struct fpi_print_data_item_fp2 *out_item;
|
||||
struct fp_print_data_item *item;
|
||||
size_t buflen = 0;
|
||||
GSList *list_item;
|
||||
unsigned char *buf;
|
||||
|
||||
fp_dbg("");
|
||||
G_DEBUG_HERE();
|
||||
|
||||
buflen = sizeof(*buf) + data->length;
|
||||
buf = malloc(buflen);
|
||||
if (!buf)
|
||||
return 0;
|
||||
list_item = data->prints;
|
||||
while (list_item) {
|
||||
item = list_item->data;
|
||||
buflen += sizeof(*out_item);
|
||||
buflen += item->length;
|
||||
list_item = g_slist_next(list_item);
|
||||
}
|
||||
|
||||
buflen += sizeof(*out_data);
|
||||
out_data = g_malloc(buflen);
|
||||
|
||||
*ret = (unsigned char *) out_data;
|
||||
buf = out_data->data;
|
||||
out_data->prefix[0] = 'F';
|
||||
out_data->prefix[1] = 'P';
|
||||
out_data->prefix[2] = '2';
|
||||
out_data->driver_id = GUINT16_TO_LE(data->driver_id);
|
||||
out_data->devtype = GUINT32_TO_LE(data->devtype);
|
||||
out_data->data_type = data->type;
|
||||
|
||||
list_item = data->prints;
|
||||
while (list_item) {
|
||||
item = list_item->data;
|
||||
out_item = (struct fpi_print_data_item_fp2 *)buf;
|
||||
out_item->length = GUINT32_TO_LE(item->length);
|
||||
/* FIXME: fp_print_data_item->data content is not endianess agnostic */
|
||||
memcpy(out_item->data, item->data, item->length);
|
||||
buf += sizeof(*out_item);
|
||||
buf += item->length;
|
||||
list_item = g_slist_next(list_item);
|
||||
}
|
||||
|
||||
*ret = (unsigned char *) buf;
|
||||
buf->prefix[0] = 'F';
|
||||
buf->prefix[1] = 'P';
|
||||
buf->prefix[2] = '1';
|
||||
buf->driver_id = GUINT16_TO_LE(data->driver_id);
|
||||
buf->devtype = GUINT32_TO_LE(data->devtype);
|
||||
buf->data_type = data->type;
|
||||
memcpy(buf->data, data->data, data->length);
|
||||
return buflen;
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
static struct fp_print_data *fpi_print_data_from_fp1_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
size_t print_data_len;
|
||||
struct fp_print_data *data;
|
||||
struct fp_print_data_item *item;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
|
||||
print_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type);
|
||||
item = fpi_print_data_item_new(print_data_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
memcpy(item->data, raw->data, print_data_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
size_t total_data_len, item_len;
|
||||
struct fp_print_data *data;
|
||||
struct fp_print_data_item *item;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
unsigned char *raw_buf;
|
||||
struct fpi_print_data_item_fp2 *raw_item;
|
||||
|
||||
total_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type);
|
||||
raw_buf = raw->data;
|
||||
while (total_data_len) {
|
||||
if (total_data_len < sizeof(*raw_item))
|
||||
break;
|
||||
total_data_len -= sizeof(*raw_item);
|
||||
|
||||
raw_item = (struct fpi_print_data_item_fp2 *)raw_buf;
|
||||
item_len = GUINT32_FROM_LE(raw_item->length);
|
||||
fp_dbg("item len %d, total_data_len %d", (int) item_len, (int) total_data_len);
|
||||
if (total_data_len < item_len) {
|
||||
fp_err("corrupted fingerprint data");
|
||||
break;
|
||||
}
|
||||
total_data_len -= item_len;
|
||||
|
||||
item = fpi_print_data_item_new(item_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
memcpy(item->data, raw_item->data, item_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
raw_buf += sizeof(*raw_item);
|
||||
raw_buf += item_len;
|
||||
}
|
||||
|
||||
if (g_slist_length(data->prints) == 0) {
|
||||
fp_print_data_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_print_data_from_data:
|
||||
* @buf: the data buffer
|
||||
* @buflen: the length of the buffer
|
||||
|
||||
* Load a stored print from a data buffer. The contents of said buffer must
|
||||
* be the untouched contents of a buffer previously supplied to you by the
|
||||
* fp_print_data_get_data() function.
|
||||
* \param buf the data buffer
|
||||
* \param buflen the length of the buffer
|
||||
* \returns the stored print represented by the data, or NULL on error. Must
|
||||
*
|
||||
* Returns: the stored print represented by the data, or %NULL on error. Must
|
||||
* be freed with fp_print_data_free() after use.
|
||||
*/
|
||||
API_EXPORTED struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
struct fpi_print_data_fp1 *raw = (struct fpi_print_data_fp1 *) buf;
|
||||
size_t print_data_len;
|
||||
struct fp_print_data *data;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
|
||||
fp_dbg("buffer size %zd", buflen);
|
||||
if (buflen < sizeof(*raw))
|
||||
return NULL;
|
||||
|
||||
if (strncmp(raw->prefix, "FP1", 3) != 0) {
|
||||
if (strncmp(raw->prefix, "FP1", 3) == 0) {
|
||||
return fpi_print_data_from_fp1_data(buf, buflen);
|
||||
} else if (strncmp(raw->prefix, "FP2", 3) == 0) {
|
||||
return fpi_print_data_from_fp2_data(buf, buflen);
|
||||
} else {
|
||||
fp_dbg("bad header prefix");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
print_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type, print_data_len);
|
||||
memcpy(data->data, raw->data, print_data_len);
|
||||
return data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *get_path_to_storedir(uint16_t driver_id, uint32_t devtype)
|
||||
@@ -209,7 +312,11 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger)
|
||||
return __get_path_to_print(dev->drv->id, dev->devtype, finger);
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
/**
|
||||
* fp_print_data_save:
|
||||
* @data: the stored print to save to disk
|
||||
* @finger: the finger that this print corresponds to
|
||||
*
|
||||
* Saves a stored print to disk, assigned to a specific finger. Even though
|
||||
* you are limited to storing only the 10 human fingers, this is a
|
||||
* per-device-type limit. For example, you can store the users right index
|
||||
@@ -220,9 +327,8 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger)
|
||||
* This function will unconditionally overwrite a fingerprint previously
|
||||
* saved for the same finger and device type. The print is saved in a hidden
|
||||
* directory beneath the current user's home directory.
|
||||
* \param data the stored print to save to disk
|
||||
* \param finger the finger that this print corresponds to
|
||||
* \returns 0 on success, non-zero on error.
|
||||
*
|
||||
* Returns: 0 on success, non-zero on error.
|
||||
*/
|
||||
API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
|
||||
enum fp_finger finger)
|
||||
@@ -319,7 +425,13 @@ static int load_from_file(char *path, struct fp_print_data **data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
/**
|
||||
* fp_print_data_load:
|
||||
* @dev: the device you are loading the print for
|
||||
* @finger: the finger of the file you are loading
|
||||
* @data: output location to put the corresponding stored print. Must be
|
||||
* freed with fp_print_data_free() after use.
|
||||
|
||||
* Loads a previously stored print from disk. The print must have been saved
|
||||
* earlier using the fp_print_data_save() function.
|
||||
*
|
||||
@@ -327,11 +439,7 @@ static int load_from_file(char *path, struct fp_print_data **data)
|
||||
* be found. Other error codes (both positive and negative) are possible for
|
||||
* obscure error conditions (e.g. corruption).
|
||||
*
|
||||
* \param dev the device you are loading the print for
|
||||
* \param finger the finger of the file you are loading
|
||||
* \param data output location to put the corresponding stored print. Must be
|
||||
* freed with fp_print_data_free() after use.
|
||||
* \returns 0 on success, non-zero on error
|
||||
* Returns: 0 on success, non-zero on error
|
||||
*/
|
||||
API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
|
||||
enum fp_finger finger, struct fp_print_data **data)
|
||||
@@ -359,11 +467,14 @@ API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
/**
|
||||
* fp_print_data_delete:
|
||||
* @dev: the device that the print belongs to
|
||||
* @finger: the finger of the file you are deleting
|
||||
|
||||
* Removes a stored print from disk previously saved with fp_print_data_save().
|
||||
* \param dev the device that the print belongs to
|
||||
* \param finger the finger of the file you are deleting
|
||||
* \returns 0 on success, negative on error
|
||||
*
|
||||
* Returns: 0 on success, negative on error
|
||||
*/
|
||||
API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
|
||||
enum fp_finger finger)
|
||||
@@ -381,18 +492,22 @@ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
|
||||
return r;
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
* Attempts to load a stored print based on a \ref dscv_print
|
||||
* "discovered print" record.
|
||||
/**
|
||||
* fp_print_data_from_dscv_print:
|
||||
* @print: the discovered print
|
||||
* @data: output location to point to the corresponding stored print. Must
|
||||
* be freed with fp_print_data_free() after use.
|
||||
|
||||
* Attempts to load a stored print based on a #fp_dscv_print
|
||||
* discovered print record.
|
||||
*
|
||||
* A return code of -ENOENT indicates that the file referred to by the
|
||||
* discovered print could not be found. Other error codes (both positive and
|
||||
* negative) are possible for obscure error conditions (e.g. corruption).
|
||||
*
|
||||
* \param print the discovered print
|
||||
* \param data output location to point to the corresponding stored print. Must
|
||||
* be freed with fp_print_data_free() after use.
|
||||
* \returns 0 on success, non-zero on error.
|
||||
* Returns: 0 on success, non-zero on error.
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
|
||||
struct fp_print_data **data)
|
||||
@@ -400,40 +515,53 @@ API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
|
||||
return load_from_file(print->path, data);
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
/**
|
||||
* fp_print_data_free:
|
||||
* @data: the stored print to destroy. If NULL, function simply returns.
|
||||
*
|
||||
* Frees a stored print. Must be called when you are finished using the print.
|
||||
* \param data the stored print to destroy. If NULL, function simply returns.
|
||||
*/
|
||||
API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
|
||||
{
|
||||
if (data)
|
||||
g_slist_free_full(data->prints, (GDestroyNotify)fpi_print_data_item_free);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
* Gets the \ref driver_id "driver ID" for a stored print. The driver ID
|
||||
/**
|
||||
* fp_print_data_get_driver_id:
|
||||
* @data: the stored print
|
||||
|
||||
* Gets the [driver ID](advanced-topics.html#driver_id) for a stored print. The driver ID
|
||||
* indicates which driver the print originally came from. The print is
|
||||
* only usable with a device controlled by that driver.
|
||||
* \param data the stored print
|
||||
* \returns the driver ID of the driver compatible with the print
|
||||
*
|
||||
* Returns: the driver ID of the driver compatible with the print
|
||||
*/
|
||||
API_EXPORTED uint16_t fp_print_data_get_driver_id(struct fp_print_data *data)
|
||||
{
|
||||
return data->driver_id;
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
* Gets the \ref devtype "devtype" for a stored print. The devtype represents
|
||||
/**
|
||||
* fp_print_data_get_devtype:
|
||||
* @data: the stored print
|
||||
|
||||
* Gets the [devtype](advanced-topics.html#device-types) for a stored print. The devtype represents
|
||||
* which type of device under the parent driver is compatible with the print.
|
||||
* \param data the stored print
|
||||
* \returns the devtype of the device range compatible with the print
|
||||
*
|
||||
* Returns: the devtype of the device range compatible with the print
|
||||
*/
|
||||
API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
|
||||
{
|
||||
return data->devtype;
|
||||
}
|
||||
|
||||
/** @defgroup dscv_print Print discovery
|
||||
* The \ref print_data "stored print" documentation detailed a simple API
|
||||
/**
|
||||
* SECTION:dscv_print
|
||||
* @title: Print discovery (deprecated)
|
||||
*
|
||||
* The [stored print](libfprint-Stored-prints.html) documentation detailed a simple API
|
||||
* for storing per-device prints for a single user, namely
|
||||
* fp_print_data_save(). It also detailed a load function,
|
||||
* fp_print_data_load(), but usage of this function is limited to scenarios
|
||||
@@ -444,7 +572,7 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
|
||||
* previously saved prints, potentially even before device discovery. These
|
||||
* functions are designed to offer this functionality to you.
|
||||
*
|
||||
* Discovered prints are stored in a <tt>dscv_print</tt> structure, and you
|
||||
* Discovered prints are stored in a #fp_dscv_print structure, and you
|
||||
* can use functions documented below to access some information about these
|
||||
* prints. You can determine if a discovered print appears to be compatible
|
||||
* with a device using functions such as fp_dscv_dev_supports_dscv_print() and
|
||||
@@ -462,6 +590,10 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
|
||||
* circumstances it may turn out that the print is corrupt or not for the
|
||||
* device that it appeared to be. Also, it is possible that the print may have
|
||||
* been deleted by the time you come to load it.
|
||||
*
|
||||
* Note that this portion of the library is deprecated. All that it offers is
|
||||
* already implementable using publicly available functions, and its usage is
|
||||
* unnecessarily restrictive in terms of how it stores data.
|
||||
*/
|
||||
|
||||
static GSList *scan_dev_store_dir(char *devpath, uint16_t driver_id,
|
||||
@@ -545,11 +677,16 @@ static GSList *scan_driver_store_dir(char *drvpath, uint16_t driver_id,
|
||||
return list;
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
/**
|
||||
* fp_discover_prints:
|
||||
*
|
||||
* Scans the users home directory and returns a list of prints that were
|
||||
* previously saved using fp_print_data_save().
|
||||
* \returns a NULL-terminated list of discovered prints, must be freed with
|
||||
*
|
||||
* Returns: a %NULL-terminated list of discovered prints, must be freed with
|
||||
* fp_dscv_prints_free() after use.
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
|
||||
{
|
||||
@@ -606,12 +743,16 @@ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
|
||||
return list;
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
/**
|
||||
* fp_dscv_prints_free:
|
||||
* @prints: the list of discovered prints. If NULL, function simply
|
||||
* returns.
|
||||
*
|
||||
* Frees a list of discovered prints. This function also frees the discovered
|
||||
* prints themselves, so make sure you do not use any discovered prints
|
||||
* after calling this function.
|
||||
* \param prints the list of discovered prints. If NULL, function simply
|
||||
* returns.
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints)
|
||||
{
|
||||
@@ -629,47 +770,67 @@ API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints)
|
||||
g_free(prints);
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
* Gets the \ref driver_id "driver ID" for a discovered print. The driver ID
|
||||
/**
|
||||
* fp_dscv_print_get_driver_id:
|
||||
* @print: the discovered print
|
||||
*
|
||||
* Gets the [driver ID](advanced-topics.html#driver_id) for a discovered print. The driver ID
|
||||
* indicates which driver the print originally came from. The print is only
|
||||
* usable with a device controlled by that driver.
|
||||
* \param print the discovered print
|
||||
* \returns the driver ID of the driver compatible with the print
|
||||
*
|
||||
* Returns: the driver ID of the driver compatible with the print
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print)
|
||||
{
|
||||
return print->driver_id;
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
* Gets the \ref devtype "devtype" for a discovered print. The devtype
|
||||
/**
|
||||
* fp_dscv_print_get_devtype:
|
||||
* @print: the discovered print
|
||||
*
|
||||
* Gets the [devtype](advanced-topics.html#device-types) for a discovered print. The devtype
|
||||
* represents which type of device under the parent driver is compatible
|
||||
* with the print.
|
||||
* \param print the discovered print
|
||||
* \returns the devtype of the device range compatible with the print
|
||||
*
|
||||
* Returns: the devtype of the device range compatible with the print
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print)
|
||||
{
|
||||
return print->devtype;
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
/**
|
||||
* fp_dscv_print_get_finger:
|
||||
* @print: discovered print
|
||||
*
|
||||
* Gets the finger code for a discovered print.
|
||||
* \param print discovered print
|
||||
* \returns a finger code from #fp_finger
|
||||
*
|
||||
* Returns: a finger code from #fp_finger
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print)
|
||||
{
|
||||
return print->finger;
|
||||
}
|
||||
|
||||
/** \ingroup dscv_print
|
||||
/**
|
||||
* fp_dscv_print_delete:
|
||||
* @print: the discovered print to remove from disk
|
||||
*
|
||||
* Removes a discovered print from disk. After successful return of this
|
||||
* function, functions such as fp_dscv_print_get_finger() will continue to
|
||||
* operate as before, however calling fp_print_data_from_dscv_print() will
|
||||
* fail for obvious reasons.
|
||||
* \param print the discovered print to remove from disk
|
||||
* \returns 0 on success, negative on error
|
||||
*
|
||||
* Returns: 0 on success, negative on error
|
||||
*
|
||||
* Deprecated: Do not use.
|
||||
*/
|
||||
API_EXPORTED int fp_dscv_print_delete(struct fp_dscv_print *print)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2007 Cyrille Bagard
|
||||
* Copyright (C) 2007 Vasily Khoruzhick
|
||||
* Copyright (C) 2009 Guido Grazioli <guido.grazioli@gmail.com>
|
||||
* Copyright (C) 2012 Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
*
|
||||
* Based on code from libfprint aes2501 driver.
|
||||
*
|
||||
@@ -24,13 +25,8 @@
|
||||
|
||||
#define FP_COMPONENT "aes1610"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include <aeslib.h>
|
||||
#include <fp_internal.h>
|
||||
#include "drivers_api.h"
|
||||
#include "aeslib.h"
|
||||
|
||||
static void start_capture(struct fp_img_dev *dev);
|
||||
static void complete_deactivation(struct fp_img_dev *dev);
|
||||
@@ -63,6 +59,7 @@ static int adjust_gain(unsigned char *buffer, int status);
|
||||
#define FRAME_WIDTH 128
|
||||
#define FRAME_HEIGHT 8
|
||||
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||
/* maximum number of frames to read during a scan */
|
||||
/* FIXME reduce substantially */
|
||||
#define MAX_FRAMES 350
|
||||
@@ -77,6 +74,13 @@ struct aes1610_dev {
|
||||
uint8_t blanks_count;
|
||||
};
|
||||
|
||||
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||
.frame_width = FRAME_WIDTH,
|
||||
.frame_height = FRAME_HEIGHT,
|
||||
.image_width = IMAGE_WIDTH,
|
||||
.get_pixel = aes_get_pixel,
|
||||
};
|
||||
|
||||
typedef void (*aes1610_read_regs_cb)(struct fp_img_dev *dev, int status,
|
||||
unsigned char *regs, void *user_data);
|
||||
|
||||
@@ -110,103 +114,6 @@ static void generic_ignore_data_cb(struct libusb_transfer *transfer)
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
|
||||
|
||||
static void read_regs_data_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
struct aes1610_read_regs *rdata = transfer->user_data;
|
||||
unsigned char *retdata = NULL;
|
||||
int r;
|
||||
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
r = -EIO;
|
||||
} else if (transfer->length != transfer->actual_length) {
|
||||
r = -EPROTO;
|
||||
} else {
|
||||
r = 0;
|
||||
retdata = transfer->buffer;
|
||||
}
|
||||
|
||||
rdata->callback(rdata->dev, r, retdata, rdata->user_data);
|
||||
g_free(rdata);
|
||||
g_free(transfer->buffer);
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
|
||||
static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
|
||||
{
|
||||
struct aes1610_read_regs *rdata = user_data;
|
||||
struct libusb_transfer *transfer;
|
||||
unsigned char *data;
|
||||
int r;
|
||||
|
||||
g_free(rdata->regwrite);
|
||||
if (result != 0)
|
||||
goto err;
|
||||
|
||||
transfer = libusb_alloc_transfer(0);
|
||||
if (!transfer) {
|
||||
result = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
data = g_malloc(126);
|
||||
libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 126,
|
||||
read_regs_data_cb, rdata, BULK_TIMEOUT);
|
||||
|
||||
r = libusb_submit_transfer(transfer);
|
||||
if (r < 0) {
|
||||
g_free(data);
|
||||
libusb_free_transfer(transfer);
|
||||
result = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return;
|
||||
err:
|
||||
rdata->callback(dev, result, NULL, rdata->user_data);
|
||||
g_free(rdata);
|
||||
}
|
||||
|
||||
|
||||
// XXX: this comes from aes2501 driver but it is unused here
|
||||
static void read_regs(struct fp_img_dev *dev, aes1610_read_regs_cb callback,
|
||||
void *user_data)
|
||||
{
|
||||
/* FIXME: regwrite is dynamic because of asynchronity. is this really
|
||||
* required? */
|
||||
struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite));
|
||||
struct aes1610_read_regs *rdata = g_malloc(sizeof(*rdata));
|
||||
|
||||
fp_dbg("");
|
||||
//regwrite->reg = AES1610_REG_CTRL2;
|
||||
//regwrite->value = AES1610_CTRL2_READ_REGS;
|
||||
rdata->dev = dev;
|
||||
rdata->callback = callback;
|
||||
rdata->user_data = user_data;
|
||||
rdata->regwrite = regwrite;
|
||||
|
||||
//aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1,
|
||||
// read_regs_rq_cb, rdata);
|
||||
}
|
||||
|
||||
/* Read the value of a specific register from a register dump */
|
||||
static int regval_from_dump(unsigned char *data, uint8_t target)
|
||||
{
|
||||
if (*data != FIRST_AES1610_REG) {
|
||||
fp_err("not a register dump");
|
||||
return -EILSEQ;
|
||||
}
|
||||
|
||||
if (!(FIRST_AES1610_REG <= target && target <= LAST_AES1610_REG)) {
|
||||
fp_err("out of range");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
target -= FIRST_AES1610_REG;
|
||||
target *= 2;
|
||||
return data[target + 1];
|
||||
}
|
||||
|
||||
static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
||||
void *user_data)
|
||||
{
|
||||
@@ -217,14 +124,13 @@ static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
||||
fpi_ssm_mark_aborted(ssm, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* read the specified number of bytes from the IN endpoint but throw them
|
||||
* away, then increment the SSM */
|
||||
static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
|
||||
{
|
||||
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||
unsigned char *data;
|
||||
struct fp_dev *dev;
|
||||
int r;
|
||||
|
||||
if (!transfer) {
|
||||
@@ -233,7 +139,8 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
|
||||
}
|
||||
|
||||
data = g_malloc(bytes);
|
||||
libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes,
|
||||
dev = fpi_ssm_get_dev(ssm);
|
||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes,
|
||||
generic_ignore_data_cb, ssm, BULK_TIMEOUT);
|
||||
|
||||
r = libusb_submit_transfer(transfer);
|
||||
@@ -244,150 +151,6 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
|
||||
}
|
||||
}
|
||||
|
||||
/****** IMAGE PROCESSING ******/
|
||||
|
||||
static int sum_histogram_values(unsigned char *data, uint8_t threshold)
|
||||
{
|
||||
int r = 0;
|
||||
int i;
|
||||
uint16_t *histogram = (uint16_t *)(data + 1);
|
||||
|
||||
if (*data != 0xde)
|
||||
return -EILSEQ;
|
||||
|
||||
if (threshold > 0x0f)
|
||||
return -EINVAL;
|
||||
|
||||
/* FIXME endianness */
|
||||
for (i = threshold; i < 16; i++)
|
||||
r += histogram[i];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* find overlapping parts of frames */
|
||||
static unsigned int find_overlap(unsigned char *first_frame,
|
||||
unsigned char *second_frame, unsigned int *min_error)
|
||||
{
|
||||
unsigned int dy;
|
||||
unsigned int not_overlapped_height = 0;
|
||||
*min_error = 255 * FRAME_SIZE;
|
||||
for (dy = 0; dy < FRAME_HEIGHT; dy++) {
|
||||
/* Calculating difference (error) between parts of frames */
|
||||
unsigned int i;
|
||||
unsigned int error = 0;
|
||||
for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) {
|
||||
/* Using ? operator to avoid abs function */
|
||||
error += first_frame[i] > second_frame[i] ?
|
||||
(first_frame[i] - second_frame[i]) :
|
||||
(second_frame[i] - first_frame[i]);
|
||||
}
|
||||
|
||||
/* Normalize error */
|
||||
error *= 15;
|
||||
error /= i;
|
||||
if (error < *min_error) {
|
||||
*min_error = error;
|
||||
not_overlapped_height = dy;
|
||||
}
|
||||
first_frame += FRAME_WIDTH;
|
||||
}
|
||||
|
||||
return not_overlapped_height;
|
||||
}
|
||||
|
||||
/* assemble a series of frames into a single image */
|
||||
static unsigned int assemble(struct aes1610_dev *aesdev, unsigned char *output,
|
||||
gboolean reverse, unsigned int *errors_sum)
|
||||
{
|
||||
uint8_t *assembled = output;
|
||||
int frame;
|
||||
uint32_t image_height = FRAME_HEIGHT;
|
||||
unsigned int min_error;
|
||||
size_t num_strips = aesdev->strips_len;
|
||||
GSList *list_entry = aesdev->strips;
|
||||
*errors_sum = 0;
|
||||
|
||||
if (num_strips < 1)
|
||||
return 0;
|
||||
|
||||
/* Rotating given data by 90 degrees
|
||||
* Taken from document describing aes1610 image format
|
||||
* TODO: move reversing detection here */
|
||||
|
||||
if (reverse)
|
||||
output += (num_strips - 1) * FRAME_SIZE;
|
||||
for (frame = 0; frame < num_strips; frame++) {
|
||||
aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output);
|
||||
|
||||
if (reverse)
|
||||
output -= FRAME_SIZE;
|
||||
else
|
||||
output += FRAME_SIZE;
|
||||
list_entry = g_slist_next(list_entry);
|
||||
}
|
||||
|
||||
/* Detecting where frames overlaped */
|
||||
output = assembled;
|
||||
for (frame = 1; frame < num_strips; frame++) {
|
||||
int not_overlapped;
|
||||
|
||||
output += FRAME_SIZE;
|
||||
not_overlapped = find_overlap(assembled, output, &min_error);
|
||||
*errors_sum += min_error;
|
||||
image_height += not_overlapped;
|
||||
assembled += FRAME_WIDTH * not_overlapped;
|
||||
memcpy(assembled, output, FRAME_SIZE);
|
||||
}
|
||||
return image_height;
|
||||
}
|
||||
|
||||
static void assemble_and_submit_image(struct fp_img_dev *dev)
|
||||
{
|
||||
struct aes1610_dev *aesdev = dev->priv;
|
||||
size_t final_size;
|
||||
struct fp_img *img;
|
||||
unsigned int errors_sum, r_errors_sum;
|
||||
|
||||
fp_dbg("");
|
||||
|
||||
BUG_ON(aesdev->strips_len == 0);
|
||||
|
||||
/* reverse list */
|
||||
aesdev->strips = g_slist_reverse(aesdev->strips);
|
||||
|
||||
/* create buffer big enough for max image */
|
||||
img = fpi_img_new(aesdev->strips_len * FRAME_SIZE);
|
||||
|
||||
img->flags = FP_IMG_COLORS_INVERTED;
|
||||
img->height = assemble(aesdev, img->data, FALSE, &errors_sum);
|
||||
img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum);
|
||||
|
||||
if (r_errors_sum > errors_sum) {
|
||||
img->height = assemble(aesdev, img->data, FALSE, &errors_sum);
|
||||
img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED;
|
||||
fp_dbg("normal scan direction");
|
||||
} else {
|
||||
fp_dbg("reversed scan direction");
|
||||
}
|
||||
|
||||
/* now that overlap has been removed, resize output image buffer */
|
||||
final_size = img->height * FRAME_WIDTH;
|
||||
img = fpi_img_resize(img, final_size);
|
||||
/* FIXME: ugly workaround */
|
||||
if (img->height < 12)
|
||||
img->height = 12;
|
||||
fpi_imgdev_image_captured(dev, img);
|
||||
|
||||
/* free strips and strip list */
|
||||
g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL);
|
||||
g_slist_free(aesdev->strips);
|
||||
aesdev->strips = NULL;
|
||||
aesdev->strips_len = 0;
|
||||
aesdev->blanks_count = 0;
|
||||
}
|
||||
|
||||
|
||||
/****** FINGER PRESENCE DETECTION ******/
|
||||
|
||||
|
||||
@@ -416,15 +179,6 @@ static const struct aes_regwrite finger_det_reqs[] = {
|
||||
{ 0x81, 0x04 }
|
||||
};
|
||||
|
||||
static const struct aes_regwrite finger_det_none[] = {
|
||||
{ 0x80, 0x01 },
|
||||
{ 0x82, 0x00 },
|
||||
{ 0x86, 0x00 },
|
||||
{ 0xB1, 0x28 },
|
||||
{ 0x1D, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
static void start_finger_detection(struct fp_img_dev *dev);
|
||||
|
||||
static void finger_det_data_cb(struct libusb_transfer *transfer)
|
||||
@@ -461,12 +215,6 @@ out:
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
|
||||
|
||||
static void finger_det_none_cb(struct fp_img_dev *dev, int result, void *user_data) | ||||